From 667ca55bad0108c4bdf8f007b89e1a52fc766aad Mon Sep 17 00:00:00 2001
From: Kent Quirk <q@lindenlab.com>
Date: Mon, 5 Jan 2009 18:59:12 +0000
Subject: [PATCH] svn merge -r106715:HEAD
 svn+ssh://svn.lindenlab.com/svn/linden/branches/q/notifications-merge-r106715
 .  QAR-1149 -- Final merge of notifications to trunk.

---
 indra/llcommon/lldate.cpp                     |   17 +-
 indra/llcommon/lldate.h                       |   29 +-
 indra/llcommon/llmemory.h                     |   59 +-
 indra/llcommon/llsd.cpp                       |   40 +-
 indra/llcommon/llsd.h                         |    4 +-
 indra/llcommon/lltimer.cpp                    |    8 +
 indra/llcommon/lltimer.h                      |    2 +
 indra/llcommon/lluuid.cpp                     |   15 +
 indra/llcommon/lluuid.h                       |    5 +-
 indra/llinventory/lleconomy.h                 |    2 +
 indra/llmath/llmath.h                         |   24 +
 indra/llmath/llrect.h                         |    5 +
 indra/llrender/llgl.cpp                       |    5 +-
 indra/llui/CMakeLists.txt                     |    4 +
 indra/llui/llcombobox.cpp                     |   32 +-
 indra/llui/llcombobox.h                       |    1 +
 indra/llui/llfloater.cpp                      |    5 +
 indra/llui/llfloater.h                        |   24 +-
 indra/llui/llfunctorregistry.cpp              |   37 +
 indra/llui/llfunctorregistry.h                |  145 ++
 indra/llui/llnotifications.cpp                | 1471 +++++++++++++++++
 indra/llui/llnotifications.h                  |  892 ++++++++++
 indra/llui/llpanel.cpp                        |  129 +-
 indra/llui/llpanel.h                          |   26 +-
 indra/llui/llscrollbar.cpp                    |   76 +-
 indra/llui/llscrollbar.h                      |    2 +-
 indra/llui/llscrolllistctrl.cpp               |  342 ++--
 indra/llui/llscrolllistctrl.h                 |  115 +-
 indra/llui/llui.cpp                           |   16 +-
 indra/llui/llui.h                             |  237 +++
 indra/llui/lluictrl.cpp                       |   11 +-
 indra/llui/lluictrl.h                         |    2 +-
 indra/llui/lluictrlfactory.h                  |    1 +
 indra/llui/lluistring.cpp                     |   13 +
 indra/llui/lluistring.h                       |    6 +-
 indra/llui/llview.cpp                         |    5 +-
 indra/llui/llview.h                           |    7 +-
 indra/llxml/llxmlnode.cpp                     |  185 ++-
 indra/llxml/llxmlnode.h                       |   26 +-
 indra/newview/CMakeLists.txt                  |    6 +
 indra/newview/app_settings/settings.xml       |   11 +
 indra/newview/llagent.cpp                     |  104 +-
 indra/newview/llagent.h                       |    6 +-
 indra/newview/llappviewer.cpp                 |  167 +-
 indra/newview/llappviewer.h                   |    3 +-
 indra/newview/llassetuploadresponders.cpp     |   28 +-
 indra/newview/llcallingcard.cpp               |   20 +-
 indra/newview/llcompilequeue.cpp              |   12 +-
 indra/newview/llconfirmationmanager.cpp       |   28 +-
 indra/newview/lldelayedgestureerror.cpp       |    8 +-
 indra/newview/lleventnotifier.cpp             |   53 +-
 indra/newview/lleventnotifier.h               |    2 +-
 indra/newview/llfirstuse.cpp                  |   46 +-
 indra/newview/llfloateranimpreview.cpp        |    2 +-
 indra/newview/llfloaterauction.cpp            |   18 +-
 indra/newview/llfloaterbuy.cpp                |    4 +-
 indra/newview/llfloaterbuycontents.cpp        |    4 +-
 indra/newview/llfloaterbuyland.cpp            |    4 +-
 indra/newview/llfloaterdaycycle.cpp           |   12 +-
 indra/newview/llfloaterenvsettings.cpp        |   14 +-
 indra/newview/llfloaterfriends.cpp            |  156 +-
 indra/newview/llfloaterfriends.h              |    8 +-
 indra/newview/llfloatergodtools.cpp           |   90 +-
 indra/newview/llfloatergodtools.h             |    8 +-
 indra/newview/llfloatergroups.cpp             |   20 +-
 indra/newview/llfloatergroups.h               |    2 +-
 indra/newview/llfloaterhardwaresettings.cpp   |    2 +-
 indra/newview/llfloaterhud.cpp                |    2 +-
 indra/newview/llfloaterland.cpp               |  150 +-
 indra/newview/llfloaterland.h                 |   11 +-
 .../newview/llfloaternotificationsconsole.cpp |  292 ++++
 indra/newview/llfloaternotificationsconsole.h |   78 +
 indra/newview/llfloateropenobject.cpp         |    6 +-
 indra/newview/llfloaterperms.cpp              |    2 +-
 indra/newview/llfloaterpostcard.cpp           |   48 +-
 indra/newview/llfloaterpostcard.h             |    2 +-
 indra/newview/llfloaterpostprocess.cpp        |   16 +-
 indra/newview/llfloaterpostprocess.h          |    2 +-
 indra/newview/llfloaterregioninfo.cpp         |  478 +++---
 indra/newview/llfloaterregioninfo.h           |   28 +-
 indra/newview/llfloaterreporter.cpp           |   35 +-
 indra/newview/llfloatersellland.cpp           |  104 +-
 indra/newview/llfloatersnapshot.cpp           |    2 +-
 indra/newview/llfloatertopobjects.cpp         |   12 +-
 indra/newview/llfloatertopobjects.h           |    4 +-
 indra/newview/llfloatertos.cpp                |    2 +-
 indra/newview/llfloaterurlentry.cpp           |   34 +-
 indra/newview/llfloaterurlentry.h             |    2 +-
 indra/newview/llfloaterwater.cpp              |   46 +-
 indra/newview/llfloaterwater.h                |    6 +-
 indra/newview/llfloaterwindlight.cpp          |   52 +-
 indra/newview/llfloaterwindlight.h            |    6 +-
 indra/newview/llfloaterworldmap.cpp           |    6 +-
 indra/newview/llgesturemgr.cpp                |    6 +-
 indra/newview/llgroupmgr.cpp                  |    6 +-
 indra/newview/llimpanel.cpp                   |   99 +-
 indra/newview/llimpanel.h                     |    6 +-
 indra/newview/llimview.cpp                    |  471 +++---
 indra/newview/llimview.h                      |    7 +-
 indra/newview/llinventorybridge.cpp           |  105 +-
 indra/newview/llinventorymodel.h              |    1 -
 indra/newview/lllandmarklist.cpp              |    4 +-
 indra/newview/llmutelist.cpp                  |   23 +-
 indra/newview/llnamelistctrl.cpp              |    5 +-
 indra/newview/llpanelavatar.cpp               |  117 +-
 indra/newview/llpanelavatar.h                 |   14 +-
 indra/newview/llpanelclassified.cpp           |   88 +-
 indra/newview/llpanelclassified.h             |    8 +-
 indra/newview/llpanelgroup.cpp                |   50 +-
 indra/newview/llpanelgroup.h                  |    3 +-
 indra/newview/llpanelgroupgeneral.cpp         |   82 +-
 indra/newview/llpanelgroupgeneral.h           |    7 +-
 indra/newview/llpanelgroupinvite.cpp          |   29 +-
 indra/newview/llpanelgroupnotices.cpp         |   12 +-
 indra/newview/llpanelgrouproles.cpp           |   95 +-
 indra/newview/llpanelgrouproles.h             |    9 +-
 indra/newview/llpanelland.cpp                 |    2 +-
 indra/newview/llpanellogin.cpp                |   10 +-
 indra/newview/llpanellogin.h                  |    2 +-
 indra/newview/llpanelpermissions.cpp          |   11 +-
 indra/newview/llpanelpick.cpp                 |    2 +-
 indra/newview/llpanelplace.cpp                |   14 +-
 indra/newview/llpanelplace.h                  |    2 +-
 indra/newview/llpreviewgesture.cpp            |   35 +-
 indra/newview/llpreviewgesture.h              |    2 +-
 indra/newview/llpreviewnotecard.cpp           |   32 +-
 indra/newview/llpreviewnotecard.h             |    2 +-
 indra/newview/llpreviewscript.cpp             |   87 +-
 indra/newview/llpreviewscript.h               |    6 +-
 indra/newview/llpreviewtexture.cpp            |   14 +-
 indra/newview/llselectmgr.cpp                 |   45 +-
 indra/newview/llselectmgr.h                   |    2 +-
 indra/newview/llstartup.cpp                   |  183 +-
 indra/newview/llstartup.h                     |    2 +-
 indra/newview/llstatusbar.cpp                 |   16 +-
 indra/newview/lltoolbar.cpp                   |    7 +-
 indra/newview/lltoolbrush.cpp                 |    6 +-
 indra/newview/lltooldraganddrop.cpp           |   78 +-
 indra/newview/lltooldraganddrop.h             |    4 +-
 indra/newview/llurldispatcher.cpp             |    5 +-
 indra/newview/llviewerinventory.cpp           |    4 +-
 indra/newview/llviewermenu.cpp                |  334 ++--
 indra/newview/llviewermenufile.cpp            |   73 +-
 indra/newview/llviewermessage.cpp             | 1058 ++++++------
 indra/newview/llviewermessage.h               |   10 +-
 indra/newview/llviewerparcelmedia.cpp         |   14 +-
 indra/newview/llviewerparcelmgr.cpp           |  179 +-
 indra/newview/llviewerparcelmgr.h             |   12 +-
 indra/newview/llviewertexteditor.cpp          |   48 +-
 indra/newview/llviewertexteditor.h            |    4 +-
 indra/newview/llviewerwindow.cpp              |  121 +-
 indra/newview/llviewerwindow.h                |   15 +-
 indra/newview/llvograss.cpp                   |   12 +-
 indra/newview/llvoiceclient.cpp               |    2 +-
 indra/newview/llvotree.cpp                    |    6 +-
 indra/newview/llwearable.cpp                  |   12 +-
 indra/newview/llwearablelist.cpp              |   30 +-
 indra/newview/llwldaycycle.cpp                |    6 +-
 indra/newview/llxmlrpctransaction.cpp         |   20 +-
 159 files changed, 6812 insertions(+), 3253 deletions(-)
 create mode 100644 indra/llui/llfunctorregistry.cpp
 create mode 100644 indra/llui/llfunctorregistry.h
 create mode 100644 indra/llui/llnotifications.cpp
 create mode 100644 indra/llui/llnotifications.h
 create mode 100644 indra/newview/llfloaternotificationsconsole.cpp
 create mode 100644 indra/newview/llfloaternotificationsconsole.h

diff --git a/indra/llcommon/lldate.cpp b/indra/llcommon/lldate.cpp
index 6b4bd0d7ef7..ff1b6c5334d 100644
--- a/indra/llcommon/lldate.cpp
+++ b/indra/llcommon/lldate.cpp
@@ -36,9 +36,12 @@
 
 #include "apr_time.h"
 
+#include <time.h>
 #include <iomanip>
 #include <sstream>
 
+#include "lltimer.h"
+
 static const F64 DATE_EPOCH = 0.0;
 
 static const F64 LL_APR_USEC_PER_SEC = 1000000.0;
@@ -122,7 +125,7 @@ void LLDate::toHTTPDateStream(std::ostream& s) const
       << " GMT";
 
     // RFC 1123 date does not use microseconds
-    llinfos << "Date in RFC 1123 format is " << s << llendl;
+    //llinfos << "Date in RFC 1123 format is " << s << llendl;
 }
 
 void LLDate::toStream(std::ostream& s) const
@@ -239,6 +242,17 @@ bool operator!=(const LLDate& first, const LLDate& second)
 	return (first.secondsSinceEpoch() != second.secondsSinceEpoch());
 }
 
+/* static */ LLDate LLDate::now()
+{
+	// time() returns seconds, we want fractions of a second, which LLTimer provides --RN
+	return LLDate(LLTimer::getTotalSeconds());
+}
+
+bool LLDate::operator<(const LLDate& rhs) const
+{
+    return mSecondsSinceEpoch < rhs.mSecondsSinceEpoch;
+}
+
 std::ostream& operator<<(std::ostream& s, const LLDate& date)
 {
 	date.toStream(s);
@@ -250,3 +264,4 @@ std::istream& operator>>(std::istream& s, LLDate& date)
 	date.fromStream(s);
 	return s;
 }
+
diff --git a/indra/llcommon/lldate.h b/indra/llcommon/lldate.h
index 2b53c8cc9a9..b660f9fcdd4 100644
--- a/indra/llcommon/lldate.h
+++ b/indra/llcommon/lldate.h
@@ -35,6 +35,7 @@
 #define LL_LLDATE_H
 
 #include <iosfwd>
+#include <string>
 
 #include "stdtypes.h"
 
@@ -53,7 +54,7 @@ class LLDate
 	LLDate();
 
 	/** 
-	 * @brief Construct a date equal to epoch.
+	 * @brief Construct a date equal the source date.
 	 */
 	LLDate(const LLDate& date);
 
@@ -111,6 +112,32 @@ class LLDate
 	 * @param seconds The number of seconds since epoch UTC.
 	 */
 	void secondsSinceEpoch(F64 seconds);
+    
+    /**
+     * @brief Create an LLDate object set to the current time.
+	 *
+	 * @return The number of seconds since epoch UTC.
+	 */
+    static LLDate now();
+
+	/** 
+	 * @brief Compare dates using operator< so we can order them using STL.
+	 *
+	 * @param rhs -- the right hand side of the comparison operator
+	 */
+	bool operator<(const LLDate& rhs) const;
+    
+	/** 
+	 * @brief Remaining comparison operators in terms of operator<
+     * This conforms to the expectation of STL.
+	 *
+	 * @param rhs -- the right hand side of the comparison operator
+	 */
+    bool operator>(const LLDate& rhs) const { return rhs < *this; }
+    bool operator<=(const LLDate& rhs) const { return !(rhs < *this); }
+    bool operator>=(const LLDate& rhs) const { return !(*this < rhs); }
+    bool operator!=(const LLDate& rhs) const { return (*this < rhs) || (rhs < *this); }
+    bool operator==(const LLDate& rhs) const { return !(*this != rhs); }
 
 private:
 	F64 mSecondsSinceEpoch;
diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h
index cc57e658fb9..3f3dd33ee3f 100644
--- a/indra/llcommon/llmemory.h
+++ b/indra/llcommon/llmemory.h
@@ -409,53 +409,58 @@ template <typename T> class LLInitializedPointer
 //
 //   class Foo: public LLSingleton<Foo>{};
 //
-//   Foo* instance = Foo::getInstance();
+//   Foo& instance = Foo::instance();
 //
-// The second way is to define a seperate class that exposes the singleton
-// interface:
+// The second way is to use the singleton class directly, without inheritance:
 //
-//   class FooSingleton: public LLSingleton<Foo>{};
+//   typedef LLSingleton<Foo> FooSingleton;
 //
-//   Foo* instance = FooSingleton::getInstance();
+//   Foo& instance = FooSingleton::instance();
+//
+// In this case, the class being managed as a singleton needs to provide an
+// initSingleton() method since the LLSingleton virtual method won't be
+// available
 //
 // As currently written, it is not thread-safe.
-#if LL_WINDOWS && _MSC_VER < 1400 // this is Visual C++ 2003 or earlier
-// workaround for VC7 compiler bug
-// adapted from http://www.codeproject.com/KB/tips/VC2003MeyersSingletonBug.aspx
-// our version doesn't introduce a nested struct so that you can still declare LLSingleton<MyClass>
-// a friend and hide your constructor
-
 template <typename T>
 class LLSingleton
 {
 public:
- 	static T* getInstance()
+	virtual ~LLSingleton() {}
+#ifdef  LL_MSVC7
+// workaround for VC7 compiler bug
+// adapted from http://www.codeproject.com/KB/tips/VC2003MeyersSingletonBug.aspx
+// our version doesn't introduce a nested struct so that you can still declare LLSingleton<MyClass>
+// a friend and hide your constructor
+	static T* getInstance()
     {
         LLSingleton<T> singleton;
-        return singleton.get();
-    }
-private:
-	T* get()
-    {
-        static T instance;
-        return &instance;
+        return singleton.vsHack();
     }
 
-};
+	T* vsHack()
 #else
-
-template <typename T>
-class LLSingleton
-{
-public:
 	static T* getInstance()
+#endif
 	{
 		static T instance;
+		static bool needs_init = true;
+		if (needs_init)
+		{
+			needs_init = false;
+			instance.initSingleton();
+		}
 		return &instance;
 	}
-};
 
-#endif
+	static T& instance()
+	{
+		return *getInstance();
+	}
+
+private:
+	virtual void initSingleton() {}
+};
 
 //----------------------------------------------------------------------------
 
diff --git a/indra/llcommon/llsd.cpp b/indra/llcommon/llsd.cpp
index 099f233f56d..4bf4e442fdf 100644
--- a/indra/llcommon/llsd.cpp
+++ b/indra/llcommon/llsd.cpp
@@ -349,7 +349,7 @@ namespace
 
 		virtual bool has(const LLSD::String&) const; 
 		virtual LLSD get(const LLSD::String&) const; 
-		        void insert(const LLSD::String& k, const LLSD& v);
+		        LLSD& insert(const LLSD::String& k, const LLSD& v);
 		virtual void erase(const LLSD::String&);
 		              LLSD& ref(const LLSD::String&);
 		virtual const LLSD& ref(const LLSD::String&) const;
@@ -388,9 +388,14 @@ namespace
 		return (i != mData.end()) ? i->second : LLSD();
 	}
 	
-	void ImplMap::insert(const LLSD::String& k, const LLSD& v)
+	LLSD& ImplMap::insert(const LLSD::String& k, const LLSD& v)
 	{
 		mData.insert(DataMap::value_type(k, v));
+		#ifdef LL_MSVC7
+			return *((LLSD*)this);
+		#else
+			return *dynamic_cast<LLSD*>(this);
+		#endif
 	}
 	
 	void ImplMap::erase(const LLSD::String& k)
@@ -436,7 +441,7 @@ namespace
 		virtual int size() const; 
 		virtual LLSD get(LLSD::Integer) const;
 		        void set(LLSD::Integer, const LLSD&);
-		        void insert(LLSD::Integer, const LLSD&);
+		        LLSD& insert(LLSD::Integer, const LLSD&);
 		        void append(const LLSD&);
 		virtual void erase(LLSD::Integer);
 		              LLSD& ref(LLSD::Integer);
@@ -485,9 +490,15 @@ namespace
 		mData[index] = v;
 	}
 	
-	void ImplArray::insert(LLSD::Integer i, const LLSD& v)
+	LLSD& ImplArray::insert(LLSD::Integer i, const LLSD& v)
 	{
-		if (i < 0) { return; }
+		if (i < 0) {
+			#ifdef LL_MSVC7
+				return *((LLSD*)this);
+			#else
+				return *dynamic_cast<LLSD*>(this);
+			#endif
+		}
 		DataVector::size_type index = i;
 		
 		if (index >= mData.size())
@@ -496,6 +507,11 @@ namespace
 		}
 		
 		mData.insert(mData.begin() + index, v);
+		#ifdef LL_MSVC7
+			return *((LLSD*)this);
+		#else
+			return *dynamic_cast<LLSD*>(this);
+		#endif
 	}
 	
 	void ImplArray::append(const LLSD& v)
@@ -739,8 +755,11 @@ LLSD LLSD::emptyMap()
 bool LLSD::has(const String& k) const	{ return safe(impl).has(k); }
 LLSD LLSD::get(const String& k) const	{ return safe(impl).get(k); } 
 
-void LLSD::insert(const String& k, const LLSD& v)
-										{ makeMap(impl).insert(k, v); }
+LLSD& LLSD::insert(const String& k, const LLSD& v)
+										{ 
+											makeMap(impl).insert(k, v); 
+											return *dynamic_cast<LLSD*>(this);
+										}
 void LLSD::erase(const String& k)		{ makeMap(impl).erase(k); }
 
 LLSD&		LLSD::operator[](const String& k)
@@ -761,8 +780,11 @@ int LLSD::size() const					{ return safe(impl).size(); }
 LLSD LLSD::get(Integer i) const			{ return safe(impl).get(i); } 
 void LLSD::set(Integer i, const LLSD& v){ makeArray(impl).set(i, v); }
 
-void LLSD::insert(Integer i, const LLSD& v)
-										{ makeArray(impl).insert(i, v); }
+LLSD& LLSD::insert(Integer i, const LLSD& v)
+										{ 
+											makeArray(impl).insert(i, v); 
+											return *this;
+										}
 void LLSD::append(const LLSD& v)		{ makeArray(impl).append(v); }
 void LLSD::erase(Integer i)				{ makeArray(impl).erase(i); }
 
diff --git a/indra/llcommon/llsd.h b/indra/llcommon/llsd.h
index 0382fb1360b..87874009dd1 100644
--- a/indra/llcommon/llsd.h
+++ b/indra/llcommon/llsd.h
@@ -222,7 +222,7 @@ class LLSD
 		
 		bool has(const String&) const;
 		LLSD get(const String&) const;
-		void insert(const String&, const LLSD&);
+		LLSD& insert(const String&, const LLSD&);
 		void erase(const String&);
 		
 		LLSD& operator[](const String&);
@@ -237,7 +237,7 @@ class LLSD
 		
 		LLSD get(Integer) const;
 		void set(Integer, const LLSD&);
-		void insert(Integer, const LLSD&);
+		LLSD& insert(Integer, const LLSD&);
 		void append(const LLSD&);
 		void erase(Integer);
 		
diff --git a/indra/llcommon/lltimer.cpp b/indra/llcommon/lltimer.cpp
index 2c346080641..2525e249897 100644
--- a/indra/llcommon/lltimer.cpp
+++ b/indra/llcommon/lltimer.cpp
@@ -569,6 +569,14 @@ LLEventTimer::LLEventTimer(F32 period)
 	sActiveList.push_back(this);
 }
 
+LLEventTimer::LLEventTimer(const LLDate& time)
+: mEventTimer()
+{
+	mPeriod = (F32)(time.secondsSinceEpoch() - LLDate::now().secondsSinceEpoch());
+	sActiveList.push_back(this);
+}
+
+
 LLEventTimer::~LLEventTimer() 
 {
 	sActiveList.remove(this);
diff --git a/indra/llcommon/lltimer.h b/indra/llcommon/lltimer.h
index 1916d67fda1..6d6f1f44cd1 100644
--- a/indra/llcommon/lltimer.h
+++ b/indra/llcommon/lltimer.h
@@ -38,6 +38,7 @@
 #include <limits.h>
 
 #include "stdtypes.h"
+#include "lldate.h"
 
 #include <string>
 #include <list>
@@ -173,6 +174,7 @@ class LLEventTimer
 {
 public:
 	LLEventTimer(F32 period);	// period is the amount of time between each call to tick() in seconds
+	LLEventTimer(const LLDate& time);
 	virtual ~LLEventTimer();
 
 	//function to be called at the supplied frequency
diff --git a/indra/llcommon/lluuid.cpp b/indra/llcommon/lluuid.cpp
index 1098d1bd3c9..019c5045d4a 100644
--- a/indra/llcommon/lluuid.cpp
+++ b/indra/llcommon/lluuid.cpp
@@ -908,6 +908,21 @@ BOOL LLUUID::parseUUID(const std::string& buf, LLUUID* value)
 	return FALSE;
 }
 
+//static
+LLUUID LLUUID::generateNewID(std::string hash_string)
+{
+	LLUUID new_id;
+	if (hash_string.empty())
+	{
+		new_id.generate();
+	}
+	else
+	{
+		new_id.generate(hash_string);
+	}
+	return new_id;
+}
+
 LLAssetID LLTransactionID::makeAssetID(const LLUUID& session) const
 {
 	LLAssetID result;
diff --git a/indra/llcommon/lluuid.h b/indra/llcommon/lluuid.h
index b2fcce51610..e5c204b5892 100644
--- a/indra/llcommon/lluuid.h
+++ b/indra/llcommon/lluuid.h
@@ -65,6 +65,9 @@ class LLUUID
 	//
 	void	generate();					// Generate a new UUID
 	void	generate(const std::string& stream); //Generate a new UUID based on hash of input stream
+
+	static LLUUID generateNewID(std::string stream = "");	//static version of above for use in initializer expressions such as constructor params, etc. 
+
 	BOOL	set(const char *in_string, BOOL emit = TRUE);	// Convert from string, if emit is FALSE, do not emit warnings
 	BOOL	set(const std::string& in_string, BOOL emit = TRUE);	// Convert from string, if emit is FALSE, do not emit warnings
 	void	setNull();					// Faster than setting to LLUUID::null.
@@ -124,7 +127,7 @@ class LLUUID
 	static S32 getNodeID(unsigned char * node_id);
 
 	static BOOL parseUUID(const std::string& buf, LLUUID* value);
-	
+
 	U8 mData[UUID_BYTES];
 };
 
diff --git a/indra/llinventory/lleconomy.h b/indra/llinventory/lleconomy.h
index 4ac7cb46058..707f4451d19 100644
--- a/indra/llinventory/lleconomy.h
+++ b/indra/llinventory/lleconomy.h
@@ -47,6 +47,8 @@ class LLGlobalEconomy
 	// become a singleton and this pattern will more easily disambiguate them.
 	typedef LLSingleton<LLGlobalEconomy> Singleton;
 
+	void initSingleton() { }
+
 	virtual void print();
 
 	static void processEconomyData(LLMessageSystem *msg, LLGlobalEconomy* econ_data);
diff --git a/indra/llmath/llmath.h b/indra/llmath/llmath.h
index 0372bae1068..916f4aa6c71 100644
--- a/indra/llmath/llmath.h
+++ b/indra/llmath/llmath.h
@@ -103,6 +103,30 @@ const F32 FP_MAG_THRESHOLD = 0.0000001f;
 // TODO: Replace with logic like is_approx_equal
 inline BOOL is_approx_zero( F32 f ) { return (-F_APPROXIMATELY_ZERO < f) && (f < F_APPROXIMATELY_ZERO); }
 
+// These functions work by interpreting sign+exp+mantissa as an unsigned
+// integer.
+// For example:
+// x = <sign>1 <exponent>00000010 <mantissa>00000000000000000000000
+// y = <sign>1 <exponent>00000001 <mantissa>11111111111111111111111
+//
+// interpreted as ints = 
+// x = 10000001000000000000000000000000
+// y = 10000000111111111111111111111111
+// which is clearly a different of 1 in the least significant bit
+// Values with the same exponent can be trivially shown to work.
+//
+// WARNING: Denormals of opposite sign do not work
+// x = <sign>1 <exponent>00000000 <mantissa>00000000000000000000001
+// y = <sign>0 <exponent>00000000 <mantissa>00000000000000000000001
+// Although these values differ by 2 in the LSB, the sign bit makes
+// the int comparison fail.
+//
+// WARNING: NaNs can compare equal
+// There is no special treatment of exceptional values like NaNs
+//
+// WARNING: Infinity is comparable with F32_MAX and negative 
+// infinity is comparable with F32_MIN
+
 inline BOOL is_approx_equal(F32 x, F32 y)
 {
 	const S32 COMPARE_MANTISSA_UP_TO_BIT = 0x02;
diff --git a/indra/llmath/llrect.h b/indra/llmath/llrect.h
index 21ca4189ff7..93b69714deb 100644
--- a/indra/llmath/llrect.h
+++ b/indra/llmath/llrect.h
@@ -223,6 +223,11 @@ template <class Type> class LLRectBase
 		return *this;
 	}
 
+	bool isValid() const
+	{
+		return mLeft <= mRight && mBottom <= mTop;
+	}
+
 	bool isNull() const
 	{
 		return mLeft == mRight || mBottom == mTop;
diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index aced88f1a2a..89c5115cfd5 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -980,13 +980,10 @@ void LLGLState::initClass()
 {
 	sStateMap[GL_DITHER] = GL_TRUE;
 	// sStateMap[GL_TEXTURE_2D] = GL_TRUE;
-
+	
 	//make sure multisample defaults to disabled
 	sStateMap[GL_MULTISAMPLE_ARB] = GL_FALSE;
 	glDisable(GL_MULTISAMPLE_ARB);
-
-	//default vertex arrays to enabled.
-	glEnableClientState(GL_VERTEX_ARRAY);
 }
 
 //static
diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt
index 897cc4275d4..1b4d4e7d54c 100644
--- a/indra/llui/CMakeLists.txt
+++ b/indra/llui/CMakeLists.txt
@@ -36,6 +36,7 @@ set(llui_SOURCE_FILES
     lleditmenuhandler.cpp
     llfloater.cpp
     llfocusmgr.cpp
+    llfunctorregistry.cpp
     lliconctrl.cpp
     llkeywords.cpp
     lllineeditor.cpp
@@ -43,6 +44,7 @@ set(llui_SOURCE_FILES
     llmodaldialog.cpp
     llmultislider.cpp
     llmultisliderctrl.cpp
+    llnotifications.cpp
     llpanel.cpp
     llprogressbar.cpp
     llradiogroup.cpp
@@ -86,6 +88,7 @@ set(llui_HEADER_FILES
     lleditmenuhandler.h
     llfloater.h
     llfocusmgr.h
+    llfunctorregistry.h
     llhtmlhelp.h
     lliconctrl.h
     llkeywords.h
@@ -95,6 +98,7 @@ set(llui_HEADER_FILES
     llmodaldialog.h
     llmultisliderctrl.h
     llmultislider.h
+    llnotifications.h
     llpanel.h
     llprogressbar.h
     llradiogroup.h
diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp
index df5bcbe752c..6edd5a7fe5b 100644
--- a/indra/llui/llcombobox.cpp
+++ b/indra/llui/llcombobox.cpp
@@ -72,11 +72,12 @@ LLComboBox::LLComboBox(	const std::string& name, const LLRect &rect, const std::
 	mTextEntryTentative(TRUE),
 	mListPosition(BELOW),
 	mPrearrangeCallback( NULL ),
-	mTextEntryCallback( NULL )
+	mTextEntryCallback( NULL ),
+	mLabel(label)
 {
 	// Always use text box 
 	// Text label button
-	mButton = new LLButton(label,
+	mButton = new LLButton(mLabel,
 								LLRect(), 
 								LLStringUtil::null,
 								NULL, this);
@@ -197,7 +198,12 @@ LLView* LLComboBox::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *
 		}
 	}
 
-	combo_box->selectFirstItem();
+	// if providing user text entry or descriptive label
+	// don't select an item under the hood
+	if (!combo_box->acceptsTextInput() && combo_box->mLabel.empty())
+	{
+		combo_box->selectFirstItem();
+	}
 
 	return combo_box;
 }
@@ -259,7 +265,10 @@ LLScrollListItem* LLComboBox::add(const std::string& name, EAddPosition pos, BOO
 {
 	LLScrollListItem* item = mList->addSimpleElement(name, pos);
 	item->setEnabled(enabled);
-	mList->selectFirstItem();
+	if (!mAllowTextEntry && mLabel.empty())
+	{
+		selectFirstItem();
+	}
 	return item;
 }
 
@@ -268,7 +277,10 @@ LLScrollListItem* LLComboBox::add(const std::string& name, const LLUUID& id, EAd
 {
 	LLScrollListItem* item = mList->addSimpleElement(name, pos, id);
 	item->setEnabled(enabled);
-	mList->selectFirstItem();
+	if (!mAllowTextEntry && mLabel.empty())
+	{
+		selectFirstItem();
+	}
 	return item;
 }
 
@@ -278,7 +290,10 @@ LLScrollListItem* LLComboBox::add(const std::string& name, void* userdata, EAddP
 	LLScrollListItem* item = mList->addSimpleElement(name, pos);
 	item->setEnabled(enabled);
 	item->setUserdata( userdata );
-	mList->selectFirstItem();
+	if (!mAllowTextEntry && mLabel.empty())
+	{
+		selectFirstItem();
+	}
 	return item;
 }
 
@@ -287,7 +302,10 @@ LLScrollListItem* LLComboBox::add(const std::string& name, LLSD value, EAddPosit
 {
 	LLScrollListItem* item = mList->addSimpleElement(name, pos, value);
 	item->setEnabled(enabled);
-	mList->selectFirstItem();
+	if (!mAllowTextEntry && mLabel.empty())
+	{
+		selectFirstItem();
+	}
 	return item;
 }
 
diff --git a/indra/llui/llcombobox.h b/indra/llui/llcombobox.h
index 7427a331294..0317ebdae91 100644
--- a/indra/llui/llcombobox.h
+++ b/indra/llui/llcombobox.h
@@ -188,6 +188,7 @@ class LLComboBox
 	LLScrollListCtrl*	mList;
 	EPreferredPosition	mListPosition;
 	LLPointer<LLUIImage>	mArrowImage;
+	std::string			mLabel;
 
 private:
 	S32					mButtonPadding;
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index 22260b52cf1..dd93684a69d 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -147,6 +147,7 @@ LLFloater::LLFloater() :
 	}
 	mDragHandle = NULL;
 	mHandle.bind(this);
+	mNotificationContext = new LLFloaterNotificationContext(getHandle());
 }
 
 LLFloater::LLFloater(const std::string& name)
@@ -220,6 +221,7 @@ void LLFloater::initFloater(const std::string& title,
 					 BOOL drag_on_left, BOOL minimizable, BOOL close_btn)
 {
 	mHandle.bind(this);
+	mNotificationContext = new LLFloaterNotificationContext(getHandle());
 
 	// Init function can be called more than once, so clear out old data.
 	for (S32 i = 0; i < BUTTON_COUNT; i++)
@@ -429,6 +431,9 @@ void LLFloater::initFloater(const std::string& title,
 // virtual
 LLFloater::~LLFloater()
 {
+	delete mNotificationContext;
+	mNotificationContext = NULL;
+
 	control_map_t::iterator itor;
 	for (itor = mFloaterControls.begin(); itor != mFloaterControls.end(); ++itor)
 	{
diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h
index b66eba8810c..ebf26769602 100644
--- a/indra/llui/llfloater.h
+++ b/indra/llui/llfloater.h
@@ -39,6 +39,7 @@
 #include "llpanel.h"
 #include "lluuid.h"
 #include "lltabcontainer.h"
+#include "llnotifications.h"
 #include <set>
 
 class LLDragHandle;
@@ -46,6 +47,7 @@ class LLResizeHandle;
 class LLResizeBar;
 class LLButton;
 class LLMultiFloater;
+class LLFloater;
 
 const S32 LLFLOATER_VPAD = 6;
 const S32 LLFLOATER_HPAD = 6;
@@ -70,6 +72,20 @@ const BOOL CLOSE_NO = FALSE;
 const BOOL ADJUST_VERTICAL_YES = TRUE;
 const BOOL ADJUST_VERTICAL_NO = FALSE;
 
+// associates a given notification instance with a particular floater
+class LLFloaterNotificationContext : 
+	public LLNotificationContext
+{
+public:
+	LLFloaterNotificationContext(LLHandle<LLFloater> floater_handle) :
+		mFloaterHandle(floater_handle)
+	{}
+
+	LLFloater* getFloater() { return mFloaterHandle.get(); }
+private:
+	LLHandle<LLFloater> mFloaterHandle;
+};
+
 
 class LLFloater : public LLPanel
 {
@@ -213,6 +229,11 @@ friend class LLFloaterView;
 	// handle refocusing.
 	static void		closeFocusedFloater();
 
+	LLNotification::Params contextualNotification(const std::string& name) 
+	{ 
+	    return LLNotification::Params(name).context(mNotificationContext); 
+	}
+
 	static void		onClickClose(void *userdata);
 	static void		onClickMinimize(void *userdata);
 	static void		onClickTearOff(void *userdata);
@@ -299,7 +320,7 @@ friend class LLFloaterView;
 	S32				mPreviousMinimizedBottom;
 	S32				mPreviousMinimizedLeft;
 	
-private:
+	LLFloaterNotificationContext* mNotificationContext;
 	LLRootHandle<LLFloater>		mHandle;	
 };
 
@@ -467,7 +488,6 @@ template <class T> class LLFloaterSingleton : public LLUISingleton<T, Visibility
 {
 };
 
-
 extern LLFloaterView* gFloaterView;
 
 #endif  // LL_FLOATER_H
diff --git a/indra/llui/llfunctorregistry.cpp b/indra/llui/llfunctorregistry.cpp
new file mode 100644
index 00000000000..a6ecc6aa183
--- /dev/null
+++ b/indra/llui/llfunctorregistry.cpp
@@ -0,0 +1,37 @@
+/**
+ * @file llfunctorregistry.cpp
+ * @author Kent Quirk
+ * @brief Maintains a registry of named callback functors taking a single LLSD parameter
+ *
+ * $LicenseInfo:firstyear=2008&license=viewergpl$
+ * 
+ * Copyright (c) 2008, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ **/
+
+#include "llfunctorregistry.h"
+
+// This is a default functor always resident in the system.
+// It's used whenever a functor isn't found in the registry, so that
+// we at least log the data relating to the user response.
diff --git a/indra/llui/llfunctorregistry.h b/indra/llui/llfunctorregistry.h
new file mode 100644
index 00000000000..02bf74a28aa
--- /dev/null
+++ b/indra/llui/llfunctorregistry.h
@@ -0,0 +1,145 @@
+/**
+ * @file llfunctorregistry.h
+ * @author Kent Quirk
+ * @brief Maintains a registry of named callback functors taking a single LLSD parameter
+ *
+ * $LicenseInfo:firstyear=2008&license=viewergpl$
+ *
+ * Copyright (c) 2003-2007, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLFUNCTORREGISTRY_H
+#define LL_LLFUNCTORREGISTRY_H
+
+#include <string>
+#include <map>
+
+#include <boost/function.hpp>
+
+#include "llsd.h"
+#include "llmemory.h"
+
+/**
+ * @class LLFunctorRegistry
+ * @brief Maintains a collection of named functors for remote binding
+ * (mainly for use in callbacks from notifications and other signals)
+ * @see LLNotifications
+ *
+ * This class maintains a collection of named functors in a singleton.
+ * We wanted to be able to persist notifications with their callbacks
+ * across restarts of the viewer; we couldn't store functors that way.
+ * Using this registry, systems that require a functor to be maintained
+ * long term can register it at system startup, and then pass in the
+ * functor by name. 
+ */
+
+template <typename FUNCTOR_TYPE>
+class LLFunctorRegistry : public LLSingleton<LLFunctorRegistry<FUNCTOR_TYPE> >
+{
+	friend class LLSingleton<LLFunctorRegistry>;
+	LOG_CLASS(LLFunctorRegistry);
+private:
+	LLFunctorRegistry() : LOGFUNCTOR("LogFunctor"), DONOTHING("DoNothing")
+	{
+		mMap[LOGFUNCTOR] = log_functor;
+		mMap[DONOTHING] = do_nothing;
+	}
+
+public:
+	typedef FUNCTOR_TYPE ResponseFunctor;
+	typedef typename std::map<std::string, FUNCTOR_TYPE> FunctorMap;
+	
+	bool registerFunctor(const std::string& name, ResponseFunctor f)
+	{
+		bool retval = true;
+		typename FunctorMap::iterator it = mMap.find(name);
+		if (mMap.count(name) == 0)
+		{
+			mMap[name] = f;
+		}
+		else
+		{
+			llerrs << "attempt to store duplicate name '" << name << "' in LLFunctorRegistry. NOT ADDED." << llendl;
+			retval = false;
+		}
+		
+		return retval;
+	}
+
+	bool unregisterFunctor(const std::string& name)
+	{
+		if (mMap.count(name) == 0)
+		{
+			llwarns << "trying to remove '" << name << "' from LLFunctorRegistry but it's not there." << llendl;
+			return false;
+		}
+		mMap.erase(name);
+		return true;
+	}
+
+	FUNCTOR_TYPE getFunctor(const std::string& name)
+	{
+		typename FunctorMap::iterator it = mMap.find(name);
+		if (mMap.count(name) != 0)
+		{
+			return mMap[name];
+		}
+		else
+		{
+			llwarns << "tried to find '" << name << "' in LLFunctorRegistry, but it wasn't there." << llendl;
+			return mMap[LOGFUNCTOR];
+		}
+	}
+
+	const std::string LOGFUNCTOR;
+	const std::string DONOTHING;
+	
+private:
+
+	static void log_functor(const LLSD& notification, const LLSD& payload)
+	{
+		llwarns << "log_functor called with payload: " << payload << llendl;
+	}
+
+	static void do_nothing(const LLSD& notification, const LLSD& payload)
+	{
+		// what the sign sez
+	}
+
+	FunctorMap mMap;
+};
+
+template <typename FUNCTOR_TYPE>
+class LLFunctorRegistration
+{
+public:
+	LLFunctorRegistration(const std::string& name, FUNCTOR_TYPE functor) 
+	{
+		LLFunctorRegistry<FUNCTOR_TYPE>::instance().registerFunctor(name, functor);
+	}
+};
+
+#endif//LL_LLFUNCTORREGISTRY_H
+
diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp
new file mode 100644
index 00000000000..c2da50b98b2
--- /dev/null
+++ b/indra/llui/llnotifications.cpp
@@ -0,0 +1,1471 @@
+/**
+* @file llnotifications.cpp
+* @brief Non-UI queue manager for keeping a prioritized list of notifications
+*
+* $LicenseInfo:firstyear=2008&license=viewergpl$
+* 
+* Copyright (c) 2008, Linden Research, Inc.
+* 
+* Second Life Viewer Source Code
+* The source code in this file ("Source Code") is provided by Linden Lab
+* to you under the terms of the GNU General Public License, version 2.0
+* ("GPL"), unless you have obtained a separate licensing agreement
+* ("Other License"), formally executed by you and Linden Lab.  Terms of
+* the GPL can be found in doc/GPL-license.txt in this distribution, or
+* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+* 
+* There are special exceptions to the terms and conditions of the GPL as
+* it is applied to this Source Code. View the full text of the exception
+* in the file doc/FLOSS-exception.txt in this software distribution, or
+* online at http://secondlifegrid.net/programs/open_source/licensing/flossexception
+* 
+* By copying, modifying or distributing this software, you acknowledge
+* that you have read and understood your obligations described above,
+* and agree to abide by those obligations.
+* 
+* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+* COMPLETENESS OR PERFORMANCE.
+* $/LicenseInfo$
+*/
+
+#include "linden_common.h"
+#include "lluictrlfactory.h"
+#include "lldir.h"
+#include "llsdserialize.h"
+
+#include "llnotifications.h"
+
+#include <algorithm>
+#include <boost/regex.hpp>
+
+
+const std::string NOTIFICATION_PERSIST_VERSION = "0.93";
+
+// local channel for notification history
+class LLNotificationHistoryChannel : public LLNotificationChannel
+{
+	LOG_CLASS(LLNotificationHistoryChannel);
+public:
+	LLNotificationHistoryChannel(const std::string& filename) : 
+		LLNotificationChannel("History", "Visible", &historyFilter),
+		mFileName(filename)
+	{
+		connectChanged(boost::bind(&LLNotificationHistoryChannel::historyHandler, this, _1));
+		loadPersistentNotifications();
+	}
+
+private:
+	bool historyHandler(const LLSD& payload)
+	{
+		// we ignore "load" messages, but rewrite the persistence file on any other
+		std::string sigtype = payload["sigtype"];
+		if (sigtype != "load")
+		{
+			savePersistentNotifications();
+		}
+		return false;
+	}
+
+	// The history channel gets all notifications except those that have been cancelled
+	static bool historyFilter(LLNotificationPtr pNotification)
+	{
+		return !pNotification->isCancelled();
+	}
+
+	void savePersistentNotifications()
+	{
+		llinfos << "Saving open notifications to " << mFileName << llendl;
+
+		llofstream notify_file(mFileName.c_str());
+		if (!notify_file.is_open()) 
+		{
+			llwarns << "Failed to open " << mFileName << llendl;
+			return;
+		}
+
+		LLSD output;
+		output["version"] = NOTIFICATION_PERSIST_VERSION;
+		LLSD& data = output["data"];
+
+		for (LLNotificationSet::iterator it = mItems.begin(); it != mItems.end(); ++it)
+		{
+			if (!LLNotifications::instance().templateExists((*it)->getName())) continue;
+
+			// only store notifications flagged as persisting
+			LLNotificationTemplatePtr templatep = LLNotifications::instance().getTemplate((*it)->getName());
+			if (!templatep->mPersist) continue;
+
+			data.append((*it)->asLLSD());
+		}
+
+		LLPointer<LLSDFormatter> formatter = new LLSDXMLFormatter();
+		formatter->format(output, notify_file, LLSDFormatter::OPTIONS_PRETTY);
+	}
+
+	void loadPersistentNotifications()
+	{
+		llinfos << "Loading open notifications from " << mFileName << llendl;
+
+		llifstream notify_file(mFileName.c_str());
+		if (!notify_file.is_open()) 
+		{
+			llwarns << "Failed to open " << mFileName << llendl;
+			return;
+		}
+
+		LLSD input;
+		LLPointer<LLSDParser> parser = new LLSDXMLParser();
+		if (parser->parse(notify_file, input, LLSDSerialize::SIZE_UNLIMITED) < 0)
+		{
+			llwarns << "Failed to parse open notifications" << llendl;
+			return;
+		}
+
+		if (input.isUndefined()) return;
+		std::string version = input["version"];
+		if (version != NOTIFICATION_PERSIST_VERSION)
+		{
+			llwarns << "Bad open notifications version: " << version << llendl;
+			return;
+		}
+		LLSD& data = input["data"];
+		if (data.isUndefined()) return;
+
+		LLNotifications& instance = LLNotifications::instance();
+		for (LLSD::array_const_iterator notification_it = data.beginArray();
+			notification_it != data.endArray();
+			++notification_it)
+		{
+			instance.add(LLNotificationPtr(new LLNotification(*notification_it)));
+		}
+	}
+
+	//virtual
+	void onDelete(LLNotificationPtr pNotification)
+	{
+		// we want to keep deleted notifications in our log
+		mItems.insert(pNotification);
+		
+		return;
+	}
+	
+private:
+	std::string mFileName;
+};
+
+bool filterIgnoredNotifications(LLNotificationPtr notification)
+{
+	LLNotificationFormPtr form = notification->getForm();
+	// Check to see if the user wants to ignore this alert
+	if (form->getIgnoreType() != LLNotificationForm::IGNORE_NO)
+	{
+		return LLUI::sConfigGroup->getWarning(notification->getName());
+	}
+
+	return true;
+}
+
+bool handleIgnoredNotification(const LLSD& payload)
+{
+	if (payload["sigtype"].asString() == "add")
+	{
+		LLNotificationPtr pNotif = LLNotifications::instance().find(payload["id"].asUUID());
+		if (!pNotif) return false;
+
+		LLNotificationFormPtr form = pNotif->getForm();
+		LLSD response;
+		switch(form->getIgnoreType())
+		{
+		case LLNotificationForm::IGNORE_WITH_DEFAULT_RESPONSE:
+			response = pNotif->getResponseTemplate(LLNotification::WITH_DEFAULT_BUTTON);
+			break;
+		case LLNotificationForm::IGNORE_WITH_LAST_RESPONSE:
+			response = LLUI::sIgnoresGroup->getLLSD("Default" + pNotif->getName());
+			break;
+		case LLNotificationForm::IGNORE_SHOW_AGAIN:
+			break;
+		default:
+			return false;
+		}
+		pNotif->setIgnored(true);
+		pNotif->respond(response);
+		return true; 	// don't process this item any further
+	}
+	return false;
+}
+
+namespace LLNotificationFilters
+{
+	// a sample filter
+	bool includeEverything(LLNotificationPtr p)
+	{
+		return true;
+	}
+};
+
+LLNotificationForm::LLNotificationForm()
+:	mFormData(LLSD::emptyArray()),
+	mIgnore(IGNORE_NO)
+{
+}
+
+
+LLNotificationForm::LLNotificationForm(const std::string& name, const LLXMLNodePtr xml_node) 
+:	mFormData(LLSD::emptyArray()),
+	mIgnore(IGNORE_NO)
+{
+	if (!xml_node->hasName("form"))
+	{
+		llwarns << "Bad xml node for form: " << xml_node->getName() << llendl;
+	}
+	LLXMLNodePtr child = xml_node->getFirstChild();
+	while(child)
+	{
+		child = LLNotifications::instance().checkForXMLTemplate(child);
+
+		LLSD item_entry;
+		std::string element_name = child->getName()->mString;
+
+		if (element_name == "ignore")
+		{
+			bool save_option = false;
+			child->getAttribute_bool("save_option", save_option);
+			if (!save_option)
+			{
+				mIgnore = IGNORE_WITH_DEFAULT_RESPONSE;
+			}
+			else
+			{
+				// remember last option chosen by user and automatically respond with that in the future
+				mIgnore = IGNORE_WITH_LAST_RESPONSE;
+				LLUI::sIgnoresGroup->declareLLSD(std::string("Default") + name, "", std::string("Default response for notification " + name));
+			}
+			child->getAttributeString("text", mIgnoreMsg);
+			LLUI::sIgnoresGroup->addWarning(name);
+		}
+		else
+		{
+			// flatten xml form entry into single LLSD map with type==name
+			item_entry["type"] = element_name;
+			const LLXMLAttribList::iterator attrib_end = child->mAttributes.end();
+			for(LLXMLAttribList::iterator attrib_it = child->mAttributes.begin();
+				attrib_it != attrib_end;
+				++attrib_it)
+			{
+				item_entry[std::string(attrib_it->second->getName()->mString)] = attrib_it->second->getValue();
+			}
+			item_entry["value"] = child->getTextContents();
+			mFormData.append(item_entry);
+		}
+
+		child = child->getNextSibling();
+	}
+}
+
+LLNotificationForm::LLNotificationForm(const LLSD& sd)
+{
+	if (sd.isArray())
+	{
+		mFormData = sd;
+	}
+	else
+	{
+		llwarns << "Invalid form data " << sd << llendl;
+		mFormData = LLSD::emptyArray();
+	}
+}
+
+LLSD LLNotificationForm::asLLSD() const
+{ 
+	return mFormData; 
+}
+
+LLSD LLNotificationForm::getElement(const std::string& element_name)
+{
+	for (LLSD::array_const_iterator it = mFormData.beginArray();
+		it != mFormData.endArray();
+		++it)
+	{
+		if ((*it)["name"].asString() == element_name) return (*it);
+	}
+	return LLSD();
+}
+
+
+bool LLNotificationForm::hasElement(const std::string& element_name)
+{
+	for (LLSD::array_const_iterator it = mFormData.beginArray();
+		it != mFormData.endArray();
+		++it)
+	{
+		if ((*it)["name"].asString() == element_name) return true;
+	}
+	return false;
+}
+
+void LLNotificationForm::addElement(const std::string& type, const std::string& name, const LLSD& value)
+{
+	LLSD element;
+	element["type"] = type;
+	element["name"] = name;
+	element["label"] = name;
+	element["value"] = value;
+	element["index"] = mFormData.size();
+	mFormData.append(element);
+}
+
+void LLNotificationForm::append(const LLSD& sub_form)
+{
+	if (sub_form.isArray())
+	{
+		for (LLSD::array_const_iterator it = sub_form.beginArray();
+			it != sub_form.endArray();
+			++it)
+		{
+			mFormData.append(*it);
+		}
+	}
+}
+
+void LLNotificationForm::formatElements(const LLSD& substitutions)
+{
+	for (LLSD::array_iterator it = mFormData.beginArray();
+		it != mFormData.endArray();
+		++it)
+	{
+		// format "text" component of each form element
+		if ((*it).has("text"))
+		{
+			std::string text = (*it)["text"].asString();
+			text = LLNotification::format(text, substitutions);
+			(*it)["text"] = text;
+		}
+		if ((*it)["type"].asString() == "text" && (*it).has("value"))
+		{
+			std::string value = (*it)["value"].asString();
+			value = LLNotification::format(value, substitutions);
+			(*it)["value"] = value;
+		}
+	}
+}
+
+std::string LLNotificationForm::getDefaultOption()
+{
+	for (LLSD::array_const_iterator it = mFormData.beginArray();
+		it != mFormData.endArray();
+		++it)
+	{
+		if ((*it)["default"]) return (*it)["name"].asString();
+	}
+	return "";
+}
+
+LLNotificationTemplate::LLNotificationTemplate() :
+	mExpireSeconds(0),
+	mExpireOption(-1),
+	mURLOption(-1),
+	mUnique(false),
+	mPriority(NOTIFICATION_PRIORITY_NORMAL)
+{
+	mForm = LLNotificationFormPtr(new LLNotificationForm()); 
+}
+
+LLNotification::LLNotification(const LLNotification::Params& p) : 
+	mTimestamp(p.timestamp), 
+	mSubstitutions(p.substitutions),
+	mPayload(p.payload),
+	mExpiresAt(0),
+	mResponseFunctorName(p.functor_name),
+	mTemporaryResponder(p.mTemporaryResponder),
+	mRespondedTo(false),
+	mPriority(p.priority),
+	mCancelled(false),
+	mIgnored(false)
+{
+	mId.generate();
+	init(p.name, p.form_elements);
+}
+
+
+LLNotification::LLNotification(const LLSD& sd) :
+	mTemporaryResponder(false),
+	mRespondedTo(false),
+	mCancelled(false),
+	mIgnored(false)
+{ 
+	mId.generate();
+	mSubstitutions = sd["substitutions"];
+	mPayload = sd["payload"]; 
+	mTimestamp = sd["time"]; 
+	mExpiresAt = sd["expiry"];
+	mPriority = (ENotificationPriority)sd["priority"].asInteger();
+	mResponseFunctorName = sd["responseFunctor"].asString();
+	std::string templatename = sd["name"].asString();
+	init(templatename, LLSD());
+	// replace form with serialized version
+	mForm = LLNotificationFormPtr(new LLNotificationForm(sd["form"]));
+}
+
+
+LLSD LLNotification::asLLSD()
+{
+	LLSD output;
+	output["name"] = mTemplatep->mName;
+	output["form"] = getForm()->asLLSD();
+	output["substitutions"] = mSubstitutions;
+	output["payload"] = mPayload;
+	output["time"] = mTimestamp;
+	output["expiry"] = mExpiresAt;
+	output["priority"] = (S32)mPriority;
+	output["responseFunctor"] = mResponseFunctorName;
+	return output;
+}
+
+void LLNotification::update()
+{
+	LLNotifications::instance().update(shared_from_this());
+}
+
+void LLNotification::updateFrom(LLNotificationPtr other)
+{
+	// can only update from the same notification type
+	if (mTemplatep != other->mTemplatep) return;
+
+	// NOTE: do NOT change the ID, since it is the key to
+	// this given instance, just update all the metadata
+	//mId = other->mId;
+
+	mPayload = other->mPayload;
+	mSubstitutions = other->mSubstitutions;
+	mTimestamp = other->mTimestamp;
+	mExpiresAt = other->mExpiresAt;
+	mCancelled = other->mCancelled;
+	mIgnored = other->mIgnored;
+	mPriority = other->mPriority;
+	mForm = other->mForm;
+	mResponseFunctorName = other->mResponseFunctorName;
+	mRespondedTo = other->mRespondedTo;
+	mTemporaryResponder = other->mTemporaryResponder;
+
+	update();
+}
+
+const LLNotificationFormPtr LLNotification::getForm()
+{
+	return mForm;
+}
+
+void LLNotification::cancel()
+{
+	mCancelled = true;
+}
+
+LLSD LLNotification::getResponseTemplate(EResponseTemplateType type)
+{
+	LLSD response = LLSD::emptyMap();
+	for (S32 element_idx = 0;
+		element_idx < mForm->getNumElements();
+		++element_idx)
+	{
+		LLSD element = mForm->getElement(element_idx);
+		if (element.has("name"))
+		{
+			response[element["name"].asString()] = element["value"];
+		}
+
+		if ((type == WITH_DEFAULT_BUTTON) 
+			&& element["default"].asBoolean())
+		{
+			response[element["name"].asString()] = true;
+		}
+	}
+	return response;
+}
+
+//static
+S32 LLNotification::getSelectedOption(const LLSD& notification, const LLSD& response)
+{
+	LLNotificationForm form(notification["form"]);
+
+	for (S32 element_idx = 0;
+		element_idx < form.getNumElements();
+		++element_idx)
+	{
+		LLSD element = form.getElement(element_idx);
+
+		// only look at buttons
+		if (element["type"].asString() == "button" 
+			&& response[element["name"].asString()].asBoolean())
+		{
+			return element["index"].asInteger();
+		}
+	}
+
+	return -1;
+}
+
+//static
+std::string LLNotification::getSelectedOptionName(const LLSD& response)
+{
+	for (LLSD::map_const_iterator response_it = response.beginMap();
+		response_it != response.endMap();
+		++response_it)
+	{
+		if (response_it->second.isBoolean() && response_it->second.asBoolean())
+		{
+			return response_it->first;
+		}
+	}
+	return "";
+}
+
+
+void LLNotification::respond(const LLSD& response)
+{
+	mRespondedTo = true;
+	LLNotificationFunctorRegistry::instance().getFunctor(mResponseFunctorName)(asLLSD(), response);
+	if (mTemporaryResponder)
+	{
+		LLNotificationFunctorRegistry::instance().unregisterFunctor(mResponseFunctorName);
+		mResponseFunctorName = "";
+		mTemporaryResponder = false;
+	}
+
+	if (mForm->getIgnoreType() != LLNotificationForm::IGNORE_NO)
+	{
+		LLUI::sIgnoresGroup->setWarning(getName(), !mIgnored);
+		if (mIgnored && mForm->getIgnoreType() == LLNotificationForm::IGNORE_WITH_LAST_RESPONSE)
+		{
+			LLUI::sIgnoresGroup->setLLSD("Default" + getName(), response);
+		}
+	}
+
+	update();
+}
+
+void LLNotification::setIgnored(bool ignore)
+{
+	mIgnored = ignore;
+}
+
+void LLNotification::setResponseFunctor(std::string const &responseFunctorName)
+{
+	if (mTemporaryResponder)
+		// get rid of the old one
+		LLNotificationFunctorRegistry::instance().unregisterFunctor(mResponseFunctorName);
+	mResponseFunctorName = responseFunctorName;
+	mTemporaryResponder = false;
+}
+
+bool LLNotification::payloadContainsAll(const std::vector<std::string>& required_fields) const
+{
+	for(std::vector<std::string>::const_iterator required_fields_it = required_fields.begin(); 
+		required_fields_it != required_fields.end();
+		required_fields_it++)
+	{
+		std::string required_field_name = *required_fields_it;
+		if( ! getPayload().has(required_field_name))
+		{
+			return false; // a required field was not found
+		}
+	}
+	return true; // all required fields were found
+}
+
+bool LLNotification::isEquivalentTo(LLNotificationPtr that) const
+{
+	if (this->mTemplatep->mName != that->mTemplatep->mName) 
+	{
+		return false; // must have the same template name or forget it
+	}
+	if (this->mTemplatep->mUnique)
+	{
+		// highlander bit sez there can only be one of these
+		return
+			this->payloadContainsAll(that->mTemplatep->mUniqueContext) &&
+			that->payloadContainsAll(this->mTemplatep->mUniqueContext);
+	}
+	return false; 
+}
+
+void LLNotification::init(const std::string& template_name, const LLSD& form_elements)
+{
+	mTemplatep = LLNotifications::instance().getTemplate(template_name);
+	if (!mTemplatep) return;
+
+	// add default substitutions
+	// TODO: change this to read from the translatable strings file!
+	mSubstitutions["SECOND_LIFE"] = "Second Life";
+	mSubstitutions["_URL"] = getURL();
+	mSubstitutions["_NAME"] = template_name;
+	// TODO: something like this so that a missing alert is sensible:
+	//mSubstitutions["_ARGS"] = get_all_arguments_as_text(mSubstitutions);
+
+	mForm = LLNotificationFormPtr(new LLNotificationForm(*mTemplatep->mForm));
+	mForm->append(form_elements);
+
+	// apply substitution to form labels
+	mForm->formatElements(mSubstitutions);
+
+	LLDate rightnow = LLDate::now();
+	if (mTemplatep->mExpireSeconds)
+	{
+		mExpiresAt = LLDate(rightnow.secondsSinceEpoch() + mTemplatep->mExpireSeconds);
+	}
+
+	if (mPriority == NOTIFICATION_PRIORITY_UNSPECIFIED)
+	{
+		mPriority = mTemplatep->mPriority;
+	}
+}
+
+std::string LLNotification::summarize() const
+{
+	std::string s = "Notification(";
+	s += getName();
+	s += ") : ";
+	s += mTemplatep ? mTemplatep->mMessage : "";
+	// should also include timestamp and expiration time (but probably not payload)
+	return s;
+}
+
+//static
+std::string LLNotification::format(const std::string& s, const LLSD& substitutions)
+{
+	if (!substitutions.isMap()) 
+	{
+		return s;
+	}
+
+	std::ostringstream output;
+	// match strings like [NAME]
+	const boost::regex key("\\[([0-9_A-Z]+)]");
+	
+	std::string::const_iterator start = s.begin();
+	std::string::const_iterator end = s.end();
+	boost::smatch match;
+	
+	while (boost::regex_search(start, end, match, key, boost::match_default))
+	{
+		bool found_replacement = false;
+		std::string replacement;
+		
+		// see if we have a replacement for the bracketed string (without the brackets)
+		// test first using has() because if we just look up with operator[] we get back an
+		// empty string even if the value is missing. We want to distinguish between 
+		// missing replacements and deliberately empty replacement strings.
+		if (substitutions.has(std::string(match[1].first, match[1].second)))
+		{
+			replacement = substitutions[std::string(match[1].first, match[1].second)].asString();
+			found_replacement = true;
+		}
+		// if not, see if there's one WITH brackets
+		else if (substitutions.has(std::string(match[0].first, match[0].second)))
+		{
+			replacement = substitutions[std::string(match[0].first, match[0].second)].asString();
+			found_replacement = true;
+		}
+		
+		if (found_replacement)
+		{
+			// found a replacement
+			// "hello world" is output
+			output << std::string(start, match[0].first) << replacement;
+		}
+		else
+		{
+			// we had no replacement, so leave the string we searched for so that it gets noticed by QA
+			// "hello [NAME_NOT_FOUND]" is output
+			output << std::string(start, match[0].second);
+		}
+		
+		// update search position 
+		start = match[0].second; 
+	}
+	// send the remainder of the string (with no further matches for bracketed names)
+	output << std::string(start, end);
+	return output.str();
+}
+
+std::string LLNotification::getMessage() const
+{
+	// all our callers cache this result, so it gives us more flexibility
+	// to do the substitution at call time rather than attempting to 
+	// cache it in the notification
+	if (!mTemplatep)
+		return std::string();
+	return format(mTemplatep->mMessage, mSubstitutions);
+}
+
+std::string LLNotification::getLabel() const
+{
+	return (mTemplatep ? format(mTemplatep->mLabel, mSubstitutions) : "");
+}
+
+
+
+// =========================================================
+// LLNotificationChannel implementation
+// ---
+void LLNotificationChannelBase::connectChanged(const LLStandardSignal::slot_type& slot)
+{
+	// when someone wants to connect to a channel, we first throw them
+	// all of the notifications that are already in the channel
+	// we use a special signal called "load" in case the channel wants to care
+	// only about new notifications
+	for (LLNotificationSet::iterator it = mItems.begin(); it != mItems.end(); ++it)
+	{
+		slot.get_slot_function()(LLSD().insert("sigtype", "load").insert("id", (*it)->id()));
+	}
+	// and then connect the signal so that all future notifications will also be
+	// forwarded.
+	mChanged.connect(slot);
+}
+
+void LLNotificationChannelBase::connectPassedFilter(const LLStandardSignal::slot_type& slot)
+{
+	// these two filters only fire for notifications added after the current one, because
+	// they don't participate in the hierarchy.
+	mPassedFilter.connect(slot);
+}
+
+void LLNotificationChannelBase::connectFailedFilter(const LLStandardSignal::slot_type& slot)
+{
+	mFailedFilter.connect(slot);
+}
+
+// external call, conforms to our standard signature
+bool LLNotificationChannelBase::updateItem(const LLSD& payload)
+{	
+	// first check to see if it's in the master list
+	LLNotificationPtr pNotification	 = LLNotifications::instance().find(payload["id"]);
+	if (!pNotification)
+		return false;	// not found
+	
+	return updateItem(payload, pNotification);
+}
+
+
+//FIX QUIT NOT WORKING
+
+
+// internal call, for use in avoiding lookup
+bool LLNotificationChannelBase::updateItem(const LLSD& payload, LLNotificationPtr pNotification)
+{	
+	std::string cmd = payload["sigtype"];
+	LLNotificationSet::iterator foundItem = mItems.find(pNotification);
+	bool wasFound = (foundItem != mItems.end());
+	bool passesFilter = mFilter(pNotification);
+	
+	// first, we offer the result of the filter test to the simple
+	// signals for pass/fail. One of these is guaranteed to be called.
+	// If either signal returns true, the change processing is NOT performed
+	// (so don't return true unless you know what you're doing!)
+	bool abortProcessing = false;
+	if (passesFilter)
+	{
+		abortProcessing = mPassedFilter(payload);
+	}
+	else
+	{
+		abortProcessing = mFailedFilter(payload);
+	}
+	
+	if (abortProcessing)
+	{
+		return true;
+	}
+	
+	if (cmd == "load")
+	{
+		// should be no reason we'd ever get a load if we already have it
+		// if passes filter send a load message, else do nothing
+		assert(!wasFound);
+		if (passesFilter)
+		{
+			// not in our list, add it and say so
+			mItems.insert(pNotification);
+			abortProcessing = mChanged(payload);
+			onLoad(pNotification);
+		}
+	}
+	else if (cmd == "change")
+	{
+		// if it passes filter now and was found, we just send a change message
+		// if it passes filter now and wasn't found, we have to add it
+		// if it doesn't pass filter and wasn't found, we do nothing
+		// if it doesn't pass filter and was found, we need to delete it
+		if (passesFilter)
+		{
+			if (wasFound)
+			{
+				// it already existed, so this is a change
+				// since it changed in place, all we have to do is resend the signal
+				abortProcessing = mChanged(payload);
+				onChange(pNotification);
+			}
+			else
+			{
+				// not in our list, add it and say so
+				mItems.insert(pNotification);
+				// our payload is const, so make a copy before changing it
+				LLSD newpayload = payload;
+				newpayload["sigtype"] = "add";
+				abortProcessing = mChanged(newpayload);
+				onChange(pNotification);
+			}
+		}
+		else
+		{
+			if (wasFound)
+			{
+				// it already existed, so this is a delete
+				mItems.erase(pNotification);
+				// our payload is const, so make a copy before changing it
+				LLSD newpayload = payload;
+				newpayload["sigtype"] = "delete";
+				abortProcessing = mChanged(newpayload);
+				onChange(pNotification);
+			}
+			// didn't pass, not on our list, do nothing
+		}
+	}
+	else if (cmd == "add")
+	{
+		// should be no reason we'd ever get an add if we already have it
+		// if passes filter send an add message, else do nothing
+		assert(!wasFound);
+		if (passesFilter)
+		{
+			// not in our list, add it and say so
+			mItems.insert(pNotification);
+			abortProcessing = mChanged(payload);
+			onAdd(pNotification);
+		}
+	}
+	else if (cmd == "delete")
+	{
+		// if we have it in our list, pass on the delete, then delete it, else do nothing
+		if (wasFound)
+		{
+			abortProcessing = mChanged(payload);
+			mItems.erase(pNotification);
+			onDelete(pNotification);
+		}
+	}
+	return abortProcessing;
+}
+
+LLNotificationChannel::LLNotificationChannel(const std::string& name, 
+											 const std::string& parent,
+											 LLNotificationFilter filter, 
+											 LLNotificationComparator comparator) : 
+LLNotificationChannelBase(filter, comparator),
+mName(name),
+mParent(parent)
+{
+	// store myself in the channel map
+	LLNotifications::instance().addChannel(LLNotificationChannelPtr(this));
+	// bind to notification broadcast
+	if (parent.empty())
+	{
+		LLNotifications::instance().connectChanged(
+			boost::bind(&LLNotificationChannelBase::updateItem, this, _1));
+	}
+	else
+	{
+		LLNotificationChannelPtr p = LLNotifications::instance().getChannel(parent);
+		LLStandardSignal::slot_type f = boost::bind(&LLNotificationChannelBase::updateItem, this, _1);
+		p->connectChanged(f);
+	}
+}
+
+
+void LLNotificationChannel::setComparator(LLNotificationComparator comparator) 
+{ 
+	mComparator = comparator; 
+	LLNotificationSet s2(mComparator);
+	s2.insert(mItems.begin(), mItems.end());
+	mItems.swap(s2);
+	
+	// notify clients that we've been resorted
+	mChanged(LLSD().insert("sigtype", "sort")); 
+}
+
+bool LLNotificationChannel::isEmpty() const
+{
+	return mItems.empty();
+}
+
+LLNotificationChannel::Iterator LLNotificationChannel::begin()
+{
+	return mItems.begin();
+}
+
+LLNotificationChannel::Iterator LLNotificationChannel::end()
+{
+	return mItems.end();
+}
+
+std::string LLNotificationChannel::summarize()
+{
+	std::string s("Channel '");
+	s += mName;
+	s += "'\n  ";
+	for (LLNotificationChannel::Iterator it = begin(); it != end(); ++it)
+	{
+		s += (*it)->summarize();
+		s += "\n  ";
+	}
+	return s;
+}
+
+
+// ---
+// END OF LLNotificationChannel implementation
+// =========================================================
+
+
+// =========================================================
+// LLNotifications implementation
+// ---
+LLNotifications::LLNotifications() : LLNotificationChannelBase(LLNotificationFilters::includeEverything,
+															   LLNotificationComparators::orderByUUID())
+{
+}
+
+
+// The expiration channel gets all notifications that are cancelled
+bool LLNotifications::expirationFilter(LLNotificationPtr pNotification)
+{
+	return pNotification->isCancelled() || pNotification->isRespondedTo();
+}
+
+bool LLNotifications::expirationHandler(const LLSD& payload)
+{
+	if (payload["sigtype"].asString() != "delete")
+	{
+		// anything added to this channel actually should be deleted from the master
+		cancel(find(payload["id"]));
+		return true;	// don't process this item any further
+	}
+	return false;
+}
+
+bool LLNotifications::uniqueFilter(LLNotificationPtr pNotif)
+{
+	if (!pNotif->hasUniquenessConstraints())
+	{
+		return true;
+	}
+
+	// checks against existing unique notifications
+	for (LLNotificationMap::iterator existing_it = mUniqueNotifications.find(pNotif->getName());
+		existing_it != mUniqueNotifications.end();
+		++existing_it)
+	{
+		LLNotificationPtr existing_notification = existing_it->second;
+		if (pNotif != existing_notification 
+			&& pNotif->isEquivalentTo(existing_notification))
+		{
+			return false;
+		}
+	}
+
+	return true;
+}
+
+bool LLNotifications::uniqueHandler(const LLSD& payload)
+{
+	LLNotificationPtr pNotif = LLNotifications::instance().find(payload["id"].asUUID());
+	if (pNotif && pNotif->hasUniquenessConstraints()) 
+	{
+		if (payload["sigtype"].asString() == "add")
+		{
+			// not a duplicate according to uniqueness criteria, so we keep it
+			// and store it for future uniqueness checks
+			mUniqueNotifications.insert(std::make_pair(pNotif->getName(), pNotif));
+		}
+		else if (payload["sigtype"].asString() == "delete")
+		{
+			mUniqueNotifications.erase(pNotif->getName());
+		}
+	}
+
+	return false;
+}
+
+bool LLNotifications::failedUniquenessTest(const LLSD& payload)
+{
+	LLNotificationPtr pNotif = LLNotifications::instance().find(payload["id"].asUUID());
+	
+	if (!pNotif || !pNotif->hasUniquenessConstraints())
+	{
+		return false;
+	}
+
+	// checks against existing unique notifications
+	for (LLNotificationMap::iterator existing_it = mUniqueNotifications.find(pNotif->getName());
+		existing_it != mUniqueNotifications.end();
+		++existing_it)
+	{
+		LLNotificationPtr existing_notification = existing_it->second;
+		if (pNotif != existing_notification 
+			&& pNotif->isEquivalentTo(existing_notification))
+		{
+			// copy notification instance data over to oldest instance
+			// of this unique notification and update it
+			existing_notification->updateFrom(pNotif);
+			// then delete the new one
+			pNotif->cancel();
+		}
+	}
+
+	return false;
+}
+
+
+void LLNotifications::addChannel(LLNotificationChannelPtr pChan)
+{
+	mChannels[pChan->getName()] = pChan;
+}
+
+LLNotificationChannelPtr LLNotifications::getChannel(const std::string& channelName)
+{
+	ChannelMap::iterator p = mChannels.find(channelName);
+	if(p == mChannels.end())
+	{
+		llerrs << "Did not find channel named " << channelName << llendl;
+	}
+	return p->second;
+}
+
+
+// this function is called once at construction time, after the object is constructed.
+void LLNotifications::initSingleton()
+{
+	loadTemplates();
+	createDefaultChannels();
+}
+
+void LLNotifications::createDefaultChannels()
+{
+	// now construct the various channels AFTER loading the notifications,
+	// because the history channel is going to rewrite the stored notifications file
+	new LLNotificationChannel("Expiration", "",
+		boost::bind(&LLNotifications::expirationFilter, this, _1));
+	new LLNotificationChannel("Unexpired", "",
+		!boost::bind(&LLNotifications::expirationFilter, this, _1)); // use negated bind
+	new LLNotificationChannel("Unique", "Unexpired",
+		boost::bind(&LLNotifications::uniqueFilter, this, _1));
+	new LLNotificationChannel("Ignore", "Unique",
+		filterIgnoredNotifications);
+	new LLNotificationChannel("Visible", "Ignore",
+		&LLNotificationFilters::includeEverything);
+
+	// create special history channel
+	//std::string notifications_log_file = gDirUtilp->getExpandedFilename ( LL_PATH_PER_SL_ACCOUNT, "open_notifications.xml" );
+	// use ^^^ when done debugging notifications serialization
+	std::string notifications_log_file = gDirUtilp->getExpandedFilename ( LL_PATH_USER_SETTINGS, "open_notifications.xml" );
+	new LLNotificationHistoryChannel(notifications_log_file);
+
+	// connect action methods to these channels
+	LLNotifications::instance().getChannel("Expiration")->
+		connectChanged(boost::bind(&LLNotifications::expirationHandler, this, _1));
+	LLNotifications::instance().getChannel("Unique")->
+		connectChanged(boost::bind(&LLNotifications::uniqueHandler, this, _1));
+	LLNotifications::instance().getChannel("Unique")->
+		connectFailedFilter(boost::bind(&LLNotifications::failedUniquenessTest, this, _1));
+	LLNotifications::instance().getChannel("Ignore")->
+		connectFailedFilter(&handleIgnoredNotification);
+}
+
+static std::string sStringSkipNextTime("Skip this dialog next time");
+static std::string sStringAlwaysChoose("Always choose this option");
+
+bool LLNotifications::addTemplate(const std::string &name, 
+								  LLNotificationTemplatePtr theTemplate)
+{
+	if (mTemplates.count(name))
+	{
+		llwarns << "LLNotifications -- attempted to add template '" << name << "' twice." << llendl;
+		return false;
+	}
+	mTemplates[name] = theTemplate;
+	return true;
+}
+
+LLNotificationTemplatePtr LLNotifications::getTemplate(const std::string& name)
+{
+	if (mTemplates.count(name))
+	{
+		return mTemplates[name];
+	}
+	else
+	{
+		return mTemplates["MissingAlert"];
+	}
+}
+
+bool LLNotifications::templateExists(const std::string& name)
+{
+	return (mTemplates.count(name) != 0);
+}
+
+void LLNotifications::clearTemplates()
+{
+	mTemplates.clear();
+}
+
+void LLNotifications::forceResponse(const LLNotification::Params& params, S32 option)
+{
+	LLNotificationPtr temp_notify(new LLNotification(params));
+	LLSD response = temp_notify->getResponseTemplate();
+	LLSD selected_item = temp_notify->getForm()->getElement(option);
+	
+	if (selected_item.isUndefined())
+	{
+		llwarns << "Invalid option" << option << " for notification " << (std::string)params.name << llendl;
+		return;
+	}
+	response[selected_item["name"].asString()] = true;
+
+	temp_notify->respond(response);
+}
+
+LLNotifications::TemplateNames LLNotifications::getTemplateNames() const
+{
+	TemplateNames names;
+	for (TemplateMap::const_iterator it = mTemplates.begin(); it != mTemplates.end(); ++it)
+	{
+		names.push_back(it->first);
+	}
+	return names;
+}
+
+typedef std::map<std::string, std::string> StringMap;
+void replaceSubstitutionStrings(LLXMLNodePtr node, StringMap& replacements)
+{
+	//llwarns << "replaceSubstitutionStrings" << llendl;
+	// walk the list of attributes looking for replacements
+	for (LLXMLAttribList::iterator it=node->mAttributes.begin();
+		 it != node->mAttributes.end(); ++it)
+	{
+		std::string value = it->second->getValue();
+		if (value[0] == '$')
+		{
+			value.erase(0, 1);	// trim off the $
+			std::string replacement;
+			StringMap::const_iterator found = replacements.find(value);
+			if (found != replacements.end())
+			{
+				replacement = found->second;
+				//llwarns << "replaceSubstituionStrings: value: " << value << " repl: " << replacement << llendl;
+
+				it->second->setValue(replacement);
+			}
+			else
+			{
+				llwarns << "replaceSubstituionStrings FAILURE: value: " << value << " repl: " << replacement << llendl;
+			}
+		}
+	}
+	
+	// now walk the list of children and call this recursively.
+	for (LLXMLNodePtr child = node->getFirstChild(); 
+		 child.notNull(); child = child->getNextSibling())
+	{
+		replaceSubstitutionStrings(child, replacements);
+	}
+}
+
+// private to this file
+// returns true if the template request was invalid and there's nothing else we
+// can do with this node, false if you should keep processing (it may have
+// replaced the contents of the node referred to)
+LLXMLNodePtr LLNotifications::checkForXMLTemplate(LLXMLNodePtr item)
+{
+	if (item->hasName("usetemplate"))
+	{
+		std::string replacementName;
+		if (item->getAttributeString("name", replacementName))
+		{
+			StringMap replacements;
+			for (LLXMLAttribList::const_iterator it=item->mAttributes.begin(); 
+				 it != item->mAttributes.end(); ++it)
+			{
+				replacements[it->second->getName()->mString] = it->second->getValue();
+			}
+			if (mXmlTemplates.count(replacementName))
+			{
+				item=LLXMLNode::replaceNode(item, mXmlTemplates[replacementName]);
+				
+				// walk the nodes looking for $(substitution) here and replace
+				replaceSubstitutionStrings(item, replacements);
+			}
+			else
+			{
+				llwarns << "XML template lookup failure on '" << replacementName << "' " << llendl;
+			}
+		}
+	}
+	return item;
+}
+
+bool LLNotifications::loadTemplates()
+{
+	const std::string xml_filename = "notifications.xml";
+	LLXMLNodePtr root;
+	
+	BOOL success  = LLUICtrlFactory::getLayeredXMLNode(xml_filename, root);
+	
+	if (!success || root.isNull() || !root->hasName( "notifications" ))
+	{
+		llerrs << "Problem reading UI Notifications file: " << xml_filename << llendl;
+		return false;
+	}
+	
+	clearTemplates();
+	
+	for (LLXMLNodePtr item = root->getFirstChild();
+		 item.notNull(); item = item->getNextSibling())
+	{
+		// we do this FIRST so that item can be changed if we 
+		// encounter a usetemplate -- we just replace the
+		// current xml node and keep processing
+		item = checkForXMLTemplate(item);
+		
+		if (item->hasName("global"))
+		{
+			std::string global_name;
+			if (item->getAttributeString("name", global_name))
+			{
+				mGlobalStrings[global_name] = item->getTextContents();
+			}
+			continue;
+		}
+		
+		if (item->hasName("template"))
+		{
+			// store an xml template; templates must have a single node (can contain
+			// other nodes)
+			std::string name;
+			item->getAttributeString("name", name);
+			LLXMLNodePtr ptr = item->getFirstChild();
+			mXmlTemplates[name] = ptr;
+			continue;
+		}
+		
+		if (!item->hasName("notification"))
+		{
+            llwarns << "Unexpected entity " << item->getName()->mString << 
+                       " found in " << xml_filename << llendl;
+			continue;
+		}
+		
+		// now we know we have a notification entry, so let's build it
+		LLNotificationTemplatePtr pTemplate(new LLNotificationTemplate());
+
+		if (!item->getAttributeString("name", pTemplate->mName))
+		{
+			llwarns << "Unable to parse notification with no name" << llendl;
+			continue;
+		}
+		
+		//llinfos << "Parsing " << pTemplate->mName << llendl;
+		
+		pTemplate->mMessage = item->getTextContents();
+		pTemplate->mDefaultFunctor = pTemplate->mName;
+		item->getAttributeString("type", pTemplate->mType);
+		item->getAttributeString("icon", pTemplate->mIcon);
+		item->getAttributeString("label", pTemplate->mLabel);
+		item->getAttributeU32("duration", pTemplate->mExpireSeconds);
+		item->getAttributeU32("expireOption", pTemplate->mExpireOption);
+
+		std::string priority;
+		item->getAttributeString("priority", priority);
+		pTemplate->mPriority = NOTIFICATION_PRIORITY_NORMAL;
+		if (!priority.empty())
+		{
+			if (priority == "low")      pTemplate->mPriority = NOTIFICATION_PRIORITY_LOW;
+			if (priority == "normal")   pTemplate->mPriority = NOTIFICATION_PRIORITY_NORMAL;
+			if (priority == "high")     pTemplate->mPriority = NOTIFICATION_PRIORITY_HIGH;
+			if (priority == "critical") pTemplate->mPriority = NOTIFICATION_PRIORITY_CRITICAL;
+		}
+		
+		item->getAttributeString("functor", pTemplate->mDefaultFunctor);
+
+		BOOL persist = false;
+		item->getAttributeBOOL("persist", persist);
+		pTemplate->mPersist = persist;
+		
+		std::string sound;
+		item->getAttributeString("sound", sound);
+		if (!sound.empty())
+		{
+			// TODO: test for bad sound effect name / missing effect
+			pTemplate->mSoundEffect = LLUUID(LLUI::sConfigGroup->getString(sound.c_str()));
+		}
+
+		for (LLXMLNodePtr child = item->getFirstChild();
+			 !child.isNull(); child = child->getNextSibling())
+		{
+			child = checkForXMLTemplate(child);
+			
+			// <url>
+			if (child->hasName("url"))
+			{
+				pTemplate->mURL = child->getTextContents();
+				child->getAttributeU32("option", pTemplate->mURLOption);
+			}
+			
+            if (child->hasName("unique"))
+            {
+                pTemplate->mUnique = true;
+                for (LLXMLNodePtr formitem = child->getFirstChild();
+                     !formitem.isNull(); formitem = formitem->getNextSibling())
+                {
+                    if (formitem->hasName("context"))
+                    {
+                        std::string key;
+                        formitem->getAttributeString("key", key);
+                        pTemplate->mUniqueContext.push_back(key);
+                        //llwarns << "adding " << key << " to unique context" << llendl;
+                    }
+                    else
+                    {
+                        llwarns << "'unique' has unrecognized subelement " 
+                        << formitem->getName()->mString << llendl;
+                    }
+                }
+            }
+            
+			// <form>
+			if (child->hasName("form"))
+			{
+                pTemplate->mForm = LLNotificationFormPtr(new LLNotificationForm(pTemplate->mName, child));
+			}
+		}
+		addTemplate(pTemplate->mName, pTemplate);
+	}
+	
+	//std::ostringstream ostream;
+	//root->writeToOstream(ostream, "\n  ");
+	//llwarns << ostream.str() << llendl;
+	
+	return true;
+}
+
+// we provide a couple of simple add notification functions so that it's reasonable to create notifications in one line
+LLNotificationPtr LLNotifications::add(const std::string& name, 
+										const LLSD& substitutions, 
+										const LLSD& payload)
+{
+	return add(LLNotification::Params(name).substitutions(substitutions).payload(payload));	
+}
+
+LLNotificationPtr LLNotifications::add(const std::string& name, 
+										const LLSD& substitutions, 
+										const LLSD& payload, 
+										const std::string& functor_name)
+{
+	return add(LLNotification::Params(name).substitutions(substitutions).payload(payload).functor_name(functor_name));	
+}
+
+LLNotificationPtr LLNotifications::add(const std::string& name, 
+										const LLSD& substitutions, 
+										const LLSD& payload, 
+										LLNotificationFunctorRegistry::ResponseFunctor functor)
+{
+	return add(LLNotification::Params(name).substitutions(substitutions).payload(payload).functor(functor));	
+}
+
+// generalized add function that takes a parameter block object for more complex instantiations
+LLNotificationPtr LLNotifications::add(const LLNotification::Params& p)
+{
+	LLNotificationPtr pNotif(new LLNotification(p));
+	add(pNotif);
+	return pNotif;
+}
+
+
+void LLNotifications::add(const LLNotificationPtr pNotif)
+{
+	// first see if we already have it -- if so, that's a problem
+	LLNotificationSet::iterator it=mItems.find(pNotif);
+	if (it != mItems.end())
+	{
+		llerrs << "Notification added a second time to the master notification channel." << llendl;
+	}
+
+	updateItem(LLSD().insert("sigtype", "add").insert("id", pNotif->id()), pNotif);
+}
+
+void LLNotifications::cancel(LLNotificationPtr pNotif)
+{
+	LLNotificationSet::iterator it=mItems.find(pNotif);
+	if (it == mItems.end())
+	{
+		llerrs << "Attempted to delete nonexistent notification " << pNotif->getName() << llendl;
+	}
+	updateItem(LLSD().insert("sigtype", "delete").insert("id", pNotif->id()), pNotif);
+	pNotif->cancel();
+}
+
+void LLNotifications::update(const LLNotificationPtr pNotif)
+{
+	LLNotificationSet::iterator it=mItems.find(pNotif);
+	if (it != mItems.end())
+	{
+		updateItem(LLSD().insert("sigtype", "change").insert("id", pNotif->id()), pNotif);
+	}
+}
+
+
+LLNotificationPtr LLNotifications::find(LLUUID uuid)
+{
+	LLNotificationPtr target = LLNotificationPtr(new LLNotification(uuid));
+	LLNotificationSet::iterator it=mItems.find(target);
+	if (it == mItems.end())
+	{
+		llwarns << "Tried to dereference uuid '" << uuid << "' as a notification key but didn't find it." << llendl;
+		return LLNotificationPtr((LLNotification*)NULL);
+	}
+	else
+	{
+		return *it;
+	}
+}
+
+void LLNotifications::forEachNotification(NotificationProcess process)
+{
+	std::for_each(mItems.begin(), mItems.end(), process);
+}
+
+std::string LLNotifications::getGlobalString(const std::string& key) const
+{
+	GlobalStringMap::const_iterator it = mGlobalStrings.find(key);
+	if (it != mGlobalStrings.end())
+	{
+		return it->second;
+	}
+	else
+	{
+		// if we don't have the key as a global, return the key itself so that the error
+		// is self-diagnosing.
+		return key;
+	}
+}
+
+													
+// ---
+// END OF LLNotifications implementation
+// =========================================================
+
+std::ostream& operator<<(std::ostream& s, const LLNotification& notification)
+{
+	s << notification.summarize();
+	return s;
+}
+
diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h
new file mode 100644
index 00000000000..2a2003f4991
--- /dev/null
+++ b/indra/llui/llnotifications.h
@@ -0,0 +1,892 @@
+/**
+* @file llnotifications.h
+* @brief Non-UI manager and support for keeping a prioritized list of notifications
+* @author Q (with assistance from Richard and Coco)
+*
+* $LicenseInfo:firstyear=2008&license=viewergpl$
+* 
+* Copyright (c) 2008, Linden Research, Inc.
+* 
+* Second Life Viewer Source Code
+* The source code in this file ("Source Code") is provided by Linden Lab
+* to you under the terms of the GNU General Public License, version 2.0
+* ("GPL"), unless you have obtained a separate licensing agreement
+* ("Other License"), formally executed by you and Linden Lab.  Terms of
+* the GPL can be found in doc/GPL-license.txt in this distribution, or
+* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+* 
+* There are special exceptions to the terms and conditions of the GPL as
+* it is applied to this Source Code. View the full text of the exception
+* in the file doc/FLOSS-exception.txt in this software distribution, or
+* online at http://secondlifegrid.net/programs/open_source/licensing/flossexception
+* 
+* By copying, modifying or distributing this software, you acknowledge
+* that you have read and understood your obligations described above,
+* and agree to abide by those obligations.
+* 
+* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+* COMPLETENESS OR PERFORMANCE.
+* $/LicenseInfo$
+*/
+
+#ifndef LL_LLNOTIFICATIONS_H
+#define LL_LLNOTIFICATIONS_H
+
+/**
+ * This system is intended to provide a singleton mechanism for adding
+ * notifications to one of an arbitrary set of event channels.
+ * 
+ * Controlling JIRA: DEV-9061
+ *
+ * Every notification has (see code for full list):
+ *  - a textual name, which is used to look up its template in the XML files
+ *  - a payload, which is a block of LLSD
+ *  - a channel, which is normally extracted from the XML files but
+ *	  can be overridden.
+ *  - a timestamp, used to order the notifications
+ *  - expiration time -- if nonzero, specifies a time after which the
+ *    notification will no longer be valid.
+ *  - a callback name and a couple of status bits related to callbacks (see below)
+ * 
+ * There is a management class called LLNotifications, which is an LLSingleton.
+ * The class maintains a collection of all of the notifications received
+ * or processed during this session, and also manages the persistence
+ * of those notifications that must be persisted.
+ * 
+ * We also have Channels. A channel is a view on a collection of notifications;
+ * The collection is defined by a filter function that controls which
+ * notifications are in the channel, and its ordering is controlled by 
+ * a comparator. 
+ *
+ * There is a hierarchy of channels; notifications flow down from
+ * the management class (LLNotifications, which itself inherits from
+ * The channel base class) to the individual channels.
+ * Any change to notifications (add, delete, modify) is 
+ * automatically propagated through the channel hierarchy.
+ * 
+ * We provide methods for adding a new notification, for removing
+ * one, and for managing channels. Channels are relatively cheap to construct
+ * and maintain, so in general, human interfaces should use channels to
+ * select and manage their lists of notifications.
+ * 
+ * We also maintain a collection of templates that are loaded from the 
+ * XML file of template translations. The system supports substitution
+ * of named variables from the payload into the XML file.
+ * 
+ * By default, only the "unknown message" template is built into the system.
+ * It is not an error to add a notification that's not found in the 
+ * template system, but it is logged.
+ *
+ */
+
+#include <string>
+#include <list>
+#include <vector>
+#include <map>
+#include <set>
+#include <iomanip>
+#include <sstream>
+
+#include <boost/utility.hpp>
+#include <boost/shared_ptr.hpp>
+#include <boost/signal.hpp>
+#include <boost/type_traits.hpp>
+
+// we want to minimize external dependencies, but this one is important
+#include "llsd.h"
+
+// and we need this to manage the notification callbacks
+#include "llfunctorregistry.h"
+#include "llui.h"
+
+class LLNotification;
+typedef boost::shared_ptr<LLNotification> LLNotificationPtr;
+
+/*****************************************************************************
+*   Signal and handler declarations
+*   Using a single handler signature means that we can have a common handler
+*   type, rather than needing a distinct one for each different handler.
+*****************************************************************************/
+
+/**
+ * A boost::signals Combiner that stops the first time a handler returns true
+ * We need this because we want to have our handlers return bool, so that
+ * we have the option to cause a handler to stop further processing. The
+ * default handler fails when the signal returns a value but has no slots.
+ */
+struct LLStopWhenHandled
+{
+    typedef bool result_type;
+
+    template<typename InputIterator>
+    result_type operator()(InputIterator first, InputIterator last) const
+    {
+        for (InputIterator si = first; si != last; ++si)
+		{
+            if (*si)
+			{
+                return true;
+			}
+		}
+        return false;
+    }
+};
+
+	
+typedef enum e_notification_priority
+{
+	NOTIFICATION_PRIORITY_UNSPECIFIED,
+	NOTIFICATION_PRIORITY_LOW,
+	NOTIFICATION_PRIORITY_NORMAL,
+	NOTIFICATION_PRIORITY_HIGH,
+	NOTIFICATION_PRIORITY_CRITICAL
+} ENotificationPriority;
+
+/**
+ * We want to have a standard signature for all signals; this way,
+ * we can easily document a protocol for communicating across
+ * dlls and into scripting languages someday.
+ * we want to return a bool to indicate whether the signal has been
+ * handled and should NOT be passed on to other listeners.
+ * Return true to stop further handling of the signal, and false
+ * to continue.
+ * We take an LLSD because this way the contents of the signal
+ * are independent of the API used to communicate it.
+ * It is const ref because then there's low cost to pass it;
+ * if you only need to inspect it, it's very cheap.
+ */
+
+typedef boost::function<void (const LLSD&, const LLSD&)> LLNotificationResponder;
+
+typedef LLFunctorRegistry<LLNotificationResponder> LLNotificationFunctorRegistry;
+typedef LLFunctorRegistration<LLNotificationResponder> LLNotificationFunctorRegistration;
+
+typedef boost::signal<bool(const LLSD&), LLStopWhenHandled>  LLStandardSignal;
+
+// context data that can be looked up via a notification's payload by the display logic
+// derive from this class to implement specific contexts
+class LLNotificationContext : public LLInstanceTracker<LLNotificationContext, LLUUID>
+{
+public:
+	LLNotificationContext() : LLInstanceTracker<LLNotificationContext, LLUUID>(LLUUID::generateNewID())
+	{
+	}
+
+	virtual ~LLNotificationContext() {}
+
+	LLSD asLLSD() const
+	{
+		return getKey();
+	}
+
+private:
+
+};
+
+// Contains notification form data, such as buttons and text fields along with
+// manipulator functions
+class LLNotificationForm
+{
+	LOG_CLASS(LLNotificationForm);
+
+public:
+	typedef enum e_ignore_type
+	{ 
+		IGNORE_NO,
+		IGNORE_WITH_DEFAULT_RESPONSE, 
+		IGNORE_WITH_LAST_RESPONSE, 
+		IGNORE_SHOW_AGAIN 
+	} EIgnoreType;
+
+	LLNotificationForm();
+	LLNotificationForm(const LLSD& sd);
+	LLNotificationForm(const std::string& name, const LLXMLNodePtr xml_node);
+
+	LLSD asLLSD() const;
+
+	S32 getNumElements() { return mFormData.size(); }
+	LLSD getElement(S32 index) { return mFormData.get(index); }
+	LLSD getElement(const std::string& element_name);
+	bool hasElement(const std::string& element_name);
+	void addElement(const std::string& type, const std::string& name, const LLSD& value = LLSD());
+	void formatElements(const LLSD& substitutions);
+	// appends form elements from another form serialized as LLSD
+	void append(const LLSD& sub_form);
+	std::string getDefaultOption();
+
+	EIgnoreType getIgnoreType() { return mIgnore; }
+	std::string getIgnoreMessage() { return mIgnoreMsg; }
+
+private:
+	LLSD	mFormData;
+	EIgnoreType mIgnore;
+	std::string mIgnoreMsg;
+};
+
+typedef boost::shared_ptr<LLNotificationForm> LLNotificationFormPtr;
+
+// This is the class of object read from the XML file (notifications.xml, 
+// from the appropriate local language directory).
+struct LLNotificationTemplate
+{
+	LLNotificationTemplate();
+    // the name of the notification -- the key used to identify it
+    // Ideally, the key should follow variable naming rules 
+    // (no spaces or punctuation).
+    std::string mName;
+    // The type of the notification
+    // used to control which queue it's stored in
+    std::string mType;
+    // The text used to display the notification. Replaceable parameters
+    // are enclosed in square brackets like this [].
+    std::string mMessage;
+	// The label for the notification; used for 
+	// certain classes of notification (those with a window and a window title). 
+	// Also used when a notification pops up underneath the current one.
+	// Replaceable parameters can be used in the label.
+	std::string mLabel;
+	// The name of the icon image. This should include an extension.
+	std::string mIcon;
+    // This is the Highlander bit -- "There Can Be Only One"
+    // An outstanding notification with this bit set
+    // is updated by an incoming notification with the same name,
+    // rather than creating a new entry in the queue.
+    // (used for things like progress indications, or repeating warnings
+    // like "the grid is going down in N minutes")
+    bool mUnique;
+    // if we want to be unique only if a certain part of the payload is constant
+    // specify the field names for the payload. The notification will only be
+    // combined if all of the fields named in the context are identical in the
+    // new and the old notification; otherwise, the notification will be
+    // duplicated. This is to support suppressing duplicate offers from the same
+    // sender but still differentiating different offers. Example: Invitation to
+    // conference chat.
+    std::vector<std::string> mUniqueContext;
+    // If this notification expires automatically, this value will be 
+    // nonzero, and indicates the number of seconds for which the notification
+    // will be valid (a teleport offer, for example, might be valid for 
+    // 300 seconds). 
+    U32 mExpireSeconds;
+    // if the offer expires, one of the options is chosen automatically
+    // based on its "value" parameter. This controls which one. 
+    // If expireSeconds is specified, expireOption should also be specified.
+    U32 mExpireOption;
+    // if the notification contains a url, it's stored here (and replaced 
+    // into the message where [_URL] is found)
+    std::string mURL;
+    // if there's a URL in the message, this controls which option visits
+    // that URL. Obsolete this and eliminate the buttons for affected
+    // messages when we allow clickable URLs in the UI
+    U32 mURLOption;
+	// does this notification persist across sessions? if so, it will be
+	// serialized to disk on first receipt and read on startup
+	bool mPersist;
+	// This is the name of the default functor, if present, to be
+	// used for the notification's callback. It is optional, and used only if 
+	// the notification is constructed without an identified functor.
+	std::string mDefaultFunctor;
+	// The form data associated with a given notification (buttons, text boxes, etc)
+    LLNotificationFormPtr mForm;
+	// default priority for notifications of this type
+	ENotificationPriority mPriority;
+	// UUID of the audio file to be played when this notification arrives
+	// this is loaded as a name, but looked up to get the UUID upon template load.
+	// If null, it wasn't specified.
+	LLUUID mSoundEffect;
+};
+
+// we want to keep a map of these by name, and it's best to manage them
+// with smart pointers
+typedef boost::shared_ptr<LLNotificationTemplate> LLNotificationTemplatePtr;
+
+/**
+ * @class LLNotification
+ * @brief The object that expresses the details of a notification
+ * 
+ * We make this noncopyable because
+ * we want to manage these through LLNotificationPtr, and only
+ * ever create one instance of any given notification.
+ * 
+ * The enable_shared_from_this flag ensures that if we construct
+ * a smart pointer from a notification, we'll always get the same
+ * shared pointer.
+ */
+class LLNotification  : 
+	boost::noncopyable,
+	public boost::enable_shared_from_this<LLNotification>
+{
+LOG_CLASS(LLNotification);
+friend class LLNotifications;
+
+public:
+	// parameter object used to instantiate a new notification
+	class Params : public LLParamBlock<Params>
+	{
+		friend class LLNotification;
+	public:
+		Params(const std::string& _name) 
+			:	name(_name),
+				mTemporaryResponder(false),
+				functor_name(_name),
+				priority(NOTIFICATION_PRIORITY_UNSPECIFIED),
+				timestamp(LLDate::now())
+		{
+		}
+
+		// pseudo-param
+		Params& functor(LLNotificationFunctorRegistry::ResponseFunctor f) 
+		{ 	
+			functor_name = LLUUID::generateNewID().asString();
+			LLNotificationFunctorRegistry::instance().registerFunctor(functor_name, f);
+
+			mTemporaryResponder = true;
+			return *this;
+		}
+
+		LLMandatoryParam<std::string>					name;
+
+		// optional
+		LLOptionalParam<LLSD>							substitutions;
+		LLOptionalParam<LLSD>							payload;
+		LLOptionalParam<ENotificationPriority>			priority;
+		LLOptionalParam<LLSD>							form_elements;
+		LLOptionalParam<LLDate>							timestamp;
+		LLOptionalParam<LLNotificationContext*>			context;
+		LLOptionalParam<std::string>					functor_name;
+
+	private:
+		bool					mTemporaryResponder;
+	};
+
+private:
+	
+	LLUUID mId;
+	LLSD mPayload;
+	LLSD mSubstitutions;
+	LLDate mTimestamp;
+	LLDate mExpiresAt;
+	bool mCancelled;
+	bool mRespondedTo; 	// once the notification has been responded to, this becomes true
+	bool mIgnored;
+	ENotificationPriority mPriority;
+	LLNotificationFormPtr mForm;
+	
+	// a reference to the template
+	LLNotificationTemplatePtr mTemplatep;
+	
+	/*
+	 We want to be able to store and reload notifications so that they can survive
+	 a shutdown/restart of the client. So we can't simply pass in callbacks;
+	 we have to specify a callback mechanism that can be used by name rather than 
+	 by some arbitrary pointer -- and then people have to initialize callbacks 
+	 in some useful location. So we use LLNotificationFunctorRegistry to manage them.
+	 */
+	 std::string mResponseFunctorName;
+	
+	/*
+	 In cases where we want to specify an explict, non-persisted callback, 
+	 we store that in the callback registry under a dynamically generated
+	 key, and store the key in the notification, so we can still look it up
+	 using the same mechanism.
+	 */
+	bool mTemporaryResponder;
+
+	void init(const std::string& template_name, const LLSD& form_elements);
+
+	LLNotification(const Params& p);
+
+	// this is just for making it easy to look things up in a set organized by UUID -- DON'T USE IT
+	// for anything real!
+	LLNotification(LLUUID uuid) : mId(uuid) {}
+
+	void cancel();
+
+	bool payloadContainsAll(const std::vector<std::string>& required_fields) const;
+
+public:
+
+	// constructor from a saved notification
+	LLNotification(const LLSD& sd);
+
+	// This is a string formatter for substituting into the message directly 
+	// from LLSD without going through the hopefully-to-be-obsoleted LLString
+	static std::string format(const std::string& text, const LLSD& substitutions);
+
+	void setResponseFunctor(std::string const &responseFunctorName);
+
+	typedef enum e_response_template_type
+	{
+		WITHOUT_DEFAULT_BUTTON,
+		WITH_DEFAULT_BUTTON
+	} EResponseTemplateType;
+
+	// return response LLSD filled in with default form contents and (optionally) the default button selected
+	LLSD getResponseTemplate(EResponseTemplateType type = WITHOUT_DEFAULT_BUTTON);
+
+	// returns index of first button with value==TRUE
+	// usually this the button the user clicked on
+	// returns -1 if no button clicked (e.g. form has not been displayed)
+	static S32 getSelectedOption(const LLSD& notification, const LLSD& response);
+	// returns name of first button with value==TRUE
+	static std::string getSelectedOptionName(const LLSD& notification);
+
+	// after someone responds to a notification (usually by clicking a button,
+	// but sometimes by filling out a little form and THEN clicking a button),
+    // the result of the response (the name and value of the button clicked,
+	// plus any other data) should be packaged up as LLSD, then passed as a
+	// parameter to the notification's respond() method here. This will look up
+	// and call the appropriate responder.
+	//
+	// response is notification serialized as LLSD:
+	// ["name"] = notification name
+	// ["form"] = LLSD tree that includes form description and any prefilled form data
+	// ["response"] = form data filled in by user
+	// (including, but not limited to which button they clicked on)
+	// ["payload"] = transaction specific data, such as ["source_id"] (originator of notification),  
+	//				["item_id"] (attached inventory item), etc.
+	// ["substitutions"] = string substitutions used to generate notification message
+    // from the template
+	// ["time"] = time at which notification was generated;
+	// ["expiry"] = time at which notification expires;
+	// ["responseFunctor"] = name of registered functor that handles responses to notification;
+	LLSD asLLSD();
+
+	void respond(const LLSD& sd);
+
+	void setIgnored(bool ignore);
+
+	bool isCancelled() const
+	{
+		return mCancelled;
+	}
+
+	bool isRespondedTo() const
+	{
+		return mRespondedTo;
+	}
+
+	bool isIgnored() const
+	{
+		return mIgnored;
+	}
+
+	const std::string& getName() const
+	{
+		return mTemplatep->mName;
+	}
+	
+	const LLUUID& id() const
+	{
+		return mId;
+	}
+	
+	const LLSD& getPayload() const
+	{
+		return mPayload;
+	}
+
+	const LLSD& getSubstitutions() const
+	{
+		return mSubstitutions;
+	}
+
+	const LLDate& getDate() const
+	{
+		return mTimestamp;
+	}
+
+	std::string getType() const
+	{
+		return (mTemplatep ? mTemplatep->mType : "");
+	}
+
+	std::string getMessage() const;
+	std::string getLabel() const;
+
+	std::string getURL() const
+	{
+		return (mTemplatep ? mTemplatep->mURL : "");
+	}
+
+	S32 getURLOption() const
+	{
+		return (mTemplatep ? mTemplatep->mURLOption : -1);
+	}
+
+	const LLNotificationFormPtr getForm();
+
+	const LLDate getExpiration() const
+	{
+		return mExpiresAt;
+	}
+
+	ENotificationPriority getPriority() const
+	{
+		return mPriority;
+	}
+
+	const LLUUID getID() const
+	{
+		return mId;
+	}
+	
+	// comparing two notifications normally means comparing them by UUID (so we can look them
+	// up quickly this way)
+	bool operator<(const LLNotification& rhs) const
+	{
+		return mId < rhs.mId;
+	}
+
+	bool operator==(const LLNotification& rhs) const
+	{
+		return mId == rhs.mId;
+	}
+
+	bool operator!=(const LLNotification& rhs) const
+	{
+		return !operator==(rhs);
+	}
+
+	bool isSameObjectAs(const LLNotification* rhs) const
+	{
+		return this == rhs;
+	}
+	
+	// this object has been updated, so tell all our clients
+	void update();
+
+	void updateFrom(LLNotificationPtr other);
+	
+	// A fuzzy equals comparator.
+	// true only if both notifications have the same template and 
+	//     1) flagged as unique (there can be only one of these) OR 
+	//     2) all required payload fields of each also exist in the other.
+	bool isEquivalentTo(LLNotificationPtr that) const;
+	
+	// if the current time is greater than the expiration, the notification is expired
+	bool isExpired() const
+	{
+		if (mExpiresAt.secondsSinceEpoch() == 0)
+		{
+			return false;
+		}
+		
+		LLDate rightnow = LLDate::now();
+		return rightnow > mExpiresAt;
+	}
+	
+	std::string summarize() const;
+
+	bool hasUniquenessConstraints() const { return (mTemplatep ? mTemplatep->mUnique : false);}
+
+	virtual ~LLNotification() {}
+};
+
+std::ostream& operator<<(std::ostream& s, const LLNotification& notification);
+
+namespace LLNotificationFilters
+{
+	// a sample filter
+	bool includeEverything(LLNotificationPtr p);
+
+	typedef enum e_comparison 
+	{ 
+		EQUAL, 
+		LESS, 
+		GREATER, 
+		LESS_EQUAL, 
+		GREATER_EQUAL 
+	} EComparison;
+
+	// generic filter functor that takes method or member variable reference
+	template<typename T>
+	struct filterBy
+	{
+		typedef boost::function<T (LLNotificationPtr)>	field_t;
+		typedef typename boost::remove_reference<T>::type		value_t;
+		
+		filterBy(field_t field, value_t value, EComparison comparison = EQUAL) 
+			:	mField(field), 
+				mFilterValue(value),
+				mComparison(comparison)
+		{
+		}		
+		
+		bool operator()(LLNotificationPtr p)
+		{
+			switch(mComparison)
+			{
+			case EQUAL:
+				return mField(p) == mFilterValue;
+			case LESS:
+				return mField(p) < mFilterValue;
+			case GREATER:
+				return mField(p) > mFilterValue;
+			case LESS_EQUAL:
+				return mField(p) <= mFilterValue;
+			case GREATER_EQUAL:
+				return mField(p) >= mFilterValue;
+			default:
+				return false;
+			}
+		}
+
+		field_t mField;
+		value_t	mFilterValue;
+		EComparison mComparison;
+	};
+};
+
+namespace LLNotificationComparators
+{
+	typedef enum e_direction { ORDER_DECREASING, ORDER_INCREASING } EDirection;
+
+	// generic order functor that takes method or member variable reference
+	template<typename T>
+	struct orderBy
+	{
+		typedef boost::function<T (LLNotificationPtr)> field_t;
+		orderBy(field_t field, EDirection = ORDER_INCREASING) : mField(field) {}
+		bool operator()(LLNotificationPtr lhs, LLNotificationPtr rhs)
+		{
+			if (mDirection == ORDER_DECREASING)
+			{
+				return mField(lhs) > mField(rhs);
+			}
+			else
+			{
+				return mField(lhs) < mField(rhs);
+			}
+		}
+
+		field_t mField;
+		EDirection mDirection;
+	};
+
+	struct orderByUUID : public orderBy<const LLUUID&>
+	{
+		orderByUUID(EDirection direction = ORDER_INCREASING) : orderBy<const LLUUID&>(&LLNotification::id, direction) {}
+	};
+
+	struct orderByDate : public orderBy<const LLDate&>
+	{
+		orderByDate(EDirection direction = ORDER_INCREASING) : orderBy<const LLDate&>(&LLNotification::getDate, direction) {}
+	};
+};
+
+typedef boost::function<bool (LLNotificationPtr)> LLNotificationFilter;
+typedef boost::function<bool (LLNotificationPtr, LLNotificationPtr)> LLNotificationComparator;
+typedef std::set<LLNotificationPtr, LLNotificationComparator> LLNotificationSet;
+typedef std::multimap<std::string, LLNotificationPtr> LLNotificationMap;
+
+// ========================================================
+// Abstract base class (interface) for a channel; also used for the master container.
+// This lets us arrange channels into a call hierarchy.
+
+// We maintain a heirarchy of notification channels; events are always started at the top
+// and propagated through the hierarchy only if they pass a filter.
+// Any channel can be created with a parent. A null parent (empty string) means it's
+// tied to the root of the tree (the LLNotifications class itself).
+// The default hierarchy looks like this:
+//
+// LLNotifications --+-- Expiration --+-- Mute --+-- Ignore --+-- Visible --+-- History
+//                                                                          +-- Alerts
+//                                                                          +-- Notifications
+//
+// In general, new channels that want to only see notifications that pass through 
+// all of the built-in tests should attach to the "Visible" channel
+//
+class LLNotificationChannelBase :
+	public boost::signals::trackable
+{
+	LOG_CLASS(LLNotificationChannelBase);
+public:
+	LLNotificationChannelBase(LLNotificationFilter filter, LLNotificationComparator comp) : 
+		mFilter(filter), mItems(comp) 
+	{}
+	virtual ~LLNotificationChannelBase() {}
+	// you can also connect to a Channel, so you can be notified of
+	// changes to this channel
+	virtual void connectChanged(const LLStandardSignal::slot_type& slot);
+	virtual void connectPassedFilter(const LLStandardSignal::slot_type& slot);
+	virtual void connectFailedFilter(const LLStandardSignal::slot_type& slot);
+
+	// use this when items change or to add a new one
+	bool updateItem(const LLSD& payload);
+	const LLNotificationFilter& getFilter() { return mFilter; }
+
+protected:
+	LLNotificationSet mItems;
+	LLStandardSignal mChanged;
+	LLStandardSignal mPassedFilter;
+	LLStandardSignal mFailedFilter;
+	
+	// these are action methods that subclasses can override to take action 
+	// on specific types of changes; the management of the mItems list is
+	// still handled by the generic handler.
+	virtual void onLoad(LLNotificationPtr p) {}
+	virtual void onAdd(LLNotificationPtr p) {}
+	virtual void onDelete(LLNotificationPtr p) {}
+	virtual void onChange(LLNotificationPtr p) {}
+
+	bool updateItem(const LLSD& payload, LLNotificationPtr pNotification);
+	LLNotificationFilter mFilter;
+};
+
+// manages a list of notifications
+// Note that if this is ever copied around, we might find ourselves with multiple copies
+// of a queue with notifications being added to different nonequivalent copies. So we 
+// make it inherit from boost::noncopyable, and then create a map of shared_ptr to manage it.
+// 
+// NOTE: LLNotificationChannel is self-registering. The *correct* way to create one is to 
+// do something like:
+//		new LLNotificationChannel("name", "parent"...);
+// You can then retrieve the channel by using the registry:
+//		LLNotifications::instance().getChannel("name")...
+//
+class LLNotificationChannel : 
+	boost::noncopyable, 
+	public LLNotificationChannelBase
+{
+	LOG_CLASS(LLNotificationChannel);
+
+public:  
+	virtual ~LLNotificationChannel() {}
+    // Notification Channels have a filter, which determines which notifications
+	// will be added to this channel. 
+	// Channel filters cannot change.
+	LLNotificationChannel(const std::string& name, const std::string& parent,
+						LLNotificationFilter filter=LLNotificationFilters::includeEverything, 
+						LLNotificationComparator comparator=LLNotificationComparators::orderByUUID());
+
+	typedef LLNotificationSet::iterator Iterator;
+    
+	std::string getName() const { return mName; }
+	std::string getParentChannelName() { return mParent; }
+    
+    bool isEmpty() const;
+    
+    Iterator begin();
+    Iterator end();
+
+    // Channels have a comparator to control sort order;
+	// the default sorts by arrival date
+    void setComparator(LLNotificationComparator comparator);
+	
+	std::string summarize();
+
+private:
+	std::string mName;
+	std::string mParent;
+	LLNotificationComparator mComparator;
+};
+
+
+
+// The type of the pointers that we're going to manage in the NotificationQueue system
+// Because LLNotifications is a singleton, we don't actually expect to ever 
+// destroy it, but if it becomes necessary to do so, the shared_ptr model
+// will ensure that we don't leak resources.
+typedef boost::shared_ptr<LLNotificationChannel> LLNotificationChannelPtr;
+
+class LLNotifications : 
+	public LLSingleton<LLNotifications>, 
+	public LLNotificationChannelBase
+{
+	LOG_CLASS(LLNotifications);
+
+	friend class LLSingleton<LLNotifications>;
+public:
+	// load notification descriptions from file; 
+	// OK to call more than once because it will reload
+	bool loadTemplates();  
+	LLXMLNodePtr checkForXMLTemplate(LLXMLNodePtr item);
+
+	// we provide a collection of simple add notification functions so that it's reasonable to create notifications in one line
+	LLNotificationPtr add(const std::string& name, 
+						const LLSD& substitutions = LLSD(), 
+						const LLSD& payload = LLSD());
+	LLNotificationPtr add(const std::string& name, 
+						const LLSD& substitutions, 
+						const LLSD& payload, 
+						const std::string& functor_name);
+	LLNotificationPtr add(const std::string& name, 
+						const LLSD& substitutions, 
+						const LLSD& payload, 
+						LLNotificationFunctorRegistry::ResponseFunctor functor);
+	LLNotificationPtr add(const LLNotification::Params& p);
+
+	void add(const LLNotificationPtr pNotif);
+	void cancel(LLNotificationPtr pNotif);
+	void update(const LLNotificationPtr pNotif);
+
+	LLNotificationPtr find(LLUUID uuid);
+	
+	typedef boost::function<void (LLNotificationPtr)> NotificationProcess;
+	
+	void forEachNotification(NotificationProcess process);
+
+	// This is all stuff for managing the templates
+	// take your template out
+	LLNotificationTemplatePtr getTemplate(const std::string& name);
+	
+	// get the whole collection
+	typedef std::vector<std::string> TemplateNames;
+	TemplateNames getTemplateNames() const;  // returns a list of notification names
+	
+	typedef std::map<std::string, LLNotificationTemplatePtr> TemplateMap;
+
+	TemplateMap::const_iterator templatesBegin() { return mTemplates.begin(); }
+	TemplateMap::const_iterator templatesEnd() { return mTemplates.end(); }
+
+	// test for existence
+	bool templateExists(const std::string& name);
+	// useful if you're reloading the file
+	void clearTemplates();   // erase all templates
+
+	void forceResponse(const LLNotification::Params& params, S32 option);
+
+	void createDefaultChannels();
+
+	typedef std::map<std::string, LLNotificationChannelPtr> ChannelMap;
+	ChannelMap mChannels;
+
+	void addChannel(LLNotificationChannelPtr pChan);
+	LLNotificationChannelPtr getChannel(const std::string& channelName);
+	
+	std::string getGlobalString(const std::string& key) const;
+
+private:
+	// we're a singleton, so we don't have a public constructor
+	LLNotifications();
+	/*virtual*/ void initSingleton();
+	
+	void loadPersistentNotifications();
+
+	bool expirationFilter(LLNotificationPtr pNotification);
+	bool expirationHandler(const LLSD& payload);
+	bool uniqueFilter(LLNotificationPtr pNotification);
+	bool uniqueHandler(const LLSD& payload);
+	bool failedUniquenessTest(const LLSD& payload);
+	LLNotificationChannelPtr pHistoryChannel;
+	LLNotificationChannelPtr pExpirationChannel;
+	
+	// put your template in
+	bool addTemplate(const std::string& name, LLNotificationTemplatePtr theTemplate);
+	TemplateMap mTemplates;
+
+	std::string mFileName;
+	
+	typedef std::map<std::string, LLXMLNodePtr> XMLTemplateMap;
+	XMLTemplateMap mXmlTemplates;
+
+	LLNotificationMap mUniqueNotifications;
+	
+	typedef std::map<std::string, std::string> GlobalStringMap;
+	GlobalStringMap mGlobalStrings;
+};
+
+
+#endif//LL_LLNOTIFICATIONS_H
+
diff --git a/indra/llui/llpanel.cpp b/indra/llui/llpanel.cpp
index 22934450e79..2edbbe6abc9 100644
--- a/indra/llui/llpanel.cpp
+++ b/indra/llui/llpanel.cpp
@@ -58,8 +58,6 @@
 #include "llresizebar.h"
 #include "llcriticaldamp.h"
 
-LLPanel::alert_queue_t LLPanel::sAlertQueue;
-
 const S32 RESIZE_BAR_OVERLAP = 1;
 const S32 RESIZE_BAR_HEIGHT = 3;
 
@@ -344,14 +342,14 @@ BOOL LLPanel::checkRequirements()
 {
 	if (!mRequirementsError.empty())
 	{
-		LLStringUtil::format_map_t args;
-		args["[COMPONENTS]"] = mRequirementsError;
-		args["[FLOATER]"] = getName();
+		LLSD args;
+		args["COMPONENTS"] = mRequirementsError;
+		args["FLOATER"] = getName();
 
 		llwarns << getName() << " failed requirements check on: \n"  
 				<< mRequirementsError << llendl;
-			
-		alertXml(std::string("FailedRequirementsCheck"), args);
+		
+		LLNotifications::instance().add(LLNotification::Params("FailedRequirementsCheck").payload(args));
 		mRequirementsError.clear();
 		return FALSE;
 	}
@@ -359,25 +357,6 @@ BOOL LLPanel::checkRequirements()
 	return TRUE;
 }
 
-//static
-void LLPanel::alertXml(const std::string& label, LLStringUtil::format_map_t args)
-{
-	sAlertQueue.push(LLAlertInfo(label,args));
-}
-
-//static
-BOOL LLPanel::nextAlert(LLAlertInfo &alert)
-{
-	if (!sAlertQueue.empty())
-	{
-		alert = sAlertQueue.front();
-		sAlertQueue.pop();
-		return TRUE;
-	}
-
-	return FALSE;
-}
-
 void LLPanel::setFocus(BOOL b)
 {
 	if( b )
@@ -1039,9 +1018,9 @@ void LLPanel::childDisplayNotFound()
 		mExpectedMembers.insert(*itor);
 	}
 	mNewExpectedMembers.clear();
-	LLStringUtil::format_map_t args;
-	args["[CONTROLS]"] = msg;
-	LLAlertDialog::showXml("FloaterNotFound", args);
+	LLSD args;
+	args["CONTROLS"] = msg;
+	LLNotifications::instance().add("FloaterNotFound", args);
 }
 
 void LLPanel::storeRectControl()
@@ -1065,6 +1044,8 @@ struct LLLayoutStack::LLEmbeddedPanel
 			mAutoResize(auto_resize),
 			mUserResize(user_resize),
 			mOrientation(orientation),
+			mCollapsed(FALSE),
+			mCollapseAmt(0.f),
 			mVisibleAmt(1.f) // default to fully visible
 	{
 		LLResizeBar::Side side = (orientation == HORIZONTAL) ? LLResizeBar::RIGHT : LLResizeBar::BOTTOM;
@@ -1095,14 +1076,28 @@ struct LLLayoutStack::LLEmbeddedPanel
 		mResizeBar = NULL;
 	}
 
+	F32 getCollapseFactor()
+	{
+		if (mOrientation == HORIZONTAL)
+		{
+			return mVisibleAmt * clamp_rescale(mCollapseAmt, 0.f, 1.f, 1.f, (F32)mMinWidth / (F32)mPanel->getRect().getWidth());
+		}
+		else
+		{
+			return mVisibleAmt * clamp_rescale(mCollapseAmt, 0.f, 1.f, 1.f, (F32)mMinHeight / (F32)mPanel->getRect().getHeight());
+		}
+	}
+
 	LLPanel* mPanel;
 	S32 mMinWidth;
 	S32 mMinHeight;
 	BOOL mAutoResize;
 	BOOL mUserResize;
+	BOOL mCollapsed;
 	LLResizeBar* mResizeBar;
 	eLayoutOrientation mOrientation;
 	F32 mVisibleAmt;
+	F32 mCollapseAmt;
 };
 
 static LLRegisterWidget<LLLayoutStack> r2("layout_stack");
@@ -1123,28 +1118,27 @@ LLLayoutStack::~LLLayoutStack()
 void LLLayoutStack::draw()
 {
 	updateLayout();
+
+	e_panel_list_t::iterator panel_it;
+	for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
 	{
-		e_panel_list_t::iterator panel_it;
-		for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
+		// clip to layout rectangle, not bounding rectangle
+		LLRect clip_rect = (*panel_it)->mPanel->getRect();
+		// scale clipping rectangle by visible amount
+		if (mOrientation == HORIZONTAL)
 		{
-			// clip to layout rectangle, not bounding rectangle
-			LLRect clip_rect = (*panel_it)->mPanel->getRect();
-			// scale clipping rectangle by visible amount
-			if (mOrientation == HORIZONTAL)
-			{
-				clip_rect.mRight = clip_rect.mLeft + llround((F32)clip_rect.getWidth() * (*panel_it)->mVisibleAmt);
-			}
-			else
-			{
-				clip_rect.mBottom = clip_rect.mTop - llround((F32)clip_rect.getHeight() * (*panel_it)->mVisibleAmt);
-			}
+			clip_rect.mRight = clip_rect.mLeft + llround((F32)clip_rect.getWidth() * (*panel_it)->getCollapseFactor());
+		}
+		else
+		{
+			clip_rect.mBottom = clip_rect.mTop - llround((F32)clip_rect.getHeight() * (*panel_it)->getCollapseFactor());
+		}
 
-			LLPanel* panelp = (*panel_it)->mPanel;
+		LLPanel* panelp = (*panel_it)->mPanel;
 
-			LLLocalClipRect clip(clip_rect);
-			// only force drawing invisible children if visible amount is non-zero
-			drawChild(panelp, 0, 0, !clip_rect.isNull());
-		}
+		LLLocalClipRect clip(clip_rect);
+		// only force drawing invisible children if visible amount is non-zero
+		drawChild(panelp, 0, 0, !clip_rect.isNull());
 	}
 }
 
@@ -1276,8 +1270,13 @@ S32 LLLayoutStack::getDefaultWidth(S32 cur_width)
 	return cur_width;
 }
 
-void LLLayoutStack::addPanel(LLPanel* panel, S32 min_width, S32 min_height, BOOL auto_resize, BOOL user_resize, S32 index)
+void LLLayoutStack::addPanel(LLPanel* panel, S32 min_width, S32 min_height, BOOL auto_resize, BOOL user_resize, EAnimate animate, S32 index)
 {
+	// panel starts off invisible (collapsed)
+	if (animate == ANIMATE)
+	{
+		panel->setVisible(FALSE);
+	}
 	LLEmbeddedPanel* embedded_panel = new LLEmbeddedPanel(panel, mOrientation, min_width, min_height, auto_resize, user_resize);
 	
 	mPanels.insert(mPanels.begin() + llclamp(index, 0, (S32)mPanels.size()), embedded_panel);
@@ -1293,6 +1292,11 @@ void LLLayoutStack::addPanel(LLPanel* panel, S32 min_width, S32 min_height, BOOL
 		sendChildToFront(resize_barp);
 	}
 
+	// start expanding panel animation
+	if (animate == ANIMATE)
+	{
+		panel->setVisible(TRUE);
+	}
 }
 
 void LLLayoutStack::removePanel(LLPanel* panel)
@@ -1300,6 +1304,14 @@ void LLLayoutStack::removePanel(LLPanel* panel)
 	removeChild(panel);
 }
 
+void LLLayoutStack::collapsePanel(LLPanel* panel, BOOL collapsed)
+{
+	LLEmbeddedPanel* panel_container = findEmbeddedPanel(panel);
+	if (!panel_container) return;
+
+	panel_container->mCollapsed = collapsed;
+}
+
 void LLLayoutStack::updateLayout(BOOL force_resize)
 {
 	calcMinExtents();
@@ -1332,6 +1344,15 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
 			}
 		}
 
+		if ((*panel_it)->mCollapsed)
+		{
+			(*panel_it)->mCollapseAmt = lerp((*panel_it)->mCollapseAmt, 1.f, LLCriticalDamp::getInterpolant(ANIM_CLOSE_TIME));
+		}
+		else
+		{
+			(*panel_it)->mCollapseAmt = lerp((*panel_it)->mCollapseAmt, 0.f, LLCriticalDamp::getInterpolant(ANIM_CLOSE_TIME));
+		}
+
 		if (mOrientation == HORIZONTAL)
 		{
 			// enforce minimize size constraint by default
@@ -1339,7 +1360,7 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
 			{
 				panelp->reshape((*panel_it)->mMinWidth, panelp->getRect().getHeight());
 			}
-        	total_width += llround(panelp->getRect().getWidth() * (*panel_it)->mVisibleAmt);
+        	total_width += llround(panelp->getRect().getWidth() * (*panel_it)->getCollapseFactor());
         	// want n-1 panel gaps for n panels
 			if (panel_it != mPanels.begin())
 			{
@@ -1353,7 +1374,7 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
 			{
 				panelp->reshape(panelp->getRect().getWidth(), (*panel_it)->mMinHeight);
 			}
-			total_height += llround(panelp->getRect().getHeight() * (*panel_it)->mVisibleAmt);
+			total_height += llround(panelp->getRect().getHeight() * (*panel_it)->getCollapseFactor());
 			if (panel_it != mPanels.begin())
 			{
 				total_height += mPanelSpacing;
@@ -1367,7 +1388,7 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
 	for (panel_it = mPanels.begin(); panel_it != mPanels.end(); ++panel_it)
 	{
 		// panels that are not fully visible do not count towards shrink headroom
-		if ((*panel_it)->mVisibleAmt < 1.f) 
+		if ((*panel_it)->getCollapseFactor() < 1.f) 
 		{
 			continue;
 		}
@@ -1431,7 +1452,7 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
 		S32 delta_size = 0;
 
 		// if panel can automatically resize (not animating, and resize flag set)...
-		if ((*panel_it)->mVisibleAmt == 1.f 
+		if ((*panel_it)->getCollapseFactor() == 1.f 
 			&& (force_resize || (*panel_it)->mAutoResize) 
 			&& !(*panel_it)->mResizeBar->hasMouseCapture()) 
 		{
@@ -1515,11 +1536,11 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
 
 		if (mOrientation == HORIZONTAL)
 		{
-			cur_x += llround(new_width * (*panel_it)->mVisibleAmt) + mPanelSpacing;
+			cur_x += llround(new_width * (*panel_it)->getCollapseFactor()) + mPanelSpacing;
 		}
 		else //VERTICAL
 		{
-			cur_y -= llround(new_height * (*panel_it)->mVisibleAmt) + mPanelSpacing;
+			cur_y -= llround(new_height * (*panel_it)->getCollapseFactor()) + mPanelSpacing;
 		}
 	}
 
diff --git a/indra/llui/llpanel.h b/indra/llui/llpanel.h
index c55eb6bba2d..da876667e68 100644
--- a/indra/llui/llpanel.h
+++ b/indra/llui/llpanel.h
@@ -49,23 +49,13 @@ const BOOL BORDER_YES = TRUE;
 const BOOL BORDER_NO = FALSE;
 
 
-struct LLAlertInfo
-{
-	std::string mLabel;
-	LLStringUtil::format_map_t mArgs;
-
-	LLAlertInfo(std::string label, LLStringUtil::format_map_t args) : mLabel(label), mArgs(args) { }
-	LLAlertInfo(){}
-};
-
-
 /*
  * General purpose concrete view base class.
  * Transparent or opaque,
  * With or without border,
  * Can contain LLUICtrls.
  */
-class LLPanel : public LLUICtrl 
+class LLPanel : public LLUICtrl, public boost::signals::trackable
 {
 public:
 
@@ -227,8 +217,6 @@ class LLPanel : public LLUICtrl
 	void childNotFound(const std::string& id) const;
 	void childDisplayNotFound();
 
-	static void		alertXml(const std::string& label, LLStringUtil::format_map_t args = LLStringUtil::format_map_t());
-	static BOOL		nextAlert(LLAlertInfo &alert);
 	static LLView*	fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
 	
 protected:
@@ -266,8 +254,6 @@ class LLPanel : public LLUICtrl
 
 	std::string		mRequirementsError;
 
-	typedef std::queue<LLAlertInfo> alert_queue_t;
-	static alert_queue_t sAlertQueue;
 }; // end class LLPanel
 
 
@@ -292,8 +278,16 @@ class LLLayoutStack : public LLView
 	S32 getMinWidth() const { return mMinWidth; }
 	S32 getMinHeight() const { return mMinHeight; }
 	
-	void addPanel(LLPanel* panel, S32 min_width, S32 min_height, BOOL auto_resize, BOOL user_resize, S32 index = S32_MAX);
+	typedef enum e_animate
+	{
+		NO_ANIMATE,
+		ANIMATE
+	} EAnimate;
+
+	void addPanel(LLPanel* panel, S32 min_width, S32 min_height, BOOL auto_resize, BOOL user_resize, EAnimate animate = NO_ANIMATE, S32 index = S32_MAX);
 	void removePanel(LLPanel* panel);
+	void collapsePanel(LLPanel* panel, BOOL collapsed = TRUE);
+	S32 getNumPanels() { return mPanels.size(); }
 
 private:
 	struct LLEmbeddedPanel;
diff --git a/indra/llui/llscrollbar.cpp b/indra/llui/llscrollbar.cpp
index a7163323bd1..734b3ab3811 100644
--- a/indra/llui/llscrollbar.cpp
+++ b/indra/llui/llscrollbar.cpp
@@ -127,6 +127,8 @@ LLScrollbar::LLScrollbar(
 	}
 	line_up_btn->setHeldDownCallback( &LLScrollbar::onLineUpBtnPressed );
 	line_up_btn->setTabStop(FALSE);
+	line_up_btn->setScaleImage(TRUE);
+
 	addChild(line_up_btn);
 
 	LLButton* line_down_btn = new LLButton(std::string("Line Down"), line_down_rect,
@@ -136,6 +138,7 @@ LLScrollbar::LLScrollbar(
 	line_down_btn->setFollowsBottom();
 	line_down_btn->setHeldDownCallback( &LLScrollbar::onLineDownBtnPressed );
 	line_down_btn->setTabStop(FALSE);
+	line_down_btn->setScaleImage(TRUE);
 	addChild(line_down_btn);
 }
 
@@ -148,20 +151,29 @@ LLScrollbar::~LLScrollbar()
 void LLScrollbar::setDocParams( S32 size, S32 pos )
 {
 	mDocSize = size;
-	mDocPos = llclamp( pos, 0, getDocPosMax() );
+	setDocPos(pos);
 	mDocChanged = TRUE;
 
 	updateThumbRect();
 }
 
-void LLScrollbar::setDocPos(S32 pos)
+void LLScrollbar::setDocPos(S32 pos, BOOL update_thumb)
 {
+	pos = llclamp(pos, 0, getDocPosMax());
 	if (pos != mDocPos)
 	{
-		mDocPos = llclamp( pos, 0, getDocPosMax() );
+		mDocPos = pos;
 		mDocChanged = TRUE;
 
-		updateThumbRect();
+		if( mChangeCallback )
+		{
+			mChangeCallback( mDocPos, this, mCallbackUserData );
+		}
+
+		if( update_thumb )
+		{
+			updateThumbRect();
+		}
 	}
 }
 
@@ -170,7 +182,7 @@ void LLScrollbar::setDocSize(S32 size)
 	if (size != mDocSize)
 	{
 		mDocSize = size;
-		mDocPos = llclamp( mDocPos, 0, getDocPosMax() );
+		setDocPos(mDocPos);
 		mDocChanged = TRUE;
 
 		updateThumbRect();
@@ -182,7 +194,7 @@ void LLScrollbar::setPageSize( S32 page_size )
 	if (page_size != mPageSize)
 	{
 		mPageSize = page_size;
-		mDocPos = llclamp( mDocPos, 0, getDocPosMax() );
+		setDocPos(mDocPos);
 		mDocChanged = TRUE;
 
 		updateThumbRect();
@@ -208,9 +220,9 @@ void LLScrollbar::updateThumbRect()
 	const S32 THUMB_MIN_LENGTH = 16;
 
 	S32 window_length = (mOrientation == LLScrollbar::HORIZONTAL) ? getRect().getWidth() : getRect().getHeight();
-	S32 thumb_bg_length = window_length - 2 * SCROLLBAR_SIZE;
+	S32 thumb_bg_length = llmax(0, window_length - 2 * SCROLLBAR_SIZE);
 	S32 visible_lines = llmin( mDocSize, mPageSize );
-	S32 thumb_length = mDocSize ? llmax( visible_lines * thumb_bg_length / mDocSize, THUMB_MIN_LENGTH ) : thumb_bg_length;
+	S32 thumb_length = mDocSize ? llmin(llmax( visible_lines * thumb_bg_length / mDocSize, THUMB_MIN_LENGTH), thumb_bg_length) : thumb_bg_length;
 
 	S32 variable_lines = mDocSize - visible_lines;
 
@@ -218,7 +230,7 @@ void LLScrollbar::updateThumbRect()
 	{ 
 		S32 thumb_start_max = thumb_bg_length + SCROLLBAR_SIZE;
 		S32 thumb_start_min = SCROLLBAR_SIZE + THUMB_MIN_LENGTH;
-		S32 thumb_start = variable_lines ? llclamp( thumb_start_max - (mDocPos * (thumb_bg_length - thumb_length)) / variable_lines, thumb_start_min, thumb_start_max ) : thumb_start_max;
+		S32 thumb_start = variable_lines ? llmin( llmax(thumb_start_max - (mDocPos * (thumb_bg_length - thumb_length)) / variable_lines, thumb_start_min), thumb_start_max ) : thumb_start_max;
 
 		mThumbRect.mLeft =  0;
 		mThumbRect.mTop = thumb_start;
@@ -230,7 +242,7 @@ void LLScrollbar::updateThumbRect()
 		// Horizontal
 		S32 thumb_start_max = thumb_bg_length + SCROLLBAR_SIZE - thumb_length;
 		S32 thumb_start_min = SCROLLBAR_SIZE;
-		S32 thumb_start = variable_lines ? llclamp( thumb_start_min + (mDocPos * (thumb_bg_length - thumb_length)) / variable_lines, thumb_start_min, thumb_start_max ) : thumb_start_min;
+		S32 thumb_start = variable_lines ? llmin(llmax( thumb_start_min + (mDocPos * (thumb_bg_length - thumb_length)) / variable_lines, thumb_start_min), thumb_start_max ) : thumb_start_min;
 	
 		mThumbRect.mLeft = thumb_start;
 		mThumbRect.mTop = SCROLLBAR_SIZE;
@@ -446,7 +458,7 @@ BOOL LLScrollbar::handleMouseUp(S32 x, S32 y, MASK mask)
 	}
 	else
 	{
-		// Opaque, so don't just check children
+		// Opaque, so don't just check children	
 		handled = LLView::handleMouseUp( x, y, mask );
 	}
 
@@ -455,13 +467,31 @@ BOOL LLScrollbar::handleMouseUp(S32 x, S32 y, MASK mask)
 
 void LLScrollbar::reshape(S32 width, S32 height, BOOL called_from_parent)
 {
+	if (width == getRect().getWidth() && height == getRect().getHeight()) return;
 	LLView::reshape( width, height, called_from_parent );
+	LLButton* up_button = getChild<LLButton>("Line Up");
+	LLButton* down_button = getChild<LLButton>("Line Down");
+
+	if (mOrientation == VERTICAL)
+	{
+		up_button->reshape(up_button->getRect().getWidth(), llmin(getRect().getHeight() / 2, SCROLLBAR_SIZE));
+		down_button->reshape(down_button->getRect().getWidth(), llmin(getRect().getHeight() / 2, SCROLLBAR_SIZE));
+		up_button->setOrigin(up_button->getRect().mLeft, getRect().getHeight() - up_button->getRect().getHeight());
+	}
+	else
+	{
+		up_button->reshape(llmin(getRect().getWidth() / 2, SCROLLBAR_SIZE), up_button->getRect().getHeight());
+		down_button->reshape(llmin(getRect().getWidth() / 2, SCROLLBAR_SIZE), down_button->getRect().getHeight());
+		down_button->setOrigin(getRect().getWidth() - down_button->getRect().getWidth(), down_button->getRect().mBottom);
+	}
 	updateThumbRect();
 }
 
 
 void LLScrollbar::draw()
 {
+	if (!getRect().isValid()) return;
+
 	S32 local_mouse_x;
 	S32 local_mouse_y;
 	LLUI::getCursorPositionLocal(this, &local_mouse_x, &local_mouse_y);
@@ -531,21 +561,7 @@ void LLScrollbar::draw()
 
 void LLScrollbar::changeLine( S32 delta, BOOL update_thumb )
 {
-	S32 new_pos = llclamp( mDocPos + delta, 0, getDocPosMax() );
-	if( new_pos != mDocPos )
-	{
-		mDocPos = new_pos;
-	}
-
-	if( mChangeCallback )
-	{
-		mChangeCallback( mDocPos, this, mCallbackUserData );
-	}
-
-	if( update_thumb )
-	{
-		updateThumbRect();
-	}
+	setDocPos(mDocPos + delta, update_thumb);
 }
 
 void LLScrollbar::setValue(const LLSD& value) 
@@ -561,22 +577,22 @@ BOOL LLScrollbar::handleKeyHere(KEY key, MASK mask)
 	switch( key )
 	{
 	case KEY_HOME:
-		changeLine( -mDocPos, TRUE );
+		setDocPos( 0 );
 		handled = TRUE;
 		break;
 	
 	case KEY_END:
-		changeLine( getDocPosMax() - mDocPos, TRUE );
+		setDocPos( getDocPosMax() );
 		handled = TRUE;
 		break;
 	
 	case KEY_DOWN:
-		changeLine( mStepSize, TRUE );
+		setDocPos( getDocPos() + mStepSize );
 		handled = TRUE;
 		break;
 	
 	case KEY_UP:
-		changeLine( - mStepSize, TRUE );
+		setDocPos( getDocPos() - mStepSize );
 		handled = TRUE;
 		break;
 
diff --git a/indra/llui/llscrollbar.h b/indra/llui/llscrollbar.h
index d35dc10bd4e..5fdacd43f8e 100644
--- a/indra/llui/llscrollbar.h
+++ b/indra/llui/llscrollbar.h
@@ -81,7 +81,7 @@ class LLScrollbar
 
 	// How many "lines" the "document" has scrolled.
 	// 0 <= DocPos <= DocSize - DocVisibile
-	void				setDocPos( S32 pos );
+	void				setDocPos( S32 pos, BOOL update_thumb = TRUE );
 	S32					getDocPos() const		{ return mDocPos; }
 
 	BOOL				isAtBeginning();
diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index c0f21ba9e56..ea0c6d4b2fd 100644
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -378,6 +378,22 @@ void LLScrollListText::draw(const LLColor4& color, const LLColor4& highlight_col
 						TRUE);
 }
 
+LLScrollListDate::LLScrollListDate( const LLDate& date, const LLFontGL* font, S32 width, U8 font_style, LLFontGL::HAlign font_alignment, LLColor4& color, BOOL use_color, BOOL visible)
+:	LLScrollListText(date.asRFC1123(), font, width, font_style, font_alignment, color, use_color, visible),
+	mDate(date)
+{
+}
+
+void LLScrollListDate::setValue(const LLSD& value)
+{
+	mDate = value.asDate();
+	LLScrollListText::setValue(mDate.asRFC1123());
+}
+
+const LLSD LLScrollListDate::getValue() const
+{
+	return mDate;
+}
 
 LLScrollListItem::~LLScrollListItem()
 {
@@ -578,6 +594,7 @@ LLScrollListCtrl::LLScrollListCtrl(const std::string& name, const LLRect& rect,
 	mSearchColumn(0),
 	mNumDynamicWidthColumns(0),
 	mTotalStaticColumnWidth(0),
+	mTotalColumnPadding(0),
 	mSorted(TRUE),
 	mDirty(FALSE),
 	mOriginalSelection(-1),
@@ -627,6 +644,28 @@ LLScrollListCtrl::LLScrollListCtrl(const std::string& name, const LLRect& rect,
 	mLastSelected = NULL;
 }
 
+S32 LLScrollListCtrl::getSearchColumn()
+{
+	// search for proper search column
+	if (mSearchColumn < 0)
+	{
+		LLScrollListItem* itemp = getFirstData();
+		if (itemp)
+		{
+			for(S32 column = 0; column < getNumColumns(); column++)
+			{
+				LLScrollListCell* cell = itemp->getColumn(column);
+				if (cell && cell->isText())
+				{
+					mSearchColumn = column;
+					break;
+				}
+			}
+		}
+	}
+	return llclamp(mSearchColumn, 0, getNumColumns());
+}
+
 LLScrollListCtrl::~LLScrollListCtrl()
 {
 	std::for_each(mItemList.begin(), mItemList.end(), DeletePointer());
@@ -890,8 +929,8 @@ BOOL LLScrollListCtrl::addItem( LLScrollListItem* item, EAddPosition pos, BOOL r
 // *TODO: Use bookkeeping to make this an incramental cost with item additions
 void LLScrollListCtrl::calcColumnWidths()
 {
-	const S32 HEADING_TEXT_PADDING = 30;
-	const S32 COLUMN_TEXT_PADDING = 20;
+	const S32 HEADING_TEXT_PADDING = 25;
+	const S32 COLUMN_TEXT_PADDING = 10;
 
 	mMaxContentWidth = 0;
 
@@ -904,20 +943,17 @@ void LLScrollListCtrl::calcColumnWidths()
 		if (!column) continue;
 
 		// update column width
-		S32 new_width = column->mWidth;
+		S32 new_width = column->getWidth();
 		if (column->mRelWidth >= 0)
 		{
 			new_width = (S32)llround(column->mRelWidth*mItemListRect.getWidth());
 		}
 		else if (column->mDynamicWidth)
 		{
-			new_width = (mItemListRect.getWidth() - mTotalStaticColumnWidth) / mNumDynamicWidthColumns;
+			new_width = (mItemListRect.getWidth() - mTotalStaticColumnWidth - mTotalColumnPadding) / mNumDynamicWidthColumns;
 		}
 
-		if (new_width != column->mWidth)
-		{
-			column->mWidth = new_width;
-		}
+		column->setWidth(new_width);
 
 		// update max content width for this column, by looking at all items
 		column->mMaxContentWidth = column->mHeader ? LLFontGL::sSansSerifSmall->getWidth(column->mLabel) + mColumnPadding + HEADING_TEXT_PADDING : 0;
@@ -971,28 +1007,13 @@ void LLScrollListCtrl::updateColumns()
 {
 	calcColumnWidths();
 
-	// propagate column widths to individual cells
-	item_list::iterator iter;
-	for (iter = mItemList.begin(); iter != mItemList.end(); iter++)
-	{
-		LLScrollListItem *itemp = *iter;
-		S32 num_cols = itemp->getNumColumns();
-		S32 i = 0;
-		for (LLScrollListCell* cell = itemp->getColumn(i); i < num_cols; cell = itemp->getColumn(++i))
-		{
-			if (i >= (S32)mColumnsIndexed.size()) break;
-
-			cell->setWidth(mColumnsIndexed[i]->mWidth);
-		}
-	}
-
 	// update column headers
 	std::vector<LLScrollListColumn*>::iterator column_ordered_it;
 	S32 left = mItemListRect.mLeft;
 	LLColumnHeader* last_header = NULL;
 	for (column_ordered_it = mColumnsIndexed.begin(); column_ordered_it != mColumnsIndexed.end(); ++column_ordered_it)
 	{
-		if ((*column_ordered_it)->mWidth < 0)
+		if ((*column_ordered_it)->getWidth() < 0)
 		{
 			// skip hidden columns
 			continue;
@@ -1001,9 +1022,11 @@ void LLScrollListCtrl::updateColumns()
 		
 		if (column->mHeader)
 		{
+			column->mHeader->updateResizeBars();
+
 			last_header = column->mHeader;
 			S32 top = mItemListRect.mTop;
-			S32 right = left + column->mWidth;
+			S32 right = left + column->getWidth();
 
 			if (column->mIndex != (S32)mColumnsIndexed.size()-1)
 			{
@@ -1021,14 +1044,30 @@ void LLScrollListCtrl::updateColumns()
 		}
 	}
 
-	//FIXME: stretch the entire last column if it is resizable (gestures windows shows truncated text in last column)
 	// expand last column header we encountered to full list width
-	if (last_header)
+	if (last_header && last_header->canResize())
 	{
 		S32 new_width = llmax(0, mItemListRect.mRight - last_header->getRect().mLeft);
 		last_header->reshape(new_width, last_header->getRect().getHeight());
 		last_header->setVisible(mDisplayColumnHeaders && new_width > 0);
+		last_header->getColumn()->setWidth(new_width);
+	}
+
+	// propagate column widths to individual cells
+	item_list::iterator iter;
+	for (iter = mItemList.begin(); iter != mItemList.end(); iter++)
+	{
+		LLScrollListItem *itemp = *iter;
+		S32 num_cols = itemp->getNumColumns();
+		S32 i = 0;
+		for (LLScrollListCell* cell = itemp->getColumn(i); i < num_cols; cell = itemp->getColumn(++i))
+		{
+			if (i >= (S32)mColumnsIndexed.size()) break;
+
+			cell->setWidth(mColumnsIndexed[i]->getWidth());
+		}
 	}
+
 }
 
 void LLScrollListCtrl::setDisplayHeading(BOOL display)
@@ -1490,7 +1529,7 @@ BOOL LLScrollListCtrl::selectItemByPrefix(const LLWString& target, BOOL case_sen
 		{
 			LLScrollListItem* item = *iter;
 			// Only select enabled items with matching names
-			LLScrollListCell* cellp = item->getColumn(mSearchColumn);
+			LLScrollListCell* cellp = item->getColumn(getSearchColumn());
 			BOOL select = cellp ? item->getEnabled() && ('\0' == cellp->getValue().asString()[0]) : FALSE;
 			if (select)
 			{
@@ -1513,7 +1552,7 @@ BOOL LLScrollListCtrl::selectItemByPrefix(const LLWString& target, BOOL case_sen
 			LLScrollListItem* item = *iter;
 
 			// Only select enabled items with matching names
-			LLScrollListCell* cellp = item->getColumn(mSearchColumn);
+			LLScrollListCell* cellp = item->getColumn(getSearchColumn());
 			if (!cellp)
 			{
 				continue;
@@ -1743,6 +1782,8 @@ void LLScrollListCtrl::drawItems()
 
 void LLScrollListCtrl::draw()
 {
+	LLLocalClipRect clip(getLocalRect());
+
 	// if user specifies sort, make sure it is maintained
 	if (needsSorting() && !isSorted())
 	{
@@ -1816,7 +1857,7 @@ BOOL LLScrollListCtrl::handleToolTip(S32 x, S32 y, std::string& msg, LLRect* sti
 			S32 rect_left = getColumnOffsetFromIndex(column_index) + mItemListRect.mLeft;
 			S32 rect_bottom = getRowOffsetFromIndex(getItemIndex(hit_item));
 			LLRect cell_rect;
-			cell_rect.setOriginAndSize(rect_left, rect_bottom, rect_left + columnp->mWidth, mLineHeight);
+			cell_rect.setOriginAndSize(rect_left, rect_bottom, rect_left + columnp->getWidth(), mLineHeight);
 			// Convert rect local to screen coordinates
 			localPointToScreen( 
 				cell_rect.mLeft, cell_rect.mBottom, 
@@ -2113,7 +2154,7 @@ S32 LLScrollListCtrl::getColumnIndexFromOffset(S32 x)
 	ordered_columns_t::const_iterator end = mColumnsIndexed.end();
 	for ( ; iter != end; ++iter)
 	{
-		width = (*iter)->mWidth + mColumnPadding;
+		width = (*iter)->getWidth() + mColumnPadding;
 		right += width;
 		if (left <= x && x < right )
 		{
@@ -2140,7 +2181,7 @@ S32 LLScrollListCtrl::getColumnOffsetFromIndex(S32 index)
 		{
 			return column_offset;
 		}
-		column_offset += (*iter)->mWidth + mColumnPadding;
+		column_offset += (*iter)->getWidth() + mColumnPadding;
 	}
 
 	// when running off the end, return the rightmost pixel
@@ -2292,7 +2333,7 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask )
 				{
 					if (getFirstSelected())
 					{
-						LLScrollListCell* cellp = getFirstSelected()->getColumn(mSearchColumn);
+						LLScrollListCell* cellp = getFirstSelected()->getColumn(getSearchColumn());
 						if (cellp)
 						{
 							cellp->highlightText(0, 0);
@@ -2379,7 +2420,7 @@ BOOL LLScrollListCtrl::handleUnicodeCharHere(llwchar uni_char)
 		{
 			LLScrollListItem* item = *iter;
 
-			LLScrollListCell* cellp = item->getColumn(mSearchColumn);
+			LLScrollListCell* cellp = item->getColumn(getSearchColumn());
 			if (cellp)
 			{
 				// Only select enabled items with matching first characters
@@ -2446,7 +2487,7 @@ void LLScrollListCtrl::selectItem(LLScrollListItem* itemp, BOOL select_single_it
 	{
 		if (mLastSelected)
 		{
-			LLScrollListCell* cellp = mLastSelected->getColumn(mSearchColumn);
+			LLScrollListCell* cellp = mLastSelected->getColumn(getSearchColumn());
 			if (cellp)
 			{
 				cellp->highlightText(0, 0);
@@ -2474,7 +2515,7 @@ void LLScrollListCtrl::deselectItem(LLScrollListItem* itemp)
 		}
 
 		itemp->setSelected(FALSE);
-		LLScrollListCell* cellp = itemp->getColumn(mSearchColumn);
+		LLScrollListCell* cellp = itemp->getColumn(getSearchColumn());
 		if (cellp)
 		{
 			cellp->highlightText(0, 0);	
@@ -2501,9 +2542,14 @@ struct SameSortColumn
 	bool operator()(std::pair<S32, BOOL> sort_column) { return sort_column.first == mColumn; }
 };
 
-BOOL LLScrollListCtrl::setSort(S32 column, BOOL ascending)
+BOOL LLScrollListCtrl::setSort(S32 column_idx, BOOL ascending)
 {
-	sort_column_t new_sort_column(column, ascending);
+	LLScrollListColumn* sort_column = getColumn(column_idx);
+	if (!sort_column) return FALSE;
+
+	sort_column->mSortAscending = ascending;
+
+	sort_column_t new_sort_column(column_idx, ascending);
 
 	if (mSortColumns.empty())
 	{
@@ -2517,7 +2563,7 @@ BOOL LLScrollListCtrl::setSort(S32 column, BOOL ascending)
 		
 		// remove any existing sort criterion referencing this column
 		// and add the new one
-		mSortColumns.erase(remove_if(mSortColumns.begin(), mSortColumns.end(), SameSortColumn(column)), mSortColumns.end()); 
+		mSortColumns.erase(remove_if(mSortColumns.begin(), mSortColumns.end(), SameSortColumn(column_idx)), mSortColumns.end()); 
 		mSortColumns.push_back(new_sort_column);
 
 		// did the sort criteria change?
@@ -2643,6 +2689,12 @@ void LLScrollListCtrl::scrollToShowSelected()
 	}
 }
 
+void LLScrollListCtrl::updateStaticColumnWidth(LLScrollListColumn* col, S32 new_width)
+{
+	mTotalStaticColumnWidth += llmax(0, new_width) - llmax(0, col->getWidth());
+}
+
+
 // virtual
 LLXMLNodePtr LLScrollListCtrl::getXML(bool save_children) const
 {
@@ -2689,7 +2741,7 @@ LLXMLNodePtr LLScrollListCtrl::getXML(bool save_children) const
 
 		child_node->createChild("name", TRUE)->setStringValue(column->mName);
 		child_node->createChild("label", TRUE)->setStringValue(column->mLabel);
-		child_node->createChild("width", TRUE)->setIntValue(column->mWidth);
+		child_node->createChild("width", TRUE)->setIntValue(column->getWidth());
 	}
 
 	return node;
@@ -2813,15 +2865,9 @@ LLView* LLScrollListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFac
 
 	scroll_list->setSearchColumn(search_column);
 
-	if (sort_column >= 0)
-	{
-		scroll_list->sortByColumnIndex(sort_column, sort_ascending);
-	}
-
 	LLSD columns;
 	S32 index = 0;
 	LLXMLNodePtr child;
-	S32 total_static = 0;
 	for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling())
 	{
 		if (child->hasName("column"))
@@ -2850,8 +2896,6 @@ LLView* LLScrollListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFac
 			std::string tooltip;
 			child->getAttributeString("tool_tip", tooltip);
 
-			if(!columndynamicwidth) total_static += llmax(0, columnwidth);
-
 			F32 columnrelwidth = 0.f;
 			child->getAttributeF32("relwidth", columnrelwidth);
 
@@ -2872,9 +2916,13 @@ LLView* LLScrollListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFac
 			index++;
 		}
 	}
-	scroll_list->setTotalStaticColumnWidth(total_static);
 	scroll_list->setColumnHeadings(columns);
 
+	if (sort_column >= 0)
+	{
+		scroll_list->sortByColumnIndex(sort_column, sort_ascending);
+	}
+
 	for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling())
 	{
 		if (child->hasName("row"))
@@ -3019,22 +3067,26 @@ void LLScrollListCtrl::addColumn(const LLSD& column, EAddPosition pos)
 	if (mColumns.find(name) == mColumns.end())
 	{
 		// Add column
-		mColumns[name] = LLScrollListColumn(column);
+		mColumns[name] = LLScrollListColumn(column, this);
 		LLScrollListColumn* new_column = &mColumns[name];
 		new_column->mParentCtrl = this;
 		new_column->mIndex = mColumns.size()-1;
 
 		// Add button
-		if (new_column->mWidth > 0 || new_column->mRelWidth > 0 || new_column->mDynamicWidth)
+		if (new_column->getWidth() > 0 || new_column->mRelWidth > 0 || new_column->mDynamicWidth)
 		{
+			if (getNumColumns() > 0)
+			{
+				mTotalColumnPadding += mColumnPadding;
+			}
 			if (new_column->mRelWidth >= 0)
 			{
-				new_column->mWidth = (S32)llround(new_column->mRelWidth*mItemListRect.getWidth());
+				new_column->setWidth((S32)llround(new_column->mRelWidth*mItemListRect.getWidth()));
 			}
 			else if(new_column->mDynamicWidth)
 			{
 				mNumDynamicWidthColumns++;
-				new_column->mWidth = (mItemListRect.getWidth() - mTotalStaticColumnWidth) / mNumDynamicWidthColumns;
+				new_column->setWidth((mItemListRect.getWidth() - mTotalStaticColumnWidth - mTotalColumnPadding) / mNumDynamicWidthColumns);
 			}
 			S32 top = mItemListRect.mTop;
 			S32 left = mItemListRect.mLeft;
@@ -3043,14 +3095,14 @@ void LLScrollListCtrl::addColumn(const LLSD& column, EAddPosition pos)
 				for (itor = mColumns.begin(); itor != mColumns.end(); ++itor)
 				{
 					if (itor->second.mIndex < new_column->mIndex &&
-						itor->second.mWidth > 0)
+						itor->second.getWidth() > 0)
 					{
-						left += itor->second.mWidth + mColumnPadding;
+						left += itor->second.getWidth() + mColumnPadding;
 					}
 				}
 			}
 			std::string button_name = "btn_" + name;
-			S32 right = left+new_column->mWidth;
+			S32 right = left+new_column->getWidth();
 			if (new_column->mIndex != (S32)mColumns.size()-1)
 			{
 				right += mColumnPadding;
@@ -3145,6 +3197,8 @@ void LLScrollListCtrl::clearColumns()
 	}
 	mColumns.clear();
 	mSortColumns.clear();
+	mTotalStaticColumnWidth = 0;
+	mTotalColumnPadding = 0;
 }
 
 void LLScrollListCtrl::setColumnLabel(const std::string& column, const std::string& label)
@@ -3244,7 +3298,7 @@ LLScrollListItem* LLScrollListCtrl::addElement(const LLSD& value, EAddPosition p
 		}
 
 		S32 index = columnp->mIndex;
-		S32 width = columnp->mWidth;
+		S32 width = columnp->getWidth();
 		LLFontGL::HAlign font_alignment = columnp->mFontAlignment;
 		LLColor4 fcolor = LLColor4::black;
 		
@@ -3301,6 +3355,19 @@ LLScrollListItem* LLScrollListCtrl::addElement(const LLSD& value, EAddPosition p
 			}
 			new_item->setColumn(index, cell);
 		}
+		else if (type == "date")
+		{
+			LLScrollListDate* cell = new LLScrollListDate(value.asDate(), font, width, font_style, font_alignment);
+			if (has_color)
+			{
+				cell->setColor(color);
+			}
+			new_item->setColumn(index, cell);
+			if (columnp->mHeader && !value.asString().empty())
+			{
+				columnp->mHeader->setHasResizableElement(TRUE);
+			}
+		}
 		else
 		{
 			LLScrollListText* cell = new LLScrollListText(value.asString(), font, width, font_style, font_alignment, fcolor, TRUE);
@@ -3325,7 +3392,7 @@ LLScrollListItem* LLScrollListCtrl::addElement(const LLSD& value, EAddPosition p
 		if (new_item->getColumn(column_idx) == NULL)
 		{
 			LLScrollListColumn* column_ptr = &column_it->second;
-			new_item->setColumn(column_idx, new LLScrollListText(LLStringUtil::null, LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF_SMALL ), column_ptr->mWidth, LLFontGL::NORMAL));
+			new_item->setColumn(column_idx, new LLScrollListText(LLStringUtil::null, LLResMgr::getInstance()->getRes( LLFONT_SANSSERIF_SMALL ), column_ptr->getWidth(), LLFontGL::NORMAL));
 		}
 	}
 
@@ -3469,6 +3536,7 @@ LLColumnHeader::LLColumnHeader(const std::string& label, const LLRect &rect, LLS
 	mButton->setMouseDownCallback(onMouseDown);
 
 	mButton->setCallbackUserData(this);
+	mButton->setToolTip(label);
 
 	mAscendingText = std::string("[LOW]...[HIGH](Ascending)"); // *TODO: Translate
 	mDescendingText = std::string("[HIGH]...[LOW](Descending)"); // *TODO: Translate
@@ -3556,7 +3624,7 @@ void LLColumnHeader::onClick(void* user_data)
 
 	LLScrollListCtrl::onClickColumn(column);
 
-	// propage new sort order to sort order list
+	// propagate new sort order to sort order list
 	headerp->mList->selectNthItem(column->mParentCtrl->getSortAscending() ? 0 : 1);
 }
 
@@ -3646,7 +3714,7 @@ void LLColumnHeader::showList()
 		text_width = llmax(text_width, LLFontGL::sSansSerifSmall->getWidth(descending_string)) + 10;
 		text_width = llmax(text_width, getRect().getWidth() - 30);
 
-		mList->getColumn(0)->mWidth = text_width;
+		mList->getColumn(0)->setWidth(text_width);
 		((LLScrollListText*)mList->getFirstData()->getColumn(0))->setText(ascending_string);
 		((LLScrollListText*)mList->getLastData()->getColumn(0))->setText(descending_string);
 
@@ -3688,7 +3756,7 @@ LLView*	LLColumnHeader::findSnapEdge(S32& new_edge_val, const LLCoordGL& mouse_d
 	llassert(snap_edge == SNAP_RIGHT);
 
 	// use higher snap threshold for column headers
-	threshold = llmin(threshold, 15);
+	threshold = llmin(threshold, 10);
 
 	LLRect snap_rect = getSnapRect();
 
@@ -3727,47 +3795,48 @@ void LLColumnHeader::userSetShape(const LLRect& new_rect)
 
 	if (delta_width != 0)
 	{
-		S32 remaining_width = delta_width;
+		S32 remaining_width = -delta_width;
 		S32 col;
 		for (col = mColumn->mIndex + 1; col < mColumn->mParentCtrl->getNumColumns(); col++)
 		{
 			LLScrollListColumn* columnp = mColumn->mParentCtrl->getColumn(col);
-			if (!columnp) break;
+			if (!columnp) continue;
 
 			if (columnp->mHeader && columnp->mHeader->canResize())
 			{
 				// how many pixels in width can this column afford to give up?
-				S32 resize_buffer_amt = llmax(0, columnp->mWidth - MIN_COLUMN_WIDTH);
+				S32 resize_buffer_amt = llmax(0, columnp->getWidth() - MIN_COLUMN_WIDTH);
 				
 				// user shrinking column, need to add width to other columns
 				if (delta_width < 0)
 				{
-					if (!columnp->mDynamicWidth && columnp->mWidth > 0)
+					if (/*!columnp->mDynamicWidth && */columnp->getWidth() > 0)
 					{
 						// statically sized column, give all remaining width to this column
-						columnp->mWidth -= remaining_width;
+						columnp->setWidth(columnp->getWidth() + remaining_width);
 						if (columnp->mRelWidth > 0.f)
 						{
-							columnp->mRelWidth = (F32)columnp->mWidth / (F32)mColumn->mParentCtrl->getItemListRect().getWidth();
+							columnp->mRelWidth = (F32)columnp->getWidth() / (F32)mColumn->mParentCtrl->getItemListRect().getWidth();
 						}
+						// all padding went to this widget, we're done
+						break;
 					}
-					break;
 				}
 				else
 				{
 					// user growing column, need to take width from other columns
-					remaining_width -= resize_buffer_amt;
+					remaining_width += resize_buffer_amt;
 
-					if (!columnp->mDynamicWidth && columnp->mWidth > 0)
+					if (/*!columnp->mDynamicWidth && */columnp->getWidth() > 0)
 					{
-						columnp->mWidth -= llmin(columnp->mWidth - MIN_COLUMN_WIDTH, delta_width);
+						columnp->setWidth(columnp->getWidth() - llmin(columnp->getWidth() - MIN_COLUMN_WIDTH, delta_width));
 						if (columnp->mRelWidth > 0.f)
 						{
-							columnp->mRelWidth = (F32)columnp->mWidth / (F32)mColumn->mParentCtrl->getItemListRect().getWidth();
+							columnp->mRelWidth = (F32)columnp->getWidth() / (F32)mColumn->mParentCtrl->getItemListRect().getWidth();
 						}
 					}
 
-					if (remaining_width <= 0)
+					if (remaining_width >= 0)
 					{
 						// width sucked up from neighboring columns, done
 						break;
@@ -3779,14 +3848,14 @@ void LLColumnHeader::userSetShape(const LLRect& new_rect)
 		// clamp resize amount to maximum that can be absorbed by other columns
 		if (delta_width > 0)
 		{
-			delta_width -= llmax(remaining_width, 0);
+			delta_width += llmin(remaining_width, 0);
 		}
 
 		// propagate constrained delta_width to new width for this column
 		new_width = getRect().getWidth() + delta_width - mColumn->mParentCtrl->getColumnPadding();
 
 		// use requested width
-		mColumn->mWidth = new_width;
+		mColumn->setWidth(new_width);
 
 		// update proportional spacing
 		if (mColumn->mRelWidth > 0.f)
@@ -3804,36 +3873,40 @@ void LLColumnHeader::userSetShape(const LLRect& new_rect)
 void LLColumnHeader::setHasResizableElement(BOOL resizable)
 {
 	// for now, dynamically spaced columns can't be resized
-	if (mColumn->mDynamicWidth) return;
+//	if (mColumn->mDynamicWidth) return;
 
-	if (resizable != mHasResizableElement)
+	if (mHasResizableElement != resizable)
 	{
+		mColumn->mParentCtrl->dirtyColumns();
 		mHasResizableElement = resizable;
+	}
+}
 
-		S32 num_resizable_columns = 0;
-		S32 col;
-		for (col = 0; col < mColumn->mParentCtrl->getNumColumns(); col++)
+void LLColumnHeader::updateResizeBars()
+{
+	S32 num_resizable_columns = 0;
+	S32 col;
+	for (col = 0; col < mColumn->mParentCtrl->getNumColumns(); col++)
+	{
+		LLScrollListColumn* columnp = mColumn->mParentCtrl->getColumn(col);
+		if (columnp->mHeader && columnp->mHeader->canResize())
 		{
-			LLScrollListColumn* columnp = mColumn->mParentCtrl->getColumn(col);
-			if (columnp->mHeader && columnp->mHeader->canResize())
-			{
-				num_resizable_columns++;
-			}
+			num_resizable_columns++;
 		}
+	}
 
-		S32 num_resizers_enabled = 0;
+	S32 num_resizers_enabled = 0;
 
-		// now enable/disable resize handles on resizable columns if we have at least two
-		for (col = 0; col < mColumn->mParentCtrl->getNumColumns(); col++)
+	// now enable/disable resize handles on resizable columns if we have at least two
+	for (col = 0; col < mColumn->mParentCtrl->getNumColumns(); col++)
+	{
+		LLScrollListColumn* columnp = mColumn->mParentCtrl->getColumn(col);
+		if (!columnp->mHeader) continue;
+		BOOL enable = num_resizable_columns >= 2 && num_resizers_enabled < (num_resizable_columns - 1) && columnp->mHeader->canResize();
+		columnp->mHeader->enableResizeBar(enable);
+		if (enable)
 		{
-			LLScrollListColumn* columnp = mColumn->mParentCtrl->getColumn(col);
-			if (!columnp->mHeader) continue;
-			BOOL enable = num_resizable_columns >= 2 && num_resizers_enabled < (num_resizable_columns - 1) && columnp->mHeader->canResize();
-			columnp->mHeader->enableResizeBar(enable);
-			if (enable)
-			{
-				num_resizers_enabled++;
-			}
+			num_resizers_enabled++;
 		}
 	}
 }
@@ -3841,7 +3914,7 @@ void LLColumnHeader::setHasResizableElement(BOOL resizable)
 void LLColumnHeader::enableResizeBar(BOOL enable)
 {
 	// for now, dynamically spaced columns can't be resized
-	if (!mColumn->mDynamicWidth)
+	//if (!mColumn->mDynamicWidth)
 	{
 		mResizeBar->setEnabled(enable);
 	}
@@ -3851,3 +3924,78 @@ BOOL LLColumnHeader::canResize()
 {
 	return getVisible() && (mHasResizableElement || mColumn->mDynamicWidth);
 }
+
+void LLScrollListColumn::setWidth(S32 width) 
+{ 
+	if (!mDynamicWidth && mRelWidth <= 0.f) 
+	{
+		mParentCtrl->updateStaticColumnWidth(this, width);
+	}
+	mWidth = width;
+}
+
+// Default constructor
+LLScrollListColumn::LLScrollListColumn() : 
+	mName(), 
+	mSortingColumn(), 
+	mSortAscending(TRUE), 
+	mLabel(), 
+	mWidth(-1), 
+	mRelWidth(-1.0), 
+	mDynamicWidth(FALSE), 
+	mMaxContentWidth(0),
+	mIndex(-1), 
+	mParentCtrl(NULL), 
+	mHeader(NULL), 
+	mFontAlignment(LLFontGL::LEFT)
+{ }
+
+LLScrollListColumn::LLScrollListColumn(const LLSD &sd, LLScrollListCtrl* parent) :
+	mWidth(0),
+	mIndex (-1),
+	mParentCtrl(parent),
+	mHeader(NULL),
+	mMaxContentWidth(0),
+	mDynamicWidth(FALSE),
+	mRelWidth(-1.f)
+{
+	mName = sd.get("name").asString();
+	mSortingColumn = mName;
+	if (sd.has("sort"))
+	{
+		mSortingColumn = sd.get("sort").asString();
+	}
+	mSortAscending = TRUE;
+	if (sd.has("sort_ascending"))
+	{
+		mSortAscending = sd.get("sort_ascending").asBoolean();
+	}
+	mLabel = sd.get("label").asString();
+	if (sd.has("relwidth") && (F32)sd.get("relwidth").asReal() > 0)
+	{
+		mRelWidth = (F32)sd.get("relwidth").asReal();
+		if (mRelWidth < 0) mRelWidth = 0;
+		if (mRelWidth > 1) mRelWidth = 1;
+		mDynamicWidth = FALSE;
+	}
+	else if(sd.has("dynamicwidth") && (BOOL)sd.get("dynamicwidth").asBoolean() == TRUE)
+	{
+		mDynamicWidth = TRUE;
+		mRelWidth = -1;
+	}
+	else
+	{
+
+		setWidth(sd.get("width").asInteger());
+	}
+
+	if (sd.has("halign"))
+	{
+		mFontAlignment = (LLFontGL::HAlign)llclamp(sd.get("halign").asInteger(), (S32)LLFontGL::LEFT, (S32)LLFontGL::HCENTER);
+	}
+	else
+	{
+		mFontAlignment = LLFontGL::LEFT;
+	}
+
+}
diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h
index 0128c01ebaf..d8ef955042c 100644
--- a/indra/llui/llscrolllistctrl.h
+++ b/indra/llui/llscrolllistctrl.h
@@ -47,6 +47,7 @@
 #include "llcombobox.h"
 #include "llscrollbar.h"
 #include "llresizebar.h"
+#include "lldate.h"
 
 /*
  * Represents a cell in a scrollable table.
@@ -133,6 +134,18 @@ class LLScrollListText : public LLScrollListCell
 	static U32 sCount;
 };
 
+
+class LLScrollListDate : public LLScrollListText
+{
+public:
+	LLScrollListDate( const LLDate& date, const LLFontGL* font, S32 width=0, U8 font_style = LLFontGL::NORMAL, LLFontGL::HAlign font_alignment = LLFontGL::LEFT, LLColor4& color = LLColor4::black, BOOL use_color = FALSE, BOOL visible = TRUE);
+	virtual void	setValue(const LLSD& value);
+	virtual const LLSD getValue() const;
+
+private:
+	LLDate		mDate;
+};
+
 /*
  * Cell displaying an image.
  */
@@ -185,88 +198,11 @@ class LLScrollListCheck : public LLScrollListCell
 class LLScrollListColumn
 {
 public:
-	// Default constructor
-	LLScrollListColumn() : 
-		mName(), 
-		mSortingColumn(), 
-		mSortAscending(TRUE), 
-		mLabel(), 
-		mWidth(-1), 
-		mRelWidth(-1.0), 
-		mDynamicWidth(FALSE), 
-		mMaxContentWidth(0),
-		mIndex(-1), 
-		mParentCtrl(NULL), 
-		mHeader(NULL), 
-		mFontAlignment(LLFontGL::LEFT)
-	{ }
-
-	LLScrollListColumn(std::string name, std::string label, S32 width, F32 relwidth) : 
-		mName(name), 
-		mSortingColumn(name), 
-        	mSortAscending(TRUE), 
-		mLabel(label), 
-		mWidth(width), 
-		mRelWidth(relwidth), 
-		mDynamicWidth(FALSE), 
-		mMaxContentWidth(0),
-		mIndex(-1), 
-		mParentCtrl(NULL), 
-		mHeader(NULL),
-		mFontAlignment(LLFontGL::LEFT)
-	{ }
-
-	LLScrollListColumn(const LLSD &sd)
-	{
-		mMaxContentWidth = 0;
-
-		mName = sd.get("name").asString();
-		mSortingColumn = mName;
-		if (sd.has("sort"))
-		{
-			mSortingColumn = sd.get("sort").asString();
-		}
-		mSortAscending = TRUE;
-		if (sd.has("sort_ascending"))
-		{
-			mSortAscending = sd.get("sort_ascending").asBoolean();
-		}
-		mLabel = sd.get("label").asString();
-		if (sd.has("relwidth") && (F32)sd.get("relwidth").asReal() > 0)
-		{
-			mRelWidth = (F32)sd.get("relwidth").asReal();
-			if (mRelWidth < 0) mRelWidth = 0;
-			if (mRelWidth > 1) mRelWidth = 1;
-			mDynamicWidth = FALSE;
-			mWidth = 0;
-		}
-		else if(sd.has("dynamicwidth") && (BOOL)sd.get("dynamicwidth").asBoolean() == TRUE)
-		{
-			mDynamicWidth = TRUE;
-			mRelWidth = -1;
-			mWidth = 0;
-		}
-		else
-		{
-			mWidth = sd.get("width").asInteger();
-			mDynamicWidth = FALSE;
-			mRelWidth = -1;
-		}
-
-		if (sd.has("halign"))
-		{
-			mFontAlignment = (LLFontGL::HAlign)llclamp(sd.get("halign").asInteger(), (S32)LLFontGL::LEFT, (S32)LLFontGL::HCENTER);
-		}
-		else
-		{
-			mFontAlignment = LLFontGL::LEFT;
-		}
-
-		mIndex = -1;
-		mParentCtrl = NULL;
-		mHeader = NULL;
-		mFontAlignment = LLFontGL::LEFT;
-	}
+	LLScrollListColumn();
+	LLScrollListColumn(const LLSD &sd, LLScrollListCtrl* parent);
+
+	void setWidth(S32 width);
+	S32 getWidth() const { return mWidth; }
 
 	// Public data is fine so long as this remains a simple struct-like data class.
 	// If it ever gets any smarter than that, these should all become private
@@ -275,7 +211,6 @@ class LLScrollListColumn
 	std::string			mSortingColumn;
 	BOOL				mSortAscending;
 	std::string			mLabel;
-	S32					mWidth;
 	F32					mRelWidth;
 	BOOL				mDynamicWidth;
 	S32					mMaxContentWidth;
@@ -283,6 +218,10 @@ class LLScrollListColumn
 	LLScrollListCtrl*	mParentCtrl;
 	class LLColumnHeader*		mHeader;
 	LLFontGL::HAlign	mFontAlignment;
+
+private:
+	S32					mWidth;
+
 };
 
 class LLColumnHeader : public LLComboBox
@@ -301,6 +240,7 @@ class LLColumnHeader : public LLComboBox
 	void setImage(const std::string &image_name);
 	LLScrollListColumn* getColumn() { return mColumn; }
 	void setHasResizableElement(BOOL resizable);
+	void updateResizeBars();
 	BOOL canResize();
 	void enableResizeBar(BOOL enable);
 	std::string getLabel() { return mOrigLabel; }
@@ -551,8 +491,7 @@ class LLScrollListCtrl : public LLUICtrl, public LLEditMenuHandler,
 
 	virtual S32		getScrollPos() const;
 	virtual void	setScrollPos( S32 pos );
-
-	S32				getSearchColumn() { return mSearchColumn; }
+	S32 getSearchColumn();
 	void			setSearchColumn(S32 column) { mSearchColumn = column; }
 	S32				getColumnIndexFromOffset(S32 x);
 	S32				getColumnOffsetFromIndex(S32 index);
@@ -613,8 +552,9 @@ class LLScrollListCtrl : public LLUICtrl, public LLEditMenuHandler,
 	virtual void	deselect();
 	virtual BOOL	canDeselect() const;
 
-	void setNumDynamicColumns(int num) { mNumDynamicWidthColumns = num; }
-	void setTotalStaticColumnWidth(int width) { mTotalStaticColumnWidth = width; }
+	void setNumDynamicColumns(S32 num) { mNumDynamicWidthColumns = num; }
+	void updateStaticColumnWidth(LLScrollListColumn* col, S32 new_width);
+	S32 getTotalStaticColumnWidth() { return mTotalStaticColumnWidth; }
 
 	std::string     getSortColumnName();
 	BOOL			getSortAscending() { return mSortColumns.empty() ? TRUE : mSortColumns.back().second; }
@@ -719,6 +659,7 @@ class LLScrollListCtrl : public LLUICtrl, public LLEditMenuHandler,
 	S32				mSearchColumn;
 	S32				mNumDynamicWidthColumns;
 	S32				mTotalStaticColumnWidth;
+	S32				mTotalColumnPadding;
 
 	BOOL			mSorted;
 	
diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp
index a4b16dc2dee..7b2c97af67c 100644
--- a/indra/llui/llui.cpp
+++ b/indra/llui/llui.cpp
@@ -30,6 +30,7 @@
  */
 
 // Utilities functions the user interface needs
+
 #include "linden_common.h"
 
 #include <string>
@@ -65,6 +66,7 @@ std::map<std::string, std::string> gTranslation;
 std::list<std::string> gUntranslated;
 
 LLControlGroup* LLUI::sConfigGroup = NULL;
+LLControlGroup* LLUI::sIgnoresGroup = NULL;
 LLControlGroup* LLUI::sColorsGroup = NULL;
 LLImageProviderInterface* LLUI::sImageProvider = NULL;
 LLUIAudioCallback LLUI::sAudioCallback = NULL;
@@ -90,7 +92,7 @@ void make_ui_sound(const char* namep)
 		LLUUID uuid(LLUI::sConfigGroup->getString(name));		
 		if (uuid.isNull())
 		{
-			if ("00000000-0000-0000-0000-000000000000" == LLUI::sConfigGroup->getString(name))
+			if (LLUI::sConfigGroup->getString(name) == LLUUID::null.asString())
 			{
 				if (LLUI::sConfigGroup->getBOOL("UISndDebugSpamToggle"))
 				{
@@ -1552,6 +1554,7 @@ bool handleShowXUINamesChanged(const LLSD& newvalue)
 }
 
 void LLUI::initClass(LLControlGroup* config, 
+					 LLControlGroup* ignores, 
 					 LLControlGroup* colors, 
 					 LLImageProviderInterface* image_provider,
 					 LLUIAudioCallback audio_callback,
@@ -1559,7 +1562,16 @@ void LLUI::initClass(LLControlGroup* config,
 					 const std::string& language)
 {
 	sConfigGroup = config;
+	sIgnoresGroup = ignores;
 	sColorsGroup = colors;
+
+	if (sConfigGroup == NULL
+		|| sIgnoresGroup == NULL
+		|| sColorsGroup == NULL)
+	{
+		llerrs << "Failure to initialize configuration groups" << llendl;
+	}
+
 	sImageProvider = image_provider;
 	sAudioCallback = audio_callback;
 	sGLScaleFactor = (scale_factor == NULL) ? LLVector2(1.f, 1.f) : *scale_factor;
@@ -1567,7 +1579,7 @@ void LLUI::initClass(LLControlGroup* config,
 	LLFontGL::sShadowColor = colors->getColor("ColorDropShadow");
 
 	LLUI::sShowXUINames = LLUI::sConfigGroup->getBOOL("ShowXUINames");
-	LLUI::sConfigGroup->getControl("ShowXUINames")->getSignal()->connect(boost::bind(&handleShowXUINamesChanged, _1));
+	LLUI::sConfigGroup->getControl("ShowXUINames")->getSignal()->connect(&handleShowXUINamesChanged);
 }
 
 void LLUI::cleanupClass()
diff --git a/indra/llui/llui.h b/indra/llui/llui.h
index e2629ee2a4a..4366c387404 100644
--- a/indra/llui/llui.h
+++ b/indra/llui/llui.h
@@ -42,6 +42,7 @@
 #include "llgl.h"			// *TODO: break this dependency
 #include <stack>
 //#include "llimagegl.h"
+#include <boost/signal.hpp>
 
 // LLUIFactory
 #include "llsd.h"
@@ -150,11 +151,13 @@ typedef	void (*LLUIAudioCallback)(const LLUUID& uuid);
 
 class LLUI
 {
+	LOG_CLASS(LLUI);
 public:
 	//
 	// Methods
 	//
 	static void initClass(LLControlGroup* config, 
+						  LLControlGroup* ignores,
 						  LLControlGroup* colors, 
 						  LLImageProviderInterface* image_provider,
 						  LLUIAudioCallback audio_callback = NULL,
@@ -190,6 +193,7 @@ class LLUI
 	// Data
 	//
 	static LLControlGroup* sConfigGroup;
+	static LLControlGroup* sIgnoresGroup;
 	static LLControlGroup* sColorsGroup;
 	static LLImageProviderInterface* sImageProvider;
 	static LLUIAudioCallback sAudioCallback;
@@ -597,4 +601,237 @@ class LLImageProviderInterface
 	virtual void cleanUp() = 0;
 };
 
+// This mix-in class adds support for tracking all instances of the specificed class parameter T
+// The (optional) key associates a value of type KEY with a given instance of T, for quick lookup
+// If KEY is not provided, then instances are stored in a simple list
+template<typename T, typename KEY = T*>
+class LLInstanceTracker : boost::noncopyable
+{
+public:
+	typedef typename std::map<KEY, T*>::iterator instance_iter;
+	typedef typename std::map<KEY, T*>::const_iterator instance_const_iter;
+
+	static T* getInstance(KEY k) { instance_iter found = sInstances.find(k); return (found == sInstances.end()) ? NULL : found->second; }
+
+	static instance_iter beginInstances() { return sInstances.begin(); }
+	static instance_iter endInstances() { return sInstances.end(); }
+	static S32 instanceCount() { return sInstances.size(); }
+protected:
+	LLInstanceTracker(KEY key) { add(key); }
+	virtual ~LLInstanceTracker() { remove(); }
+	virtual void setKey(KEY key) { remove(); add(key); }
+	virtual const KEY& getKey() const { return mKey; }
+
+private:
+	void add(KEY key) 
+	{ 
+		mKey = key; 
+		sInstances[key] = static_cast<T*>(this); 
+	}
+	void remove() { sInstances.erase(mKey); }
+
+private:
+
+	KEY mKey;
+	static std::map<KEY, T*> sInstances;
+};
+
+template<typename T>
+class LLInstanceTracker<T, T*> : boost::noncopyable
+{
+public:
+	typedef typename std::set<T*>::iterator instance_iter;
+	typedef typename std::set<T*>::const_iterator instance_const_iter;
+
+	static instance_iter instancesBegin() { return sInstances.begin(); }
+	static instance_iter instancesEnd() { return sInstances.end(); }
+	static S32 instanceCount() { return sInstances.size(); }
+
+protected:
+	LLInstanceTracker() { sInstances.insert(static_cast<T*>(this)); }
+	virtual ~LLInstanceTracker() { sInstances.erase(static_cast<T*>(this)); }
+
+	static std::set<T*> sInstances;
+};
+
+template <typename T, typename KEY> std::map<KEY, T*> LLInstanceTracker<T, KEY>::sInstances;
+template <typename T> std::set<T*> LLInstanceTracker<T, T*>::sInstances;
+
+class LLCallbackRegistry
+{
+public:
+	typedef boost::signal<void()> callback_signal_t;
+	
+	void registerCallback(const callback_signal_t::slot_type& slot)
+	{
+		mCallbacks.connect(slot);
+	}
+
+	void fireCallbacks()
+	{
+		mCallbacks();
+	}
+
+private:
+	callback_signal_t mCallbacks;
+};
+
+class LLInitClassList : 
+	public LLCallbackRegistry, 
+	public LLSingleton<LLInitClassList>
+{
+	friend class LLSingleton<LLInitClassList>;
+private:
+	LLInitClassList() {}
+};
+
+class LLDestroyClassList : 
+	public LLCallbackRegistry, 
+	public LLSingleton<LLDestroyClassList>
+{
+	friend class LLSingleton<LLDestroyClassList>;
+private:
+	LLDestroyClassList() {}
+};
+
+template<typename T>
+class LLRegisterWith
+{
+public:
+	LLRegisterWith(boost::function<void ()> func)
+	{
+		T::instance().registerCallback(func);
+	}
+
+	// this avoids a MSVC bug where non-referenced static members are "optimized" away
+	// even if their constructors have side effects
+	void reference()
+	{
+		S32 dummy;
+		dummy = 0;
+	}
+};
+
+template<typename T>
+class LLInitClass
+{
+public:
+	LLInitClass() { sRegister.reference(); }
+
+	static LLRegisterWith<LLInitClassList> sRegister;
+private:
+
+	static void initClass()
+	{
+		llerrs << "No static initClass() method defined for " << typeid(T).name() << llendl;
+	}
+};
+
+template<typename T>
+class LLDestroyClass
+{
+public:
+	LLDestroyClass() { sRegister.reference(); }
+
+	static LLRegisterWith<LLDestroyClassList> sRegister;
+private:
+
+	static void destroyClass()
+	{
+		llerrs << "No static destroyClass() method defined for " << typeid(T).name() << llendl;
+	}
+};
+
+template <typename T> LLRegisterWith<LLInitClassList> LLInitClass<T>::sRegister(&T::initClass);
+template <typename T> LLRegisterWith<LLDestroyClassList> LLDestroyClass<T>::sRegister(&T::destroyClass);
+
+
+template <typename DERIVED>
+class LLParamBlock
+{
+protected:
+	LLParamBlock() { sBlock = (DERIVED*)this; }
+
+	typedef typename boost::add_const<DERIVED>::type Tconst;
+
+	template <typename T>
+	class LLMandatoryParam
+	{
+	public:
+		typedef typename boost::add_const<T>::type T_const;
+
+		LLMandatoryParam(T_const initial_val) : mVal(initial_val), mBlock(sBlock) {}
+		LLMandatoryParam(const LLMandatoryParam<T>& other) : mVal(other.mVal) {}
+
+		DERIVED& operator ()(T_const set_value) { mVal = set_value; return *mBlock; }
+		operator T() const { return mVal; } 
+		T operator=(T_const set_value) { mVal = set_value; return mVal; }
+
+	private: 
+		T	mVal;
+		DERIVED* mBlock;
+	};
+
+	template <typename T>
+	class LLOptionalParam
+	{
+	public:
+		typedef typename boost::add_const<T>::type T_const;
+
+		LLOptionalParam(T_const initial_val) : mVal(initial_val), mBlock(sBlock) {}
+		LLOptionalParam() : mBlock(sBlock) {}
+		LLOptionalParam(const LLOptionalParam<T>& other) : mVal(other.mVal) {}
+
+		DERIVED& operator ()(T_const set_value) { mVal = set_value; return *mBlock; }
+		operator T() const { return mVal; } 
+		T operator=(T_const set_value) { mVal = set_value; return mVal; }
+
+	private:
+		T	mVal;
+		DERIVED* mBlock;
+	};
+
+	// specialization that requires initialization for reference types 
+	template <typename T>
+	class LLOptionalParam <T&>
+	{
+	public:
+		typedef typename boost::add_const<T&>::type T_const;
+
+		LLOptionalParam(T_const initial_val) : mVal(initial_val), mBlock(sBlock) {}
+		LLOptionalParam(const LLOptionalParam<T&>& other) : mVal(other.mVal) {}
+
+		DERIVED& operator ()(T_const set_value) { mVal = set_value; return *mBlock; }
+		operator T&() const { return mVal; } 
+		T& operator=(T_const set_value) { mVal = set_value; return mVal; }
+
+	private:
+		T&	mVal;
+		DERIVED* mBlock;
+	};
+
+	// specialization that initializes pointer params to NULL
+	template<typename T> 
+	class LLOptionalParam<T*>
+	{
+	public:
+		typedef typename boost::add_const<T*>::type T_const;
+
+		LLOptionalParam(T_const initial_val) : mVal(initial_val), mBlock(sBlock) {}
+		LLOptionalParam() : mVal((T*)NULL), mBlock(sBlock)  {}
+		LLOptionalParam(const LLOptionalParam<T*>& other) : mVal(other.mVal) {}
+
+		DERIVED& operator ()(T_const set_value) { mVal = set_value; return *mBlock; }
+		operator T*() const { return mVal; } 
+		T* operator=(T_const set_value) { mVal = set_value; return mVal; }
+	private:
+		T*	mVal;
+		DERIVED* mBlock;
+	};
+
+	static DERIVED* sBlock;
+};
+
+template <typename T> T* LLParamBlock<T>::sBlock = NULL;
+
 #endif
diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp
index f7419d615b4..6e822f7c03e 100644
--- a/indra/llui/lluictrl.cpp
+++ b/indra/llui/lluictrl.cpp
@@ -475,10 +475,10 @@ BOOL LLUICtrl::focusPrevItem(BOOL text_fields_only)
 	return focusPrev(result);
 }
 
-LLUICtrl* LLUICtrl::findRootMostFocusRoot() const
+LLUICtrl* LLUICtrl::findRootMostFocusRoot()
 {
-	const LLUICtrl* focus_root = NULL;
-	const LLUICtrl* next_view = this;
+	LLUICtrl* focus_root = NULL;
+	LLUICtrl* next_view = this;
 	while(next_view)
 	{
 		if (next_view->isFocusRoot())
@@ -487,9 +487,8 @@ LLUICtrl* LLUICtrl::findRootMostFocusRoot() const
 		}
 		next_view = next_view->getParentUICtrl();
 	}
-	// since focus_root could be this, need to cast away const to return
-	// a non-const result
-	return const_cast<LLUICtrl*>(focus_root);
+
+	return focus_root;
 }
 
 
diff --git a/indra/llui/lluictrl.h b/indra/llui/lluictrl.h
index 4ad9042b9a6..7d1f504f799 100644
--- a/indra/llui/lluictrl.h
+++ b/indra/llui/lluictrl.h
@@ -141,7 +141,7 @@ class LLUICtrl
 	
 	static LLView* fromXML(LLXMLNodePtr node, LLView* parent, class LLUICtrlFactory* factory);
 
-	LLUICtrl*		findRootMostFocusRoot() const;
+	LLUICtrl*		findRootMostFocusRoot();
 
 	class LLTextInputFilter : public LLQueryFilter, public LLSingleton<LLTextInputFilter>
 	{
diff --git a/indra/llui/lluictrlfactory.h b/indra/llui/lluictrlfactory.h
index 3e22e196b0c..dfcea7290e4 100644
--- a/indra/llui/lluictrlfactory.h
+++ b/indra/llui/lluictrlfactory.h
@@ -78,6 +78,7 @@ class LLUICtrlFactory : public LLSingleton<LLUICtrlFactory>
 	static bool getLayeredXMLNode(const std::string &filename, LLXMLNodePtr& root);
 
 private:
+	bool getLayeredXMLNodeImpl(const std::string &filename, LLXMLNodePtr& root);
 
 	typedef std::map<LLHandle<LLPanel>, std::string> built_panel_t;
 	built_panel_t mBuiltPanels;
diff --git a/indra/llui/lluistring.cpp b/indra/llui/lluistring.cpp
index 0dde20934c2..51768ad8854 100644
--- a/indra/llui/lluistring.cpp
+++ b/indra/llui/lluistring.cpp
@@ -31,6 +31,7 @@
 
 #include "linden_common.h"
 #include "lluistring.h"
+#include "llsd.h"
 
 const LLStringUtil::format_map_t LLUIString::sNullArgs;
 
@@ -54,6 +55,18 @@ void LLUIString::setArgList(const LLStringUtil::format_map_t& args)
 	format();
 }
 
+void LLUIString::setArgs(const LLSD& sd)
+{
+	if (!sd.isMap()) return;
+	for(LLSD::map_const_iterator sd_it = sd.beginMap();
+		sd_it != sd.endMap();
+		++sd_it)
+	{
+		setArg(sd_it->first, sd_it->second.asString());
+	}
+	format();
+}
+
 void LLUIString::setArg(const std::string& key, const std::string& replacement)
 {
 	mArgs[key] = replacement;
diff --git a/indra/llui/lluistring.h b/indra/llui/lluistring.h
index 773bc097634..c99aeb50c69 100644
--- a/indra/llui/lluistring.h
+++ b/indra/llui/lluistring.h
@@ -50,9 +50,9 @@
 // llinfos << mMessage.getString() << llendl; // outputs "Welcome Steve to Second Life"
 // mMessage.setArg("[USERNAME]", "Joe");
 // llinfos << mMessage.getString() << llendl; // outputs "Welcome Joe to Second Life"
-// mMessage = "Recepción a la [SECONDLIFE] [USERNAME]"
+// mMessage = "Recepci￳n a la [SECONDLIFE] [USERNAME]"
 // mMessage.setArg("[SECONDLIFE]", "Segunda Vida");
-// llinfos << mMessage.getString() << llendl; // outputs "Recepción a la Segunda Vida Joe"
+// llinfos << mMessage.getString() << llendl; // outputs "Recepci￳n a la Segunda Vida Joe"
 
 // Implementation Notes:
 // Attempting to have operator[](const std::string& s) return mArgs[s] fails because we have
@@ -71,6 +71,8 @@ class LLUIString
 	LLUIString& operator=(const std::string& s) { assign(s); return *this; }
 
 	void setArgList(const LLStringUtil::format_map_t& args);
+	void setArgs(const LLStringUtil::format_map_t& args) { setArgList(args); }
+	void setArgs(const class LLSD& sd);
 	void setArg(const std::string& key, const std::string& replacement);
 
 	const std::string& getString() const { return mResult; }
diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp
index 3e7e59876c6..65e9417b8b8 100644
--- a/indra/llui/llview.cpp
+++ b/indra/llui/llview.cpp
@@ -1260,7 +1260,7 @@ void LLView::draw()
 	{
 		LLView *viewp = *child_iter;
 
-		if (viewp->getVisible() && viewp != focus_view)
+		if (viewp->getVisible() && viewp != focus_view && viewp->getRect().isValid())
 		{
 			// Only draw views that are within the root view
 			localRectToScreen(viewp->getRect(),&screenRect);
@@ -1357,7 +1357,8 @@ void LLView::drawChild(LLView* childp, S32 x_offset, S32 y_offset, BOOL force_dr
 	{
 		++sDepth;
 
-		if (childp->getVisible() || force_draw)
+		if ((childp->getVisible() && childp->getRect().isValid()) 
+			|| force_draw)
 		{
 			glMatrixMode(GL_MODELVIEW);
 			LLUI::pushMatrix();
diff --git a/indra/llui/llview.h b/indra/llui/llview.h
index ff7a1afb387..ae0df615994 100644
--- a/indra/llui/llview.h
+++ b/indra/llui/llview.h
@@ -485,7 +485,7 @@ class LLView : public LLMouseHandler, public LLMortician
 			// did we find *something* with that name?
 			if (child)
 			{
-				llwarns << "Found child named " << name << " but of wrong type" << llendl;
+				llwarns << "Found child named " << name << " but of wrong type " << typeid(child).name() << ", expecting " << typeid(T).name() << llendl;
 			}
 			if (create_if_missing)
 			{
@@ -496,6 +496,11 @@ class LLView : public LLMouseHandler, public LLMortician
 		return result;
 	}
 
+	template <class T> T& getChildRef(const std::string& name, BOOL recurse = TRUE) const
+	{
+		return *getChild<T>(name, recurse, TRUE);
+	}
+
 	virtual LLView* getChildView(const std::string& name, BOOL recurse = TRUE, BOOL create_if_missing = TRUE) const;
 
 	template <class T> T* createDummyWidget(const std::string& name) const
diff --git a/indra/llxml/llxmlnode.cpp b/indra/llxml/llxmlnode.cpp
index 750c1fc1eff..aef1488e514 100644
--- a/indra/llxml/llxmlnode.cpp
+++ b/indra/llxml/llxmlnode.cpp
@@ -65,6 +65,9 @@ LLXMLNode::LLXMLNode() :
 	mEncoding(ENCODING_DEFAULT),
 	mParent(NULL),
 	mChildren(NULL),
+	mAttributes(),
+	mPrev(NULL),
+	mNext(NULL),
 	mName(NULL), 
 	mValue(""), 
 	mDefault(NULL)
@@ -83,6 +86,9 @@ LLXMLNode::LLXMLNode(const char* name, BOOL is_attribute) :
 	mEncoding(ENCODING_DEFAULT),
 	mParent(NULL),
 	mChildren(NULL),
+	mAttributes(),
+	mPrev(NULL),
+	mNext(NULL),
 	mValue(""), 
 	mDefault(NULL)
 {
@@ -101,17 +107,65 @@ LLXMLNode::LLXMLNode(LLStringTableEntry* name, BOOL is_attribute) :
 	mEncoding(ENCODING_DEFAULT),
 	mParent(NULL),
 	mChildren(NULL),
+	mAttributes(),
+	mPrev(NULL),
+	mNext(NULL),
 	mName(name),
 	mValue(""), 
 	mDefault(NULL)
 {
 }
 
+// copy constructor (except for the children)
+LLXMLNode::LLXMLNode(const LLXMLNode& rhs) : 
+	mID(rhs.mID),
+	mIsAttribute(rhs.mIsAttribute),
+	mVersionMajor(rhs.mVersionMajor), 
+	mVersionMinor(rhs.mVersionMinor), 
+	mLength(rhs.mLength), 
+	mPrecision(rhs.mPrecision),
+	mType(rhs.mType),
+	mEncoding(rhs.mEncoding),
+	mParent(NULL),
+	mChildren(NULL),
+	mAttributes(),
+	mPrev(NULL),
+	mNext(NULL),
+	mName(rhs.mName), 
+	mValue(rhs.mValue), 
+	mDefault(rhs.mDefault)
+{
+}
+
+// returns a new copy of this node and all its children
+LLXMLNodePtr LLXMLNode::deepCopy()
+{
+	LLXMLNodePtr newnode = LLXMLNodePtr(new LLXMLNode(*this));
+	if (mChildren.notNull())
+	{
+		for (LLXMLChildList::iterator iter = mChildren->map.begin();
+			 iter != mChildren->map.end(); ++iter)
+		{
+			newnode->addChild(iter->second->deepCopy());
+		}
+	}
+	for (LLXMLAttribList::iterator iter = mAttributes.begin();
+		 iter != mAttributes.end(); ++iter)
+	{
+		newnode->addChild(iter->second->deepCopy());
+	}
+
+	return newnode;
+}
+
 // virtual
 LLXMLNode::~LLXMLNode()
 {
 	// Strictly speaking none of this should be required execept 'delete mChildren'...
-	if (mChildren)
+	// Sadly, that's only true if we hadn't had reference-counted smart pointers linked
+	// in three different directions. This entire class is a frightening, hard-to-maintain
+	// mess.
+	if (mChildren.notNull())
 	{
 		for (LLXMLChildList::iterator iter = mChildren->map.begin();
 			 iter != mChildren->map.end(); ++iter)
@@ -124,7 +178,7 @@ LLXMLNode::~LLXMLNode()
 		mChildren->map.clear();
 		mChildren->head = NULL;
 		mChildren->tail = NULL;
-		delete mChildren;
+		mChildren = NULL;
 	}
 	for (LLXMLAttribList::iterator iter = mAttributes.begin();
 		 iter != mAttributes.end(); ++iter)
@@ -160,7 +214,7 @@ BOOL LLXMLNode::removeChild(LLXMLNode *target_child)
 			return TRUE;
 		}
 	}
-	else if (mChildren)
+	else if (mChildren.notNull())
 	{
 		LLXMLChildList::iterator children_itr = mChildren->map.find(target_child->mName);
 		while (children_itr != mChildren->map.end())
@@ -183,7 +237,6 @@ BOOL LLXMLNode::removeChild(LLXMLNode *target_child)
 				mChildren->map.erase(children_itr);
 				if (mChildren->map.empty())
 				{
-					delete mChildren;
 					mChildren = NULL;
 				}
 				return TRUE;
@@ -201,7 +254,7 @@ BOOL LLXMLNode::removeChild(LLXMLNode *target_child)
 	return FALSE;
 }
 
-void LLXMLNode::addChild(LLXMLNodePtr new_child)
+void LLXMLNode::addChild(LLXMLNodePtr new_child, LLXMLNodePtr after_child)
 {
 	if (new_child->mParent != NULL)
 	{
@@ -219,7 +272,7 @@ void LLXMLNode::addChild(LLXMLNodePtr new_child)
 	}
 	else
 	{
-		if (!mChildren)
+		if (mChildren.isNull())
 		{
 			mChildren = new LLXMLChildren();
 			mChildren->head = new_child;
@@ -227,11 +280,33 @@ void LLXMLNode::addChild(LLXMLNodePtr new_child)
 		}
 		mChildren->map.insert(std::make_pair(new_child->mName, new_child));
 
-		if (mChildren->tail != new_child)
+		// if after_child is specified, it damn well better be in the list of children
+		// for this node. I'm not going to assert that, because it would be expensive,
+		// but don't specify that parameter if you didn't get the value for it from the
+		// list of children of this node!
+		if (after_child.isNull())
 		{
-			mChildren->tail->mNext = new_child;
-			new_child->mPrev = mChildren->tail;
-			mChildren->tail = new_child;
+			if (mChildren->tail != new_child)
+			{
+				mChildren->tail->mNext = new_child;
+				new_child->mPrev = mChildren->tail;
+				mChildren->tail = new_child;
+			}
+		}
+		else
+		{
+			if (after_child->mNext.notNull())
+			{
+				// if after_child was not the last item, fix up some pointers
+				after_child->mNext->mPrev = new_child;
+				new_child->mNext = after_child->mNext;
+			}
+			new_child->mPrev = after_child;
+			after_child->mNext = new_child;
+			if (mChildren->tail == after_child)
+			{
+				mChildren->tail = new_child;
+			}
 		}
 	}
 
@@ -293,7 +368,7 @@ void LLXMLNode::updateDefault()
 		}
 	}
 
-	if (mChildren)
+	if (mChildren.notNull())
 	{
 		LLXMLChildList::const_iterator children_itr;
 		LLXMLChildList::const_iterator children_end = mChildren->map.end();
@@ -566,6 +641,24 @@ bool LLXMLNode::updateNode(
 }
 
 
+// static 
+LLXMLNodePtr LLXMLNode::replaceNode(LLXMLNodePtr node, LLXMLNodePtr update_node)
+{	
+	if (!node || !update_node)
+	{
+		llwarns << "Node invalid" << llendl;
+		return node;
+	}
+	
+	LLXMLNodePtr cloned_node = update_node->deepCopy();
+	node->mParent->addChild(cloned_node, node);	// add after node
+	LLXMLNodePtr parent = node->mParent;
+	parent->removeChild(node);
+	parent->updateDefault();
+	
+	return cloned_node;
+}
+
 
 
 // static
@@ -618,7 +711,7 @@ bool LLXMLNode::parseBuffer(
 	{
 		llwarns << "Error parsing xml error code: "
 				<< XML_ErrorString(XML_GetErrorCode(my_parser))
-				<< " on lne " << XML_GetCurrentLineNumber(my_parser)
+				<< " on line " << XML_GetCurrentLineNumber(my_parser)
 				<< llendl;
 	}
 
@@ -722,7 +815,7 @@ BOOL LLXMLNode::isFullyDefault()
 		&& has_default_length
 		&& has_default_attribute)
 	{
-		if (mChildren)
+		if (mChildren.notNull())
 		{
 			LLXMLChildList::const_iterator children_itr;
 			LLXMLChildList::const_iterator children_end = mChildren->map.end();
@@ -888,7 +981,7 @@ void LLXMLNode::writeToOstream(std::ostream& output_stream, const std::string& i
 		}
 	}
 
-	if (!mChildren && mValue == "")
+	if (mChildren.isNull() && mValue == "")
 	{
 		output_stream << " />\n";
 		return;
@@ -896,7 +989,7 @@ void LLXMLNode::writeToOstream(std::ostream& output_stream, const std::string& i
 	else
 	{
 		output_stream << ">\n";
-		if (mChildren)
+		if (mChildren.notNull())
 		{
 			// stream non-attributes
 			std::string next_indent = indent + "\t";
@@ -922,7 +1015,7 @@ void LLXMLNode::findName(const std::string& name, LLXMLNodeList &results)
 		results.insert(std::make_pair(this->mName->mString, this));
 		return;
 	}
-	if (mChildren)
+	if (mChildren.notNull())
 	{
 		LLXMLChildList::const_iterator children_itr;
 		LLXMLChildList::const_iterator children_end = mChildren->map.end();
@@ -941,7 +1034,7 @@ void LLXMLNode::findName(LLStringTableEntry* name, LLXMLNodeList &results)
 		results.insert(std::make_pair(this->mName->mString, this));
 		return;
 	}
-	if (mChildren)
+	if (mChildren.notNull())
 	{
 		LLXMLChildList::const_iterator children_itr;
 		LLXMLChildList::const_iterator children_end = mChildren->map.end();
@@ -960,7 +1053,7 @@ void LLXMLNode::findID(const std::string& id, LLXMLNodeList &results)
 		results.insert(std::make_pair(this->mName->mString, this));
 		return;
 	}
-	if (mChildren)
+	if (mChildren.notNull())
 	{
 		LLXMLChildList::const_iterator children_itr;
 		LLXMLChildList::const_iterator children_end = mChildren->map.end();
@@ -974,11 +1067,11 @@ void LLXMLNode::findID(const std::string& id, LLXMLNodeList &results)
 
 void LLXMLNode::scrubToTree(LLXMLNode *tree)
 {
-	if (!tree || !tree->mChildren)
+	if (!tree || tree->mChildren.isNull())
 	{
 		return;
 	}
-	if (mChildren)
+	if (mChildren.notNull())
 	{
 		std::vector<LLXMLNodePtr> to_delete_list;
 		LLXMLChildList::iterator itor = mChildren->map.begin();
@@ -1023,7 +1116,7 @@ bool LLXMLNode::getChild(const char* name, LLXMLNodePtr& node, BOOL use_default_
 
 bool LLXMLNode::getChild(const LLStringTableEntry* name, LLXMLNodePtr& node, BOOL use_default_if_missing)
 {
-	if (mChildren)
+	if (mChildren.notNull())
 	{
 		LLXMLChildList::const_iterator child_itr = mChildren->map.find(name);
 		if (child_itr != mChildren->map.end())
@@ -1047,7 +1140,7 @@ void LLXMLNode::getChildren(const char* name, LLXMLNodeList &children, BOOL use_
 
 void LLXMLNode::getChildren(const LLStringTableEntry* name, LLXMLNodeList &children, BOOL use_default_if_missing) const
 {
-	if (mChildren)
+	if (mChildren.notNull())
 	{
 		LLXMLChildList::const_iterator child_itr = mChildren->map.find(name);
 		if (child_itr != mChildren->map.end())
@@ -1071,6 +1164,25 @@ void LLXMLNode::getChildren(const LLStringTableEntry* name, LLXMLNodeList &child
 	}
 }
 
+// recursively walks the tree and returns all children at all nesting levels matching the name
+void LLXMLNode::getDescendants(const LLStringTableEntry* name, LLXMLNodeList &children) const
+{
+	if (mChildren.notNull())
+	{
+		for (LLXMLChildList::const_iterator child_itr = mChildren->map.begin();
+			 child_itr != mChildren->map.end(); ++child_itr)
+		{
+			LLXMLNodePtr child = (*child_itr).second;
+			if (name == child->mName)
+			{
+				children.insert(std::make_pair(child->mName->mString, child));
+			}
+			// and check each child as well
+			child->getDescendants(name, children);
+		}
+	}
+}
+
 bool LLXMLNode::getAttribute(const char* name, LLXMLNodePtr& node, BOOL use_default_if_missing)
 {
     return getAttribute(gStringTable.checkStringEntry(name), node, use_default_if_missing);
@@ -1111,6 +1223,23 @@ BOOL LLXMLNode::hasAttribute(const char* name )
 	return getAttribute(name, node);
 }
 
+// the structure of these getAttribute_ functions is ugly, but it's because the
+// underlying system is based on BOOL and LLString; if we change
+// so that they're based on more generic mechanisms, these will be
+// simplified.
+bool LLXMLNode::getAttribute_bool(const char* name, bool& value )
+{
+	LLXMLNodePtr node;
+    if (!getAttribute(name, node))
+    {
+        return false;
+    }
+    BOOL temp;
+	bool retval = node->getBoolValue(1, &temp);
+    value = temp;
+    return retval;
+}
+
 BOOL LLXMLNode::getAttributeBOOL(const char* name, BOOL& value )
 {
 	LLXMLNodePtr node;
@@ -2521,7 +2650,7 @@ void LLXMLNode::setName(LLStringTableEntry* name)
 
 U32 LLXMLNode::getChildCount() const 
 { 
-	if (mChildren)
+	if (mChildren.notNull())
 	{
 		return mChildren->map.size(); 
 	}
@@ -2540,7 +2669,7 @@ U32 get_rand(U32 max_value)
 
 LLXMLNode *get_rand_node(LLXMLNode *node)
 {
-	if (node->mChildren)
+	if (node->mChildren.notNull())
 	{
 		U32 num_children = node->mChildren->map.size();
 		if (get_rand(2) == 0)
@@ -2748,7 +2877,7 @@ void LLXMLNode::createUnitTest(S32 max_num_children)
 
 BOOL LLXMLNode::performUnitTest(std::string &error_buffer)
 {
-	if (!mChildren)
+	if (mChildren.isNull())
 	{
 		error_buffer.append(llformat("ERROR Node %s: No children found.\n", mName->mString));
 		return FALSE;
@@ -3007,14 +3136,14 @@ BOOL LLXMLNode::performUnitTest(std::string &error_buffer)
 	return TRUE;
 }
 
-LLXMLNodePtr LLXMLNode::getFirstChild()
+LLXMLNodePtr LLXMLNode::getFirstChild() const
 {
-	if (!mChildren) return NULL;
+	if (mChildren.isNull()) return NULL;
 	LLXMLNodePtr ret = mChildren->head;
 	return ret;
 }
 
-LLXMLNodePtr LLXMLNode::getNextSibling()
+LLXMLNodePtr LLXMLNode::getNextSibling() const
 {
 	LLXMLNodePtr ret = mNext;
 	return ret;
diff --git a/indra/llxml/llxmlnode.h b/indra/llxml/llxmlnode.h
index 5ca726effed..dec225dde6f 100644
--- a/indra/llxml/llxmlnode.h
+++ b/indra/llxml/llxmlnode.h
@@ -87,12 +87,13 @@ class LLVector3d;
 class LLVector4;
 class LLVector4U;
 
-struct LLXMLChildren
+struct LLXMLChildren : public LLThreadSafeRefCount
 {
 	LLXMLChildList map;			// Map of children names->pointers
 	LLXMLNodePtr head;			// Head of the double-linked list
 	LLXMLNodePtr tail;			// Tail of the double-linked list
 };
+typedef LLPointer<LLXMLChildren> LLXMLChildrenPtr;
 
 class LLXMLNode : public LLThreadSafeRefCount
 {
@@ -124,11 +125,13 @@ class LLXMLNode : public LLThreadSafeRefCount
 	LLXMLNode();
 	LLXMLNode(const char* name, BOOL is_attribute);
 	LLXMLNode(LLStringTableEntry* name, BOOL is_attribute);
+	LLXMLNode(const LLXMLNode& rhs);
+	LLXMLNodePtr deepCopy();
 
 	BOOL isNull();
 
 	BOOL deleteChild(LLXMLNode* child);
-    void addChild(LLXMLNodePtr new_parent); 
+    void addChild(LLXMLNodePtr new_child, LLXMLNodePtr after_child = LLXMLNodePtr(NULL)); 
     void setParent(LLXMLNodePtr new_parent); // reparent if necessary
 
     // Serialization
@@ -146,8 +149,9 @@ class LLXMLNode : public LLThreadSafeRefCount
 		LLXMLNodePtr& node, 
 		LLXMLNode* defaults);
 	static bool updateNode(
-	LLXMLNodePtr& node,
-	LLXMLNodePtr& update_node);
+		LLXMLNodePtr& node,
+		LLXMLNodePtr& update_node);
+	static LLXMLNodePtr replaceNode(LLXMLNodePtr node, LLXMLNodePtr replacement_node);
 	static void writeHeaderToFile(LLFILE *fOut);
     void writeToFile(LLFILE *fOut, const std::string& indent = std::string());
     void writeToOstream(std::ostream& output_stream, const std::string& indent = std::string());
@@ -176,6 +180,10 @@ class LLXMLNode : public LLThreadSafeRefCount
 
 	BOOL hasAttribute(const char* name );
 
+        // these are designed to be more generic versions of the functions
+    // rather than relying on LL-types
+    bool getAttribute_bool(const char* name, bool& value ); 
+
 	BOOL getAttributeBOOL(const char* name, BOOL& value );
 	BOOL getAttributeU8(const char* name, U8& value );
 	BOOL getAttributeS8(const char* name, S8& value );
@@ -211,13 +219,16 @@ class LLXMLNode : public LLThreadSafeRefCount
     bool getChild(const LLStringTableEntry* name, LLXMLNodePtr& node, BOOL use_default_if_missing = TRUE);
     void getChildren(const char* name, LLXMLNodeList &children, BOOL use_default_if_missing = TRUE) const;
     void getChildren(const LLStringTableEntry* name, LLXMLNodeList &children, BOOL use_default_if_missing = TRUE) const;
+	
+	// recursively finds all children at any level matching name
+	void getDescendants(const LLStringTableEntry* name, LLXMLNodeList &children) const;
 
 	bool getAttribute(const char* name, LLXMLNodePtr& node, BOOL use_default_if_missing = TRUE);
 	bool getAttribute(const LLStringTableEntry* name, LLXMLNodePtr& node, BOOL use_default_if_missing = TRUE);
 
 	// The following skip over attributes
-	LLXMLNodePtr getFirstChild();
-	LLXMLNodePtr getNextSibling();
+	LLXMLNodePtr getFirstChild() const;
+	LLXMLNodePtr getNextSibling() const;
 
     LLXMLNodePtr getRoot();
 
@@ -251,7 +262,6 @@ class LLXMLNode : public LLThreadSafeRefCount
 	void setName(LLStringTableEntry* name);
 
 	// Escapes " (quot) ' (apos) & (amp) < (lt) > (gt)
-	// TomY TODO: Make this private
 	static std::string escapeXML(const std::string& xml);
 
 	// Set the default node corresponding to this default node
@@ -291,7 +301,7 @@ class LLXMLNode : public LLThreadSafeRefCount
 	Encoding mEncoding;			// The value encoding
 
 	LLXMLNode* mParent;				// The parent node
-	LLXMLChildren* mChildren;		// The child nodes
+	LLXMLChildrenPtr mChildren;		// The child nodes
 	LLXMLAttribList mAttributes;		// The attribute nodes
 	LLXMLNodePtr mPrev;				// Double-linked list previous node
 	LLXMLNodePtr mNext;				// Double-linked list next node
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 21e491e1b5b..0be8b53d41a 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -169,6 +169,7 @@ set(viewer_SOURCE_FILES
     llfloatermute.cpp
     llfloaternamedesc.cpp
     llfloaternewim.cpp
+    llfloaternotificationsconsole.cpp
     llfloaterobjectiminfo.cpp
     llfloateropenobject.cpp
     llfloaterparcel.cpp
@@ -570,6 +571,7 @@ set(viewer_HEADER_FILES
     llfloatermute.h
     llfloaternamedesc.h
     llfloaternewim.h
+    llfloaternotificationsconsole.h
     llfloaterobjectiminfo.h
     llfloateropenobject.h
     llfloaterparcel.h
@@ -1091,6 +1093,8 @@ set(viewer_XUI_FILES
     skins/default/xui/en-us/floater_name_description.xml
     skins/default/xui/en-us/floater_new_im.xml
     skins/default/xui/en-us/floater_new_outfit_dialog.xml
+    skins/default/xui/en-us/floater_notifications_console.xml
+    skins/default/xui/en-us/floater_notification.xml
     skins/default/xui/en-us/floater_object_im_info.xml
     skins/default/xui/en-us/floater_openobject.xml
     skins/default/xui/en-us/floater_pay_object.xml
@@ -1149,6 +1153,7 @@ set(viewer_XUI_FILES
     skins/default/xui/en-us/menu_slurl.xml
     skins/default/xui/en-us/menu_viewer.xml
     skins/default/xui/en-us/mime_types.xml
+    skins/default/xui/en-us/notifications.xml
     skins/default/xui/en-us/notify.xml
     skins/default/xui/en-us/panel_audio_device.xml
     skins/default/xui/en-us/panel_audio.xml
@@ -1177,6 +1182,7 @@ set(viewer_XUI_FILES
     skins/default/xui/en-us/panel_media_controls.xml
     skins/default/xui/en-us/panel_media_remote_expanded.xml
     skins/default/xui/en-us/panel_media_remote.xml
+    skins/default/xui/en-us/panel_notifications_channel.xml
     skins/default/xui/en-us/panel_overlaybar.xml
     skins/default/xui/en-us/panel_place_small.xml
     skins/default/xui/en-us/panel_place.xml
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 13fc1650100..b2f9f0a2ca0 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -55,6 +55,17 @@
         <real>1.0</real>
       </array>
     </map>
+    <key>AlertedUnsupportedHardware</key>
+    <map>
+      <key>Comment</key>
+      <string>Set if there's unsupported hardware and we've already done a notification.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
     <key>AllowIdleAFK</key>
     <map>
       <key>Comment</key>
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 7eca956f7db..55b74abd627 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -583,7 +583,7 @@ void LLAgent::onAppFocusGained()
 
 void LLAgent::ageChat()
 {
-	if (mAvatarObject)
+	if (mAvatarObject.notNull())
 	{
 		// get amount of time since I last chatted
 		F64 elapsed_time = (F64)mAvatarObject->mChatTimer.getElapsedTimeF32();
@@ -600,7 +600,7 @@ void LLAgent::unlockView()
 {
 	if (getFocusOnAvatar())
 	{
-		if (mAvatarObject)
+		if (mAvatarObject.notNull())
 		{
 			setFocusGlobal( LLVector3d::zero, mAvatarObject->mID );
 		}
@@ -1017,7 +1017,7 @@ void LLAgent::sendReliableMessage()
 //-----------------------------------------------------------------------------
 LLVector3 LLAgent::getVelocity() const
 {
-	if (mAvatarObject)
+	if (mAvatarObject.notNull())
 	{
 		return mAvatarObject->getVelocity();
 	}
@@ -1038,7 +1038,7 @@ void LLAgent::setPositionAgent(const LLVector3 &pos_agent)
 		llerrs << "setPositionAgent is not a number" << llendl;
 	}
 
-	if (!mAvatarObject.isNull() && mAvatarObject->getParent())
+	if (mAvatarObject.notNull() && mAvatarObject->getParent())
 	{
 		LLVector3 pos_agent_sitting;
 		LLVector3d pos_agent_d;
@@ -1076,7 +1076,7 @@ void LLAgent::slamLookAt(const LLVector3 &look_at)
 //-----------------------------------------------------------------------------
 const LLVector3d &LLAgent::getPositionGlobal() const
 {
-	if (!mAvatarObject.isNull() && !mAvatarObject->mDrawable.isNull())
+	if (mAvatarObject.notNull() && !mAvatarObject->mDrawable.isNull())
 	{
 		mPositionGlobal = getPosGlobalFromAgent(mAvatarObject->getRenderPosition());
 	}
@@ -1093,7 +1093,7 @@ const LLVector3d &LLAgent::getPositionGlobal() const
 //-----------------------------------------------------------------------------
 const LLVector3 &LLAgent::getPositionAgent()
 {
-	if(!mAvatarObject.isNull() && !mAvatarObject->mDrawable.isNull())
+	if(mAvatarObject.notNull() && !mAvatarObject->mDrawable.isNull())
 	{
 		mFrameAgent.setOrigin(mAvatarObject->getRenderPosition());	
 	}
@@ -2345,11 +2345,11 @@ void LLAgent::stopAutoPilot(BOOL user_cancel)
 		if (user_cancel && !mAutoPilotBehaviorName.empty())
 		{
 			if (mAutoPilotBehaviorName == "Sit")
-				LLNotifyBox::showXml("CancelledSit");
+				LLNotifications::instance().add("CancelledSit");
 			else if (mAutoPilotBehaviorName == "Attach")
-				LLNotifyBox::showXml("CancelledAttach");
+				LLNotifications::instance().add("CancelledAttach");
 			else
-				LLNotifyBox::showXml("Cancelled");
+				LLNotifications::instance().add("Cancelled");
 		}
 	}
 }
@@ -2374,7 +2374,7 @@ void LLAgent::autoPilot(F32 *delta_yaw)
 			mAutoPilotTargetGlobal = object->getPositionGlobal();
 		}
 		
-		if (!mAvatarObject)
+		if (mAvatarObject.isNull())
 		{
 			return;
 		}
@@ -2455,7 +2455,7 @@ void LLAgent::autoPilot(F32 *delta_yaw)
 		// If we're flying, handle autopilot points above or below you.
 		if (getFlying() && xy_distance < AUTOPILOT_HEIGHT_ADJUST_DISTANCE)
 		{
-			if (mAvatarObject)
+			if (mAvatarObject.notNull())
 			{
 				F64 current_height = mAvatarObject->getPositionGlobal().mdV[VZ];
 				F32 delta_z = (F32)(mAutoPilotTargetGlobal.mdV[VZ] - current_height);
@@ -2540,7 +2540,7 @@ void LLAgent::propagate(const F32 dt)
 	pitch(PITCH_RATE * (F32) mPitchKey * dt);
 	
 	// handle auto-land behavior
-	if (mAvatarObject)
+	if (mAvatarObject.notNull())
 	{
 		BOOL in_air = mAvatarObject->mInAir;
 		LLVector3 land_vel = getVelocity();
@@ -2591,7 +2591,7 @@ void LLAgent::updateLookAt(const S32 mouse_x, const S32 mouse_y)
 	static LLVector3 last_at_axis;
 
 
-	if ( mAvatarObject.isNull() )
+	if (mAvatarObject.isNull())
 	{
 		return;
 	}
@@ -2864,7 +2864,7 @@ void LLAgent::endAnimationUpdateUI()
 		}
 
 		// Disable mouselook-specific animations
-		if (mAvatarObject)
+		if (mAvatarObject.notNull())
 		{
 			if( mAvatarObject->isAnyAnimationSignaled(AGENT_GUN_AIM_ANIMS, NUM_AGENT_GUN_AIM_ANIMS) )
 			{
@@ -2910,7 +2910,7 @@ void LLAgent::endAnimationUpdateUI()
 			gMorphView->setVisible( FALSE );
 		}
 
-		if (mAvatarObject)
+		if (mAvatarObject.notNull())
 		{
 			if(mCustomAnim)
 			{
@@ -2953,7 +2953,7 @@ void LLAgent::endAnimationUpdateUI()
 		gIMMgr->setFloaterOpen( FALSE );
 		gConsole->setVisible( TRUE );
 
-		if (mAvatarObject)
+		if (mAvatarObject.notNull())
 		{
 			// Trigger mouselook-specific animations
 			if( mAvatarObject->isAnyAnimationSignaled(AGENT_GUN_HOLD_ANIMS, NUM_AGENT_GUN_HOLD_ANIMS) )
@@ -3014,7 +3014,7 @@ void LLAgent::endAnimationUpdateUI()
 		}
 
 		// freeze avatar
-		if (mAvatarObject)
+		if (mAvatarObject.notNull())
 		{
 			mPauseRequest = mAvatarObject->requestPause();
 		}
@@ -3048,7 +3048,7 @@ void LLAgent::updateCamera()
 
 	validateFocusObject();
 
-	if (!mAvatarObject.isNull() && 
+	if (mAvatarObject.notNull() && 
 		mAvatarObject->mIsSitting &&
 		camera_mode == CAMERA_MODE_MOUSELOOK)
 	{
@@ -3162,7 +3162,7 @@ void LLAgent::updateCamera()
 	//Ventrella
 	if ( mCameraMode == CAMERA_MODE_FOLLOW )
 	{
-		if ( !mAvatarObject.isNull() )
+		if ( mAvatarObject.notNull() )
 		{
 			//--------------------------------------------------------------------------------
 			// this is where the avatar's position and rotation are given to followCam, and 
@@ -3472,7 +3472,7 @@ LLVector3d LLAgent::calcFocusPositionTargetGlobal()
 	{
 		LLVector3d at_axis(1.0, 0.0, 0.0);
 		LLQuaternion agent_rot = mFrameAgent.getQuaternion();
-		if (!mAvatarObject.isNull() && mAvatarObject->getParent())
+		if (mAvatarObject.notNull() && mAvatarObject->getParent())
 		{
 			LLViewerObject* root_object = (LLViewerObject*)mAvatarObject->getRoot();
 			if (!root_object->flagCameraDecoupled())
@@ -3770,7 +3770,7 @@ LLVector3d LLAgent::calcCameraPositionTargetGlobal(BOOL *hit_limit)
 			camera_offset.setVec( local_camera_offset );
 			camera_position_global = frame_center_global + head_offset + camera_offset;
 
-			if (!mAvatarObject.isNull())
+			if (mAvatarObject.notNull())
 			{
 				LLVector3d camera_lag_d;
 				F32 lag_interp = LLCriticalDamp::getInterpolant(CAMERA_LAG_HALF_LIFE);
@@ -4001,7 +4001,7 @@ void LLAgent::changeCameraToMouselook(BOOL animate)
 	gSavedSettings.setBOOL("ThirdPersonBtnState",	FALSE);
 	gSavedSettings.setBOOL("BuildBtnState",			FALSE);
 
-	if (mAvatarObject)
+	if (mAvatarObject.notNull())
 	{
 		mAvatarObject->stopMotion( ANIM_AGENT_BODY_NOISE );
 		mAvatarObject->stopMotion( ANIM_AGENT_BREATHE_ROT );
@@ -4089,7 +4089,7 @@ void LLAgent::changeCameraToFollow(BOOL animate)
 			LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset);
 		}
 
-		if (mAvatarObject)
+		if (mAvatarObject.notNull())
 		{
 			mAvatarObject->mPelvisp->setPosition(LLVector3::zero);
 			mAvatarObject->startMotion( ANIM_AGENT_BODY_NOISE );
@@ -4137,7 +4137,7 @@ void LLAgent::changeCameraToThirdPerson(BOOL animate)
 
 	mCameraZoomFraction = INITIAL_ZOOM_FRACTION;
 
-	if (mAvatarObject)
+	if (mAvatarObject.notNull())
 	{
 		if (!mAvatarObject->mIsSitting)
 		{
@@ -4183,7 +4183,7 @@ void LLAgent::changeCameraToThirdPerson(BOOL animate)
 	}
 
 	// Remove any pitch from the avatar
-	if (!mAvatarObject.isNull() && mAvatarObject->getParent())
+	if (mAvatarObject.notNull() && mAvatarObject->getParent())
 	{
 		LLQuaternion obj_rot = ((LLViewerObject*)mAvatarObject->getParent())->getRenderRotation();
 		at_axis = LLViewerCamera::getInstance()->getAtAxis();
@@ -4262,7 +4262,7 @@ void LLAgent::changeCameraToCustomizeAvatar(BOOL avatar_animate, BOOL camera_ani
 		LLVOAvatar::onCustomizeStart();
 	}
 
-	if (!mAvatarObject.isNull())
+	if (mAvatarObject.notNull())
 	{
 		if(avatar_animate)
 		{
@@ -4362,7 +4362,7 @@ void LLAgent::setFocusGlobal(const LLVector3d& focus, const LLUUID &object_id)
 	{
 		if (focus.isExactlyZero())
 		{
-			if (!mAvatarObject.isNull())
+			if (mAvatarObject.notNull())
 			{
 				mFocusTargetGlobal = getPosGlobalFromAgent(mAvatarObject->mHeadp->getWorldPosition());
 			}
@@ -4407,7 +4407,7 @@ void LLAgent::setFocusGlobal(const LLVector3d& focus, const LLUUID &object_id)
 	{
 		if (focus.isExactlyZero())
 		{
-			if (!mAvatarObject.isNull())
+			if (mAvatarObject.notNull())
 			{
 				mFocusTargetGlobal = getPosGlobalFromAgent(mAvatarObject->mHeadp->getWorldPosition());
 			}
@@ -4544,7 +4544,7 @@ void LLAgent::setFocusOnAvatar(BOOL focus_on_avatar, BOOL animate)
 		if (mCameraMode == CAMERA_MODE_THIRD_PERSON)
 		{
 			LLVector3 at_axis;
-			if (!mAvatarObject.isNull() && mAvatarObject->getParent())
+			if (mAvatarObject.notNull() && mAvatarObject->getParent())
 			{
 				LLQuaternion obj_rot = ((LLViewerObject*)mAvatarObject->getParent())->getRenderRotation();
 				at_axis = LLViewerCamera::getInstance()->getAtAxis();
@@ -4611,7 +4611,7 @@ void LLAgent::lookAtLastChat()
 		if (chatter->isAvatar())
 		{
 			LLVOAvatar *chatter_av = (LLVOAvatar*)chatter;
-			if (!mAvatarObject.isNull() && chatter_av->mHeadp)
+			if (mAvatarObject.notNull() && chatter_av->mHeadp)
 			{
 				delta_pos = chatter_av->mHeadp->getWorldPosition() - mAvatarObject->mHeadp->getWorldPosition();
 			}
@@ -4692,7 +4692,7 @@ void LLAgent::setStartPosition( U32 location_id )
       LLVector3 agent_pos = getPositionAgent();
       LLVector3 agent_look_at = mFrameAgent.getAtAxis();
 
-      if (mAvatarObject)
+      if (mAvatarObject.notNull())
       {
 	// the z height is at the agent's feet
 	agent_pos.mV[VZ] -= 0.5f * mAvatarObject->mBodySize.mV[VZ];
@@ -4853,7 +4853,7 @@ void LLAgent::setTeen(bool teen)
 
 void LLAgent::buildFullname(std::string& name) const
 {
-	if (mAvatarObject)
+	if (mAvatarObject.notNull())
 	{
 		name = mAvatarObject->getFullname();
 	}
@@ -4871,7 +4871,7 @@ void LLAgent::buildFullnameAndTitle(std::string& name) const
 		name.erase(0, name.length());
 	}
 
-	if (mAvatarObject)
+	if (mAvatarObject.notNull())
 	{
 		name += mAvatarObject->getFullname();
 	}
@@ -5226,7 +5226,7 @@ void LLAgent::getName(std::string& name)
 {
 	name.clear();
 
-	if (mAvatarObject)
+	if (mAvatarObject.notNull())
 	{
 		LLNameValue *first_nv = mAvatarObject->getNVPair("FirstName");
 		LLNameValue *last_nv = mAvatarObject->getNVPair("LastName");
@@ -6726,7 +6726,7 @@ void LLAgent::onInitialWearableAssetArrived( LLWearable* wearable, void* userdat
 void LLAgent::recoverMissingWearable( EWearableType type )
 {
 	// Try to recover by replacing missing wearable with a new one.
-	LLNotifyBox::showXml("ReplacedMissingWearable");
+	LLNotifications::instance().add("ReplacedMissingWearable");
 	lldebugs << "Wearable " << LLWearable::typeToTypeLabel( type ) << " could not be downloaded.  Replaced inventory item with default wearable." << llendl;
 	LLWearable* new_wearable = gWearableList.createNewWearable(type);
 
@@ -7157,8 +7157,10 @@ void LLAgent::removeWearable( EWearableType type )
 	{
 		if( old_wearable->isDirty() )
 		{
+			LLSD payload;
+			payload["wearable_type"] = (S32)type;
 			// Bring up view-modal dialog: Save changes? Yes, No, Cancel
-			gViewerWindow->alertXml("WearableSave", LLAgent::onRemoveWearableDialog, (void*)type );
+			LLNotifications::instance().add("WearableSave", LLSD(), payload, &LLAgent::onRemoveWearableDialog);
 			return;
 		}
 		else
@@ -7169,9 +7171,10 @@ void LLAgent::removeWearable( EWearableType type )
 }
 
 // static 
-void LLAgent::onRemoveWearableDialog( S32 option, void* userdata )
+bool LLAgent::onRemoveWearableDialog(const LLSD& notification, const LLSD& response )
 {
-	EWearableType type = (EWearableType)(intptr_t)userdata;
+	S32 option = LLNotification::getSelectedOption(notification, response);
+	EWearableType type = (EWearableType)notification["payload"]["wearable_type"].asInteger();
 	switch( option )
 	{
 	case 0:  // "Save"
@@ -7190,6 +7193,7 @@ void LLAgent::onRemoveWearableDialog( S32 option, void* userdata )
 		llassert(0);
 		break;
 	}
+	return false;
 }
 
 // Called by removeWearable() and onRemoveWearableDialog() to actually do the removal.
@@ -7388,8 +7392,9 @@ void LLAgent::setWearable( LLInventoryItem* new_item, LLWearable* new_wearable )
 		if( old_wearable->isDirty() )
 		{
 			// Bring up modal dialog: Save changes? Yes, No, Cancel
-			gViewerWindow->alertXml( "WearableSave", LLAgent::onSetWearableDialog,
-				new LLSetWearableData( new_item->getUUID(), new_wearable ));
+			LLSD payload;
+			payload["item_id"] = new_item->getUUID();
+			LLNotifications::instance().add( "WearableSave", LLSD(), payload, boost::bind(LLAgent::onSetWearableDialog, _1, _2, new_wearable));
 			return;
 		}
 	}
@@ -7398,25 +7403,25 @@ void LLAgent::setWearable( LLInventoryItem* new_item, LLWearable* new_wearable )
 }
 
 // static 
-void LLAgent::onSetWearableDialog( S32 option, void* userdata )
+bool LLAgent::onSetWearableDialog( const LLSD& notification, const LLSD& response, LLWearable* wearable )
 {
-	LLSetWearableData* data = (LLSetWearableData*)userdata;
-	LLInventoryItem* new_item = gInventory.getItem( data->mNewItemID );
+	S32 option = LLNotification::getSelectedOption(notification, response);
+	LLInventoryItem* new_item = gInventory.getItem( notification["payload"]["item_id"].asUUID());
 	if( !new_item )
 	{
-		delete data;
-		return;
+		delete wearable;
+		return false;
 	}
 
 	switch( option )
 	{
 	case 0:  // "Save"
-		gAgent.saveWearable( data->mNewWearable->getType() );
-		gAgent.setWearableFinal( new_item, data->mNewWearable );
+		gAgent.saveWearable( wearable->getType() );
+		gAgent.setWearableFinal( new_item, wearable );
 		break;
 
 	case 1:  // "Don't Save"
-		gAgent.setWearableFinal( new_item, data->mNewWearable );
+		gAgent.setWearableFinal( new_item, wearable );
 		break;
 
 	case 2: // "Cancel"
@@ -7427,7 +7432,8 @@ void LLAgent::onSetWearableDialog( S32 option, void* userdata )
 		break;
 	}
 
-	delete data;
+	delete wearable;
+	return false;
 }
 
 // Called from setWearable() and onSetWearableDialog() to actually set the wearable.
diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h
index f561f55e466..f1e0bc93081 100644
--- a/indra/newview/llagent.h
+++ b/indra/newview/llagent.h
@@ -591,10 +591,8 @@ class LLAgent : public LLObservable
 	//--------------------------------------------------------------------
 	// Wearables
 	//--------------------------------------------------------------------
-	BOOL			getWearablesLoaded() const	{ return mWearablesLoaded; }
-
 	void			setWearable( LLInventoryItem* new_item, LLWearable* wearable );
-	static void		onSetWearableDialog( S32 option, void* userdata );
+	static bool		onSetWearableDialog( const LLSD& notification, const LLSD& response, LLWearable* wearable );
 	void			setWearableFinal( LLInventoryItem* new_item, LLWearable* new_wearable );
 	void			setWearableOutfit( 	const LLInventoryItem::item_array_t& items, const LLDynamicArray< LLWearable* >& wearables, BOOL remove );
 	void			queryWearableCache();
@@ -624,7 +622,7 @@ class LLAgent : public LLObservable
 	void			makeNewOutfitDone(S32 index);
 
 	void			removeWearable( EWearableType type );
-	static void		onRemoveWearableDialog( S32 option, void* userdata );
+	static bool		onRemoveWearableDialog(const LLSD& notification, const LLSD& response );
 	void			removeWearableFinal( EWearableType type );
 	
 	void			sendAgentWearablesUpdate();
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index b8b08855a89..54fdcc38946 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -652,6 +652,7 @@ bool LLAppViewer::init()
 
 	// Widget construction depends on LLUI being initialized
 	LLUI::initClass(&gSavedSettings, 
+					&gSavedSettings, 
 					&gColors, 
 					LLUIImageList::getInstance(),
 					ui_audio_callback,
@@ -663,7 +664,7 @@ bool LLAppViewer::init()
 				&LLURLDispatcher::dispatchFromTextEditor);
 	
 	LLUICtrlFactory::getInstance()->setupPaths(); // update paths with correct language set
-	
+
 	/////////////////////////////////////////////////
 	//
 	// Load settings files
@@ -736,7 +737,10 @@ bool LLAppViewer::init()
 	//
 	initWindow();
 
-#if LL_LCD_COMPILE
+	// call all self-registered classes
+	LLInitClassList::instance().fireCallbacks();
+
+	#if LL_LCD_COMPILE
 		// start up an LCD window on a logitech keyboard, if there is one
 		HINSTANCE hInstance = GetModuleHandle(NULL);
 		gLcdScreen = new LLLCD(hInstance);
@@ -762,64 +766,67 @@ bool LLAppViewer::init()
 	// If we don't have the right GL requirements, exit.
 	if (!gGLManager.mHasRequirements && !gNoRender)
 	{	
-		// can't use an alert here since we're existing and
+		// can't use an alert here since we're exiting and
 		// all hell breaks lose.
 		OSMessageBox(
-			LLAlertDialog::getTemplateMessage("UnsupportedGLRequirements"),
+			LLNotifications::instance().getGlobalString("UnsupportedGLRequirements"),
 			LLStringUtil::null,
 			OSMB_OK);
 		return 0;
 	}
 
-
-	bool unsupported = false;
-	LLStringUtil::format_map_t args;
-	std::string minSpecs;
-		
-	// get cpu data from xml
-	std::stringstream minCPUString(LLAlertDialog::getTemplateMessage("UnsupportedCPUAmount"));
-	S32 minCPU = 0;
-	minCPUString >> minCPU;
-
-	// get RAM data from XML
-	std::stringstream minRAMString(LLAlertDialog::getTemplateMessage("UnsupportedRAMAmount"));
-	U64 minRAM = 0;
-	minRAMString >> minRAM;
-	minRAM = minRAM * 1024 * 1024;
-
-	if(!LLFeatureManager::getInstance()->isGPUSupported() && LLFeatureManager::getInstance()->getGPUClass() != GPU_CLASS_UNKNOWN)
-	{
-		minSpecs += LLAlertDialog::getTemplateMessage("UnsupportedGPU");
-		minSpecs += "\n";
-		unsupported = true;
-	}
-	if(gSysCPU.getMhz() < minCPU)
-	{
-		minSpecs += LLAlertDialog::getTemplateMessage("UnsupportedCPU");
-		minSpecs += "\n";
-		unsupported = true;
-	}
-	if(gSysMemory.getPhysicalMemoryClamped() < minRAM)
-	{
-		minSpecs += LLAlertDialog::getTemplateMessage("UnsupportedRAM");
-		minSpecs += "\n";
-		unsupported = true;
-	}
-
-	if (LLFeatureManager::getInstance()->getGPUClass() == GPU_CLASS_UNKNOWN)
+	// alert the user if they are using unsupported hardware
+	if(!gSavedSettings.getBOOL("AlertedUnsupportedHardware"))
 	{
-		gViewerWindow->alertXml("UnknownGPU");
-	} 
+		bool unsupported = false;
+		LLSD args;
+		std::string minSpecs;
 		
-	if(unsupported)
-	{
-		if(!gSavedSettings.controlExists("WarnUnsupportedHardware") 
-			|| gSavedSettings.getBOOL("WarnUnsupportedHardware"))
+		// get cpu data from xml
+		std::stringstream minCPUString(LLNotifications::instance().getGlobalString("UnsupportedCPUAmount"));
+		S32 minCPU = 0;
+		minCPUString >> minCPU;
+
+		// get RAM data from XML
+		std::stringstream minRAMString(LLNotifications::instance().getGlobalString("UnsupportedRAMAmount"));
+		U64 minRAM = 0;
+		minRAMString >> minRAM;
+		minRAM = minRAM * 1024 * 1024;
+
+		if(!LLFeatureManager::getInstance()->isGPUSupported() && LLFeatureManager::getInstance()->getGPUClass() != GPU_CLASS_UNKNOWN)
+		{
+			minSpecs += LLNotifications::instance().getGlobalString("UnsupportedGPU");
+			minSpecs += "\n";
+			unsupported = true;
+		}
+		if(gSysCPU.getMhz() < minCPU)
+		{
+			minSpecs += LLNotifications::instance().getGlobalString("UnsupportedCPU");
+			minSpecs += "\n";
+			unsupported = true;
+		}
+		if(gSysMemory.getPhysicalMemoryClamped() < minRAM)
 		{
-			args["MINSPECS"] = minSpecs;
-			gViewerWindow->alertXml("UnsupportedHardware", args );
+			minSpecs += LLNotifications::instance().getGlobalString("UnsupportedRAM");
+			minSpecs += "\n";
+			unsupported = true;
 		}
 
+		if (LLFeatureManager::getInstance()->getGPUClass() == GPU_CLASS_UNKNOWN)
+		{
+			LLNotifications::instance().add("UnknownGPU");
+		} 
+			
+		if(unsupported)
+		{
+			if(!gSavedSettings.controlExists("WarnUnsupportedHardware") 
+				|| gSavedSettings.getBOOL("WarnUnsupportedHardware"))
+			{
+				args["MINSPECS"] = minSpecs;
+				LLNotifications::instance().add("UnsupportedHardware", args );
+			}
+
+		}
 	}
 
 	// save the graphics card
@@ -1153,8 +1160,6 @@ bool LLAppViewer::cleanup()
 
 	// Note: this is where gLocalSpeakerMgr and gActiveSpeakerMgr used to be deleted.
 
-	LLNotifyBox::cleanup();
-
 	LLWorldMap::getInstance()->reset(); // release any images
 	
 	llinfos << "Global stuff deleted" << llendflush;
@@ -1705,25 +1710,6 @@ bool LLAppViewer::initConfiguration()
 	LLFirstUse::addConfigVariable("FirstVoice");
 	LLFirstUse::addConfigVariable("FirstMedia");
 		
-    //////
-    // *FIX:Mani - Find a way to remove the gUICtrlFactory and
-    // LLAlertDialog::parseAlerts dependecies on the being loaded
-    // *before* the user settings. Having to do this init here
-    // seems odd. 
-
-	// This is where gUICtrlFactory used to be instantiated with a new LLUICtrlFactory
-	// which needed to happen before calling parseAlerts below.
-	// TODO: That method is still dependant upon the base LLUICtrlFactory constructor being called
-	// which registers some callbacks so I'm leaving in a call to getInstance here to cause that to
-	// still happen. This needs to be cleaned up later when the base and derived classes
-	// are planned to be combined. -MG
-	LLUICtrlFactory::getInstance();
-	
-
-	// Pre-load alerts.xml to define the warnings settings (always loads from skins/xui/en-us/)
-	// Do this *before* loading the settings file
-	LLAlertDialog::parseAlerts("alerts.xml", &gSavedSettings, TRUE);
-
 	// - read command line settings.
 	LLControlGroupCLP clp;
 	std::string	cmd_line_config	= gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,
@@ -2151,8 +2137,6 @@ bool LLAppViewer::initWindow()
 
 	LLUI::sWindow = gViewerWindow->getWindow();
 
-	LLAlertDialog::parseAlerts("alerts.xml");
-	LLNotifyBox::parseNotify("notify.xml");
 	LLTrans::parseStrings("strings.xml");
 
 	// Show watch cursor
@@ -2614,32 +2598,34 @@ void LLAppViewer::requestQuit()
 	mQuitRequested = true;
 }
 
-static void finish_quit(S32 option, void *userdata)
+static bool finish_quit(const LLSD& notification, const LLSD& response)
 {
+	S32 option = LLNotification::getSelectedOption(notification, response);
+
 	if (option == 0)
 	{
 		LLAppViewer::instance()->requestQuit();
 	}
+	return false;
 }
+static LLNotificationFunctorRegistration finish_quit_reg("ConfirmQuit", finish_quit);
 
 void LLAppViewer::userQuit()
 {
-	gViewerWindow->alertXml("ConfirmQuit", finish_quit, NULL);
+	LLNotifications::instance().add("ConfirmQuit");
 }
 
-static void finish_early_exit(S32 option, void* userdata)
+static bool finish_early_exit(const LLSD& notification, const LLSD& response)
 {
 	LLAppViewer::instance()->forceQuit();
+	return false;
 }
 
-void LLAppViewer::earlyExit(const std::string& msg)
+void LLAppViewer::earlyExit(const std::string& name, const LLSD& substitutions)
 {
-   	llwarns << "app_early_exit: " << msg << llendl;
+   	llwarns << "app_early_exit: " << name << llendl;
 	gDoDisconnect = TRUE;
-// 	LLStringUtil::format_map_t args;
-// 	args["[MESSAGE]"] = mesg;
-// 	gViewerWindow->alertXml("AppEarlyExit", args, finish_early_exit);
-	LLAlertDialog::showCritical(msg, finish_early_exit, NULL);
+	LLNotifications::instance().add(name, substitutions, LLSD(), finish_early_exit);
 }
 
 void LLAppViewer::forceExit(S32 arg)
@@ -2953,18 +2939,22 @@ const std::string& LLAppViewer::getWindowTitle() const
 }
 
 // Callback from a dialog indicating user was logged out.  
-void finish_disconnect(S32 option, void* userdata)
+bool finish_disconnect(const LLSD& notification, const LLSD& response)
 {
+	S32 option = LLNotification::getSelectedOption(notification, response);
+
 	if (1 == option)
 	{
         LLAppViewer::instance()->forceQuit();
 	}
+	return false;
 }
 
 // Callback from an early disconnect dialog, force an exit
-void finish_forced_disconnect(S32 /* option */, void* /* userdata */)
+bool finish_forced_disconnect(const LLSD& notification, const LLSD& response)
 {
 	LLAppViewer::instance()->forceQuit();
+	return false;
 }
 
 
@@ -2984,19 +2974,19 @@ void LLAppViewer::forceDisconnect(const std::string& mesg)
 		big_reason = mesg;
 	}
 
-	LLStringUtil::format_map_t args;
+	LLSD args;
 	gDoDisconnect = TRUE;
 
 	if (LLStartUp::getStartupState() < STATE_STARTED)
 	{
 		// Tell users what happened
-		args["[ERROR_MESSAGE]"] = big_reason;
-		gViewerWindow->alertXml("ErrorMessage", args, finish_forced_disconnect);
+		args["ERROR_MESSAGE"] = big_reason;
+		LLNotifications::instance().add("ErrorMessage", args, LLSD(), &finish_forced_disconnect);
 	}
 	else
 	{
-		args["[MESSAGE]"] = big_reason;
-		gViewerWindow->alertXml("YouHaveBeenLoggedOut", args, finish_disconnect );
+		args["MESSAGE"] = big_reason;
+		LLNotifications::instance().add("YouHaveBeenLoggedOut", args, LLSD(), &finish_disconnect );
 	}
 }
 
@@ -3763,6 +3753,9 @@ void LLAppViewer::disconnectViewer()
 	// Now we just ask the LLWorld singleton to cleanly shut down.
 	LLWorld::getInstance()->destroyClass();
 
+	// call all self-registered classes
+	LLDestroyClassList::instance().fireCallbacks();
+
 	cleanup_xfer_manager();
 	gDisconnected = TRUE;
 }
diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h
index 41081237c7f..f8940322c57 100644
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -63,7 +63,8 @@ class LLAppViewer : public LLApp
 	void forceQuit(); // Puts the viewer into 'shutting down without error' mode.
 	void requestQuit(); // Request a quit. A kinder, gentler quit.
 	void userQuit(); // The users asks to quit. Confirm, then requestQuit()
-    void earlyExit(const std::string& msg); // Display an error dialog and forcibly quit.
+    void earlyExit(const std::string& name, 
+				   const LLSD& substitutions = LLSD()); // Display an error dialog and forcibly quit.
     void forceExit(S32 arg); // exit() immediately (after some cleanup).
     void abortQuit();  // Called to abort a quit request.
 
diff --git a/indra/newview/llassetuploadresponders.cpp b/indra/newview/llassetuploadresponders.cpp
index d25f827a725..a90532b451f 100644
--- a/indra/newview/llassetuploadresponders.cpp
+++ b/indra/newview/llassetuploadresponders.cpp
@@ -102,21 +102,21 @@ void LLAssetUploadResponder::error(U32 statusNum, const std::string& reason)
 {
 	llinfos << "LLAssetUploadResponder::error " << statusNum 
 			<< " reason: " << reason << llendl;
-	LLStringUtil::format_map_t args;
+	LLSD args;
 	switch(statusNum)
 	{
 		case 400:
-			args["[FILE]"] = (mFileName.empty() ? mVFileID.asString() : mFileName);
-			args["[REASON]"] = "Error in upload request.  Please visit "
+			args["FILE"] = (mFileName.empty() ? mVFileID.asString() : mFileName);
+			args["REASON"] = "Error in upload request.  Please visit "
 				"http://secondlife.com/support for help fixing this problem.";
-			gViewerWindow->alertXml("CannotUploadReason", args);
+			LLNotifications::instance().add("CannotUploadReason", args);
 			break;
 		case 500:
 		default:
-			args["[FILE]"] = (mFileName.empty() ? mVFileID.asString() : mFileName);
-			args["[REASON]"] = "The server is experiencing unexpected "
+			args["FILE"] = (mFileName.empty() ? mVFileID.asString() : mFileName);
+			args["REASON"] = "The server is experiencing unexpected "
 				"difficulties.";
-			gViewerWindow->alertXml("CannotUploadReason", args);
+			LLNotifications::instance().add("CannotUploadReason", args);
 			break;
 	}
 	LLUploadDialog::modalUploadFinished();
@@ -171,10 +171,10 @@ void LLAssetUploadResponder::uploadFailure(const LLSD& content)
 	}
 	else
 	{
-		LLStringUtil::format_map_t args;
-		args["[FILE]"] = (mFileName.empty() ? mVFileID.asString() : mFileName);
-		args["[REASON]"] = content["message"].asString();
-		gViewerWindow->alertXml("CannotUploadReason", args);
+		LLSD args;
+		args["FILE"] = (mFileName.empty() ? mVFileID.asString() : mFileName);
+		args["REASON"] = content["message"].asString();
+		LLNotifications::instance().add("CannotUploadReason", args);
 	}
 }
 
@@ -220,9 +220,9 @@ void LLNewAgentInventoryResponder::uploadComplete(const LLSD& content)
 		gMessageSystem->addUUIDFast(_PREHASH_TransactionID, LLUUID::null );
 		gAgent.sendReliableMessage();
 
-		LLStringUtil::format_map_t args;
-		args["[AMOUNT]"] = llformat("%d",LLGlobalEconomy::Singleton::getInstance()->getPriceUpload());
-		LLNotifyBox::showXml("UploadPayment", args);
+		LLSD args;
+		args["AMOUNT"] = llformat("%d",LLGlobalEconomy::Singleton::getInstance()->getPriceUpload());
+		LLNotifications::instance().add("UploadPayment", args);
 	}
 
 	// Actually add the upload to viewer inventory
diff --git a/indra/newview/llcallingcard.cpp b/indra/newview/llcallingcard.cpp
index 1fdefbac490..2395d1daabb 100644
--- a/indra/newview/llcallingcard.cpp
+++ b/indra/newview/llcallingcard.cpp
@@ -592,19 +592,19 @@ void LLAvatarTracker::processChange(LLMessageSystem* msg)
 				if((mBuddyInfo[agent_id]->getRightsGrantedFrom() ^  new_rights) & LLRelationship::GRANT_MODIFY_OBJECTS)
 				{
 					std::string first, last;
-					LLStringUtil::format_map_t args;
+					LLSD args;
 					if(gCacheName->getName(agent_id, first, last))
 					{
-						args["[FIRST_NAME]"] = first;
-						args["[LAST_NAME]"] = last;	
+						args["FIRST_NAME"] = first;
+						args["LAST_NAME"] = last;	
 					}
 					if(LLRelationship::GRANT_MODIFY_OBJECTS & new_rights)
 					{
-						gViewerWindow->alertXml("GrantedModifyRights",args);
+						LLNotifications::instance().add("GrantedModifyRights",args);
 					}
 					else
 					{
-						gViewerWindow->alertXml("RevokedModifyRights",args);
+						LLNotifications::instance().add("RevokedModifyRights",args);
 					}
 				}
 				(mBuddyInfo[agent_id])->setRightsFrom(new_rights);
@@ -638,7 +638,7 @@ void LLAvatarTracker::processNotify(LLMessageSystem* msg, bool online)
 			tracking_id = mTrackingData->mAvatarID;
 		}
 		BOOL notify = FALSE;
-		LLStringUtil::format_map_t args;
+		LLSD args;
 		for(S32 i = 0; i < count; ++i)
 		{
 			msg->getUUIDFast(_PREHASH_AgentBlock, _PREHASH_AgentID, agent_id, i);
@@ -652,8 +652,8 @@ void LLAvatarTracker::processNotify(LLMessageSystem* msg, bool online)
 					if(gCacheName->getName(agent_id, first, last))
 					{
 						notify = TRUE;
-						args["[FIRST]"] = first;
-						args["[LAST]"] = last;
+						args["FIRST"] = first;
+						args["LAST"] = last;
 					}
 				}
 			}
@@ -674,14 +674,14 @@ void LLAvatarTracker::processNotify(LLMessageSystem* msg, bool online)
 		if(notify)
 		{
 			// Popup a notify box with online status of this agent
-			LLNotifyBox::showXml(online ? "FriendOnline" : "FriendOffline", args);
+			LLNotificationPtr notification = LLNotifications::instance().add(online ? "FriendOnline" : "FriendOffline", args);
 
 			// If there's an open IM session with this agent, send a notification there too.
 			LLUUID session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, agent_id);
 			LLFloaterIMPanel *floater = gIMMgr->findFloaterBySession(session_id);
 			if (floater)
 			{
-				LLUIString notifyMsg = LLNotifyBox::getTemplateMessage((online ? "FriendOnline" : "FriendOffline"),args);
+				std::string notifyMsg = notification->getMessage();
 				if (!notifyMsg.empty())
 					floater->addHistoryLine(notifyMsg,gSavedSettings.getColor4("SystemChatColor"));
 			}
diff --git a/indra/newview/llcompilequeue.cpp b/indra/newview/llcompilequeue.cpp
index e9dbc69bcec..299a2cc33a1 100644
--- a/indra/newview/llcompilequeue.cpp
+++ b/indra/newview/llcompilequeue.cpp
@@ -524,9 +524,9 @@ void LLFloaterCompileQueue::onSaveTextComplete(const LLUUID& asset_id, void* use
 	if (status)
 	{
 		llwarns << "Unable to save text for script." << llendl;
-		LLStringUtil::format_map_t args;
-		args["[REASON]"] = std::string(LLAssetStorage::getErrorString(status));
-		gViewerWindow->alertXml("CompileQueueSaveText", args);
+		LLSD args;
+		args["REASON"] = std::string(LLAssetStorage::getErrorString(status));
+		LLNotifications::instance().add("CompileQueueSaveText", args);
 	}
 }
 
@@ -545,9 +545,9 @@ void LLFloaterCompileQueue::onSaveBytecodeComplete(const LLUUID& asset_id, void*
 	else
 	{
 		llwarns << "Unable to save bytecode for script." << llendl;
-		LLStringUtil::format_map_t args;
-		args["[REASON]"] = std::string(LLAssetStorage::getErrorString(status));
-		gViewerWindow->alertXml("CompileQueueSaveBytecode", args);
+		LLSD args;
+		args["REASON"] = std::string(LLAssetStorage::getErrorString(status));
+		LLNotifications::instance().add("CompileQueueSaveBytecode", args);
 	}
 	delete data;
 	data = NULL;
diff --git a/indra/newview/llconfirmationmanager.cpp b/indra/newview/llconfirmationmanager.cpp
index 167afb80625..6c465ccf92e 100644
--- a/indra/newview/llconfirmationmanager.cpp
+++ b/indra/newview/llconfirmationmanager.cpp
@@ -45,24 +45,22 @@ LLConfirmationManager::ListenerBase::~ListenerBase()
 }
 
 
-static void onConfirmAlert(S32 option, void* data)
+static bool onConfirmAlert(const LLSD& notification, const LLSD& response, LLConfirmationManager::ListenerBase* listener)
 {
-	LLConfirmationManager::ListenerBase* listener
-		= (LLConfirmationManager::ListenerBase*)data;
-		
+	S32 option = LLNotification::getSelectedOption(notification, response);
 	if (option == 0)
 	{
 		listener->confirmed("");
 	}
 	
 	delete listener;
+	return false;
 }
 
-static void onConfirmAlertPassword(
-	S32 option, const std::string& text, void* data)
+static bool onConfirmAlertPassword(const LLSD& notification, const LLSD& response, LLConfirmationManager::ListenerBase* listener)
 {
-	LLConfirmationManager::ListenerBase* listener
-		= (LLConfirmationManager::ListenerBase*)data;
+	std::string text = response["message"].asString();
+	S32 option = LLNotification::getSelectedOption(notification, response);
 		
 	if (option == 0)
 	{
@@ -70,6 +68,7 @@ static void onConfirmAlertPassword(
 	}
 	
 	delete listener;
+	return false;
 }
 
  
@@ -77,22 +76,17 @@ void LLConfirmationManager::confirm(Type type,
 	const std::string& action,
 	ListenerBase* listener)
 {
-	LLStringUtil::format_map_t args;
-	args["[ACTION]"] = action;
+	LLSD args;
+	args["ACTION"] = action;
 
 	switch (type)
 	{
 		case TYPE_CLICK:
-		  gViewerWindow->alertXml("ConfirmPurchase", args,
-								  onConfirmAlert, listener);
+			LLNotifications::instance().add("ConfirmPurchase", args, LLSD(), boost::bind(onConfirmAlert, _1, _2, listener));
 		  break;
 
 		case TYPE_PASSWORD:
-		  gViewerWindow->alertXmlEditText("ConfirmPurchasePassword", args,
-										  NULL, NULL,
-										  onConfirmAlertPassword, listener,
-										  LLStringUtil::format_map_t(),
-										  TRUE);
+			LLNotifications::instance().add("ConfirmPurchasePassword", args, LLSD(), boost::bind(onConfirmAlertPassword, _1, _2, listener));
 		  break;
 		case TYPE_NONE:
 		default:
diff --git a/indra/newview/lldelayedgestureerror.cpp b/indra/newview/lldelayedgestureerror.cpp
index 832b1b91302..9799bc1240d 100644
--- a/indra/newview/lldelayedgestureerror.cpp
+++ b/indra/newview/lldelayedgestureerror.cpp
@@ -98,18 +98,18 @@ void LLDelayedGestureError::onIdle(void *userdata)
 //static 
 bool LLDelayedGestureError::doDialog(const LLErrorEntry &ent, bool uuid_ok)
 {
-	LLStringUtil::format_map_t args;
+	LLSD args;
 	LLInventoryItem *item = gInventory.getItem( ent.mItemID );
 
 	if ( item )
 	{
-		args["[NAME]"] = item->getName();
+		args["NAME"] = item->getName();
 	}
 	else
 	{
 		if ( uuid_ok || ent.mTimer.getElapsedTimeF32() > MAX_NAME_WAIT_TIME )
 		{
-			args["[NAME]"] = std::string( ent.mItemID.asString() );
+			args["NAME"] = ent.mItemID.asString();
 		}
 		else
 		{
@@ -118,7 +118,7 @@ bool LLDelayedGestureError::doDialog(const LLErrorEntry &ent, bool uuid_ok)
 	}
 	 
 
-	LLNotifyBox::showXml(ent.mNotifyName, args);
+	LLNotifications::instance().add(ent.mNotifyName, args);
 
 	return true;
 }
diff --git a/indra/newview/lleventnotifier.cpp b/indra/newview/lleventnotifier.cpp
index 343a572a6a0..59f5cd342be 100644
--- a/indra/newview/lleventnotifier.cpp
+++ b/indra/newview/lleventnotifier.cpp
@@ -77,11 +77,11 @@ void LLEventNotifier::update()
 
 			if (np->getEventDate() < (alert_time))
 			{
-				LLStringUtil::format_map_t args;
-				args["[NAME]"] = np->getEventName();
-				args["[DATE]"] = np->getEventDateStr();
-				LLNotifyBox::showXml("EventNotification", args, 
-									 notifyCallback, np);
+				LLSD args;
+				args["NAME"] = np->getEventName();
+				args["DATE"] = np->getEventDateStr();
+				LLNotifications::instance().add("EventNotification", args, LLSD(),
+					boost::bind(&LLEventNotification::handleResponse, np, _1, _2));
 				mEventNotifications.erase(iter++);
 			}
 			else
@@ -173,47 +173,38 @@ void LLEventNotifier::remove(const U32 event_id)
 	mEventNotifications.erase(iter);
 }
 
-//static
-void LLEventNotifier::notifyCallback(S32 option, void *user_data)
+LLEventNotification::LLEventNotification() :
+	mEventID(0),
+	mEventName("")
 {
-	LLEventNotification *np = (LLEventNotification *)user_data;
-	if (!np)
-	{
-		llwarns << "Event notification callback without data!" << llendl;
-		return;
-	}
+}
+
+
+LLEventNotification::~LLEventNotification()
+{
+}
+
+bool LLEventNotification::handleResponse(const LLSD& notification, const LLSD& response)
+{
+	S32 option = LLNotification::getSelectedOption(notification, response);
 	switch (option)
 	{
 	case 0:
-		gAgent.teleportViaLocation(np->getEventPosGlobal());
-		gFloaterWorldMap->trackLocation(np->getEventPosGlobal());
+		gAgent.teleportViaLocation(getEventPosGlobal());
+		gFloaterWorldMap->trackLocation(getEventPosGlobal());
 		break;
 	case 1:
 		gDisplayEventHack = TRUE;
-		LLFloaterDirectory::showEvents(np->getEventID());
+		LLFloaterDirectory::showEvents(getEventID());
 		break;
 	case 2:
 		break;
 	}
 
 	// We could clean up the notification on the server now if we really wanted to.
+	return false;
 }
 
-
-
-LLEventNotification::LLEventNotification() :
-	mEventID(0),
-	mEventName(""),
-	mEventDate(0)
-{
-}
-
-
-LLEventNotification::~LLEventNotification()
-{
-}
-
-
 BOOL LLEventNotification::load(const LLUserAuth::response_t &response)
 {
 
diff --git a/indra/newview/lleventnotifier.h b/indra/newview/lleventnotifier.h
index bbd1facf315..ac906521d21 100644
--- a/indra/newview/lleventnotifier.h
+++ b/indra/newview/lleventnotifier.h
@@ -56,7 +56,6 @@ class LLEventNotifier
 
 	typedef std::map<U32, LLEventNotification *> en_map;
 
-	static void notifyCallback(S32 option, void *user_data);
 protected:
 	en_map	mEventNotifications;
 	LLFrameTimer	mNotificationTimer;
@@ -78,6 +77,7 @@ class LLEventNotification
 	time_t				getEventDate() const			{ return mEventDate; }
 	const std::string	&getEventDateStr() const		{ return mEventDateStr; }
 	LLVector3d			getEventPosGlobal() const		{ return mEventPosGlobal; }
+	bool				handleResponse(const LLSD& notification, const LLSD& payload);
 protected:
 	U32			mEventID;			// EventID for this event
 	std::string	mEventName;
diff --git a/indra/newview/llfirstuse.cpp b/indra/newview/llfirstuse.cpp
index 475473abe78..fce4d41207b 100644
--- a/indra/newview/llfirstuse.cpp
+++ b/indra/newview/llfirstuse.cpp
@@ -85,9 +85,9 @@ void LLFirstUse::useBalanceIncrease(S32 delta)
 	{
 		gSavedSettings.setWarning("FirstBalanceIncrease", FALSE);
 
-		LLStringUtil::format_map_t args;
-		args["[AMOUNT]"] = llformat("%d",delta);
-		LLNotifyBox::showXml("FirstBalanceIncrease", args);
+		LLSD args;
+		args["AMOUNT"] = llformat("%d",delta);
+		LLNotifications::instance().add("FirstBalanceIncrease", args);
 	}
 }
 
@@ -99,9 +99,9 @@ void LLFirstUse::useBalanceDecrease(S32 delta)
 	{
 		gSavedSettings.setWarning("FirstBalanceDecrease", FALSE);
 
-		LLStringUtil::format_map_t args;
-		args["[AMOUNT]"] = llformat("%d",-delta);
-		LLNotifyBox::showXml("FirstBalanceDecrease", args);
+		LLSD args;
+		args["AMOUNT"] = llformat("%d",-delta);
+		LLNotifications::instance().add("FirstBalanceDecrease", args);
 	}
 }
 
@@ -114,8 +114,8 @@ void LLFirstUse::useSit()
 	//if (gSavedSettings.getWarning("FirstSit"))
 	//{
 	//	gSavedSettings.setWarning("FirstSit", FALSE);
-
-	//	LLNotifyBox::showXml("FirstSit");
+        //
+	//	LLNotifications::instance().add("FirstSit");
 	//}
 }
 
@@ -126,7 +126,7 @@ void LLFirstUse::useMap()
 	{
 		gSavedSettings.setWarning("FirstMap", FALSE);
 
-		LLNotifyBox::showXml("FirstMap");
+		LLNotifications::instance().add("FirstMap");
 	}
 }
 
@@ -143,7 +143,7 @@ void LLFirstUse::useBuild()
 	{
 		gSavedSettings.setWarning("FirstBuild", FALSE);
 
-		LLNotifyBox::showXml("FirstBuild");
+		LLNotifications::instance().add("FirstBuild");
 	}
 }
 
@@ -154,7 +154,7 @@ void LLFirstUse::useLeftClickNoHit()
 	{
 		gSavedSettings.setWarning("FirstLeftClickNoHit", FALSE);
 
-		LLNotifyBox::showXml("FirstLeftClickNoHit");
+		LLNotifications::instance().add("FirstLeftClickNoHit");
 	}
 }
 
@@ -168,7 +168,7 @@ void LLFirstUse::useTeleport()
 		{
 			gSavedSettings.setWarning("FirstTeleport", FALSE);
 
-			LLNotifyBox::showXml("FirstTeleport");
+		        LLNotifications::instance().add("FirstTeleport");
 		}
 	}
 }
@@ -184,7 +184,7 @@ void LLFirstUse::useOverrideKeys()
 		{
 			gSavedSettings.setWarning("FirstOverrideKeys", FALSE);
 
-			LLNotifyBox::showXml("FirstOverrideKeys");
+			LLNotifications::instance().add("FirstOverrideKeys");
 		}
 	}
 }
@@ -202,7 +202,7 @@ void LLFirstUse::useAppearance()
 	{
 		gSavedSettings.setWarning("FirstAppearance", FALSE);
 
-		LLNotifyBox::showXml("FirstAppearance");
+		LLNotifications::instance().add("FirstAppearance");
 	}
 }
 
@@ -213,7 +213,7 @@ void LLFirstUse::useInventory()
 	{
 		gSavedSettings.setWarning("FirstInventory", FALSE);
 
-		LLNotifyBox::showXml("FirstInventory");
+		LLNotifications::instance().add("FirstInventory");
 	}
 }
 
@@ -225,10 +225,10 @@ void LLFirstUse::useSandbox()
 	{
 		gSavedSettings.setWarning("FirstSandbox", FALSE);
 
-		LLStringUtil::format_map_t args;
-		args["[HOURS]"] = llformat("%d",SANDBOX_CLEAN_FREQ);
-		args["[TIME]"] = llformat("%d",SANDBOX_FIRST_CLEAN_HOUR);
-		LLNotifyBox::showXml("FirstSandbox", args);
+		LLSD args;
+		args["HOURS"] = llformat("%d",SANDBOX_CLEAN_FREQ);
+		args["TIME"] = llformat("%d",SANDBOX_FIRST_CLEAN_HOUR);
+		LLNotifications::instance().add("FirstSandbox", args);
 	}
 }
 
@@ -239,7 +239,7 @@ void LLFirstUse::useFlexible()
 	{
 		gSavedSettings.setWarning("FirstFlexible", FALSE);
 
-		LLNotifyBox::showXml("FirstFlexible");
+		LLNotifications::instance().add("FirstFlexible");
 	}
 }
 
@@ -250,7 +250,7 @@ void LLFirstUse::useDebugMenus()
 	{
 		gSavedSettings.setWarning("FirstDebugMenus", FALSE);
 
-		LLNotifyBox::showXml("FirstDebugMenus");
+		LLNotifications::instance().add("FirstDebugMenus");
 	}
 }
 
@@ -261,7 +261,7 @@ void LLFirstUse::useSculptedPrim()
 	{
 		gSavedSettings.setWarning("FirstSculptedPrim", FALSE);
 
-		LLNotifyBox::showXml("FirstSculptedPrim");
+		LLNotifications::instance().add("FirstSculptedPrim");
 		
 	}
 }
@@ -273,6 +273,6 @@ void LLFirstUse::useMedia()
 	{
 		gSavedSettings.setWarning("FirstMedia", FALSE);
 
-		LLNotifyBox::showXml("FirstMedia");
+		LLNotifications::instance().add("FirstMedia");
 	}
 }
diff --git a/indra/newview/llfloateranimpreview.cpp b/indra/newview/llfloateranimpreview.cpp
index c7e35bcfb55..a84026e1326 100644
--- a/indra/newview/llfloateranimpreview.cpp
+++ b/indra/newview/llfloateranimpreview.cpp
@@ -1001,7 +1001,7 @@ void LLFloaterAnimPreview::onBtnOK(void* userdata)
 			else
 			{
 				llwarns << "Failure writing animation data." << llendl;
-				gViewerWindow->alertXml("WriteAnimationFail");
+				LLNotifications::instance().add("WriteAnimationFail");
 			}
 		}
 
diff --git a/indra/newview/llfloaterauction.cpp b/indra/newview/llfloaterauction.cpp
index a90d11f6eaa..100c6ee20dc 100644
--- a/indra/newview/llfloaterauction.cpp
+++ b/indra/newview/llfloaterauction.cpp
@@ -238,7 +238,7 @@ void LLFloaterAuction::onClickOK(void* data)
 								   FALSE);
 		self->getWindow()->incBusyCount();
 
-		LLNotifyBox::showXml("UploadingAuctionSnapshot");
+		LLNotifications::instance().add("UploadingAuctionSnapshot");
 
 	}
 	LLMessageSystem* msg = gMessageSystem;
@@ -277,13 +277,13 @@ void auction_tga_upload_done(const LLUUID& asset_id, void* user_data, S32 status
 
 	if (0 == status)
 	{
-		LLNotifyBox::showXml("UploadWebSnapshotDone");
+		LLNotifications::instance().add("UploadWebSnapshotDone");
 	}
 	else
 	{
-		LLStringUtil::format_map_t args;
-		args["[REASON]"] = std::string(LLAssetStorage::getErrorString(status));
-		gViewerWindow->alertXml("UploadAuctionSnapshotFail", args);
+		LLSD args;
+		args["REASON"] = std::string(LLAssetStorage::getErrorString(status));
+		LLNotifications::instance().add("UploadAuctionSnapshotFail", args);
 	}
 }
 
@@ -298,12 +298,12 @@ void auction_j2c_upload_done(const LLUUID& asset_id, void* user_data, S32 status
 
 	if (0 == status)
 	{
-		LLNotifyBox::showXml("UploadSnapshotDone");
+		LLNotifications::instance().add("UploadSnapshotDone");
 	}
 	else
 	{
-		LLStringUtil::format_map_t args;
-		args["[REASON]"] = std::string(LLAssetStorage::getErrorString(status));
-		gViewerWindow->alertXml("UploadAuctionSnapshotFail", args);
+		LLSD args;
+		args["REASON"] = std::string(LLAssetStorage::getErrorString(status));
+		LLNotifications::instance().add("UploadAuctionSnapshotFail", args);
 	}
 }
diff --git a/indra/newview/llfloaterbuy.cpp b/indra/newview/llfloaterbuy.cpp
index 9edb0afb5c2..5bdb4a23744 100644
--- a/indra/newview/llfloaterbuy.cpp
+++ b/indra/newview/llfloaterbuy.cpp
@@ -86,7 +86,7 @@ void LLFloaterBuy::show(const LLSaleInfo& sale_info)
 
 	if (selection->getRootObjectCount() != 1)
 	{
-		gViewerWindow->alertXml("BuyOneObjectOnly");
+		LLNotifications::instance().add("BuyOneObjectOnly");
 		return;
 	}
 
@@ -136,7 +136,7 @@ void LLFloaterBuy::show(const LLSaleInfo& sale_info)
 	BOOL owners_identical = LLSelectMgr::getInstance()->selectGetOwner(owner_id, owner_name);
 	if (!owners_identical)
 	{
-		gViewerWindow->alertXml("BuyObjectOneOwner");
+		LLNotifications::instance().add("BuyObjectOneOwner");
 		return;
 	}
 
diff --git a/indra/newview/llfloaterbuycontents.cpp b/indra/newview/llfloaterbuycontents.cpp
index d74707f6b12..1dd12413ccd 100644
--- a/indra/newview/llfloaterbuycontents.cpp
+++ b/indra/newview/llfloaterbuycontents.cpp
@@ -83,7 +83,7 @@ void LLFloaterBuyContents::show(const LLSaleInfo& sale_info)
 
 	if (selection->getRootObjectCount() != 1)
 	{
-		gViewerWindow->alertXml("BuyContentsOneOnly");
+		LLNotifications::instance().add("BuyContentsOneOnly");
 		return;
 	}
 
@@ -113,7 +113,7 @@ void LLFloaterBuyContents::show(const LLSaleInfo& sale_info)
 	BOOL owners_identical = LLSelectMgr::getInstance()->selectGetOwner(owner_id, owner_name);
 	if (!owners_identical)
 	{
-		gViewerWindow->alertXml("BuyContentsOneOwner");
+		LLNotifications::instance().add("BuyContentsOneOwner");
 		return;
 	}
 
diff --git a/indra/newview/llfloaterbuyland.cpp b/indra/newview/llfloaterbuyland.cpp
index 7aa6af2fea0..65cea37a0f1 100644
--- a/indra/newview/llfloaterbuyland.cpp
+++ b/indra/newview/llfloaterbuyland.cpp
@@ -213,7 +213,7 @@ void LLFloaterBuyLand::buyLand(
 {
 	if(is_for_group && !gAgent.hasPowerInActiveGroup(GP_LAND_DEED))
 	{
-		gViewerWindow->alertXml("OnlyOfficerCanBuyLand");
+		LLNotifications::instance().add("OnlyOfficerCanBuyLand");
 		return;
 	}
 
@@ -976,7 +976,7 @@ BOOL LLFloaterBuyLandUI::canClose()
 	if (!can_close)
 	{
 		// explain to user why they can't do this, see DEV-9605
-		gViewerWindow->alertXml("CannotCloseFloaterBuyLand");
+		LLNotifications::instance().add("CannotCloseFloaterBuyLand");
 	}
 	return can_close;
 }
diff --git a/indra/newview/llfloaterdaycycle.cpp b/indra/newview/llfloaterdaycycle.cpp
index af42a92ed84..de308b5425e 100644
--- a/indra/newview/llfloaterdaycycle.cpp
+++ b/indra/newview/llfloaterdaycycle.cpp
@@ -98,17 +98,9 @@ LLFloaterDayCycle::~LLFloaterDayCycle()
 void LLFloaterDayCycle::onClickHelp(void* data)
 {
 	LLFloaterDayCycle* self = LLFloaterDayCycle::instance();
-	const std::string* xml_alert = (std::string*)data;
 
-	LLAlertDialog* dialogp = gViewerWindow->alertXml(*xml_alert);
-	if (dialogp)
-	{
-		LLFloater* root_floater = gFloaterView->getParentFloater(self);
-		if (root_floater)
-		{
-			root_floater->addDependentFloater(dialogp);
-		}
-	}
+	std::string xml_alert = *(std::string *) data;
+	LLNotifications::instance().add(self->contextualNotification(xml_alert));
 }
 
 void LLFloaterDayCycle::initHelpBtn(const std::string& name, const std::string& xml_alert)
diff --git a/indra/newview/llfloaterenvsettings.cpp b/indra/newview/llfloaterenvsettings.cpp
index b28cc040475..90225ecfa16 100644
--- a/indra/newview/llfloaterenvsettings.cpp
+++ b/indra/newview/llfloaterenvsettings.cpp
@@ -67,18 +67,8 @@ LLFloaterEnvSettings::~LLFloaterEnvSettings()
 
 void LLFloaterEnvSettings::onClickHelp(void* data)
 {
-	LLFloaterEnvSettings* self = static_cast<LLFloaterEnvSettings*>(data);
-
-	const char* xml_alert = "EnvSettingsHelpButton";
-	LLAlertDialog* dialogp = gViewerWindow->alertXml(xml_alert);
-	if (dialogp)
-	{
-		LLFloater* root_floater = gFloaterView->getParentFloater(self);
-		if (root_floater)
-		{
-			root_floater->addDependentFloater(dialogp);
-		}
-	}
+	LLFloaterEnvSettings* self = (LLFloaterEnvSettings*)data;
+	LLNotifications::instance().add(self->contextualNotification("EnvSettingsHelpButton"));
 }
 
 void LLFloaterEnvSettings::initCallbacks(void) 
diff --git a/indra/newview/llfloaterfriends.cpp b/indra/newview/llfloaterfriends.cpp
index 2d7d2ee15d6..f5493172ba0 100644
--- a/indra/newview/llfloaterfriends.cpp
+++ b/indra/newview/llfloaterfriends.cpp
@@ -523,9 +523,9 @@ void LLPanelFriends::onSelectName(LLUICtrl* ctrl, void* user_data)
 //static
 void LLPanelFriends::onMaximumSelect(void* user_data)
 {
-	LLStringUtil::format_map_t args;
-	args["[MAX_SELECT]"] = llformat("%d", MAX_FRIEND_SELECT);
-	LLNotifyBox::showXml("MaxListSelectMessage", args);
+	LLSD args;
+	args["MAX_SELECT"] = llformat("%d", MAX_FRIEND_SELECT);
+	LLNotifications::instance().add("MaxListSelectMessage", args);
 };
 
 // static
@@ -585,27 +585,22 @@ void LLPanelFriends::requestFriendship(const LLUUID& target_id, const std::strin
 					 calling_card_folder_id);
 }
 
-struct LLAddFriendData
-{
-	LLUUID mID;
-	std::string mName;
-};
-
 // static
-void LLPanelFriends::callbackAddFriendWithMessage(S32 option, const std::string& text, void* data)
+bool LLPanelFriends::callbackAddFriendWithMessage(const LLSD& notification, const LLSD& response)
 {
-	LLAddFriendData* add = (LLAddFriendData*)data;
+	S32 option = LLNotification::getSelectedOption(notification, response);
 	if (option == 0)
 	{
-		requestFriendship(add->mID, add->mName, text);
+		requestFriendship(notification["payload"]["id"].asUUID(), 
+		    notification["payload"]["name"].asString(),
+		    response["message"].asString());
 	}
-	delete add;
+	return false;
 }
 
-// static
-void LLPanelFriends::callbackAddFriend(S32 option, void* data)
+bool LLPanelFriends::callbackAddFriend(const LLSD& notification, const LLSD& response)
 {
-	LLAddFriendData* add = (LLAddFriendData*)data;
+	S32 option = LLNotification::getSelectedOption(notification, response);
 	if (option == 0)
 	{
 		// Servers older than 1.25 require the text of the message to be the
@@ -613,9 +608,11 @@ void LLPanelFriends::callbackAddFriend(S32 option, void* data)
 		LLUUID calling_card_folder_id = 
 			gInventory.findCategoryUUIDForType(LLAssetType::AT_CALLINGCARD);
 		std::string message = calling_card_folder_id.asString();
-		requestFriendship(add->mID, add->mName, message);
+		requestFriendship(notification["payload"]["id"].asUUID(), 
+		    notification["payload"]["name"].asString(),
+		    message);
 	}
-	delete add;
+    return false;
 }
 
 // static
@@ -634,27 +631,25 @@ void LLPanelFriends::requestFriendshipDialog(const LLUUID& id,
 {
 	if(id == gAgentID)
 	{
-		LLNotifyBox::showXml("AddSelfFriend");
+		LLNotifications::instance().add("AddSelfFriend");
 		return;
 	}
 
-	LLAddFriendData* data = new LLAddFriendData();
-	data->mID = id;
-	data->mName = name;
-	
-	LLStringUtil::format_map_t args;
-	args["[NAME]"] = name;
-
-	// Look for server versions like: Second Life Server 1.24.4.95600
+	LLSD args;
+	args["NAME"] = name;
+	LLSD payload;
+	payload["id"] = id;
+	payload["name"] = name;
+    // Look for server versions like: Second Life Server 1.24.4.95600
 	if (gLastVersionChannel.find(" 1.24.") != std::string::npos)
 	{
 		// Old and busted server version, doesn't support friend
 		// requests with messages.
-		gViewerWindow->alertXml("AddFriend", args, callbackAddFriend, data);
+    	LLNotifications::instance().add("AddFriend", args, payload, &callbackAddFriend);
 	}
 	else
 	{
-		gViewerWindow->alertXmlEditText("AddFriendWithMessage", args, NULL, NULL, callbackAddFriendWithMessage, data);
+    	LLNotifications::instance().add("AddFriendWithMessage", args, payload, &callbackAddFriendWithMessage);
 	}
 }
 
@@ -677,7 +672,7 @@ void LLPanelFriends::onClickRemove(void* user_data)
 
 	//llinfos << "LLPanelFriends::onClickRemove()" << llendl;
 	LLDynamicArray<LLUUID> ids = panelp->getSelectedIDs();
-	LLStringUtil::format_map_t args;
+	LLSD args;
 	if(ids.size() > 0)
 	{
 		std::string msgType = "RemoveFromFriends";
@@ -687,18 +682,27 @@ void LLPanelFriends::onClickRemove(void* user_data)
 			std::string first, last;
 			if(gCacheName->getName(agent_id, first, last))
 			{
-				args["[FIRST_NAME]"] = first;
-				args["[LAST_NAME]"] = last;	
+				args["FIRST_NAME"] = first;
+				args["LAST_NAME"] = last;	
 			}
 		}
 		else
 		{
 			msgType = "RemoveMultipleFromFriends";
 		}
-		gViewerWindow->alertXml(msgType,
+		LLSD payload;
+
+		for (LLDynamicArray<LLUUID>::iterator it = ids.begin();
+			it != ids.end();
+			++it)
+		{
+			payload["ids"].append(*it);
+		}
+
+		LLNotifications::instance().add(msgType,
 			args,
-			&handleRemove,
-			(void*)new LLDynamicArray<LLUUID>(ids));
+			payload,
+			&handleRemove);
 	}
 }
 
@@ -730,13 +734,10 @@ void LLPanelFriends::confirmModifyRights(rights_map_t& ids, EGrantRevoke command
 {
 	if (ids.empty()) return;
 	
-	LLStringUtil::format_map_t args;
+	LLSD args;
 	if(ids.size() > 0)
 	{
-		// copy map of ids onto heap
-		rights_map_t* rights = new rights_map_t(ids); 
-		// package with panel pointer
-		std::pair<LLPanelFriends*, rights_map_t*>* user_data = new std::pair<LLPanelFriends*, rights_map_t*>(this, rights);
+		rights_map_t* rights = new rights_map_t(ids);
 
 		// for single friend, show their name
 		if(ids.size() == 1)
@@ -745,62 +746,65 @@ void LLPanelFriends::confirmModifyRights(rights_map_t& ids, EGrantRevoke command
 			std::string first, last;
 			if(gCacheName->getName(agent_id, first, last))
 			{
-				args["[FIRST_NAME]"] = first;
-				args["[LAST_NAME]"] = last;	
+				args["FIRST_NAME"] = first;
+				args["LAST_NAME"] = last;	
 			}
 			if (command == GRANT)
 			{
-				gViewerWindow->alertXml("GrantModifyRights", args, modifyRightsConfirmation, user_data);
+				LLNotifications::instance().add("GrantModifyRights", 
+					args, 
+					LLSD(), 
+					boost::bind(&LLPanelFriends::modifyRightsConfirmation, this, _1, _2, rights));
 			}
 			else
 			{
-				gViewerWindow->alertXml("RevokeModifyRights", args, modifyRightsConfirmation, user_data);
+				LLNotifications::instance().add("RevokeModifyRights", 
+					args, 
+					LLSD(), 
+					boost::bind(&LLPanelFriends::modifyRightsConfirmation, this, _1, _2, rights));
 			}
 		}
 		else
 		{
 			if (command == GRANT)
 			{
-				gViewerWindow->alertXml("GrantModifyRightsMultiple", args, modifyRightsConfirmation, user_data);
+				LLNotifications::instance().add("GrantModifyRightsMultiple", 
+					args, 
+					LLSD(), 
+					boost::bind(&LLPanelFriends::modifyRightsConfirmation, this, _1, _2, rights));
 			}
 			else
 			{
-				gViewerWindow->alertXml("RevokeModifyRightsMultiple", args, modifyRightsConfirmation, user_data);
+				LLNotifications::instance().add("RevokeModifyRightsMultiple", 
+					args, 
+					LLSD(), 
+					boost::bind(&LLPanelFriends::modifyRightsConfirmation, this, _1, _2, rights));
 			}
 		}
 	}
 }
 
-// static
-void LLPanelFriends::modifyRightsConfirmation(S32 option, void* user_data)
+bool LLPanelFriends::modifyRightsConfirmation(const LLSD& notification, const LLSD& response, rights_map_t* rights)
 {
-	std::pair<LLPanelFriends*, rights_map_t*>* data = (std::pair<LLPanelFriends*, rights_map_t*>*)user_data;
-	LLPanelFriends* panelp = data->first;
-
-	if(panelp)
+	S32 option = LLNotification::getSelectedOption(notification, response);
+	if(0 == option)
 	{
-		if(0 == option)
-		{
-			panelp->sendRightsGrant(*(data->second));
-		}
-		else
+		sendRightsGrant(*rights);
+	}
+	else
+	{
+		// need to resync view with model, since user cancelled operation
+		rights_map_t::iterator rights_it;
+		for (rights_it = rights->begin(); rights_it != rights->end(); ++rights_it)
 		{
-			// need to resync view with model, since user cancelled operation
-			rights_map_t* rights = data->second;
-			rights_map_t::iterator rights_it;
-			for (rights_it = rights->begin(); rights_it != rights->end(); ++rights_it)
-			{
-				const LLRelationship* info = LLAvatarTracker::instance().getBuddyInfo(rights_it->first);
-				panelp->updateFriendItem(rights_it->first, info);
-				// Might have changed the column the user is sorted on.
-				panelp->mFriendsList->sortItems();
-			}
+			const LLRelationship* info = LLAvatarTracker::instance().getBuddyInfo(rights_it->first);
+			updateFriendItem(rights_it->first, info);
 		}
-		panelp->refreshUI();
 	}
+	refreshUI();
 
-	delete data->second;
-	delete data;
+	delete rights;
+	return false;
 }
 
 void LLPanelFriends::applyRightsToFriends()
@@ -924,12 +928,14 @@ void LLPanelFriends::sendRightsGrant(rights_map_t& ids)
 
 
 // static
-void LLPanelFriends::handleRemove(S32 option, void* user_data)
+bool LLPanelFriends::handleRemove(const LLSD& notification, const LLSD& response)
 {
-	LLDynamicArray<LLUUID>* ids = static_cast<LLDynamicArray<LLUUID>*>(user_data);
-	for(LLDynamicArray<LLUUID>::iterator itr = ids->begin(); itr != ids->end(); ++itr)
+	S32 option = LLNotification::getSelectedOption(notification, response);
+
+	const LLSD& ids = notification["payload"]["ids"];
+	for(LLSD::array_const_iterator itr = ids.beginArray(); itr != ids.endArray(); ++itr)
 	{
-		LLUUID id = (*itr);
+		LLUUID id = itr->asUUID();
 		const LLRelationship* ip = LLAvatarTracker::instance().getBuddyInfo(id);
 		if(ip)
 		{			
@@ -955,5 +961,5 @@ void LLPanelFriends::handleRemove(S32 option, void* user_data)
 		}
 		
 	}
-	delete ids;
+	return false;
 }
diff --git a/indra/newview/llfloaterfriends.h b/indra/newview/llfloaterfriends.h
index e3f3f96d00c..58f7cc3bb28 100644
--- a/indra/newview/llfloaterfriends.h
+++ b/indra/newview/llfloaterfriends.h
@@ -119,8 +119,8 @@ class LLPanelFriends : public LLPanel, public LLEventTimer
 
 	// callback methods
 	static void onSelectName(LLUICtrl* ctrl, void* user_data);
-	static void callbackAddFriendWithMessage(S32 option, const std::string& text, void* user_data);
-	static void callbackAddFriend(S32 option, void* user_data);
+	static bool callbackAddFriend(const LLSD& notification, const LLSD& response);
+	static bool callbackAddFriendWithMessage(const LLSD& notification, const LLSD& response);
 	static void onPickAvatar(const std::vector<std::string>& names, const std::vector<LLUUID>& ids, void* user_data);
 	static void onMaximumSelect(void* user_data);
 
@@ -134,8 +134,8 @@ class LLPanelFriends : public LLPanel, public LLEventTimer
 
 	static void onClickModifyStatus(LLUICtrl* ctrl, void* user_data);
 
-	static void handleRemove(S32 option, void* user_data);
-	static void modifyRightsConfirmation(S32 option, void* user_data);
+	static bool handleRemove(const LLSD& notification, const LLSD& response);
+	bool modifyRightsConfirmation(const LLSD& notification, const LLSD& response, rights_map_t* rights);
 
 private:
 	// member data
diff --git a/indra/newview/llfloatergodtools.cpp b/indra/newview/llfloatergodtools.cpp
index a4022d844a2..c1eb273acc1 100644
--- a/indra/newview/llfloatergodtools.cpp
+++ b/indra/newview/llfloatergodtools.cpp
@@ -918,34 +918,31 @@ void LLPanelGridTools::refresh()
 // static
 void LLPanelGridTools::onClickKickAll(void* userdata)
 {
-	LLPanelGridTools* self = (LLPanelGridTools*) userdata;
-
 	S32 left, top;
 	gFloaterView->getNewFloaterPosition(&left, &top);
 	LLRect rect(left, top, left+400, top-300);
 
-	gViewerWindow->alertXmlEditText("KickAllUsers", LLStringUtil::format_map_t(),
-									NULL, NULL,
-									LLPanelGridTools::confirmKick, self);
+	LLNotifications::instance().add("KickAllUsers", LLSD(), LLSD(), LLPanelGridTools::confirmKick);
 }
 
 
-void LLPanelGridTools::confirmKick(S32 option, const std::string& text, void* userdata)
+bool LLPanelGridTools::confirmKick(const LLSD& notification, const LLSD& response)
 {
-	LLPanelGridTools* self = (LLPanelGridTools*) userdata;
-
-	if (option == 0)
+	if (LLNotification::getSelectedOption(notification, response) == 0)
 	{
-		self->mKickMessage = text;
-		gViewerWindow->alertXml("ConfirmKick",LLPanelGridTools::finishKick, self);
+		LLSD payload;
+		payload["kick_message"] = response["message"].asString();
+		LLNotifications::instance().add("ConfirmKick", LLSD(), payload, LLPanelGridTools::finishKick);
 	}
+	return false;
 }
 
 
 // static
-void LLPanelGridTools::finishKick(S32 option, void* userdata)
+bool LLPanelGridTools::finishKick(const LLSD& notification, const LLSD& response)
 {
-	LLPanelGridTools* self = (LLPanelGridTools*) userdata;
+	S32 option = LLNotification::getSelectedOption(notification, response);
+
 
 	if (option == 0)
 	{
@@ -957,26 +954,24 @@ void LLPanelGridTools::finishKick(S32 option, void* userdata)
 		msg->addUUIDFast(_PREHASH_GodSessionID, gAgent.getSessionID());
 		msg->addUUIDFast(_PREHASH_AgentID,   LL_UUID_ALL_AGENTS );
 		msg->addU32("KickFlags", KICK_FLAGS_DEFAULT );
-		msg->addStringFast(_PREHASH_Reason,    self->mKickMessage );
+		msg->addStringFast(_PREHASH_Reason,    notification["payload"]["kick_message"].asString());
 		gAgent.sendReliableMessage();
 	}
+	return false;
 }
 
 
 // static
 void LLPanelGridTools::onClickFlushMapVisibilityCaches(void* data)
 {
-	gViewerWindow->alertXml("FlushMapVisibilityCaches",
-							flushMapVisibilityCachesConfirm, data);
+	LLNotifications::instance().add("FlushMapVisibilityCaches", LLSD(), LLSD(), flushMapVisibilityCachesConfirm);
 }
 
 // static
-void LLPanelGridTools::flushMapVisibilityCachesConfirm(S32 option, void* data)
+bool LLPanelGridTools::flushMapVisibilityCachesConfirm(const LLSD& notification, const LLSD& response)
 {
-	if (option != 0) return;
-
-	LLPanelGridTools* self = (LLPanelGridTools*)data;
-	if (!self) return;
+	S32 option = LLNotification::getSelectedOption(notification, response);
+	if (option != 0) return false;
 
 	// HACK: Send this as an EstateOwnerRequest so it gets routed
 	// correctly by the spaceserver. JC
@@ -992,6 +987,7 @@ void LLPanelGridTools::flushMapVisibilityCachesConfirm(S32 option, void* data)
 	msg->nextBlock("ParamList");
 	msg->addString("Parameter", gAgent.getID().asString());
 	gAgent.sendReliableMessage();
+	return false;
 }
 
 
@@ -1182,13 +1178,16 @@ void LLPanelObjectTools::onClickDeletePublicOwnedBy(void* userdata)
 		panelp->mSimWideDeletesFlags = 
 			SWD_SCRIPTED_ONLY | SWD_OTHERS_LAND_ONLY;
 
-		LLStringUtil::format_map_t args;
-		args["[AVATAR_NAME]"] = panelp->childGetValue("target_avatar_name").asString();
+		LLSD args;
+		args["AVATAR_NAME"] = panelp->childGetValue("target_avatar_name").asString();
+		LLSD payload;
+		payload["avatar_id"] = panelp->mTargetAvatar;
+		payload["flags"] = (S32)panelp->mSimWideDeletesFlags;
 
-		gViewerWindow->alertXml( "GodDeleteAllScriptedPublicObjectsByUser",
+		LLNotifications::instance().add( "GodDeleteAllScriptedPublicObjectsByUser",
 								args,
-								callbackSimWideDeletes, 
-								userdata);
+								payload,
+								callbackSimWideDeletes);
 	}
 }
 
@@ -1201,13 +1200,16 @@ void LLPanelObjectTools::onClickDeleteAllScriptedOwnedBy(void* userdata)
 	{
 		panelp->mSimWideDeletesFlags = SWD_SCRIPTED_ONLY;
 
-		LLStringUtil::format_map_t args;
-		args["[AVATAR_NAME]"] = panelp->childGetValue("target_avatar_name").asString();
+		LLSD args;
+		args["AVATAR_NAME"] = panelp->childGetValue("target_avatar_name").asString();
+		LLSD payload;
+		payload["avatar_id"] = panelp->mTargetAvatar;
+		payload["flags"] = (S32)panelp->mSimWideDeletesFlags;
 
-		gViewerWindow->alertXml( "GodDeleteAllScriptedObjectsByUser",
+		LLNotifications::instance().add( "GodDeleteAllScriptedObjectsByUser",
 								args,
-								callbackSimWideDeletes, 
-								userdata);
+								payload,
+								callbackSimWideDeletes);
 	}
 }
 
@@ -1220,28 +1222,32 @@ void LLPanelObjectTools::onClickDeleteAllOwnedBy(void* userdata)
 	{
 		panelp->mSimWideDeletesFlags = 0;
 
-		LLStringUtil::format_map_t args;
-		args["[AVATAR_NAME]"] = panelp->childGetValue("target_avatar_name").asString();
+		LLSD args;
+		args["AVATAR_NAME"] = panelp->childGetValue("target_avatar_name").asString();
+		LLSD payload;
+		payload["avatar_id"] = panelp->mTargetAvatar;
+		payload["flags"] = (S32)panelp->mSimWideDeletesFlags;
 
-		gViewerWindow->alertXml( "GodDeleteAllObjectsByUser",
+		LLNotifications::instance().add( "GodDeleteAllObjectsByUser",
 								args,
-								callbackSimWideDeletes, 
-								userdata);
+								payload,
+								callbackSimWideDeletes);
 	}
 }
 
 // static
-void LLPanelObjectTools::callbackSimWideDeletes( S32 option, void* userdata )
+bool LLPanelObjectTools::callbackSimWideDeletes( const LLSD& notification, const LLSD& response )
 {
+	S32 option = LLNotification::getSelectedOption(notification, response);
 	if (option == 0)
 	{
-		LLPanelObjectTools* object_tools = (LLPanelObjectTools*) userdata;
-		if (!object_tools->mTargetAvatar.isNull())
+		if (!notification["payload"]["avatar_id"].asUUID().isNull())
 		{
-			send_sim_wide_deletes(object_tools->mTargetAvatar, 
-								  object_tools->mSimWideDeletesFlags);
+			send_sim_wide_deletes(notification["payload"]["avatar_id"].asUUID(), 
+								  notification["payload"]["flags"].asInteger());
 		}
 	}
+	return false;
 }
 
 void LLPanelObjectTools::onClickSet(void* data)
@@ -1420,7 +1426,7 @@ void LLPanelRequestTools::onClickRequest(void* data)
 
 void terrain_download_done(void** data, S32 status, LLExtStat ext_status)
 {
-	LLNotifyBox::showXml("TerrainDownloaded");
+	LLNotifications::instance().add("TerrainDownloaded");
 }
 
 
diff --git a/indra/newview/llfloatergodtools.h b/indra/newview/llfloatergodtools.h
index 7cc840cc97f..b70b9d795d6 100644
--- a/indra/newview/llfloatergodtools.h
+++ b/indra/newview/llfloatergodtools.h
@@ -201,11 +201,11 @@ class LLPanelGridTools
 	void refresh();
 
 	static void onClickKickAll(void *data);
-	static void confirmKick(S32 option, const std::string& text, void* userdata);
-	static void finishKick(S32 option, void* userdata);
+	static bool confirmKick(const LLSD& notification, const LLSD& response);
+	static bool finishKick(const LLSD& notification, const LLSD& response);
 	static void onDragSunPhase(LLUICtrl *ctrl, void *userdata);
 	static void onClickFlushMapVisibilityCaches(void* data);
-	static void flushMapVisibilityCachesConfirm(S32 option, void* data);
+	static bool flushMapVisibilityCachesConfirm(const LLSD& notification, const LLSD& response);
 
 protected:
 	std::string        mKickMessage; // Message to send on kick
@@ -240,7 +240,7 @@ class LLPanelObjectTools
 	static void onClickDeletePublicOwnedBy(void* data);
 	static void onClickDeleteAllScriptedOwnedBy(void* data);
 	static void onClickDeleteAllOwnedBy(void* data);
-	static void callbackSimWideDeletes(S32 option, void* userdata);
+	static bool callbackSimWideDeletes(const LLSD& notification, const LLSD& response);
 	static void onGetTopColliders(void* data);
 	static void onGetTopScripts(void* data);
 	static void onGetScriptDigest(void* data);
diff --git a/indra/newview/llfloatergroups.cpp b/indra/newview/llfloatergroups.cpp
index ca3332e4ad5..e798327bb78 100644
--- a/indra/newview/llfloatergroups.cpp
+++ b/indra/newview/llfloatergroups.cpp
@@ -388,10 +388,11 @@ void LLPanelGroups::leave()
 		}
 		if(i < count)
 		{
-			LLUUID* cb_data = new LLUUID((const LLUUID&)group_id);
-			LLStringUtil::format_map_t args;
-			args["[GROUP]"] = gAgent.mGroups.get(i).mName;
-			gViewerWindow->alertXml("GroupLeaveConfirmMember", args, callbackLeaveGroup, (void*)cb_data);
+			LLSD args;
+			args["GROUP"] = gAgent.mGroups.get(i).mName;
+			LLSD payload;
+			payload["group_id"] = group_id;
+			LLNotifications::instance().add("GroupLeaveConfirmMember", args, payload, callbackLeaveGroup);
 		}
 	}
 }
@@ -402,10 +403,11 @@ void LLPanelGroups::search()
 }
 
 // static
-void LLPanelGroups::callbackLeaveGroup(S32 option, void* userdata)
+bool LLPanelGroups::callbackLeaveGroup(const LLSD& notification, const LLSD& response)
 {
-	LLUUID* group_id = (LLUUID*)userdata;
-	if(option == 0 && group_id)
+	S32 option = LLNotification::getSelectedOption(notification, response);
+	LLUUID group_id = notification["payload"]["group_id"].asUUID();
+	if(option == 0)
 	{
 		LLMessageSystem* msg = gMessageSystem;
 		msg->newMessageFast(_PREHASH_LeaveGroupRequest);
@@ -413,10 +415,10 @@ void LLPanelGroups::callbackLeaveGroup(S32 option, void* userdata)
 		msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
 		msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
 		msg->nextBlockFast(_PREHASH_GroupData);
-		msg->addUUIDFast(_PREHASH_GroupID, *group_id);
+		msg->addUUIDFast(_PREHASH_GroupID, group_id);
 		gAgent.sendReliableMessage();
 	}
-	delete group_id;
+	return false;
 }
 
 void LLPanelGroups::onGroupList(LLUICtrl* ctrl, void* userdata)
diff --git a/indra/newview/llfloatergroups.h b/indra/newview/llfloatergroups.h
index 6d99f340855..a94b143d39e 100644
--- a/indra/newview/llfloatergroups.h
+++ b/indra/newview/llfloatergroups.h
@@ -120,7 +120,7 @@ class LLPanelGroups : public LLPanel, public LLSimpleListener
 	void search();
 	void callVote();
 
-	static void callbackLeaveGroup(S32 option, void* userdata);
+	static bool callbackLeaveGroup(const LLSD& notification, const LLSD& response);
 
 };
 
diff --git a/indra/newview/llfloaterhardwaresettings.cpp b/indra/newview/llfloaterhardwaresettings.cpp
index e4c13b2ae47..1db153434f3 100644
--- a/indra/newview/llfloaterhardwaresettings.cpp
+++ b/indra/newview/llfloaterhardwaresettings.cpp
@@ -62,7 +62,7 @@ LLFloaterHardwareSettings::~LLFloaterHardwareSettings()
 void LLFloaterHardwareSettings::onClickHelp(void* data)
 {
 	const char* xml_alert = "HardwareSettingsHelpButton";
-	gViewerWindow->alertXml(xml_alert);
+	LLNotifications::instance().add(xml_alert);
 }
 
 void LLFloaterHardwareSettings::initCallbacks(void) 
diff --git a/indra/newview/llfloaterhud.cpp b/indra/newview/llfloaterhud.cpp
index 848068ee9d7..8c97628e4e6 100644
--- a/indra/newview/llfloaterhud.cpp
+++ b/indra/newview/llfloaterhud.cpp
@@ -102,7 +102,7 @@ void LLFloaterHUD::showHUD()
 	// do not build the floater if there the url is empty
 	if (gSavedSettings.getString("TutorialURL") == "")
 	{
-		LLAlertDialog::showXml("TutorialNotFound");
+		LLNotifications::instance().add("TutorialNotFound");
 		return;
 	}
 
diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp
index a92634bc311..8b4b3805eec 100644
--- a/indra/newview/llfloaterland.cpp
+++ b/indra/newview/llfloaterland.cpp
@@ -85,8 +85,6 @@ static const BOOL BUY_PERSONAL_LAND = FALSE;
 LLParcelSelectionObserver* LLFloaterLand::sObserver = NULL;
 S32 LLFloaterLand::sLastTab = 0;
 
-LLHandle<LLFloater> LLPanelLandGeneral::sBuyPassDialogHandle;
-
 // Local classes
 class LLParcelSelectionObserver : public LLParcelObserver
 {
@@ -872,12 +870,12 @@ void LLPanelLandGeneral::onClickBuyPass(void* data)
 	cost = llformat("%d", pass_price);
 	time = llformat("%.2f", pass_hours);
 
-	LLStringUtil::format_map_t args;
-	args["[COST]"] = cost;
-	args["[PARCEL_NAME]"] = parcel_name;
-	args["[TIME]"] = time;
+	LLSD args;
+	args["COST"] = cost;
+	args["PARCEL_NAME"] = parcel_name;
+	args["TIME"] = time;
 	
-	sBuyPassDialogHandle = gViewerWindow->alertXml("LandBuyPass", args, cbBuyPass)->getHandle();
+	LLNotifications::instance().add("LandBuyPass", args, LLSD(), cbBuyPass);
 }
 
 // static
@@ -889,7 +887,7 @@ void LLPanelLandGeneral::onClickStartAuction(void* data)
 	{
 		if(parcelp->getForSale())
 		{
-			gViewerWindow->alertXml("CannotStartAuctionAlreadForSale");
+			LLNotifications::instance().add("CannotStartAuctionAlreadForSale");
 		}
 		else
 		{
@@ -899,19 +897,15 @@ void LLPanelLandGeneral::onClickStartAuction(void* data)
 }
 
 // static
-void LLPanelLandGeneral::cbBuyPass(S32 option, void* data)
+bool LLPanelLandGeneral::cbBuyPass(const LLSD& notification, const LLSD& response)
 {
+	S32 option = LLNotification::getSelectedOption(notification, response);
 	if (0 == option)
 	{
 		// User clicked OK
 		LLViewerParcelMgr::getInstance()->buyPass();
 	}
-}
-
-//static 
-BOOL LLPanelLandGeneral::buyPassDialogVisible()
-{
-	return sBuyPassDialogHandle.get() != NULL;
+	return false;
 }
 
 // static
@@ -1249,28 +1243,27 @@ void send_return_objects_message(S32 parcel_local_id, S32 return_type,
 	msg->sendReliable(region->getHost());
 }
 
-// static
-void LLPanelLandObjects::callbackReturnOwnerObjects(S32 option, void* userdata)
+bool LLPanelLandObjects::callbackReturnOwnerObjects(const LLSD& notification, const LLSD& response)
 {
-	LLPanelLandObjects	*lop = (LLPanelLandObjects *)userdata;
-	LLParcel *parcel = lop->mParcel->getParcel();
+	S32 option = LLNotification::getSelectedOption(notification, response);
+	LLParcel *parcel = mParcel->getParcel();
 	if (0 == option)
 	{
 		if (parcel)
 		{
 			LLUUID owner_id = parcel->getOwnerID();	
-			LLStringUtil::format_map_t args;
+			LLSD args;
 			if (owner_id == gAgentID)
 			{
-				LLNotifyBox::showXml("OwnedObjectsReturned");
+				LLNotifications::instance().add("OwnedObjectsReturned");
 			}
 			else
 			{
 				std::string first, last;
 				gCacheName->getName(owner_id, first, last);
-				args["[FIRST]"] = first;
-				args["[LAST]"] = last;
-				LLNotifyBox::showXml("OtherObjectsReturned", args);
+				args["FIRST"] = first;
+				args["LAST"] = last;
+				LLNotifications::instance().add("OtherObjectsReturned", args);
 			}
 			send_return_objects_message(parcel->getLocalID(), RT_OWNER);
 		}
@@ -1278,81 +1271,82 @@ void LLPanelLandObjects::callbackReturnOwnerObjects(S32 option, void* userdata)
 
 	LLSelectMgr::getInstance()->unhighlightAll();
 	LLViewerParcelMgr::getInstance()->sendParcelPropertiesUpdate( parcel );
-	lop->refresh();
+	refresh();
+	return false;
 }
 
-// static
-void LLPanelLandObjects::callbackReturnGroupObjects(S32 option, void* userdata)
+bool LLPanelLandObjects::callbackReturnGroupObjects(const LLSD& notification, const LLSD& response)
 {
-	LLPanelLandObjects	*lop = (LLPanelLandObjects *)userdata;
-	LLParcel *parcel = lop->mParcel->getParcel();
+	S32 option = LLNotification::getSelectedOption(notification, response);
+	LLParcel *parcel = mParcel->getParcel();
 	if (0 == option)
 	{
 		if (parcel)
 		{
 			std::string group_name;
 			gCacheName->getGroupName(parcel->getGroupID(), group_name);
-			LLStringUtil::format_map_t args;
-			args["[GROUPNAME]"] = group_name;
-			LLNotifyBox::showXml("GroupObjectsReturned", args);
+			LLSD args;
+			args["GROUPNAME"] = group_name;
+			LLNotifications::instance().add("GroupObjectsReturned", args);
 			send_return_objects_message(parcel->getLocalID(), RT_GROUP);
 		}
 	}
 	LLSelectMgr::getInstance()->unhighlightAll();
 	LLViewerParcelMgr::getInstance()->sendParcelPropertiesUpdate( parcel );
-	lop->refresh();
+	refresh();
+	return false;
 }
 
-// static
-void LLPanelLandObjects::callbackReturnOtherObjects(S32 option, void* userdata)
+bool LLPanelLandObjects::callbackReturnOtherObjects(const LLSD& notification, const LLSD& response)
 {
-	LLPanelLandObjects	*lop = (LLPanelLandObjects *)userdata;
-	LLParcel *parcel = lop->mParcel->getParcel();
+	S32 option = LLNotification::getSelectedOption(notification, response);
+	LLParcel *parcel = mParcel->getParcel();
 	if (0 == option)
 	{
 		if (parcel)
 		{
-			LLNotifyBox::showXml("UnOwnedObjectsReturned");
+			LLNotifications::instance().add("UnOwnedObjectsReturned");
 			send_return_objects_message(parcel->getLocalID(), RT_OTHER);
 		}
 	}
 	LLSelectMgr::getInstance()->unhighlightAll();
 	LLViewerParcelMgr::getInstance()->sendParcelPropertiesUpdate( parcel );
-	lop->refresh();
+	refresh();
+	return false;
 }
 
-// static
-void LLPanelLandObjects::callbackReturnOwnerList(S32 option, void* userdata)
+bool LLPanelLandObjects::callbackReturnOwnerList(const LLSD& notification, const LLSD& response)
 {
-	LLPanelLandObjects	*self = (LLPanelLandObjects *)userdata;
-	LLParcel *parcel = self->mParcel->getParcel();
+	S32 option = LLNotification::getSelectedOption(notification, response);
+	LLParcel *parcel = mParcel->getParcel();
 	if (0 == option)
 	{
 		if (parcel)
 		{
 			// Make sure we have something selected.
-			uuid_list_t::iterator selected = self->mSelectedOwners.begin();
-			if (selected != self->mSelectedOwners.end())
+			uuid_list_t::iterator selected = mSelectedOwners.begin();
+			if (selected != mSelectedOwners.end())
 			{
-				LLStringUtil::format_map_t args;
-				if (self->mSelectedIsGroup)
+				LLSD args;
+				if (mSelectedIsGroup)
 				{
-					args["[GROUPNAME]"] = self->mSelectedName;
-					LLNotifyBox::showXml("GroupObjectsReturned", args);
+					args["GROUPNAME"] = mSelectedName;
+					LLNotifications::instance().add("GroupObjectsReturned", args);
 				}
 				else
 				{
-					args["[NAME]"] = self->mSelectedName;
-					LLNotifyBox::showXml("OtherObjectsReturned2", args);
+					args["NAME"] = mSelectedName;
+					LLNotifications::instance().add("OtherObjectsReturned2", args);
 				}
 
-				send_return_objects_message(parcel->getLocalID(), RT_LIST, &(self->mSelectedOwners));
+				send_return_objects_message(parcel->getLocalID(), RT_LIST, &(mSelectedOwners));
 			}
 		}
 	}
 	LLSelectMgr::getInstance()->unhighlightAll();
 	LLViewerParcelMgr::getInstance()->sendParcelPropertiesUpdate( parcel );
-	self->refresh();
+	refresh();
+	return false;
 }
 
 
@@ -1374,16 +1368,16 @@ void LLPanelLandObjects::onClickReturnOwnerList(void* userdata)
 
 	send_parcel_select_objects(parcelp->getLocalID(), RT_LIST, &(self->mSelectedOwners));
 
-	LLStringUtil::format_map_t args;
-	args["[NAME]"] = self->mSelectedName;
-	args["[N]"] = llformat("%d",self->mSelectedCount);
+	LLSD args;
+	args["NAME"] = self->mSelectedName;
+	args["N"] = llformat("%d",self->mSelectedCount);
 	if (self->mSelectedIsGroup)
 	{
-		gViewerWindow->alertXml("ReturnObjectsDeededToGroup", args, callbackReturnOwnerList, userdata);	
+		LLNotifications::instance().add("ReturnObjectsDeededToGroup", args, LLSD(), boost::bind(&LLPanelLandObjects::callbackReturnOwnerList, self, _1, _2));	
 	}
 	else 
 	{
-		gViewerWindow->alertXml("ReturnObjectsOwnedByUser", args, callbackReturnOwnerList, userdata);	
+		LLNotifications::instance().add("ReturnObjectsOwnedByUser", args, LLSD(), boost::bind(&LLPanelLandObjects::callbackReturnOwnerList, self, _1, _2));	
 	}
 }
 
@@ -1591,19 +1585,19 @@ void LLPanelLandObjects::onClickReturnOwnerObjects(void* userdata)
 
 	LLUUID owner_id = parcel->getOwnerID();
 	
-	LLStringUtil::format_map_t args;
-	args["[N]"] = llformat("%d",owned);
+	LLSD args;
+	args["N"] = llformat("%d",owned);
 
 	if (owner_id == gAgent.getID())
 	{
-		gViewerWindow->alertXml("ReturnObjectsOwnedBySelf", args, callbackReturnOwnerObjects, userdata);
+		LLNotifications::instance().add("ReturnObjectsOwnedBySelf", args, LLSD(), boost::bind(&LLPanelLandObjects::callbackReturnOwnerObjects, panelp, _1, _2));
 	}
 	else
 	{
 		std::string name;
 		gCacheName->getFullName(owner_id, name);
-		args["[NAME]"] = name;
-		gViewerWindow->alertXml("ReturnObjectsOwnedByUser", args, callbackReturnOwnerObjects, userdata);
+		args["NAME"] = name;
+		LLNotifications::instance().add("ReturnObjectsOwnedByUser", args, LLSD(), boost::bind(&LLPanelLandObjects::callbackReturnOwnerObjects, panelp, _1, _2));
 	}
 }
 
@@ -1619,12 +1613,12 @@ void LLPanelLandObjects::onClickReturnGroupObjects(void* userdata)
 	std::string group_name;
 	gCacheName->getGroupName(parcel->getGroupID(), group_name);
 	
-	LLStringUtil::format_map_t args;
-	args["[NAME]"] = group_name;
-	args["[N]"] = llformat("%d", parcel->getGroupPrimCount());
+	LLSD args;
+	args["NAME"] = group_name;
+	args["N"] = llformat("%d", parcel->getGroupPrimCount());
 
 	// create and show confirmation textbox
-	gViewerWindow->alertXml("ReturnObjectsDeededToGroup", args, callbackReturnGroupObjects, userdata);
+	LLNotifications::instance().add("ReturnObjectsDeededToGroup", args, LLSD(), boost::bind(&LLPanelLandObjects::callbackReturnGroupObjects, panelp, _1, _2));
 }
 
 // static
@@ -1640,16 +1634,16 @@ void LLPanelLandObjects::onClickReturnOtherObjects(void* userdata)
 
 	send_parcel_select_objects(parcel->getLocalID(), RT_OTHER);
 
-	LLStringUtil::format_map_t args;
-	args["[N]"] = llformat("%d", other);
+	LLSD args;
+	args["N"] = llformat("%d", other);
 	
 	if (parcel->getIsGroupOwned())
 	{
 		std::string group_name;
 		gCacheName->getGroupName(parcel->getGroupID(), group_name);
-		args["[NAME]"] = group_name;
+		args["NAME"] = group_name;
 
-		gViewerWindow->alertXml("ReturnObjectsNotOwnedByGroup", args, callbackReturnOtherObjects, userdata);
+		LLNotifications::instance().add("ReturnObjectsNotOwnedByGroup", args, LLSD(), boost::bind(&LLPanelLandObjects::callbackReturnOtherObjects, panelp, _1, _2));
 	}
 	else
 	{
@@ -1657,15 +1651,15 @@ void LLPanelLandObjects::onClickReturnOtherObjects(void* userdata)
 
 		if (owner_id == gAgent.getID())
 		{
-			gViewerWindow->alertXml("ReturnObjectsNotOwnedBySelf", args, callbackReturnOtherObjects, userdata);
+			LLNotifications::instance().add("ReturnObjectsNotOwnedBySelf", args, LLSD(), boost::bind(&LLPanelLandObjects::callbackReturnOtherObjects, panelp, _1, _2));
 		}
 		else
 		{
 			std::string name;
 			gCacheName->getFullName(owner_id, name);
-			args["[NAME]"] = name;
+			args["NAME"] = name;
 
-			gViewerWindow->alertXml("ReturnObjectsNotOwnedByUser", args, callbackReturnOtherObjects, userdata);
+			LLNotifications::instance().add("ReturnObjectsNotOwnedByUser", args, LLSD(), boost::bind(&LLPanelLandObjects::callbackReturnOtherObjects, panelp, _1, _2));
 		}
 	}
 }
@@ -2073,7 +2067,7 @@ void LLPanelLandOptions::onCommitAny(LLUICtrl *ctrl, void *userdata)
 	if (!allow_other_scripts && region && region->getAllowDamage())
 	{
 
-		gViewerWindow->alertXml("UnableToDisableOutsideScripts");
+		LLNotifications::instance().add("UnableToDisableOutsideScripts");
 		return;
 	}
 
@@ -2117,7 +2111,7 @@ void LLPanelLandOptions::onClickSet(void* userdata)
 
 	if (agent_parcel->getLocalID() != selected_parcel->getLocalID())
 	{
-		gViewerWindow->alertXml("MustBeInParcel");
+		LLNotifications::instance().add("MustBeInParcel");
 		return;
 	}
 
@@ -2160,11 +2154,11 @@ void LLPanelLandOptions::onClickPublishHelp(void*)
 
 	if(! can_change_identity)
 	{
-		gViewerWindow->alertXml("ClickPublishHelpLandDisabled");
+		LLNotifications::instance().add("ClickPublishHelpLandDisabled");
 	}
 	else
 	{
-		gViewerWindow->alertXml("ClickPublishHelpLand");
+		LLNotifications::instance().add("ClickPublishHelpLand");
 	}
 }
 
diff --git a/indra/newview/llfloaterland.h b/indra/newview/llfloaterland.h
index 9bed9d53ae8..1d95a3e3f6e 100644
--- a/indra/newview/llfloaterland.h
+++ b/indra/newview/llfloaterland.h
@@ -151,8 +151,7 @@ class LLPanelLandGeneral
 	static void finalizeSetSellChange(void * userdata);
 	static void onSalePriceChange(LLUICtrl *ctrl, void * userdata);
 
-	static void cbBuyPass(S32 option, void*);
-	static BOOL buyPassDialogVisible();
+	static bool cbBuyPass(const LLSD& notification, const LLSD& response);
 
 	static void onClickSellLand(void* data);
 	static void onClickStopSellLand(void* data);
@@ -234,10 +233,10 @@ class LLPanelLandObjects
 	void refresh();
 	virtual void draw();
 
-	static void callbackReturnOwnerObjects(S32, void*);
-	static void callbackReturnGroupObjects(S32, void*);
-	static void callbackReturnOtherObjects(S32, void*);
-	static void callbackReturnOwnerList(S32, void*);
+	bool callbackReturnOwnerObjects(const LLSD& notification, const LLSD& response);
+	bool callbackReturnGroupObjects(const LLSD& notification, const LLSD& response);
+	bool callbackReturnOtherObjects(const LLSD& notification, const LLSD& response);
+	bool callbackReturnOwnerList(const LLSD& notification, const LLSD& response);
 
 	static void clickShowCore(LLPanelLandObjects* panelp, S32 return_type, uuid_list_t* list = 0);
 	static void onClickShowOwnerObjects(void*);
diff --git a/indra/newview/llfloaternotificationsconsole.cpp b/indra/newview/llfloaternotificationsconsole.cpp
new file mode 100644
index 00000000000..12dcd582549
--- /dev/null
+++ b/indra/newview/llfloaternotificationsconsole.cpp
@@ -0,0 +1,292 @@
+/** 
+ * @file llnotificationsconsole.cpp
+ * @brief Debugging console for unified notifications.
+ *
+ * $LicenseInfo:firstyear=2003&license=viewergpl$
+ * 
+ * Copyright (c) 2003-2007, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+#include "llfloaternotificationsconsole.h"
+#include "llnotifications.h"
+#include "lluictrlfactory.h"
+#include "llbutton.h"
+#include "llscrolllistctrl.h"
+#include "llpanel.h"
+#include "llcombobox.h"
+#include "llviewertexteditor.h"
+
+const S32 NOTIFICATION_PANEL_HEADER_HEIGHT = 20;
+const S32 HEADER_PADDING = 38;
+
+class LLNotificationChannelPanel : public LLPanel
+{
+public:
+	LLNotificationChannelPanel(const std::string& channel_name);
+	BOOL postBuild();
+
+private:
+	bool update(const LLSD& payload, bool passed_filter);
+	static void toggleClick(void* user_data);
+	static void onClickNotification(void* user_data);
+	static void onClickNotificationReject(void* user_data);
+	LLNotificationChannelPtr mChannelPtr;
+	LLNotificationChannelPtr mChannelRejectsPtr;
+};
+
+LLNotificationChannelPanel::LLNotificationChannelPanel(const std::string& channel_name) 
+	: LLPanel(channel_name)
+{
+	mChannelPtr = LLNotifications::instance().getChannel(channel_name);
+	mChannelRejectsPtr = LLNotificationChannelPtr(
+		new LLNotificationChannel(channel_name + "rejects", mChannelPtr->getParentChannelName(), !boost::bind(mChannelPtr->getFilter(), _1)));
+	LLUICtrlFactory::instance().buildPanel(this, "panel_notifications_channel.xml");
+}
+
+BOOL LLNotificationChannelPanel::postBuild()
+{
+	LLButton* header_button = getChild<LLButton>("header");
+	header_button->setLabel(mChannelPtr->getName());
+	header_button->setClickedCallback(toggleClick, this);
+
+	mChannelPtr->connectChanged(boost::bind(&LLNotificationChannelPanel::update, this, _1, true));
+	mChannelRejectsPtr->connectChanged(boost::bind(&LLNotificationChannelPanel::update, this, _1, false));
+
+	LLScrollListCtrl* scroll = getChild<LLScrollListCtrl>("notifications_list");
+	scroll->setDoubleClickCallback(onClickNotification);
+	scroll->setCallbackUserData(this);
+
+	scroll = getChild<LLScrollListCtrl>("notification_rejects_list");
+	scroll->setDoubleClickCallback(onClickNotificationReject);
+	scroll->setCallbackUserData(this);
+
+	return TRUE;
+}
+
+//static
+void LLNotificationChannelPanel::toggleClick(void *user_data)
+{
+	LLNotificationChannelPanel* self = (LLNotificationChannelPanel*)user_data;
+	if (!self) return;
+	
+	LLButton* header_button = self->getChild<LLButton>("header");
+	
+	LLLayoutStack* stack = dynamic_cast<LLLayoutStack*>(self->getParent());
+	if (stack)
+	{
+		stack->collapsePanel(self, header_button->getToggleState());
+	}
+
+	// turn off tab stop for collapsed panel
+	self->getChild<LLScrollListCtrl>("notifications_list")->setTabStop(!header_button->getToggleState());
+	self->getChild<LLScrollListCtrl>("notifications_list")->setVisible(!header_button->getToggleState());
+	self->getChild<LLScrollListCtrl>("notification_rejects_list")->setTabStop(!header_button->getToggleState());
+	self->getChild<LLScrollListCtrl>("notification_rejects_list")->setVisible(!header_button->getToggleState());
+}
+
+/*static*/
+void LLNotificationChannelPanel::onClickNotification(void* user_data)
+{
+	LLNotificationChannelPanel* self = (LLNotificationChannelPanel*)user_data;
+	if (!self) return;
+	void* data = self->getChild<LLScrollListCtrl>("notifications_list")->getFirstSelected()->getUserdata();
+	if (data)
+	{
+		gFloaterView->getParentFloater(self)->addDependentFloater(new LLFloaterNotification((LLNotification*)data), TRUE);
+	}
+}
+
+/*static*/
+void LLNotificationChannelPanel::onClickNotificationReject(void* user_data)
+{
+	LLNotificationChannelPanel* self = (LLNotificationChannelPanel*)user_data;
+	if (!self) return;
+	void* data = self->getChild<LLScrollListCtrl>("notification_rejects_list")->getFirstSelected()->getUserdata();
+	if (data)
+	{
+		gFloaterView->getParentFloater(self)->addDependentFloater(new LLFloaterNotification((LLNotification*)data), TRUE);
+	}
+}
+
+bool LLNotificationChannelPanel::update(const LLSD& payload, bool passed_filter)
+{
+	LLNotificationPtr notification = LLNotifications::instance().find(payload["id"].asUUID());
+	if (notification)
+	{
+		LLSD row;
+		row["columns"][0]["value"] = notification->getName();
+		row["columns"][0]["column"] = "name";
+
+		row["columns"][1]["value"] = notification->getMessage();
+		row["columns"][1]["column"] = "content";
+
+		row["columns"][2]["value"] = notification->getDate();
+		row["columns"][2]["column"] = "date";
+		row["columns"][2]["type"] = "date";
+
+		LLScrollListItem* sli = passed_filter ? 
+			getChild<LLScrollListCtrl>("notifications_list")->addElement(row) :
+			getChild<LLScrollListCtrl>("notification_rejects_list")->addElement(row);
+		sli->setUserdata(&(*notification));
+	}
+
+	return false;
+}
+
+//
+// LLFloaterNotificationConsole
+//
+LLFloaterNotificationConsole::LLFloaterNotificationConsole(const LLSD& key)
+{
+	LLUICtrlFactory::instance().buildFloater(this, "floater_notifications_console.xml");
+}
+
+void LLFloaterNotificationConsole::onClose(bool app_quitting)
+{
+	setVisible(FALSE);
+	//destroy();
+}
+
+
+BOOL LLFloaterNotificationConsole::postBuild()
+{
+	// these are in the order of processing
+	addChannel("Unexpired");
+	addChannel("Ignore");
+	addChannel("Visible", true);
+	// all the ones below attach to the Visible channel
+	addChannel("History");
+	addChannel("Alerts");
+	addChannel("AlertModal");
+	addChannel("Group Notifications");
+	addChannel("Notifications");
+	addChannel("NotificationTips");
+
+	getChild<LLButton>("add_notification")->setClickedCallback(onClickAdd, this);
+
+	LLComboBox* notifications = getChild<LLComboBox>("notification_types");
+	LLNotifications::TemplateNames names = LLNotifications::instance().getTemplateNames();
+	for (LLNotifications::TemplateNames::iterator template_it = names.begin();
+		template_it != names.end();
+		++template_it)
+	{
+		notifications->add(*template_it);
+	}
+	notifications->sortByName();
+
+	return TRUE;
+}
+
+void LLFloaterNotificationConsole::addChannel(const std::string& name, bool open)
+{
+	LLLayoutStack& stack = getChildRef<LLLayoutStack>("notification_channels");
+	LLNotificationChannelPanel* panelp = new LLNotificationChannelPanel(name);
+	stack.addPanel(panelp, 0, NOTIFICATION_PANEL_HEADER_HEIGHT, TRUE, TRUE, LLLayoutStack::ANIMATE);
+
+	LLButton& header_button = panelp->getChildRef<LLButton>("header");
+	header_button.setToggleState(!open);
+	stack.collapsePanel(panelp, !open);
+
+	updateResizeLimits();
+}
+
+void LLFloaterNotificationConsole::removeChannel(const std::string& name)
+{
+	LLPanel* panelp = getChild<LLPanel>(name, TRUE, FALSE);
+	if (panelp)
+	{
+		getChildRef<LLLayoutStack>("notification_channels").removePanel(panelp);
+		delete panelp;
+	}
+
+	updateResizeLimits();
+}
+
+//static 
+void LLFloaterNotificationConsole::updateResizeLimits()
+{
+	LLLayoutStack& stack = getChildRef<LLLayoutStack>("notification_channels");
+	setResizeLimits(getMinWidth(), LLFLOATER_HEADER_SIZE + HEADER_PADDING + ((NOTIFICATION_PANEL_HEADER_HEIGHT + 3) * stack.getNumPanels()));
+}
+
+void LLFloaterNotificationConsole::onClickAdd(void* user_data)
+{
+	LLFloaterNotificationConsole* floater = (LLFloaterNotificationConsole*)user_data;
+
+	std::string message_name = floater->getChild<LLComboBox>("notification_types")->getValue().asString();
+	if (!message_name.empty())
+	{
+		LLNotifications::instance().add(message_name, LLSD());
+	}
+}
+
+
+//=============== LLFloaterNotification ================
+
+LLFloaterNotification::LLFloaterNotification(LLNotification* note) : mNote(note)
+{
+	LLUICtrlFactory::instance().buildFloater(this, "floater_notification.xml");
+}
+
+BOOL LLFloaterNotification::postBuild()
+{
+	setTitle(mNote->getName());
+	getChild<LLViewerTextEditor>("payload")->setText(mNote->getMessage());
+
+	LLComboBox* responses_combo = getChild<LLComboBox>("response");
+	LLCtrlListInterface* response_list = responses_combo->getListInterface();
+	LLNotificationFormPtr form(mNote->getForm());
+	if(!form)
+	{
+		return TRUE;
+	}
+
+	responses_combo->setCommitCallback(onCommitResponse);
+	responses_combo->setCallbackUserData(this);
+
+	LLSD form_sd = form->asLLSD();
+
+	for (LLSD::array_const_iterator form_item = form_sd.beginArray(); form_item != form_sd.endArray(); ++form_item)
+	{
+		if ( (*form_item)["type"].asString() != "button") continue;
+		std::string text = (*form_item)["text"].asString();
+		response_list->addSimpleElement(text);
+	}
+
+	return TRUE;
+}
+
+void LLFloaterNotification::respond()
+{
+	LLComboBox* responses_combo = getChild<LLComboBox>("response");
+	LLCtrlListInterface* response_list = responses_combo->getListInterface();
+	const std::string& trigger = response_list->getSelectedValue().asString();
+	//llinfos << trigger << llendl;
+
+	LLSD response = mNote->getResponseTemplate();
+	response[trigger] = true;
+	mNote->respond(response);
+}
diff --git a/indra/newview/llfloaternotificationsconsole.h b/indra/newview/llfloaternotificationsconsole.h
new file mode 100644
index 00000000000..5b8e79f0bbd
--- /dev/null
+++ b/indra/newview/llfloaternotificationsconsole.h
@@ -0,0 +1,78 @@
+/** 
+ * @file llfloaternotificationsconsole.h
+ * @brief Debugging console for unified notifications.
+ *
+ * $LicenseInfo:firstyear=2003&license=viewergpl$
+ * 
+ * Copyright (c) 2003-2007, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLFLOATER_NOTIFICATIONS_CONSOLE_H
+#define LL_LLFLOATER_NOTIFICATIONS_CONSOLE_H
+
+#include "llfloater.h"
+#include "llnotifications.h"
+
+class LLFloaterNotificationConsole : 
+	public LLFloater, 
+	public LLFloaterSingleton<LLFloaterNotificationConsole>
+{
+public:
+	LLFloaterNotificationConsole(const LLSD& key);
+
+	// LLPanel
+	BOOL postBuild();
+	void onClose(bool app_quitting);
+
+	void addChannel(const std::string& type, bool open = false);
+	void updateResizeLimits(LLLayoutStack &stack);
+
+	void removeChannel(const std::string& type);
+	void updateResizeLimits();
+
+private:
+	static void onClickAdd(void* user_data);
+};
+
+
+/*
+ * @brief Pop-up debugging view of a generic new notification.
+ */
+class LLFloaterNotification : public LLFloater
+{
+public:
+	LLFloaterNotification(LLNotification* note);
+
+	// LLPanel
+	BOOL postBuild();
+	void respond();
+	void onClose(bool app_quitting) { setVisible(FALSE); }
+
+private:
+	static void onCommitResponse(LLUICtrl* ctrl, void* data) { ((LLFloaterNotification*)data)->respond(); }
+	LLNotification* mNote;
+};
+#endif
+
diff --git a/indra/newview/llfloateropenobject.cpp b/indra/newview/llfloateropenobject.cpp
index b1380ccd8ca..55376c5634d 100644
--- a/indra/newview/llfloateropenobject.cpp
+++ b/indra/newview/llfloateropenobject.cpp
@@ -109,7 +109,7 @@ void LLFloaterOpenObject::show()
 	LLObjectSelectionHandle object_selection = LLSelectMgr::getInstance()->getSelection();
 	if (object_selection->getRootObjectCount() != 1)
 	{
-		gViewerWindow->alertXml("UnableToViewContentsMoreThanOne");
+		LLNotifications::instance().add("UnableToViewContentsMoreThanOne");
 		return;
 	}
 
@@ -131,7 +131,7 @@ void LLFloaterOpenObject::moveToInventory(bool wear)
 {
 	if (mObjectSelection->getRootObjectCount() != 1)
 	{
-		gViewerWindow->alertXml("OnlyCopyContentsOfSingleItem");
+		LLNotifications::instance().add("OnlyCopyContentsOfSingleItem");
 		return;
 	}
 
@@ -172,7 +172,7 @@ void LLFloaterOpenObject::moveToInventory(bool wear)
 		delete data;
 		data = NULL;
 
-		gViewerWindow->alertXml("OpenObjectCannotCopy");
+		LLNotifications::instance().add("OpenObjectCannotCopy");
 	}
 }
 
diff --git a/indra/newview/llfloaterperms.cpp b/indra/newview/llfloaterperms.cpp
index 9405bc61b25..c2d67d602a5 100644
--- a/indra/newview/llfloaterperms.cpp
+++ b/indra/newview/llfloaterperms.cpp
@@ -153,5 +153,5 @@ U32 LLFloaterPerms::getNextOwnerPerms(std::string prefix)
 //static
 void LLFloaterPerms::onClickHelp(void* data)
 {
-	gViewerWindow->alertXml("ClickUploadHelpPermissions");
+	LLNotifications::instance().add("ClickUploadHelpPermissions");
 }
diff --git a/indra/newview/llfloaterpostcard.cpp b/indra/newview/llfloaterpostcard.cpp
index 3182568fe87..f5a7a65abfe 100644
--- a/indra/newview/llfloaterpostcard.cpp
+++ b/indra/newview/llfloaterpostcard.cpp
@@ -249,20 +249,20 @@ void LLFloaterPostcard::onClickSend(void* data)
 		
 		if (to.empty() || !boost::regex_match(to, emailFormat))
 		{
-			gViewerWindow->alertXml("PromptRecipientEmail");
+			LLNotifications::instance().add("PromptRecipientEmail");
 			return;
 		}
 
 		if (from.empty() || !boost::regex_match(from, emailFormat))
 		{
-			gViewerWindow->alertXml("PromptSelfEmail");
+			LLNotifications::instance().add("PromptSelfEmail");
 			return;
 		}
 
 		std::string subject(self->childGetValue("subject_form").asString());
 		if(subject.empty() || !self->mHasFirstMsgFocus)
 		{
-			gViewerWindow->alertXml("PromptMissingSubjMsg", missingSubjMsgAlertCallback, self);
+			LLNotifications::instance().add("PromptMissingSubjMsg", LLSD(), LLSD(), boost::bind(&LLFloaterPostcard::missingSubjMsgAlertCallback, self, _1, _2));
 			return;
 		}
 
@@ -272,7 +272,7 @@ void LLFloaterPostcard::onClickSend(void* data)
 		}
 		else
 		{
-			gViewerWindow->alertXml("ErrorProcessingSnapshot");
+			LLNotifications::instance().add("ErrorProcessingSnapshot");
 		}
 	}
 }
@@ -286,9 +286,9 @@ void LLFloaterPostcard::uploadCallback(const LLUUID& asset_id, void *user_data,
 	
 	if (result)
 	{
-		LLStringUtil::format_map_t args;
-		args["[REASON]"] = std::string(LLAssetStorage::getErrorString(result));
-		gViewerWindow->alertXml("ErrorUploadingPostcard", args);
+		LLSD args;
+		args["REASON"] = std::string(LLAssetStorage::getErrorString(result));
+		LLNotifications::instance().add("ErrorUploadingPostcard", args);
 	}
 	else
 	{
@@ -345,30 +345,28 @@ void LLFloaterPostcard::onMsgFormFocusRecieved(LLFocusableElement* receiver, voi
 	}
 }
 
-void LLFloaterPostcard::missingSubjMsgAlertCallback(S32 option, void* data)
+bool LLFloaterPostcard::missingSubjMsgAlertCallback(const LLSD& notification, const LLSD& response)
 {
-	if(data)
+	S32 option = LLNotification::getSelectedOption(notification, response);
+	if(0 == option)
 	{
-		LLFloaterPostcard* self = static_cast<LLFloaterPostcard*>(data);
-		if(0 == option)
+		// User clicked OK
+		if((childGetValue("subject_form").asString()).empty())
 		{
-			// User clicked OK
-			if((self->childGetValue("subject_form").asString()).empty())
-			{
-				// Stuff the subject back into the form.
-				self->childSetValue("subject_form", self->getString("default_subject"));
-			}
-
-			if(!self->mHasFirstMsgFocus)
-			{
-				// The user never switched focus to the messagee window. 
-				// Using the default string.
-				self->childSetValue("msg_form", self->getString("default_message"));
-			}
+			// Stuff the subject back into the form.
+			childSetValue("subject_form", getString("default_subject"));
+		}
 
-			self->sendPostcard();
+		if(!mHasFirstMsgFocus)
+		{
+			// The user never switched focus to the messagee window. 
+			// Using the default string.
+			childSetValue("msg_form", getString("default_message"));
 		}
+
+		sendPostcard();
 	}
+	return false;
 }
 
 void LLFloaterPostcard::sendPostcard()
diff --git a/indra/newview/llfloaterpostcard.h b/indra/newview/llfloaterpostcard.h
index 28248f65df5..94c619c7e54 100644
--- a/indra/newview/llfloaterpostcard.h
+++ b/indra/newview/llfloaterpostcard.h
@@ -65,7 +65,7 @@ class LLFloaterPostcard
 	static void updateUserInfo(const std::string& email);
 
 	static void onMsgFormFocusRecieved(LLFocusableElement* receiver, void* data);
-	static void missingSubjMsgAlertCallback(S32 option, void* data);
+	bool missingSubjMsgAlertCallback(const LLSD& notification, const LLSD& response);
 
 	void sendPostcard();
 
diff --git a/indra/newview/llfloaterpostprocess.cpp b/indra/newview/llfloaterpostprocess.cpp
index 692b7e036fc..ce5f9c124f9 100644
--- a/indra/newview/llfloaterpostprocess.cpp
+++ b/indra/newview/llfloaterpostprocess.cpp
@@ -169,11 +169,13 @@ void LLFloaterPostProcess::onSaveEffect(void* userData)
 {
 	LLLineEditor* editBox = static_cast<LLLineEditor*>(userData);
 
-	LLSD::String effectName(editBox->getValue().asString());
+	std::string effectName(editBox->getValue().asString());
 
 	if (gPostProcess->mAllEffects.has(effectName))
 	{
-		gViewerWindow->alertXml("PPSaveEffectAlert", &LLFloaterPostProcess::saveAlertCallback, userData);
+		LLSD payload;
+		payload["effect_name"] = effectName;
+		LLNotifications::instance().add("PPSaveEffectAlert", LLSD(), payload, &LLFloaterPostProcess::saveAlertCallback);
 	}
 	else
 	{
@@ -192,20 +194,18 @@ void LLFloaterPostProcess::onChangeEffectName(LLUICtrl* ctrl, void * userData)
 	editBox->setValue(comboBox->getSelectedValue());
 }
 
-void LLFloaterPostProcess::saveAlertCallback(S32 option, void* userData)
+bool LLFloaterPostProcess::saveAlertCallback(const LLSD& notification, const LLSD& response)
 {
-	LLLineEditor* editBox = static_cast<LLLineEditor*>(userData);
+	S32 option = LLNotification::getSelectedOption(notification, response);
 
 	// if they choose save, do it.  Otherwise, don't do anything
 	if (option == 0)
 	{
-		LLSD::String effectName(editBox->getValue().asString());
-
-		gPostProcess->saveEffect(effectName);
+		gPostProcess->saveEffect(notification["payload"]["effect_name"].asString());
 
 		sPostProcess->syncMenu();
 	}
-
+	return false;
 }
 
 void LLFloaterPostProcess::show()
diff --git a/indra/newview/llfloaterpostprocess.h b/indra/newview/llfloaterpostprocess.h
index 8b590f8b8ef..88d3fd04e70 100644
--- a/indra/newview/llfloaterpostprocess.h
+++ b/indra/newview/llfloaterpostprocess.h
@@ -68,7 +68,7 @@ class LLFloaterPostProcess : public LLFloater
 	static void onChangeEffectName(LLUICtrl* ctrl, void * userData);
 
 	/// prompts a user when overwriting an effect
-	static void saveAlertCallback(S32 option, void* userData);
+	static bool saveAlertCallback(const LLSD& notification, const LLSD& response);
 
 	/// show off our menu
 	static void show();
diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp
index 737a2afbb78..1e10f90609b 100644
--- a/indra/newview/llfloaterregioninfo.cpp
+++ b/indra/newview/llfloaterregioninfo.cpp
@@ -59,6 +59,7 @@
 #include "llfloatergroups.h"
 #include "llfloatertelehub.h"
 #include "llfloaterwindlight.h"
+#include "llinventorymodel.h"
 #include "lllineeditor.h"
 #include "llalertdialog.h"
 #include "llnamelistctrl.h"
@@ -540,8 +541,8 @@ void LLPanelRegionInfo::initHelpBtn(const std::string& name, const std::string&
 // static
 void LLPanelRegionInfo::onClickHelp(void* data)
 {
-	const std::string* xml_alert = (std::string*)data;
-	gViewerWindow->alertXml(*xml_alert);
+	std::string* xml_alert = (std::string*)data;
+	LLNotifications::instance().add(*xml_alert);
 }
 
 /////////////////////////////////////////////////////////////////////////////
@@ -638,16 +639,17 @@ void LLPanelRegionGeneralInfo::onKickCommit(const std::vector<std::string>& name
 void LLPanelRegionGeneralInfo::onClickKickAll(void* userdata)
 {
 	llinfos << "LLPanelRegionGeneralInfo::onClickKickAll" << llendl;
-	gViewerWindow->alertXml("KickUsersFromRegion", onKickAllCommit, userdata);
+	LLNotifications::instance().add("KickUsersFromRegion", 
+									LLSD(), 
+									LLSD(), 
+									boost::bind(&LLPanelRegionGeneralInfo::onKickAllCommit, (LLPanelRegionGeneralInfo*)userdata, _1, _2));
 }
 
-// static
-void LLPanelRegionGeneralInfo::onKickAllCommit(S32 option, void* userdata)
+bool LLPanelRegionGeneralInfo::onKickAllCommit(const LLSD& notification, const LLSD& response)
 {
+	S32 option = LLNotification::getSelectedOption(notification, response);
 	if (option == 0)
 	{
-		LLPanelRegionGeneralInfo* self = (LLPanelRegionGeneralInfo*)userdata;
-		if(!self) return;
 		strings_t strings;
 		// [0] = our agent id
 		std::string buffer;
@@ -656,26 +658,29 @@ void LLPanelRegionGeneralInfo::onKickAllCommit(S32 option, void* userdata)
 
 		LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
 		// historical message name
-		self->sendEstateOwnerMessage(gMessageSystem, "teleporthomeallusers", invoice, strings);
+		sendEstateOwnerMessage(gMessageSystem, "teleporthomeallusers", invoice, strings);
 	}
+	return false;
 }
 
 // static
 void LLPanelRegionGeneralInfo::onClickMessage(void* userdata)
 {
 	llinfos << "LLPanelRegionGeneralInfo::onClickMessage" << llendl;
-	gViewerWindow->alertXmlEditText("MessageRegion", LLStringUtil::format_map_t(),
-									NULL, NULL,
-									onMessageCommit, userdata);
+	LLNotifications::instance().add("MessageRegion", 
+		LLSD(), 
+		LLSD(), 
+		boost::bind(&LLPanelRegionGeneralInfo::onMessageCommit, (LLPanelRegionGeneralInfo*)userdata, _1, _2));
 }
 
 // static
-void LLPanelRegionGeneralInfo::onMessageCommit(S32 option, const std::string& text, void* userdata)
+bool LLPanelRegionGeneralInfo::onMessageCommit(const LLSD& notification, const LLSD& response)
 {
-	if(option != 0) return;
-	if(text.empty()) return;
-	LLPanelRegionGeneralInfo* self = (LLPanelRegionGeneralInfo*)userdata;
-	if(!self) return;
+	if(LLNotification::getSelectedOption(notification, response) != 0) return false;
+
+	std::string text = response["message"].asString();
+	if (text.empty()) return false;
+
 	llinfos << "Message to everyone: " << text << llendl;
 	strings_t strings;
 	// [0] grid_x, unused here
@@ -693,7 +698,8 @@ void LLPanelRegionGeneralInfo::onMessageCommit(S32 option, const std::string& te
 	strings.push_back(strings_t::value_type(name));
 	strings.push_back(strings_t::value_type(text));
 	LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
-	self->sendEstateOwnerMessage(gMessageSystem, "simulatormessage", invoice, strings);
+	sendEstateOwnerMessage(gMessageSystem, "simulatormessage", invoice, strings);
+	return false;
 }
 
 // static
@@ -780,7 +786,7 @@ BOOL LLPanelRegionGeneralInfo::sendUpdate()
 		LLViewerRegion* region = gAgent.getRegion();
 		if (region && access != region->getSimAccess() )
 		{
-			gViewerWindow->alertXml("RegionMaturityChange");
+			LLNotifications::instance().add("RegionMaturityChange");
 		}
 	}
 
@@ -881,48 +887,56 @@ void LLPanelRegionDebugInfo::onClickReturn(void* data)
 	LLPanelRegionDebugInfo* panelp = (LLPanelRegionDebugInfo*) data;
 	if (panelp->mTargetAvatar.isNull()) return;
 
-	LLStringUtil::format_map_t args;
-	args["[USER_NAME]"] = panelp->childGetValue("target_avatar_name").asString();
-	gViewerWindow->alertXml("EstateObjectReturn", args, callbackReturn, data);
+	LLSD args;
+	args["USER_NAME"] = panelp->childGetValue("target_avatar_name").asString();
+	LLSD payload;
+	payload["avatar_id"] = panelp->mTargetAvatar;
+	
+	U32 flags = SWD_ALWAYS_RETURN_OBJECTS;
+
+	if (panelp->childGetValue("return_scripts").asBoolean())
+	{
+		flags |= SWD_SCRIPTED_ONLY;
+	}
+	
+	if (panelp->childGetValue("return_other_land").asBoolean())
+	{
+		flags |= SWD_OTHERS_LAND_ONLY;
+	}
+	payload["flags"] = int(flags);
+	payload["return_estate_wide"] = panelp->childGetValue("return_estate_wide").asBoolean();
+	LLNotifications::instance().add("EstateObjectReturn", args, payload, 
+									boost::bind(&LLPanelRegionDebugInfo::callbackReturn, panelp, _1, _2));
 }
 
-// static
-void LLPanelRegionDebugInfo::callbackReturn( S32 option, void* userdata )
+bool LLPanelRegionDebugInfo::callbackReturn(const LLSD& notification, const LLSD& response)
 {
-	if (option != 0) return;
+	S32 option = LLNotification::getSelectedOption(notification, response);
+	if (option != 0) return false;
 
-	LLPanelRegionDebugInfo* self = (LLPanelRegionDebugInfo*) userdata;
-	if (!self->mTargetAvatar.isNull())
+	LLUUID target_avatar = notification["payload"]["avatar_id"].asUUID();
+	if (!target_avatar.isNull())
 	{
-		U32 flags = SWD_ALWAYS_RETURN_OBJECTS;
-
-		if (self->childGetValue("return_scripts").asBoolean())
-		{
-			flags |= SWD_SCRIPTED_ONLY;
-		}
-		
-		if (self->childGetValue("return_other_land").asBoolean())
-		{
-			flags |= SWD_OTHERS_LAND_ONLY;
-		}
-
-		if (self->childGetValue("return_estate_wide").asBoolean())
+		U32 flags = notification["payload"]["flags"].asInteger();
+		bool return_estate_wide = notification["payload"]["return_estate_wide"];
+		if (return_estate_wide)
 		{
 			// send as estate message - routed by spaceserver to all regions in estate
 			strings_t strings;
 			strings.push_back(llformat("%d", flags));
-			strings.push_back(self->mTargetAvatar.asString());
+			strings.push_back(target_avatar.asString());
 
 			LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
 		
-			self->sendEstateOwnerMessage(gMessageSystem, "estateobjectreturn", invoice, strings);
+			sendEstateOwnerMessage(gMessageSystem, "estateobjectreturn", invoice, strings);
 		}
 		else
 		{
 			// send to this simulator only
-			send_sim_wide_deletes(self->mTargetAvatar, flags);
-		}
+  			send_sim_wide_deletes(target_avatar, flags);
+  		}
 	}
+	return false;
 }
 
 
@@ -953,19 +967,20 @@ void LLPanelRegionDebugInfo::onClickTopScripts(void* data)
 // static
 void LLPanelRegionDebugInfo::onClickRestart(void* data)
 {
-	gViewerWindow->alertXml("ConfirmRestart", callbackRestart, data);
+	LLNotifications::instance().add("ConfirmRestart", LLSD(), LLSD(), 
+		boost::bind(&LLPanelRegionDebugInfo::callbackRestart, (LLPanelRegionDebugInfo*)data, _1, _2));
 }
 
-// static
-void LLPanelRegionDebugInfo::callbackRestart(S32 option, void* data)
+bool LLPanelRegionDebugInfo::callbackRestart(const LLSD& notification, const LLSD& response)
 {
-	if (option != 0) return;
+	S32 option = LLNotification::getSelectedOption(notification, response);
+	if (option != 0) return false;
 
-	LLPanelRegionDebugInfo* self = (LLPanelRegionDebugInfo*)data;
 	strings_t strings;
 	strings.push_back("120");
 	LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
-	self->sendEstateOwnerMessage(gMessageSystem, "restart", invoice, strings);
+	sendEstateOwnerMessage(gMessageSystem, "restart", invoice, strings);
+	return false;
 }
 
 // static
@@ -1123,21 +1138,21 @@ BOOL LLPanelRegionTextureInfo::validateTextureSizes()
 
 		if (components != 3)
 		{
-			LLStringUtil::format_map_t args;
-			args["[TEXTURE_NUM]"] = llformat("%d",i+1);
-			args["[TEXTURE_BIT_DEPTH]"] = llformat("%d",components * 8);
-			gViewerWindow->alertXml("InvalidTerrainBitDepth", args);
+			LLSD args;
+			args["TEXTURE_NUM"] = i+1;
+			args["TEXTURE_BIT_DEPTH"] = llformat("%d",components * 8);
+			LLNotifications::instance().add("InvalidTerrainBitDepth", args);
 			return FALSE;
 		}
 
 		if (width > 512 || height > 512)
 		{
 
-			LLStringUtil::format_map_t args;
-			args["[TEXTURE_NUM]"] = llformat("%d",i+1);
-			args["[TEXTURE_SIZE_X]"] = llformat("%d",width);
-			args["[TEXTURE_SIZE_Y]"] = llformat("%d",height);
-			gViewerWindow->alertXml("InvalidTerrainSize", args);
+			LLSD args;
+			args["TEXTURE_NUM"] = i+1;
+			args["TEXTURE_SIZE_X"] = width;
+			args["TEXTURE_SIZE_Y"] = height;
+			LLNotifications::instance().add("InvalidTerrainSize", args);
 			return FALSE;
 			
 		}
@@ -1334,26 +1349,27 @@ void LLPanelRegionTerrainInfo::onClickUploadRaw(void* data)
 	LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
 	self->sendEstateOwnerMessage(gMessageSystem, "terrain", invoice, strings);
 
-	gViewerWindow->alertXml("RawUploadStarted");
+	LLNotifications::instance().add("RawUploadStarted");
 }
 
 // static
 void LLPanelRegionTerrainInfo::onClickBakeTerrain(void* data)
 {
-	gViewerWindow->alertXml("ConfirmBakeTerrain", 
-							 callbackBakeTerrain, data);
+	LLNotifications::instance().add(
+		LLNotification::Params("ConfirmBakeTerrain")
+		.functor(boost::bind(&LLPanelRegionTerrainInfo::callbackBakeTerrain, (LLPanelRegionTerrainInfo*)data, _1, _2)));
 }
 
-// static
-void LLPanelRegionTerrainInfo::callbackBakeTerrain(S32 option, void* data)
+bool LLPanelRegionTerrainInfo::callbackBakeTerrain(const LLSD& notification, const LLSD& response)
 {
-	if (option != 0) return;
+	S32 option = LLNotification::getSelectedOption(notification, response);
+	if (option != 0) return false;
 
-	LLPanelRegionTerrainInfo* self = (LLPanelRegionTerrainInfo*)data;
 	strings_t strings;
 	strings.push_back("bake");
 	LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
-	self->sendEstateOwnerMessage(gMessageSystem, "terrain", invoice, strings);
+	sendEstateOwnerMessage(gMessageSystem, "terrain", invoice, strings);
+	return false;
 }
 
 /////////////////////////////////////////////////////////////////////////////
@@ -1440,9 +1456,9 @@ void LLPanelEstateInfo::onClickAddAllowedAgent(void* user_data)
 	{
 		//args
 
-		LLStringUtil::format_map_t args;
-		args["[MAX_AGENTS]"] = llformat("%d",ESTATE_MAX_ACCESS_IDS);
-		gViewerWindow->alertXml("MaxAllowedAgentOnRegion", args);
+		LLSD args;
+		args["MAX_AGENTS"] = llformat("%d",ESTATE_MAX_ACCESS_IDS);
+		LLNotifications::instance().add("MaxAllowedAgentOnRegion", args);
 		return;
 	}
 	accessAddCore(ESTATE_ACCESS_ALLOWED_AGENT_ADD, "EstateAllowedAgentAdd");
@@ -1462,35 +1478,36 @@ void LLPanelEstateInfo::onClickAddAllowedGroup(void* user_data)
 	if (!list) return;
 	if (list->getItemCount() >= ESTATE_MAX_ACCESS_IDS)
 	{
-		LLStringUtil::format_map_t args;
-		args["[MAX_GROUPS]"] = llformat("%d",ESTATE_MAX_ACCESS_IDS);
-		gViewerWindow->alertXml("MaxAllowedGroupsOnRegion", args);
+		LLSD args;
+		args["MAX_GROUPS"] = llformat("%d",ESTATE_MAX_ACCESS_IDS);
+		LLNotifications::instance().add("MaxAllowedGroupsOnRegion", args);
 		return;
 	}
+
+	LLNotification::Params params("ChangeLindenAccess");
+	params.functor(boost::bind(&LLPanelEstateInfo::addAllowedGroup, self, _1, _2));
 	if (isLindenEstate())
 	{
-		gViewerWindow->alertXml("ChangeLindenAccess", addAllowedGroup, user_data);
+		LLNotifications::instance().add(params);
 	}
 	else
 	{
-		addAllowedGroup(0, user_data);
+		LLNotifications::instance().forceResponse(params, 0);
 	}
 }
 
-// static
-void LLPanelEstateInfo::addAllowedGroup(S32 option, void* user_data)
+bool LLPanelEstateInfo::addAllowedGroup(const LLSD& notification, const LLSD& response)
 {
-	if (option != 0) return;
+	S32 option = LLNotification::getSelectedOption(notification, response);
+	if (option != 0) return false;
 
-	LLPanelEstateInfo* panelp = (LLPanelEstateInfo*)user_data;
-
-	LLFloater* parent_floater = gFloaterView->getParentFloater(panelp);
+	LLFloater* parent_floater = gFloaterView->getParentFloater(this);
 
 	LLFloaterGroupPicker* widget;
 	widget = LLFloaterGroupPicker::showInstance(LLSD(gAgent.getID()));
 	if (widget)
 	{
-		widget->setSelectCallback(addAllowedGroup2, user_data);
+		widget->setSelectCallback(addAllowedGroup2, NULL);
 		if (parent_floater)
 		{
 			LLRect new_rect = gFloaterView->findNeighboringPosition(parent_floater, widget);
@@ -1498,6 +1515,8 @@ void LLPanelEstateInfo::addAllowedGroup(S32 option, void* user_data)
 			parent_floater->addDependentFloater(widget);
 		}
 	}
+
+	return false;
 }
 
 // static
@@ -1514,9 +1533,9 @@ void LLPanelEstateInfo::onClickAddBannedAgent(void* user_data)
 	if (!list) return;
 	if (list->getItemCount() >= ESTATE_MAX_ACCESS_IDS)
 	{
-		LLStringUtil::format_map_t args;
-		args["[MAX_BANNED]"] = llformat("%d",ESTATE_MAX_ACCESS_IDS);
-		gViewerWindow->alertXml("MaxBannedAgentsOnRegion", args);
+		LLSD args;
+		args["MAX_BANNED"] = llformat("%d",ESTATE_MAX_ACCESS_IDS);
+		LLNotifications::instance().add("MaxBannedAgentsOnRegion", args);
 		return;
 	}
 	accessAddCore(ESTATE_ACCESS_BANNED_AGENT_ADD, "EstateBannedAgentAdd");
@@ -1536,9 +1555,9 @@ void LLPanelEstateInfo::onClickAddEstateManager(void* user_data)
 	if (!list) return;
 	if (list->getItemCount() >= ESTATE_MAX_MANAGERS)
 	{	// Tell user they can't add more managers
-		LLStringUtil::format_map_t args;
-		args["[MAX_MANAGER]"] = llformat("%d",ESTATE_MAX_MANAGERS);
-		gViewerWindow->alertXml("MaxManagersOnRegion", args);
+		LLSD args;
+		args["MAX_MANAGER"] = llformat("%d",ESTATE_MAX_MANAGERS);
+		LLNotifications::instance().add("MaxManagersOnRegion", args);
 	}
 	else
 	{	// Go pick managers to add
@@ -1558,7 +1577,6 @@ void LLPanelEstateInfo::onClickRemoveEstateManager(void* user_data)
 struct LLKickFromEstateInfo
 {
 	LLPanelEstateInfo *mEstatePanelp;
-	std::string    mDialogName;
 	LLUUID      mAgentID;
 };
 
@@ -1590,45 +1608,42 @@ void LLPanelEstateInfo::onKickUserCommit(const std::vector<std::string>& names,
 	//keep track of what user they want to kick and other misc info
 	LLKickFromEstateInfo *kick_info = new LLKickFromEstateInfo();
 	kick_info->mEstatePanelp = self;
-	kick_info->mDialogName  = "EstateKickUser";
 	kick_info->mAgentID     = ids[0];
 
 	//Bring up a confirmation dialog
-	LLStringUtil::format_map_t args;
-	args["[EVIL_USER]"] = names[0];
-	gViewerWindow->alertXml(kick_info->mDialogName, args, LLPanelEstateInfo::kickUserConfirm, (void*)kick_info);
+	LLSD args;
+	args["EVIL_USER"] = names[0];
+	LLSD payload;
+	payload["agent_id"] = ids[0];
+	LLNotifications::instance().add("EstateKickUser", args, payload, boost::bind(&LLPanelEstateInfo::kickUserConfirm, self, _1, _2));
 
 }
 
-void LLPanelEstateInfo::kickUserConfirm(S32 option, void* userdata)
+bool LLPanelEstateInfo::kickUserConfirm(const LLSD& notification, const LLSD& response)
 {
-	//extract the callback parameter
-	LLKickFromEstateInfo *kick_info = (LLKickFromEstateInfo*) userdata;
-	if (!kick_info) return;
-
-	LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
-	strings_t strings;
-	std::string buffer;
-
+	S32 option = LLNotification::getSelectedOption(notification, response);
 	switch(option)
 	{
 	case 0:
-		//Kick User
-		kick_info->mAgentID.toString(buffer);
-		strings.push_back(buffer);
+		{
+			//Kick User
+			strings_t strings;
+			strings.push_back(notification["payload"]["agent_id"].asString());
 
-		kick_info->mEstatePanelp->sendEstateOwnerMessage(gMessageSystem, "kickestate", invoice, strings);
-		break;
+			sendEstateOwnerMessage(gMessageSystem, "kickestate", LLFloaterRegionInfo::getLastInvoice(), strings);
+			break;
+		}
 	default:
 		break;
 	}
-
-	delete kick_info;
-	kick_info = NULL;
+	return false;
 }
 
 //---------------------------------------------------------------------------
 // Core Add/Remove estate access methods
+// TODO: INTERNATIONAL: don't build message text here;
+// instead, create multiple translatable messages and choose
+// one based on the status.
 //---------------------------------------------------------------------------
 std::string all_estates_text()
 {
@@ -1669,6 +1684,33 @@ bool LLPanelEstateInfo::isLindenEstate()
 typedef std::vector<LLUUID> AgentOrGroupIDsVector;
 struct LLEstateAccessChangeInfo
 {
+	LLEstateAccessChangeInfo(const LLSD& sd)
+	{
+		mDialogName = sd["dialog_name"].asString();
+		mOperationFlag = (U32)sd["operation"].asInteger();
+		LLSD::array_const_iterator end_it = sd["allowed_ids"].endArray();
+		for (LLSD::array_const_iterator id_it = sd["allowed_ids"].beginArray();
+			id_it != end_it;
+			++id_it)
+		{
+			mAgentOrGroupIDs.push_back(id_it->asUUID());
+		}
+	}
+
+	const LLSD asLLSD() const
+	{
+		LLSD sd;
+		sd["name"] = mDialogName;
+		sd["operation"] = (S32)mOperationFlag;
+		for (AgentOrGroupIDsVector::const_iterator it = mAgentOrGroupIDs.begin();
+			it != mAgentOrGroupIDs.end();
+			++it)
+		{
+			sd["allowed_ids"].append(*it);
+		}
+		return sd;
+	}
+
 	U32 mOperationFlag;	// ESTATE_ACCESS_BANNED_AGENT_ADD, _REMOVE, etc.
 	std::string mDialogName;
 	AgentOrGroupIDsVector mAgentOrGroupIDs; // List of agent IDs to apply to this change
@@ -1678,56 +1720,65 @@ struct LLEstateAccessChangeInfo
 // static
 void LLPanelEstateInfo::addAllowedGroup2(LLUUID id, void* user_data)
 {
-	LLEstateAccessChangeInfo* change_info = new LLEstateAccessChangeInfo;
-	change_info->mOperationFlag = ESTATE_ACCESS_ALLOWED_GROUP_ADD;
-	change_info->mDialogName = "EstateAllowedGroupAdd";
-	change_info->mAgentOrGroupIDs.push_back(id);
+	LLSD payload;
+	payload["operation"] = (S32)ESTATE_ACCESS_ALLOWED_GROUP_ADD;
+	payload["dialog_name"] = "EstateAllowedGroupAdd";
+	payload["allowed_ids"].append(id);
+
+	LLSD args;
+	args["ALL_ESTATES"] = all_estates_text();
 
+	LLNotification::Params params("EstateAllowedGroupAdd");
+	params.payload(payload)
+		.substitutions(args)
+		.functor(accessCoreConfirm);
 	if (isLindenEstate())
 	{
-		accessCoreConfirm(0, (void*)change_info);
+		LLNotifications::instance().forceResponse(params, 0);
 	}
 	else
 	{
-		LLStringUtil::format_map_t args;
-		args["[ALL_ESTATES]"] = all_estates_text();
-		gViewerWindow->alertXml(change_info->mDialogName, args, accessCoreConfirm, (void*)change_info);
+		LLNotifications::instance().add(params);
 	}
 }
 
 // static
 void LLPanelEstateInfo::accessAddCore(U32 operation_flag, const std::string& dialog_name)
 {
-	LLEstateAccessChangeInfo* change_info = new LLEstateAccessChangeInfo;
-	change_info->mOperationFlag = operation_flag;
-	change_info->mDialogName = dialog_name;
+	LLSD payload;
+	payload["operation"] = (S32)operation_flag;
+	payload["dialog_name"] = dialog_name;
 	// agent id filled in after avatar picker
 
+	LLNotification::Params params("ChangeLindenAccess");
+	params.payload(payload)
+		.functor(accessAddCore2);
+
 	if (isLindenEstate())
 	{
-		gViewerWindow->alertXml("ChangeLindenAccess", accessAddCore2, change_info);
+		LLNotifications::instance().add(params);
 	}
 	else
 	{
 		// same as clicking "OK"
-		accessAddCore2(0, change_info);
+		LLNotifications::instance().forceResponse(params, 0);
 	}
 }
 
 // static
-void LLPanelEstateInfo::accessAddCore2(S32 option, void* data)
+bool LLPanelEstateInfo::accessAddCore2(const LLSD& notification, const LLSD& response)
 {
-	LLEstateAccessChangeInfo* change_info = (LLEstateAccessChangeInfo*)data;
+	S32 option = LLNotification::getSelectedOption(notification, response);
 	if (option != 0)
 	{
 		// abort change
-		delete change_info;
-		change_info = NULL;
-		return;
+		return false;
 	}
 
+	LLEstateAccessChangeInfo* change_info = new LLEstateAccessChangeInfo(notification["payload"]);
 	// avatar picker yes multi-select, yes close-on-select
 	LLFloaterAvatarPicker::show(accessAddCore3, (void*)change_info, TRUE, TRUE);
+	return false;
 }
 
 // static
@@ -1756,12 +1807,12 @@ void LLPanelEstateInfo::accessAddCore3(const std::vector<std::string>& names, co
 		int currentCount = (list ? list->getItemCount() : 0);
 		if (ids.size() + currentCount > ESTATE_MAX_ACCESS_IDS)
 		{
-			LLStringUtil::format_map_t args;
-			args["[NUM_ADDED]"] = llformat("%d",ids.size());
-			args["[MAX_AGENTS]"] = llformat("%d",ESTATE_MAX_ACCESS_IDS);
-			args["[LIST_TYPE]"] = "Allowed Residents";
-			args["[NUM_EXCESS]"] = llformat("%d",(ids.size()+currentCount)-ESTATE_MAX_ACCESS_IDS);
-			gViewerWindow->alertXml("MaxAgentOnRegionBatch", args);
+			LLSD args;
+			args["NUM_ADDED"] = llformat("%d",ids.size());
+			args["MAX_AGENTS"] = llformat("%d",ESTATE_MAX_ACCESS_IDS);
+			args["LIST_TYPE"] = "Allowed Residents";
+			args["NUM_EXCESS"] = llformat("%d",(ids.size()+currentCount)-ESTATE_MAX_ACCESS_IDS);
+			LLNotifications::instance().add("MaxAgentOnRegionBatch", args);
 			delete change_info;
 			return;
 		}
@@ -1772,28 +1823,34 @@ void LLPanelEstateInfo::accessAddCore3(const std::vector<std::string>& names, co
 		int currentCount = (list ? list->getItemCount() : 0);
 		if (ids.size() + currentCount > ESTATE_MAX_ACCESS_IDS)
 		{
-			LLStringUtil::format_map_t args;
-			args["[NUM_ADDED]"] = llformat("%d",ids.size());
-			args["[MAX_AGENTS]"] = llformat("%d",ESTATE_MAX_ACCESS_IDS);
-			args["[LIST_TYPE]"] = "Banned Residents";
-			args["[NUM_EXCESS]"] = llformat("%d",(ids.size()+currentCount)-ESTATE_MAX_ACCESS_IDS);
-			gViewerWindow->alertXml("MaxAgentOnRegionBatch", args);
+			LLSD args;
+			args["NUM_ADDED"] = llformat("%d",ids.size());
+			args["MAX_AGENTS"] = llformat("%d",ESTATE_MAX_ACCESS_IDS);
+			args["LIST_TYPE"] = "Banned Residents";
+			args["NUM_EXCESS"] = llformat("%d",(ids.size()+currentCount)-ESTATE_MAX_ACCESS_IDS);
+			LLNotifications::instance().add("MaxAgentOnRegionBatch", args);
 			delete change_info;
 			return;
 		}
 	}
 
+	LLSD args;
+	args["ALL_ESTATES"] = all_estates_text();
+
+	LLNotification::Params params(change_info->mDialogName);
+	params.substitutions(args)
+		.payload(change_info->asLLSD())
+		.functor(accessCoreConfirm);
+
 	if (isLindenEstate())
 	{
 		// just apply to this estate
-		accessCoreConfirm(0, (void*)change_info);
+		LLNotifications::instance().forceResponse(params, 0);
 	}
 	else
 	{
 		// ask if this estate or all estates with this owner
-		LLStringUtil::format_map_t args;
-		args["[ALL_ESTATES]"] = all_estates_text();
-		gViewerWindow->alertXml(change_info->mDialogName, args, accessCoreConfirm, (void*)change_info);
+		LLNotifications::instance().add(params);
 	}
 }
 
@@ -1809,85 +1866,87 @@ void LLPanelEstateInfo::accessRemoveCore(U32 operation_flag, const std::string&
 	if (list_vector.size() == 0)
 		return;
 
-	LLEstateAccessChangeInfo* change_info = new LLEstateAccessChangeInfo;
-	change_info->mOperationFlag = operation_flag;
-	change_info->mDialogName = dialog_name;
+	LLSD payload;
+	payload["operation"] = (S32)operation_flag;
+	payload["dialog_name"] = dialog_name;
 	
 	for (std::vector<LLScrollListItem*>::const_iterator iter = list_vector.begin();
 	     iter != list_vector.end();
 	     iter++)
 	{
 		LLScrollListItem *item = (*iter);
-		change_info->mAgentOrGroupIDs.push_back(item->getUUID());
+		payload["allowed_ids"].append(item->getUUID());
 	}
 	
+	LLNotification::Params params("ChangeLindenAccess");
+	params.payload(payload)
+		.functor(accessRemoveCore2);
+
 	if (isLindenEstate())
 	{
 		// warn on change linden estate
-		gViewerWindow->alertXml("ChangeLindenAccess", 
-					accessRemoveCore2,
-					(void*)change_info);
+		LLNotifications::instance().add(params);
 	}
 	else
 	{
 		// just proceed, as if clicking OK
-		accessRemoveCore2(0, (void*)change_info);
+		LLNotifications::instance().forceResponse(params, 0);
 	}
 }
 
 // static
-void LLPanelEstateInfo::accessRemoveCore2(S32 option, void* data)
+bool LLPanelEstateInfo::accessRemoveCore2(const LLSD& notification, const LLSD& response)
 {
-	LLEstateAccessChangeInfo* change_info = (LLEstateAccessChangeInfo*)data;
+	S32 option = LLNotification::getSelectedOption(notification, response);
 	if (option != 0)
 	{
 		// abort
-		delete change_info;
-		change_info = NULL;
-		return;
+		return false;
 	}
 
 	// If Linden estate, can only apply to "this" estate, not all estates
 	// owned by NULL.
 	if (isLindenEstate())
 	{
-		accessCoreConfirm(0, (void*)change_info);
+		accessCoreConfirm(notification, response);
 	}
 	else
 	{
-		LLStringUtil::format_map_t args;
-		args["[ALL_ESTATES]"] = all_estates_text();
-		gViewerWindow->alertXml(change_info->mDialogName, 
-					args, 
-					accessCoreConfirm, 
-					(void*)change_info);
+		LLSD args;
+		args["ALL_ESTATES"] = all_estates_text();
+		LLNotifications::instance().add(notification["payload"]["dialog_name"], 
+										args,
+										notification["payload"],
+										accessCoreConfirm);
 	}
+	return false;
 }
 
 // Used for both access add and remove operations, depending on the mOperationFlag
 // passed in (ESTATE_ACCESS_BANNED_AGENT_ADD, ESTATE_ACCESS_ALLOWED_AGENT_REMOVE, etc.)
 // static
-void LLPanelEstateInfo::accessCoreConfirm(S32 option, void* data)
+bool LLPanelEstateInfo::accessCoreConfirm(const LLSD& notification, const LLSD& response)
 {
-	LLEstateAccessChangeInfo* change_info = (LLEstateAccessChangeInfo*)data;
-	const U32 originalFlags = change_info->mOperationFlag;
-	AgentOrGroupIDsVector& ids = change_info->mAgentOrGroupIDs;
+	S32 option = LLNotification::getSelectedOption(notification, response);
+	const U32 originalFlags = (U32)notification["payload"]["operation"].asInteger();
 
 	LLViewerRegion* region = gAgent.getRegion();
 	
-	for (AgentOrGroupIDsVector::const_iterator iter = ids.begin();
-	     iter != ids.end();
+	LLSD::array_const_iterator end_it = notification["payload"]["allowed_ids"].endArray();
+
+	for (LLSD::array_const_iterator iter = notification["payload"]["allowed_ids"].beginArray();
+		iter != end_it;
 	     iter++)
 	{
 		U32 flags = originalFlags;
-		if (iter + 1 != ids.end())
+		if (iter + 1 != end_it)
 			flags |= ESTATE_ACCESS_NO_REPLY;
 
-		const LLUUID id = (*iter);
-		if ((change_info->mOperationFlag & ESTATE_ACCESS_BANNED_AGENT_ADD)
+		const LLUUID id = iter->asUUID();
+		if (((U32)notification["payload"]["operation"].asInteger() & ESTATE_ACCESS_BANNED_AGENT_ADD)
 		    && region && (region->getOwner() == id))
 		{
-			gViewerWindow->alertXml("OwnerCanNotBeDenied");
+			LLNotifications::instance().add("OwnerCanNotBeDenied");
 			break;
 		}
 		switch(option)
@@ -1919,8 +1978,7 @@ void LLPanelEstateInfo::accessCoreConfirm(S32 option, void* data)
 			    break;
 		}
 	}
-	delete change_info;
-	change_info = NULL;
+	return false;
 }
 
 // key = "estateaccessdelta"
@@ -2146,34 +2204,34 @@ BOOL LLPanelEstateInfo::sendUpdate()
 {
 	llinfos << "LLPanelEsateInfo::sendUpdate()" << llendl;
 
+	LLNotification::Params params("ChangeLindenEstate");
+	params.functor(boost::bind(&LLPanelEstateInfo::callbackChangeLindenEstate, this, _1, _2));
+
 	if (getEstateID() <= ESTATE_LAST_LINDEN)
 	{
 		// trying to change reserved estate, warn
-		gViewerWindow->alertXml("ChangeLindenEstate",
-							   callbackChangeLindenEstate,
-							   this);
+		LLNotifications::instance().add(params);
 	}
 	else
 	{
 		// for normal estates, just make the change
-		callbackChangeLindenEstate(0, this);
+		LLNotifications::instance().forceResponse(params, 0);
 	}
 	return TRUE;
 }
 
-// static
-void LLPanelEstateInfo::callbackChangeLindenEstate(S32 option, void* data)
+bool LLPanelEstateInfo::callbackChangeLindenEstate(const LLSD& notification, const LLSD& response)
 {
-	LLPanelEstateInfo* self = (LLPanelEstateInfo*)data;
+	S32 option = LLNotification::getSelectedOption(notification, response);
 	switch(option)
 	{
 	case 0:
 		// send the update
-		if (!self->commitEstateInfoCaps())
+		if (!commitEstateInfoCaps())
 		{
 			// the caps method failed, try the old way
 			LLFloaterRegionInfo::nextInvoice();
-			self->commitEstateInfoDataserver();
+			commitEstateInfoDataserver();
 		}
 		// we don't want to do this because we'll get it automatically from the sim
 		// after the spaceserver processes it
@@ -2188,6 +2246,7 @@ void LLPanelEstateInfo::callbackChangeLindenEstate(S32 option, void* data)
 		// do nothing
 		break;
 	}
+	return false;
 }
 
 
@@ -2572,18 +2631,15 @@ BOOL LLPanelEstateInfo::checkSunHourSlider(LLUICtrl* child_ctrl)
 void LLPanelEstateInfo::onClickMessageEstate(void* userdata)
 {
 	llinfos << "LLPanelEstateInfo::onClickMessageEstate" << llendl;
-	gViewerWindow->alertXmlEditText("MessageEstate", LLStringUtil::format_map_t(),
-									NULL, NULL,
-									onMessageCommit, userdata);
+	LLNotifications::instance().add("MessageEstate", LLSD(), LLSD(), boost::bind(&LLPanelEstateInfo::onMessageCommit, (LLPanelEstateInfo*)userdata, _1, _2));
 }
 
-// static
-void LLPanelEstateInfo::onMessageCommit(S32 option, const std::string& text, void* userdata)
+bool LLPanelEstateInfo::onMessageCommit(const LLSD& notification, const LLSD& response)
 {
-	if(option != 0) return;
-	if(text.empty()) return;
-	LLPanelEstateInfo* self = (LLPanelEstateInfo*)userdata;
-	if(!self) return;
+	S32 option = LLNotification::getSelectedOption(notification, response);
+	std::string text = response["message"].asString();
+	if(option != 0) return false;
+	if(text.empty()) return false;
 	llinfos << "Message to everyone: " << text << llendl;
 	strings_t strings;
 	//integers_t integers;
@@ -2592,7 +2648,8 @@ void LLPanelEstateInfo::onMessageCommit(S32 option, const std::string& text, voi
 	strings.push_back(strings_t::value_type(name));
 	strings.push_back(strings_t::value_type(text));
 	LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
-	self->sendEstateOwnerMessage(gMessageSystem, "instantmessage", invoice, strings);
+	sendEstateOwnerMessage(gMessageSystem, "instantmessage", invoice, strings);
+	return false;
 }
 
 LLPanelEstateCovenant::LLPanelEstateCovenant()
@@ -2695,9 +2752,10 @@ BOOL LLPanelEstateCovenant::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop
 		*accept = ACCEPT_YES_COPY_SINGLE;
 		if (item && drop)
 		{
-			gViewerWindow->alertXml("EstateChangeCovenant",
-									LLPanelEstateCovenant::confirmChangeCovenantCallback,
-									item);
+			LLSD payload;
+			payload["item_id"] = item->getUUID();
+			LLNotifications::instance().add("EstateChangeCovenant", LLSD(), payload,
+									LLPanelEstateCovenant::confirmChangeCovenantCallback);
 		}
 		break;
 	default:
@@ -2709,12 +2767,13 @@ BOOL LLPanelEstateCovenant::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop
 } 
 
 // static 
-void LLPanelEstateCovenant::confirmChangeCovenantCallback(S32 option, void* userdata)
+bool LLPanelEstateCovenant::confirmChangeCovenantCallback(const LLSD& notification, const LLSD& response)
 {
-	LLInventoryItem* item = (LLInventoryItem*)userdata;
+	S32 option = LLNotification::getSelectedOption(notification, response);
+	LLInventoryItem* item = gInventory.getItem(notification["payload"]["item_id"].asUUID());
 	LLPanelEstateCovenant* self = LLFloaterRegionInfo::getPanelCovenant();
 
-	if (!item || !self) return;
+	if (!item || !self) return false;
 
 	switch(option)
 	{
@@ -2724,22 +2783,22 @@ void LLPanelEstateCovenant::confirmChangeCovenantCallback(S32 option, void* user
 	default:
 		break;
 	}
+	return false;
 }
 
 // static
 void LLPanelEstateCovenant::resetCovenantID(void* userdata)
 {
-	gViewerWindow->alertXml("EstateChangeCovenant",
-							LLPanelEstateCovenant::confirmResetCovenantCallback,
-							NULL);
+	LLNotifications::instance().add("EstateChangeCovenant", LLSD(), LLSD(), confirmResetCovenantCallback);
 }
 
 // static
-void LLPanelEstateCovenant::confirmResetCovenantCallback(S32 option, void* userdata)
+bool LLPanelEstateCovenant::confirmResetCovenantCallback(const LLSD& notification, const LLSD& response)
 {
 	LLPanelEstateCovenant* self = LLFloaterRegionInfo::getPanelCovenant();
-	if (!self) return;
+	if (!self) return false;
 
+	S32 option = LLNotification::getSelectedOption(notification, response);
 	switch(option)
 	{
 	case 0:		
@@ -2748,6 +2807,7 @@ void LLPanelEstateCovenant::confirmResetCovenantCallback(S32 option, void* userd
 	default:
 		break;
 	}
+	return false;
 }
 
 void LLPanelEstateCovenant::loadInvItem(LLInventoryItem *itemp)
@@ -2808,7 +2868,7 @@ void LLPanelEstateCovenant::onLoadComplete(LLVFS *vfs,
 				if( !panelp->mEditor->importBuffer( buffer, file_length+1 ) )
 				{
 					llwarns << "Problem importing estate covenant." << llendl;
-					gViewerWindow->alertXml("ProblemImportingEstateCovenant");
+					LLNotifications::instance().add("ProblemImportingEstateCovenant");
 				}
 				else
 				{
@@ -2829,15 +2889,15 @@ void LLPanelEstateCovenant::onLoadComplete(LLVFS *vfs,
 			if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status ||
 				LL_ERR_FILE_EMPTY == status)
 			{
-				gViewerWindow->alertXml("MissingNotecardAssetID");
+				LLNotifications::instance().add("MissingNotecardAssetID");
 			}
 			else if (LL_ERR_INSUFFICIENT_PERMISSIONS == status)
 			{
-				gViewerWindow->alertXml("NotAllowedToViewNotecard");
+				LLNotifications::instance().add("NotAllowedToViewNotecard");
 			}
 			else
 			{
-				gViewerWindow->alertXml("UnableToLoadNotecard");
+				LLNotifications::instance().add("UnableToLoadNotecardAsset");
 			}
 
 			llwarns << "Problem loading notecard: " << status << llendl;
diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h
index 8580189a2ec..8c14e463ff1 100644
--- a/indra/newview/llfloaterregioninfo.h
+++ b/indra/newview/llfloaterregioninfo.h
@@ -161,9 +161,9 @@ class LLPanelRegionGeneralInfo : public LLPanelRegionInfo
 	static void onClickKick(void* userdata);
 	static void onKickCommit(const std::vector<std::string>& names, const std::vector<LLUUID>& ids, void* userdata);
 	static void onClickKickAll(void* userdata);
-	static void onKickAllCommit(S32 option, void* userdata);
+	bool onKickAllCommit(const LLSD& notification, const LLSD& response);
 	static void onClickMessage(void* userdata);
-	static void onMessageCommit(S32 option, const std::string& text, void* userdata);
+	bool onMessageCommit(const LLSD& notification, const LLSD& response);
 	static void onClickManageTelehub(void* data);
 };
 
@@ -186,11 +186,11 @@ class LLPanelRegionDebugInfo : public LLPanelRegionInfo
 	static void onClickChooseAvatar(void*);
 	static void callbackAvatarID(const std::vector<std::string>& names, const std::vector<LLUUID>& ids, void* data);
 	static void onClickReturn(void *);
-	static void callbackReturn(S32 option, void*);
+	bool callbackReturn(const LLSD& notification, const LLSD& response);
 	static void onClickTopColliders(void*);
 	static void onClickTopScripts(void*);
 	static void onClickRestart(void* data);
-	static void callbackRestart(S32 option, void* data);
+	bool callbackRestart(const LLSD& notification, const LLSD& response);
 	static void onClickCancelRestart(void* data);
 	
 private:
@@ -240,7 +240,7 @@ class LLPanelRegionTerrainInfo : public LLPanelRegionInfo
 	static void onClickDownloadRaw(void*);
 	static void onClickUploadRaw(void*);
 	static void onClickBakeTerrain(void*);
-	static void callbackBakeTerrain(S32 option, void* data);
+	bool callbackBakeTerrain(const LLSD& notification, const LLSD& response);
 };
 
 /////////////////////////////////////////////////////////////////////////////
@@ -269,27 +269,27 @@ class LLPanelEstateInfo : public LLPanelRegionInfo
 	static void onClickKickUser(void* userdata);
 
 	// Group picker callback is different, can't use core methods below
-	static void addAllowedGroup(S32 option, void* data);
+	bool addAllowedGroup(const LLSD& notification, const LLSD& response);
 	static void addAllowedGroup2(LLUUID id, void* data);
 
 	// Core methods for all above add/remove button clicks
 	static void accessAddCore(U32 operation_flag, const std::string& dialog_name);
-	static void accessAddCore2(S32 option, void* data);
+	static bool accessAddCore2(const LLSD& notification, const LLSD& response);
 	static void accessAddCore3(const std::vector<std::string>& names, const std::vector<LLUUID>& ids, void* data);
 
 	static void accessRemoveCore(U32 operation_flag, const std::string& dialog_name, const std::string& list_ctrl_name);
-	static void accessRemoveCore2(S32 option, void* data);
+	static bool accessRemoveCore2(const LLSD& notification, const LLSD& response);
 
 	// used for both add and remove operations
-	static void accessCoreConfirm(S32 option, void* data);
-	static void kickUserConfirm(S32 option, void* userdata);
+	static bool accessCoreConfirm(const LLSD& notification, const LLSD& response);
+	bool kickUserConfirm(const LLSD& notification, const LLSD& response);
 
 	// Send the actual EstateOwnerRequest "estateaccessdelta" message
 	static void sendEstateAccessDelta(U32 flags, const LLUUID& agent_id);
 
 	static void onKickUserCommit(const std::vector<std::string>& names, const std::vector<LLUUID>& ids, void* userdata);
 	static void onClickMessageEstate(void* data);
-	static void onMessageCommit(S32 option, const std::string& text, void* data);
+	bool onMessageCommit(const LLSD& notification, const LLSD& response);
 	
 	LLPanelEstateInfo();
 	~LLPanelEstateInfo() {}
@@ -344,7 +344,7 @@ class LLPanelEstateInfo : public LLPanelRegionInfo
 protected:
 	virtual BOOL sendUpdate();
 	// confirmation dialog callback
-	static void callbackChangeLindenEstate(S32 opt, void* data);
+	bool callbackChangeLindenEstate(const LLSD& notification, const LLSD& response);
 
 	void commitEstateInfoDataserver();
 	bool commitEstateInfoCaps();
@@ -377,9 +377,9 @@ class LLPanelEstateCovenant : public LLPanelRegionInfo
 						   BOOL drop, EDragAndDropType cargo_type,
 						   void *cargo_data, EAcceptance *accept,
 						   std::string& tooltip_msg);
-	static void confirmChangeCovenantCallback(S32 option, void* userdata);
+	static bool confirmChangeCovenantCallback(const LLSD& notification, const LLSD& response);
 	static void resetCovenantID(void* userdata);
-	static void confirmResetCovenantCallback(S32 option, void* userdata);
+	static bool confirmResetCovenantCallback(const LLSD& notification, const LLSD& response);
 	void sendChangeCovenantID(const LLUUID &asset_id);
 	void loadInvItem(LLInventoryItem *itemp);
 	static void onLoadComplete(LLVFS *vfs,
diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp
index da435c94523..e87ffeb2585 100644
--- a/indra/newview/llfloaterreporter.cpp
+++ b/indra/newview/llfloaterreporter.cpp
@@ -207,10 +207,10 @@ void LLFloaterReporter::processRegionInfo(LLMessageSystem* msg)
 	{
 		if ( gEmailToEstateOwner )
 		{
-			gViewerWindow->alertXml("HelpReportAbuseEmailEO");
+			LLNotifications::instance().add("HelpReportAbuseEmailEO");
 		}
 		else
-			gViewerWindow->alertXml("HelpReportAbuseEmailLL");
+			LLNotifications::instance().add("HelpReportAbuseEmailLL");
 	};
 }
 
@@ -406,7 +406,7 @@ void LLFloaterReporter::onClickSend(void *userdata)
 					category_value == IP_CONTENT_REMOVAL ||
 					category_value == IP_PERMISSONS_EXPLOIT)
 				{
-					gViewerWindow->alertXml("HelpReportAbuseContainsCopyright");
+					LLNotifications::instance().add("HelpReportAbuseContainsCopyright");
 					self->mCopyrightWarningSeen = TRUE;
 					return;
 				}
@@ -415,7 +415,7 @@ void LLFloaterReporter::onClickSend(void *userdata)
 			{
 				// IP_CONTENT_REMOVAL *always* shows the dialog - 
 				// ergo you can never send that abuse report type.
-				gViewerWindow->alertXml("HelpReportAbuseContainsCopyright");
+				LLNotifications::instance().add("HelpReportAbuseContainsCopyright");
 				return;
 			}
 		}
@@ -524,7 +524,7 @@ void LLFloaterReporter::showFromMenu(EReportType report_type)
 
 		if (report_type == BUG_REPORT)
 		{
- 			gViewerWindow->alertXml("HelpReportBug");
+ 			LLNotifications::instance().add("HelpReportBug");
 		}
 		else
 		{
@@ -610,11 +610,11 @@ bool LLFloaterReporter::validateReport()
 	{
 		if ( mReportType != BUG_REPORT )
 		{
-			gViewerWindow->alertXml("HelpReportAbuseSelectCategory");
+			LLNotifications::instance().add("HelpReportAbuseSelectCategory");
 		}
 		else
 		{
-			gViewerWindow->alertXml("HelpReportBugSelectCategory");
+			LLNotifications::instance().add("HelpReportBugSelectCategory");
 		}
 		return false;
 	}
@@ -623,13 +623,13 @@ bool LLFloaterReporter::validateReport()
 	{
 	  if ( childGetText("abuser_name_edit").empty() )
 	  {
-		  gViewerWindow->alertXml("HelpReportAbuseAbuserNameEmpty");
+		  LLNotifications::instance().add("HelpReportAbuseAbuserNameEmpty");
 		  return false;
 	  };
   
 	  if ( childGetText("abuse_location_edit").empty() )
 	  {
-		  gViewerWindow->alertXml("HelpReportAbuseAbuserLocationEmpty");
+		  LLNotifications::instance().add("HelpReportAbuseAbuserLocationEmpty");
 		  return false;
 	  };
 	};
@@ -638,11 +638,11 @@ bool LLFloaterReporter::validateReport()
 	{
 		if ( mReportType != BUG_REPORT )
 		{
-			gViewerWindow->alertXml("HelpReportAbuseSummaryEmpty");
+			LLNotifications::instance().add("HelpReportAbuseSummaryEmpty");
 		}
 		else
 		{
-			gViewerWindow->alertXml("HelpReportBugSummaryEmpty");
+			LLNotifications::instance().add("HelpReportBugSummaryEmpty");
 		}
 		return false;
 	};
@@ -651,11 +651,11 @@ bool LLFloaterReporter::validateReport()
 	{
 		if ( mReportType != BUG_REPORT )
 		{
-			gViewerWindow->alertXml("HelpReportAbuseDetailsEmpty");
+			LLNotifications::instance().add("HelpReportAbuseDetailsEmpty");
 		}
 		else
 		{
-			gViewerWindow->alertXml("HelpReportBugDetailsEmpty");
+			LLNotifications::instance().add("HelpReportBugDetailsEmpty");
 		}
 		return false;
 	};
@@ -951,13 +951,12 @@ void LLFloaterReporter::uploadDoneCallback(const LLUUID &uuid, void *user_data,
 
 	if(result < 0)
 	{
-		LLStringUtil::format_map_t args;
-		std::string reason = std::string(LLAssetStorage::getErrorString(result));
-		args["[REASON]"] = reason;
-		gViewerWindow->alertXml("ErrorUploadingReportScreenshot", args);
+		LLSD args;
+		args["REASON"] = std::string(LLAssetStorage::getErrorString(result));
+		LLNotifications::instance().add("ErrorUploadingReportScreenshot", args);
 
 		std::string err_msg("There was a problem uploading a report screenshot");
-		err_msg += " due to the following reason: " + reason;
+		err_msg += " due to the following reason: " + args["REASON"].asString();
 		llwarns << err_msg << llendl;
 		return;
 	}
diff --git a/indra/newview/llfloatersellland.cpp b/indra/newview/llfloatersellland.cpp
index 749ccbe7fa2..1e1d1f6fd2c 100644
--- a/indra/newview/llfloatersellland.cpp
+++ b/indra/newview/llfloatersellland.cpp
@@ -79,9 +79,9 @@ class LLFloaterSellLandUI
 	static void doSelectAgent(void *userdata);
 	static void doCancel(void *userdata);
 	static void doSellLand(void *userdata);
-	static void onConfirmSale(S32 option, void *userdata);
+	bool onConfirmSale(const LLSD& notification, const LLSD& response);
 	static void doShowObjects(void *userdata);
-	static void callbackHighlightTransferable(S32 option, void* userdata);
+	static bool callbackHighlightTransferable(const LLSD& notification, const LLSD& response);
 
 	static void callbackAvatarPick(const std::vector<std::string>& names, const std::vector<LLUUID>& ids, void* data);
 
@@ -443,15 +443,16 @@ void LLFloaterSellLandUI::doShowObjects(void *userdata)
 
 	send_parcel_select_objects(parcel->getLocalID(), RT_SELL);
 
-	LLNotifyBox::showXml("TransferObjectsHighlighted",
-						 callbackHighlightTransferable,
-						 userdata);
+	LLNotifications::instance().add("TransferObjectsHighlighted",
+						LLSD(), LLSD(),
+						&LLFloaterSellLandUI::callbackHighlightTransferable);
 }
 
 // static
-void LLFloaterSellLandUI::callbackHighlightTransferable(S32 option, void* userdata)
+bool LLFloaterSellLandUI::callbackHighlightTransferable(const LLSD& notification, const LLSD& data)
 {
 	LLSelectMgr::getInstance()->unhighlightAll();
+	return false;
 }
 
 // static
@@ -462,83 +463,89 @@ void LLFloaterSellLandUI::doSellLand(void *userdata)
 	LLParcel* parcel = self->mParcelSelection->getParcel();
 
 	// Do a confirmation
-	if (!parcel->getForSale())
+	S32 sale_price = self->childGetValue("price");
+	S32 area = parcel->getArea();
+	std::string authorizedBuyerName = "Anyone";
+	bool sell_to_anyone = true;
+	if ("user" == self->childGetValue("sell_to").asString())
 	{
-		S32 sale_price = self->childGetValue("price");
-		S32 area = parcel->getArea();
-		std::string authorizedBuyerName = "Anyone";
-		bool sell_to_anyone = true;
-		if ("user" == self->childGetValue("sell_to").asString())
-		{
-			authorizedBuyerName = self->childGetText("sell_to_agent");
-			sell_to_anyone = false;
-		}
+		authorizedBuyerName = self->childGetText("sell_to_agent");
+		sell_to_anyone = false;
+	}
 
-		// must sell to someone if indicating sale to anyone
-		if ((sale_price == 0) && sell_to_anyone)
-		{
-			gViewerWindow->alertXml("SalePriceRestriction");
-			return;
-		}
+	// must sell to someone if indicating sale to anyone
+	if (!parcel->getForSale() 
+		&& (sale_price == 0) 
+		&& sell_to_anyone)
+	{
+		LLNotifications::instance().add("SalePriceRestriction");
+		return;
+	}
 
-		LLStringUtil::format_map_t args;
-		args["[LAND_SIZE]"] = llformat("%d",area);
-		args["[SALE_PRICE]"] = llformat("%d",sale_price);
-		args["[NAME]"] = authorizedBuyerName;
+	LLSD args;
+	args["LAND_SIZE"] = llformat("%d",area);
+	args["SALE_PRICE"] = llformat("%d",sale_price);
+	args["NAME"] = authorizedBuyerName;
 
-		if (sell_to_anyone)
-		{
-			gViewerWindow->alertXml("ConfirmLandSaleToAnyoneChange", args, onConfirmSale, self);
-		}
-		else
-		{
-			gViewerWindow->alertXml("ConfirmLandSaleChange", args, onConfirmSale, self);
-		}
+	LLNotification::Params params("ConfirmLandSaleChange");
+	params.substitutions(args)
+		.functor(boost::bind(&LLFloaterSellLandUI::onConfirmSale, self, _1, _2));
+
+	if (sell_to_anyone)
+	{
+		params.name("ConfirmLandSaleToAnyoneChange");
+	}
+	
+	if (parcel->getForSale())
+	{
+		// parcel already for sale, so ignore this question
+		LLNotifications::instance().forceResponse(params, -1);
 	}
 	else
 	{
-		onConfirmSale(-1, self);
+		// ask away
+		LLNotifications::instance().add(params);
 	}
+
 }
 
-// static
-void LLFloaterSellLandUI::onConfirmSale(S32 option, void *userdata)
+bool LLFloaterSellLandUI::onConfirmSale(const LLSD& notification, const LLSD& response)
 {
+	S32 option = LLNotification::getSelectedOption(notification, response);
 	if (option != 0)
 	{
-		return;
+		return false;
 	}
-	LLFloaterSellLandUI* self = (LLFloaterSellLandUI*)userdata;
-	S32  sale_price	= self->childGetValue("price");
+	S32  sale_price	= childGetValue("price");
 
 	// Valid extracted data
 	if (sale_price < 0)
 	{
 		// TomY TODO: Throw an error
-		return;
+		return false;
 	}
 
-	LLParcel* parcel = self->mParcelSelection->getParcel();
-	if (!parcel) return;
+	LLParcel* parcel = mParcelSelection->getParcel();
+	if (!parcel) return false;
 
 	// can_agent_modify_parcel deprecated by GROUPS
 // 	if (!can_agent_modify_parcel(parcel))
 // 	{
-// 		self->close();
+// 		close();
 // 		return;
 // 	}
 
 	parcel->setParcelFlag(PF_FOR_SALE, TRUE);
 	parcel->setSalePrice(sale_price);
 	bool sell_with_objects = false;
-	if ("yes" == self->childGetValue("sell_objects").asString())
+	if ("yes" == childGetValue("sell_objects").asString())
 	{
 		sell_with_objects = true;
 	}
 	parcel->setSellWithObjects(sell_with_objects);
-	if ("user" == self->childGetValue("sell_to").asString())
+	if ("user" == childGetValue("sell_to").asString())
 	{
-		parcel->setAuthorizedBuyerID(self->mAuthorizedBuyer);
+		parcel->setAuthorizedBuyerID(mAuthorizedBuyer);
 	}
 	else
 	{
@@ -548,5 +555,6 @@ void LLFloaterSellLandUI::onConfirmSale(S32 option, void *userdata)
 	// Send update to server
 	LLViewerParcelMgr::getInstance()->sendParcelPropertiesUpdate( parcel );
 
-	self->close();
+	close();
+	return false;
 }
diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp
index dcfb1e94422..207b2ea6556 100644
--- a/indra/newview/llfloatersnapshot.cpp
+++ b/indra/newview/llfloatersnapshot.cpp
@@ -966,7 +966,7 @@ void LLSnapshotLivePreview::saveTexture()
 	}
 	else
 	{
-		gViewerWindow->alertXml("ErrorEncodingSnapshot");
+		LLNotifications::instance().add("ErrorEncodingSnapshot");
 		llwarns << "Error encoding snapshot" << llendl;
 	}
 
diff --git a/indra/newview/llfloatertopobjects.cpp b/indra/newview/llfloatertopobjects.cpp
index eea6b40cba1..3b79f58db7b 100644
--- a/indra/newview/llfloatertopobjects.cpp
+++ b/indra/newview/llfloatertopobjects.cpp
@@ -353,17 +353,19 @@ void LLFloaterTopObjects::doToObjects(int action, bool all)
 }
 
 //static
-void LLFloaterTopObjects::callbackReturnAll(S32 option, void* userdata)
+bool LLFloaterTopObjects::callbackReturnAll(const LLSD& notification, const LLSD& response)
 {
+	S32 option = LLNotification::getSelectedOption(notification, response);
 	if (option == 0)
 	{
 		sInstance->doToObjects(ACTION_RETURN, true);
 	}
+	return false;
 }
 
 void LLFloaterTopObjects::onReturnAll(void* data)
 {	
-	gViewerWindow->alertXml("ReturnAllTopObjects", callbackReturnAll, NULL);
+	LLNotifications::instance().add("ReturnAllTopObjects", LLSD(), LLSD(), &callbackReturnAll);
 }
 
 
@@ -374,17 +376,19 @@ void LLFloaterTopObjects::onReturnSelected(void* data)
 
 
 //static
-void LLFloaterTopObjects::callbackDisableAll(S32 option, void* userdata)
+bool LLFloaterTopObjects::callbackDisableAll(const LLSD& notification, const LLSD& response)
 {
+	S32 option = LLNotification::getSelectedOption(notification, response);
 	if (option == 0)
 	{
 		sInstance->doToObjects(ACTION_DISABLE, true);
 	}
+	return false;
 }
 
 void LLFloaterTopObjects::onDisableAll(void* data)
 {
-	gViewerWindow->alertXml("DisableAllTopObjects", callbackDisableAll, NULL);
+	LLNotifications::instance().add("DisableAllTopObjects", LLSD(), LLSD(), callbackDisableAll);
 }
 
 void LLFloaterTopObjects::onDisableSelected(void* data)
diff --git a/indra/newview/llfloatertopobjects.h b/indra/newview/llfloatertopobjects.h
index 5b23e737d7e..a6f07a6a34f 100644
--- a/indra/newview/llfloatertopobjects.h
+++ b/indra/newview/llfloatertopobjects.h
@@ -72,8 +72,8 @@ class LLFloaterTopObjects : public LLFloater
 	static void onDisableAll(void* data);
 	static void onDisableSelected(void* data);
 
-	static void callbackReturnAll(S32 option, void* userdata);
-	static void callbackDisableAll(S32 option, void* userdata);
+	static bool callbackReturnAll(const LLSD& notification, const LLSD& response);
+	static bool callbackDisableAll(const LLSD& notification, const LLSD& response);
 
 	static void onGetByOwnerName(LLUICtrl* ctrl, void* data);
 	static void onGetByObjectName(LLUICtrl* ctrl, void* data);
diff --git a/indra/newview/llfloatertos.cpp b/indra/newview/llfloatertos.cpp
index ad592f909e6..bd09bf9ef61 100644
--- a/indra/newview/llfloatertos.cpp
+++ b/indra/newview/llfloatertos.cpp
@@ -257,7 +257,7 @@ void LLFloaterTOS::onCancel( void* userdata )
 {
 	LLFloaterTOS* self = (LLFloaterTOS*) userdata;
 	llinfos << "User disagrees with TOS." << llendl;
-	gViewerWindow->alertXml("MustAgreeToLogIn", login_alert_done);
+	LLNotifications::instance().add("MustAgreeToLogIn", LLSD(), LLSD(), login_alert_done);
 	LLStartUp::setStartupState( STATE_LOGIN_SHOW );
 	self->mLoadCompleteCount = 0;  // reset counter for next time we come to TOS
 	self->close(); // destroys this object
diff --git a/indra/newview/llfloaterurlentry.cpp b/indra/newview/llfloaterurlentry.cpp
index 69916f80eaa..3efd6eed615 100644
--- a/indra/newview/llfloaterurlentry.cpp
+++ b/indra/newview/llfloaterurlentry.cpp
@@ -262,32 +262,30 @@ void LLFloaterURLEntry::onBtnCancel( void* userdata )
 //-----------------------------------------------------------------------------
 void LLFloaterURLEntry::onBtnClear( void* userdata )
 {
-	gViewerWindow->alertXml( "ConfirmClearMediaUrlList", callback_clear_url_list, userdata );
+	LLNotifications::instance().add( "ConfirmClearMediaUrlList", LLSD(), LLSD(), 
+									boost::bind(&LLFloaterURLEntry::callback_clear_url_list, (LLFloaterURLEntry*)userdata, _1, _2) );
 }
 
-void LLFloaterURLEntry::callback_clear_url_list(S32 option, void* userdata)
+bool LLFloaterURLEntry::callback_clear_url_list(const LLSD& notification, const LLSD& response)
 {
+	S32 option = LLNotification::getSelectedOption(notification, response);
 	if ( option == 0 ) // YES
 	{
-		LLFloaterURLEntry *self =(LLFloaterURLEntry *)userdata;
-
-		if ( self )
+		// clear saved list
+		LLCtrlListInterface* url_list = childGetListInterface("media_entry");
+		if ( url_list )
 		{
-			// clear saved list
-			LLCtrlListInterface* url_list = self->childGetListInterface("media_entry");
-			if ( url_list )
-			{
-				url_list->operateOnAll( LLCtrlListInterface::OP_DELETE );
-			}
+			url_list->operateOnAll( LLCtrlListInterface::OP_DELETE );
+		}
 
-			// clear current contents of combo box
-			self->mMediaURLEdit->clear();
+		// clear current contents of combo box
+		mMediaURLEdit->clear();
 
-			// clear stored version of list
-			LLURLHistory::clear("parcel");
+		// clear stored version of list
+		LLURLHistory::clear("parcel");
 
-			// cleared the list so disable Clear button
-			self->childSetEnabled( "clear_btn", false );
-		}
+		// cleared the list so disable Clear button
+		childSetEnabled( "clear_btn", false );
 	}
+	return false;
 }
diff --git a/indra/newview/llfloaterurlentry.h b/indra/newview/llfloaterurlentry.h
index 53e77880f5b..f85106dffe4 100644
--- a/indra/newview/llfloaterurlentry.h
+++ b/indra/newview/llfloaterurlentry.h
@@ -63,7 +63,7 @@ class LLFloaterURLEntry : public LLFloater
 	static void		onBtnOK(void*);
 	static void		onBtnCancel(void*);
 	static void		onBtnClear(void*);
-	static void		callback_clear_url_list(S32 option, void* userdata);
+	bool		callback_clear_url_list(const LLSD& notification, const LLSD& response);
 };
 
 #endif  // LL_LLFLOATERURLENTRY_H
diff --git a/indra/newview/llfloaterwater.cpp b/indra/newview/llfloaterwater.cpp
index 4705b2f5ba0..1a8beb7a58c 100644
--- a/indra/newview/llfloaterwater.cpp
+++ b/indra/newview/llfloaterwater.cpp
@@ -176,15 +176,7 @@ void LLFloaterWater::onClickHelp(void* data)
 	LLFloaterWater* self = LLFloaterWater::instance();
 
 	const std::string* xml_alert = (std::string*)data;
-	LLAlertDialog* dialogp = gViewerWindow->alertXml(*xml_alert);
-	if (dialogp)
-	{
-		LLFloater* root_floater = gFloaterView->getParentFloater(self);
-		if (root_floater)
-		{
-			root_floater->addDependentFloater(dialogp);
-		}
-	}
+	LLNotifications::instance().add(self->contextualNotification(*xml_alert));
 }
 
 void LLFloaterWater::initHelpBtn(const std::string& name, const std::string& xml_alert)
@@ -192,11 +184,14 @@ void LLFloaterWater::initHelpBtn(const std::string& name, const std::string& xml
 	childSetAction(name, onClickHelp, new std::string(xml_alert));
 }
 
-void LLFloaterWater::newPromptCallback(S32 option, const std::string& text, void* userData)
+bool LLFloaterWater::newPromptCallback(const LLSD& notification, const LLSD& response)
 {
+	std::string text = response["message"].asString();
+	S32 option = LLNotification::getSelectedOption(notification, response);
+
 	if(text == "")
 	{
-		return;
+		return false;
 	}
 
 	if(option == 0) {
@@ -224,9 +219,10 @@ void LLFloaterWater::newPromptCallback(S32 option, const std::string& text, void
 		} 
 		else 
 		{
-			gViewerWindow->alertXml("ExistsWaterPresetAlert");
+			LLNotifications::instance().add("ExistsWaterPresetAlert");
 		}
 	}
+	return false;
 }
 
 void LLFloaterWater::syncMenu()
@@ -596,8 +592,7 @@ void LLFloaterWater::onNormalMapPicked(LLUICtrl* ctrl, void* userData)
 
 void LLFloaterWater::onNewPreset(void* userData)
 {
-	gViewerWindow->alertXmlEditText("NewWaterPreset", LLStringUtil::format_map_t(), 
-		NULL, NULL, newPromptCallback, NULL);
+	LLNotifications::instance().add("NewWaterPreset", LLSD(),  LLSD(), newPromptCallback);
 }
 
 void LLFloaterWater::onSavePreset(void* userData)
@@ -619,15 +614,16 @@ void LLFloaterWater::onSavePreset(void* userData)
 		comboBox->getSelectedItemLabel());
 	if(sIt != sDefaultPresets.end() && !gSavedSettings.getBOOL("WaterEditPresets")) 
 	{
-		gViewerWindow->alertXml("WLNoEditDefault");
+		LLNotifications::instance().add("WLNoEditDefault");
 		return;
 	}
 
-	gViewerWindow->alertXml("WLSavePresetAlert", saveAlertCallback, sWaterMenu);
+	LLNotifications::instance().add("WLSavePresetAlert", LLSD(), LLSD(), saveAlertCallback);
 }
 
-void LLFloaterWater::saveAlertCallback(S32 option, void* userdata)
+bool LLFloaterWater::saveAlertCallback(const LLSD& notification, const LLSD& response)
 {
+	S32 option = LLNotification::getSelectedOption(notification, response);
 	// if they choose save, do it.  Otherwise, don't do anything
 	if(option == 0) 
 	{
@@ -640,7 +636,7 @@ void LLFloaterWater::saveAlertCallback(S32 option, void* userdata)
 		// comment this back in to save to file
 		param_mgr->savePreset(param_mgr->mCurParams.mName);
 	}
-
+	return false;
 }
 
 void LLFloaterWater::onDeletePreset(void* userData)
@@ -652,13 +648,14 @@ void LLFloaterWater::onDeletePreset(void* userData)
 		return;
 	}
 
-	LLStringUtil::format_map_t args;
-	args["[SKY]"] = combo_box->getSelectedValue().asString();
-	gViewerWindow->alertXml("WLDeletePresetAlert", args, deleteAlertCallback, sWaterMenu);
+	LLSD args;
+	args["SKY"] = combo_box->getSelectedValue().asString();
+	LLNotifications::instance().add("WLDeletePresetAlert", args, LLSD(), deleteAlertCallback);
 }
 
-void LLFloaterWater::deleteAlertCallback(S32 option, void* userdata)
+bool LLFloaterWater::deleteAlertCallback(const LLSD& notification, const LLSD& response)
 {
+	S32 option = LLNotification::getSelectedOption(notification, response);
 	// if they choose delete, do it.  Otherwise, don't do anything
 	if(option == 0) 
 	{
@@ -680,8 +677,8 @@ void LLFloaterWater::deleteAlertCallback(S32 option, void* userdata)
 		std::set<std::string>::iterator sIt = sDefaultPresets.find(name);
 		if(sIt != sDefaultPresets.end()) 
 		{
-			gViewerWindow->alertXml("WaterNoEditDefault");
-			return;
+			LLNotifications::instance().add("WaterNoEditDefault");
+			return false;
 		}
 
 		LLWaterParamManager::instance()->removeParamSet(name, true);
@@ -710,6 +707,7 @@ void LLFloaterWater::deleteAlertCallback(S32 option, void* userdata)
 			combo_box->setCurrentByIndex(new_index);
 		}
 	}
+	return false;
 }
 
 
diff --git a/indra/newview/llfloaterwater.h b/indra/newview/llfloaterwater.h
index 883b2a35f1f..ad361266fe0 100644
--- a/indra/newview/llfloaterwater.h
+++ b/indra/newview/llfloaterwater.h
@@ -63,7 +63,7 @@ class LLFloaterWater : public LLFloater
 	static void onClickHelp(void* data);
 	void initHelpBtn(const std::string& name, const std::string& xml_alert);
 
-	static void newPromptCallback(S32 option, const std::string& text, void* userData);
+	static bool newPromptCallback(const LLSD& notification, const LLSD& response);
 
 	/// general purpose callbacks for dealing with color controllers
 	static void onColorControlRMoved(LLUICtrl* ctrl, void* userData);
@@ -97,13 +97,13 @@ class LLFloaterWater : public LLFloater
 	static void onSavePreset(void* userData);
 
 	/// prompts a user when overwriting a preset
-	static void saveAlertCallback(S32 option, void* userdata);
+	static bool saveAlertCallback(const LLSD& notification, const LLSD& response);
 
 	/// when user hits the save preset button
 	static void onDeletePreset(void* userData);
 
 	/// prompts a user when overwriting a preset
-	static void deleteAlertCallback(S32 option, void* userdata);
+	static bool deleteAlertCallback(const LLSD& notification, const LLSD& response);
 
 	/// what to do when you change the preset name
 	static void onChangePresetName(LLUICtrl* ctrl, void* userData);
diff --git a/indra/newview/llfloaterwindlight.cpp b/indra/newview/llfloaterwindlight.cpp
index 4e277740292..8ae291f24c7 100644
--- a/indra/newview/llfloaterwindlight.cpp
+++ b/indra/newview/llfloaterwindlight.cpp
@@ -233,16 +233,8 @@ void LLFloaterWindLight::onClickHelp(void* data)
 {
 	LLFloaterWindLight* self = LLFloaterWindLight::instance();
 
-	const std::string* xml_alert = (std::string*)data;
-	LLAlertDialog* dialogp = gViewerWindow->alertXml(*xml_alert);
-	if (dialogp)
-	{
-		LLFloater* root_floater = gFloaterView->getParentFloater(self);
-		if (root_floater)
-		{
-			root_floater->addDependentFloater(dialogp);
-		}
-	}		
+	const std::string xml_alert = *(std::string*)data;
+	LLNotifications::instance().add(self->contextualNotification(xml_alert));
 }
 
 void LLFloaterWindLight::initHelpBtn(const std::string& name, const std::string& xml_alert)
@@ -250,11 +242,14 @@ void LLFloaterWindLight::initHelpBtn(const std::string& name, const std::string&
 	childSetAction(name, onClickHelp, new std::string(xml_alert));
 }
 
-void LLFloaterWindLight::newPromptCallback(S32 option, const std::string& text, void* userData)
+bool LLFloaterWindLight::newPromptCallback(const LLSD& notification, const LLSD& response)
 {
+	std::string text = response["message"].asString();
+	S32 option = LLNotification::getSelectedOption(notification, response);
+
 	if(text == "")
 	{
-		return;
+		return false;
 	}
 
 	if(option == 0) {
@@ -303,9 +298,10 @@ void LLFloaterWindLight::newPromptCallback(S32 option, const std::string& text,
 		} 
 		else 
 		{
-			gViewerWindow->alertXml("ExistsSkyPresetAlert");
+			LLNotifications::instance().add("ExistsSkyPresetAlert");
 		}
 	}
+	return false;
 }
 
 void LLFloaterWindLight::syncMenu()
@@ -784,8 +780,7 @@ void LLFloaterWindLight::onStarAlphaMoved(LLUICtrl* ctrl, void* userData)
 
 void LLFloaterWindLight::onNewPreset(void* userData)
 {
-	gViewerWindow->alertXmlEditText("NewSkyPreset", LLStringUtil::format_map_t(), 
-		NULL, NULL, newPromptCallback, NULL);
+	LLNotifications::instance().add("NewSkyPreset", LLSD(), LLSD(), newPromptCallback);
 }
 
 void LLFloaterWindLight::onSavePreset(void* userData)
@@ -805,18 +800,19 @@ void LLFloaterWindLight::onSavePreset(void* userData)
 		comboBox->getSelectedItemLabel());
 	if(sIt != sDefaultPresets.end() && !gSavedSettings.getBOOL("SkyEditPresets")) 
 	{
-		gViewerWindow->alertXml("WLNoEditDefault");
+		LLNotifications::instance().add("WLNoEditDefault");
 		return;
 	}
 
 	LLWLParamManager::instance()->mCurParams.mName = 
 		comboBox->getSelectedItemLabel();
 
-	gViewerWindow->alertXml("WLSavePresetAlert", saveAlertCallback, sWindLight);
+	LLNotifications::instance().add("WLSavePresetAlert", LLSD(), LLSD(), saveAlertCallback);
 }
 
-void LLFloaterWindLight::saveAlertCallback(S32 option, void* userdata)
+bool LLFloaterWindLight::saveAlertCallback(const LLSD& notification, const LLSD& response)
 {
+	S32 option = LLNotification::getSelectedOption(notification, response);
 	// if they choose save, do it.  Otherwise, don't do anything
 	if(option == 0) 
 	{
@@ -827,7 +823,7 @@ void LLFloaterWindLight::saveAlertCallback(S32 option, void* userdata)
 		// comment this back in to save to file
 		param_mgr->savePreset(param_mgr->mCurParams.mName);
 	}
-
+	return false;
 }
 
 void LLFloaterWindLight::onDeletePreset(void* userData)
@@ -840,17 +836,20 @@ void LLFloaterWindLight::onDeletePreset(void* userData)
 		return;
 	}
 
-	LLStringUtil::format_map_t args;
-	args["[SKY]"] = combo_box->getSelectedValue().asString();
-	gViewerWindow->alertXml("WLDeletePresetAlert", args, deleteAlertCallback, sWindLight);
+	LLSD args;
+	args["SKY"] = combo_box->getSelectedValue().asString();
+	LLNotifications::instance().add("WLDeletePresetAlert", args, LLSD(), 
+									boost::bind(&LLFloaterWindLight::deleteAlertCallback, sWindLight, _1, _2));
 }
 
-void LLFloaterWindLight::deleteAlertCallback(S32 option, void* userdata)
+bool LLFloaterWindLight::deleteAlertCallback(const LLSD& notification, const LLSD& response)
 {
+	S32 option = LLNotification::getSelectedOption(notification, response);
+
 	// if they choose delete, do it.  Otherwise, don't do anything
 	if(option == 0) 
 	{
-		LLComboBox* combo_box = sWindLight->getChild<LLComboBox>( 
+		LLComboBox* combo_box = getChild<LLComboBox>( 
 			"WLPresetsCombo");
 		LLFloaterDayCycle* day_cycle = NULL;
 		LLComboBox* key_combo = NULL;
@@ -870,8 +869,8 @@ void LLFloaterWindLight::deleteAlertCallback(S32 option, void* userdata)
 		std::set<std::string>::iterator sIt = sDefaultPresets.find(name);
 		if(sIt != sDefaultPresets.end()) 
 		{
-			gViewerWindow->alertXml("WLNoEditDefault");
-			return;
+			LLNotifications::instance().add("WLNoEditDefault");
+			return false;
 		}
 
 		LLWLParamManager::instance()->removeParamSet(name, true);
@@ -899,6 +898,7 @@ void LLFloaterWindLight::deleteAlertCallback(S32 option, void* userdata)
 			combo_box->setCurrentByIndex(new_index);
 		}
 	}
+	return false;
 }
 
 
diff --git a/indra/newview/llfloaterwindlight.h b/indra/newview/llfloaterwindlight.h
index d9e02b11171..35f8a65cbdc 100644
--- a/indra/newview/llfloaterwindlight.h
+++ b/indra/newview/llfloaterwindlight.h
@@ -63,7 +63,7 @@ class LLFloaterWindLight : public LLFloater
 	static void onClickHelp(void* data);
 	void initHelpBtn(const std::string& name, const std::string& xml_alert);
 
-	static void newPromptCallback(S32 option, const std::string& text, void* userData);
+	static bool newPromptCallback(const LLSD& notification, const LLSD& response);
 
 	/// general purpose callbacks for dealing with color controllers
 	static void onColorControlRMoved(LLUICtrl* ctrl, void* userData);
@@ -94,13 +94,13 @@ class LLFloaterWindLight : public LLFloater
 	static void onSavePreset(void* userData);
 
 	/// prompts a user when overwriting a preset
-	static void saveAlertCallback(S32 option, void* userdata);
+	static bool saveAlertCallback(const LLSD& notification, const LLSD& response);
 
 	/// when user hits the save preset button
 	static void onDeletePreset(void* userData);
 
 	/// prompts a user when overwriting a preset
-	static void deleteAlertCallback(S32 option, void* userdata);
+	bool deleteAlertCallback(const LLSD& notification, const LLSD& response);
 
 	/// what to do when you change the preset name
 	static void onChangePresetName(LLUICtrl* ctrl, void* userData);
diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp
index 2281f1b5989..1c6eb84a8a3 100644
--- a/indra/newview/llfloaterworldmap.cpp
+++ b/indra/newview/llfloaterworldmap.cpp
@@ -1303,10 +1303,10 @@ void LLFloaterWorldMap::onCopySLURL(void* data)
 	LLFloaterWorldMap* self = (LLFloaterWorldMap*)data;
 	gViewerWindow->mWindow->copyTextToClipboard(utf8str_to_wstring(self->mSLURL));
 	
-	LLStringUtil::format_map_t args;
-	args["[SLURL]"] = self->mSLURL;
+	LLSD args;
+	args["SLURL"] = self->mSLURL;
 
-	LLAlertDialog::showXml("CopySLURL", args);
+	LLNotifications::instance().add("CopySLURL", args);
 }
 
 void LLFloaterWorldMap::onCheckEvents(LLUICtrl*, void* data)
diff --git a/indra/newview/llgesturemgr.cpp b/indra/newview/llgesturemgr.cpp
index a25b1daebf1..eba295531a1 100644
--- a/indra/newview/llgesturemgr.cpp
+++ b/indra/newview/llgesturemgr.cpp
@@ -952,9 +952,9 @@ void LLGestureManager::onLoadComplete(LLVFS *vfs,
 					&& gGestureManager.mDeactivateSimilarNames.length() > 0)
 				{
 					// we're done with this set of deactivations
-					LLStringUtil::format_map_t args;
-					args["[NAMES]"] = gGestureManager.mDeactivateSimilarNames;
-					LLNotifyBox::showXml("DeactivatedGesturesTrigger", args);
+					LLSD args;
+					args["NAMES"] = gGestureManager.mDeactivateSimilarNames;
+					LLNotifications::instance().add("DeactivatedGesturesTrigger", args);
 				}
 			}
 
diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp
index 631b2caa91b..9a8e70242c2 100644
--- a/indra/newview/llgroupmgr.cpp
+++ b/indra/newview/llgroupmgr.cpp
@@ -1288,9 +1288,9 @@ void LLGroupMgr::processCreateGroupReply(LLMessageSystem* msg, void ** data)
 	else
 	{
 		// *TODO:translate
-		LLStringUtil::format_map_t args;
-		args["[MESSAGE]"] = message;
-		gViewerWindow->alertXml("UnableToCreateGroup", args);
+		LLSD args;
+		args["MESSAGE"] = message;
+		LLNotifications::instance().add("UnableToCreateGroup", args);
 	}
 }
 
diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp
index 770c1177981..98b07862001 100644
--- a/indra/newview/llimpanel.cpp
+++ b/indra/newview/llimpanel.cpp
@@ -306,13 +306,13 @@ void LLVoiceCallCapResponder::error(U32 status, const std::string& reason)
 		if ( 403 == status )
 		{
 			//403 == no ability
-			LLNotifyBox::showXml(
+			LLNotifications::instance().add(
 				"VoiceNotAllowed",
 				channelp->getNotifyArgs());
 		}
 		else
 		{
-			LLNotifyBox::showXml(
+			LLNotifications::instance().add(
 				"VoiceCallGenericError",
 				channelp->getNotifyArgs());
 		}
@@ -348,7 +348,7 @@ LLVoiceChannel::LLVoiceChannel(const LLUUID& session_id, const std::string& sess
 	mSessionName(session_name),
 	mIgnoreNextSessionLeave(FALSE)
 {
-	mNotifyArgs["[VOICE_CHANNEL_NAME]"] = mSessionName;
+	mNotifyArgs["VOICE_CHANNEL_NAME"] = mSessionName;
 
 	if (!sVoiceChannelMap.insert(std::make_pair(session_id, this)).second)
 	{
@@ -384,13 +384,13 @@ void LLVoiceChannel::setChannelInfo(
 	{
 		if (mURI.empty())
 		{
-			LLNotifyBox::showXml("VoiceChannelJoinFailed", mNotifyArgs);
+			LLNotifications::instance().add("VoiceChannelJoinFailed", mNotifyArgs);
 			llwarns << "Received empty URI for channel " << mSessionName << llendl;
 			deactivate();
 		}
 		else if (mCredentials.empty())
 		{
-			LLNotifyBox::showXml("VoiceChannelJoinFailed", mNotifyArgs);
+			LLNotifications::instance().add("VoiceChannelJoinFailed", mNotifyArgs);
 			llwarns << "Received empty credentials for channel " << mSessionName << llendl;
 			deactivate();
 		}
@@ -433,25 +433,26 @@ void LLVoiceChannel::handleStatusChange(EStatusType type)
 	switch(type)
 	{
 	case STATUS_LOGIN_RETRY:
-		mLoginNotificationHandle = LLNotifyBox::showXml("VoiceLoginRetry")->getHandle();
+		//mLoginNotificationHandle = LLNotifyBox::showXml("VoiceLoginRetry")->getHandle();
+		LLNotifications::instance().add("VoiceLoginRetry");
 		break;
 	case STATUS_LOGGED_IN:
-		if (!mLoginNotificationHandle.isDead())
-		{
-			LLNotifyBox* notifyp = (LLNotifyBox*)mLoginNotificationHandle.get();
-			if (notifyp)
-			{
-				notifyp->close();
-			}
-			mLoginNotificationHandle.markDead();
-		}
+		//if (!mLoginNotificationHandle.isDead())
+		//{
+		//	LLNotifyBox* notifyp = (LLNotifyBox*)mLoginNotificationHandle.get();
+		//	if (notifyp)
+		//	{
+		//		notifyp->close();
+		//	}
+		//	mLoginNotificationHandle.markDead();
+		//}
 		break;
 	case STATUS_LEFT_CHANNEL:
 		if (callStarted() && !mIgnoreNextSessionLeave && !sSuspended)
 		{
 			// if forceably removed from channel
 			// update the UI and revert to default channel
-			LLNotifyBox::showXml("VoiceChannelDisconnected", mNotifyArgs);
+			LLNotifications::instance().add("VoiceChannelDisconnected", mNotifyArgs);
 			deactivate();
 		}
 		mIgnoreNextSessionLeave = FALSE;
@@ -793,9 +794,9 @@ void LLVoiceChannelGroup::handleError(EStatusType status)
 	// notification
 	if (!notify.empty())
 	{
-		LLNotifyBox::showXml(notify, mNotifyArgs);
+		LLNotificationPtr notification = LLNotifications::instance().add(notify, mNotifyArgs);
 		// echo to im window
-		gIMMgr->addMessage(mSessionID, LLUUID::null, SYSTEM_FROM, LLNotifyBox::getTemplateMessage(notify, mNotifyArgs));
+		gIMMgr->addMessage(mSessionID, LLUUID::null, SYSTEM_FROM, notification->getMessage());
 	}
 
 	LLVoiceChannel::handleError(status);
@@ -896,7 +897,7 @@ void LLVoiceChannelProximal::handleError(EStatusType status)
 	// notification
 	if (!notify.empty())
 	{
-		LLNotifyBox::showXml(notify, mNotifyArgs);
+		LLNotifications::instance().add(notify, mNotifyArgs);
 	}
 
 	LLVoiceChannel::handleError(status);
@@ -934,12 +935,12 @@ void LLVoiceChannelP2P::handleStatusChange(EStatusType type)
 			if (mState == STATE_RINGING)
 			{
 				// other user declined call
-				LLNotifyBox::showXml("P2PCallDeclined", mNotifyArgs);
+				LLNotifications::instance().add("P2PCallDeclined", mNotifyArgs);
 			}
 			else
 			{
 				// other user hung up
-				LLNotifyBox::showXml("VoiceChannelDisconnectedP2P", mNotifyArgs);
+				LLNotifications::instance().add("VoiceChannelDisconnectedP2P", mNotifyArgs);
 			}
 			deactivate();
 		}
@@ -957,7 +958,7 @@ void LLVoiceChannelP2P::handleError(EStatusType type)
 	switch(type)
 	{
 	case ERROR_NOT_AVAILABLE:
-		LLNotifyBox::showXml("P2PCallNoAnswer", mNotifyArgs);
+		LLNotifications::instance().add("P2PCallNoAnswer", mNotifyArgs);
 		break;
 	default:
 		break;
@@ -2213,35 +2214,33 @@ void LLFloaterIMPanel::showSessionStartError(
 	//their own XML file which would be read in by any LLIMPanel
 	//post build function instead of repeating the same info
 	//in the group, adhoc and normal IM xml files.
-	LLStringUtil::format_map_t args;
-	args["[REASON]"] =
+	LLSD args;
+	args["REASON"] =
 		LLFloaterIM::sErrorStringsMap[error_string];
-	args["[RECIPIENT]"] = getTitle();
+	args["RECIPIENT"] = getTitle();
+
+	LLSD payload;
+	payload["session_id"] = mSessionUUID;
 
-	gViewerWindow->alertXml(
+	LLNotifications::instance().add(
 		"ChatterBoxSessionStartError",
 		args,
-		onConfirmForceCloseError,
-		new LLUUID(mSessionUUID));
+		payload,
+		onConfirmForceCloseError);
 }
 
 void LLFloaterIMPanel::showSessionEventError(
 	const std::string& event_string,
 	const std::string& error_string)
 {
-	LLStringUtil::format_map_t args;
-	std::string event;
-
-	event = LLFloaterIM::sEventStringsMap[event_string];
-	args["[RECIPIENT]"] = getTitle();
-	LLStringUtil::format(event, args);
-
-
-	args = LLStringUtil::format_map_t();
-	args["[REASON]"] = LLFloaterIM::sErrorStringsMap[error_string];
-	args["[EVENT]"] = event;
+	LLSD args;
+	args["REASON"] =
+		LLFloaterIM::sErrorStringsMap[error_string];
+	args["EVENT"] =
+		LLFloaterIM::sEventStringsMap[event_string];
+	args["RECIPIENT"] = getTitle();
 
-	gViewerWindow->alertXml(
+	LLNotifications::instance().add(
 		"ChatterBoxSessionEventError",
 		args);
 }
@@ -2249,16 +2248,19 @@ void LLFloaterIMPanel::showSessionEventError(
 void LLFloaterIMPanel::showSessionForceClose(
 	const std::string& reason_string)
 {
-	LLStringUtil::format_map_t args;
+	LLSD args;
 
-	args["[NAME]"] = getTitle();
-	args["[REASON]"] = LLFloaterIM::sForceCloseSessionMap[reason_string];
+	args["NAME"] = getTitle();
+	args["REASON"] = LLFloaterIM::sForceCloseSessionMap[reason_string];
 
-	gViewerWindow->alertXml(
+	LLSD payload;
+	payload["session_id"] = mSessionUUID;
+
+	LLNotifications::instance().add(
 		"ForceCloseChatterBoxSession",
 		args,
-		LLFloaterIMPanel::onConfirmForceCloseError,
-		new LLUUID(mSessionUUID));
+		payload,
+		LLFloaterIMPanel::onConfirmForceCloseError);
 
 }
 
@@ -2268,10 +2270,10 @@ void LLFloaterIMPanel::onKickSpeaker(void* user_data)
 
 }
 
-void LLFloaterIMPanel::onConfirmForceCloseError(S32 option, void* data)
+bool LLFloaterIMPanel::onConfirmForceCloseError(const LLSD& notification, const LLSD& response)
 {
 	//only 1 option really
-	LLUUID session_id = *((LLUUID*) data);
+	LLUUID session_id = notification["payload"]["session_id"];
 
 	if ( gIMMgr )
 	{
@@ -2280,6 +2282,7 @@ void LLFloaterIMPanel::onConfirmForceCloseError(S32 option, void* data)
 
 		if ( floaterp ) floaterp->close(FALSE);
 	}
+	return false;
 }
 
 
diff --git a/indra/newview/llimpanel.h b/indra/newview/llimpanel.h
index b20dcd02bd5..4681c5684bc 100644
--- a/indra/newview/llimpanel.h
+++ b/indra/newview/llimpanel.h
@@ -81,7 +81,7 @@ class LLVoiceChannel : public LLVoiceClientStatusObserver
 	EState getState() { return mState; }
 
 	void updateSessionID(const LLUUID& new_session_id);
-	const LLStringUtil::format_map_t& getNotifyArgs() { return mNotifyArgs; }
+	const LLSD& getNotifyArgs() { return mNotifyArgs; }
 
 	static LLVoiceChannel* getChannelByID(const LLUUID& session_id);
 	static LLVoiceChannel* getChannelByURI(std::string uri);
@@ -100,7 +100,7 @@ class LLVoiceChannel : public LLVoiceClientStatusObserver
 	LLUUID		mSessionID;
 	EState		mState;
 	std::string	mSessionName;
-	LLStringUtil::format_map_t mNotifyArgs;
+	LLSD mNotifyArgs;
 	BOOL		mIgnoreNextSessionLeave;
 	LLHandle<LLPanel> mLoginNotificationHandle;
 
@@ -266,7 +266,7 @@ class LLFloaterIMPanel : public LLFloater
 		const std::string& error_string);
 	void showSessionForceClose(const std::string& reason);
 
-	static void onConfirmForceCloseError(S32 option, void* data);
+	static bool onConfirmForceCloseError(const LLSD& notification, const LLSD& response);
 
 private:
 	// called by constructors
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index c33de4c457c..552854e7fa4 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -97,6 +97,96 @@ std::map<std::string,std::string> LLFloaterIM::sForceCloseSessionMap;
 //	return (LLStringUtil::compareDict( a->mName, b->mName ) < 0);
 //}
 
+class LLViewerChatterBoxInvitationAcceptResponder :
+	public LLHTTPClient::Responder
+{
+public:
+	LLViewerChatterBoxInvitationAcceptResponder(
+		const LLUUID& session_id,
+		LLIMMgr::EInvitationType invitation_type)
+	{
+		mSessionID = session_id;
+		mInvitiationType = invitation_type;
+	}
+
+	void result(const LLSD& content)
+	{
+		if ( gIMMgr)
+		{
+			LLFloaterIMPanel* floaterp =
+				gIMMgr->findFloaterBySession(mSessionID);
+
+			if (floaterp)
+			{
+				//we've accepted our invitation
+				//and received a list of agents that were
+				//currently in the session when the reply was sent
+				//to us.  Now, it is possible that there were some agents
+				//to slip in/out between when that message was sent to us
+				//and now.
+
+				//the agent list updates we've received have been
+				//accurate from the time we were added to the session
+				//but unfortunately, our base that we are receiving here
+				//may not be the most up to date.  It was accurate at
+				//some point in time though.
+				floaterp->setSpeakers(content);
+
+				//we now have our base of users in the session
+				//that was accurate at some point, but maybe not now
+				//so now we apply all of the udpates we've received
+				//in case of race conditions
+				floaterp->updateSpeakersList(
+					gIMMgr->getPendingAgentListUpdates(mSessionID));
+
+				if ( mInvitiationType == LLIMMgr::INVITATION_TYPE_VOICE )
+				{
+					floaterp->requestAutoConnect();
+					LLFloaterIMPanel::onClickStartCall(floaterp);
+					// always open IM window when connecting to voice
+					LLFloaterChatterBox::showInstance(TRUE);
+				}
+				else if ( mInvitiationType == LLIMMgr::INVITATION_TYPE_IMMEDIATE )
+				{
+					LLFloaterChatterBox::showInstance(TRUE);
+				}
+			}
+
+			gIMMgr->clearPendingAgentListUpdates(mSessionID);
+			gIMMgr->clearPendingInvitation(mSessionID);
+		}
+	}
+
+	void error(U32 statusNum, const std::string& reason)
+	{		
+		//throw something back to the viewer here?
+		if ( gIMMgr )
+		{
+			gIMMgr->clearPendingAgentListUpdates(mSessionID);
+			gIMMgr->clearPendingInvitation(mSessionID);
+
+			LLFloaterIMPanel* floaterp =
+				gIMMgr->findFloaterBySession(mSessionID);
+
+			if ( floaterp )
+			{
+				if ( 404 == statusNum )
+				{
+					std::string error_string;
+					error_string = "does not exist";
+
+					floaterp->showSessionStartError(
+						error_string);
+				}
+			}
+		}
+	}
+
+private:
+	LLUUID mSessionID;
+	LLIMMgr::EInvitationType mInvitiationType;
+};
+
 
 // the other_participant_id is either an agent_id, a group_id, or an inventory
 // folder item_id (collection of calling cards)
@@ -256,38 +346,104 @@ class LLIMViewFriendObserver : public LLFriendObserver
 };
 
 
-class LLIMMgr::LLIMSessionInvite
+bool inviteUserResponse(const LLSD& notification, const LLSD& response)
 {
-public:
-	LLIMSessionInvite(
-		const LLUUID& session_id,
-		const std::string& session_name,
-		const LLUUID& caller_id,
-		const std::string& caller_name,
-		EInstantMessage type,
-		EInvitationType inv_type,
-		const std::string& session_handle,
-		const std::string& notify_box) : 
-		mSessionID(session_id),
-		mSessionName(session_name),
-		mCallerID(caller_id),
-		mCallerName(caller_name),
-		mType(type),
-		mInvType(inv_type),
-		mSessionHandle(session_handle),
-		mNotifyBox(notify_box)
-	{};
-
-	LLUUID		mSessionID;
-	std::string	mSessionName;
-	LLUUID		mCallerID;
-	std::string	mCallerName;
-	EInstantMessage mType;
-	EInvitationType mInvType;
-	std::string	mSessionHandle;
-	std::string	mNotifyBox;
-};
+	const LLSD& payload = notification["payload"];
+	LLUUID session_id = payload["session_id"].asUUID();
+	EInstantMessage type = (EInstantMessage)payload["type"].asInteger();
+	LLIMMgr::EInvitationType inv_type = (LLIMMgr::EInvitationType)payload["inv_type"].asInteger();
+	S32 option = LLNotification::getSelectedOption(notification, response);
+	switch(option) 
+	{
+	case 0: // accept
+		{
+			if (type == IM_SESSION_P2P_INVITE)
+			{
+				// create a normal IM session
+				session_id = gIMMgr->addP2PSession(
+					payload["session_name"].asString(),
+					payload["caller_id"].asUUID(),
+					payload["session_handle"].asString());
+
+				LLFloaterIMPanel* im_floater =
+					gIMMgr->findFloaterBySession(
+						session_id);
+				if (im_floater)
+				{
+					im_floater->requestAutoConnect();
+					LLFloaterIMPanel::onClickStartCall(im_floater);
+					// always open IM window when connecting to voice
+					LLFloaterChatterBox::showInstance(session_id);
+				}
+
+				gIMMgr->clearPendingAgentListUpdates(session_id);
+				gIMMgr->clearPendingInvitation(session_id);
+			}
+			else
+			{
+				gIMMgr->addSession(
+					payload["session_name"].asString(),
+					type,
+					session_id);
+
+				std::string url = gAgent.getRegion()->getCapability(
+					"ChatSessionRequest");
+
+				LLSD data;
+				data["method"] = "accept invitation";
+				data["session-id"] = session_id;
+				LLHTTPClient::post(
+					url,
+					data,
+					new LLViewerChatterBoxInvitationAcceptResponder(
+						session_id,
+						inv_type));
+			}
+		}
+		break;
+	case 2: // mute (also implies ignore, so this falls through to the "ignore" case below)
+	{
+		// mute the sender of this invite
+		if (!LLMuteList::getInstance()->isMuted(payload["caller_id"].asUUID()))
+		{
+			LLMute mute(payload["caller_id"].asUUID(), payload["caller_name"].asString(), LLMute::AGENT);
+			LLMuteList::getInstance()->add(mute);
+		}
+	}
+	/* FALLTHROUGH */
+	
+	case 1: // decline
+	{
+		if (type == IM_SESSION_P2P_INVITE)
+		{
+			if(gVoiceClient)
+			{
+				std::string s = payload["session_handle"].asString();
+				gVoiceClient->declineInvite(s);
+			}
+		}
+		else
+		{
+			std::string url = gAgent.getRegion()->getCapability(
+				"ChatSessionRequest");
+
+			LLSD data;
+			data["method"] = "decline invitation";
+			data["session-id"] = session_id;
+			LLHTTPClient::post(
+				url,
+				data,
+				NULL);				
+		}
+	}
 
+	gIMMgr->clearPendingAgentListUpdates(session_id);
+	gIMMgr->clearPendingInvitation(session_id);
+	break;
+	}
+	
+	return false;
+}
 
 //
 // Public Static Member Functions
@@ -510,7 +666,7 @@ void LLIMMgr::addMessage(
 	}
 }
 
-void LLIMMgr::addSystemMessage(const LLUUID& session_id, const std::string& message_name, const LLStringUtil::format_map_t& args)
+void LLIMMgr::addSystemMessage(const LLUUID& session_id, const std::string& message_name, const LLSD& args)
 {
 	LLUIString message;
 	
@@ -520,7 +676,7 @@ void LLIMMgr::addSystemMessage(const LLUUID& session_id, const std::string& mess
 		LLFloaterChat* floaterp = LLFloaterChat::getInstance();
 
 		message = floaterp->getString(message_name);
-		message.setArgList(args);
+		message.setArgs(args);
 
 		LLChat chat(message);
 		chat.mSourceType = CHAT_SOURCE_SYSTEM;
@@ -532,7 +688,7 @@ void LLIMMgr::addSystemMessage(const LLUUID& session_id, const std::string& mess
 		if (floaterp)
 		{
 			message = floaterp->getString(message_name);
-			message.setArgList(args);
+			message.setArgs(args);
 
 			gIMMgr->addMessage(session_id, LLUUID::null, SYSTEM_FROM, message.getString());
 		}
@@ -687,7 +843,7 @@ void LLIMMgr::removeSession(const LLUUID& session_id)
 		LLFloaterChatterBox::getInstance(LLSD())->removeFloater(floater);
 		//mTabContainer->removeTabPanel(floater);
 
-		clearPendingInviation(session_id);
+		clearPendingInvitation(session_id);
 		clearPendingAgentListUpdates(session_id);
 	}
 }
@@ -733,21 +889,21 @@ void LLIMMgr::inviteToSession(
 		ad_hoc_invite = TRUE;
 	}
 
-	LLIMSessionInvite* invite = new LLIMSessionInvite(
-		session_id,
-		session_name,
-		caller_id,
-		caller_name,
-		type,
-		inv_type,
-		session_handle,
-		notify_box_type);
+	LLSD payload;
+	payload["session_id"] = session_id;
+	payload["session_name"] = session_name;
+	payload["caller_id"] = caller_id;
+	payload["caller_name"] = caller_name;
+	payload["type"] = type;
+	payload["inv_type"] = inv_type;
+	payload["session_handle"] = session_handle;
+	payload["notify_box_type"] = notify_box_type;
 	
 	LLVoiceChannel* channelp = LLVoiceChannel::getChannelByID(session_id);
 	if (channelp && channelp->callStarted())
 	{
 		// you have already started a call to the other user, so just accept the invite
-		inviteUserResponse(0, invite); // inviteUserResponse deletes
+		LLNotifications::instance().forceResponse(LLNotification::Params("VoiceInviteP2P").payload(payload), 0);
 		return;
 	}
 
@@ -761,7 +917,7 @@ void LLIMMgr::inviteToSession(
 			if (gSavedSettings.getBOOL("VoiceCallsFriendsOnly"))
 			{
 				// invite not from a friend, so decline
-				inviteUserResponse(1, invite); // inviteUserResponse deletes
+				LLNotifications::instance().forceResponse(LLNotification::Params("VoiceInviteP2P").payload(payload), 1);
 				return;
 			}
 		}
@@ -771,230 +927,41 @@ void LLIMMgr::inviteToSession(
 	{
 		if (caller_name.empty())
 		{
-			gCacheName->get(caller_id, FALSE, onInviteNameLookup, invite);
+			gCacheName->getName(caller_id, onInviteNameLookup, new LLSD(payload));
 		}
 		else
 		{
-			LLStringUtil::format_map_t args;
-			args["[NAME]"] = caller_name;
-			args["[GROUP]"] = session_name;
+			LLSD args;
+			args["NAME"] = caller_name;
+			args["GROUP"] = session_name;
 
-			LLNotifyBox::showXml(notify_box_type, 
+			LLNotifications::instance().add(notify_box_type, 
 					     args, 
-					     inviteUserResponse, 
-					     (void*)invite); // inviteUserResponse deletes
+						 payload,
+						 &inviteUserResponse);
 
 		}
 		mPendingInvitations[session_id.asString()] = LLSD();
 	}
-	else
-	{
-		delete invite;
-	}
 }
 
 //static 
 void LLIMMgr::onInviteNameLookup(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group, void* userdata)
 {
-	LLIMSessionInvite* invite = (LLIMSessionInvite*)userdata;
+	LLSD payload = *(LLSD*)userdata;
+	delete (LLSD*)userdata;
 
-	invite->mCallerName = first + " " + last;
-	invite->mSessionName = invite->mCallerName;
+	payload["caller_name"] = first + " " + last;
+	payload["session_name"] = payload["caller_name"].asString();
 
-	LLStringUtil::format_map_t args;
-	args["[NAME]"] = invite->mCallerName;
+	LLSD args;
+	args["NAME"] = payload["caller_name"].asString();
 
-	LLNotifyBox::showXml(
-		invite->mNotifyBox,
+	LLNotifications::instance().add(
+		payload["notify_box_type"].asString(),
 		args, 
-		inviteUserResponse, 
-		(void*)invite);
-}
-
-class LLViewerChatterBoxInvitationAcceptResponder :
-	public LLHTTPClient::Responder
-{
-public:
-	LLViewerChatterBoxInvitationAcceptResponder(
-		const LLUUID& session_id,
-		LLIMMgr::EInvitationType invitation_type)
-	{
-		mSessionID = session_id;
-		mInvitiationType = invitation_type;
-	}
-
-	void result(const LLSD& content)
-	{
-		if ( gIMMgr)
-		{
-			LLFloaterIMPanel* floaterp =
-				gIMMgr->findFloaterBySession(mSessionID);
-
-			if (floaterp)
-			{
-				//we've accepted our invitation
-				//and received a list of agents that were
-				//currently in the session when the reply was sent
-				//to us.  Now, it is possible that there were some agents
-				//to slip in/out between when that message was sent to us
-				//and now.
-
-				//the agent list updates we've received have been
-				//accurate from the time we were added to the session
-				//but unfortunately, our base that we are receiving here
-				//may not be the most up to date.  It was accurate at
-				//some point in time though.
-				floaterp->setSpeakers(content);
-
-				//we now have our base of users in the session
-				//that was accurate at some point, but maybe not now
-				//so now we apply all of the udpates we've received
-				//in case of race conditions
-				floaterp->updateSpeakersList(
-					gIMMgr->getPendingAgentListUpdates(mSessionID));
-
-				if ( mInvitiationType == LLIMMgr::INVITATION_TYPE_VOICE )
-				{
-					floaterp->requestAutoConnect();
-					LLFloaterIMPanel::onClickStartCall(floaterp);
-					// always open IM window when connecting to voice
-					LLFloaterChatterBox::showInstance(TRUE);
-				}
-				else if ( mInvitiationType == LLIMMgr::INVITATION_TYPE_IMMEDIATE )
-				{
-					LLFloaterChatterBox::showInstance(TRUE);
-				}
-			}
-
-			gIMMgr->clearPendingAgentListUpdates(mSessionID);
-			gIMMgr->clearPendingInviation(mSessionID);
-		}
-	}
-
-	void error(U32 statusNum, const std::string& reason)
-	{		
-		//throw something back to the viewer here?
-		if ( gIMMgr )
-		{
-			gIMMgr->clearPendingAgentListUpdates(mSessionID);
-			gIMMgr->clearPendingInviation(mSessionID);
-
-			LLFloaterIMPanel* floaterp =
-				gIMMgr->findFloaterBySession(mSessionID);
-
-			if ( floaterp )
-			{
-				if ( 404 == statusNum )
-				{
-					std::string error_string;
-					error_string = "does not exist";
-
-					floaterp->showSessionStartError(
-						error_string);
-				}
-			}
-		}
-	}
-
-private:
-	LLUUID mSessionID;
-	LLIMMgr::EInvitationType mInvitiationType;
-};
-
-//static
-void LLIMMgr::inviteUserResponse(S32 option, void* user_data)
-{
-	LLIMSessionInvite* invitep = (LLIMSessionInvite*)user_data;
-
-	switch(option) 
-	{
-	case 0: // accept
-		{
-			if (invitep->mType == IM_SESSION_P2P_INVITE)
-			{
-				// create a normal IM session
-				invitep->mSessionID = gIMMgr->addP2PSession(
-					invitep->mSessionName,
-					invitep->mCallerID,
-					invitep->mSessionHandle);
-
-				LLFloaterIMPanel* im_floater =
-					gIMMgr->findFloaterBySession(
-						invitep->mSessionID);
-				if (im_floater)
-				{
-					im_floater->requestAutoConnect();
-					LLFloaterIMPanel::onClickStartCall(im_floater);
-					// always open IM window when connecting to voice
-					LLFloaterChatterBox::showInstance(invitep->mSessionID);
-				}
-
-				gIMMgr->clearPendingAgentListUpdates(invitep->mSessionID);
-				gIMMgr->clearPendingInviation(invitep->mSessionID);
-			}
-			else
-			{
-				gIMMgr->addSession(
-					invitep->mSessionName,
-					invitep->mType,
-					invitep->mSessionID);
-
-				std::string url = gAgent.getRegion()->getCapability(
-					"ChatSessionRequest");
-
-				LLSD data;
-				data["method"] = "accept invitation";
-				data["session-id"] = invitep->mSessionID;
-				LLHTTPClient::post(
-					url,
-					data,
-					new LLViewerChatterBoxInvitationAcceptResponder(
-						invitep->mSessionID,
-						invitep->mInvType));
-			}
-		}
-		break;
-	case 2: // mute (also implies ignore, so this falls through to the "ignore" case below)
-	{
-		// mute the sender of this invite
-		if (!LLMuteList::getInstance()->isMuted(invitep->mCallerID))
-		{
-			LLMute mute(invitep->mCallerID, invitep->mCallerName, LLMute::AGENT);
-			LLMuteList::getInstance()->add(mute);
-		}
-	}
-	/* FALLTHROUGH */
-	
-	case 1: // decline
-	{
-		if (invitep->mType == IM_SESSION_P2P_INVITE)
-		{
-			if(gVoiceClient)
-			{
-				gVoiceClient->declineInvite(invitep->mSessionHandle);
-			}
-		}
-		else
-		{
-			std::string url = gAgent.getRegion()->getCapability(
-				"ChatSessionRequest");
-
-			LLSD data;
-			data["method"] = "decline invitation";
-			data["session-id"] = invitep->mSessionID;
-			LLHTTPClient::post(
-				url,
-				data,
-				NULL);				
-		}
-	}
-
-	gIMMgr->clearPendingAgentListUpdates(invitep->mSessionID);
-	gIMMgr->clearPendingInviation(invitep->mSessionID);
-	break;
-	}
-	
-	delete invitep;
+		payload,
+		&inviteUserResponse);
 }
 
 void LLIMMgr::refresh()
@@ -1068,7 +1035,7 @@ BOOL LLIMMgr::hasSession(const LLUUID& session_id)
 	return (findFloaterBySession(session_id) != NULL);
 }
 
-void LLIMMgr::clearPendingInviation(const LLUUID& session_id)
+void LLIMMgr::clearPendingInvitation(const LLUUID& session_id)
 {
 	if ( mPendingInvitations.has(session_id.asString()) )
 	{
diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h
index da64cd3bab2..175f47ebc1f 100644
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -68,7 +68,7 @@ class LLIMMgr : public LLSingleton<LLIMMgr>
 					const LLVector3& position = LLVector3::zero,
 					bool link_name = false);
 
-	void addSystemMessage(const LLUUID& session_id, const std::string& message_name, const LLStringUtil::format_map_t& args);
+	void addSystemMessage(const LLUUID& session_id, const std::string& message_name, const LLSD& args);
 
 	// This method returns TRUE if the local viewer has a session
 	// currently open keyed to the uuid. The uuid can be keyed by
@@ -157,7 +157,7 @@ class LLIMMgr : public LLSingleton<LLIMMgr>
 
 	static LLUUID computeSessionID(EInstantMessage dialog, const LLUUID& other_participant_id);
 
-	void clearPendingInviation(const LLUUID& session_id);
+	void clearPendingInvitation(const LLUUID& session_id);
 
 	LLSD getPendingAgentListUpdates(const LLUUID& session_id);
 	void addPendingAgentListUpdates(
@@ -169,8 +169,6 @@ class LLIMMgr : public LLSingleton<LLIMMgr>
 	const std::set<LLHandle<LLFloater> >& getIMFloaterHandles() { return mFloaters; }
 
 private:
-	class LLIMSessionInvite;
-
 	// create a panel and update internal representation for
 	// consistency. Returns the pointer, caller (the class instance
 	// since it is a private method) is not responsible for deleting
@@ -197,7 +195,6 @@ class LLIMMgr : public LLSingleton<LLIMMgr>
 
 	void processIMTypingCore(const LLIMInfo* im_info, BOOL typing);
 
-	static void inviteUserResponse(S32 option, void* user_data);
 	static void onInviteNameLookup(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group, void* userdata);
 
 private:
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index a4b80ed7c1d..38527558508 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -109,8 +109,8 @@ void wear_inventory_category_on_avatar_loop(LLWearable* wearable, void*);
 void wear_inventory_category_on_avatar_step3(LLWearableHoldingPattern* holder, BOOL append);
 void remove_inventory_category_from_avatar(LLInventoryCategory* category);
 void remove_inventory_category_from_avatar_step2( BOOL proceed, void* userdata);
-void move_task_inventory_callback(S32 option, void* user_data);
-void confirm_replace_attachment_rez(S32 option, void* user_data);
+bool move_task_inventory_callback(const LLSD& notification, const LLSD& response, LLMoveInv*);
+bool confirm_replace_attachment_rez(const LLSD& notification, const LLSD& response);
 
 std::string ICON_NAME[ICON_NAME_COUNT] =
 {
@@ -1288,7 +1288,7 @@ void warn_move_inventory(LLViewerObject* object, LLMoveInv* move_inv)
 	{
 		dialog = "MoveInventoryFromObject";
 	}
-	gViewerWindow->alertXml(dialog, move_task_inventory_callback, move_inv);
+	LLNotifications::instance().add(dialog, LLSD(), LLSD(), boost::bind(move_task_inventory_callback, _1, _2, move_inv));
 }
 
 // Move/copy all inventory items from the Contents folder of an in-world
@@ -1377,7 +1377,9 @@ BOOL move_inv_category_world_to_agent(const LLUUID& object_id,
 		}
 		else
 		{
-			move_task_inventory_callback(0, (void*)(move_inv));
+			LLNotification::Params params("MoveInventoryFromObject");
+			params.functor(boost::bind(move_task_inventory_callback, _1, _2, move_inv));
+			LLNotifications::instance().forceResponse(params, 0);
 		}
 	}
 	return accept;
@@ -2187,12 +2189,12 @@ void LLFolderBridge::modifyOutfit(BOOL append)
 }
 
 // helper stuff
-void move_task_inventory_callback(S32 option, void* user_data)
+bool move_task_inventory_callback(const LLSD& notification, const LLSD& response, LLMoveInv* move_inv)
 {
-	LLMoveInv* move_inv = (LLMoveInv*)user_data;
 	LLFloaterOpenObject::LLCatAndWear* cat_and_wear = (LLFloaterOpenObject::LLCatAndWear* )move_inv->mUserData;
 	LLViewerObject* object = gObjectList.findObject(move_inv->mObjectID);
-	
+	S32 option = LLNotification::getSelectedOption(notification, response);
+
 	if(option == 0 && object)
 	{
 		if (cat_and_wear && cat_and_wear->mWear)
@@ -2223,6 +2225,7 @@ void move_task_inventory_callback(S32 option, void* user_data)
 	}
 
 	delete move_inv;
+	return false;
 }
 
 BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
@@ -2353,7 +2356,9 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
 			}
 			else
 			{
-				move_task_inventory_callback(0, (void*)(move_inv));
+				LLNotification::Params params("MoveInventoryFromObject");
+				params.functor(boost::bind(move_task_inventory_callback, _1, _2, move_inv));
+				LLNotifications::instance().forceResponse(params, 0);
 			}
 		}
 		
@@ -2648,23 +2653,28 @@ void open_landmark(LLViewerInventoryItem* inv_item,
 	}
 }
 
-static void open_landmark_callback(S32 option, void* data)
+static bool open_landmark_callback(const LLSD& notification, const LLSD& response)
 {
-	LLUUID* asset_idp = (LLUUID*)data;
+	S32 option = LLNotification::getSelectedOption(notification, response);
+
+	LLUUID asset_id = notification["payload"]["asset_id"].asUUID();
 	if (option == 0)
 	{
 		// HACK: This is to demonstrate teleport on double click for landmarks
-		gAgent.teleportViaLandmark( *asset_idp );
+		gAgent.teleportViaLandmark( asset_id );
 
 		// we now automatically track the landmark you're teleporting to
 		// because you'll probably arrive at a telehub instead
 		if( gFloaterWorldMap )
 		{
-			gFloaterWorldMap->trackLandmark( *asset_idp );
+			gFloaterWorldMap->trackLandmark( asset_id );
 		}
 	}
-	delete asset_idp;
+
+	return false;
 }
+static LLNotificationFunctorRegistration open_landmark_callback_reg("TeleportFromLandmark", open_landmark_callback);
+
 
 void LLLandmarkBridge::openItem()
 {
@@ -2674,9 +2684,9 @@ void LLLandmarkBridge::openItem()
 		// Opening (double-clicking) a landmark immediately teleports,
 		// but warns you the first time.
 		// open_landmark(item, std::string("  ") + getPrefix() + item->getName(), FALSE);
-		LLUUID* asset_idp = new LLUUID(item->getAssetUUID());
-		LLAlertDialog::showXml("TeleportFromLandmark",
-			open_landmark_callback, (void*)asset_idp);
+		LLSD payload;
+		payload["asset_id"] = item->getAssetUUID();
+		LLNotifications::instance().add("TeleportFromLandmark", LLSD(), payload);
 	}
 }
 
@@ -3321,8 +3331,9 @@ std::string LLObjectBridge::getLabelSuffix() const
 
 void rez_attachment(LLViewerInventoryItem* item, LLViewerJointAttachment* attachment)
 {
-	LLAttachmentRezAction* rez_action = new LLAttachmentRezAction;
-	rez_action->mItemID = item->getUUID();
+	LLSD payload;
+	payload["item_id"] = item->getUUID();
+
 	S32 attach_pt = 0;
 	if (gAgent.getAvatarObject() && attachment)
 	{
@@ -3336,46 +3347,46 @@ void rez_attachment(LLViewerInventoryItem* item, LLViewerJointAttachment* attach
 			}
 		}
 	}
-	rez_action->mAttachPt = attach_pt;
+
+	payload["attachment_point"] = attach_pt;
+
 	if (attachment && attachment->getObject())
 	{
-		gViewerWindow->alertXml("ReplaceAttachment", confirm_replace_attachment_rez, (void*)rez_action);
+		LLNotifications::instance().add("ReplaceAttachment", LLSD(), payload, confirm_replace_attachment_rez);
 	}
 	else
 	{
-		confirm_replace_attachment_rez(0/*YES*/, (void*)rez_action);
+		LLNotifications::instance().forceResponse(LLNotification::Params("ReplaceAttachment").payload(payload), 0/*YES*/);
 	}
 }
 
-void confirm_replace_attachment_rez(S32 option, void* user_data)
+bool confirm_replace_attachment_rez(const LLSD& notification, const LLSD& response)
 {
-	LLAttachmentRezAction* rez_action = (LLAttachmentRezAction*)user_data;
+	S32 option = LLNotification::getSelectedOption(notification, response);
 	if (option == 0/*YES*/)
 	{
-		if (rez_action)
+		LLViewerInventoryItem* itemp = gInventory.getItem(notification["payload"]["item_id"].asUUID());
+		
+		if (itemp)
 		{
-			LLViewerInventoryItem* itemp = gInventory.getItem(rez_action->mItemID);
-			
-			if (itemp)
-			{
-				LLMessageSystem* msg = gMessageSystem;
-				msg->newMessageFast(_PREHASH_RezSingleAttachmentFromInv);
-				msg->nextBlockFast(_PREHASH_AgentData);
-				msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
-				msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-				msg->nextBlockFast(_PREHASH_ObjectData);
-				msg->addUUIDFast(_PREHASH_ItemID, itemp->getUUID());
-				msg->addUUIDFast(_PREHASH_OwnerID, itemp->getPermissions().getOwner());
-				msg->addU8Fast(_PREHASH_AttachmentPt, rez_action->mAttachPt);
-				pack_permissions_slam(msg, itemp->getFlags(), itemp->getPermissions());
-				msg->addStringFast(_PREHASH_Name, itemp->getName());
-				msg->addStringFast(_PREHASH_Description, itemp->getDescription());
-				msg->sendReliable(gAgent.getRegion()->getHost());
-			}
+			LLMessageSystem* msg = gMessageSystem;
+			msg->newMessageFast(_PREHASH_RezSingleAttachmentFromInv);
+			msg->nextBlockFast(_PREHASH_AgentData);
+			msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+			msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+			msg->nextBlockFast(_PREHASH_ObjectData);
+			msg->addUUIDFast(_PREHASH_ItemID, itemp->getUUID());
+			msg->addUUIDFast(_PREHASH_OwnerID, itemp->getPermissions().getOwner());
+			msg->addU8Fast(_PREHASH_AttachmentPt, notification["payload"]["attachment_point"].asInteger());
+			pack_permissions_slam(msg, itemp->getFlags(), itemp->getPermissions());
+			msg->addStringFast(_PREHASH_Name, itemp->getName());
+			msg->addStringFast(_PREHASH_Description, itemp->getDescription());
+			msg->sendReliable(gAgent.getRegion()->getHost());
 		}
 	}
-	delete rez_action;
+	return false;
 }
+static LLNotificationFunctorRegistration confirm_replace_attachment_rez_reg("ReplaceAttachment", confirm_replace_attachment_rez);
 
 void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
 {
@@ -3927,7 +3938,7 @@ void wear_inventory_category_on_avatar_step2( BOOL proceed, void* userdata )
 
 		if( !wearable_count && !obj_count && !gest_count)
 		{
-			gViewerWindow->alertXml("CouldNotPutOnOutfit");
+			LLNotifications::instance().add("CouldNotPutOnOutfit");
 			delete wear_info;
 			return;
 		}
@@ -4334,7 +4345,7 @@ void LLWearableBridge::openItem()
 {
 	if( isInTrash() )
 	{
-		gViewerWindow->alertXml("CannotWearTrash");
+		LLNotifications::instance().add("CannotWearTrash");
 	}
 	else if(isAgentInventory())
 	{
@@ -4363,7 +4374,7 @@ void LLWearableBridge::openItem()
 		{
 			// *TODO: We should fetch the item details, and then do
 			// the operation above.
-			gViewerWindow->alertXml("CannotWearInfoNotComplete");
+			LLNotifications::instance().add("CannotWearInfoNotComplete");
 		}
 	}
 }
@@ -4464,7 +4475,7 @@ void LLWearableBridge::wearOnAvatar()
 	// destroy clothing items.
 	if (!gAgent.areWearablesLoaded()) 
 	{
-		gViewerWindow->alertXml("CanNotChangeAppearanceUntilLoaded");
+		LLNotifications::instance().add("CanNotChangeAppearanceUntilLoaded");
 		return;
 	}
 
diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h
index 064ace52f2e..c0cda4c6a4d 100644
--- a/indra/newview/llinventorymodel.h
+++ b/indra/newview/llinventorymodel.h
@@ -92,7 +92,6 @@ class LLViewerInventoryItem;
 class LLViewerInventoryCategory;
 class LLMessageSystem;
 class LLInventoryCollectFunctor;
-class LLAlertDialog;
 
 class LLInventoryModel
 {
diff --git a/indra/newview/lllandmarklist.cpp b/indra/newview/lllandmarklist.cpp
index 59b4d245ac6..d98ee1894b8 100644
--- a/indra/newview/lllandmarklist.cpp
+++ b/indra/newview/lllandmarklist.cpp
@@ -119,11 +119,11 @@ void LLLandmarkList::processGetAssetReply(
 
 		if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status )
 		{
-			LLNotifyBox::showXml("LandmarkMissing");
+			LLNotifications::instance().add("LandmarkMissing");
 		}
 		else
 		{
-			LLNotifyBox::showXml("UnableToLoadLandmark");
+			LLNotifications::instance().add("UnableToLoadLandmark");
 		}
 
 		gLandmarkList.mBadList.insert(uuid);
diff --git a/indra/newview/llmutelist.cpp b/indra/newview/llmutelist.cpp
index 3ad26b703a1..cc9be04cfcc 100644
--- a/indra/newview/llmutelist.cpp
+++ b/indra/newview/llmutelist.cpp
@@ -66,7 +66,8 @@
 #include "llfloaterchat.h"
 #include "llimpanel.h"
 #include "llimview.h"
-#include "llnotify.h"
+#include "lltrans.h"
+#include "llnotifications.h"
 #include "lluistring.h"
 #include "llviewerobject.h" 
 #include "llviewerobjectlist.h"
@@ -278,7 +279,7 @@ BOOL LLMuteList::add(const LLMute& mute, U32 flags)
 	if ((mute.mType == LLMute::AGENT)
 		&& isLinden(mute.mName) && (flags & LLMute::flagTextChat || flags == 0))
 	{
-		gViewerWindow->alertXml("MuteLinden");
+		LLNotifications::instance().add("MuteLinden");
 		return FALSE;
 	}
 	
@@ -480,35 +481,35 @@ void notify_automute_callback(const LLUUID& agent_id, const std::string& first_n
 {
 	U32 temp_data = (U32) (uintptr_t) user_data;
 	LLMuteList::EAutoReason reason = (LLMuteList::EAutoReason)temp_data;
-	LLUIString auto_message;
-
+	
+	std::string auto_message;
 	switch (reason)
 	{
 	default:
 	case LLMuteList::AR_IM:
-		auto_message = LLNotifyBox::getTemplateMessage("AutoUnmuteByIM");
+		auto_message = LLTrans::getString("AutoUnmuteByIM");
 		break;
 	case LLMuteList::AR_INVENTORY:
-		auto_message = LLNotifyBox::getTemplateMessage("AutoUnmuteByInventory");
+		auto_message = LLTrans::getString("AutoUnmuteByInventory");
 		break;
 	case LLMuteList::AR_MONEY:
-		auto_message = LLNotifyBox::getTemplateMessage("AutoUnmuteByMoney");
+		auto_message = LLTrans::getString("AutoUnmuteByMoney");
 		break;
 	}
 
-	auto_message.setArg("[FIRST]", first_name);
-	auto_message.setArg("[LAST]", last_name);
+	std::string message = LLNotification::format(auto_message, 
+							   LLSD().insert("FIRST", first_name).insert("LAST", last_name));
 
 	if (reason == LLMuteList::AR_IM)
 	{
 		LLFloaterIMPanel *timp = gIMMgr->findFloaterBySession(agent_id);
 		if (timp)
 		{
-			timp->addHistoryLine(auto_message.getString());
+			timp->addHistoryLine(message);
 		}
 	}
 
-	LLChat auto_chat(auto_message.getString());
+	LLChat auto_chat(message);
 	LLFloaterChat::addChat(auto_chat, FALSE, FALSE);
 }
 
diff --git a/indra/newview/llnamelistctrl.cpp b/indra/newview/llnamelistctrl.cpp
index dfc327e329a..5b4e9561378 100644
--- a/indra/newview/llnamelistctrl.cpp
+++ b/indra/newview/llnamelistctrl.cpp
@@ -349,7 +349,7 @@ LLView* LLNameListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFacto
 
 	LLSD columns;
 	S32 index = 0;
-	S32 total_static = 0;
+	//S32 total_static = 0;
 	LLXMLNodePtr child;
 	for (child = node->getFirstChild(); child.notNull(); child = child->getNextSibling())
 	{
@@ -383,7 +383,7 @@ LLView* LLNameListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFacto
 			LLFontGL::HAlign h_align = LLFontGL::LEFT;
 			h_align = LLView::selectFontHAlign(child);
 
-			if(!columndynamicwidth) total_static += llmax(0, columnwidth);
+			//if(!columndynamicwidth) total_static += llmax(0, columnwidth);
 
 			columns[index]["name"] = columnname;
 			columns[index]["label"] = labelname;
@@ -394,7 +394,6 @@ LLView* LLNameListCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFacto
 			index++;
 		}
 	}
-	name_list->setTotalStaticColumnWidth(total_static);
 	name_list->setColumnHeadings(columns);
 
 
diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp
index 9c8817da9ad..3f4732692fd 100644
--- a/indra/newview/llpanelavatar.cpp
+++ b/indra/newview/llpanelavatar.cpp
@@ -352,20 +352,24 @@ void LLPanelAvatarSecondLife::onDoubleClickGroup(void* data)
 // static
 void LLPanelAvatarSecondLife::onClickPublishHelp(void *)
 {
-	gViewerWindow->alertXml("ClickPublishHelpAvatar");
+	LLNotifications::instance().add("ClickPublishHelpAvatar");
 }
 
 // static
 void LLPanelAvatarSecondLife::onClickPartnerHelp(void *)
 {
-    gViewerWindow->alertXml("ClickPartnerHelpAvatar", onClickPartnerHelpLoadURL, (void*) NULL);
+	LLNotifications::instance().add("ClickPartnerHelpAvatar", LLSD(), LLSD(), onClickPartnerHelpLoadURL);
 }
 
 // static 
-void LLPanelAvatarSecondLife::onClickPartnerHelpLoadURL(S32 option, void* userdata)
+bool LLPanelAvatarSecondLife::onClickPartnerHelpLoadURL(const LLSD& notification, const LLSD& response)
 {
-  if (option == 0)
-    LLWeb::loadURL("http://secondlife.com/partner");
+	S32 option = LLNotification::getSelectedOption(notification, response);
+	if (option == 0)
+	{
+		LLWeb::loadURL("http://secondlife.com/partner");
+	}
+	return false;
 }
 
 // static
@@ -593,7 +597,7 @@ void LLPanelAvatarWeb::onCommitURL(LLUICtrl* ctrl, void* data)
 // static
 void LLPanelAvatarWeb::onClickWebProfileHelp(void *)
 {
-	gViewerWindow->alertXml("ClickWebProfileHelpAvatar");
+	LLNotifications::instance().add("ClickWebProfileHelpAvatar");
 }
 
 void LLPanelAvatarWeb::load(std::string url)
@@ -930,26 +934,25 @@ void LLPanelAvatarClassified::onClickNew(void* data)
 {
 	LLPanelAvatarClassified* self = (LLPanelAvatarClassified*)data;
 
-	gViewerWindow->alertXml("AddClassified",callbackNew,self);
+	LLNotifications::instance().add("AddClassified", LLSD(), LLSD(), boost::bind(&LLPanelAvatarClassified::callbackNew, self, _1, _2));
 		
 }
 
-// static
-void LLPanelAvatarClassified::callbackNew(S32 option, void* data)
+bool LLPanelAvatarClassified::callbackNew(const LLSD& notification, const LLSD& response)
 {
-	LLPanelAvatarClassified* self = (LLPanelAvatarClassified*)data;
-
+	S32 option = LLNotification::getSelectedOption(notification, response);
 	if (0 == option)
 	{
 		LLPanelClassified* panel_classified = new LLPanelClassified(false, false);
 		panel_classified->initNewClassified();
-		LLTabContainer*	tabs = self->getChild<LLTabContainer>("classified tab");
+		LLTabContainer*	tabs = getChild<LLTabContainer>("classified tab");
 		if(tabs)
 		{
 			tabs->addTabPanel(panel_classified, panel_classified->getClassifiedName());
 			tabs->selectLastTab();
 		}
 	}
+	return false;
 }
 
 
@@ -966,18 +969,17 @@ void LLPanelAvatarClassified::onClickDelete(void* data)
 	}
 	if (!panel_classified) return;
 
-	LLStringUtil::format_map_t args;
-	args["[NAME]"] = panel_classified->getClassifiedName();
-	gViewerWindow->alertXml("DeleteClassified", args, callbackDelete, self);
+	LLSD args;
+	args["NAME"] = panel_classified->getClassifiedName();
+	LLNotifications::instance().add("DeleteClassified", args, LLSD(), boost::bind(&LLPanelAvatarClassified::callbackDelete, self, _1, _2));
 		
 }
 
 
-// static
-void LLPanelAvatarClassified::callbackDelete(S32 option, void* data)
+bool  LLPanelAvatarClassified::callbackDelete(const LLSD& notification, const LLSD& response)
 {
-	LLPanelAvatarClassified* self = (LLPanelAvatarClassified*)data;
-	LLTabContainer*	tabs = self->getChild<LLTabContainer>("classified tab");
+	S32 option = LLNotification::getSelectedOption(notification, response);
+	LLTabContainer*	tabs = getChild<LLTabContainer>("classified tab");
 	LLPanelClassified* panel_classified=NULL;
 	if(tabs)
 	{
@@ -986,7 +988,7 @@ void LLPanelAvatarClassified::callbackDelete(S32 option, void* data)
 	
 	LLMessageSystem* msg = gMessageSystem;
 
-	if (!panel_classified) return;
+	if (!panel_classified) return false;
 
 	if (0 == option)
 	{
@@ -1005,6 +1007,7 @@ void LLPanelAvatarClassified::callbackDelete(S32 option, void* data)
 		delete panel_classified;
 		panel_classified = NULL;
 	}
+	return false;
 }
 
 
@@ -1124,24 +1127,23 @@ void LLPanelAvatarPicks::onClickDelete(void* data)
 
 	if (!panel_pick) return;
 
-	LLStringUtil::format_map_t args;
-	args["[PICK]"] = panel_pick->getPickName();
+	LLSD args;
+	args["PICK"] = panel_pick->getPickName();
 
-	gViewerWindow->alertXml("DeleteAvatarPick", args,
-		callbackDelete,
-		self);
+	LLNotifications::instance().add("DeleteAvatarPick", args, LLSD(),
+									boost::bind(&LLPanelAvatarPicks::callbackDelete, self, _1, _2));
 }
 
 
 // static
-void LLPanelAvatarPicks::callbackDelete(S32 option, void* data)
+bool LLPanelAvatarPicks::callbackDelete(const LLSD& notification, const LLSD& response)
 {
-	LLPanelAvatarPicks* self = (LLPanelAvatarPicks*)data;
-	LLTabContainer* tabs = self->getChild<LLTabContainer>("picks tab");
-	LLPanelPick* panel_pick = tabs?(LLPanelPick*)tabs->getCurrentPanel():NULL;
+	S32 option = LLNotification::getSelectedOption(notification, response);
+	LLTabContainer* tabs = getChild<LLTabContainer>("picks tab");
+	LLPanelPick* panel_pick = tabs ? (LLPanelPick*)tabs->getCurrentPanel() : NULL;
 	LLMessageSystem* msg = gMessageSystem;
 
-	if (!panel_pick) return;
+	if (!panel_pick) return false;
 
 	if (0 == option)
 	{
@@ -1177,6 +1179,7 @@ void LLPanelAvatarPicks::callbackDelete(S32 option, void* data)
 		delete panel_pick;
 		panel_pick = NULL;
 	}
+	return false;
 }
 
 
@@ -1835,7 +1838,7 @@ void LLPanelAvatar::processAvatarPropertiesReply(LLMessageSystem *msg, void**)
 				args["[PAYMENTINFO]"] = self->mPanelSecondLife->getString(payment_text);
 				std::string age_text = age_verified ? "AgeVerified" : "NotAgeVerified";
 				// Do not display age verification status at this time
-				//args["[AGEVERIFICATION]"] = self->mPanelSecondLife->getString(age_text);
+				//args["[[AGEVERIFICATION]]"] = self->mPanelSecondLife->getString(age_text);
 				args["[AGEVERIFICATION]"] = " ";
 			}
 			else
@@ -2187,85 +2190,93 @@ void LLPanelAvatar::onClickKick(void* userdata)
 	gFloaterView->getNewFloaterPosition(&left, &top);
 	LLRect rect(left, top, left+400, top-300);
 
-	gViewerWindow->alertXmlEditText("KickUser", LLStringUtil::format_map_t(),
-									NULL, NULL,
-									LLPanelAvatar::finishKick, self);
+	LLSD payload;
+	payload["avatar_id"] = self->mAvatarID;
+	LLNotifications::instance().add("KickUser", LLSD(), payload, finishKick);
 }
 
-// static
-void LLPanelAvatar::finishKick(S32 option, const std::string& text, void* userdata)
+//static
+bool LLPanelAvatar::finishKick(const LLSD& notification, const LLSD& response)
 {
-	LLPanelAvatar* self = (LLPanelAvatar*) userdata;
+	S32 option = LLNotification::getSelectedOption(notification, response);
 
 	if (option == 0)
 	{
+		LLUUID avatar_id = notification["payload"]["avatar_id"].asUUID();
 		LLMessageSystem* msg = gMessageSystem;
 
 		msg->newMessageFast(_PREHASH_GodKickUser);
 		msg->nextBlockFast(_PREHASH_UserInfo);
 		msg->addUUIDFast(_PREHASH_GodID,		gAgent.getID() );
 		msg->addUUIDFast(_PREHASH_GodSessionID, gAgent.getSessionID());
-		msg->addUUIDFast(_PREHASH_AgentID,   self->mAvatarID );
+		msg->addUUIDFast(_PREHASH_AgentID,   avatar_id );
 		msg->addU32("KickFlags", KICK_FLAGS_DEFAULT );
-		msg->addStringFast(_PREHASH_Reason,    text );
+		msg->addStringFast(_PREHASH_Reason,    response["message"].asString() );
 		gAgent.sendReliableMessage();
 	}
+	return false;
 }
 
 // static
 void LLPanelAvatar::onClickFreeze(void* userdata)
 {
-	gViewerWindow->alertXmlEditText("FreezeUser", LLStringUtil::format_map_t(),
-									NULL, NULL,
-									LLPanelAvatar::finishFreeze, userdata);
+	LLPanelAvatar* self = (LLPanelAvatar*) userdata;
+	LLSD payload;
+	payload["avatar_id"] = self->mAvatarID;
+	LLNotifications::instance().add("FreezeUser", LLSD(), payload, LLPanelAvatar::finishFreeze);
 }
 
 // static
-void LLPanelAvatar::finishFreeze(S32 option, const std::string& text, void* userdata)
+bool LLPanelAvatar::finishFreeze(const LLSD& notification, const LLSD& response)
 {
-	LLPanelAvatar* self = (LLPanelAvatar*) userdata;
+	S32 option = LLNotification::getSelectedOption(notification, response);
 
 	if (option == 0)
 	{
+		LLUUID avatar_id = notification["payload"]["avatar_id"].asUUID();
 		LLMessageSystem* msg = gMessageSystem;
 
 		msg->newMessageFast(_PREHASH_GodKickUser);
 		msg->nextBlockFast(_PREHASH_UserInfo);
 		msg->addUUIDFast(_PREHASH_GodID,		gAgent.getID() );
 		msg->addUUIDFast(_PREHASH_GodSessionID, gAgent.getSessionID());
-		msg->addUUIDFast(_PREHASH_AgentID,   self->mAvatarID );
+		msg->addUUIDFast(_PREHASH_AgentID,   avatar_id );
 		msg->addU32("KickFlags", KICK_FLAGS_FREEZE );
-		msg->addStringFast(_PREHASH_Reason,    text );
+		msg->addStringFast(_PREHASH_Reason, response["message"].asString() );
 		gAgent.sendReliableMessage();
 	}
+	return false;
 }
 
 // static
 void LLPanelAvatar::onClickUnfreeze(void* userdata)
 {
-	gViewerWindow->alertXmlEditText("UnFreezeUser", LLStringUtil::format_map_t(),
-									NULL, NULL,
-									LLPanelAvatar::finishUnfreeze, userdata);
+	LLPanelAvatar* self = (LLPanelAvatar*) userdata;
+	LLSD payload;
+	payload["avatar_id"] = self->mAvatarID;
+	LLNotifications::instance().add("UnFreezeUser", LLSD(), payload, LLPanelAvatar::finishUnfreeze);
 }
 
 // static
-void LLPanelAvatar::finishUnfreeze(S32 option, const std::string& text, void* userdata)
+bool LLPanelAvatar::finishUnfreeze(const LLSD& notification, const LLSD& response)
 {
-	LLPanelAvatar* self = (LLPanelAvatar*) userdata;
-
+	S32 option = LLNotification::getSelectedOption(notification, response);
+	std::string text = response["message"].asString();
 	if (option == 0)
 	{
+		LLUUID avatar_id = notification["payload"]["avatar_id"].asUUID();
 		LLMessageSystem* msg = gMessageSystem;
 
 		msg->newMessageFast(_PREHASH_GodKickUser);
 		msg->nextBlockFast(_PREHASH_UserInfo);
 		msg->addUUIDFast(_PREHASH_GodID,		gAgent.getID() );
 		msg->addUUIDFast(_PREHASH_GodSessionID, gAgent.getSessionID());
-		msg->addUUIDFast(_PREHASH_AgentID,   self->mAvatarID );
+		msg->addUUIDFast(_PREHASH_AgentID,   avatar_id );
 		msg->addU32("KickFlags", KICK_FLAGS_UNFREEZE );
 		msg->addStringFast(_PREHASH_Reason,    text );
 		gAgent.sendReliableMessage();
 	}
+	return false;
 }
 
 // static
diff --git a/indra/newview/llpanelavatar.h b/indra/newview/llpanelavatar.h
index 833b1243890..b7f9c696873 100644
--- a/indra/newview/llpanelavatar.h
+++ b/indra/newview/llpanelavatar.h
@@ -117,7 +117,7 @@ class LLPanelAvatarSecondLife
 	static void onDoubleClickGroup(void* userdata);
 	static void onClickPublishHelp(void *userdata);
 	static void onClickPartnerHelp(void *userdata);
-	static void onClickPartnerHelpLoadURL(S32 option, void* userdata);
+	static bool onClickPartnerHelpLoadURL(const LLSD& notification, const LLSD& response);
 	static void onClickPartnerInfo(void *userdata);
 
 	// Clear out the controls anticipating new network data.
@@ -231,8 +231,8 @@ class LLPanelAvatarClassified : public LLPanelAvatarTab
 	static void onClickNew(void* data);
 	static void onClickDelete(void* data);
 
-	static void callbackDelete(S32 option, void* data);
-	static void callbackNew(S32 option, void* data);
+	bool callbackDelete(const LLSD& notification, const LLSD& response);
+	bool callbackNew(const LLSD& notification, const LLSD& response);
 };
 
 
@@ -257,7 +257,7 @@ class LLPanelAvatarPicks : public LLPanelAvatarTab
 	static void onClickNew(void* data);
 	static void onClickDelete(void* data);
 
-	static void callbackDelete(S32 option, void* data);
+	bool callbackDelete(const LLSD& notification, const LLSD& response);
 };
 
 
@@ -325,9 +325,9 @@ class LLPanelAvatar : public LLPanel
 private:
 	void enableOKIfReady();
 
-	static void finishKick(S32 option, const std::string& text, void* userdata);
-	static void finishFreeze(S32 option, const std::string& text, void* userdata);
-	static void finishUnfreeze(S32 option, const std::string& text, void* userdata);
+	static bool finishKick(const LLSD& notification, const LLSD& response);
+	static bool finishFreeze(const LLSD& notification, const LLSD& response);
+	static bool finishUnfreeze(const LLSD& notification, const LLSD& response);
 
 	static void showProfileCallback(S32 option, void *userdata);
 
diff --git a/indra/newview/llpanelclassified.cpp b/indra/newview/llpanelclassified.cpp
index 64cc19e2fd5..e50f2649af2 100644
--- a/indra/newview/llpanelclassified.cpp
+++ b/indra/newview/llpanelclassified.cpp
@@ -317,12 +317,12 @@ BOOL LLPanelClassified::titleIsValid()
 	const std::string& name = mNameEditor->getText();
 	if (name.empty())
 	{
-		gViewerWindow->alertXml("BlankClassifiedName");
+		LLNotifications::instance().add("BlankClassifiedName");
 		return FALSE;
 	}
 	if (!isalnum(name[0]))
 	{
-		gViewerWindow->alertXml("ClassifiedMustBeAlphanumeric");
+		LLNotifications::instance().add("ClassifiedMustBeAlphanumeric");
 		return FALSE;
 	}
 
@@ -339,31 +339,24 @@ void LLPanelClassified::apply()
 	}
 }
 
-
-// static
-void LLPanelClassified::saveCallback(S32 option, void* data)
+bool LLPanelClassified::saveCallback(const LLSD& notification, const LLSD& response)
 {
-	LLPanelClassified* self = (LLPanelClassified*)data;
+	S32 option = LLNotification::getSelectedOption(notification, response);
+
 	switch(option)
 	{
 		case 0: // Save
-			self->sendClassifiedInfoUpdate();
+			sendClassifiedInfoUpdate();
 			// fall through to close
 
 		case 1: // Don't Save
 			{
-				self->mForceClose = true;
+				mForceClose = true;
 				// Close containing floater
-				LLView* view = self;
-				while (view)
+				LLFloater* parent_floater = gFloaterView->getParentFloater(this);
+				if (parent_floater)
 				{
-					LLFloater* floaterp = dynamic_cast<LLFloater*>(view);
-					if (floaterp)
-					{
-						floaterp->close();
-						break;
-					}
-					view = view->getParent();
+					parent_floater->close();
 				}
 			}
 			break;
@@ -373,16 +366,18 @@ void LLPanelClassified::saveCallback(S32 option, void* data)
             LLAppViewer::instance()->abortQuit();
 			break;
 	}
+	return false;
 }
 
+
 BOOL LLPanelClassified::canClose()
 {
 	if (mForceClose || !checkDirty()) 
 		return TRUE;
 
-	LLStringUtil::format_map_t args;
-	args["[NAME]"] = mNameEditor->getText();
-	LLAlertDialog::showXml("ClassifiedSave", args, saveCallback, this);
+	LLSD args;
+	args["NAME"] = mNameEditor->getText();
+	LLNotifications::instance().add("ClassifiedSave", args, LLSD(), boost::bind(&LLPanelClassified::saveCallback, this, _1, _2));
 	return FALSE;
 }
 
@@ -785,8 +780,11 @@ void LLPanelClassified::onClickUpdate(void* data)
 	// If user has not set mature, do not allow publish
 	if(self->mMatureCombo->getCurrentIndex() == DECLINE_TO_STATE)
 	{
-		LLStringUtil::format_map_t args;
-		gViewerWindow->alertXml("SetClassifiedMature", &callbackConfirmMature, self);
+		// Tell user about it
+		LLNotifications::instance().add("SetClassifiedMature", 
+				LLSD(), 
+				LLSD(), 
+				boost::bind(&LLPanelClassified::confirmMature, self, _1, _2));
 		return;
 	}
 
@@ -794,16 +792,11 @@ void LLPanelClassified::onClickUpdate(void* data)
 	self->gotMature();
 }
 
-// static
-void LLPanelClassified::callbackConfirmMature(S32 option, void* data)
-{
-	LLPanelClassified* self = (LLPanelClassified*)data;
-	self->confirmMature(option);
-}
-
-// invoked from callbackConfirmMature
-void LLPanelClassified::confirmMature(S32 option)
+// Callback from a dialog indicating response to mature notification
+bool LLPanelClassified::confirmMature(const LLSD& notification, const LLSD& response)
 {
+	S32 option = LLNotification::getSelectedOption(notification, response);
+	
 	// 0 == Yes
 	// 1 == No
 	// 2 == Cancel
@@ -816,11 +809,12 @@ void LLPanelClassified::confirmMature(S32 option)
 		mMatureCombo->setCurrentByIndex(NON_MATURE_CONTENT);
 		break;
 	default:
-		return;
+		return false;
 	}
 	
 	// If we got here it means they set a valid value
 	gotMature();
+	return false;
 }
 
 // Called after we have determined whether this classified has
@@ -830,7 +824,9 @@ void LLPanelClassified::gotMature()
 	// if already paid for, just do the update
 	if (mPaidFor)
 	{
-		callbackConfirmPublish(0, this);
+		LLNotification::Params params("PublishClassified");
+		params.functor(boost::bind(&LLPanelClassified::confirmPublish, this, _1, _2));
+		LLNotifications::instance().forceResponse(params, 0);
 	}
 	else
 	{
@@ -850,11 +846,11 @@ void LLPanelClassified::callbackGotPriceForListing(S32 option, std::string text,
 	S32 price_for_listing = strtol(text.c_str(), NULL, 10);
 	if (price_for_listing < MINIMUM_PRICE_FOR_LISTING)
 	{
-		LLStringUtil::format_map_t args;
+		LLSD args;
 		std::string price_text = llformat("%d", MINIMUM_PRICE_FOR_LISTING);
-		args["[MIN_PRICE]"] = price_text;
+		args["MIN_PRICE"] = price_text;
 			
-		gViewerWindow->alertXml("MinClassifiedPrice", args);
+		LLNotifications::instance().add("MinClassifiedPrice", args);
 		return;
 	}
 
@@ -862,10 +858,10 @@ void LLPanelClassified::callbackGotPriceForListing(S32 option, std::string text,
 	// update send
 	self->mPriceForListing = price_for_listing;
 
-	LLStringUtil::format_map_t args;
-	args["[AMOUNT]"] = llformat("%d", price_for_listing);
-	gViewerWindow->alertXml("PublishClassified", args, &callbackConfirmPublish, self);
-
+	LLSD args;
+	args["AMOUNT"] = llformat("%d", price_for_listing);
+	LLNotifications::instance().add("PublishClassified", args, LLSD(), 
+									boost::bind(&LLPanelClassified::confirmPublish, self, _1, _2));
 }
 
 void LLPanelClassified::resetDirty()
@@ -889,10 +885,11 @@ void LLPanelClassified::resetDirty()
 }
 
 // invoked from callbackConfirmPublish
-void LLPanelClassified::confirmPublish(S32 option)
+bool LLPanelClassified::confirmPublish(const LLSD& notification, const LLSD& response)
 {
+	S32 option = LLNotification::getSelectedOption(notification, response);
 	// Option 0 = publish
-	if (option != 0) return;
+	if (option != 0) return false;
 
 	sendClassifiedInfoUpdate();
 
@@ -911,14 +908,9 @@ void LLPanelClassified::confirmPublish(S32 option)
 	}
 
 	resetDirty();
+	return false;
 }
 
-// static
-void LLPanelClassified::callbackConfirmPublish(S32 option, void* data)
-{
-	LLPanelClassified* self = (LLPanelClassified*)data;
-	self->confirmPublish(option);
-}
 
 // static
 void LLPanelClassified::onClickTeleport(void* data)
diff --git a/indra/newview/llpanelclassified.h b/indra/newview/llpanelclassified.h
index ee84d89f43f..f808eb99133 100644
--- a/indra/newview/llpanelclassified.h
+++ b/indra/newview/llpanelclassified.h
@@ -100,17 +100,15 @@ class LLPanelClassified : public LLPanel
     static void processClassifiedInfoReply(LLMessageSystem* msg, void**);
 
 	// Confirmation dialogs flow in this order
-	static void callbackConfirmMature(S32 option, void* data);
-	void confirmMature(S32 option);
+	bool confirmMature(const LLSD& notification, const LLSD& response);
 	void gotMature();
 	static void callbackGotPriceForListing(S32 option, std::string text, void* data);
-	static void callbackConfirmPublish(S32 option, void* data);
-	void confirmPublish(S32 option);
+	bool confirmPublish(const LLSD& notification, const LLSD& response);
 
 	void sendClassifiedClickMessage(const std::string& type);
 
 protected:
-	static void saveCallback(S32 option, void* data);
+	bool saveCallback(const LLSD& notification, const LLSD& response);
 
 	static void onClickUpdate(void* data);
     static void onClickTeleport(void* data);
diff --git a/indra/newview/llpanelgroup.cpp b/indra/newview/llpanelgroup.cpp
index 2d5f789141d..6233740d53e 100644
--- a/indra/newview/llpanelgroup.cpp
+++ b/indra/newview/llpanelgroup.cpp
@@ -45,6 +45,7 @@
 #include "lluictrlfactory.h"
 #include "llviewerwindow.h"
 #include "llappviewer.h"
+#include "llnotifications.h"
 
 // static
 void* LLPanelGroupTab::createTab(void* data)
@@ -115,17 +116,12 @@ void LLPanelGroupTab::handleClickHelp()
 	std::string help_text( getHelpText() );
 	if ( !help_text.empty() )
 	{
-		LLStringUtil::format_map_t args;
-		args["[MESSAGE]"] = help_text;
-		LLAlertDialog* dialogp = gViewerWindow->alertXml("GenericAlert", args);
-		if (dialogp)
-		{
-			LLFloater* root_floater = gFloaterView->getParentFloater(this);;
-			if (root_floater)
-			{
-				root_floater->addDependentFloater(dialogp);
-			}
-		}
+		LLSD args;
+		args["MESSAGE"] = help_text;
+		LLFloater* parent_floater = gFloaterView->getParentFloater(this);
+		LLNotification::Params params(parent_floater->contextualNotification("GenericAlert"));
+		params.substitutions(args);
+		LLNotifications::instance().add(params);
 	}
 }
 
@@ -411,11 +407,11 @@ BOOL LLPanelGroup::attemptTransition()
 			mesg = mDefaultNeedsApplyMesg;
 		}
 		// Create a notify box, telling the user about the unapplied tab.
-		LLStringUtil::format_map_t args;
-		args["[NEEDS_APPLY_MESSAGE]"] = mesg;
-		args["[WANT_APPLY_MESSAGE]"] = mWantApplyMesg;
-		gViewerWindow->alertXml("PanelGroupApply", args,
-								onNotifyCallback, (void*) this);
+		LLSD args;
+		args["NEEDS_APPLY_MESSAGE"] = mesg;
+		args["WANT_APPLY_MESSAGE"] = mWantApplyMesg;
+		LLNotifications::instance().add("PanelGroupApply", args, LLSD(),
+			boost::bind(&LLPanelGroup::handleNotifyCallback, this, _1, _2));
 		mShowingNotifyDialog = TRUE;
 		
 		// We need to reselect the current tab, since it isn't finished.
@@ -465,18 +461,9 @@ void LLPanelGroup::transitionToTab()
 	}
 }
 
-// static
-void LLPanelGroup::onNotifyCallback(S32 option, void* user_data)
-{
-	LLPanelGroup* self = static_cast<LLPanelGroup*>(user_data);
-	if (self)
-	{
-		self->handleNotifyCallback(option);
-	}
-}
-
-void LLPanelGroup::handleNotifyCallback(S32 option)
+bool LLPanelGroup::handleNotifyCallback(const LLSD& notification, const LLSD& response)
 {
+	S32 option = LLNotification::getSelectedOption(notification, response);
 	mShowingNotifyDialog = FALSE;
 	switch (option)
 	{
@@ -512,6 +499,7 @@ void LLPanelGroup::handleNotifyCallback(S32 option)
 		LLAppViewer::instance()->abortQuit();
 		break;
 	}
+	return false;
 }
 
 // static
@@ -568,9 +556,9 @@ bool LLPanelGroup::apply()
 	// Inform the user.
 	if ( !apply_mesg.empty() )
 	{
-		LLStringUtil::format_map_t args;
-		args["[MESSAGE]"] = apply_mesg;
-		gViewerWindow->alertXml("GenericAlert", args);
+		LLSD args;
+		args["MESSAGE"] = apply_mesg;
+		LLNotifications::instance().add("GenericAlert", args);
 	}
 
 	return false;
@@ -638,7 +626,7 @@ void LLPanelGroup::showNotice(const std::string& subject,
 		// We need to clean up that inventory offer.
 		if (inventory_offer)
 		{
-			inventory_offer_callback( IOR_DECLINE , inventory_offer); 
+			inventory_offer->forceResponse(IOR_DECLINE);
 		}
 		return;
 	}
diff --git a/indra/newview/llpanelgroup.h b/indra/newview/llpanelgroup.h
index f27ef75843d..946448a2245 100644
--- a/indra/newview/llpanelgroup.h
+++ b/indra/newview/llpanelgroup.h
@@ -87,8 +87,7 @@ class LLPanelGroup : public LLPanel,
 	void updateTabVisibility();
 
 	// Used by attemptTransition to query the user's response to a tab that needs to apply. 
-	static void onNotifyCallback(S32 option, void* user_data);
-	void handleNotifyCallback(S32 option);
+	bool handleNotifyCallback(const LLSD& notification, const LLSD& response);
 
 	bool apply();
 	void refreshData();
diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp
index 044ad280fa6..f6f262f2bed 100644
--- a/indra/newview/llpanelgroupgeneral.cpp
+++ b/indra/newview/llpanelgroupgeneral.cpp
@@ -344,18 +344,18 @@ void LLPanelGroupGeneral::onClickJoin(void *userdata)
 	if (gdatap)
 	{
 		S32 cost = gdatap->mMembershipFee;
-		LLStringUtil::format_map_t args;
-		args["[COST]"] = llformat("%d", cost);
-		
+		LLSD args;
+		args["COST"] = llformat("%d", cost);
+		LLSD payload;
+		payload["group_id"] = self->mGroupID;
+
 		if (can_afford_transaction(cost))
 		{
-			gViewerWindow->alertXml("JoinGroupCanAfford", args,
-						LLPanelGroupGeneral::joinDlgCB,
-						self);
+			LLNotifications::instance().add("JoinGroupCanAfford", args, payload, LLPanelGroupGeneral::joinDlgCB);
 		}
 		else
 		{
-			gViewerWindow->alertXml("JoinGroupCannotAfford", args);
+			LLNotifications::instance().add("JoinGroupCannotAfford", args, payload);
 		}
 	}
 	else
@@ -366,17 +366,18 @@ void LLPanelGroupGeneral::onClickJoin(void *userdata)
 }
 
 // static
-void LLPanelGroupGeneral::joinDlgCB(S32 which, void *userdata)
+bool LLPanelGroupGeneral::joinDlgCB(const LLSD& notification, const LLSD& response)
 {
-	LLPanelGroupGeneral* self = (LLPanelGroupGeneral*) userdata;
+	S32 option = LLNotification::getSelectedOption(notification, response);
 
-	if (which == 1 || !self)
+	if (option == 1)
 	{
 		// user clicked cancel
-		return;
+		return false;
 	}
 
-	LLGroupMgr::getInstance()->sendGroupMemberJoin(self->mGroupID);
+	LLGroupMgr::getInstance()->sendGroupMemberJoin(notification["payload"]["group_id"].asUUID());
+	return false;
 }
 
 // static
@@ -444,9 +445,8 @@ bool LLPanelGroupGeneral::apply(std::string& mesg)
 		if(mComboMature &&
 		   mComboMature->getCurrentIndex() == DECLINE_TO_STATE)
 		{
-			LLStringUtil::format_map_t args;
-			gViewerWindow->alertXml("SetGroupMature", &callbackConfirmMatureApply,
-				new LLHandle<LLPanel>(getHandle()));
+			LLNotifications::instance().add("SetGroupMature", LLSD(), LLSD(), 
+											boost::bind(&LLPanelGroupGeneral::confirmMatureApply, this, _1, _2));
 			return false;
 		}
 
@@ -464,10 +464,9 @@ bool LLPanelGroupGeneral::apply(std::string& mesg)
 				return false;
 			}
 
-			LLStringUtil::format_map_t args;
-			args["[MESSAGE]"] = mConfirmGroupCreateStr;
-			gViewerWindow->alertXml("GenericAlertYesCancel", args,
-				createGroupCallback, new LLHandle<LLPanel>(getHandle()) );
+			LLSD args;
+			args["MESSAGE"] = mConfirmGroupCreateStr;
+			LLNotifications::instance().add("GenericAlertYesCancel", args, LLSD(), boost::bind(&LLPanelGroupGeneral::createGroupCallback, this, _1, _2));
 
 			return false;
 		}
@@ -545,22 +544,10 @@ void LLPanelGroupGeneral::cancel()
 	notifyObservers();
 }
 
-
-// static
-void LLPanelGroupGeneral::callbackConfirmMatureApply(S32 option, void* data)
-{
-	LLHandle<LLPanel>* handlep = (LLHandle<LLPanel>*)data;
-	LLPanelGroupGeneral* self = dynamic_cast<LLPanelGroupGeneral*>(handlep->get());
-	delete handlep;
-	if (self)
-	{
-		self->confirmMatureApply(option);
-	}
-}
-
 // invoked from callbackConfirmMature
-void LLPanelGroupGeneral::confirmMatureApply(S32 option)
+bool LLPanelGroupGeneral::confirmMatureApply(const LLSD& notification, const LLSD& response)
 {
+	S32 option = LLNotification::getSelectedOption(notification, response);
 	// 0 == Yes
 	// 1 == No
 	// 2 == Cancel
@@ -573,39 +560,35 @@ void LLPanelGroupGeneral::confirmMatureApply(S32 option)
 		mComboMature->setCurrentByIndex(NON_MATURE_CONTENT);
 		break;
 	default:
-		return;
+		return false;
 	}
 
 	// If we got here it means they set a valid value
 	std::string mesg = "";
 	apply(mesg);
+	return false;
 }
 
 // static
-void LLPanelGroupGeneral::createGroupCallback(S32 option, void* userdata)
+bool LLPanelGroupGeneral::createGroupCallback(const LLSD& notification, const LLSD& response)
 {
-	LLHandle<LLPanel> panel_handle = *(LLHandle<LLPanel>*)userdata;
-	delete (LLHandle<LLPanel>*)userdata;
-
-	LLPanelGroupGeneral* self = dynamic_cast<LLPanelGroupGeneral*>(panel_handle.get());
-	if (!self) return;
-
+	S32 option = LLNotification::getSelectedOption(notification, response);
 	switch(option)
 	{
 	case 0:
 		{
 			// Yay!  We are making a new group!
-			U32 enrollment_fee = (self->mCtrlEnrollmentFee->get() ? 
-									(U32) self->mSpinEnrollmentFee->get() : 0);
+			U32 enrollment_fee = (mCtrlEnrollmentFee->get() ? 
+									(U32) mSpinEnrollmentFee->get() : 0);
 		
-			LLGroupMgr::getInstance()->sendCreateGroupRequest(self->mGroupNameEditor->getText(),
-												self->mEditCharter->getText(),
-												self->mCtrlShowInGroupList->get(),
-												self->mInsignia->getImageAssetID(),
+			LLGroupMgr::getInstance()->sendCreateGroupRequest(mGroupNameEditor->getText(),
+												mEditCharter->getText(),
+												mCtrlShowInGroupList->get(),
+												mInsignia->getImageAssetID(),
 												enrollment_fee,
-												self->mCtrlOpenEnrollment->get(),
+												mCtrlOpenEnrollment->get(),
 												false,
-												self->mComboMature->getCurrentIndex() == MATURE_CONTENT);
+												mComboMature->getCurrentIndex() == MATURE_CONTENT);
 
 		}
 		break;
@@ -613,6 +596,7 @@ void LLPanelGroupGeneral::createGroupCallback(S32 option, void* userdata)
 	default:
 		break;
 	}
+	return false;
 }
 
 static F32 sSDTime = 0.0f;
diff --git a/indra/newview/llpanelgroupgeneral.h b/indra/newview/llpanelgroupgeneral.h
index 982d0678dd7..c38594ef0de 100644
--- a/indra/newview/llpanelgroupgeneral.h
+++ b/indra/newview/llpanelgroupgeneral.h
@@ -57,8 +57,7 @@ class LLPanelGroupGeneral : public LLPanelGroupTab
 	virtual bool needsApply(std::string& mesg);
 	virtual bool apply(std::string& mesg);
 	virtual void cancel();
-	static void createGroupCallback(S32 option, void* user_data);
-	static void callbackConfirmMatureApply(S32 option, void* data);
+	bool createGroupCallback(const LLSD& notification, const LLSD& response);
 	
 	virtual void update(LLGroupChange gc);
 	
@@ -77,11 +76,11 @@ class LLPanelGroupGeneral : public LLPanelGroupTab
 	static void onReceiveNotices(LLUICtrl* ctrl, void* data);
 	static void openProfile(void* data);
 
-    static void joinDlgCB(S32 which, void *userdata);
+    static bool joinDlgCB(const LLSD& notification, const LLSD& response);
 
 	void updateMembers();
 	void updateChanged();
-	void confirmMatureApply(S32 option);
+	bool confirmMatureApply(const LLSD& notification, const LLSD& response);
 
 	BOOL			mPendingMemberUpdate;
 	BOOL			mChanged;
diff --git a/indra/newview/llpanelgroupinvite.cpp b/indra/newview/llpanelgroupinvite.cpp
index c4af61587c4..70440dd75aa 100644
--- a/indra/newview/llpanelgroupinvite.cpp
+++ b/indra/newview/llpanelgroupinvite.cpp
@@ -66,7 +66,7 @@ class LLPanelGroupInvite::impl
 	static void callbackAddUsers(const std::vector<std::string>& names,
 								 const std::vector<LLUUID>& agent_ids,
 								 void* user_data);
-	static void inviteOwnerCallback(S32 option, void* userdata);
+	bool inviteOwnerCallback(const LLSD& notification, const LLSD& response);
 
 public:
 	LLUUID mGroupID;
@@ -158,9 +158,9 @@ void LLPanelGroupInvite::impl::submitInvitations()
 		// owner role: display confirmation and wait for callback
 		if ((role_id == gdatap->mOwnerRole) && (!mConfirmedOwnerInvite))
 		{
-			LLStringUtil::format_map_t args;
-			args["[MESSAGE]"] = mOwnerWarning;
-			gViewerWindow->alertXml("GenericAlertYesCancel", args, inviteOwnerCallback, this);
+			LLSD args;
+			args["MESSAGE"] = mOwnerWarning;
+			LLNotifications::instance().add("GenericAlertYesCancel", args, LLSD(), boost::bind(&LLPanelGroupInvite::impl::inviteOwnerCallback, this, _1, _2));
 			return; // we'll be called again if user confirms
 		}
 	}
@@ -180,24 +180,23 @@ void LLPanelGroupInvite::impl::submitInvitations()
 	(*mCloseCallback)(mCloseCallbackUserData);
 }
 
-//static
-void LLPanelGroupInvite::impl::inviteOwnerCallback(S32 option, void* userdata)
+bool LLPanelGroupInvite::impl::inviteOwnerCallback(const LLSD& notification, const LLSD& response)
 {
-	LLPanelGroupInvite::impl* self = (LLPanelGroupInvite::impl*)userdata;
-	if (!self) return;
+	S32 option = LLNotification::getSelectedOption(notification, response);
 
 	switch(option)
 	{
 	case 0:
 		// user confirmed that they really want a new group owner
-		self->mConfirmedOwnerInvite = true;
-		self->submitInvitations();
+		mConfirmedOwnerInvite = true;
+		submitInvitations();
 		break;
 	case 1:
 		// fall through
 	default:
 		break;
 	}
+	return false;
 }
 
 
@@ -396,16 +395,14 @@ void LLPanelGroupInvite::addUsers(std::vector<LLUUID>& agent_ids)
 		if(dest && dest->isAvatar())
 		{
 			std::string fullname;
-			LLStringUtil::format_map_t args;
+			LLSD args;
 			LLNameValue* nvfirst = dest->getNVPair("FirstName");
 			LLNameValue* nvlast = dest->getNVPair("LastName");
 			if(nvfirst && nvlast)
 			{
-				args["[FIRST]"] = nvfirst->getString();
-				args["[LAST]"] = nvlast->getString();
-				fullname = nvfirst->getString();
-				fullname += " ";
-				fullname += nvlast->getString();
+				args["FIRST"] = std::string(nvfirst->getString());
+				args["LAST"] = std::string(nvlast->getString());
+				fullname = std::string(nvfirst->getString()) + " " + std::string(nvlast->getString());
 			}
 			if (!fullname.empty())
 			{
diff --git a/indra/newview/llpanelgroupnotices.cpp b/indra/newview/llpanelgroupnotices.cpp
index 18fcc9d291d..1b1a7e32a05 100644
--- a/indra/newview/llpanelgroupnotices.cpp
+++ b/indra/newview/llpanelgroupnotices.cpp
@@ -53,6 +53,7 @@
 #include "roles_constants.h"
 #include "llviewerwindow.h"
 #include "llviewermessage.h"
+#include "llnotifications.h"
 
 const S32 NOTICE_DATE_STRING_SIZE = 30;
 
@@ -195,7 +196,8 @@ LLPanelGroupNotices::~LLPanelGroupNotices()
 	if (mInventoryOffer)
 	{
 		// Cancel the inventory offer.
-		inventory_offer_callback( IOR_DECLINE , mInventoryOffer); 
+		mInventoryOffer->forceResponse(IOR_DECLINE);
+
 		mInventoryOffer = NULL;
 	}
 }
@@ -345,7 +347,7 @@ void LLPanelGroupNotices::onClickOpenAttachment(void* data)
 {
 	LLPanelGroupNotices* self = (LLPanelGroupNotices*)data;
 
-	inventory_offer_callback( IOR_ACCEPT , self->mInventoryOffer);
+	self->mInventoryOffer->forceResponse(IOR_ACCEPT);
 	self->mInventoryOffer = NULL;
 	self->mBtnOpenAttachment->setEnabled(FALSE);
 }
@@ -357,7 +359,7 @@ void LLPanelGroupNotices::onClickSendMessage(void* data)
 	if (self->mCreateSubject->getText().empty())
 	{
 		// Must supply a subject
-		gViewerWindow->alertXml("MustSpecifyGroupNoticeSubject");
+		LLNotifications::instance().add("MustSpecifyGroupNoticeSubject");
 		return;
 	}
 	send_group_notice(
@@ -384,7 +386,7 @@ void LLPanelGroupNotices::onClickNewMessage(void* data)
 
 	if (self->mInventoryOffer)
 	{
-		inventory_offer_callback( IOR_DECLINE , self->mInventoryOffer);
+		self->mInventoryOffer->forceResponse(IOR_DECLINE);
 		self->mInventoryOffer = NULL;
 	}
 
@@ -535,7 +537,7 @@ void LLPanelGroupNotices::showNotice(const std::string& subject,
 	if (mInventoryOffer)
 	{
 		// Cancel the inventory offer for the previously viewed notice
-		inventory_offer_callback( IOR_DECLINE , mInventoryOffer); 
+		mInventoryOffer->forceResponse(IOR_DECLINE); 
 		mInventoryOffer = NULL;
 	}
 
diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp
index 4b48fb35109..6fb601bf56e 100644
--- a/indra/newview/llpanelgrouproles.cpp
+++ b/indra/newview/llpanelgrouproles.cpp
@@ -237,11 +237,11 @@ BOOL LLPanelGroupRoles::attemptTransition()
 			mesg = mDefaultNeedsApplyMesg;
 		}
 		// Create a notify box, telling the user about the unapplied tab.
-		LLStringUtil::format_map_t args;
-		args["[NEEDS_APPLY_MESSAGE]"] = mesg;
-		args["[WANT_APPLY_MESSAGE]"] = mWantApplyMesg;
-		gViewerWindow->alertXml("PanelGroupApply", args,
-								onNotifyCallback, (void*) this);
+		LLSD args;
+		args["NEEDS_APPLY_MESSAGE"] = mesg;
+		args["WANT_APPLY_MESSAGE"] = mWantApplyMesg;
+		LLNotifications::instance().add("PanelGroupApply", args, LLSD(),
+			boost::bind(&LLPanelGroupRoles::handleNotifyCallback, this, _1, _2));
 		mHasModal = TRUE;
 		// We need to reselect the current tab, since it isn't finished.
 		if (mSubTabContainer)
@@ -282,18 +282,9 @@ void LLPanelGroupRoles::transitionToTab()
 	}
 }
 
-// static
-void LLPanelGroupRoles::onNotifyCallback(S32 option, void* user_data)
-{
-	LLPanelGroupRoles* self = static_cast<LLPanelGroupRoles*>(user_data);
-	if (self)
-	{
-		self->handleNotifyCallback(option);
-	}
-}
-
-void LLPanelGroupRoles::handleNotifyCallback(S32 option)
+bool LLPanelGroupRoles::handleNotifyCallback(const LLSD& notification, const LLSD& response)
 {
+	S32 option = LLNotification::getSelectedOption(notification, response);
 	mHasModal = FALSE;
 	switch (option)
 	{
@@ -307,9 +298,9 @@ void LLPanelGroupRoles::handleNotifyCallback(S32 option)
 			if ( !apply_mesg.empty() )
 			{
 				mHasModal = TRUE;
-				LLStringUtil::format_map_t args;
-				args["[MESSAGE]"] = apply_mesg;
-				gViewerWindow->alertXml("GenericAlert", args, onModalClose, (void*) this);
+				LLSD args;
+				args["MESSAGE"] = apply_mesg;
+				LLNotifications::instance().add("GenericAlert", args, LLSD(), boost::bind(&LLPanelGroupRoles::onModalClose, this, _1, _2));
 			}
 			// Skip switching tabs.
 			break;
@@ -337,16 +328,13 @@ void LLPanelGroupRoles::handleNotifyCallback(S32 option)
 		// Do nothing.  The user is canceling the action.
 		break;
 	}
+	return false;
 }
 
-// static
-void LLPanelGroupRoles::onModalClose(S32 option, void* user_data)
+bool LLPanelGroupRoles::onModalClose(const LLSD& notification, const LLSD& response)
 {
-	LLPanelGroupRoles* self = static_cast<LLPanelGroupRoles*>(user_data);
-	if (self)
-	{
-		self->mHasModal = FALSE;
-	}
+	mHasModal = FALSE;
+	return false;
 }
 
 
@@ -1375,16 +1363,16 @@ bool LLPanelGroupMembersSubTab::apply(std::string& mesg)
 		if ( mNumOwnerAdditions > 0 )
 		{
 			LLRoleData rd;
-			LLStringUtil::format_map_t args;
+			LLSD args;
 
 			if ( gdatap->getRoleData(gdatap->mOwnerRole, rd) )
 			{
 				mHasModal = TRUE;
-				args["[ROLE_NAME]"] = rd.mRoleName;
-				gViewerWindow->alertXml("AddGroupOwnerWarning",
+				args["ROLE_NAME"] = rd.mRoleName;
+				LLNotifications::instance().add("AddGroupOwnerWarning",
 										args,
-										addOwnerCB,
-										this);
+										LLSD(),
+										boost::bind(&LLPanelGroupMembersSubTab::addOwnerCB, this, _1, _2));
 			}
 			else
 			{
@@ -1404,20 +1392,17 @@ bool LLPanelGroupMembersSubTab::apply(std::string& mesg)
 	return true;
 }
 
-//static
-void LLPanelGroupMembersSubTab::addOwnerCB(S32 option, void* data)
+bool LLPanelGroupMembersSubTab::addOwnerCB(const LLSD& notification, const LLSD& response)
 {
-	LLPanelGroupMembersSubTab* self = (LLPanelGroupMembersSubTab*) data;
-
-	if (!self) return;
-	
-	self->mHasModal = FALSE;
+	S32 option = LLNotification::getSelectedOption(notification, response);
+	mHasModal = FALSE;
 
 	if (0 == option)
 	{
 		// User clicked "Yes"
-		self->applyMemberChanges();
+		applyMemberChanges();
 	}
+	return false;
 }
 
 void LLPanelGroupMembersSubTab::applyMemberChanges()
@@ -2225,22 +2210,19 @@ void LLPanelGroupRolesSubTab::handleActionCheck(LLCheckBoxCtrl* check, bool forc
 			check->set(FALSE);
 
 			LLRoleData rd;
-			LLStringUtil::format_map_t args;
+			LLSD args;
 
 			if ( gdatap->getRoleData(role_id, rd) )
 			{
-				args["[ACTION_NAME]"] = rap->mDescription;
-				args["[ROLE_NAME]"] = rd.mRoleName;
-				struct ActionCBData* cb_data = new ActionCBData;
-				cb_data->mSelf = this;
-				cb_data->mCheck = check;
+				args["ACTION_NAME"] = rap->mDescription;
+				args["ROLE_NAME"] = rd.mRoleName;
 				mHasModal = TRUE;
 				std::string warning = "AssignDangerousActionWarning";
 				if (GP_ROLE_CHANGE_ACTIONS == power)
 				{
 					warning = "AssignDangerousAbilityWarning";
 				}
-				gViewerWindow->alertXml(warning, args, addActionCB, cb_data);
+				LLNotifications::instance().add(warning, args, LLSD(), boost::bind(&LLPanelGroupRolesSubTab::addActionCB, this, _1, _2, check));
 			}
 			else
 			{
@@ -2262,22 +2244,21 @@ void LLPanelGroupRolesSubTab::handleActionCheck(LLCheckBoxCtrl* check, bool forc
 	notifyObservers();
 }
 
-//static
-void LLPanelGroupRolesSubTab::addActionCB(S32 option, void* data)
+bool LLPanelGroupRolesSubTab::addActionCB(const LLSD& notification, const LLSD& response, LLCheckBoxCtrl* check)
 {
-	struct ActionCBData* cb_data = (struct ActionCBData*) data;
+	if (!check) return false;
 
-	if (!cb_data || !cb_data->mSelf || !cb_data->mCheck) return;
-
-	cb_data->mSelf->mHasModal = FALSE;
+	mHasModal = FALSE;
 
+	S32 option = LLNotification::getSelectedOption(notification, response);
 	if (0 == option)
 	{
 		// User clicked "Yes"
-		cb_data->mCheck->set(TRUE);
+		check->set(TRUE);
 		const bool force_add = true;
-		cb_data->mSelf->handleActionCheck(cb_data->mCheck, force_add);
+		handleActionCheck(check, force_add);
 	}
+	return false;
 }
 
 
@@ -2413,9 +2394,9 @@ void LLPanelGroupRolesSubTab::handleDeleteRole()
 
 	if (role_item->getUUID().isNull() || role_item->getUUID() == gdatap->mOwnerRole)
 	{
-		LLStringUtil::format_map_t args;
-		args["[MESSAGE]"] = mRemoveEveryoneTxt;
-		LLNotifyBox::showXml("GenericNotify", args);
+		LLSD args;
+		args["MESSAGE"] = mRemoveEveryoneTxt;
+		LLNotifications::instance().add("GenericNotify", args);
 		return;
 	}
 
diff --git a/indra/newview/llpanelgrouproles.h b/indra/newview/llpanelgrouproles.h
index f55d70f0185..592e585f9ea 100644
--- a/indra/newview/llpanelgrouproles.h
+++ b/indra/newview/llpanelgrouproles.h
@@ -73,9 +73,8 @@ class LLPanelGroupRoles : public LLPanelGroupTab,
 	void transitionToTab();
 
 	// Used by attemptTransition to query the user's response to a tab that needs to apply. 
-	static void onNotifyCallback(S32 option, void* user_data);
-	void handleNotifyCallback(S32 option);
-	static void onModalClose(S32 option, void* user_data);
+	bool handleNotifyCallback(const LLSD& notification, const LLSD& response);
+	bool onModalClose(const LLSD& notification, const LLSD& response);
 
 	// Most of these messages are just passed on to the current sub-tab.
 	virtual std::string getHelpText() const;
@@ -188,7 +187,7 @@ class LLPanelGroupMembersSubTab : public LLPanelGroupSubTab
 						 LLRoleMemberChangeType type);
 
 	void applyMemberChanges();
-	static void addOwnerCB(S32 option, void* data);
+	bool addOwnerCB(const LLSD& notification, const LLSD& response);
 
 	virtual void activate();
 	virtual void deactivate();
@@ -250,7 +249,7 @@ class LLPanelGroupRolesSubTab : public LLPanelGroupSubTab
 
 	static void onActionCheck(LLUICtrl*, void*);
 	void handleActionCheck(LLCheckBoxCtrl*, bool force=false);
-	static void addActionCB(S32 option, void* data);
+	bool addActionCB(const LLSD& notification, const LLSD& response, LLCheckBoxCtrl* check);
 
 	static void onPropertiesKey(LLLineEditor*, void*);
 
diff --git a/indra/newview/llpanelland.cpp b/indra/newview/llpanelland.cpp
index 11f88695c57..05381ae7d8e 100644
--- a/indra/newview/llpanelland.cpp
+++ b/indra/newview/llpanelland.cpp
@@ -266,5 +266,5 @@ void LLPanelLandInfo::onClickAbout(void*)
 
 void LLPanelLandInfo::onShowOwnersHelp(void* user_data)
 {
-	gViewerWindow->alertXml("ShowOwnersHelp");
+	LLNotifications::instance().add("ShowOwnersHelp");
 }
diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp
index 20228ed3064..929043e97d6 100644
--- a/indra/newview/llpanellogin.cpp
+++ b/indra/newview/llpanellogin.cpp
@@ -899,16 +899,17 @@ void LLPanelLogin::onClickConnect(void *)
 		}
 		else
 		{
-			gViewerWindow->alertXml("MustHaveAccountToLogIn",
-									LLPanelLogin::newAccountAlertCallback);
+			LLNotifications::instance().add("MustHaveAccountToLogIn", LLSD(), LLSD(),
+										LLPanelLogin::newAccountAlertCallback);
 		}
 	}
 }
 
 
 // static
-void LLPanelLogin::newAccountAlertCallback(S32 option, void*)
+bool LLPanelLogin::newAccountAlertCallback(const LLSD& notification, const LLSD& response)
 {
+	S32 option = LLNotification::getSelectedOption(notification, response);
 	if (0 == option)
 	{
 		llinfos << "Going to account creation URL" << llendl;
@@ -918,6 +919,7 @@ void LLPanelLogin::newAccountAlertCallback(S32 option, void*)
 	{
 		sInstance->setFocus(TRUE);
 	}
+	return false;
 }
 
 
@@ -964,7 +966,7 @@ void LLPanelLogin::onPassKey(LLLineEditor* caller, void* user_data)
 {
 	if (gKeyboard->getKeyDown(KEY_CAPSLOCK) && sCapslockDidNotification == FALSE)
 	{
-		LLNotifyBox::showXml("CapsKeyOn");
+		LLNotifications::instance().add("CapsKeyOn");
 		sCapslockDidNotification = TRUE;
 	}
 }
diff --git a/indra/newview/llpanellogin.h b/indra/newview/llpanellogin.h
index 9d7e386cdad..1f803fa57c5 100644
--- a/indra/newview/llpanellogin.h
+++ b/indra/newview/llpanellogin.h
@@ -82,7 +82,7 @@ class LLPanelLogin:
 private:
 	static void onClickConnect(void*);
 	static void onClickNewAccount(void*);
-	static void newAccountAlertCallback(S32 option, void*);
+	static bool newAccountAlertCallback(const LLSD& notification, const LLSD& response);
 	static void onClickQuit(void*);
 	static void onClickVersion(void*);
 	virtual void onNavigateComplete( const EventType& eventIn );
diff --git a/indra/newview/llpanelpermissions.cpp b/indra/newview/llpanelpermissions.cpp
index 8a75385984d..b46e04d4625 100644
--- a/indra/newview/llpanelpermissions.cpp
+++ b/indra/newview/llpanelpermissions.cpp
@@ -876,8 +876,9 @@ void LLPanelPermissions::cbGroupID(LLUUID group_id, void* userdata)
 	LLSelectMgr::getInstance()->sendGroup(group_id);
 }
 
-void callback_deed_to_group(S32 option, void*)
+bool callback_deed_to_group(const LLSD& notification, const LLSD& response)
 {
+	S32 option = LLNotification::getSelectedOption(notification, response);
 	if (0 == option)
 	{
 		LLUUID group_id;
@@ -888,12 +889,12 @@ void callback_deed_to_group(S32 option, void*)
 //			LLViewerStats::getInstance()->incStat(LLViewerStats::ST_RELEASE_COUNT);
 		}
 	}
+	return false;
 }
 
 void LLPanelPermissions::onClickDeedToGroup(void* data)
 {
-			gViewerWindow->alertXml( "DeedObjectToGroup",
-			callback_deed_to_group, NULL);
+	LLNotifications::instance().add( "DeedObjectToGroup", LLSD(), LLSD(), callback_deed_to_group);
 }
 
 ///----------------------------------------------------------------------------
@@ -1092,7 +1093,7 @@ void LLPanelPermissions::onCommitClickAction(LLUICtrl* ctrl, void*)
 		LLSelectMgr::getInstance()->selectGetSaleInfo(sale_info);
 		if (!sale_info.isForSale())
 		{
-			gViewerWindow->alertXml("CantSetBuyObject");
+			LLNotifications::instance().add("CantSetBuyObject");
 
 			// Set click action back to its old value
 			U8 click_action = 0;
@@ -1110,7 +1111,7 @@ void LLPanelPermissions::onCommitClickAction(LLUICtrl* ctrl, void*)
 		if (!can_pay)
 		{
 			// Warn, but do it anyway.
-			gViewerWindow->alertXml("ClickActionNotPayable");
+			LLNotifications::instance().add("ClickActionNotPayable");
 		}
 	}
 	LLSelectMgr::getInstance()->selectionSetClickAction(click_action);
diff --git a/indra/newview/llpanelpick.cpp b/indra/newview/llpanelpick.cpp
index 9bd118fa1d3..2420d8d424e 100644
--- a/indra/newview/llpanelpick.cpp
+++ b/indra/newview/llpanelpick.cpp
@@ -476,7 +476,7 @@ void LLPanelPick::onClickSet(void* data)
 	// is the location and nothing else
 	if ( gAgent.getRegion ()->getName () != self->mSimName )
 	{
-		gViewerWindow->alertXml("SetPickLocation");
+		LLNotifications::instance().add("SetPickLocation");
 	};
 
 	self->mLocationEditor->setText(location_text);
diff --git a/indra/newview/llpanelplace.cpp b/indra/newview/llpanelplace.cpp
index 4ae253360a9..100fa3209d1 100644
--- a/indra/newview/llpanelplace.cpp
+++ b/indra/newview/llpanelplace.cpp
@@ -416,24 +416,24 @@ void LLPanelPlace::onClickLandmark(void* data)
 void LLPanelPlace::onClickAuction(void* data)
 {
 	LLPanelPlace* self = (LLPanelPlace*)data;
+	LLSD payload;
+	payload["auction_id"] = self->mAuctionID;
 
-	gViewerWindow->alertXml("GoToAuctionPage",
-		callbackAuctionWebPage, 
-		self);
+	LLNotifications::instance().add("GoToAuctionPage", LLSD(), payload, callbackAuctionWebPage);
 }
 
 // static
-void LLPanelPlace::callbackAuctionWebPage(S32 option, void* data)
+bool LLPanelPlace::callbackAuctionWebPage(const LLSD& notification, const LLSD& response)
 {
-	LLPanelPlace* self = (LLPanelPlace*)data;
-
+	S32 option = LLNotification::getSelectedOption(notification, response);
 	if (0 == option)
 	{
 		std::string url;
-		url = AUCTION_URL + llformat( "%010d", self->mAuctionID);
+		url = AUCTION_URL + llformat("%010d", response["auction_id"].asInteger());
 
 		llinfos << "Loading auction page " << url << llendl;
 
 		LLWeb::loadURL(url);
 	}
+	return false;
 }
diff --git a/indra/newview/llpanelplace.h b/indra/newview/llpanelplace.h
index 7a09f5cca61..db47889546c 100644
--- a/indra/newview/llpanelplace.h
+++ b/indra/newview/llpanelplace.h
@@ -83,7 +83,7 @@ class LLPanelPlace : public LLPanel
 	static void onClickAuction(void* data);
 
 	// Go to auction web page if user clicked OK
-	static void callbackAuctionWebPage(S32 option, void* data);
+	static bool callbackAuctionWebPage(const LLSD& notification, const LLSD& response);
 
 protected:
 	LLUUID			mParcelID;
diff --git a/indra/newview/llpreviewgesture.cpp b/indra/newview/llpreviewgesture.cpp
index 7661f9acd69..7e465a88bc4 100644
--- a/indra/newview/llpreviewgesture.cpp
+++ b/indra/newview/llpreviewgesture.cpp
@@ -284,9 +284,8 @@ BOOL LLPreviewGesture::canClose()
 	else
 	{
 		// Bring up view-modal dialog: Save changes? Yes, No, Cancel
-		gViewerWindow->alertXml("SaveChanges",
-								  handleSaveChangesDialog,
-								  this );
+		LLNotifications::instance().add("SaveChanges", LLSD(), LLSD(),
+			boost::bind(&LLPreviewGesture::handleSaveChangesDialog, this, _1, _2) );
 		return FALSE;
 	}
 }
@@ -320,22 +319,21 @@ void LLPreviewGesture::setMinimized(BOOL minimize)
 }
 
 
-// static
-void LLPreviewGesture::handleSaveChangesDialog(S32 option, void* data)
+bool LLPreviewGesture::handleSaveChangesDialog(const LLSD& notification, const LLSD& response)
 {
-	LLPreviewGesture* self = (LLPreviewGesture*)data;
+	S32 option = LLNotification::getSelectedOption(notification, response);
 	switch(option)
 	{
 	case 0:  // "Yes"
-		gGestureManager.stopGesture(self->mPreviewGesture);
-		self->mCloseAfterSave = TRUE;
-		onClickSave(data);
+		gGestureManager.stopGesture(mPreviewGesture);
+		mCloseAfterSave = TRUE;
+		onClickSave(this);
 		break;
 
 	case 1:  // "No"
-		gGestureManager.stopGesture(self->mPreviewGesture);
-		self->mDirty = FALSE; // Force the dirty flag because user has clicked NO on confirm save dialog...
-		self->close();
+		gGestureManager.stopGesture(mPreviewGesture);
+		mDirty = FALSE; // Force the dirty flag because user has clicked NO on confirm save dialog...
+		close();
 		break;
 
 	case 2: // "Cancel"
@@ -344,6 +342,7 @@ void LLPreviewGesture::handleSaveChangesDialog(S32 option, void* data)
 		LLAppViewer::instance()->abortQuit();
 		break;
 	}
+	return false;
 }
 
 
@@ -1114,14 +1113,14 @@ void LLPreviewGesture::saveIfNeeded()
 
 	if (dp.getCurrentSize() > 1000)
 	{
-		gViewerWindow->alertXml("GestureSaveFailedTooManySteps");
+		LLNotifications::instance().add("GestureSaveFailedTooManySteps");
 
 		delete gesture;
 		gesture = NULL;
 	}
 	else if (!ok)
 	{
-		gViewerWindow->alertXml("GestureSaveFailedTryAgain");
+		LLNotifications::instance().add("GestureSaveFailedTryAgain");
 		delete gesture;
 		gesture = NULL;
 	}
@@ -1260,7 +1259,7 @@ void LLPreviewGesture::onSaveComplete(const LLUUID& asset_uuid, void* user_data,
 			}
 			else
 			{
-				gViewerWindow->alertXml("GestureSaveFailedObjectNotFound");
+				LLNotifications::instance().add("GestureSaveFailedObjectNotFound");
 			}
 		}
 
@@ -1274,9 +1273,9 @@ void LLPreviewGesture::onSaveComplete(const LLUUID& asset_uuid, void* user_data,
 	else
 	{
 		llwarns << "Problem saving gesture: " << status << llendl;
-		LLStringUtil::format_map_t args;
-		args["[REASON]"] = std::string(LLAssetStorage::getErrorString(status));
-		gViewerWindow->alertXml("GestureSaveFailedReason",args);
+		LLSD args;
+		args["REASON"] = std::string(LLAssetStorage::getErrorString(status));
+		LLNotifications::instance().add("GestureSaveFailedReason", args);
 	}
 	delete info;
 	info = NULL;
diff --git a/indra/newview/llpreviewgesture.h b/indra/newview/llpreviewgesture.h
index 3b07608134a..bbe9486bfd5 100644
--- a/indra/newview/llpreviewgesture.h
+++ b/indra/newview/llpreviewgesture.h
@@ -101,7 +101,7 @@ class LLPreviewGesture : public LLPreview
 							   void* user_data,
 							   S32 status, LLExtStat ext_status);
 
-	static void handleSaveChangesDialog(S32 option, void* userdata);
+	bool handleSaveChangesDialog(const LLSD& notification, const LLSD& response);
 
 	// Write UI back into gesture
 	LLMultiGesture* createGesture();
diff --git a/indra/newview/llpreviewnotecard.cpp b/indra/newview/llpreviewnotecard.cpp
index 61ebe6cbbcd..ef61270069e 100644
--- a/indra/newview/llpreviewnotecard.cpp
+++ b/indra/newview/llpreviewnotecard.cpp
@@ -229,9 +229,7 @@ BOOL LLPreviewNotecard::canClose()
 	else
 	{
 		// Bring up view-modal dialog: Save changes? Yes, No, Cancel
-		gViewerWindow->alertXml("SaveChanges",
-								  &LLPreviewNotecard::handleSaveChangesDialog,
-								  this);
+		LLNotifications::instance().add("SaveChanges", LLSD(), LLSD(), boost::bind(&LLPreviewNotecard::handleSaveChangesDialog,this, _1, _2));
 								  
 		return FALSE;
 	}
@@ -403,15 +401,15 @@ void LLPreviewNotecard::onLoadComplete(LLVFS *vfs,
 			if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status ||
 				LL_ERR_FILE_EMPTY == status)
 			{
-				LLNotifyBox::showXml("NotecardMissing");
+				LLNotifications::instance().add("NotecardMissing");
 			}
 			else if (LL_ERR_INSUFFICIENT_PERMISSIONS == status)
 			{
-				LLNotifyBox::showXml("NotecardNoPermissions");
+				LLNotifications::instance().add("NotecardNoPermissions");
 			}
 			else
 			{
-				LLNotifyBox::showXml("UnableToLoadNotecard");
+				LLNotifications::instance().add("UnableToLoadNotecard");
 			}
 
 			llwarns << "Problem loading notecard: " << status << llendl;
@@ -578,7 +576,7 @@ void LLPreviewNotecard::onSaveComplete(const LLUUID& asset_uuid, void* user_data
 			}
 			else
 			{
-				gViewerWindow->alertXml("SaveNotecardFailObjectNotFound");
+				LLNotifications::instance().add("SaveNotecardFailObjectNotFound");
 			}
 		}
 		// Perform item copy to inventory
@@ -601,9 +599,9 @@ void LLPreviewNotecard::onSaveComplete(const LLUUID& asset_uuid, void* user_data
 	else
 	{
 		llwarns << "Problem saving notecard: " << status << llendl;
-		LLStringUtil::format_map_t args;
-		args["[REASON]"] = std::string(LLAssetStorage::getErrorString(status));
-		gViewerWindow->alertXml("SaveNotecardFailReason",args);
+		LLSD args;
+		args["REASON"] = std::string(LLAssetStorage::getErrorString(status));
+		LLNotifications::instance().add("SaveNotecardFailReason", args);
 	}
 
 	std::string uuid_string;
@@ -614,20 +612,19 @@ void LLPreviewNotecard::onSaveComplete(const LLUUID& asset_uuid, void* user_data
 	delete info;
 }
 
-// static
-void LLPreviewNotecard::handleSaveChangesDialog(S32 option, void* userdata)
+bool LLPreviewNotecard::handleSaveChangesDialog(const LLSD& notification, const LLSD& response)
 {
-	LLPreviewNotecard* self = (LLPreviewNotecard*)userdata;
+	S32 option = LLNotification::getSelectedOption(notification, response);
 	switch(option)
 	{
 	case 0:  // "Yes"
-		self->mCloseAfterSave = TRUE;
-		LLPreviewNotecard::onClickSave((void*)self);
+		mCloseAfterSave = TRUE;
+		LLPreviewNotecard::onClickSave((void*)this);
 		break;
 
 	case 1:  // "No"
-		self->mForceClose = TRUE;
-		self->close();
+		mForceClose = TRUE;
+		close();
 		break;
 
 	case 2: // "Cancel"
@@ -636,6 +633,7 @@ void LLPreviewNotecard::handleSaveChangesDialog(S32 option, void* userdata)
 		LLAppViewer::instance()->abortQuit();
 		break;
 	}
+	return false;
 }
 
 void LLPreviewNotecard::reshape(S32 width, S32 height, BOOL called_from_parent)
diff --git a/indra/newview/llpreviewnotecard.h b/indra/newview/llpreviewnotecard.h
index 1c801abf590..7175a764ec9 100644
--- a/indra/newview/llpreviewnotecard.h
+++ b/indra/newview/llpreviewnotecard.h
@@ -101,7 +101,7 @@ class LLPreviewNotecard : public LLPreview
 							   void* user_data,
 							   S32 status, LLExtStat ext_status);
 
-	static void handleSaveChangesDialog(S32 option, void* userdata);
+	bool handleSaveChangesDialog(const LLSD& notification, const LLSD& response);
 
 	virtual const char *getTitleName() const { return "Note"; }
 
diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp
index 2717c444154..42363079a41 100644
--- a/indra/newview/llpreviewscript.cpp
+++ b/indra/newview/llpreviewscript.cpp
@@ -608,27 +608,26 @@ BOOL LLScriptEdCore::canClose()
 	else
 	{
 		// Bring up view-modal dialog: Save changes? Yes, No, Cancel
-		gViewerWindow->alertXml("SaveChanges", LLScriptEdCore::handleSaveChangesDialog, this);
+		LLNotifications::instance().add("SaveChanges", LLSD(), LLSD(), boost::bind(&LLScriptEdCore::handleSaveChangesDialog, this, _1, _2));
 		return FALSE;
 	}
 }
 
-// static
-void LLScriptEdCore::handleSaveChangesDialog( S32 option, void* userdata )
+bool LLScriptEdCore::handleSaveChangesDialog(const LLSD& notification, const LLSD& response )
 {
-	LLScriptEdCore* self = (LLScriptEdCore*) userdata;
+	S32 option = LLNotification::getSelectedOption(notification, response);
 	switch( option )
 	{
 	case 0:  // "Yes"
 		// close after saving
-		LLScriptEdCore::doSave( self, TRUE );
+		LLScriptEdCore::doSave( this, TRUE );
 		break;
 
 	case 1:  // "No"
-		self->mForceClose = TRUE;
+		mForceClose = TRUE;
 		// This will close immediately because mForceClose is true, so we won't
 		// infinite loop with these dialogs. JC
-		((LLFloater*) self->getParent())->close();
+		((LLFloater*) getParent())->close();
 		break;
 
 	case 2: // "Cancel"
@@ -637,29 +636,32 @@ void LLScriptEdCore::handleSaveChangesDialog( S32 option, void* userdata )
         LLAppViewer::instance()->abortQuit();
 		break;
 	}
+	return false;
 }
 
 // static 
-void LLScriptEdCore::onHelpWebDialog(S32 option, void* userdata)
+bool LLScriptEdCore::onHelpWebDialog(const LLSD& notification, const LLSD& response)
 {
-	LLScriptEdCore* corep = (LLScriptEdCore*)userdata;
+	S32 option = LLNotification::getSelectedOption(notification, response);
 
 	switch(option)
 	{
 	case 0:
-		LLWeb::loadURL(corep->mHelpURL);
+		LLWeb::loadURL(notification["payload"]["help_url"]);
 		break;
 	default:
 		break;
 	}
+	return false;
 }
 
 // static 
 void LLScriptEdCore::onBtnHelp(void* userdata)
 {
-		gViewerWindow->alertXml("WebLaunchLSLGuide",
-			onHelpWebDialog,
-			userdata);
+	LLScriptEdCore* corep = (LLScriptEdCore*)userdata;
+	LLSD payload;
+	payload["help_url"] = corep->mHelpURL;
+	LLNotifications::instance().add("WebLaunchLSLGuide", LLSD(), payload, onHelpWebDialog);
 }
 
 // static 
@@ -818,8 +820,7 @@ void LLScriptEdCore::onBtnUndoChanges( void* userdata )
 	LLScriptEdCore* self = (LLScriptEdCore*) userdata;
 	if( !self->mEditor->tryToRevertToPristineState() )
 	{
-		gViewerWindow->alertXml("ScriptCannotUndo",
-			 LLScriptEdCore::handleReloadFromServerDialog, self);
+		LLNotifications::instance().add("ScriptCannotUndo", LLSD(), LLSD(), boost::bind(&LLScriptEdCore::handleReloadFromServerDialog, self, _1, _2));
 	}
 }
 
@@ -965,17 +966,16 @@ void LLScriptEdCore::onErrorList(LLUICtrl*, void* user_data)
 	}
 }
 
-// static
-void LLScriptEdCore::handleReloadFromServerDialog( S32 option, void* userdata )
+bool LLScriptEdCore::handleReloadFromServerDialog(const LLSD& notification, const LLSD& response )
 {
-	LLScriptEdCore* self = (LLScriptEdCore*) userdata;
+	S32 option = LLNotification::getSelectedOption(notification, response);
 	switch( option )
 	{
 	case 0: // "Yes"
-		if( self->mLoadCallback )
+		if( mLoadCallback )
 		{
-			self->mEditor->setText( self->getString("loading") );
-			self->mLoadCallback( self->mUserdata );
+			mEditor->setText( getString("loading") );
+			mLoadCallback( mUserdata );
 		}
 		break;
 
@@ -986,6 +986,7 @@ void LLScriptEdCore::handleReloadFromServerDialog( S32 option, void* userdata )
 		llassert(0);
 		break;
 	}
+	return false;
 }
 
 void LLScriptEdCore::selectFirstError()
@@ -1444,9 +1445,9 @@ void LLPreviewLSL::onSaveComplete(const LLUUID& asset_uuid, void* user_data, S32
 	else
 	{
 		llwarns << "Problem saving script: " << status << llendl;
-		LLStringUtil::format_map_t args;
-		args["[REASON]"] = std::string(LLAssetStorage::getErrorString(status));
-		gViewerWindow->alertXml("SaveScriptFailReason", args);
+		LLSD args;
+		args["REASON"] = std::string(LLAssetStorage::getErrorString(status));
+		LLNotifications::instance().add("SaveScriptFailReason", args);
 	}
 	delete info;
 }
@@ -1482,9 +1483,9 @@ void LLPreviewLSL::onSaveBytecodeComplete(const LLUUID& asset_uuid, void* user_d
 	else
 	{
 		llwarns << "Problem saving LSL Bytecode (Preview)" << llendl;
-		LLStringUtil::format_map_t args;
-		args["[REASON]"] = std::string(LLAssetStorage::getErrorString(status));
-		gViewerWindow->alertXml("SaveBytecodeFailReason", args);
+		LLSD args;
+		args["REASON"] = std::string(LLAssetStorage::getErrorString(status));
+		LLNotifications::instance().add("SaveBytecodeFailReason", args);
 	}
 	delete instance_uuid;
 }
@@ -1530,15 +1531,15 @@ void LLPreviewLSL::onLoadComplete( LLVFS *vfs, const LLUUID& asset_uuid, LLAsset
 			if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status ||
 				LL_ERR_FILE_EMPTY == status)
 			{
-				LLNotifyBox::showXml("ScriptMissing");
+				LLNotifications::instance().add("ScriptMissing");
 			}
 			else if (LL_ERR_INSUFFICIENT_PERMISSIONS == status)
 			{
-				LLNotifyBox::showXml("ScriptNoPermissions");
+				LLNotifications::instance().add("ScriptNoPermissions");
 			}
 			else
 			{
-				LLNotifyBox::showXml("UnableToLoadScript");
+				LLNotifications::instance().add("UnableToLoadScript");
 			}
 
 			preview->mAssetStatus = PREVIEW_ASSET_ERROR;
@@ -1846,15 +1847,15 @@ void LLLiveLSLEditor::onLoadComplete(LLVFS *vfs, const LLUUID& asset_id,
 			if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status ||
 				LL_ERR_FILE_EMPTY == status)
 			{
-				LLNotifyBox::showXml("ScriptMissing");
+				LLNotifications::instance().add("ScriptMissing");
 			}
 			else if (LL_ERR_INSUFFICIENT_PERMISSIONS == status)
 			{
-				LLNotifyBox::showXml("ScriptNoPermissions");
+				LLNotifications::instance().add("ScriptNoPermissions");
 			}
 			else
 			{
-				LLNotifyBox::showXml("UnableToLoadScript");
+				LLNotifications::instance().add("UnableToLoadScript");
 			}
 			instance->mAssetStatus = PREVIEW_ASSET_ERROR;
 		}
@@ -1941,7 +1942,7 @@ void LLLiveLSLEditor::onRunningCheckboxClicked( LLUICtrl*, void* userdata )
 	else
 	{
 		runningCheckbox->set(!running);
-		gViewerWindow->alertXml("CouldNotStartStopScript");
+		LLNotifications::instance().add("CouldNotStartStopScript");
 	}
 }
 
@@ -1964,7 +1965,7 @@ void LLLiveLSLEditor::onReset(void *userdata)
 	}
 	else
 	{
-		gViewerWindow->alertXml("CouldNotStartStopScript"); 
+		LLNotifications::instance().add("CouldNotStartStopScript"); 
 	}
 }
 
@@ -2058,7 +2059,7 @@ void LLLiveLSLEditor::saveIfNeeded()
 	LLViewerObject* object = gObjectList.findObject(mObjectID);
 	if(!object)
 	{
-		gViewerWindow->alertXml("SaveScriptFailObjectNotFound");
+		LLNotifications::instance().add("SaveScriptFailObjectNotFound");
 		return;
 	}
 
@@ -2066,7 +2067,7 @@ void LLLiveLSLEditor::saveIfNeeded()
 	{
 		// $NOTE: While the error message may not be exactly correct,
 		// it's pretty close.
-		gViewerWindow->alertXml("SaveScriptFailObjectNotFound");
+		LLNotifications::instance().add("SaveScriptFailObjectNotFound");
 		return;
 	}
 
@@ -2268,9 +2269,9 @@ void LLLiveLSLEditor::onSaveTextComplete(const LLUUID& asset_uuid, void* user_da
 	if (status)
 	{
 		llwarns << "Unable to save text for a script." << llendl;
-		LLStringUtil::format_map_t args;
-		args["[REASON]"] = std::string(LLAssetStorage::getErrorString(status));
-		gViewerWindow->alertXml("CompileQueueSaveText", args);
+		LLSD args;
+		args["REASON"] = std::string(LLAssetStorage::getErrorString(status));
+		LLNotifications::instance().add("CompileQueueSaveText", args);
 	}
 	else
 	{
@@ -2329,9 +2330,9 @@ void LLLiveLSLEditor::onSaveBytecodeComplete(const LLUUID& asset_uuid, void* use
 		llinfos << "Problem saving LSL Bytecode (Live Editor)" << llendl;
 		llwarns << "Unable to save a compiled script." << llendl;
 
-		LLStringUtil::format_map_t args;
-		args["[REASON]"] = std::string(LLAssetStorage::getErrorString(status));
-		gViewerWindow->alertXml("CompileQueueSaveBytecode", args);
+		LLSD args;
+		args["REASON"] = std::string(LLAssetStorage::getErrorString(status));
+		LLNotifications::instance().add("CompileQueueSaveBytecode", args);
 	}
 
 	std::string filepath = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,asset_uuid.asString());
diff --git a/indra/newview/llpreviewscript.h b/indra/newview/llpreviewscript.h
index c0af06f4802..c84d5e6d8f8 100644
--- a/indra/newview/llpreviewscript.h
+++ b/indra/newview/llpreviewscript.h
@@ -80,10 +80,10 @@ class LLScriptEdCore : public LLPanel
 
 	BOOL			canClose();
 
-	static void		handleSaveChangesDialog(S32 option, void* userdata);
-	static void		handleReloadFromServerDialog(S32 option, void* userdata);
+	bool			handleSaveChangesDialog(const LLSD& notification, const LLSD& response);
+	bool			handleReloadFromServerDialog(const LLSD& notification, const LLSD& response);
 
-	static void		onHelpWebDialog(S32 option, void* userdata);
+	static bool		onHelpWebDialog(const LLSD& notification, const LLSD& response);
 	static void		onBtnHelp(void* userdata);
 	static void		onBtnDynamicHelp(void* userdata);
 	static void		onCheckLock(LLUICtrl*, void*);
diff --git a/indra/newview/llpreviewtexture.cpp b/indra/newview/llpreviewtexture.cpp
index 79b83133523..fefa6d40d73 100644
--- a/indra/newview/llpreviewtexture.cpp
+++ b/indra/newview/llpreviewtexture.cpp
@@ -349,15 +349,15 @@ void LLPreviewTexture::onFileLoadedForSave(BOOL success,
 		LLPointer<LLImageTGA> image_tga = new LLImageTGA;
 		if( !image_tga->encode( src ) )
 		{
-			LLStringUtil::format_map_t args;
-			args["[FILE]"] = self->mSaveFileName;
-			gViewerWindow->alertXml("CannotEncodeFile", args);
+			LLSD args;
+			args["FILE"] = self->mSaveFileName;
+			LLNotifications::instance().add("CannotEncodeFile", args);
 		}
 		else if( !image_tga->save( self->mSaveFileName ) )
 		{
-			LLStringUtil::format_map_t args;
-			args["[FILE]"] = self->mSaveFileName;
-			gViewerWindow->alertXml("CannotWriteFile", args);
+			LLSD args;
+			args["FILE"] = self->mSaveFileName;
+			LLNotifications::instance().add("CannotWriteFile", args);
 		}
 		else
 		{
@@ -370,7 +370,7 @@ void LLPreviewTexture::onFileLoadedForSave(BOOL success,
 
 	if( self && !success )
 	{
-		gViewerWindow->alertXml("CannotDownloadFile");
+		LLNotifications::instance().add("CannotDownloadFile");
 	}
 }
 
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index 81decdf40a0..ae4be6173b3 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -2695,7 +2695,8 @@ void LLSelectMgr::selectDelete()
 		return;
 	}
 
-	LLObjectSelectionHandle* selection_handlep = new LLObjectSelectionHandle(getSelection());
+	LLNotification::Params params("ConfirmObjectDeleteLock");
+	params.functor(boost::bind(&LLSelectMgr::confirmDelete, _1, _2, getSelection()));
 
 	if(locked_but_deleteable_object ||
 	   no_copy_but_deleteable_object ||
@@ -2711,72 +2712,55 @@ void LLSelectMgr::selectDelete()
 		if(locked_but_deleteable_object && !no_copy_but_deleteable_object && all_owned_by_you)
 		{
 			//Locked only
-			gViewerWindow->alertXml(  "ConfirmObjectDeleteLock",
-								  &LLSelectMgr::confirmDelete,
-								  selection_handlep);
+			params.name("ConfirmObjectDeleteLock");
 		}
 		else if(!locked_but_deleteable_object && no_copy_but_deleteable_object && all_owned_by_you)
 		{
 			//No Copy only
-			gViewerWindow->alertXml(  "ConfirmObjectDeleteNoCopy",
-								  &LLSelectMgr::confirmDelete,
-								  selection_handlep);
+			params.name("ConfirmObjectDeleteNoCopy");
 		}
 		else if(!locked_but_deleteable_object && !no_copy_but_deleteable_object && !all_owned_by_you)
 		{
 			//not owned only
-			gViewerWindow->alertXml(  "ConfirmObjectDeleteNoOwn",
-								  &LLSelectMgr::confirmDelete,
-								  selection_handlep);
+			params.name("ConfirmObjectDeleteNoOwn");
 		}
 		else if(locked_but_deleteable_object && no_copy_but_deleteable_object && all_owned_by_you)
 		{
 			//locked and no copy
-			gViewerWindow->alertXml(  "ConfirmObjectDeleteLockNoCopy",
-								  &LLSelectMgr::confirmDelete,
-								  selection_handlep);
+			params.name("ConfirmObjectDeleteLockNoCopy");
 		}
 		else if(locked_but_deleteable_object && !no_copy_but_deleteable_object && !all_owned_by_you)
 		{
 			//locked and not owned
-			gViewerWindow->alertXml(  "ConfirmObjectDeleteLockNoOwn",
-								  &LLSelectMgr::confirmDelete,
-								  selection_handlep);
+			params.name("ConfirmObjectDeleteLockNoOwn");
 		}
 		else if(!locked_but_deleteable_object && no_copy_but_deleteable_object && !all_owned_by_you)
 		{
 			//no copy and not owned
-			gViewerWindow->alertXml(  "ConfirmObjectDeleteNoCopyNoOwn",
-								  &LLSelectMgr::confirmDelete,
-								  selection_handlep);
+			params.name("ConfirmObjectDeleteNoCopyNoOwn");
 		}
 		else
 		{
 			//locked, no copy and not owned
-			gViewerWindow->alertXml(  "ConfirmObjectDeleteLockNoCopyNoOwn",
-								  &LLSelectMgr::confirmDelete,
-								  selection_handlep);
+			params.name("ConfirmObjectDeleteLockNoCopyNoOwn");
 		}
 		
-		
-		
+		LLNotifications::instance().add(params);
 	}
 	else
 	{
-		confirmDelete(0, (void*)selection_handlep);
+		LLNotifications::instance().forceResponse(params, 0);
 	}
 }
 
 // static
-void LLSelectMgr::confirmDelete(S32 option, void* data)
+bool LLSelectMgr::confirmDelete(const LLSD& notification, const LLSD& response, LLObjectSelectionHandle handle)
 {
-	LLObjectSelectionHandle handle = *(LLObjectSelectionHandle*)data;
-	delete (LLObjectSelectionHandle*)data;
-
+	S32 option = LLNotification::getSelectedOption(notification, response);
 	if (!handle->getObjectCount())
 	{
 		llwarns << "Nothing to delete!" << llendl;
-		return;
+		return false;
 	}
 
 	switch(option)
@@ -2815,6 +2799,7 @@ void LLSelectMgr::confirmDelete(S32 option, void* data)
 	default:
 		break;
 	}
+	return false;
 }
 
 
diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h
index f210fdb9d33..27bcb5a5824 100644
--- a/indra/newview/llselectmgr.h
+++ b/indra/newview/llselectmgr.h
@@ -683,7 +683,7 @@ class LLSelectMgr : public LLEditMenuHandler, public LLSingleton<LLSelectMgr>
 	static void packHingeHead(void *user_data);
 	static void packPermissionsHead(void* user_data);
 	static void packGodlikeHead(void* user_data);
-	static void confirmDelete(S32 option, void* data);
+	static bool confirmDelete(const LLSD& notification, const LLSD& response, LLObjectSelectionHandle handle);
 	
 private:
 	LLPointer<LLViewerImage>				mSilhouetteImagep;
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 9a6454be33e..1dc1ddd451c 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -235,18 +235,17 @@ std::string load_password_from_disk();
 void save_password_to_disk(const char* hashed_password);
 bool is_hex_string(U8* str, S32 len);
 void show_first_run_dialog();
-void first_run_dialog_callback(S32 option, void* userdata);
+bool first_run_dialog_callback(const LLSD& notification, const LLSD& response);
 void set_startup_status(const F32 frac, const std::string& string, const std::string& msg);
-void login_alert_status(S32 option, void* user_data);
+bool login_alert_status(const LLSD& notification, const LLSD& response);
 void update_app(BOOL mandatory, const std::string& message);
-void update_dialog_callback(S32 option, void *userdata);
+bool update_dialog_callback(const LLSD& notification, const LLSD& response);
 void login_packet_failed(void**, S32 result);
 void use_circuit_callback(void**, S32 result);
 void register_viewer_callbacks(LLMessageSystem* msg);
 void init_stat_view();
 void asset_callback_nothing(LLVFS*, const LLUUID&, LLAssetType::EType, void*, S32);
-void dialog_choose_gender_first_start();
-void callback_choose_gender(S32 option, void* userdata);
+bool callback_choose_gender(const LLSD& notification, const LLSD& response);
 void init_start_screen(S32 location_id);
 void release_start_screen();
 void reset_login();
@@ -387,16 +386,16 @@ bool idle_startup()
 
 		if (LLFeatureManager::getInstance()->isSafe())
 		{
-			gViewerWindow->alertXml("DisplaySetToSafe");
+			LLNotifications::instance().add("DisplaySetToSafe");
 		}
 		else if ((gSavedSettings.getS32("LastFeatureVersion") < LLFeatureManager::getInstance()->getVersion()) &&
 				 (gSavedSettings.getS32("LastFeatureVersion") != 0))
 		{
-			gViewerWindow->alertXml("DisplaySetToRecommended");
+			LLNotifications::instance().add("DisplaySetToRecommended");
 		}
 		else if (!gViewerWindow->getInitAlert().empty())
 		{
-			gViewerWindow->alertXml(gViewerWindow->getInitAlert());
+			LLNotifications::instance().add(gViewerWindow->getInitAlert());
 		}
 			
 		gSavedSettings.setS32("LastFeatureVersion", LLFeatureManager::getInstance()->getVersion());
@@ -419,10 +418,11 @@ bool idle_startup()
 		}
 		if (!xml_ok)
 		{
-			// *TODO:translate (maybe - very unlikely error message)
-			// Note: alerts.xml may be invalid - if this gets translated it will need to be in the code
-			std::string bad_xui_msg = "An error occured while updating Second Life. Please download the latest version from www.secondlife.com.";
-            LLAppViewer::instance()->earlyExit(bad_xui_msg);
+			// If XML is bad, there's a good possibility that notifications.xml is ALSO bad.
+			// If that's so, then we'll get a fatal error on attempting to load it, 
+			// which will display a nontranslatable error message that says so.
+			// Otherwise, we'll display a reasonable error message that IS translatable.
+			LLAppViewer::instance()->earlyExit("BadInstallation");
 		}
 		//
 		// Statistics stuff
@@ -440,9 +440,9 @@ bool idle_startup()
 
 		if (ll_init_ares() == NULL || !gAres->isInitialized())
 		{
-			LL_WARNS("AppInit") << "Could not start address resolution system" << LL_ENDL;
-			std::string msg = LLTrans::getString("LoginFailedNoNetwork");
-			LLAppViewer::instance()->earlyExit(msg);
+			std::string diagnostic = "Could not start address resolution system";
+			LL_WARNS("AppInit") << diagnostic << LL_ENDL;
+			LLAppViewer::instance()->earlyExit("LoginFailedNoNetwork", LLSD().insert("DIAGNOSTIC", diagnostic));
 		}
 		
 		//
@@ -500,9 +500,9 @@ bool idle_startup()
 				   circuit_heartbeat_interval,
 				   circuit_timeout))
 			{
-				std::string msg = LLTrans::getString("LoginFailedNoNetwork");
-				msg.append(llformat(" Error: %d", gMessageSystem->getErrorCode()));
-				LLAppViewer::instance()->earlyExit(msg);
+				std::string diagnostic = llformat(" Error: %d", gMessageSystem->getErrorCode());
+				LL_WARNS("AppInit") << diagnostic << LL_ENDL;
+				LLAppViewer::instance()->earlyExit("LoginFailedNoNetwork", LLSD().insert("DIAGNOSTIC", diagnostic));
 			}
 
 			#if LL_WINDOWS
@@ -525,7 +525,7 @@ bool idle_startup()
 		}
 		else
 		{
-			LLAppViewer::instance()->earlyExit("Message Template " + message_template_path + " not found.");
+			LLAppViewer::instance()->earlyExit("MessageTemplateNotFound", LLSD().insert("PATH", message_template_path));
 		}
 
 		if(gMessageSystem && gMessageSystem->isOK())
@@ -1551,9 +1551,9 @@ bool idle_startup()
 					exit(0);
 				}
 				// Bounce back to the login screen.
-				LLStringUtil::format_map_t args;
-				args["[ERROR_MESSAGE]"] = emsg.str();
-				gViewerWindow->alertXml("ErrorMessage", args, login_alert_done);
+				LLSD args;
+				args["ERROR_MESSAGE"] = emsg.str();
+				LLNotifications::instance().add("ErrorMessage", args, LLSD(), login_alert_done);
 				reset_login();
 				gSavedSettings.setBOOL("AutoLogin", FALSE);
 				show_connect_box = true;
@@ -1571,9 +1571,9 @@ bool idle_startup()
 				exit(0);
 			}
 			// Bounce back to the login screen.
-			LLStringUtil::format_map_t args;
-			args["[ERROR_MESSAGE]"] = emsg.str();
-			gViewerWindow->alertXml("ErrorMessage", args, login_alert_done);
+			LLSD args;
+			args["ERROR_MESSAGE"] = emsg.str();
+			LLNotifications::instance().add("ErrorMessage", args, LLSD(), login_alert_done);
 			reset_login();
 			gSavedSettings.setBOOL("AutoLogin", FALSE);
 			show_connect_box = true;
@@ -2300,23 +2300,23 @@ bool idle_startup()
 				// location is not your expected location. So, if this is
 				// your first login, then you do not have an expectation,
 				// thus, do not show this alert.
-				LLStringUtil::format_map_t args;
+				LLSD args;
 				if (url_ok)
 				{
-					args["[TYPE]"] = "desired";
-					args["[HELP]"] = "";
+					args["TYPE"] = "desired";
+					args["HELP"] = "";
 				}
 				else if (gSavedSettings.getBOOL("LoginLastLocation"))
 				{
-					args["[TYPE]"] = "last";
-					args["[HELP]"] = "";
+					args["TYPE"] = "last";
+					args["HELP"] = "";
 				}
 				else
 				{
-					args["[TYPE]"] = "home";
-					args["[HELP]"] = "You may want to set a new home location.";
+					args["TYPE"] = "home";
+					args["HELP"] = "You may want to set a new home location.";
 				}
-				gViewerWindow->alertXml("AvatarMoved", args);
+				LLNotifications::instance().add("AvatarMoved", args);
 			}
 			else
 			{
@@ -2411,16 +2411,15 @@ bool idle_startup()
 			// initial outfit, but if the load hasn't started
 			// already then something is wrong so fall back
 			// to generic outfits. JC
-			gViewerWindow->alertXml("WelcomeChooseSex",
-				callback_choose_gender, NULL);
+			LLNotifications::instance().add("WelcomeChooseSex", LLSD(), LLSD(),
+				callback_choose_gender);
 			LLStartUp::setStartupState( STATE_CLEANUP );
 			return TRUE;
 		}
 		
 		if (wearables_time > MAX_WEARABLES_TIME)
 		{
-			// It's taken too long to load, show the world
-			gViewerWindow->alertXml("ClothingLoading");
+			LLNotifications::instance().add("ClothingLoading");
 			LLViewerStats::getInstance()->incStat(LLViewerStats::ST_WEARABLES_TOO_LONG);
 			LLStartUp::setStartupState( STATE_CLEANUP );
 			return TRUE;
@@ -2440,7 +2439,7 @@ bool idle_startup()
 		else
 		{
 			// OK to just get the wearables
-			if ( gAgent.getWearablesLoaded() )
+			if ( gAgent.areWearablesLoaded() )
 			{
 				// We have our clothing, proceed.
 				//llinfos << "wearables loaded" << llendl;
@@ -2722,11 +2721,12 @@ bool is_hex_string(U8* str, S32 len)
 
 void show_first_run_dialog()
 {
-	gViewerWindow->alertXml("FirstRun", first_run_dialog_callback, NULL);
+	LLNotifications::instance().add("FirstRun", LLSD(), LLSD(), first_run_dialog_callback);
 }
 
-void first_run_dialog_callback(S32 option, void* userdata)
+bool first_run_dialog_callback(const LLSD& notification, const LLSD& response)
 {
+	S32 option = LLNotification::getSelectedOption(notification, response);
 	if (0 == option)
 	{
 		LL_DEBUGS("AppInit") << "First run dialog cancelling" << LL_ENDL;
@@ -2734,6 +2734,7 @@ void first_run_dialog_callback(S32 option, void* userdata)
 	}
 
 	LLPanelLogin::giveFocus();
+	return false;
 }
 
 
@@ -2746,8 +2747,9 @@ void set_startup_status(const F32 frac, const std::string& string, const std::st
 	gViewerWindow->setProgressMessage(msg);
 }
 
-void login_alert_status(S32 option, void* user_data)
+bool login_alert_status(const LLSD& notification, const LLSD& response)
 {
+	S32 option = LLNotification::getSelectedOption(notification, response);
     // Buttons
     switch( option )
     {
@@ -2766,6 +2768,7 @@ void login_alert_status(S32 option, void* user_data)
     }
 
 	LLPanelLogin::giveFocus();
+	return false;
 }
 
 void update_app(BOOL mandatory, const std::string& auth_msg)
@@ -2781,67 +2784,66 @@ void update_app(BOOL mandatory, const std::string& auth_msg)
 	{
 		msg = "(" + auth_msg + ") \n";
 	}
-	LLStringUtil::format_map_t args;
-	args["[MESSAGE]"] = msg;
-	
-	// represent a bool as a null/non-null pointer
-	void *mandatoryp = mandatory ? &mandatory : NULL;
 
+	LLSD args;
+	args["MESSAGE"] = msg;
+	
+	LLSD payload;
+	payload["mandatory"] = mandatory;
+
+/*
+ We're constructing one of the following 6 strings here:
+	 "DownloadWindowsMandatory"
+	 "DownloadWindowsReleaseForDownload"
+	 "DownloadWindows"
+	 "DownloadMacMandatory"
+	 "DownloadMacReleaseForDownload"
+	 "DownloadMac"
+ 
+ I've called them out explicitly in this comment so that they can be grepped for.
+ 
+ Also, we assume that if we're not Windows we're Mac. If we ever intend to support 
+ Linux with autoupdate, this should be an explicit #elif LL_DARWIN, but 
+ we'd rather deliver the wrong message than no message, so until Linux is supported
+ we'll leave it alone.
+ */
+	std::string notification_name = "Download";
+	
 #if LL_WINDOWS
-	if (mandatory)
-	{
-		gViewerWindow->alertXml("DownloadWindowsMandatory", args,
-								update_dialog_callback,
-								mandatoryp);
-	}
-	else
-	{
-#if LL_RELEASE_FOR_DOWNLOAD
-		gViewerWindow->alertXml("DownloadWindowsReleaseForDownload", args,
-								update_dialog_callback,
-								mandatoryp);
+	notification_name += "Windows";
 #else
-		gViewerWindow->alertXml("DownloadWindows", args,
-								update_dialog_callback,
-								mandatoryp);
+	notification_name += "Mac";
 #endif
-	}
-#else
+	
 	if (mandatory)
 	{
-		gViewerWindow->alertXml("DownloadMacMandatory", args,
-								update_dialog_callback,
-								mandatoryp);
+		notification_name += "Mandatory";
 	}
 	else
 	{
 #if LL_RELEASE_FOR_DOWNLOAD
-		gViewerWindow->alertXml("DownloadMacReleaseForDownload", args,
-								update_dialog_callback,
-								mandatoryp);
-#else
-		gViewerWindow->alertXml("DownloadMac", args,
-								update_dialog_callback,
-								mandatoryp);
+		notification_name += "ReleaseForDownload";
 #endif
 	}
-#endif
-
+	
+	LLNotifications::instance().add(notification_name, args, payload, update_dialog_callback);
+	
 }
 
-
-void update_dialog_callback(S32 option, void *userdata)
+bool update_dialog_callback(const LLSD& notification, const LLSD& response)
 {
-	bool mandatory = userdata != NULL;
+	S32 option = LLNotification::getSelectedOption(notification, response);
+	std::string update_exe_path;
+	bool mandatory = notification["payload"]["mandatory"].asBoolean();
 
 #if !LL_RELEASE_FOR_DOWNLOAD
 	if (option == 2)
 	{
 		LLStartUp::setStartupState( STATE_LOGIN_AUTH_INIT ); 
-		return;
+		return false;
 	}
 #endif
-	
+
 	if (option == 1)
 	{
 		// ...user doesn't want to do it
@@ -2855,7 +2857,7 @@ void update_dialog_callback(S32 option, void *userdata)
 		{
 			LLStartUp::setStartupState( STATE_LOGIN_AUTH_INIT );
 		}
-		return;
+		return false;
 	}
 	
 	LLSD query_map = LLSD::emptyMap();
@@ -2890,7 +2892,7 @@ void update_dialog_callback(S32 option, void *userdata)
 		// We're hosed, bail
 		LL_WARNS("AppInit") << "LLDir::getTempFilename() failed" << LL_ENDL;
 		LLAppViewer::instance()->forceQuit();
-		return;
+		return false;
 	}
 
 	LLAppViewer::sUpdaterInfo->mUpdateExePath += ".exe";
@@ -2911,7 +2913,7 @@ void update_dialog_callback(S32 option, void *userdata)
 
 		LL_WARNS("AppInit") << "Unable to copy the updater!" << LL_ENDL;
 		LLAppViewer::instance()->forceQuit();
-		return;
+		return false;
 	}
 
 	// if a sim name was passed in via command line parameter (typically through a SLURL)
@@ -2955,6 +2957,7 @@ void update_dialog_callback(S32 option, void *userdata)
 		LLStringUtil::null, OSMB_OK);
 #endif
 	LLAppViewer::instance()->forceQuit();
+	return false;
 }
 
 void use_circuit_callback(void**, S32 result)
@@ -2968,8 +2971,7 @@ void use_circuit_callback(void**, S32 result)
 		{
 			// Make sure user knows something bad happened. JC
 			LL_WARNS("AppInit") << "Backing up to login screen!" << LL_ENDL;
-			gViewerWindow->alertXml("LoginPacketNeverReceived",
-				login_alert_status, NULL);
+			LLNotifications::instance().add("LoginPacketNeverReceived", LLSD(), LLSD(), login_alert_status);
 			reset_login();
 		}
 		else
@@ -3753,8 +3755,9 @@ const S32 OPT_CLOSED_WINDOW = -1;
 const S32 OPT_MALE = 0;
 const S32 OPT_FEMALE = 1;
 
-void callback_choose_gender(S32 option, void* userdata)
-{
+bool callback_choose_gender(const LLSD& notification, const LLSD& response)
+{	
+	S32 option = LLNotification::getSelectedOption(notification, response);
 	switch(option)
 	{
 	case OPT_MALE:
@@ -3767,6 +3770,7 @@ void callback_choose_gender(S32 option, void* userdata)
 		LLStartUp::loadInitialOutfit( FEMALE_OUTFIT_FOLDER, "female" );
 		break;
 	}
+	return false;
 }
 
 void LLStartUp::loadInitialOutfit( const std::string& outfit_folder_name,
@@ -3809,8 +3813,8 @@ void LLStartUp::loadInitialOutfit( const std::string& outfit_folder_name,
 	// This is really misnamed -- it means we have started loading
 	// an outfit/shape that will give the avatar a gender eventually. JC
 	gAgent.setGenderChosen(TRUE);
+
 }
-			
 
 // Loads a bitmap to display during load
 // location_id = 0 => last position
@@ -3990,9 +3994,10 @@ bool LLStartUp::dispatchURL()
 	return false;
 }
 
-void login_alert_done(S32 option, void* user_data)
+bool login_alert_done(const LLSD& notification, const LLSD& response)
 {
 	LLPanelLogin::giveFocus();
+	return false;
 }
 
 
diff --git a/indra/newview/llstartup.h b/indra/newview/llstartup.h
index 1639ed55b65..f89642aa2a6 100644
--- a/indra/newview/llstartup.h
+++ b/indra/newview/llstartup.h
@@ -38,7 +38,7 @@
 bool idle_startup();
 std::string load_password_from_disk();
 void release_start_screen();
-void login_alert_done(S32 option, void* user_data);
+bool login_alert_done(const LLSD& notification, const LLSD& response);
 
 // constants, variables,  & enumerations
 extern std::string SCREEN_HOME_FILENAME;
diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp
index 278f7ea9d14..8b274a045b1 100644
--- a/indra/newview/llstatusbar.cpp
+++ b/indra/newview/llstatusbar.cpp
@@ -767,7 +767,7 @@ static void onClickBuyCurrency(void* data)
 
 static void onClickHealth(void* )
 {
-	LLNotifyBox::showXml("NotSafe");
+	LLNotifications::instance().add("NotSafe");
 }
 
 static void onClickScriptDebug(void*)
@@ -777,22 +777,22 @@ static void onClickScriptDebug(void*)
 
 static void onClickFly(void* )
 {
-	LLNotifyBox::showXml("NoFly");
+	LLNotifications::instance().add("NoFly");
 }
 
 static void onClickPush(void* )
 {
-	LLNotifyBox::showXml("PushRestricted");
+	LLNotifications::instance().add("PushRestricted");
 }
 
 static void onClickVoice(void* )
 {
-	LLNotifyBox::showXml("NoVoice");
+	LLNotifications::instance().add("NoVoice");
 }
 
 static void onClickBuild(void*)
 {
-	LLNotifyBox::showXml("NoBuild");
+	LLNotifications::instance().add("NoBuild");
 }
 
 static void onClickScripts(void*)
@@ -800,15 +800,15 @@ static void onClickScripts(void*)
 	LLViewerRegion* region = gAgent.getRegion();
 	if(region && region->getRegionFlags() & REGION_FLAGS_ESTATE_SKIP_SCRIPTS)
 	{
-		LLNotifyBox::showXml("ScriptsStopped");
+		LLNotifications::instance().add("ScriptsStopped");
 	}
 	else if(region && region->getRegionFlags() & REGION_FLAGS_SKIP_SCRIPTS)
 	{
-		LLNotifyBox::showXml("ScriptsNotRunning");
+		LLNotifications::instance().add("ScriptsNotRunning");
 	}
 	else
 	{
-		LLNotifyBox::showXml("NoOutsideScripts");
+		LLNotifications::instance().add("NoOutsideScripts");
 	}
 }
 
diff --git a/indra/newview/lltoolbar.cpp b/indra/newview/lltoolbar.cpp
index d7db0f85d96..b9235a489a1 100644
--- a/indra/newview/lltoolbar.cpp
+++ b/indra/newview/lltoolbar.cpp
@@ -307,7 +307,10 @@ void LLToolBar::refresh()
 	}
 	gSavedSettings.setBOOL("BuildBtnState", build_mode);
 
-	updateCommunicateList();
+	if (isInVisibleChain())
+	{
+		updateCommunicateList();
+	}
 }
 
 void LLToolBar::updateCommunicateList()
@@ -444,7 +447,7 @@ void LLToolBar::onClickChat(void* user_data)
 // static
 void LLToolBar::onClickAppearance(void*)
 {
-	if (gAgent.getWearablesLoaded())
+	if (gAgent.areWearablesLoaded())
 	{
 		gAgent.changeCameraToCustomizeAvatar();
 	}
diff --git a/indra/newview/lltoolbrush.cpp b/indra/newview/lltoolbrush.cpp
index 6bdd4e77676..92233c0d9f3 100644
--- a/indra/newview/lltoolbrush.cpp
+++ b/indra/newview/lltoolbrush.cpp
@@ -648,9 +648,9 @@ void LLToolBrushLand::alertNoTerraform(LLViewerRegion* regionp)
 {
 	if (!regionp) return;
 	
-	LLStringUtil::format_map_t args;
-	args["[REGION]"] = regionp->getName();
-	gViewerWindow->alertXml("RegionNoTerraforming", args);
+	LLSD args;
+	args["REGION"] = regionp->getName();
+	LLNotifications::instance().add("RegionNoTerraforming", args);
 
 }
 
diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp
index 25b58e14097..7459a23bef2 100644
--- a/indra/newview/lltooldraganddrop.cpp
+++ b/indra/newview/lltooldraganddrop.cpp
@@ -1052,9 +1052,9 @@ BOOL LLToolDragAndDrop::handleDropTextureProtections(LLViewerObject* hit_obj,
 	if (hit_obj->isInventoryDirty())
 	{
 		hit_obj->fetchInventoryFromServer();
-		LLStringUtil::format_map_t args;
-		args["[ERROR_MESSAGE]"] = "Unable to add texture.\nPlease wait a few seconds and try again.";
-		gViewerWindow->alertXml("ErrorMessage", args);
+		LLSD args;
+		args["ERROR_MESSAGE"] = "Unable to add texture.\nPlease wait a few seconds and try again.";
+		LLNotifications::instance().add("ErrorMessage", args);
 		return FALSE;
 	}
 	if (hit_obj->getInventoryItemByAsset(item->getAssetUUID()))
@@ -1505,45 +1505,42 @@ void LLToolDragAndDrop::giveInventory(const LLUUID& to_agent,
 	else
 	{
 		// ask if the agent is sure.
-		LLGiveInventoryInfo* info = new LLGiveInventoryInfo(to_agent,
-															item->getUUID(),
-															im_session_id);
-
-		gViewerWindow->alertXml("CannotCopyWarning",
-								&LLToolDragAndDrop::handleCopyProtectedItem,
-								(void*)info);
+		LLSD payload;
+		payload["agent_id"] = to_agent;
+		payload["item_id"] = item->getUUID();
+		LLNotifications::instance().add("CannotCopyWarning", LLSD(), payload, 
+		        &LLToolDragAndDrop::handleCopyProtectedItem);
 	}
 }
-
 // static
-void LLToolDragAndDrop::handleCopyProtectedItem(S32 option, void* data)
+bool LLToolDragAndDrop::handleCopyProtectedItem(const LLSD& notification, const LLSD& response)
 {
-	LLGiveInventoryInfo* info = (LLGiveInventoryInfo*)data;
+	S32 option = LLNotification::getSelectedOption(notification, response);
 	LLInventoryItem* item = NULL;
 	switch(option)
 	{
 	case 0:  // "Yes"
-		item = gInventory.getItem(info->mInventoryObjectID);
+		item = gInventory.getItem(notification["payload"]["item_id"].asUUID());
 		if(item)
 		{
-			LLToolDragAndDrop::commitGiveInventoryItem(info->mToAgentID,
-													   item,
-													   info->mIMSessionID);
+			LLToolDragAndDrop::commitGiveInventoryItem(notification["payload"]["agent_id"].asUUID(),
+													   item);
 			// delete it for now - it will be deleted on the server
 			// quickly enough.
-			gInventory.deleteObject(info->mInventoryObjectID);
+			gInventory.deleteObject(notification["payload"]["item_id"].asUUID());
 			gInventory.notifyObservers();
 		}
 		else
 		{
-			gViewerWindow->alertXml("CannotGiveItem");		
+			LLNotifications::instance().add("CannotGiveItem");		
 		}
 		break;
 
 	default: // no, cancel, whatever, who cares, not yes.
-		gViewerWindow->alertXml("TransactionCancelled");
+		LLNotifications::instance().add("TransactionCancelled");
 		break;
 	}
+	return false;
 }
 
 // static
@@ -1592,7 +1589,7 @@ void LLToolDragAndDrop::commitGiveInventoryItem(const LLUUID& to_agent,
 	// If this item was given by drag-and-drop into an IM panel, log this action in the IM panel chat.
 	if (im_session_id != LLUUID::null)
 	{
-		LLStringUtil::format_map_t args;
+		LLSD args;
 		gIMMgr->addSystemMessage(im_session_id, "inventory_item_offered", args);
 	}
 
@@ -1632,18 +1629,18 @@ void LLToolDragAndDrop::giveInventoryCategory(const LLUUID& to_agent,
 	}
 	if(!complete)
 	{
-		LLNotifyBox::showXml("IncompleteInventory");
+		LLNotifications::instance().add("IncompleteInventory");
 		return;
 	}
  	count = items.count() + cats.count();
  	if(count > MAX_ITEMS)
   	{
-		gViewerWindow->alertXml("TooManyItems");
+		LLNotifications::instance().add("TooManyItems");
   		return;
   	}
  	else if(count == 0)
   	{
-		gViewerWindow->alertXml("NoItems");
+		LLNotifications::instance().add("NoItems");
   		return;
   	}
 	else
@@ -1656,29 +1653,29 @@ void LLToolDragAndDrop::giveInventoryCategory(const LLUUID& to_agent,
 		{
 			LLGiveInventoryInfo* info = NULL;
 			info = new LLGiveInventoryInfo(to_agent, cat->getUUID());
-			LLStringUtil::format_map_t args;
-			args["[COUNT]"] = llformat("%d",giveable.countNoCopy());
-			gViewerWindow->alertXml("CannotCopyCountItems", args,
-				&LLToolDragAndDrop::handleCopyProtectedCategory,
-				(void*)info);
-				
+			LLSD args;
+			args["COUNT"] = llformat("%d",giveable.countNoCopy());
+			LLSD payload;
+			payload["agent_id"] = to_agent;
+			payload["folder_id"] = cat->getUUID();
+			LLNotifications::instance().add("CannotCopyCountItems", args, payload, &LLToolDragAndDrop::handleCopyProtectedCategory);
 		}
 	}
 }
 
 
 // static
-void LLToolDragAndDrop::handleCopyProtectedCategory(S32 option, void* data)
+bool LLToolDragAndDrop::handleCopyProtectedCategory(const LLSD& notification, const LLSD& response)
 {
-	LLGiveInventoryInfo* info = (LLGiveInventoryInfo*)data;
+	S32 option = LLNotification::getSelectedOption(notification, response);
 	LLInventoryCategory* cat = NULL;
 	switch(option)
 	{
 	case 0:  // "Yes"
-		cat = gInventory.getCategory(info->mInventoryObjectID);
+		cat = gInventory.getCategory(notification["payload"]["folder_id"].asUUID());
 		if(cat)
 		{
-			LLToolDragAndDrop::commitGiveInventoryCategory(info->mToAgentID,
+			LLToolDragAndDrop::commitGiveInventoryCategory(notification["payload"]["agent_id"].asUUID(),
 														   cat);
 			LLViewerInventoryCategory::cat_array_t cats;
 			LLViewerInventoryItem::item_array_t items;
@@ -1697,14 +1694,15 @@ void LLToolDragAndDrop::handleCopyProtectedCategory(S32 option, void* data)
 		}
 		else
 		{
-			gViewerWindow->alertXml("CannotGiveCategory");
+			LLNotifications::instance().add("CannotGiveCategory");
 		}
 		break;
 
 	default: // no, cancel, whatever, who cares, not yes.
-		gViewerWindow->alertXml("TransactionCancelled");
+		LLNotifications::instance().add("TransactionCancelled");
 		break;
 	}
+	return false;
 }
 
 // static
@@ -1731,12 +1729,12 @@ void LLToolDragAndDrop::commitGiveInventoryCategory(const LLUUID& to_agent,
  	S32 count = items.count() + cats.count();
  	if(count > MAX_ITEMS)
   	{
-		gViewerWindow->alertXml("TooManyItems");
+		LLNotifications::instance().add("TooManyItems");
   		return;
   	}
  	else if(count == 0)
   	{
-		gViewerWindow->alertXml("NoItems");
+		LLNotifications::instance().add("NoItems");
   		return;
   	}
 	else
@@ -2299,7 +2297,7 @@ EAcceptance LLToolDragAndDrop::dad3dWearItem(
 			// destroy clothing items.
 			if (!gAgent.areWearablesLoaded()) 
 			{
-				gViewerWindow->alertXml("CanNotChangeAppearanceUntilLoaded");
+				LLNotifications::instance().add("CanNotChangeAppearanceUntilLoaded");
 				return ACCEPT_NO;
 			}
 
@@ -2394,7 +2392,7 @@ EAcceptance LLToolDragAndDrop::dad3dWearCategory(
 		// destroy clothing items.
 		if (!gAgent.areWearablesLoaded()) 
 		{
-			gViewerWindow->alertXml("CanNotChangeAppearanceUntilLoaded");
+			LLNotifications::instance().add("CanNotChangeAppearanceUntilLoaded");
 			return ACCEPT_NO;
 		}
 	}
diff --git a/indra/newview/lltooldraganddrop.h b/indra/newview/lltooldraganddrop.h
index 627ef86c383..462e57b390b 100644
--- a/indra/newview/lltooldraganddrop.h
+++ b/indra/newview/lltooldraganddrop.h
@@ -209,13 +209,13 @@ class LLToolDragAndDrop : public LLTool, public LLSingleton<LLToolDragAndDrop>
 
 
 	// give inventory item functionality
-	static void handleCopyProtectedItem(S32 option, void* data);
+	static bool handleCopyProtectedItem(const LLSD& notification, const LLSD& response);
 	static void commitGiveInventoryItem(const LLUUID& to_agent,
 										LLInventoryItem* item,
 										const LLUUID &im_session_id = LLUUID::null);
 
 	// give inventory category functionality
-	static void handleCopyProtectedCategory(S32 option, void* data);
+	static bool handleCopyProtectedCategory(const LLSD& notification, const LLSD& response);
 	static void commitGiveInventoryCategory(const LLUUID& to_agent,
 						LLInventoryCategory* cat);
 public:
diff --git a/indra/newview/llurldispatcher.cpp b/indra/newview/llurldispatcher.cpp
index 477146a473b..3f6227ee564 100644
--- a/indra/newview/llurldispatcher.cpp
+++ b/indra/newview/llurldispatcher.cpp
@@ -43,7 +43,6 @@
 #include "llpanellogin.h"
 #include "llstartup.h"			// gStartupState
 #include "llurlsimstring.h"
-#include "llviewerwindow.h"		// alertXml()
 #include "llweb.h"
 #include "llworldmap.h"
 
@@ -147,8 +146,8 @@ bool LLURLDispatcherImpl::dispatchCore(const std::string& url,
 	/*
 	// Inform the user we can't handle this
 	std::map<std::string, std::string> args;
-	args["[SLURL]"] = url;
-	gViewerWindow->alertXml("BadURL", args);
+	args["SLURL"] = url;
+	r;
 	*/
 	
 	return false;
diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
index c28ed7c435f..e52b3a9b837 100644
--- a/indra/newview/llviewerinventory.cpp
+++ b/indra/newview/llviewerinventory.cpp
@@ -403,7 +403,7 @@ void LLViewerInventoryCategory::updateServer(BOOL is_new) const
 	// communicate that change with the server.
 	if(LLAssetType::AT_NONE != mPreferredType)
 	{
-		LLNotifyBox::showXml("CannotModifyProtectedCategories");
+		LLNotifications::instance().add("CannotModifyProtectedCategories");
 		return;
 	}
 
@@ -427,7 +427,7 @@ void LLViewerInventoryCategory::removeFromServer( void )
 	// communicate that change with the server.
 	if(LLAssetType::AT_NONE != mPreferredType)
 	{
-		LLNotifyBox::showXml("CannotRemoveProtectedCategories");
+		LLNotifications::instance().add("CannotRemoveProtectedCategories");
 		return;
 	}
 
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index c8ad7fad979..5131b77a7c0 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -1,3 +1,4 @@
+
 /** 
  * @file llviewermenu.cpp
  * @brief Builds menus out of items.
@@ -309,7 +310,7 @@ BOOL is_selection_buy_not_take();
 S32 selection_price();
 BOOL enable_take();
 void handle_take();
-void confirm_take(S32 option, void* data);
+bool confirm_take(const LLSD& notification, const LLSD& response);
 BOOL enable_buy(void*); 
 void handle_buy(void *);
 void handle_buy_object(LLSaleInfo sale_info);
@@ -999,6 +1000,7 @@ void init_debug_world_menu(LLMenuGL* menu)
 
 void handle_export_menus_to_xml(void*)
 {
+
 	LLFilePicker& picker = LLFilePicker::instance();
 	if(!picker.getSaveFile(LLFilePicker::FFSAVE_XML))
 	{
@@ -2122,9 +2124,10 @@ class LLGoToObject : public view_listener_t
 //---------------------------------------------------------------------------
 // Parcel freeze, eject, etc.
 //---------------------------------------------------------------------------
-void callback_freeze(S32 option, void* data)
+bool callback_freeze(const LLSD& notification, const LLSD& response)
 {
-	LLUUID* avatar_id = (LLUUID*) data;
+	LLUUID avatar_id = notification["payload"]["avatar_id"].asUUID();
+	S32 option = LLNotification::getSelectedOption(notification, response);
 
 	if (0 == option || 1 == option)
 	{
@@ -2136,7 +2139,7 @@ void callback_freeze(S32 option, void* data)
 		}
 
 		LLMessageSystem* msg = gMessageSystem;
-		LLViewerObject* avatar = gObjectList.findObject(*avatar_id);
+		LLViewerObject* avatar = gObjectList.findObject(avatar_id);
 
 		if (avatar)
 		{
@@ -2145,16 +2148,15 @@ void callback_freeze(S32 option, void* data)
 			msg->addUUID("AgentID", gAgent.getID());
 			msg->addUUID("SessionID", gAgent.getSessionID());
 			msg->nextBlock("Data");
-			msg->addUUID("TargetID", *avatar_id );
+			msg->addUUID("TargetID", avatar_id );
 			msg->addU32("Flags", flags );
 			msg->sendReliable( avatar->getRegion()->getHost() );
 		}
 	}
-
-	delete avatar_id;
-	avatar_id = NULL;
+	return false;
 }
 
+
 class LLAvatarFreeze : public view_listener_t
 {
 	bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
@@ -2162,23 +2164,25 @@ class LLAvatarFreeze : public view_listener_t
 		LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() );
 		if( avatar )
 		{
-			LLUUID* avatar_id = new LLUUID( avatar->getID() );
 			std::string fullname = avatar->getFullname();
+			LLSD payload;
+			payload["avatar_id"] = avatar->getID();
 
 			if (!fullname.empty())
 			{
-				LLStringUtil::format_map_t args;
-				args["[AVATAR_NAME]"] = fullname;
-				gViewerWindow->alertXml("FreezeAvatarFullname",
+				LLSD args;
+				args["AVATAR_NAME"] = fullname;
+				LLNotifications::instance().add("FreezeAvatarFullname",
 							args,
-							callback_freeze,
-							(void*)avatar_id);
+							payload,
+							callback_freeze);
 			}
 			else
 			{
-				gViewerWindow->alertXml("FreezeAvatar",
-							callback_freeze,
-							(void*)avatar_id);
+				LLNotifications::instance().add("FreezeAvatar",
+							LLSD(),
+							payload,
+							callback_freeze);
 			}
 		}
 		return true;
@@ -2224,26 +2228,16 @@ class LLAvatarDebug : public view_listener_t
 	}
 };
 
-struct MenuCallbackData
+bool callback_eject(const LLSD& notification, const LLSD& response)
 {
-	bool ban_enabled;
-	LLUUID avatar_id;
-};
-
-void callback_eject(S32 option, void* data)
-{
-	MenuCallbackData *callback_data = (MenuCallbackData*)data;
-	if (!callback_data)
-	{
-		return;
-	}
+	S32 option = LLNotification::getSelectedOption(notification, response);
 	if (2 == option)
 	{
-		// Cancle button.
-		return;
+		// Cancel button.
+		return false;
 	}
-	LLUUID avatar_id = callback_data->avatar_id;
-	bool ban_enabled = callback_data->ban_enabled;
+	LLUUID avatar_id = notification["payload"]["avatar_id"].asUUID();
+	bool ban_enabled = notification["payload"]["ban_enabled"].asBoolean();
 
 	if (0 == option)
 	{
@@ -2285,10 +2279,7 @@ void callback_eject(S32 option, void* data)
 			msg->sendReliable( avatar->getRegion()->getHost() );
 		}
 	}
-
-
-	delete callback_data;
-	callback_data = NULL;
+	return false;
 }
 
 class LLAvatarEject : public view_listener_t
@@ -2298,8 +2289,8 @@ class LLAvatarEject : public view_listener_t
 		LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() );
 		if( avatar )
 		{
-			MenuCallbackData *data = new MenuCallbackData;
-			(*data).avatar_id = avatar->getID();
+			LLSD payload;
+			payload["avatar_id"] = avatar->getID();
 			std::string fullname = avatar->getFullname();
 
 			const LLVector3d& pos = avatar->getPositionGlobal();
@@ -2307,40 +2298,42 @@ class LLAvatarEject : public view_listener_t
 			
 			if (LLViewerParcelMgr::getInstance()->isParcelOwnedByAgent(parcel,GP_LAND_MANAGE_BANNED))
 			{
-				(*data).ban_enabled = true;
+                payload["ban_enabled"] = true;
 				if (!fullname.empty())
 				{
-					LLStringUtil::format_map_t args;
-					args["[AVATAR_NAME]"] = fullname;
-					gViewerWindow->alertXml("EjectAvatarFullname",
-						args,
-						callback_eject,
-						(void*)data);
+    				LLSD args;
+    				args["AVATAR_NAME"] = fullname;
+    				LLNotifications::instance().add("EjectAvatarFullname",
+    							args,
+    							payload,
+    							callback_eject);
 				}
 				else
 				{
-					gViewerWindow->alertXml("EjectAvatar",
-						callback_eject,
-						(void*)data);
+    				LLNotifications::instance().add("EjectAvatarFullname",
+    							LLSD(),
+    							payload,
+    							callback_eject);
 				}
 			}
 			else
 			{
-				(*data).ban_enabled = false;
+                payload["ban_enabled"] = false;
 				if (!fullname.empty())
 				{
-					LLStringUtil::format_map_t args;
-					args["[AVATAR_NAME]"] = fullname;
-					gViewerWindow->alertXml("EjectAvatarFullnameNoBan",
-						args,
-						callback_eject,
-						(void*)data);
+    				LLSD args;
+    				args["AVATAR_NAME"] = fullname;
+    				LLNotifications::instance().add("EjectAvatarFullnameNoBan",
+    							args,
+    							payload,
+    							callback_eject);
 				}
 				else
 				{
-					gViewerWindow->alertXml("EjectAvatarNoBan",
-						callback_eject,
-						(void*)data);
+    				LLNotifications::instance().add("EjectAvatarNoBan",
+    							LLSD(),
+    							payload,
+    							callback_eject);
 				}
 			}
 		}
@@ -2387,13 +2380,16 @@ class LLAvatarGiveCard : public view_listener_t
 		if(dest && dest->isAvatar())
 		{
 			bool found_name = false;
-			LLStringUtil::format_map_t args;
+			LLSD args;
+			LLSD old_args;
 			LLNameValue* nvfirst = dest->getNVPair("FirstName");
 			LLNameValue* nvlast = dest->getNVPair("LastName");
 			if(nvfirst && nvlast)
 			{
-				args["[FIRST]"] = nvfirst->getString();
-				args["[LAST]"] = nvlast->getString();
+				args["FIRST"] = nvfirst->getString();
+				args["LAST"] = nvlast->getString();
+				old_args["FIRST"] = nvfirst->getString();
+				old_args["LAST"] = nvlast->getString();
 				found_name = true;
 			}
 			LLViewerRegion* region = dest->getRegion();
@@ -2415,11 +2411,11 @@ class LLAvatarGiveCard : public view_listener_t
 				transaction_id.generate();
 				msg->addUUIDFast(_PREHASH_TransactionID, transaction_id);
 				msg->sendReliable(dest_host);
-				LLNotifyBox::showXml("OfferedCard", args);
+				LLNotifications::instance().add("OfferedCard", args);
 			}
 			else
 			{
-				gViewerWindow->alertXml("CantOfferCallingCard", args);
+				LLNotifications::instance().add("CantOfferCallingCard", old_args);
 			}
 		}
 		return true;
@@ -2436,8 +2432,9 @@ void login_done(S32 which, void *user)
 }
 
 
-void callback_leave_group(S32 option, void *userdata)
+bool callback_leave_group(const LLSD& notification, const LLSD& response)
 {
+	S32 option = LLNotification::getSelectedOption(notification, response);
 	if (option == 0)
 	{
 		LLMessageSystem *msg = gMessageSystem;
@@ -2450,15 +2447,16 @@ void callback_leave_group(S32 option, void *userdata)
 		msg->addUUIDFast(_PREHASH_GroupID, gAgent.mGroupID );
 		gAgent.sendReliableMessage();
 	}
+	return false;
 }
 
 void handle_leave_group(void *)
 {
 	if (gAgent.getGroupID() != LLUUID::null)
 	{
-		LLStringUtil::format_map_t args;
-		args["[GROUP]"] = gAgent.mGroupName;
-		gViewerWindow->alertXml("GroupLeaveConfirmMember", args, callback_leave_group);
+		LLSD args;
+		args["GROUP"] = gAgent.mGroupName;
+		LLNotifications::instance().add("GroupLeaveConfirmMember", args, LLSD(), callback_leave_group);
 	}
 }
 
@@ -2521,7 +2519,7 @@ void handle_buy_object(LLSaleInfo sale_info)
 {
 	if(!LLSelectMgr::getInstance()->selectGetAllRootsValid())
 	{
-		LLNotifyBox::showXml("UnableToBuyWhileDownloading");
+		LLNotifications::instance().add("UnableToBuyWhileDownloading");
 		return;
 	}
 
@@ -2530,7 +2528,7 @@ void handle_buy_object(LLSaleInfo sale_info)
 	BOOL owners_identical = LLSelectMgr::getInstance()->selectGetOwner(owner_id, owner_name);
 	if (!owners_identical)
 	{
-		LLNotifyBox::showXml("CannotBuyObjectsFromDifferentOwners");
+		LLNotifications::instance().add("CannotBuyObjectsFromDifferentOwners");
 		return;
 	}
 
@@ -2540,7 +2538,7 @@ void handle_buy_object(LLSaleInfo sale_info)
 	valid &= LLSelectMgr::getInstance()->selectGetAggregatePermissions(ag_perm);
 	if(!valid || !sale_info.isForSale() || !perm.allowTransferTo(gAgent.getID()))
 	{
-		LLNotifyBox::showXml("ObjectNotForSale");
+		LLNotifications::instance().add("ObjectNotForSale");
 		return;
 	}
 
@@ -2686,22 +2684,22 @@ void set_god_level(U8 god_level)
 	// inventory in items may change in god mode
 	gObjectList.dirtyAllObjectInventory();
 
-    if(gViewerWindow)
-    {
-        gViewerWindow->setMenuBackgroundColor(god_level > GOD_NOT,
+        if(gViewerWindow)
+        {
+            gViewerWindow->setMenuBackgroundColor(god_level > GOD_NOT,
             LLViewerLogin::getInstance()->isInProductionGrid());
-    }
-
-    LLStringUtil::format_map_t args;
+        }
+    
+        LLSD args;
 	if(god_level > GOD_NOT)
 	{
-		args["[LEVEL]"] = llformat("%d",(S32)god_level);
-		LLNotifyBox::showXml("EnteringGodMode", args);
+		args["LEVEL"] = llformat("%d",(S32)god_level);
+		LLNotifications::instance().add("EnteringGodMode", args);
 	}
 	else
 	{
-		args["[LEVEL]"] = llformat("%d",(S32)old_god_level);
-		LLNotifyBox::showXml("LeavingGodMode", args);
+		args["LEVEL"] = llformat("%d",(S32)old_god_level);
+		LLNotifications::instance().add("LeavingGodMode", args);
 	}
 
 
@@ -2826,13 +2824,13 @@ void request_friendship(const LLUUID& dest_id)
 	if(dest && dest->isAvatar())
 	{
 		std::string fullname;
-		LLStringUtil::format_map_t args;
+		LLSD args;
 		LLNameValue* nvfirst = dest->getNVPair("FirstName");
 		LLNameValue* nvlast = dest->getNVPair("LastName");
 		if(nvfirst && nvlast)
 		{
-			args["[FIRST]"] = nvfirst->getString();
-			args["[LAST]"] = nvlast->getString();
+			args["FIRST"] = nvfirst->getString();
+			args["LAST"] = nvlast->getString();
 			fullname = nvfirst->getString();
 			fullname += " ";
 			fullname += nvlast->getString();
@@ -2843,7 +2841,7 @@ void request_friendship(const LLUUID& dest_id)
 		}
 		else
 		{
-			gViewerWindow->alertXml("CantOfferFriendship");
+			LLNotifications::instance().add("CantOfferFriendship");
 		}
 	}
 }
@@ -2853,12 +2851,8 @@ class LLEditEnableCustomizeAvatar : public view_listener_t
 {
 	bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
 	{
-		LLVOAvatar* avatar = gAgent.getAvatarObject();
-
-		bool enabled = ((avatar && avatar->isFullyLoaded()) &&
-				   (gAgent.getWearablesLoaded()));
-
-		gMenuHolder->findControl(userdata["control"].asString())->setValue(enabled);
+		bool new_value = gAgent.areWearablesLoaded();
+		gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value);
 		return true;
 	}
 };
@@ -3184,7 +3178,7 @@ void disabled_duplicate(void*)
 {
 	if (LLSelectMgr::getInstance()->getSelection()->getPrimaryObject())
 	{
-		LLNotifyBox::showXml("CopyFailed");
+		LLNotifications::instance().add("CopyFailed");
 	}
 }
 
@@ -3317,7 +3311,7 @@ void handle_claim_public_land(void*)
 {
 	if (LLViewerParcelMgr::getInstance()->getSelectionRegion() != gAgent.getRegion())
 	{
-		LLNotifyBox::showXml("ClaimPublicLand");
+		LLNotifications::instance().add("ClaimPublicLand");
 		return;
 	}
 
@@ -3550,7 +3544,7 @@ void derez_objects(EDeRezDestination dest, const LLUUID& dest_id)
 	}
 	else if(!error.empty())
 	{
-		gViewerWindow->alertXml(error);
+		LLNotifications::instance().add(error);
 	}
 }
 
@@ -3577,16 +3571,13 @@ class LLObjectReturn : public view_listener_t
 		
 		mObjectSelection = LLSelectMgr::getInstance()->getEditSelection();
 
-		gViewerWindow->alertXml("ReturnToOwner",
-			onReturnToOwner,
-			(void*)this);
+		LLNotifications::instance().add("ReturnToOwner", LLSD(), LLSD(), boost::bind(&LLObjectReturn::onReturnToOwner, this, _1, _2));
 		return true;
 	}
 
-	static void onReturnToOwner(S32 option, void* data)
+	bool onReturnToOwner(const LLSD& notification, const LLSD& response)
 	{
-		LLObjectReturn* object_return = (LLObjectReturn*)data;
-
+		S32 option = LLNotification::getSelectedOption(notification, response);
 		if (0 == option)
 		{
 			// Ignore category ID for this derez destination.
@@ -3594,7 +3585,8 @@ class LLObjectReturn : public view_listener_t
 		}
 
 		// drop reference to current selection
-		object_return->mObjectSelection = NULL;
+		mObjectSelection = NULL;
+		return false;
 	}
 
 protected:
@@ -3731,48 +3723,46 @@ void handle_take()
 	{
 		category_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_OBJECT);
 	}
-	LLUUID* cat_id = new LLUUID(category_id);
+	LLSD payload;
+	payload["folder_id"] = category_id;
+
+	LLNotification::Params params("ConfirmObjectTakeLock");
+	params.payload(payload)
+		.functor(confirm_take);
+
 	if(locked_but_takeable_object ||
 	   !you_own_everything)
 	{
 		if(locked_but_takeable_object && you_own_everything)
 		{
-			gViewerWindow->alertXml("ConfirmObjectTakeLock",
-			confirm_take,
-			(void*)cat_id);
+			params.name("ConfirmObjectTakeLock");
 
 		}
 		else if(!locked_but_takeable_object && !you_own_everything)
 		{
-			gViewerWindow->alertXml("ConfirmObjectTakeNoOwn",
-			confirm_take,
-			(void*)cat_id);
+			params.name("ConfirmObjectTakeNoOwn");
 		}
 		else
 		{
-			gViewerWindow->alertXml("ConfirmObjectTakeLockNoOwn",
-			confirm_take,
-			(void*)cat_id);
+			params.name("ConfirmObjectTakeLockNoOwn");
 		}
-
-
+	
+		LLNotifications::instance().add(params);
 	}
-
 	else
 	{
-		confirm_take(0, (void*)cat_id);
+		LLNotifications::instance().forceResponse(params, 0);
 	}
 }
 
-void confirm_take(S32 option, void* data)
+bool confirm_take(const LLSD& notification, const LLSD& response)
 {
-	LLUUID* cat_id = (LLUUID*)data;
-	if(!cat_id) return;
+	S32 option = LLNotification::getSelectedOption(notification, response);
 	if(enable_take() && (option == 0))
 	{
-		derez_objects(DRD_TAKE_INTO_AGENT_INVENTORY, *cat_id);
+		derez_objects(DRD_TAKE_INTO_AGENT_INVENTORY, notification["payload"]["folder_id"].asUUID());
 	}
-	delete cat_id;
+	return false;
 }
 
 // You can take an item when it is public and transferrable, or when
@@ -3934,13 +3924,15 @@ S32 selection_price()
 	return total_price;
 }
 
-void callback_show_buy_currency(S32 option, void*)
+bool callback_show_buy_currency(const LLSD& notification, const LLSD& response)
 {
+	S32 option = LLNotification::getSelectedOption(notification, response);
 	if (0 == option)
 	{
 		llinfos << "Loading page " << BUY_CURRENCY_URL << llendl;
 		LLWeb::loadURL(BUY_CURRENCY_URL);
 	}
+	return false;
 }
 
 
@@ -3955,14 +3947,13 @@ void show_buy_currency(const char* extra)
 	}
 	mesg << "Go to " << BUY_CURRENCY_URL << "\nfor information on purchasing currency?";
 
-	LLStringUtil::format_map_t args;
+	LLSD args;
 	if (extra != NULL)
 	{
-		args["[EXTRA]"] = extra;
+		args["EXTRA"] = extra;
 	}
-	args["[URL]"] = BUY_CURRENCY_URL;
-	gViewerWindow->alertXml("PromptGoToCurrencyPage", args, 
-		callback_show_buy_currency);
+	args["URL"] = BUY_CURRENCY_URL;
+	LLNotifications::instance().add("PromptGoToCurrencyPage", args, LLSD(), callback_show_buy_currency);
 }
 
 void handle_buy_currency(void*)
@@ -4142,29 +4133,29 @@ class LLToolsLink : public view_listener_t
 	{
 		if(!LLSelectMgr::getInstance()->selectGetAllRootsValid())
 		{
-			LLNotifyBox::showXml("UnableToLinkWhileDownloading");
+			LLNotifications::instance().add("UnableToLinkWhileDownloading");
 			return true;
 		}
 
 		S32 object_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount();
 		if (object_count > MAX_CHILDREN_PER_TASK + 1)
 		{
-			LLStringUtil::format_map_t args;
-			args["[COUNT]"] = llformat("%d", object_count);
+			LLSD args;
+			args["COUNT"] = llformat("%d", object_count);
 			int max = MAX_CHILDREN_PER_TASK+1;
-			args["[MAX]"] = llformat("%d", max);
-			gViewerWindow->alertXml("UnableToLinkObjects", args);
+			args["MAX"] = llformat("%d", max);
+			LLNotifications::instance().add("UnableToLinkObjects", args);
 			return true;
 		}
 
 		if(LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() < 2)
 		{
-			gViewerWindow->alertXml("CannotLinkIncompleteSet");
+			LLNotifications::instance().add("CannotLinkIncompleteSet");
 			return true;
 		}
 		if(!LLSelectMgr::getInstance()->selectGetRootsModify())
 		{
-			gViewerWindow->alertXml("CannotLinkModify");
+			LLNotifications::instance().add("CannotLinkModify");
 			return true;
 		}
 		LLUUID owner_id;
@@ -4174,7 +4165,7 @@ class LLToolsLink : public view_listener_t
 			// we don't actually care if you're the owner, but novices are
 			// the most likely to be stumped by this one, so offer the
 			// easiest and most likely solution.
-			gViewerWindow->alertXml("CannotLinkDifferentOwners");
+			LLNotifications::instance().add("CannotLinkDifferentOwners");
 			return true;
 		}
 		LLSelectMgr::getInstance()->sendLink();
@@ -4738,7 +4729,7 @@ class LLWorldSetBusy : public view_listener_t
 		else
 		{
 			gAgent.setBusy();
-			gViewerWindow->alertXml("BusyModeSet");
+			LLNotifications::instance().add("BusyModeSet");
 		}
 		return true;
 	}
@@ -4764,7 +4755,7 @@ class LLWorldCreateLandmark : public view_listener_t
 		if (!agent_parcel->getAllowLandmark()
 			&& !LLViewerParcelMgr::isParcelOwnedByAgent(agent_parcel, GP_LAND_ALLOW_LANDMARK))
 		{
-			gViewerWindow->alertXml("CannotCreateLandmarkNotOwner");
+			LLNotifications::instance().add("CannotCreateLandmarkNotOwner");
 			return true;
 		}
 
@@ -4871,16 +4862,14 @@ class LLAvatarAddFriend : public view_listener_t
 	}
 };
 
-void complete_give_money(S32 option, void* user_data)
+bool complete_give_money(const LLSD& notification, const LLSD& response, LLObjectSelectionHandle handle)
 {
+	S32 option = LLNotification::getSelectedOption(notification, response);
 	if (option == 0)
 	{
 		gAgent.clearBusy();
 	}
 
-	LLObjectSelectionHandle handle(*(LLObjectSelectionHandle*)user_data);
-	delete (LLObjectSelectionHandle*)user_data;
-
 	LLViewerObject* objectp = handle->getPrimaryObject();
 
 	// Show avatar's name if paying attachment
@@ -4906,19 +4895,22 @@ void complete_give_money(S32 option, void* user_data)
 			LLFloaterPay::payViaObject(&give_money, objectp->getID());
 		}
 	}
+	return false;
 }
 
 bool handle_give_money_dialog()
 {
-	LLObjectSelectionHandle* handlep = new LLObjectSelectionHandle(LLSelectMgr::getInstance()->getSelection());
+	LLNotification::Params params("BusyModePay");
+	params.functor(boost::bind(complete_give_money, _1, _2, LLSelectMgr::getInstance()->getSelection()));
+
 	if (gAgent.getBusy())
 	{
 		// warn users of being in busy mode during a transaction
-		gViewerWindow->alertXml("BusyModePay", complete_give_money, handlep);
+		LLNotifications::instance().add(params);
 	}
 	else
 	{
-		complete_give_money(1, handlep);
+		LLNotifications::instance().forceResponse(params, 1);
 	}
 	return true;
 }
@@ -5069,7 +5061,7 @@ class LLShowFloater : public view_listener_t
 		}
 		else if (floater_name == "appearance")
 		{
-			if (gAgent.getWearablesLoaded())
+			if (gAgent.areWearablesLoaded())
 			{
 				gAgent.changeCameraToCustomizeAvatar();
 			}
@@ -5272,14 +5264,14 @@ class LLFloaterVisible : public view_listener_t
 	}
 };
 
-void callback_show_url(S32 option, void* data)
+bool callback_show_url(const LLSD& notification, const LLSD& response)
 {
-	std::string* urlp = (std::string*)data;
+	S32 option = LLNotification::getSelectedOption(notification, response);
 	if (0 == option)
 	{
-		LLWeb::loadURL(*urlp);
+		LLWeb::loadURL(notification["payload"]["url"].asString());
 	}
-	delete urlp;
+	return false;
 }
 
 class LLPromptShowURL : public view_listener_t
@@ -5292,15 +5284,16 @@ class LLPromptShowURL : public view_listener_t
 		{
 			std::string alert = param.substr(0, offset);
 			std::string url = param.substr(offset+1);
-			std::string* url_copy = new std::string(url);
 
 			if(gSavedSettings.getBOOL("UseExternalBrowser"))
 			{ 
-				gViewerWindow->alertXml(alert, callback_show_url, url_copy);
+    			LLSD payload;
+    			payload["url"] = url;
+    			LLNotifications::instance().add(alert, LLSD(), payload, callback_show_url);
 			}
 			else
 			{
-				callback_show_url(0, url_copy);
+		        LLWeb::loadURL(url);
 			}
 		}
 		else
@@ -5311,6 +5304,39 @@ class LLPromptShowURL : public view_listener_t
 	}
 };
 
+bool callback_show_file(const LLSD& notification, const LLSD& response)
+{
+	S32 option = LLNotification::getSelectedOption(notification, response);
+	if (0 == option)
+	{
+		LLWeb::loadURL(notification["payload"]["url"]);
+	}
+	return false;
+}
+
+class LLPromptShowFile : public view_listener_t
+{
+	bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+	{
+		std::string param = userdata.asString();
+		std::string::size_type offset = param.find(",");
+		if (offset != param.npos)
+		{
+			std::string alert = param.substr(0, offset);
+			std::string file = param.substr(offset+1);
+
+			LLSD payload;
+			payload["url"] = file;
+			LLNotifications::instance().add(alert, LLSD(), payload, callback_show_file);
+		}
+		else
+		{
+			llinfos << "PromptShowFile invalid parameters! Expecting \"ALERT,FILE\"." << llendl;
+		}
+		return true;
+	}
+};
+
 class LLShowAgentProfile : public view_listener_t
 {
 	bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
@@ -5940,11 +5966,11 @@ void queue_actions(LLFloaterScriptQueue* q, const std::string& noscriptmsg, cons
 	{
 		if ( !func.scripted )
 		{
-			gViewerWindow->alertXml(noscriptmsg);
+			LLNotifications::instance().add(noscriptmsg);
 		}
 		else if ( !func.modifiable )
 		{
-			gViewerWindow->alertXml(nomodmsg);
+			LLNotifications::instance().add(nomodmsg);
 		}
 		else
 		{
@@ -6933,7 +6959,7 @@ void handle_save_to_xml(void*)
 	LLFloater* frontmost = gFloaterView->getFrontmost();
 	if (!frontmost)
 	{
-		gViewerWindow->alertXml("NoFrontmostFloater");
+        LLNotifications::instance().add("NoFrontmostFloater");
 		return;
 	}
 
diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp
index 33c21b40614..5f42aff5265 100644
--- a/indra/newview/llviewermenufile.cpp
+++ b/indra/newview/llviewermenufile.cpp
@@ -178,9 +178,9 @@ const std::string upload_pick(void* data)
 		std::string short_name = gDirUtilp->getBaseFileName(filename);
 		
 		// No extension
-		LLStringUtil::format_map_t args;
-		args["[FILE]"] = short_name;
-		gViewerWindow->alertXml("NoFileExtension", args);
+		LLSD args;
+		args["FILE"] = short_name;
+		LLNotifications::instance().add("NoFileExtension", args);
 		return std::string();
 	}
 	else
@@ -220,11 +220,11 @@ const std::string upload_pick(void* data)
 		{
 			//should only get here if the extension exists
 			//but is invalid
-			LLStringUtil::format_map_t args;
-			args["[EXTENSION]"] = ext;
-			args["[VALIDS]"] = valid_extensions;
-			gViewerWindow->alertXml("InvalidFileExtension", args);
-			return std::string();
+			LLSD args;
+			args["EXTENSION"] = ext;
+			args["VALIDS"] = valid_extensions;
+			LLNotifications::instance().add("InvalidFileExtension", args);
+			return NULL;
 		}
 	}//end else (non-null extension)
 
@@ -239,9 +239,9 @@ const std::string upload_pick(void* data)
 		if (check_for_invalid_wav_formats(filename,error_msg))
 		{
 			llinfos << error_msg << ": " << filename << llendl;
-			LLStringUtil::format_map_t args;
-			args["[FILE]"] = filename;
-			gViewerWindow->alertXml( error_msg, args );
+			LLSD args;
+			args["FILE"] = filename;
+			LLNotifications::instance().add( error_msg, args );
 			return std::string();
 		}
 	}//end if a wave/sound file
@@ -337,10 +337,10 @@ class LLFileUploadBulk : public view_listener_t
 	}
 };
 
-void upload_error(const std::string& error_message, const std::string& label, const std::string& filename, const LLStringUtil::format_map_t args) 
+void upload_error(const std::string& error_message, const std::string& label, const std::string& filename, const LLSD& args) 
 {
 	llwarns << error_message << llendl;
-	gViewerWindow->alertXml(label, args);
+	LLNotifications::instance().add(label, args);
 	if(LLFile::remove(filename) == -1)
 	{
 		lldebugs << "unable to remove temp file" << llendl;
@@ -531,10 +531,9 @@ void upload_new_resource(const std::string& src_filename, std::string name,
 	LLTransactionID tid;
 	LLAssetID uuid;
 	
-	LLStringUtil::format_map_t args;
+	LLSD args;
 
 	std::string exten = gDirUtilp->getExtension(src_filename);
-
 	LLAssetType::EType asset_type = LLAssetType::AT_NONE;
 	std::string error_message;
 
@@ -548,7 +547,7 @@ void upload_new_resource(const std::string& src_filename, std::string name,
 		error_message = llformat(
 				"No file extension for the file: '%s'\nPlease make sure the file has a correct file extension",
 				short_name.c_str());
-		args["[FILE]"] = short_name;
+		args["FILE"] = short_name;
  		upload_error(error_message, "NofileExtension", filename, args);
 		return;
 	}
@@ -560,9 +559,9 @@ void upload_new_resource(const std::string& src_filename, std::string name,
 												 IMG_CODEC_BMP ))
 		{
 			error_message = llformat( "Problem with file %s:\n\n%s\n",
-					 src_filename.c_str(), LLImage::getLastError().c_str());
-			args["[FILE]"] = src_filename;
-			args["[ERROR]"] = LLImage::getLastError();
+					src_filename.c_str(), LLImage::getLastError().c_str());
+			args["FILE"] = src_filename;
+			args["ERROR"] = LLImage::getLastError();
 			upload_error(error_message, "ProblemWithFile", filename, args);
 			return;
 		}
@@ -576,8 +575,8 @@ void upload_new_resource(const std::string& src_filename, std::string name,
 		{
 			error_message = llformat("Problem with file %s:\n\n%s\n",
 					src_filename.c_str(), LLImage::getLastError().c_str());
-			args["[FILE]"] = src_filename;
-			args["[ERROR]"] = LLImage::getLastError();
+			args["FILE"] = src_filename;
+			args["ERROR"] = LLImage::getLastError();
 			upload_error(error_message, "ProblemWithFile", filename, args);
 			return;
 		}
@@ -591,8 +590,8 @@ void upload_new_resource(const std::string& src_filename, std::string name,
 		{
 			error_message = llformat("Problem with file %s:\n\n%s\n",
 					src_filename.c_str(), LLImage::getLastError().c_str());
-			args["[FILE]"] = src_filename;
-			args["[ERROR]"] = LLImage::getLastError();
+			args["FILE"] = src_filename;
+			args["ERROR"] = LLImage::getLastError();
 			upload_error(error_message, "ProblemWithFile", filename, args);
 			return;
 		}
@@ -606,8 +605,8 @@ void upload_new_resource(const std::string& src_filename, std::string name,
  		{
  			error_message = llformat("Problem with file %s:\n\n%s\n",
  					src_filename.c_str(), LLImage::getLastError().c_str());
- 			args["[FILE]"] = src_filename;
- 			args["[ERROR]"] = LLImage::getLastError();
+ 			args["FILE"] = src_filename;
+ 			args["ERROR"] = LLImage::getLastError();
  			upload_error(error_message, "ProblemWithFile", filename, args);
  			return;
  		}
@@ -627,13 +626,13 @@ void upload_new_resource(const std::string& src_filename, std::string name,
 			{
 				case LLVORBISENC_DEST_OPEN_ERR:
 				    error_message = llformat( "Couldn't open temporary compressed sound file for writing: %s\n", filename.c_str());
-					args["[FILE]"] = filename;
+					args["FILE"] = filename;
 					upload_error(error_message, "CannotOpenTemporarySoundFile", filename, args);
 					break;
 
 				default:	
 				  error_message = llformat("Unknown vorbis encode failure on: %s\n", src_filename.c_str());
-					args["[FILE]"] = src_filename;
+					args["FILE"] = src_filename;
 					upload_error(error_message, "UnknownVorbisEncodeFailure", filename, args);
 					break;	
 			}	
@@ -675,7 +674,7 @@ void upload_new_resource(const std::string& src_filename, std::string name,
                                          {	 	
                                                  fclose(in);	 	
                                                  error_message = llformat("corrupt resource file: %s", src_filename.c_str());
-												 args["[FILE]"] = src_filename;
+												 args["FILE"] = src_filename;
 												 upload_error(error_message, "CorruptResourceFile", filename, args);
                                                  return;
                                          }	 	
@@ -703,7 +702,7 @@ void upload_new_resource(const std::string& src_filename, std::string name,
                          {	 	
                                  fclose(in);	 	
                                  error_message = llformat("unknown linden resource file version in file: %s", src_filename.c_str());
-								 args["[FILE]"] = src_filename;
+								 args["FILE"] = src_filename;
 								 upload_error(error_message, "UnknownResourceFileVersion", filename, args);
                                  return;
                          }	 	
@@ -745,7 +744,7 @@ void upload_new_resource(const std::string& src_filename, std::string name,
                  {	 	
                          fclose(in);	 	
                          error_message = llformat( "Unable to create output file: %s", filename.c_str());
-						 args["[FILE]"] = filename;
+						 args["FILE"] = filename;
 						 upload_error(error_message, "UnableToCreateOutputFile", filename, args);
                          return;
                  }	 	
@@ -815,9 +814,9 @@ void upload_new_resource(const std::string& src_filename, std::string name,
 	else
 	{
 		llwarns << error_message << llendl;
-		LLStringUtil::format_map_t args;
-		args["[ERROR_MESSAGE]"] = error_message;
-		gViewerWindow->alertXml("ErrorMessage", args);
+		LLSD args;
+		args["ERROR_MESSAGE"] = error_message;
+		LLNotifications::instance().add("ErrorMessage", args);
 		if(LLFile::remove(filename) == -1)
 		{
 			lldebugs << "unable to remove temp file" << llendl;
@@ -900,10 +899,10 @@ void upload_done_callback(const LLUUID& uuid, void* user_data, S32 result, LLExt
 	}
 	else // 	if(result >= 0)
 	{
-		LLStringUtil::format_map_t args;
-		args["[FILE]"] = LLInventoryType::lookupHumanReadable(data->mInventoryType);
-		args["[REASON]"] = std::string(LLAssetStorage::getErrorString(result));
-		gViewerWindow->alertXml("CannotUploadReason", args);
+		LLSD args;
+		args["FILE"] = LLInventoryType::lookupHumanReadable(data->mInventoryType);
+		args["REASON"] = std::string(LLAssetStorage::getErrorString(result));
+		LLNotifications::instance().add("CannotUploadReason", args);
 	}
 
 	LLUploadDialog::modalUploadFinished();
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index e38ef27cf13..daab3a78477 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -96,6 +96,7 @@
 #include "llmenugl.h"
 #include "llmutelist.h"
 #include "llnetmap.h"
+#include "llnotifications.h"
 #include "llnotify.h"
 #include "llpanelgrouplandmoney.h"
 #include "llselectmgr.h"
@@ -157,7 +158,6 @@ extern BOOL gDebugClicks;
 
 // function prototypes
 void open_offer(const std::vector<LLUUID>& items, const std::string& from_name);
-void friendship_offer_callback(S32 option, void* user_data);
 bool check_offer_throttle(const std::string& from_name, bool check_only);
 void callbackCacheEstateOwnerName(const LLUUID& id,
 								  const std::string& first, const std::string& last,
@@ -184,14 +184,66 @@ const std::string SCRIPT_QUESTIONS[SCRIPT_PERMISSION_EOF] =
 		"ControlYourCamera"
 	};
 
-struct LLFriendshipOffer
+const BOOL SCRIPT_QUESTION_IS_CAUTION[SCRIPT_PERMISSION_EOF] = 
 {
-	LLUUID mFromID;
-	LLUUID mTransactionID;
-	BOOL mOnline;
-	LLHost mHost;
+	TRUE,	// ScriptTakeMoney,
+	FALSE,	// ActOnControlInputs
+	FALSE,	// RemapControlInputs
+	FALSE,	// AnimateYourAvatar
+	FALSE,	// AttachToYourAvatar
+	FALSE,	// ReleaseOwnership,
+	FALSE,	// LinkAndDelink,
+	FALSE,	// AddAndRemoveJoints
+	FALSE,	// ChangePermissions
+	FALSE,	// TrackYourCamera,
+	FALSE	// ControlYourCamera
 };
 
+bool friendship_offer_callback(const LLSD& notification, const LLSD& response)
+{
+	S32 option = LLNotification::getSelectedOption(notification, response);
+	LLUUID fid;
+	LLMessageSystem* msg = gMessageSystem;
+	const LLSD& payload = notification["payload"];
+	switch(option)
+	{
+	case 0:
+		// accept
+		LLAvatarTracker::formFriendship(payload["from_id"]);
+
+		fid = gInventory.findCategoryUUIDForType(LLAssetType::AT_CALLINGCARD);
+
+		// This will also trigger an onlinenotification if the user is online
+		msg->newMessageFast(_PREHASH_AcceptFriendship);
+		msg->nextBlockFast(_PREHASH_AgentData);
+		msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+		msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+		msg->nextBlockFast(_PREHASH_TransactionBlock);
+		msg->addUUIDFast(_PREHASH_TransactionID, payload["session_id"]);
+		msg->nextBlockFast(_PREHASH_FolderData);
+		msg->addUUIDFast(_PREHASH_FolderID, fid);
+		msg->sendReliable(LLHost(payload["sender"].asString()));
+		break;
+	case 1:
+		// decline
+		msg->newMessageFast(_PREHASH_DeclineFriendship);
+		msg->nextBlockFast(_PREHASH_AgentData);
+		msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+		msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+		msg->nextBlockFast(_PREHASH_TransactionBlock);
+		msg->addUUIDFast(_PREHASH_TransactionID, payload["session_id"]);
+		msg->sendReliable(LLHost(payload["sender"].asString()));
+		break;
+	default:
+		// close button probably, possibly timed out
+		break;
+	}
+
+	return false;
+}
+static LLNotificationFunctorRegistration friendship_offer_callback_reg("OfferFriendship", friendship_offer_callback);
+static LLNotificationFunctorRegistration friendship_offer_callback_reg_nm("OfferFriendshipNoMessage", friendship_offer_callback);
+
 //const char BUSY_AUTO_RESPONSE[] =	"The Resident you messaged is in 'busy mode' which means they have "
 //									"requested not to be disturbed. Your message will still be shown in their IM "
 //									"panel for later viewing.";
@@ -563,34 +615,31 @@ void send_sound_trigger(const LLUUID& sound_id, F32 gain)
 	gAgent.sendMessage();
 }
 
-struct LLJoinGroupData
-{
-	LLUUID mGroupID;
-	LLUUID mTransactionID;
-	std::string mName;
-	std::string mMessage;
-	S32 mFee;
-};
-
-void join_group_callback(S32 option, void* user_data)
+bool join_group_response(const LLSD& notification, const LLSD& response)
 {
-	LLJoinGroupData* data = (LLJoinGroupData*)user_data;
+	S32 option = LLNotification::getSelectedOption(notification, response);
 	BOOL delete_context_data = TRUE;
 	bool accept_invite = false;
 
-	if (option == 2 && data && !data->mGroupID.isNull())
+	LLUUID group_id = notification["payload"]["group_id"].asUUID();
+	LLUUID transaction_id = notification["payload"]["transaction_id"].asUUID();
+	std::string name = notification["payload"]["name"].asString();
+	std::string message = notification["payload"]["message"].asString();
+	S32 fee = notification["payload"]["fee"].asInteger();
+
+	if (option == 2 && !group_id.isNull())
 	{
-		LLFloaterGroupInfo::showFromUUID(data->mGroupID);
-		LLStringUtil::format_map_t args;
-		args["[MESSAGE]"] = data->mMessage;
-		LLNotifyBox::showXml("JoinGroup", args, &join_group_callback, data);
-		return;
+		LLFloaterGroupInfo::showFromUUID(group_id);
+		LLSD args;
+		args["MESSAGE"] = message;
+		LLNotifications::instance().add("JoinGroup", args, notification["payload"]);
+		return false;
 	}
-	if(option == 0 && data && !data->mGroupID.isNull())
+	if(option == 0 && !group_id.isNull())
 	{
 		// check for promotion or demotion.
 		S32 max_groups = MAX_AGENT_GROUPS;
-		if(gAgent.isInGroup(data->mGroupID)) ++max_groups;
+		if(gAgent.isInGroup(group_id)) ++max_groups;
 
 		if(gAgent.mGroups.count() < max_groups)
 		{
@@ -599,10 +648,10 @@ void join_group_callback(S32 option, void* user_data)
 		else
 		{
 			delete_context_data = FALSE;
-			LLStringUtil::format_map_t args;
-			args["[NAME]"] = data->mName;
-			args["[INVITE]"] = data->mMessage;
-			LLAlertDialog::showXml("JoinedTooManyGroupsMember", args, join_group_callback, (void*)data);
+			LLSD args;
+			args["NAME"] = name;
+			args["INVITE"] = message;
+			LLNotifications::instance().add("JoinedTooManyGroupsMember", args, notification["payload"]);
 		}
 	}
 
@@ -610,45 +659,44 @@ void join_group_callback(S32 option, void* user_data)
 	{
 		// If there is a fee to join this group, make
 		// sure the user is sure they want to join.
-		if (data->mFee > 0)
+		if (fee > 0)
 		{
 			delete_context_data = FALSE;
-			LLStringUtil::format_map_t args;
-			args["[COST]"] = llformat("%d", data->mFee);
-			// Set the fee to 0, so that we don't keep
+			LLSD args;
+			args["COST"] = llformat("%d", fee);
+			// Set the fee for next time to 0, so that we don't keep
 			// asking about a fee.
-			data->mFee = 0;
-			gViewerWindow->alertXml("JoinGroupCanAfford",
+			LLSD next_payload = notification["payload"];
+			next_payload["fee"] = 0;
+			LLNotifications::instance().add("JoinGroupCanAfford",
 									args,
-									join_group_callback,
-									(void*)data);
+									next_payload);
 		}
 		else
 		{
-			send_improved_im(data->mGroupID,
+			send_improved_im(group_id,
 							 std::string("name"),
 							 std::string("message"),
 							IM_ONLINE,
 							IM_GROUP_INVITATION_ACCEPT,
-							data->mTransactionID);
+							transaction_id);
 		}
 	}
-	else if (data)
+	else
 	{
-		send_improved_im(data->mGroupID,
+		send_improved_im(group_id,
 						 std::string("name"),
 						 std::string("message"),
 						IM_ONLINE,
 						IM_GROUP_INVITATION_DECLINE,
-						data->mTransactionID);
+						transaction_id);
 	}
 
-	if(delete_context_data)
-	{
-		delete data;
-		data = NULL;
-	}
+	return false;
 }
+static LLNotificationFunctorRegistration jgr_1("JoinGroup", join_group_response);
+static LLNotificationFunctorRegistration jgr_2("JoinedTooManyGroupsMember", join_group_response);
+static LLNotificationFunctorRegistration jgr_3("JoinGroupCanAfford", join_group_response);
 
 
 //-----------------------------------------------------------------------------
@@ -930,9 +978,15 @@ void inventory_offer_mute_callback(const LLUUID& blocked_id,
 	{
 	public:
 		OfferMatcher(const LLUUID& to_block) : blocked_id(to_block) {}
-		BOOL matches(LLNotifyBox::notify_callback_t callback, void* cb_data) const
+		BOOL matches(const LLNotificationPtr notification) const
 		{
-			return callback == inventory_offer_callback && ((LLOfferInfo*)cb_data)->mFromID == blocked_id;
+			if(notification->getName() == "ObjectGiveItem" 
+				|| notification->getName() == "ObjectGiveItemUnknownUser"
+				|| notification->getName() == "UserGiveItem")
+			{
+				return (notification->getPayload()["from_id"].asUUID() == blocked_id);
+			}
+			return FALSE;
 		}
 	private:
 		const LLUUID& blocked_id;
@@ -940,12 +994,43 @@ void inventory_offer_mute_callback(const LLUUID& blocked_id,
 	gNotifyBoxView->purgeMessagesMatching(OfferMatcher(blocked_id));
 }
 
-void inventory_offer_callback(S32 button, void* user_data)
+LLOfferInfo::LLOfferInfo(const LLSD& sd)
+{
+	mIM = (EInstantMessage)sd["im_type"].asInteger();
+	mFromID = sd["from_id"].asUUID();
+	mFromGroup = sd["from_group"].asBoolean();
+	mFromObject = sd["from_object"].asBoolean();
+	mTransactionID = sd["transaction_id"].asUUID();
+	mFolderID = sd["folder_id"].asUUID();
+	mObjectID = sd["object_id"].asUUID();
+	mType = LLAssetType::lookup(sd["type"].asString().c_str());
+	mFromName = sd["from_name"].asString();
+	mDesc = sd["description"].asString();
+	mHost = LLHost(sd["sender"].asString());
+}
+
+LLSD LLOfferInfo::asLLSD()
+{
+	LLSD sd;
+	sd["im_type"] = mIM;
+	sd["from_id"] = mFromID;
+	sd["from_group"] = mFromGroup;
+	sd["from_object"] = mFromObject;
+	sd["transaction_id"] = mTransactionID;
+	sd["folder_id"] = mFolderID;
+	sd["object_id"] = mObjectID;
+	sd["type"] = LLAssetType::lookup(mType);
+	sd["from_name"] = mFromName;
+	sd["description"] = mDesc;
+	sd["sender"] = mHost.getIPandPort();
+	return sd;
+}
+
+bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD& response)
  {
 	LLChat chat;
 	std::string log_message;
-	LLOfferInfo* info = (LLOfferInfo*)user_data;
-	if(!info) return;
+	S32 button = LLNotification::getSelectedOption(notification, response);
 
 	// For muting, we need to add the mute, then decline the offer.
 	// This must be done here because:
@@ -954,7 +1039,7 @@ void inventory_offer_callback(S32 button, void* user_data)
 	// * we can't build two messages at once.  JC
 	if (2 == button)
 	{
-		gCacheName->get(info->mFromID, info->mFromGroup, inventory_offer_mute_callback, user_data);
+		gCacheName->get(mFromID, mFromGroup, inventory_offer_mute_callback, this);
 	}
 
 	LLMessageSystem* msg = gMessageSystem;
@@ -964,9 +1049,9 @@ void inventory_offer_callback(S32 button, void* user_data)
 	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
 	msg->nextBlockFast(_PREHASH_MessageBlock);
 	msg->addBOOLFast(_PREHASH_FromGroup, FALSE);
-	msg->addUUIDFast(_PREHASH_ToAgentID, info->mFromID);
+	msg->addUUIDFast(_PREHASH_ToAgentID, mFromID);
 	msg->addU8Fast(_PREHASH_Offline, IM_ONLINE);
-	msg->addUUIDFast(_PREHASH_ID, info->mTransactionID);
+	msg->addUUIDFast(_PREHASH_ID, mTransactionID);
 	msg->addU32Fast(_PREHASH_Timestamp, NO_TIMESTAMP); // no timestamp necessary
 	std::string name;
 	gAgent.buildFullname(name);
@@ -977,50 +1062,50 @@ void inventory_offer_callback(S32 button, void* user_data)
 	msg->addVector3Fast(_PREHASH_Position, gAgent.getPositionAgent());
 	LLInventoryObserver* opener = NULL;
 	LLViewerInventoryCategory* catp = NULL;
-	catp = (LLViewerInventoryCategory*)gInventory.getCategory(info->mObjectID);
+	catp = (LLViewerInventoryCategory*)gInventory.getCategory(mObjectID);
 	LLViewerInventoryItem* itemp = NULL;
 	if(!catp)
 	{
-		itemp = (LLViewerInventoryItem*)gInventory.getItem(info->mObjectID);
+		itemp = (LLViewerInventoryItem*)gInventory.getItem(mObjectID);
 	}
 
 	// *TODO:translate
 	std::string from_string; // Used in the pop-up.
 	std::string chatHistory_string;  // Used in chat history.
-	if (info->mFromObject == TRUE)
+	if (mFromObject == TRUE)
 	{
-		if (info->mFromGroup)
+		if (mFromGroup)
 		{
 			std::string group_name;
-			if (gCacheName->getGroupName(info->mFromID, group_name))
+			if (gCacheName->getGroupName(mFromID, group_name))
 			{
-				from_string = std::string("An object named '") + info->mFromName + "' owned by the group '" + group_name + "'";
-				chatHistory_string = info->mFromName + " owned by the group '" + group_name + "'";
+				from_string = std::string("An object named '") + mFromName + "' owned by the group '" + group_name + "'";
+				chatHistory_string = mFromName + " owned by the group '" + group_name + "'";
 			}
 			else
 			{
-				from_string = std::string("An object named '") + info->mFromName + "' owned by an unknown group";
-				chatHistory_string = info->mFromName + " owned by an unknown group";
+				from_string = std::string("An object named '") + mFromName + "' owned by an unknown group";
+				chatHistory_string = mFromName + " owned by an unknown group";
 			}
 		}
 		else
 		{
 			std::string first_name, last_name;
-			if (gCacheName->getName(info->mFromID, first_name, last_name))
+			if (gCacheName->getName(mFromID, first_name, last_name))
 			{
-				from_string = std::string("An object named '") + info->mFromName + "' owned by " + first_name + " " + last_name;
-				chatHistory_string = info->mFromName + " owned by " + first_name + " " + last_name;
+				from_string = std::string("An object named '") + mFromName + "' owned by " + first_name + " " + last_name;
+				chatHistory_string = mFromName + " owned by " + first_name + " " + last_name;
 			}
 			else
 			{
-				from_string = std::string("An object named '") + info->mFromName + "' owned by an unknown user";
-				chatHistory_string = info->mFromName + " owned by an unknown user";
+				from_string = std::string("An object named '") + mFromName + "' owned by an unknown user";
+				chatHistory_string = mFromName + " owned by an unknown user";
 			}
 		}
 	}
 	else
 	{
-		from_string = chatHistory_string = info->mFromName;
+		from_string = chatHistory_string = mFromName;
 	}
 	
 	bool busy=FALSE;
@@ -1033,24 +1118,24 @@ void inventory_offer_callback(S32 button, void* user_data)
 		// group_notice_inventory is 1 greater than the offer integer value.
 		// Generates IM_INVENTORY_ACCEPTED, IM_TASK_INVENTORY_ACCEPTED, 
 		// or IM_GROUP_NOTICE_INVENTORY_ACCEPTED
-		msg->addU8Fast(_PREHASH_Dialog, (U8)(info->mIM + 1));
-		msg->addBinaryDataFast(_PREHASH_BinaryBucket, &(info->mFolderID.mData),
-					 sizeof(info->mFolderID.mData));
+		msg->addU8Fast(_PREHASH_Dialog, (U8)(mIM + 1));
+		msg->addBinaryDataFast(_PREHASH_BinaryBucket, &(mFolderID.mData),
+					 sizeof(mFolderID.mData));
 		// send the message
-		msg->sendReliable(info->mHost);
+		msg->sendReliable(mHost);
 
 		//don't spam them if they are getting flooded
-		if (check_offer_throttle(info->mFromName, true))
+		if (check_offer_throttle(mFromName, true))
 		{
-			log_message = chatHistory_string + " gave you " + info->mDesc + ".";
+			log_message = chatHistory_string + " gave you " + mDesc + ".";
  			chat.mText = log_message;
  			LLFloaterChat::addChatHistory(chat);
 		}
 
 		// we will want to open this item when it comes back.
-		LL_DEBUGS("Messaging") << "Initializing an opener for tid: " << info->mTransactionID
+		LL_DEBUGS("Messaging") << "Initializing an opener for tid: " << mTransactionID
 				 << LL_ENDL;
-		switch (info->mIM)
+		switch (mIM)
 		{
 		case IM_INVENTORY_OFFERED:
 		{
@@ -1058,7 +1143,7 @@ void inventory_offer_callback(S32 button, void* user_data)
 			// end has already copied the items into your inventory,
 			// so we can fetch it out of our inventory.
 			LLInventoryFetchObserver::item_ref_t items;
-			items.push_back(info->mObjectID);
+			items.push_back(mObjectID);
 			LLOpenAgentOffer* open_agent_offer = new LLOpenAgentOffer(from_string);
 			open_agent_offer->fetchItems(items);
 			if(catp || (itemp && itemp->isComplete()))
@@ -1084,7 +1169,7 @@ void inventory_offer_callback(S32 button, void* user_data)
 		default:
 			LL_WARNS("Messaging") << "inventory_offer_callback: unknown offer type" << LL_ENDL;
 			break;
-		}	// end switch (info->mIM)
+		}	// end switch (mIM)
 		break;
 
 	case IOR_BUSY:
@@ -1100,14 +1185,14 @@ void inventory_offer_callback(S32 button, void* user_data)
 		// or IM_GROUP_NOTICE_INVENTORY_DECLINED
 	default:
 		// close button probably (or any of the fall-throughs from above)
-		msg->addU8Fast(_PREHASH_Dialog, (U8)(info->mIM + 2));
+		msg->addU8Fast(_PREHASH_Dialog, (U8)(mIM + 2));
 		msg->addBinaryDataFast(_PREHASH_BinaryBucket, EMPTY_BINARY_BUCKET, EMPTY_BINARY_BUCKET_SIZE);
 		// send the message
-		msg->sendReliable(info->mHost);
+		msg->sendReliable(mHost);
 
-		log_message = "You decline " + info->mDesc + " from " + info->mFromName + ".";
+		log_message = "You decline " + mDesc + " from " + mFromName + ".";
 		chat.mText = log_message;
-		if( LLMuteList::getInstance()->isMuted(info->mFromID ) && ! LLMuteList::getInstance()->isLinden(info->mFromName) )  // muting for SL-42269
+		if( LLMuteList::getInstance()->isMuted(mFromID ) && ! LLMuteList::getInstance()->isLinden(mFromName) )  // muting for SL-42269
 		{
 			chat.mMuted = TRUE;
 		}
@@ -1116,13 +1201,13 @@ void inventory_offer_callback(S32 button, void* user_data)
 		// If it's from an agent, we have to fetch the item to throw
 		// it away. If it's from a task or group, just denying the 
 		// request will suffice to discard the item.
-		if(IM_INVENTORY_OFFERED == info->mIM)
+		if(IM_INVENTORY_OFFERED == mIM)
 		{
 			LLInventoryFetchComboObserver::folder_ref_t folders;
 			LLInventoryFetchComboObserver::item_ref_t items;
-			items.push_back(info->mObjectID);
+			items.push_back(mObjectID);
 			LLDiscardAgentOffer* discard_agent_offer;
-			discard_agent_offer = new LLDiscardAgentOffer(info->mFolderID, info->mObjectID);
+			discard_agent_offer = new LLDiscardAgentOffer(mFolderID, mObjectID);
 			discard_agent_offer->fetch(folders, items);
 			if(catp || (itemp && itemp->isComplete()))
 			{
@@ -1134,9 +1219,9 @@ void inventory_offer_callback(S32 button, void* user_data)
 			}
 			
 		}
-		if (busy &&	(!info->mFromGroup && !info->mFromObject))
+		if (busy &&	(!mFromGroup && !mFromObject))
 		{
-			busy_message(msg,info->mFromID);
+			busy_message(msg,mFromID);
 		}
 		break;
 	}
@@ -1146,12 +1231,12 @@ void inventory_offer_callback(S32 button, void* user_data)
 		gInventory.addObserver(opener);
 	}
 
-	delete info;
-	info = NULL;
-
 	// Allow these to stack up, but once you deal with one, reset the
 	// position.
 	gFloaterView->resetStartingFloaterPosition();
+
+	delete this;
+	return false;
 }
 
 
@@ -1161,14 +1246,14 @@ void inventory_offer_handler(LLOfferInfo* info, BOOL from_task)
 	//accepting it.  SEE SL-39554
 	if (gAgent.getBusy())
 	{
-		inventory_offer_callback(IOR_BUSY, info);
+		info->forceResponse(IOR_BUSY);
 		return;
 	}
 	
 	//If muted, don't even go through the messaging stuff.  Just curtail the offer here.
 	if (LLMuteList::getInstance()->isMuted(info->mFromID, info->mFromName))
 	{
-		inventory_offer_callback(IOR_MUTE, info);
+		info->forceResponse(IOR_MUTE);
 		return;
 	}
 
@@ -1180,7 +1265,7 @@ void inventory_offer_handler(LLOfferInfo* info, BOOL from_task)
 	{
 		// For certain types, just accept the items into the inventory,
 		// and possibly open them on receipt depending upon "ShowNewInventory".
-		inventory_offer_callback(IOR_ACCEPT, info);
+		info->forceResponse(IOR_ACCEPT);
 		return;
 	}
 
@@ -1192,23 +1277,25 @@ void inventory_offer_handler(LLOfferInfo* info, BOOL from_task)
 		LLStringUtil::truncate(msg, indx);
 	}
 	
-	LLStringUtil::format_map_t args;
+	LLSD args;
 	args["[OBJECTNAME]"] = msg;
 
+	LLSD payload;
+
 	// must protect against a NULL return from lookupHumanReadable()
 	std::string typestr = ll_safe_string(LLAssetType::lookupHumanReadable(info->mType));
 	if (!typestr.empty())
 	{
-		args["[OBJECTTYPE]"] = typestr;
+		args["OBJECTTYPE"] = typestr;
 	}
 	else
 	{
 		LL_WARNS("Messaging") << "LLAssetType::lookupHumanReadable() returned NULL - probably bad asset type: " << info->mType << LL_ENDL;
-		args["[OBJECTTYPE]"] = "";
+		args["OBJECTTYPE"] = "";
 
 		// This seems safest, rather than propagating bogosity
 		LL_WARNS("Messaging") << "Forcing an inventory-decline for probably-bad asset type." << LL_ENDL;
-		inventory_offer_callback(IOR_DECLINE, info);
+		info->forceResponse(IOR_DECLINE);
 		return;
 	}
 
@@ -1220,8 +1307,8 @@ void inventory_offer_handler(LLOfferInfo* info, BOOL from_task)
 		std::string group_name;
 		if (gCacheName->getGroupName(info->mFromID, group_name))
 		{
-			args["[FIRST]"] = group_name;
-			args["[LAST]"] = "";
+			args["FIRST"] = group_name;
+			args["LAST"] = "";
 			name_found = TRUE;
 		}
 	}
@@ -1230,95 +1317,100 @@ void inventory_offer_handler(LLOfferInfo* info, BOOL from_task)
 		std::string first_name, last_name;
 		if (gCacheName->getName(info->mFromID, first_name, last_name))
 		{
-			args["[FIRST]"] = first_name;
-			args["[LAST]"] = last_name;
+			args["FIRST"] = first_name;
+			args["LAST"] = last_name;
 			name_found = TRUE;
 		}
 	}
+
+	payload["from_id"] = info->mFromID;
+	args["OBJECTFROMNAME"] = info->mFromName;
+	args["NAME"] = info->mFromName;
+
+	LLNotification::Params p("ObjectGiveItem");
+	p.substitutions(args).payload(payload).functor(boost::bind(&LLOfferInfo::inventory_offer_callback, info, _1, _2));
+
 	if (from_task)
 	{
-		args["[OBJECTFROMNAME]"] = info->mFromName;
-		LLNotifyBox::showXml(name_found ? "ObjectGiveItem" : "ObjectGiveItemUnknownUser",
-							args, &inventory_offer_callback, (void*)info);
+		p.name = name_found ? "ObjectGiveItem" : "ObjectGiveItemUnknownUser";
 	}
 	else
 	{
-		// *TODO:translate -> [FIRST] [LAST]
-		args["[NAME]"] = info->mFromName;
-		LLNotifyBox::showXml("UserGiveItem", args,
-							&inventory_offer_callback, (void*)info);
+		p.name = "UserGiveItem";
 	}
+
+	LLNotifications::instance().add(p);
 }
 
 
-void group_vote_callback(S32 option, void *userdata)
+bool group_vote_callback(const LLSD& notification, const LLSD& response)
 {
-	LLUUID *group_id = (LLUUID *)userdata;
-	if (!group_id) return;
-
+	LLUUID group_id = notification["payload"]["group_id"].asUUID();
+	S32 option = LLNotification::getSelectedOption(notification, response);
 	switch(option)
 	{
 	case 0:
 		// Vote Now
 		// Open up the voting tab
-		LLFloaterGroupInfo::showFromUUID(*group_id, "voting_tab");
+		LLFloaterGroupInfo::showFromUUID(group_id, "voting_tab");
 		break;
 	default:
 		// Vote Later or
 		// close button
 		break;
 	}
-	delete group_id;
-	group_id = NULL;
+	return false;
 }
+static LLNotificationFunctorRegistration group_vote_callback_reg("GroupVote", group_vote_callback);
 
-struct LLLureInfo
+bool lure_callback(const LLSD& notification, const LLSD& response)
 {
-	LLLureInfo(const LLUUID& from, const LLUUID& lure_id, BOOL godlike) :
-		mFromID(from),
-		mLureID(lure_id),
-		mGodlike(godlike)
-	{}
-
-	LLUUID mFromID;
-	LLUUID mLureID;
-	BOOL mGodlike;
-};
+	S32 option = 0;
+	if (response.isInteger()) 
+	{
+		option = response.asInteger();
+	}
+	else
+	{
+		option = LLNotification::getSelectedOption(notification, response);
+	}
+	
+	LLUUID from_id = notification["payload"]["from_id"].asUUID();
+	LLUUID lure_id = notification["payload"]["lure_id"].asUUID();
+	BOOL godlike = notification["payload"]["godlike"].asBoolean();
 
-void lure_callback(S32 option, void* user_data)
-{
-	LLLureInfo* info = (LLLureInfo*)user_data;
-	if(!info) return;
 	switch(option)
 	{
 	case 0:
 		{
 			// accept
-			gAgent.teleportViaLure(info->mLureID, info->mGodlike);
+			gAgent.teleportViaLure(lure_id, godlike);
 		}
 		break;
 	case 1:
 	default:
 		// decline
-		send_simple_im(info->mFromID,
+		send_simple_im(from_id,
 					   LLStringUtil::null,
 					   IM_LURE_DECLINED,
-					   info->mLureID);
+					   lure_id);
 		break;
 	}
-	delete info;
-	info = NULL;
+	return false;
 }
+static LLNotificationFunctorRegistration lure_callback_reg("TeleportOffered", lure_callback);
 
-void goto_url_callback(S32 option, void* user_data)
+bool goto_url_callback(const LLSD& notification, const LLSD& response)
 {
-	char* url = (char*)user_data;
+	std::string url = notification["payload"]["url"].asString();
+	S32 option = LLNotification::getSelectedOption(notification, response);
 	if(1 == option)
 	{
 		LLWeb::loadURL(url);
 	}
-	delete[] url;
+	return false;
 }
+static LLNotificationFunctorRegistration goto_url_callback_reg("GotoURL", goto_url_callback);
 
 void process_improved_im(LLMessageSystem *msg, void **user_data)
 {
@@ -1332,7 +1424,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 	U8 offline;
 	U8 d = 0;
 	LLUUID session_id;
-	U32 t;
+	U32 timestamp;
 	std::string name;
 	std::string message;
 	U32 parent_estate_id = 0;
@@ -1350,7 +1442,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 	msg->getU8Fast(  _PREHASH_MessageBlock, _PREHASH_Offline, offline);
 	msg->getU8Fast(  _PREHASH_MessageBlock, _PREHASH_Dialog, d);
 	msg->getUUIDFast(_PREHASH_MessageBlock, _PREHASH_ID, session_id);
-	msg->getU32Fast( _PREHASH_MessageBlock, _PREHASH_Timestamp, t);
+	msg->getU32Fast( _PREHASH_MessageBlock, _PREHASH_Timestamp, timestamp);
 	//msg->getData("MessageBlock", "Count",		&count);
 	msg->getStringFast(_PREHASH_MessageBlock, _PREHASH_FromAgentName, name);
 	msg->getStringFast(_PREHASH_MessageBlock, _PREHASH_Message,		message);
@@ -1360,7 +1452,6 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 	msg->getBinaryDataFast(  _PREHASH_MessageBlock, _PREHASH_BinaryBucket, binary_bucket, 0, 0, MTUBYTES);
 	binary_bucket_size = msg->getSizeFast(_PREHASH_MessageBlock, _PREHASH_BinaryBucket);
 	EInstantMessage dialog = (EInstantMessage)d;
-	time_t timestamp = (time_t)t;
 
 	BOOL is_busy = gAgent.getBusy();
 	BOOL is_muted = LLMuteList::getInstance()->isMuted(from_id, name, LLMute::flagTextChat);
@@ -1389,18 +1480,18 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 		message_offset = 3;
 	}
 
-	LLStringUtil::format_map_t args;
+	LLSD args;
 	switch(dialog)
 	{
 	case IM_CONSOLE_AND_CHAT_HISTORY:
 		// These are used for system messages, hence don't need the name,
 		// as it is always "Second Life".
 	  	// *TODO:translate
-		args["[MESSAGE]"] = message;
+		args["MESSAGE"] = message;
 
 		// Note: don't put the message in the IM history, even though was sent
 		// via the IM mechanism.
-		LLNotifyBox::showXml("SystemMessageTip",args);
+		LLNotifications::instance().add("SystemMessageTip",args);
 		break;
 
 	case IM_NOTHING_SPECIAL: 
@@ -1470,9 +1561,9 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 		else if (to_id.isNull())
 		{
 			// Message to everyone from GOD
-			args["[NAME]"] = name;
-			args["[MESSAGE]"] = message;
-			LLNotifyBox::showXml("GodMessage", args);
+			args["NAME"] = name;
+			args["MESSAGE"] = message;
+			LLNotifications::instance().add("GodMessage", args);
 
 			// Treat like a system message and put in chat history.
 			// Claim to be from a local agent so it doesn't go into
@@ -1541,8 +1632,8 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 		{
 			// This is a block, modeless dialog.
 			//*TODO:translate
-			args["[MESSAGE]"] = message;
-			LLNotifyBox::showXml("SystemMessage", args);
+			args["MESSAGE"] = message;
+			LLNotifications::instance().add("SystemMessage", args);
 		}
 		break;
 	case IM_GROUP_NOTICE:
@@ -1579,9 +1670,11 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 
 			// If there is inventory, give the user the inventory offer.
 			LLOfferInfo* info = NULL;
+
 			if (has_inventory)
 			{
 				info = new LLOfferInfo;
+				
 				info->mIM = IM_GROUP_NOTICE;
 				info->mFromID = from_id;
 				info->mFromGroup = from_group;
@@ -1610,13 +1703,26 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 			std::string subj(*iter++);
 			std::string mes(*iter++);
 
-			if (IM_GROUP_NOTICE == dialog)
+			// Send the notification down the new path.
+			// For requested notices, we don't want to send the popups.
+			if (dialog != IM_GROUP_NOTICE_REQUESTED)
 			{
-				subj += "\n";
-				mes = "\n\n" + mes;
-				LLGroupNotifyBox::show(subj,mes,name,group_id,t,has_inventory,item_name,info);
+				LLSD payload;
+				payload["subject"] = subj;
+				payload["message"] = mes;
+				payload["sender_name"] = name;
+				payload["group_id"] = group_id;
+				payload["inventory_name"] = item_name;
+				payload["inventory_offer"] = info ? info->asLLSD() : LLSD();
+
+				LLSD args;
+				args["SUBJECT"] = subj;
+				args["MESSAGE"] = mes;
+				LLNotifications::instance().add(LLNotification::Params("GroupNotice").substitutions(args).payload(payload).timestamp(timestamp));
 			}
-			else if (IM_GROUP_NOTICE_REQUESTED == dialog)
+
+			// Also send down the old path for now.
+			if (IM_GROUP_NOTICE_REQUESTED == dialog)
 			{
 				LLFloaterGroupInfo::showNotice(subj,mes,group_id,has_inventory,item_name,info);
 			}
@@ -1628,7 +1734,6 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 			if ((is_busy || is_muted))
 			{
 				LLMessageSystem *msg = gMessageSystem;
-				join_group_callback(1, NULL);
 				busy_message(msg,from_id);
 			}
 			else
@@ -1651,18 +1756,16 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 				invite_bucket = (struct invite_bucket_t*) &binary_bucket[0];
 				S32 membership_fee = ntohl(invite_bucket->membership_fee);
 
-				LLJoinGroupData* userdata = new LLJoinGroupData;
-				userdata->mTransactionID = session_id;
-				userdata->mGroupID = from_id;
-				userdata->mName.assign(name);
-				userdata->mMessage.assign(message);
-				userdata->mFee = membership_fee;
-
-				LLStringUtil::format_map_t args;
-				args["[MESSAGE]"] = message;
-				LLNotifyBox::showXml("JoinGroup", args,
-									 &join_group_callback,
-									 (void*)userdata);
+				LLSD payload;
+				payload["transaction_id"] = session_id;
+				payload["group_id"] = from_id;
+				payload["name"] = name;
+				payload["message"] = message;
+				payload["fee"] = membership_fee;
+
+				LLSD args;
+				args["MESSAGE"] = message;
+				LLNotifications::instance().add("JoinGroup", args, payload, join_group_response);
 			}
 		}
 		break;
@@ -1722,7 +1825,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 			if ( is_muted )
 			{
 				// Same as closing window
-				inventory_offer_callback(-1, info);
+				info->forceResponse(IOR_DECLINE);
 			}
 			else
 			{
@@ -1733,23 +1836,25 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 
 	case IM_INVENTORY_ACCEPTED:
 	{
-		args["[NAME]"] = name;
-		LLNotifyBox::showXml("InventoryAccepted", args);
+		args["NAME"] = name;
+		LLNotifications::instance().add("InventoryAccepted", args);
 		break;
 	}
 	case IM_INVENTORY_DECLINED:
 	{
-		args["[NAME]"] = name;
-		LLNotifyBox::showXml("InventoryDeclined", args);
+		args["NAME"] = name;
+		LLNotifications::instance().add("InventoryDeclined", args);
 		break;
 	}
 	case IM_GROUP_VOTE:
 	{
-		LLUUID *userdata = new LLUUID(session_id);
-		args["[NAME]"] = name;
-		args["[MESSAGE]"] = message;
-		LLNotifyBox::showXml("GroupVote", args,
-							 &group_vote_callback, userdata);
+		LLSD args;
+		args["NAME"] = name;
+		args["MESSAGE"] = message;
+
+		LLSD payload;
+		payload["group_id"] = session_id;
+		LLNotifications::instance().add("GroupVote", args, payload);
 	}
 	break;
 
@@ -1856,9 +1961,9 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 		}
 		{
 			// Construct a viewer alert for this message.
-			args["[NAME]"] = name;
-			args["[MESSAGE]"] = message;
-			LLNotifyBox::showXml("ObjectMessage", args);
+			args["NAME"] = name;
+			args["MESSAGE"] = message;
+			LLNotifications::instance().add("ObjectMessage", args);
 		}
 		break;
 	case IM_BUSY_AUTO_RESPONSE:
@@ -1887,27 +1992,34 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 			}
 			else
 			{
+				LLSD args;
 				// *TODO:translate -> [FIRST] [LAST] (maybe)
-				LLLureInfo* info = new LLLureInfo(from_id, session_id, FALSE);
-				args["[NAME]"] = name;
-				args["[MESSAGE]"] = message;
-				LLNotifyBox::showXml("OfferTeleport", args,
-									 lure_callback, (void*)info);
+				args["NAME"] = name;
+				args["MESSAGE"] = message;
+				LLSD payload;
+				payload["from_id"] = from_id;
+				payload["lure_id"] = session_id;
+				payload["godlike"] = FALSE;
+				LLNotifications::instance().add("TeleportOffered", args, payload);
 			}
 		}
 		break;
 
 	case IM_GODLIKE_LURE_USER:
 		{
-			LLLureInfo* info = new LLLureInfo(from_id, session_id, TRUE);
+			LLSD payload;
+			payload["from_id"] = from_id;
+			payload["lure_id"] = session_id;
+			payload["godlike"] = TRUE;
 			// do not show a message box, because you're about to be
 			// teleported.
-			lure_callback(0, (void *)info);
+			LLNotifications::instance().forceResponse(LLNotification::Params("TeleportOffered").payload(payload), 0);
 		}
 		break;
 
 	case IM_GOTO_URL:
 		{
+			LLSD args;
 			// n.b. this is for URLs sent by the system, not for
 			// URLs sent by scripts (i.e. llLoadURL)
 			if (binary_bucket_size <= 0)
@@ -1918,38 +2030,33 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 				return;
 			}
 
-			char* url = new char[binary_bucket_size];
-			if (url == NULL)
-			{
-				LL_ERRS("Messaging") << "Memory Allocation failed" << LL_ENDL;
-				return;
-			}
-
-			strncpy(url, (char*)binary_bucket, binary_bucket_size-1);		/* Flawfinder: ignore */
-			url[binary_bucket_size-1] = '\0';
-			args["[MESSAGE]"] = message;
-			args["[URL]"] = url;
-			LLNotifyBox::showXml("GotoURL", args,
-								 goto_url_callback, (void*)url);
+			std::string url;
+			
+			url.assign((char*)binary_bucket, binary_bucket_size-1);
+			args["MESSAGE"] = message;
+			args["URL"] = url;
+			LLSD payload;
+			payload["url"] = url;
+			LLNotifications::instance().add("GotoURL", args, payload );
 		}
 		break;
 
 	case IM_FRIENDSHIP_OFFERED:
 		{
-			LLFriendshipOffer* offer = new LLFriendshipOffer;
-			offer->mFromID = from_id;
-			offer->mTransactionID = session_id;
-			offer->mOnline = (offline == IM_ONLINE);
-			offer->mHost = msg->getSender();
+			LLSD payload;
+			payload["from_id"] = from_id;
+			payload["session_id"] = session_id;;
+			payload["online"] = (offline == IM_ONLINE);
+			payload["sender"] = msg->getSender().getIPandPort();
 
 			if (is_busy)
 			{
 				busy_message(msg, from_id);
-				friendship_offer_callback(1, (void*)offer);
+				LLNotifications::instance().forceResponse(LLNotification::Params("OfferFriendship").payload(payload), 1);
 			}
 			else if (is_muted)
 			{
-				friendship_offer_callback(1, (void*)offer);
+				LLNotifications::instance().forceResponse(LLNotification::Params("OfferFriendship").payload(payload), 1);
 			}
 			else
 			{
@@ -1957,14 +2064,12 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 				if(message.empty())
 				{
 					//support for frienship offers from clients before July 2008
-					LLNotifyBox::showXml("OfferFriendshipNoMessage", args,
-						&friendship_offer_callback, (void*)offer);
+				        LLNotifications::instance().add("OfferFriendshipNoMessage", args, payload);
 				}
 				else
 				{
 					args["[MESSAGE]"] = message;
-					LLNotifyBox::showXml("OfferFriendship", args,
-						&friendship_offer_callback, (void*)offer);
+				        LLNotifications::instance().add("OfferFriendship", args, payload);
 				}
 			}
 		}
@@ -1981,14 +2086,14 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 			strings.push_back(from_id.asString());
 			send_generic_message("requestonlinenotification", strings);
 			
-			args["[NAME]"] = name;
-			LLNotifyBox::showXml("FriendshipAccepted", args);
+			args["NAME"] = name;
+			LLNotifications::instance().add("FriendshipAccepted", args);
 		}
 		break;
 
 	case IM_FRIENDSHIP_DECLINED:
-		args["[NAME]"] = name;
-		LLNotifyBox::showXml("FriendshipDeclined", args);
+		args["NAME"] = name;
+		LLNotifications::instance().add("FriendshipDeclined", args);
 		break;
 
 	default:
@@ -2025,61 +2130,9 @@ void busy_message (LLMessageSystem* msg, LLUUID from_id)
 	}
 }
 
-void friendship_offer_callback(S32 option, void* user_data)
+bool callingcard_offer_callback(const LLSD& notification, const LLSD& response)
 {
-	LLFriendshipOffer* offer = (LLFriendshipOffer*)user_data;
-	if(!offer) return;
-	LLUUID fid;
-	LLMessageSystem* msg = gMessageSystem;
-	switch(option)
-	{
-	case 0:
-		// accept
-		LLAvatarTracker::formFriendship(offer->mFromID);
-
-		fid = gInventory.findCategoryUUIDForType(LLAssetType::AT_CALLINGCARD);
-
-		// This will also trigger an onlinenotification if the user is online
-		msg->newMessageFast(_PREHASH_AcceptFriendship);
-		msg->nextBlockFast(_PREHASH_AgentData);
-		msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
-		msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-		msg->nextBlockFast(_PREHASH_TransactionBlock);
-		msg->addUUIDFast(_PREHASH_TransactionID, offer->mTransactionID);
-		msg->nextBlockFast(_PREHASH_FolderData);
-		msg->addUUIDFast(_PREHASH_FolderID, fid);
-		msg->sendReliable(offer->mHost);
-		break;
-	case 1:
-		// decline
-		msg->newMessageFast(_PREHASH_DeclineFriendship);
-		msg->nextBlockFast(_PREHASH_AgentData);
-		msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
-		msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-		msg->nextBlockFast(_PREHASH_TransactionBlock);
-		msg->addUUIDFast(_PREHASH_TransactionID, offer->mTransactionID);
-		msg->sendReliable(offer->mHost);
-		break;
-	default:
-		// close button probably, possibly timed out
-		break;
-	}
-
-	delete offer;
-	offer = NULL;
-}
-
-struct LLCallingCardOfferData
-{
-	LLUUID mTransactionID;
-	LLUUID mSourceID;
-	LLHost mHost;
-};
-
-void callingcard_offer_callback(S32 option, void* user_data)
-{
-	LLCallingCardOfferData* offerdata = (LLCallingCardOfferData*)user_data;
-	if(!offerdata) return;
+	S32 option = LLNotification::getSelectedOption(notification, response);
 	LLUUID fid;
 	LLUUID from_id;
 	LLMessageSystem* msg = gMessageSystem;
@@ -2092,11 +2145,11 @@ void callingcard_offer_callback(S32 option, void* user_data)
 		msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
 		msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
 		msg->nextBlockFast(_PREHASH_TransactionBlock);
-		msg->addUUIDFast(_PREHASH_TransactionID, offerdata->mTransactionID);
+		msg->addUUIDFast(_PREHASH_TransactionID, notification["payload"]["transaction_id"].asUUID());
 		fid = gInventory.findCategoryUUIDForType(LLAssetType::AT_CALLINGCARD);
 		msg->nextBlockFast(_PREHASH_FolderData);
 		msg->addUUIDFast(_PREHASH_FolderID, fid);
-		msg->sendReliable(offerdata->mHost);
+		msg->sendReliable(LLHost(notification["payload"]["sender"].asString()));
 		break;
 	case 1:
 		// decline		
@@ -2105,18 +2158,18 @@ void callingcard_offer_callback(S32 option, void* user_data)
 		msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
 		msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
 		msg->nextBlockFast(_PREHASH_TransactionBlock);
-		msg->addUUIDFast(_PREHASH_TransactionID, offerdata->mTransactionID);
-		msg->sendReliable(offerdata->mHost);
-		busy_message(msg, offerdata->mSourceID);
+		msg->addUUIDFast(_PREHASH_TransactionID, notification["payload"]["transaction_id"].asUUID());
+		msg->sendReliable(LLHost(notification["payload"]["sender"].asString()));
+		busy_message(msg, notification["payload"]["source_id"].asUUID());
 		break;
 	default:
 		// close button probably, possibly timed out
 		break;
 	}
 
-	delete offerdata;
-	offerdata = NULL;
+	return false;
 }
+static LLNotificationFunctorRegistration callingcard_offer_cb_reg("OfferCallingCard", callingcard_offer_callback);
 
 void process_offer_callingcard(LLMessageSystem* msg, void**)
 {
@@ -2128,13 +2181,13 @@ void process_offer_callingcard(LLMessageSystem* msg, void**)
 	LLUUID tid;
 	msg->getUUIDFast(_PREHASH_AgentBlock, _PREHASH_TransactionID, tid);
 
-	LLCallingCardOfferData* offerdata = new LLCallingCardOfferData;
-	offerdata->mTransactionID = tid;
-	offerdata->mSourceID = source_id;
-	offerdata->mHost = msg->getSender();
+	LLSD payload;
+	payload["transaction_id"] = tid;
+	payload["source_id"] = source_id;
+	payload["sender"] = msg->getSender().getIPandPort();
 
 	LLViewerObject* source = gObjectList.findObject(source_id);
-	LLStringUtil::format_map_t args;
+	LLSD args;
 	std::string source_name;
 	if(source && source->isAvatar())
 	{
@@ -2142,8 +2195,8 @@ void process_offer_callingcard(LLMessageSystem* msg, void**)
 		LLNameValue* nvlast  = source->getNVPair("LastName");
 		if (nvfirst && nvlast)
 		{
-			args["[FIRST]"] = nvfirst->getString();
-			args["[LAST]"] = nvlast->getString();
+			args["FIRST"] = nvfirst->getString();
+			args["LAST"] = nvlast->getString();
 			source_name = std::string(nvfirst->getString()) + " " + nvlast->getString();
 		}
 	}
@@ -2154,33 +2207,27 @@ void process_offer_callingcard(LLMessageSystem* msg, void**)
 			|| LLMuteList::getInstance()->isMuted(source_id, source_name, LLMute::flagTextChat))
 		{
 			// automatically decline offer
-			callingcard_offer_callback(1, (void*)offerdata);
-			offerdata = NULL; // pointer was freed by callback
+			LLNotifications::instance().forceResponse(LLNotification::Params("OfferCallingCard").payload(payload), 1);
 		}
 		else
 		{
-			LLNotifyBox::showXml("OfferCallingCard", args,
-					     &callingcard_offer_callback, (void*)offerdata);
-			offerdata = NULL; // pointer ownership transferred
+			LLNotifications::instance().add("OfferCallingCard", args, payload);
 		}
 	}
 	else
 	{
 		LL_WARNS("Messaging") << "Calling card offer from an unknown source." << LL_ENDL;
 	}
-
-	delete offerdata; // !=NULL if we didn't give ownership away
-	offerdata = NULL;
 }
 
 void process_accept_callingcard(LLMessageSystem* msg, void**)
 {
-	LLNotifyBox::showXml("CallingCardAccepted");
+	LLNotifications::instance().add("CallingCardAccepted");
 }
 
 void process_decline_callingcard(LLMessageSystem* msg, void**)
 {
-	LLNotifyBox::showXml("CallingCardDeclined");
+	LLNotifications::instance().add("CallingCardDeclined");
 }
 
 
@@ -2496,18 +2543,18 @@ class LLFetchInWelcomeArea : public LLInventoryFetchDescendentsObserver
 				LLInventoryModel::EXCLUDE_TRASH,
 				is_card);
 		}
-		LLStringUtil::format_map_t args;
+		LLSD args;
 		if ( land_items.count() > 0 )
 		{	// Show notification that they can now teleport to landmarks.  Use a random landmark from the inventory
 			S32 random_land = ll_rand( land_items.count() - 1 );
-			args["[NAME]"] = land_items[random_land]->getName();
-			LLNotifyBox::showXml("TeleportToLandmark",args);
+			args["NAME"] = land_items[random_land]->getName();
+			LLNotifications::instance().add("TeleportToLandmark",args);
 		}
 		if ( card_items.count() > 0 )
 		{	// Show notification that they can now contact people.  Use a random calling card from the inventory
 			S32 random_card = ll_rand( card_items.count() - 1 );
-			args["[NAME]"] = card_items[random_card]->getName();
-			LLNotifyBox::showXml("TeleportToPerson",args);
+			args["NAME"] = card_items[random_card]->getName();
+			LLNotifications::instance().add("TeleportToPerson",args);
 		}
 
 		gInventory.removeObserver(this);
@@ -2688,11 +2735,6 @@ void process_avatar_init_complete(LLMessageSystem* msg, void**)
 }
 */
 
-static void display_release_notes(S32, void* data)
-{
-	gAgent.getRegion()->showReleaseNotes();
-}
-
 void process_agent_movement_complete(LLMessageSystem* msg, void**)
 {
 	gAgentMovementCompleted = true;
@@ -2864,8 +2906,9 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**)
 
 	if (!gLastVersionChannel.empty())
 	{
-		LLNotifyBox::showXml(
-			"ServerVersionChanged",	display_release_notes, NULL);
+		LLSD payload;
+		payload["message"] = version_channel;
+		LLNotifications::instance().add("ServerVersionChanged", LLSD(), payload);
 	}
 
 	gLastVersionChannel = version_channel;
@@ -4059,9 +4102,9 @@ void process_money_balance_reply( LLMessageSystem* msg, void** )
 		// Make the user confirm the transaction, since they might
 		// have missed something during an event.
 		// *TODO:translate
-		LLStringUtil::format_map_t args;
-		args["[MESSAGE]"] = desc;
-		LLNotifyBox::showXml("SystemMessage", args);
+		LLSD args;
+		args["MESSAGE"] = desc;
+		LLNotifications::instance().add("SystemMessage", args);
 
 		// Once the 'recent' container gets large enough, chop some
 		// off the beginning.
@@ -4121,54 +4164,54 @@ void process_alert_core(const std::string& message, BOOL modal)
 		// Allow the server to spawn a named alert so that server alerts can be
 		// translated out of English.
 		std::string alert_name(message.substr(ALERT_PREFIX.length()));
-		LLAlertDialog::showXml(alert_name);
+		LLNotifications::instance().add(alert_name);
 	}
 	else if (message.find(NOTIFY_PREFIX) == 0)
 	{
 		// Allow the server to spawn a named notification so that server notifications can be
 		// translated out of English.
 		std::string notify_name(message.substr(NOTIFY_PREFIX.length()));
-		LLNotifyBox::showXml(notify_name);
+		LLNotifications::instance().add(notify_name);
 	}
 	else if (message[0] == '/')
 	{
 		// System message is important, show in upper-right box not tip
 		std::string text(message.substr(1));
-		LLStringUtil::format_map_t args;
+		LLSD args;
 		if (text.substr(0,17) == "RESTART_X_MINUTES")
 		{
 			S32 mins = 0;
 			LLStringUtil::convertToS32(text.substr(18), mins);
-			args["[MINUTES]"] = llformat("%d",mins);
-			LLNotifyBox::showXml("RegionRestartMinutes", args);
+			args["MINUTES"] = llformat("%d",mins);
+			LLNotifications::instance().add("RegionRestartMinutes", args);
 		}
 		else if (text.substr(0,17) == "RESTART_X_SECONDS")
 		{
 			S32 secs = 0;
 			LLStringUtil::convertToS32(text.substr(18), secs);
-			args["[SECONDS]"] = llformat("%d",secs);
-			LLNotifyBox::showXml("RegionRestartSeconds", args);
+			args["SECONDS"] = llformat("%d",secs);
+			LLNotifications::instance().add("RegionRestartSeconds", args);
 		}
 		else
 		{
 			// *TODO:translate
-			args["[MESSAGE]"] = text;
-			LLNotifyBox::showXml("SystemMessage", args);
+			args["MESSAGE"] = text;
+			LLNotifications::instance().add("SystemMessage", args);
 		}
 	}
 	else if (modal)
 	{
 		// *TODO:translate
-		LLStringUtil::format_map_t args;
-		args["[ERROR_MESSAGE]"] = message;
-		gViewerWindow->alertXml("ErrorMessage", args);
+		LLSD args;
+		args["ERROR_MESSAGE"] = message;
+		LLNotifications::instance().add("ErrorMessage", args);
 	}
 	else
 	{
 		// *TODO:translate
-		LLStringUtil::format_map_t args;
-		args["[MESSAGE]"] = message;
-		LLNotifyBox::showXml("SystemMessageTip", args);
+		LLSD args;
+		args["MESSAGE"] = message;
+		LLNotifications::instance().add("SystemMessageTip", args);
 	}
 }
 
@@ -4300,23 +4343,7 @@ void process_economy_data(LLMessageSystem *msg, void** /*user_data*/)
 	gMenuHolder->childSetLabelArg("Bulk Upload", "[COST]", llformat("%d", upload_cost));
 }
 
-class LLScriptQuestionCBData
-{
-public:
-	LLScriptQuestionCBData(const LLUUID &taskid, const LLUUID &itemid, const LLHost &sender, S32 questions, const std::string& object_name, const std::string& owner_name)
-		: mTaskID(taskid), mItemID(itemid), mSender(sender), mQuestions(questions), mObjectName(object_name), mOwnerName(owner_name)
-	{
-	}
-
-	LLUUID mTaskID;
-	LLUUID mItemID;
-	LLHost mSender;
-	S32	   mQuestions;
-	std::string mObjectName;
-	std::string mOwnerName;
-};
-
-void notify_cautioned_script_question(LLScriptQuestionCBData* cbdata, S32 orig_questions, BOOL granted)
+void notify_cautioned_script_question(const LLSD& notification, const LLSD& response, S32 orig_questions, BOOL granted)
 {
 	// only continue if at least some permissions were requested
 	if (orig_questions)
@@ -4327,16 +4354,16 @@ void notify_cautioned_script_question(LLScriptQuestionCBData* cbdata, S32 orig_q
 		// located in [REGIONNAME] at [REGIONPOS], 
 		// has been <granted|denied> permission to: [PERMISSIONS]."
 
-		LLUIString notice(LLNotifyBox::getTemplateMessage(granted ? "ScriptQuestionCautionChatGranted" : "ScriptQuestionCautionChatDenied"));
+		LLUIString notice(LLFloaterChat::getInstance()->getString(granted ? "ScriptQuestionCautionChatGranted" : "ScriptQuestionCautionChatDenied"));
 
 		// always include the object name and owner name 
-		notice.setArg("[OBJECTNAME]", cbdata->mObjectName);
-		notice.setArg("[OWNERNAME]", cbdata->mOwnerName);
+		notice.setArg("[OBJECTNAME]", notification["payload"]["object_name"].asString());
+		notice.setArg("[OWNERNAME]", notification["payload"]["owner_name"].asString());
 
 		// try to lookup viewerobject that corresponds to the object that
 		// requested permissions (here, taskid->requesting object id)
 		BOOL foundpos = FALSE;
-		LLViewerObject* viewobj = gObjectList.findObject(cbdata->mTaskID);
+		LLViewerObject* viewobj = gObjectList.findObject(notification["payload"]["task_id"].asUUID());
 		if (viewobj)
 		{
 			// found the viewerobject, get it's position in its region
@@ -4369,7 +4396,7 @@ void notify_cautioned_script_question(LLScriptQuestionCBData* cbdata, S32 orig_q
 		std::string perms;
 		for (S32 i = 0; i < SCRIPT_PERMISSION_EOF; i++)
 		{
-			if ((orig_questions & LSCRIPTRunTimePermissionBits[i]) && LLNotifyBox::getTemplateIsCaution(SCRIPT_QUESTIONS[i]))
+			if ((orig_questions & LSCRIPTRunTimePermissionBits[i]) && SCRIPT_QUESTION_IS_CAUTION[i])
 			{
 				count++;
 				caution = TRUE;
@@ -4381,7 +4408,7 @@ void notify_cautioned_script_question(LLScriptQuestionCBData* cbdata, S32 orig_q
 					perms.append(", ");
 				}
 
-				perms.append(LLNotifyBox::getTemplateMessage(SCRIPT_QUESTIONS[i]));
+				perms.append(LLFloaterChat::getInstance()->getString(SCRIPT_QUESTIONS[i]));
 			}
 		}
 
@@ -4397,43 +4424,12 @@ void notify_cautioned_script_question(LLScriptQuestionCBData* cbdata, S32 orig_q
 	}
 }
 
-void script_question_decline_cb(S32 option, void* user_data)
-{
-	LLMessageSystem *msg = gMessageSystem;
-	LLScriptQuestionCBData *cbdata = (LLScriptQuestionCBData *)user_data;
-	
-	// remember the permissions requested so they can be checked
-	// when it comes time to log a chat message
-	S32 orig = cbdata->mQuestions;
-
-	// this callback will always decline all permissions requested
-	// (any question flags set in the ScriptAnswerYes message
-	// will be interpreted as having been granted, so clearing all
-	// the bits will deny every permission)
-	cbdata->mQuestions = 0;
-
-	// respond with the permissions denial
-	msg->newMessageFast(_PREHASH_ScriptAnswerYes);
-	msg->nextBlockFast(_PREHASH_AgentData);
-	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
-	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-	msg->nextBlockFast(_PREHASH_Data);
-	msg->addUUIDFast(_PREHASH_TaskID, cbdata->mTaskID);
-	msg->addUUIDFast(_PREHASH_ItemID, cbdata->mItemID);
-	msg->addS32Fast(_PREHASH_Questions, cbdata->mQuestions);
-	msg->sendReliable(cbdata->mSender);
-
-	// log a chat message, if appropriate
-	notify_cautioned_script_question(cbdata, orig, FALSE);
-
-	delete cbdata;
-}
-
-void script_question_cb(S32 option, void* user_data)
+bool script_question_cb(const LLSD& notification, const LLSD& response)
 {
+	S32 option = LLNotification::getSelectedOption(notification, response);
 	LLMessageSystem *msg = gMessageSystem;
-	LLScriptQuestionCBData *cbdata = (LLScriptQuestionCBData *)user_data;
-	S32 orig = cbdata->mQuestions;
+	S32 orig = notification["payload"]["questions"].asInteger();
+	S32 new_questions = orig;
 
 	// check whether permissions were granted or denied
 	BOOL allowed = TRUE;
@@ -4441,48 +4437,68 @@ void script_question_cb(S32 option, void* user_data)
 	// if any other button was clicked, the permissions were denied
 	if (option != 0)
 	{
-		cbdata->mQuestions = 0;
+		new_questions = 0;
 		allowed = FALSE;
 	}	
 
+	LLUUID task_id = notification["payload"]["task_id"].asUUID();
+	LLUUID item_id = notification["payload"]["item_id"].asUUID();
+
 	// reply with the permissions granted or denied
 	msg->newMessageFast(_PREHASH_ScriptAnswerYes);
 	msg->nextBlockFast(_PREHASH_AgentData);
 	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
 	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
 	msg->nextBlockFast(_PREHASH_Data);
-	msg->addUUIDFast(_PREHASH_TaskID, cbdata->mTaskID);
-	msg->addUUIDFast(_PREHASH_ItemID, cbdata->mItemID);
-	msg->addS32Fast(_PREHASH_Questions, cbdata->mQuestions);
-	msg->sendReliable(cbdata->mSender);
+	msg->addUUIDFast(_PREHASH_TaskID, task_id);
+	msg->addUUIDFast(_PREHASH_ItemID, item_id);
+	msg->addS32Fast(_PREHASH_Questions, new_questions);
+	msg->sendReliable(LLHost(notification["payload"]["sender"].asString()));
 
 	// only log a chat message if caution prompts are enabled
 	if (gSavedSettings.getBOOL("PermissionsCautionEnabled"))
 	{
 		// log a chat message, if appropriate
-		notify_cautioned_script_question(cbdata, orig, allowed);
+		notify_cautioned_script_question(notification, response, orig, allowed);
 	}
 
-	if ( option == 2 ) // mute
+	if ( response["Mute"] ) // mute
 	{
-		LLMuteList::getInstance()->add(LLMute(cbdata->mItemID, cbdata->mObjectName, LLMute::OBJECT));
+		LLMuteList::getInstance()->add(LLMute(item_id, notification["payload"]["object_name"].asString(), LLMute::OBJECT));
 
 		// purge the message queue of any previously queued requests from the same source. DEV-4879
 		class OfferMatcher : public LLNotifyBoxView::Matcher
 		{
 		public:
 			OfferMatcher(const LLUUID& to_block) : blocked_id(to_block) {}
-			BOOL matches(LLNotifyBox::notify_callback_t callback, void* cb_data) const
+			BOOL matches(const LLNotificationPtr notification) const
 			{
-				return callback == script_question_cb && ((LLScriptQuestionCBData*)cb_data)->mItemID == blocked_id;
+				if (notification->getName() == "ScriptQuestionCaution"
+					|| notification->getName() == "ScriptQuestion")
+				{
+					return (notification->getPayload()["item_id"].asUUID() == blocked_id);
+				}
+				return FALSE;
 			}
 		private:
 			const LLUUID& blocked_id;
 		};
-		gNotifyBoxView->purgeMessagesMatching(OfferMatcher(cbdata->mItemID));
+		// should do this via the channel
+		gNotifyBoxView->purgeMessagesMatching(OfferMatcher(item_id));
+	}
+
+	if (response["Details"])
+	{
+		// respawn notification...
+		LLNotifications::instance().add(notification["name"], notification["substitutions"], notification["payload"]);
+
+		// ...with description on top
+		LLNotifications::instance().add("DebitPermissionDetails");
 	}
-	delete cbdata;
+	return false;
 }
+static LLNotificationFunctorRegistration script_question_cb_reg_1("ScriptQuestion", script_question_cb);
+static LLNotificationFunctorRegistration script_question_cb_reg_2("ScriptQuestionCaution", script_question_cb);
 
 void process_script_question(LLMessageSystem *msg, void **user_data)
 {
@@ -4532,9 +4548,9 @@ void process_script_question(LLMessageSystem *msg, void **user_data)
 	{
 		BOOL caution = FALSE;
 		S32 count = 0;
-		LLStringUtil::format_map_t args;
-		args["[OBJECTNAME]"] = object_name;
-		args["[NAME]"] = owner_name;
+		LLSD args;
+		args["OBJECTNAME"] = object_name;
+		args["NAME"] = owner_name;
 
 		// check the received permission flags against each permission
 		for (S32 i = 0; i < SCRIPT_PERMISSION_EOF; i++)
@@ -4542,34 +4558,32 @@ void process_script_question(LLMessageSystem *msg, void **user_data)
 			if (questions & LSCRIPTRunTimePermissionBits[i])
 			{
 				count++;
-				script_question += "    " + LLNotifyBox::getTemplateMessage(SCRIPT_QUESTIONS[i]) + "\n";
+				script_question += "    " + LLFloaterChat::getInstance()->getString(SCRIPT_QUESTIONS[i]) + "\n";
 
 				// check whether permission question should cause special caution dialog
-				caution |= LLNotifyBox::getTemplateIsCaution(SCRIPT_QUESTIONS[i]);
+				caution |= (SCRIPT_QUESTION_IS_CAUTION[i]);
 			}
 		}
-		args["[QUESTIONS]"] = script_question;
+		args["QUESTIONS"] = script_question;
 
-		LLScriptQuestionCBData *cbdata = new LLScriptQuestionCBData(taskid, itemid, sender, questions, object_name, owner_name);
+		LLSD payload;
+		payload["task_id"] = taskid;
+		payload["item_id"] = itemid;
+		payload["sender"] = sender.getIPandPort();
+		payload["questions"] = questions;
+		payload["object_name"] = object_name;
+		payload["owner_name"] = owner_name;
 
 		// check whether cautions are even enabled or not
 		if (gSavedSettings.getBOOL("PermissionsCautionEnabled"))
 		{
-			if (caution)
-			{
-				// display the caution permissions prompt
-				LLNotifyBox::showXml("ScriptQuestionCaution", args, TRUE, script_question_cb, cbdata);
-			}
-			else
-			{
-				// display the permissions request normally
-				LLNotifyBox::showXml("ScriptQuestion", args, FALSE, script_question_cb, cbdata);
-			}
+			// display the caution permissions prompt
+			LLNotifications::instance().add(caution ? "ScriptQuestionCaution" : "ScriptQuestion", args, payload);
 		}
 		else
 		{
 			// fall back to default behavior if cautions are entirely disabled
-			LLNotifyBox::showXml("ScriptQuestion", args, FALSE, script_question_cb, cbdata);
+			LLNotifications::instance().add("ScriptQuestion", args, payload);
 		}
 
 	}
@@ -4706,18 +4720,18 @@ void process_teleport_failed(LLMessageSystem *msg, void**)
 	std::string reason;
 	msg->getStringFast(_PREHASH_Info, _PREHASH_Reason, reason);
 
-	LLStringUtil::format_map_t args;
+	LLSD args;
 	std::string big_reason = LLAgent::sTeleportErrorMessages[reason];
 	if ( big_reason.size() > 0 )
 	{	// Substitute verbose reason from the local map
-		args["[REASON]"] = big_reason;
+		args["REASON"] = big_reason;
 	}
 	else
 	{	// Nothing found in the map - use what the server returned
-		args["[REASON]"] = reason;
+		args["REASON"] = reason;
 	}
 
-	gViewerWindow->alertXml("CouldNotTeleportReason", args);
+	LLNotifications::instance().add("CouldNotTeleportReason", args);
 
 	if( gAgent.getTeleportState() != LLAgent::TELEPORT_NONE )
 	{
@@ -4839,9 +4853,10 @@ void send_group_notice(const LLUUID& group_id,
 			bin_bucket_size);
 }
 
-void handle_lure_callback(S32 option, const std::string& text, void* userdata)
+bool handle_lure_callback(const LLSD& notification, const LLSD& response)
 {
-	LLDynamicArray<LLUUID>* invitees = (LLDynamicArray<LLUUID>*)userdata;
+	std::string text = response["message"].asString();
+	S32 option = LLNotification::getSelectedOption(notification, response);
 
 	if(0 == option)
 	{
@@ -4853,21 +4868,17 @@ void handle_lure_callback(S32 option, const std::string& text, void* userdata)
 		msg->nextBlockFast(_PREHASH_Info);
 		msg->addU8Fast(_PREHASH_LureType, (U8)0); // sim will fill this in.
 		msg->addStringFast(_PREHASH_Message, text);
-		for(LLDynamicArray<LLUUID>::iterator itr = invitees->begin(); itr != invitees->end(); ++itr)
+		for(LLSD::array_const_iterator it = notification["payload"]["ids"].beginArray();
+			it != notification["payload"]["ids"].endArray();
+			++it)
 		{
 			msg->nextBlockFast(_PREHASH_TargetData);
-			msg->addUUIDFast(_PREHASH_TargetID, *itr);
+			msg->addUUIDFast(_PREHASH_TargetID, it->asUUID());
 		}
 		gAgent.sendReliableMessage();
 	}
 
-	delete invitees;
-	invitees = NULL;
-}
-
-void handle_lure_callback_godlike(S32 option, void* userdata)
-{
-	handle_lure_callback(option, LLStringUtil::null, userdata);
+	return false;
 }
 
 void handle_lure(const LLUUID& invitee)
@@ -4880,21 +4891,23 @@ void handle_lure(const LLUUID& invitee)
 // Prompt for a message to the invited user.
 void handle_lure(LLDynamicArray<LLUUID>& ids) 
 {
-	LLDynamicArray<LLUUID>* userdata = new LLDynamicArray<LLUUID>(ids);
+	LLSD edit_args;
+	edit_args["REGION"] = gAgent.getRegion()->getName();
 
-	LLStringUtil::format_map_t edit_args;
-	edit_args["[REGION]"] = gAgent.getRegion()->getName();
+	LLSD payload;
+	for (LLDynamicArray<LLUUID>::iterator it = ids.begin();
+		it != ids.end();
+		++it)
+	{
+		payload["ids"].append(*it);
+	}
 	if (gAgent.isGodlike())
 	{
-		gViewerWindow->alertXmlEditText("OfferTeleportFromGod", edit_args,
-										&handle_lure_callback_godlike, userdata,
-										NULL, NULL, edit_args);
+		LLNotifications::instance().add("OfferTeleportFromGod", edit_args, payload, handle_lure_callback);
 	}
 	else
 	{
-		gViewerWindow->alertXmlEditText("OfferTeleport", edit_args,
-										NULL, NULL,
-										handle_lure_callback, userdata, edit_args);
+		LLNotifications::instance().add("OfferTeleport", edit_args, payload, handle_lure_callback);
 	}
 }
 
@@ -4986,21 +4999,13 @@ const S32 SCRIPT_DIALOG_BUTTON_STR_SIZE = 24;
 const S32 SCRIPT_DIALOG_MAX_MESSAGE_SIZE = 512;
 const char* SCRIPT_DIALOG_HEADER = "Script Dialog:\n";
 
-struct ScriptDialogInfo
+bool callback_script_dialog(const LLSD& notification, const LLSD& response)
 {
-	LLHost mSender;
-	LLUUID mObjectID;
-	S32 mChatChannel;
-	std::vector<std::string> mButtons;
-};
-
-void callback_script_dialog(S32 option, void* data)
-{
-	ScriptDialogInfo* info = (ScriptDialogInfo*)data;
-	if (!info) return;
-
+	LLNotificationForm form(notification["form"]);
+	std::string button = LLNotification::getSelectedOptionName(response);
+	S32 button_idx = LLNotification::getSelectedOption(notification, response);
 	// Didn't click "Ignore"
-	if (0 != option)
+	if (button_idx != -1)
 	{
 		LLMessageSystem* msg = gMessageSystem;
 		msg->newMessage("ScriptDialogReply");
@@ -5008,112 +5013,108 @@ void callback_script_dialog(S32 option, void* data)
 		msg->addUUID("AgentID", gAgent.getID());
 		msg->addUUID("SessionID", gAgent.getSessionID());
 		msg->nextBlock("Data");
-		msg->addUUID("ObjectID", info->mObjectID);
-		msg->addS32("ChatChannel", info->mChatChannel);
-		msg->addS32("ButtonIndex", option);
-		msg->addString("ButtonLabel", info->mButtons[option-1]);
-		msg->sendReliable(info->mSender);
+		msg->addUUID("ObjectID", notification["payload"]["object_id"].asUUID());
+		msg->addS32("ChatChannel", notification["payload"]["chat_channel"].asInteger());
+		msg->addS32("ButtonIndex", button_idx);
+		msg->addString("ButtonLabel", button);
+		msg->sendReliable(LLHost(notification["payload"]["sender"].asString()));
 	}
 
-	delete info;
+	return false;
 }
+static LLNotificationFunctorRegistration callback_script_dialog_reg_1("ScriptDialog", callback_script_dialog);
+static LLNotificationFunctorRegistration callback_script_dialog_reg_2("ScriptDialogGroup", callback_script_dialog);
 
 void process_script_dialog(LLMessageSystem* msg, void**)
 {
 	S32 i;
 
-	ScriptDialogInfo* info = new ScriptDialogInfo;
+	LLSD payload;
 
-	std::string message; // Account for size of "Script Dialog:\n"
+	std::string message; 
 	std::string first_name;
 	std::string last_name;
 	std::string title;
-	info->mSender = msg->getSender();
 
-	msg->getUUID("Data", "ObjectID", info->mObjectID);
+	LLUUID object_id;
+	S32 chat_channel;
+	msg->getUUID("Data", "ObjectID", object_id);
 	msg->getString("Data", "FirstName", first_name);
 	msg->getString("Data", "LastName", last_name);
 	msg->getString("Data", "ObjectName", title);
 	msg->getString("Data", "Message", message);
-	msg->getS32("Data", "ChatChannel", info->mChatChannel);
+	msg->getS32("Data", "ChatChannel", chat_channel);
 
 		// unused for now
 	LLUUID image_id;
 	msg->getUUID("Data", "ImageID", image_id);
 
+	payload["sender"] = msg->getSender().getIPandPort();
+	payload["object_id"] = object_id;
+	payload["chat_channel"] = chat_channel;
+
+	// build up custom form
 	S32 button_count = msg->getNumberOfBlocks("Buttons");
 	if (button_count > SCRIPT_DIALOG_MAX_BUTTONS)
 	{
 		button_count = SCRIPT_DIALOG_MAX_BUTTONS;
 	}
 
+	LLNotificationForm form;
 	for (i = 0; i < button_count; i++)
 	{
 		std::string tdesc;
 		msg->getString("Buttons", "ButtonLabel", tdesc, i);
-		info->mButtons.push_back(tdesc);
+		form.addElement("button", std::string(tdesc));
 	}
 
-	LLStringUtil::format_map_t args;
-	args["[TITLE]"] = title;
-	args["[MESSAGE]"] = message;
+	LLSD args;
+	args["TITLE"] = title;
+	args["MESSAGE"] = message;
+	LLNotificationPtr notification;
 	if (!first_name.empty())
 	{
-		args["[FIRST]"] = first_name;
-		args["[LAST]"] = last_name;
-		LLNotifyBox::showXml("ScriptDialog", args,
-							 callback_script_dialog, info,
-							 info->mButtons,
-							 TRUE);
+		args["FIRST"] = first_name;
+		args["LAST"] = last_name;
+		notification = LLNotifications::instance().add(
+			LLNotification::Params("ScriptDialog").substitutions(args).payload(payload).form_elements(form.asLLSD()));
 	}
 	else
 	{
-		args["[GROUPNAME]"] = last_name;
-		LLNotifyBox::showXml("ScriptDialogGroup", args,
-							 callback_script_dialog, info,
-							 info->mButtons,
-							 TRUE);
+		args["GROUPNAME"] = last_name;
+		notification = LLNotifications::instance().add(
+			LLNotification::Params("ScriptDialogGroup").substitutions(args).payload(payload).form_elements(form.asLLSD()));
 	}
 }
 
 //---------------------------------------------------------------------------
 
-struct LoadUrlInfo
-{
-	LLUUID mObjectID;
-	LLUUID mOwnerID;
-	BOOL mOwnerIsGroup;
-	std::string mObjectName;
-	std::string mMessage;
-	std::string mUrl;
-};
 
-std::vector<LoadUrlInfo*> gLoadUrlList;
+std::vector<LLSD> gLoadUrlList;
 
-void callback_load_url(S32 option, void* data)
+bool callback_load_url(const LLSD& notification, const LLSD& response)
 {
-	LoadUrlInfo* infop = (LoadUrlInfo*)data;
-	if (!infop) return;
+	S32 option = LLNotification::getSelectedOption(notification, response);
 
 	if (0 == option)
 	{
-		LLWeb::loadURLExternal(infop->mUrl);
+		LLWeb::loadURL(notification["payload"]["url"].asString());
 	}
 
-	delete infop;
-	infop = NULL;
+	return false;
 }
+static LLNotificationFunctorRegistration callback_load_url_reg("LoadWebPage", callback_load_url);
 
 
 // We've got the name of the person who owns the object hurling the url.
 // Display confirmation dialog.
 void callback_load_url_name(const LLUUID& id, const std::string& first, const std::string& last, BOOL is_group, void* data)
 {
-	std::vector<LoadUrlInfo*>::iterator it;
+	std::vector<LLSD>::iterator it;
 	for (it = gLoadUrlList.begin(); it != gLoadUrlList.end(); )
 	{
-		LoadUrlInfo* infop = *it;
-		if (infop->mOwnerID == id)
+		LLSD load_url_info = *it;
+		if (load_url_info["owner_id"].asUUID() == id)
 		{
 			it = gLoadUrlList.erase(it);
 
@@ -5130,16 +5131,15 @@ void callback_load_url_name(const LLUUID& id, const std::string& first, const st
 			// For legacy name-only mutes.
 			if (LLMuteList::getInstance()->isMuted(LLUUID::null, owner_name))
 			{
-				delete infop;
-				infop = NULL;
 				continue;
 			}
-			LLStringUtil::format_map_t args;
-			args["[URL]"] = infop->mUrl;
-			args["[MESSAGE]"] = infop->mMessage;
-			args["[OBJECTNAME]"] = infop->mObjectName;
-			args["[NAME]"] = owner_name;
-			LLNotifyBox::showXml("LoadWebPage", args, callback_load_url, infop);
+			LLSD args;
+			args["URL"] = load_url_info["url"].asString();
+			args["MESSAGE"] = load_url_info["message"].asString();;
+			args["OBJECTNAME"] = load_url_info["object_name"].asString();
+			args["NAME"] = owner_name;
+
+			LLNotifications::instance().add("LoadWebPage", args, load_url_info);
 		}
 		else
 		{
@@ -5150,40 +5150,51 @@ void callback_load_url_name(const LLUUID& id, const std::string& first, const st
 
 void process_load_url(LLMessageSystem* msg, void**)
 {
-	LoadUrlInfo* infop = new LoadUrlInfo;
-
-	msg->getString("Data", "ObjectName", infop->mObjectName);
-	msg->getUUID(  "Data", "ObjectID", infop->mObjectID);
-	msg->getUUID(  "Data", "OwnerID", infop->mOwnerID);
-	msg->getBOOL(  "Data", "OwnerIsGroup", infop->mOwnerIsGroup);
-	msg->getString("Data", "Message", infop->mMessage);
-	msg->getString("Data", "URL", infop->mUrl);
+	LLUUID object_id;
+	LLUUID owner_id;
+	BOOL owner_is_group;
+	char object_name[256];		/* Flawfinder: ignore */
+	char message[256];		/* Flawfinder: ignore */
+	char url[256];		/* Flawfinder: ignore */
+
+	msg->getString("Data", "ObjectName", 256, object_name);
+	msg->getUUID(  "Data", "ObjectID", object_id);
+	msg->getUUID(  "Data", "OwnerID", owner_id);
+	msg->getBOOL(  "Data", "OwnerIsGroup", owner_is_group);
+	msg->getString("Data", "Message", 256, message);
+	msg->getString("Data", "URL", 256, url);
+
+	LLSD payload;
+	payload["object_id"] = object_id;
+	payload["owner_id"] = owner_id;
+	payload["owner_is_group"] = owner_is_group;
+	payload["object_name"] = object_name;
+	payload["message"] = message;
+	payload["url"] = url;
 
 	// URL is safety checked in load_url above
 
 	// Check if object or owner is muted
-	if (LLMuteList::getInstance()->isMuted(infop->mObjectID, infop->mObjectName) ||
-	    LLMuteList::getInstance()->isMuted(infop->mOwnerID))
+	if (LLMuteList::getInstance()->isMuted(object_id, object_name) ||
+	    LLMuteList::getInstance()->isMuted(owner_id))
 	{
 		LL_INFOS("Messaging")<<"Ignoring load_url from muted object/owner."<<LL_ENDL;
-		delete infop;
-		infop = NULL;
 		return;
 	}
 
 	// Add to list of pending name lookups
-	gLoadUrlList.push_back(infop);
+	gLoadUrlList.push_back(payload);
 
-	gCacheName->get(infop->mOwnerID, infop->mOwnerIsGroup, callback_load_url_name);
+	gCacheName->get(owner_id, owner_is_group, callback_load_url_name);
 }
 
 
 void callback_download_complete(void** data, S32 result, LLExtStat ext_status)
 {
 	std::string* filepath = (std::string*)data;
-	LLStringUtil::format_map_t args;
-	args["[DOWNLOAD_PATH]"] = *filepath;
-	gViewerWindow->alertXml("FinishedRawDownload", args);
+	LLSD args;
+	args["DOWNLOAD_PATH"] = *filepath;
+	LLNotifications::instance().add("FinishedRawDownload", args);
 	delete filepath;
 }
 
@@ -5415,3 +5426,10 @@ void invalid_message_callback(LLMessageSystem* msg,
 
 // Please do not add more message handlers here. This file is huge.
 // Put them in a file related to the functionality you are implementing. JC
+
+void LLOfferInfo::forceResponse(InventoryOfferResponse response)
+{
+	LLNotification::Params params("UserGiveItem");
+	params.functor(boost::bind(&LLOfferInfo::inventory_offer_callback, this, _1, _2));
+	LLNotifications::instance().forceResponse(params, response);
+}
diff --git a/indra/newview/llviewermessage.h b/indra/newview/llviewermessage.h
index a2ed04d0a77..bbda752e89c 100644
--- a/indra/newview/llviewermessage.h
+++ b/indra/newview/llviewermessage.h
@@ -192,11 +192,15 @@ void process_decline_callingcard(LLMessageSystem* msg, void**);
 void invalid_message_callback(LLMessageSystem*, void*, EMessageException);
 
 void process_initiate_download(LLMessageSystem* msg, void**);
-void inventory_offer_callback(S32 option, void* user_data);
 void start_new_inventory_observer();
 
 struct LLOfferInfo
 {
+	LLOfferInfo() {};
+	LLOfferInfo(const LLSD& sd);
+
+	void forceResponse(InventoryOfferResponse response);
+
 	EInstantMessage mIM;
 	LLUUID mFromID;
 	BOOL mFromGroup;
@@ -208,6 +212,10 @@ struct LLOfferInfo
 	std::string mFromName;
 	std::string mDesc;
 	LLHost mHost;
+
+	LLSD asLLSD();
+	bool inventory_offer_callback(const LLSD& notification, const LLSD& response);
+
 };
 
 void process_feature_disabled_message(LLMessageSystem* msg, void**);
diff --git a/indra/newview/llviewerparcelmedia.cpp b/indra/newview/llviewerparcelmedia.cpp
index fe588534e5e..05c589c398f 100644
--- a/indra/newview/llviewerparcelmedia.cpp
+++ b/indra/newview/llviewerparcelmedia.cpp
@@ -50,7 +50,7 @@ S32 LLViewerParcelMedia::sMediaParcelLocalID = 0;
 LLUUID LLViewerParcelMedia::sMediaRegionID;
 
 // Local functions
-void callback_play_media(S32 option, void* data);
+bool callback_play_media(const LLSD& notification, const LLSD& response, LLParcel* parcel);
 
 // Move this to its own file.
 // helper class that tries to download a URL from a web site and calls a method
@@ -167,8 +167,8 @@ void LLViewerParcelMedia::update(LLParcel* parcel)
 				// First use warning
 				if(	gSavedSettings.getWarning("FirstStreamingVideo") )
 				{
-					gViewerWindow->alertXml("ParcelCanPlayMedia",
-						callback_play_media, (void*)parcel);
+					LLNotifications::instance().add("ParcelCanPlayMedia", LLSD(), LLSD(),
+						boost::bind(callback_play_media, _1, _2, parcel));
 
 				}
 
@@ -192,7 +192,7 @@ void LLViewerParcelMedia::update(LLParcel* parcel)
 				{
 					gSavedSettings.setWarning("QuickTimeInstalled", FALSE);
 
-					LLNotifyBox::showXml("NoQuickTime" );
+					LLNotifications::instance().add("NoQuickTime" );
 				};
 			}
 		}
@@ -382,9 +382,9 @@ void LLViewerParcelMedia::processParcelMediaUpdate( LLMessageSystem *msg, void *
 	}
 }
 
-void callback_play_media(S32 option, void* data)
+bool callback_play_media(const LLSD& notification, const LLSD& response, LLParcel* parcel)
 {
-	LLParcel* parcel = (LLParcel*)data;
+	S32 option = LLNotification::getSelectedOption(notification, response);
 	if (option == 0)
 	{
 		gSavedSettings.setBOOL("AudioStreamingVideo", TRUE);
@@ -395,6 +395,6 @@ void callback_play_media(S32 option, void* data)
 		gSavedSettings.setBOOL("AudioStreamingVideo", FALSE);
 	}
 	gSavedSettings.setWarning("FirstStreamingVideo", FALSE);
-
+	return false;
 }
 
diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp
index 6e37ec2095a..099204e7403 100644
--- a/indra/newview/llviewerparcelmgr.cpp
+++ b/indra/newview/llviewerparcelmgr.cpp
@@ -90,7 +90,7 @@ void callback_prepare_video(S32 option, void* data);
 void prepare_video(const LLParcel *parcelp);
 void start_video(const LLParcel *parcelp);
 void stop_video();
-void callback_god_force_owner(S32 option, void* user_data);
+bool callback_god_force_owner(const LLSD&, const LLSD&);
 
 struct LLGodForceOwnerData
 {
@@ -515,7 +515,7 @@ LLParcelSelectionHandle LLViewerParcelMgr::selectLand(const LLVector3d &corner1,
 
 	if (region != region_other)
 	{
-		LLNotifyBox::showXml("CantSelectLandFromMultipleRegions");
+		LLNotifications::instance().add("CantSelectLandFromMultipleRegions");
 		mSelected = FALSE;
 		notifyObservers();
 		return NULL;
@@ -904,7 +904,7 @@ void LLViewerParcelMgr::sendParcelGodForceOwner(const LLUUID& owner_id)
 {
 	if (!mSelected)
 	{
-		gViewerWindow->alertXml("CannotSetLandOwnerNothingSelected");
+		LLNotifications::instance().add("CannotSetLandOwnerNothingSelected");
 		return;
 	}
 
@@ -919,7 +919,7 @@ void LLViewerParcelMgr::sendParcelGodForceOwner(const LLUUID& owner_id)
 	if (!region)
 	{
 		// TODO: Add a force owner version of this alert.
-		gViewerWindow->alertXml("CannotContentifyNoRegion");
+		LLNotifications::instance().add("CannotContentifyNoRegion");
 		return;
 	}
 
@@ -927,29 +927,33 @@ void LLViewerParcelMgr::sendParcelGodForceOwner(const LLUUID& owner_id)
 	LLViewerRegion *region2 = LLWorld::getInstance()->getRegionFromPosGlobal( east_north_region_check );
 	if (region != region2)
 	{
-		gViewerWindow->alertXml("CannotSetLandOwnerMultipleRegions");
+		LLNotifications::instance().add("CannotSetLandOwnerMultipleRegions");
 		return;
 	}
 
 	llinfos << "Region " << region->getOriginGlobal() << llendl;
 
-	LLGodForceOwnerData* data = new LLGodForceOwnerData(owner_id, mCurrentParcel->getLocalID(), region->getHost());
+	LLSD payload;
+	payload["owner_id"] = owner_id;
+	payload["parcel_local_id"] = mCurrentParcel->getLocalID();
+	payload["region_host"] = region->getHost().getIPandPort();
+	LLNotification::Params params("ForceOwnerAuctionWarning");
+	params.payload(payload).functor(callback_god_force_owner);
+
 	if(mCurrentParcel->getAuctionID())
 	{
-		gViewerWindow->alertXml("ForceOwnerAuctionWarning",
-			callback_god_force_owner,
-			(void*)data);
+		LLNotifications::instance().add(params);
 	}
 	else
 	{
-		callback_god_force_owner(0, (void*)data);
+		LLNotifications::instance().forceResponse(params, 0);
 	}
 }
 
-void callback_god_force_owner(S32 option, void* user_data)
+bool callback_god_force_owner(const LLSD& notification, const LLSD& response)
 {
-	LLGodForceOwnerData* data = (LLGodForceOwnerData*)user_data;
-	if(data && (0 == option))
+	S32 option = LLNotification::getSelectedOption(notification, response);
+	if(0 == option)
 	{
 		LLMessageSystem* msg = gMessageSystem;
 		msg->newMessage("ParcelGodForceOwner");
@@ -957,24 +961,24 @@ void callback_god_force_owner(S32 option, void* user_data)
 		msg->addUUID("AgentID", gAgent.getID());
 		msg->addUUID("SessionID", gAgent.getSessionID());
 		msg->nextBlock("Data");
-		msg->addUUID("OwnerID", data->mOwnerID);
-		msg->addS32( "LocalID", data->mLocalID);
-		msg->sendReliable(data->mHost);
+		msg->addUUID("OwnerID", notification["payload"]["owner_id"].asUUID());
+		msg->addS32( "LocalID", notification["payload"]["parcel_local_id"].asInteger());
+		msg->sendReliable(LLHost(notification["payload"]["region_host"].asString()));
 	}
-	delete data;
+	return false;
 }
 
 void LLViewerParcelMgr::sendParcelGodForceToContent()
 {
 	if (!mSelected)
 	{
-		gViewerWindow->alertXml("CannotContentifyNothingSelected");
+		LLNotifications::instance().add("CannotContentifyNothingSelected");
 		return;
 	}
 	LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal( mWestSouth );
 	if (!region)
 	{
-		gViewerWindow->alertXml("CannotContentifyNoRegion");
+		LLNotifications::instance().add("CannotContentifyNoRegion");
 		return;
 	}
 
@@ -992,14 +996,14 @@ void LLViewerParcelMgr::sendParcelRelease()
 {
 	if (!mSelected)
 	{
-        gViewerWindow->alertXml("CannotReleaseLandNothingSelected");
+        LLNotifications::instance().add("CannotReleaseLandNothingSelected");
 		return;
 	}
 
 	LLViewerRegion *region = LLWorld::getInstance()->getRegionFromPosGlobal( mWestSouth );
 	if (!region)
 	{
-		gViewerWindow->alertXml("CannotReleaseLandNoRegion");
+		LLNotifications::instance().add("CannotReleaseLandNoRegion");
 		return;
 	}
 
@@ -1054,14 +1058,14 @@ LLViewerParcelMgr::ParcelBuyInfo* LLViewerParcelMgr::setupParcelBuy(
 {
 	if (!mSelected || !mCurrentParcel)
 	{
-		gViewerWindow->alertXml("CannotBuyLandNothingSelected");
+		LLNotifications::instance().add("CannotBuyLandNothingSelected");
 		return NULL;
 	}
 
 	LLViewerRegion *region = LLWorld::getInstance()->getRegionFromPosGlobal( mWestSouth );
 	if (!region)
 	{
-		gViewerWindow->alertXml("CannotBuyLandNoRegion");
+		LLNotifications::instance().add("CannotBuyLandNoRegion");
 		return NULL;
 	}
 	
@@ -1079,7 +1083,7 @@ LLViewerParcelMgr::ParcelBuyInfo* LLViewerParcelMgr::setupParcelBuy(
 
 		if (region != region2)
 		{
-			gViewerWindow->alertXml("CantBuyLandAcrossMultipleRegions");
+			LLNotifications::instance().add("CantBuyLandAcrossMultipleRegions");
 			return NULL;
 		}
 	}
@@ -1160,18 +1164,18 @@ void LLViewerParcelMgr::sendParcelDeed(const LLUUID& group_id)
 {
 	if (!mSelected || !mCurrentParcel)
 	{
-		gViewerWindow->alertXml("CannotDeedLandNothingSelected");
+		LLNotifications::instance().add("CannotDeedLandNothingSelected");
 		return;
 	}
 	if(group_id.isNull())
 	{
-		gViewerWindow->alertXml("CannotDeedLandNoGroup");
+		LLNotifications::instance().add("CannotDeedLandNoGroup");
 		return;
 	}
 	LLViewerRegion *region = LLWorld::getInstance()->getRegionFromPosGlobal( mWestSouth );
 	if (!region)
 	{
-		gViewerWindow->alertXml("CannotDeedLandNoRegion");
+		LLNotifications::instance().add("CannotDeedLandNoRegion");
 		return;
 	}
 
@@ -1908,26 +1912,27 @@ void LLViewerParcelMgr::deedLandToGroup()
 {
 	std::string group_name;
 	gCacheName->getGroupName(mCurrentParcel->getGroupID(), group_name);
-	LLStringUtil::format_map_t args;
-	args["[AREA]"] = llformat("%d", mCurrentParcel->getArea());
-	args["[GROUP_NAME]"] = group_name;
+	LLSD args;
+	args["AREA"] = llformat("%d", mCurrentParcel->getArea());
+	args["GROUP_NAME"] = group_name;
 	if(mCurrentParcel->getContributeWithDeed())
 	{
 		std::string first_name, last_name;
 		gCacheName->getName(mCurrentParcel->getOwnerID(), first_name, last_name);
-		args["[FIRST_NAME]"] = first_name;
-		args["[LAST_NAME]"] = last_name;
-		gViewerWindow->alertXml("DeedLandToGroupWithContribution",args, deedAlertCB, NULL);
+		args["FIRST_NAME"] = first_name;
+		args["LAST_NAME"] = last_name;
+		LLNotifications::instance().add("DeedLandToGroupWithContribution",args, LLSD(), deedAlertCB);
 	}
 	else
 	{
-		gViewerWindow->alertXml("DeedLandToGroup",args, deedAlertCB, NULL);
+		LLNotifications::instance().add("DeedLandToGroup",args, LLSD(), deedAlertCB);
 	}
 }
 
 // static
-void LLViewerParcelMgr::deedAlertCB(S32 option, void*)
+bool LLViewerParcelMgr::deedAlertCB(const LLSD& notification, const LLSD& response)
 {
+	S32 option = LLNotification::getSelectedOption(notification, response);
 	if (option == 0)
 	{
 		LLParcel* parcel = LLViewerParcelMgr::getInstance()->getParcelSelection()->getParcel();
@@ -1938,6 +1943,7 @@ void LLViewerParcelMgr::deedAlertCB(S32 option, void*)
 		}
 		LLViewerParcelMgr::getInstance()->sendParcelDeed(group_id);
 	}
+	return false;
 }
 
 
@@ -1945,26 +1951,26 @@ void LLViewerParcelMgr::startReleaseLand()
 {
 	if (!mSelected)
 	{
-		gViewerWindow->alertXml("CannotReleaseLandNothingSelected");
+		LLNotifications::instance().add("CannotReleaseLandNothingSelected");
 		return;
 	}
 
 	if (mRequestResult == PARCEL_RESULT_NO_DATA)
 	{
-		gViewerWindow->alertXml("CannotReleaseLandWatingForServer");
+		LLNotifications::instance().add("CannotReleaseLandWatingForServer");
 		return;
 	}
 
 	if (mRequestResult == PARCEL_RESULT_MULTIPLE)
 	{
-		gViewerWindow->alertXml("CannotReleaseLandSelected");
+		LLNotifications::instance().add("CannotReleaseLandSelected");
 		return;
 	}
 
 	if (!isParcelOwnedByAgent(mCurrentParcel, GP_LAND_RELEASE)
 		&& !(gAgent.canManageEstate()))
 	{
-		gViewerWindow->alertXml("CannotReleaseLandDontOwn");
+		LLNotifications::instance().add("CannotReleaseLandDontOwn");
 		return;
 	}
 
@@ -1972,31 +1978,30 @@ void LLViewerParcelMgr::startReleaseLand()
 	LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal(parcel_center);
 	if (!region)
 	{
-		gViewerWindow->alertXml("CannotReleaseLandRegionNotFound");
+		LLNotifications::instance().add("CannotReleaseLandRegionNotFound");
 		return;
 	}
 /*
 	if ((region->getRegionFlags() & REGION_FLAGS_BLOCK_LAND_RESELL)
 		&& !gAgent.isGodlike())
 	{
-		LLStringUtil::format_map_t args;
-		args["[REGION]"] = region->getName();
-		gViewerWindow->alertXml("CannotReleaseLandNoTransfer", args);
+		LLSD args;
+		args["REGION"] = region->getName();
+		LLNotifications::instance().add("CannotReleaseLandNoTransfer", args);
 		return;
 	}
 */
 
 	if (!mCurrentParcelSelection->mWholeParcelSelected)
 	{
-		gViewerWindow->alertXml("CannotReleaseLandPartialSelection");
+		LLNotifications::instance().add("CannotReleaseLandPartialSelection");
 		return;
 	}
 
 	// Compute claim price
-	LLStringUtil::format_map_t args;
-	args["[AREA]"] = llformat("%d",mCurrentParcel->getArea());
-	gViewerWindow->alertXml("ReleaseLandWarning", args,
-				releaseAlertCB, this);
+	LLSD args;
+	args["AREA"] = llformat("%d",mCurrentParcel->getArea());
+	LLNotifications::instance().add("ReleaseLandWarning", args, LLSD(), releaseAlertCB);
 }
 
 bool LLViewerParcelMgr::canAgentBuyParcel(LLParcel* parcel, bool forGroup) const
@@ -2052,38 +2057,42 @@ void LLViewerParcelMgr::startDivideLand()
 {
 	if (!mSelected)
 	{
-		gViewerWindow->alertXml("CannotDivideLandNothingSelected");
+		LLNotifications::instance().add("CannotDivideLandNothingSelected");
 		return;
 	}
 
 	if (mCurrentParcelSelection->mWholeParcelSelected)
 	{
-		gViewerWindow->alertXml("CannotDivideLandPartialSelection");
+		LLNotifications::instance().add("CannotDivideLandPartialSelection");
 		return;
 	}
 
-	gViewerWindow->alertXml("LandDivideWarning", 
-		callbackDivideLand,
-		this);
+	LLSD payload;
+	payload["west_south_border"] = ll_sd_from_vector3d(mWestSouth);
+	payload["east_north_border"] = ll_sd_from_vector3d(mEastNorth);
+
+	LLNotifications::instance().add("LandDivideWarning", LLSD(), payload, callbackDivideLand);
 }
 
 // static
-void LLViewerParcelMgr::callbackDivideLand(S32 option, void* data)
+bool LLViewerParcelMgr::callbackDivideLand(const LLSD& notification, const LLSD& response)
 {
-	LLViewerParcelMgr* self = (LLViewerParcelMgr*)data;
+	S32 option = LLNotification::getSelectedOption(notification, response);
+	LLVector3d west_south_d = ll_vector3d_from_sd(notification["payload"]["west_south_border"]);
+	LLVector3d east_north_d = ll_vector3d_from_sd(notification["payload"]["east_north_border"]);
+	LLVector3d parcel_center = (west_south_d + east_north_d) / 2.0;
 
-	LLVector3d parcel_center = (self->mWestSouth + self->mEastNorth) / 2.0;
 	LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal(parcel_center);
 	if (!region)
 	{
-		gViewerWindow->alertXml("CannotDivideLandNoRegion");
-		return;
+		LLNotifications::instance().add("CannotDivideLandNoRegion");
+		return false;
 	}
 
 	if (0 == option)
 	{
-		LLVector3 west_south = region->getPosRegionFromGlobal(self->mWestSouth);
-		LLVector3 east_north = region->getPosRegionFromGlobal(self->mEastNorth);
+		LLVector3 west_south = region->getPosRegionFromGlobal(west_south_d);
+		LLVector3 east_north = region->getPosRegionFromGlobal(east_north_d);
 
 		LLMessageSystem* msg = gMessageSystem;
 		msg->newMessage("ParcelDivide");
@@ -2097,6 +2106,7 @@ void LLViewerParcelMgr::callbackDivideLand(S32 option, void* data)
 		msg->addF32("North", east_north.mV[VY]);
 		msg->sendReliable(region->getHost());
 	}
+	return false;
 }
 
 
@@ -2104,44 +2114,48 @@ void LLViewerParcelMgr::startJoinLand()
 {
 	if (!mSelected)
 	{
-		gViewerWindow->alertXml("CannotJoinLandNothingSelected");
+		LLNotifications::instance().add("CannotJoinLandNothingSelected");
 		return;
 	}
 
 	if (mCurrentParcelSelection->mWholeParcelSelected)
 	{
-		gViewerWindow->alertXml("CannotJoinLandEntireParcelSelected");
+		LLNotifications::instance().add("CannotJoinLandEntireParcelSelected");
 		return;
 	}
 
 	if (!mCurrentParcelSelection->mSelectedMultipleOwners)
 	{
-		gViewerWindow->alertXml("CannotJoinLandSelection");
+		LLNotifications::instance().add("CannotJoinLandSelection");
 		return;
 	}
 
-	gViewerWindow->alertXml("JoinLandWarning",
-		callbackJoinLand,
-		this);
+	LLSD payload;
+	payload["west_south_border"] = ll_sd_from_vector3d(mWestSouth);
+	payload["east_north_border"] = ll_sd_from_vector3d(mEastNorth);
+
+	LLNotifications::instance().add("JoinLandWarning", LLSD(), payload, callbackJoinLand);
 }
 
 // static
-void LLViewerParcelMgr::callbackJoinLand(S32 option, void* data)
+bool LLViewerParcelMgr::callbackJoinLand(const LLSD& notification, const LLSD& response)
 {
-	LLViewerParcelMgr* self = (LLViewerParcelMgr*)data;
+	S32 option = LLNotification::getSelectedOption(notification, response);
+	LLVector3d west_south_d = ll_vector3d_from_sd(notification["payload"]["west_south_border"]);
+	LLVector3d east_north_d = ll_vector3d_from_sd(notification["payload"]["east_north_border"]);
+	LLVector3d parcel_center = (west_south_d + east_north_d) / 2.0;
 
-	LLVector3d parcel_center = (self->mWestSouth + self->mEastNorth) / 2.0;
 	LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal(parcel_center);
 	if (!region)
 	{
-		gViewerWindow->alertXml("CannotJoinLandNoRegion");
-		return;
+		LLNotifications::instance().add("CannotJoinLandNoRegion");
+		return false;
 	}
 
 	if (0 == option)
 	{
-		LLVector3 west_south = region->getPosRegionFromGlobal(self->mWestSouth);
-		LLVector3 east_north = region->getPosRegionFromGlobal(self->mEastNorth);
+		LLVector3 west_south = region->getPosRegionFromGlobal(west_south_d);
+		LLVector3 east_north = region->getPosRegionFromGlobal(east_north_d);
 
 		LLMessageSystem* msg = gMessageSystem;
 		msg->newMessage("ParcelJoin");
@@ -2155,6 +2169,7 @@ void LLViewerParcelMgr::callbackJoinLand(S32 option, void* data)
 		msg->addF32("North", east_north.mV[VY]);
 		msg->sendReliable(region->getHost());
 	}
+	return false;
 }
 
 
@@ -2162,19 +2177,19 @@ void LLViewerParcelMgr::startDeedLandToGroup()
 {
 	if (!mSelected || !mCurrentParcel)
 	{
-		gViewerWindow->alertXml("CannotDeedLandNothingSelected");
+		LLNotifications::instance().add("CannotDeedLandNothingSelected");
 		return;
 	}
 
 	if (mRequestResult == PARCEL_RESULT_NO_DATA)
 	{
-		gViewerWindow->alertXml("CannotDeedLandWaitingForServer");
+		LLNotifications::instance().add("CannotDeedLandWaitingForServer");
 		return;
 	}
 
 	if (mRequestResult == PARCEL_RESULT_MULTIPLE)
 	{
-		gViewerWindow->alertXml("CannotDeedLandMultipleSelected");
+		LLNotifications::instance().add("CannotDeedLandMultipleSelected");
 		return;
 	}
 
@@ -2182,7 +2197,7 @@ void LLViewerParcelMgr::startDeedLandToGroup()
 	LLViewerRegion* region = LLWorld::getInstance()->getRegionFromPosGlobal(parcel_center);
 	if (!region)
 	{
-		gViewerWindow->alertXml("CannotDeedLandNoRegion");
+		LLNotifications::instance().add("CannotDeedLandNoRegion");
 		return;
 	}
 
@@ -2192,9 +2207,9 @@ void LLViewerParcelMgr::startDeedLandToGroup()
 		if((region->getRegionFlags() & REGION_FLAGS_BLOCK_LAND_RESELL)
 			&& (mCurrentParcel->getOwnerID() != region->getOwner()))
 		{
-			LLStringUtil::format_map_t args;
-			args["[REGION]"] = region->getName();
-			gViewerWindow->alertXml("CannotDeedLandNoTransfer", args);
+			LLSD args;
+			args["REGION"] = region->getName();
+			LLNotifications::instance().add("CannotDeedLandNoTransfer", args);
 			return;
 		}
 	}
@@ -2222,13 +2237,15 @@ void LLViewerParcelMgr::reclaimParcel()
 }
 
 // static
-void LLViewerParcelMgr::releaseAlertCB(S32 option, void *)
+bool LLViewerParcelMgr::releaseAlertCB(const LLSD& notification, const LLSD& response)
 {
+	S32 option = LLNotification::getSelectedOption(notification, response);
 	if (option == 0)
 	{
 		// Send the release message, not a force
 		LLViewerParcelMgr::getInstance()->sendParcelRelease();
 	}
+	return false;
 }
 
 void LLViewerParcelMgr::buyPass()
diff --git a/indra/newview/llviewerparcelmgr.h b/indra/newview/llviewerparcelmgr.h
index 4326e07e46b..920423cdfa4 100644
--- a/indra/newview/llviewerparcelmgr.h
+++ b/indra/newview/llviewerparcelmgr.h
@@ -110,7 +110,7 @@ class LLViewerParcelMgr : public LLSingleton<LLViewerParcelMgr>
 	void selectCollisionParcel();
 
 	// Select the parcel at a specific point
-	LLSafeHandle<LLParcelSelection> selectParcelAt(const LLVector3d& pos_global);
+	LLParcelSelectionHandle selectParcelAt(const LLVector3d& pos_global);
 
 	// Take the current rectangle select, and select the parcel contained
 	// within it.
@@ -259,7 +259,7 @@ class LLViewerParcelMgr : public LLSingleton<LLViewerParcelMgr>
 	static BOOL isParcelModifiableByAgent(const LLParcel* parcelp, U64 group_proxy_power);
 
 private:
-	static void releaseAlertCB(S32 option, void *data);
+	static bool releaseAlertCB(const LLSD& notification, const LLSD& response);
 
 	// If the user is claiming land and the current selection 
 	// borders a piece of land the user already owns, ask if he
@@ -272,12 +272,10 @@ class LLViewerParcelMgr : public LLSingleton<LLViewerParcelMgr>
 	// move land from current owner to it's group.
 	void deedLandToGroup();
 
-	static void claimAlertCB(S32 option, void* data);
-	static void buyAlertCB(S32 option, void* data);
-	static void deedAlertCB(S32 option, void*);
+	static bool deedAlertCB(const LLSD& notification, const LLSD& response);
 
-	static void callbackDivideLand(S32 option, void* data);
-	static void callbackJoinLand(S32 option, void* data);
+	static bool callbackDivideLand(const LLSD& notification, const LLSD& response);
+	static bool callbackJoinLand(const LLSD& notification, const LLSD& response);
 
 	//void	finishClaim(BOOL user_to_user_sale, U32 join);
 	LLViewerImage* getBlockedImage() const;
diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp
index c2c3e7e320b..50486137c11 100644
--- a/indra/newview/llviewertexteditor.cpp
+++ b/indra/newview/llviewertexteditor.cpp
@@ -1420,58 +1420,50 @@ void LLViewerTextEditor::openEmbeddedLandmark( LLInventoryItem* item )
 
 void LLViewerTextEditor::openEmbeddedNotecard( LLInventoryItem* item )
 {
-	//if (saved)
-	//{
-		// An LLInventoryItem needs to be in an inventory to be opened.
-		// This will give the item to the viewer's agent.
-		// The callback will attempt to open it if its not already opened.
 	copyInventory(item, gInventoryCallbacks.registerCB(mInventoryCallback));
-
-	//}
-	//else
-	//{
-	//	LLNotecardCopyInfo *info = new LLNotecardCopyInfo(this, item);
-	//	gViewerWindow->alertXml("ConfirmNotecardSave",		
-	//							LLViewerTextEditor::onNotecardDialog, (void*)info);
-	//}
 }
 
 void LLViewerTextEditor::showUnsavedAlertDialog( LLInventoryItem* item )
 {
-	LLNotecardCopyInfo *info = new LLNotecardCopyInfo(this, item);
-	gViewerWindow->alertXml( "ConfirmNotecardSave",
-		LLViewerTextEditor::onNotecardDialog, (void*)info);
+	LLSD payload;
+	payload["item_id"] = item->getUUID();
+	payload["notecard_id"] = mNotecardInventoryID;
+	LLNotifications::instance().add( "ConfirmNotecardSave", LLSD(), payload, LLViewerTextEditor::onNotecardDialog);
 }
+
 // static
-void LLViewerTextEditor::onNotecardDialog( S32 option, void* userdata )
+bool LLViewerTextEditor::onNotecardDialog(const LLSD& notification, const LLSD& response )
 {
-	LLNotecardCopyInfo *info = (LLNotecardCopyInfo *)userdata;
+	S32 option = LLNotification::getSelectedOption(notification, response);
 	if( option == 0 )
 	{
 		// itemptr is deleted by LLPreview::save
-		LLPointer<LLInventoryItem>* itemptr = new LLPointer<LLInventoryItem>(info->mItem);
-		LLPreview::save( info->mTextEd->mNotecardInventoryID, itemptr);
+		LLPointer<LLInventoryItem>* itemptr = new LLPointer<LLInventoryItem>(gInventory.getItem(notification["payload"]["item_id"].asUUID()));
+		LLPreview::save( notification["payload"]["notecard_id"].asUUID() , itemptr);
 	}
+	return false;
 }
 
 
 
 void LLViewerTextEditor::showCopyToInvDialog( LLInventoryItem* item )
 {
-	LLNotecardCopyInfo *info = new LLNotecardCopyInfo(this, item);
-	gViewerWindow->alertXml( "ConfirmItemCopy",
-		LLViewerTextEditor::onCopyToInvDialog, (void*)info);
+	LLSD payload;
+	payload["item_id"] = item->getUUID();
+	payload["notecard_id"] = mNotecardInventoryID;
+	LLNotifications::instance().add( "ConfirmItemCopy", LLSD(), payload,
+		boost::bind(&LLViewerTextEditor::onCopyToInvDialog, this, _1, _2));
 }
 
-// static
-void LLViewerTextEditor::onCopyToInvDialog( S32 option, void* userdata )
+bool LLViewerTextEditor::onCopyToInvDialog(const LLSD& notification, const LLSD& response)
 {
-	LLNotecardCopyInfo *info = (LLNotecardCopyInfo *)userdata;
+	S32 option = LLNotification::getSelectedOption(notification, response);
 	if( 0 == option )
 	{
-		info->mTextEd->copyInventory(info->mItem);
+		LLInventoryItem* itemp = gInventory.getItem(notification["payload"]["item_id"].asUUID());
+		copyInventory(itemp);
 	}
-	delete info;
+	return false;
 }
 
 
diff --git a/indra/newview/llviewertexteditor.h b/indra/newview/llviewertexteditor.h
index 7ce28fc60ad..2e1c0f1d863 100644
--- a/indra/newview/llviewertexteditor.h
+++ b/indra/newview/llviewertexteditor.h
@@ -113,8 +113,8 @@ class LLViewerTextEditor : public LLTextEditor
 	void			showCopyToInvDialog( LLInventoryItem* item );
 	void			showUnsavedAlertDialog( LLInventoryItem* item );
 
-	static void		onCopyToInvDialog( S32 option, void* userdata );
-	static void		onNotecardDialog( S32 option, void* userdata );
+	bool			onCopyToInvDialog(const LLSD& notification, const LLSD& response );
+	static bool		onNotecardDialog(const LLSD& notification, const LLSD& response );
 	
 	LLPointer<LLInventoryItem> mDragItem;
 	BOOL mDragItemSaved;
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 48b4a79afa2..a129fac47b0 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -182,6 +182,9 @@
 #include "llviewerjoystick.h"
 #include "llviewernetwork.h"
 
+#include "llfloatertest.h" // HACK!
+#include "llfloaternotificationsconsole.h"
+
 #if LL_WINDOWS
 #include <tchar.h> // For Unicode conversion methods
 #endif
@@ -246,6 +249,7 @@ std::string	LLViewerWindow::sMovieBaseName;
 extern void toggle_debug_menus(void*);
 
 
+
 ////////////////////////////////////////////////////////////////////////////
 //
 // LLDebugText
@@ -1421,6 +1425,13 @@ LLViewerWindow::LLViewerWindow(
 	mIsFullscreenChecked(false),
 	mCurrResolutionIndex(0)
 {
+	// these are self registering so they don't need to be retained here
+	new LLNotificationChannel("VW_alerts", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "alert"));
+	new LLNotificationChannel("VW_alertmodal", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "alertmodal"));
+
+	LLNotifications::instance().getChannel("VW_alerts")->connectChanged(&LLViewerWindow::onAlert);
+	LLNotifications::instance().getChannel("VW_alertmodal")->connectChanged(&LLViewerWindow::onAlert);
+
 	// Default to application directory.
 	LLViewerWindow::sSnapshotBaseName = "Snapshot";
 	LLViewerWindow::sMovieBaseName = "SLmovie";
@@ -1532,8 +1543,6 @@ LLViewerWindow::LLViewerWindow(
 	// Can't have spaces in settings.ini strings, so use underscores instead and convert them.
 	LLStringUtil::replaceChar(mOverlayTitle, '_', ' ');
 
-	LLAlertDialog::setDisplayCallback(alertCallback); // call this before calling any modal dialogs
-
 	// sync the keyboard's setting with the saved setting
 	gSavedSettings.getControl("NumpadControl")->firePropertyChanged();
 
@@ -2179,7 +2188,7 @@ void LLViewerWindow::setNormalControlsVisible( BOOL visible )
 
 void LLViewerWindow::setMenuBackgroundColor(bool god_mode, bool dev_grid)
 {
-   	LLStringUtil::format_map_t args;
+    LLSD args;
     LLColor4 new_bg_color;
 
     if(god_mode && LLViewerLogin::getInstance()->isInProductionGrid())
@@ -2232,12 +2241,6 @@ void LLViewerWindow::draw()
 	stop_glerror();
 	
 	LLUI::setLineWidth(1.f);
-	//popup alerts from the UI
-	LLAlertInfo alert;
-	while (LLPanel::nextAlert(alert))
-	{
-		alertXml(alert.mLabel, alert.mArgs);
-	}
 
 	LLUI::setLineWidth(1.f);
 	// Reset any left-over transforms
@@ -2421,6 +2424,15 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
 		}
 	}
 
+	// Debugging view for unified notifications
+	if ((MASK_SHIFT & mask) 
+		&& (MASK_CONTROL & mask)
+		&& ('N' == key || 'n' == key))
+	{
+		LLFloaterNotificationConsole::showInstance();
+		return TRUE;
+	}
+
 	// handle escape key
 	//if (key == KEY_ESCAPE && mask == MASK_NONE)
 	//{
@@ -4909,10 +4921,10 @@ BOOL LLViewerWindow::changeDisplaySettings(BOOL fullscreen, LLCoordScreen size,
 
 	if (!result_first_try)
 	{
-		LLStringUtil::format_map_t args;
-		args["[RESX]"] = llformat("%d",size.mX);
-		args["[RESY]"] = llformat("%d",size.mY);
-		alertXml("ResolutionSwitchFail", args);
+		LLSD args;
+		args["RESX"] = llformat("%d",size.mX);
+		args["RESY"] = llformat("%d",size.mY);
+		LLNotifications::instance().add("ResolutionSwitchFail", args);
 		size = old_size; // for reshape below
 	}
 
@@ -5027,72 +5039,18 @@ S32 LLViewerWindow::getChatConsoleBottomPad()
 
 //----------------------------------------------------------------------------
 
-// static
-bool LLViewerWindow::alertCallback(S32 modal)
-{
-	if (gNoRender)
-	{
-		return false;
-	}
-	else
-	{
-// 		if (modal) // we really always want to take you out of mouselook
-		{
-			// If we're in mouselook, the mouse is hidden and so the user can't click 
-			// the dialog buttons.  In that case, change to First Person instead.
-			if( gAgent.cameraMouselook() )
-			{
-				gAgent.changeCameraToDefault();
-			}
-		}
-		return true;
-	}
-}
-
-LLAlertDialog* LLViewerWindow::alertXml(const std::string& xml_filename,
-							  LLAlertDialog::alert_callback_t callback, void* user_data)
-{
-	LLStringUtil::format_map_t args;
-	return alertXml( xml_filename, args, callback, user_data );
-}
 
-LLAlertDialog* LLViewerWindow::alertXml(const std::string& xml_filename, const LLStringUtil::format_map_t& args,
-							  LLAlertDialog::alert_callback_t callback, void* user_data)
+//static 
+bool LLViewerWindow::onAlert(const LLSD& notify)
 {
-	if (gNoRender)
-	{
-		llinfos << "Alert: " << xml_filename << llendl;
-		if (callback)
-		{
-			callback(-1, user_data);
-		}
-		return NULL;
-	}
+	LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
 
-	// If we're in mouselook, the mouse is hidden and so the user can't click 
-	// the dialog buttons.  In that case, change to First Person instead.
-	if( gAgent.cameraMouselook() )
-	{
-		gAgent.changeCameraToDefault();
-	}
-
-	// Note: object adds, removes, and destroys itself.
-	return LLAlertDialog::showXml( xml_filename, args, callback, user_data );
-}
-
-LLAlertDialog* LLViewerWindow::alertXmlEditText(const std::string& xml_filename, const LLStringUtil::format_map_t& args,
-									  LLAlertDialog::alert_callback_t callback, void* user_data,
-									  LLAlertDialog::alert_text_callback_t text_callback, void *text_data,
-									  const LLStringUtil::format_map_t& edit_args, BOOL draw_asterixes)
-{
 	if (gNoRender)
 	{
-		llinfos << "Alert: " << xml_filename << llendl;
-		if (callback)
-		{
-			callback(-1, user_data);
-		}
-		return NULL;
+		llinfos << "Alert: " << notification->getName() << llendl;
+		notification->respond(LLSD::emptyMap());
+		LLNotifications::instance().cancel(notification);
+		return false;
 	}
 
 	// If we're in mouselook, the mouse is hidden and so the user can't click 
@@ -5101,20 +5059,7 @@ LLAlertDialog* LLViewerWindow::alertXmlEditText(const std::string& xml_filename,
 	{
 		gAgent.changeCameraToDefault();
 	}
-
-	// Note: object adds, removes, and destroys itself.
-	LLAlertDialog* alert = LLAlertDialog::createXml( xml_filename, args, callback, user_data );
-	if (alert)
-	{
-		if (text_callback)
-		{
-			alert->setEditTextCallback(text_callback, text_data);
-		}
-		alert->setEditTextArgs(edit_args);
-		alert->setDrawAsterixes(draw_asterixes);
-		alert->show();
-	}
-	return alert;
+	return false;
 }
 
 ////////////////////////////////////////////////////////////////////////////
diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h
index 6309cec8193..d6c27a31bc5 100644
--- a/indra/newview/llviewerwindow.h
+++ b/indra/newview/llviewerwindow.h
@@ -47,6 +47,7 @@
 #include "lltimer.h"
 #include "llstat.h"
 #include "llalertdialog.h"
+#include "llnotifications.h"
 
 class LLView;
 class LLViewerObject;
@@ -353,20 +354,10 @@ class LLViewerWindow : public LLWindowCallbacks
 
 	void			drawPickBuffer() const;
 
-	LLAlertDialog* alertXml(const std::string& xml_filename,
-				  LLAlertDialog::alert_callback_t callback = NULL, void* user_data = NULL);
-	LLAlertDialog* alertXml(const std::string& xml_filename, const LLStringUtil::format_map_t& args,
-				  LLAlertDialog::alert_callback_t callback = NULL, void* user_data = NULL);
-	LLAlertDialog* alertXmlEditText(const std::string& xml_filename, const LLStringUtil::format_map_t& args,
-						  LLAlertDialog::alert_callback_t callback, void* user_data,
-						  LLAlertDialog::alert_text_callback_t text_callback, void *text_data,
-						  const LLStringUtil::format_map_t& edit_args = LLStringUtil::format_map_t(),
-						  BOOL draw_asterixes = FALSE);
-
-	static bool alertCallback(S32 modal);
-	
 private:
 	bool                    shouldShowToolTipFor(LLMouseHandler *mh);
+	static bool onAlert(const LLSD& notify);
+	
 	void			switchToolByMask(MASK mask);
 	void			destroyWindow();
 	void			drawMouselookInstructions();
diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp
index d416ae5bf68..d644ad50859 100644
--- a/indra/newview/llvograss.cpp
+++ b/indra/newview/llvograss.cpp
@@ -109,12 +109,6 @@ void LLVOGrass::updateSpecies()
 }
 
 
-void alert_done(S32 option, void* user_data)
-{
-	return;
-}
-
-
 void LLVOGrass::initClass()
 {
 	LLVector3 pos(0.0f, 0.0f, 0.0f);
@@ -224,9 +218,9 @@ void LLVOGrass::initClass()
 
 	if (!have_all_grass) 
 	{
-		LLStringUtil::format_map_t args;
-		args["[SPECIES]"] = err;
-		gViewerWindow->alertXml("ErrorUndefinedGrasses", args, alert_done );
+		LLSD args;
+		args["SPECIES"] = err;
+		LLNotifications::instance().add("ErrorUndefinedGrasses", args);
 	}
 
 	for (S32 i = 0; i < GRASS_MAX_BLADES; ++i)
diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp
index 8b1eba11a01..fb284207159 100644
--- a/indra/newview/llvoiceclient.cpp
+++ b/indra/newview/llvoiceclient.cpp
@@ -4188,7 +4188,7 @@ class LLViewerRequiredVoiceVersion : public LLHTTPNode
 				if (!sAlertedUser)
 				{
 					//sAlertedUser = TRUE;
-					gViewerWindow->alertXml("VoiceVersionMismatch");
+					LLNotifications::instance().add("VoiceVersionMismatch");
 					gSavedSettings.setBOOL("EnableVoiceChat", FALSE); // toggles listener
 				}
 			}
diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp
index 7e3b96eb8f7..486ecb82e32 100644
--- a/indra/newview/llvotree.cpp
+++ b/indra/newview/llvotree.cpp
@@ -253,9 +253,9 @@ void LLVOTree::initClass()
 
 		if (!have_all_trees) 
 		{
-			LLStringUtil::format_map_t args;
-			args["[SPECIES]"] = err;
-			gViewerWindow->alertXml("ErrorUndefinedTrees", args );
+			LLSD args;
+			args["SPECIES"] = err;
+			LLNotifications::instance().add("ErrorUndefinedTrees", args);
 		}
 };
 
diff --git a/indra/newview/llwearable.cpp b/indra/newview/llwearable.cpp
index ef077101e97..c473fed04aa 100644
--- a/indra/newview/llwearable.cpp
+++ b/indra/newview/llwearable.cpp
@@ -867,9 +867,9 @@ void LLWearable::saveNewAsset()
 		std::string buffer = llformat("Unable to save '%s' to wearable file.", mName.c_str());
 		llwarns << buffer << llendl;
 		
-		LLStringUtil::format_map_t args;
-		args["[NAME]"] = mName;
-		gViewerWindow->alertXml("CannotSaveWearableOutOfSpace", args);
+		LLSD args;
+		args["NAME"] = mName;
+		LLNotifications::instance().add("CannotSaveWearableOutOfSpace", args);
 		return;
 	}
 
@@ -915,9 +915,9 @@ void LLWearable::onSaveNewAssetComplete(const LLUUID& new_asset_id, void* userda
 	{
 		std::string buffer = llformat("Unable to save %s to central asset store.", type_name.c_str());
 		llwarns << buffer << " Status: " << status << llendl;
-		LLStringUtil::format_map_t args;
-		args["[NAME]"] = type_name;
-		gViewerWindow->alertXml("CannotSaveToAssetStore", args);
+		LLSD args;
+		args["NAME"] = type_name;
+		LLNotifications::instance().add("CannotSaveToAssetStore", args);
 	}
 
 	// Delete temp file
diff --git a/indra/newview/llwearablelist.cpp b/indra/newview/llwearablelist.cpp
index a32c43302d0..70719b827c4 100644
--- a/indra/newview/llwearablelist.cpp
+++ b/indra/newview/llwearablelist.cpp
@@ -149,27 +149,27 @@ void LLWearableList::processGetAssetReply( const char* filename, const LLAssetID
 		  {
 			  // Fail
 			  break;
-		  }
+		}
 		  default:
-		  {
+		{
 			  static const S32 MAX_RETRIES = 3;
 			  if (data->mRetries < MAX_RETRIES)
 			  {
-				  // Try again
+			  // Try again
 				  data->mRetries++;
-				  gAssetStorage->getAssetData(uuid,
-											  data->mAssetType,
-											  LLWearableList::processGetAssetReply,
-											  userdata);  // re-use instead of deleting.
-				  return;
-			  }
+			  gAssetStorage->getAssetData(uuid,
+										  data->mAssetType,
+										  LLWearableList::processGetAssetReply,
+										  userdata);  // re-use instead of deleting.
+			  return;
+		}
 			  else
 			  {
 				  // Fail
 				  break;
 			  }
 		  }
-		}
+	}
 	}
 
 	if (wearable) // success
@@ -180,17 +180,17 @@ void LLWearableList::processGetAssetReply( const char* filename, const LLAssetID
 	}
 	else
 	{
-		LLStringUtil::format_map_t args;
+		LLSD args;
 		// *TODO:translate
-		args["[TYPE]"] = LLAssetType::lookupHumanReadable(data->mAssetType);
+		args["TYPE"] = LLAssetType::lookupHumanReadable(data->mAssetType);
 		if (data->mName.empty())
 		{
-			LLNotifyBox::showXml("FailedToFindWearableUnnamed", args);
+			LLNotifications::instance().add("FailedToFindWearableUnnamed", args);
 		}
 		else
 		{
-			args["[DESC]"] = data->mName;
-			LLNotifyBox::showXml("FailedToFindWearable", args);
+			args["DESC"] = data->mName;
+			LLNotifications::instance().add("FailedToFindWearable", args);
 		}
 	}
 	// Always call callback; wearable will be NULL if we failed
diff --git a/indra/newview/llwldaycycle.cpp b/indra/newview/llwldaycycle.cpp
index 1abf7605801..9f8ddc10298 100644
--- a/indra/newview/llwldaycycle.cpp
+++ b/indra/newview/llwldaycycle.cpp
@@ -82,9 +82,9 @@ void LLWLDayCycle::loadDayCycle(const std::string & fileName)
 			if(!success)
 			{
 				// alert the user
-				LLStringUtil::format_map_t args;
-				args["[SKY]"] = day_data[i][1].asString();
-				gViewerWindow->alertXml("WLMissingSky", args);
+				LLSD args;
+				args["SKY"] = day_data[i][1].asString();
+				LLNotifications::instance().add("WLMissingSky", args);
 				continue;
 			}
 			
diff --git a/indra/newview/llxmlrpctransaction.cpp b/indra/newview/llxmlrpctransaction.cpp
index d9c6b6c58aa..7fbcaf6c21e 100644
--- a/indra/newview/llxmlrpctransaction.cpp
+++ b/indra/newview/llxmlrpctransaction.cpp
@@ -417,28 +417,10 @@ void LLXMLRPCTransaction::Impl::setStatus(Status status,
 				mStatusMessage =
 					"Despite our best efforts, something unexpected has gone wrong. \n"
 					" \n"
-					"Please check www.secondlife.com/status \n"
+					"Please check secondlife.com/status \n"
 					"to see if there is a known problem with the service.";
 
 				mStatusURI = "http://secondlife.com/status/";
-				/*
-				mStatusMessage =
-					"Despite our best efforts, something unexpected has gone wrong.\n"
-					"Please go to the Support section of the SecondLife.com web site\n"
-					"and report the problem.  If possible, include your SecondLife.log\n"
-					"file from:\n"
-#if LL_WINDOWS
-					"C:\\Documents and Settings\\<name>\\Application Data\\SecondLife\\logs\n"
-#elif LL_DARWIN
-					"~/Library/Application Support/SecondLife/logs\n"
-#elif LL_LINUX
-					"~/.secondlife/logs\n"
-#else
-#error "Need platform here."
-#endif
-					"Thank you.";
-				mStatusURI = "http://secondlife.com/community/support.php";
-				*/
 		}
 	}
 }
-- 
GitLab