[SCM] A client for connecting to 3D metaverses such as Linden Labs Secondlife(tm) and OpenSim grids branch, master, updated. upstream/1.21.6-122-g0cd6f5f

Robin Cornelius robin.cornelius at gmail.com
Tue Apr 14 11:20:35 UTC 2009


The following commit has been merged in the master branch:
commit 0cd6f5fb0661058555f9772a22715b7e4c6d5f09
Author: Robin Cornelius <robin.cornelius at gmail.com>
Date:   Tue Apr 14 11:21:20 2009 +0100

    Import new patch set

diff --git a/debian/changelog b/debian/changelog
index 64c679a..7f67884 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,89 @@
+omvviewer (1.22.11-1) unstable; urgency=low
+
+  * New Upstream Version
+
+ -- Robin Cornelius <robin.cornelius at gmail.com>  Fri, 13 Mar 2009 09:56:30 +0000
+
+omvviewer (1.22.10-1) experimental; urgency=low
+
+  * New Upstream Version
+
+ -- Robin Cornelius <robin.cornelius at gmail.com>  Thu, 26 Feb 2009 21:10:43 +0000
+
+omvviewer (1.22.9-2) experimental; urgency=low
+
+  * Fix a crash issue with a patch
+
+ -- Robin Cornelius <robin.cornelius at gmail.com>  Sat, 14 Feb 2009 12:57:28 +0000
+
+omvviewer (1.22.9-1) experimental; urgency=low
+
+  * New Upstream Version
+
+ -- Robin Cornelius <robin.cornelius at gmail.com>  Fri, 13 Feb 2009 18:11:56 +0000
+
+omvviewer (1.22.8-1) experimental; urgency=low
+
+  * New Upstream Version
+    + Drop OpenAL patch, included upstream
+
+ -- Robin Cornelius <robin.cornelius at gmail.com>  Thu, 05 Feb 2009 22:27:02 +0000
+
+omvviewer (1.22.7-1) experimental; urgency=low
+
+  * New Upstream Version
+    + New patches
+      - AvatarLoginList
+      - VWR-11663_Save_Load_scripts
+      - Dale Glass' avatar scanner
+      - VWR 11103 Fix local ruler on linked objects
+      - VWR 11674 don't download muted sounds
+      - VWR 11128 Correctly Find pythong during build
+      - VWR 11138 Fix build system
+
+ -- Robin Cornelius <robin.cornelius at gmail.com>  Thu, 29 Jan 2009 10:51:56 +0000
+
+omvviewer (1.22.5-1) experimental; urgency=low
+
+  * New Upstream Version
+
+ -- Robin Cornelius <robin.cornelius at gmail.com>  Thu, 08 Jan 2009 12:38:41 +0000
+
+omvviewer (1.22.4-1) experimental; urgency=low
+
+  * New Upstream Version
+    + Add missing SDL cursors
+
+ -- Robin Cornelius <robin.cornelius at gmail.com>  Sat, 20 Dec 2008 18:03:56 +0000
+
+omvviewer (1.22.2-1) experimental; urgency=low
+
+  * New Upstream Version
+
+ -- Robin Cornelius <robin.cornelius at gmail.com>  Sat, 06 Dec 2008 17:46:10 +0000
+
+omvviewer (1.22.1-1) experimental; urgency=low
+
+  * New Upstream RC Version
+    + Change depends to require a cares enabled libcurl
+    + Rework debian/rules to allow debug flags to be passed to build
+  * New Patches
+    + Avatar scanner floater
+    + VWR-9557-EnableBuildWithNvidiaOrMesaHeaders
+    + correctly_find_dbus_headers_on_standalone
+  * Drop patches applied upstream
+    + VWR4070-openjpeg_check_number_of_components
+    + rename_binary_cmake
+    + no_old_school_typedefs
+
+ -- Robin Cornelius <robin.cornelius at gmail.com>  Tue, 25 Nov 2008 21:16:52 +0000
+
+omvviewer (1.22.0-1) unstable; urgency=low
+
+  * New Upstream Version
+
+ -- Robin Cornelius <robin.cornelius at gmail.com>  Sun, 23 Nov 2008 16:43:59 +0000
+
 omvviewer (1.21.6-1) unstable; urgency=low
 
   * New Upstream Version
@@ -611,5 +697,6 @@ slviewer (1.16.0.5-1) unstable; urgency=low
 
   * Initial release (Closes: #406335, #406185)
 
- -- Paul "TBBle" Hampson <Paul.Hampson at Pobox.com>  Fri, 25 May 2007 00:02:48 +1000rename_binary_cmake.patch
+ -- Paul "TBBle" Hampson <Paul.Hampson at Pobox.com>  Fri, 25 May 2007 00:02:48 +1000
+
 
diff --git a/debian/control b/debian/control
index bcb7a53..136b950 100644
--- a/debian/control
+++ b/debian/control
@@ -2,14 +2,14 @@ Source: omvviewer
 Section: games
 Priority: extra
 Maintainer: Secondlife Debian Team <secondlife-debian-maintainers at slupdate.byteme.org.uk>
-Uploaders: Robin Cornelius <robin.cornelius at gmail.com>
-Build-Depends: debhelper (>= 5), quilt (>= 0.40), cmake, libcairo2-dev, libglib2.0-dev, libgtk2.0-dev, libsdl1.2-dev, libvorbis-dev, libopenjpeg-dev, libjpeg62-dev, libpng12-dev, flex, bison, libssl-dev, libexpat1-dev, libaprutil1-dev, libapr1-dev, zlib1g-dev, libxmlrpc-epi-dev, libgl1-mesa-dev ( >= 7 ) | libgl-dev, libboost-dev, libboost-regex-dev,libboost-signals-dev ,libboost-program-options-dev, libgstreamer0.10-dev, libgstreamer-plugins-base0.10-dev, libc-ares-dev , libllmozlib2-dev  (>= 0.0.1), libopenal-dev, libalut-dev, libapr1-dev, python, libcurl4-gnutls-dev
+Uploaders: Robin Cornelius <robin.cornelius at gmail.com>, Carlo Wood <carlo at alinoe.com>
+Build-Depends: debhelper (>= 5), quilt (>= 0.40), cmake, libcairo2-dev, libglib2.0-dev, libgtk2.0-dev, libsdl1.2-dev, libvorbis-dev, libopenjpeg-dev, libjpeg62-dev, libpng12-dev, flex, bison, libssl-dev, libexpat1-dev, libaprutil1-dev, libapr1-dev, zlib1g-dev, libxmlrpc-epi-dev, libgl1-mesa-dev ( >= 7 ) | libgl-dev, libboost-dev, libboost-regex-dev,libboost-signals-dev ,libboost-program-options-dev, libgstreamer0.10-dev, libgstreamer-plugins-base0.10-dev, libc-ares-dev , libllmozlib2-dev  (>= 0.0.1) | libllmozlib2-qt-dev, libopenal-dev, libalut-dev, libapr1-dev, python, libcurl4-cares-dev, libdbus-glib-1-dev
 Standards-Version: 3.8.0
 XS-Vcs-Git: http://git.debian.org/git/pkg-games/slviewer.git
 
 Package: omvviewer
 Architecture: i386 amd64 powerpc
-Depends: ${misc:Depends}, ${shlibs:Depends}, omvviewer-data  (= ${source:Version}), omvviewer-artwork  (>= 1.21.6), ttf-kochi-mincho, ttf-dejavu, libc-ares1
+Depends: ${misc:Depends}, ${shlibs:Depends}, omvviewer-data  (= ${source:Version}), omvviewer-artwork  (>= 1.22.11), ttf-kochi-mincho, ttf-dejavu
 Recommends: libgstreamer0.10-0, libgstreamer-plugins-base0.10-0
 Replaces: slviewer
 Description: Open Metaverse Viewer
@@ -22,7 +22,7 @@ Description: Open Metaverse Viewer
 
 Package: omvviewer-dbg
 Architecture: i386 amd64 powerpc
-Depends: omvviewer (= ${binary:Version})
+Depends: ${misc:Depends}, omvviewer (= ${binary:Version})
 Replaces: slviewer-dbg
 Description: Second Life grid client
  This package contains the debug symbols for the omvviewer and should
@@ -30,7 +30,7 @@ Description: Second Life grid client
  
 Package: omvviewer-data
 Architecture: all
-Recommends: omvviewer
+Recommends: ${misc:Depends}, omvviewer
 Replaces: slviewer-data
 Description: Datafiles for Open Metaverse viewer
  This package contains the static datafiles needed by a Open 
diff --git a/debian/omvviewer-data.install b/debian/omvviewer-data.install
index ab26faf..f053279 100644
--- a/debian/omvviewer-data.install
+++ b/debian/omvviewer-data.install
@@ -6,3 +6,4 @@ indra/newview/skins/ usr/share/omvviewer
 scripts/messages/message_template.msg usr/share/omvviewer/app_settings
 etc/message.xml usr/share/omvviewer/app_settings
 indra/newview/linux_tools/launch_url.sh usr/share/omvviewer
+
diff --git a/debian/omvviewer.README.Debian b/debian/omvviewer.README.Debian
index 6069fdc..d3a61aa 100644
--- a/debian/omvviewer.README.Debian
+++ b/debian/omvviewer.README.Debian
@@ -39,4 +39,3 @@ home directory ~/.secondlife/
 
 
 
-
diff --git a/debian/patches/0000_keep_statbars_from_overshooting.patch.diff b/debian/patches/0000_keep_statbars_from_overshooting.patch.diff
deleted file mode 100644
index 13a17d5..0000000
--- a/debian/patches/0000_keep_statbars_from_overshooting.patch.diff
+++ /dev/null
@@ -1,49 +0,0 @@
-#! /bin/sh /usr/share/dpatch/dpatch-run
-## Keep stat bars from overshooting.dpatch by  <root at debian.example.org>
-##
-## All lines beginning with `## DP:' are a description of the patch.
-## DP: No description.
-
- at DPATCH@
-
-Index: ./indra/newview/llstatbar.cpp
-===================================================================
---- ./indra/newview/llstatbar.cpp	(revision 49)
-+++ ./indra/newview/llstatbar.cpp	(working copy)
-@@ -223,6 +223,7 @@
- 		}
- 
- 		right = (S32) ((max - mMinBar) * value_scale);
-+		right = llclamp(0, right, width);
- 		gl_rect_2d(left, top, right, bottom, LLColor4(1.f, 0.f, 0.f, 0.25f));
- 
- 		S32 num_values = mStatp->getNumValues() - 1;
-@@ -238,22 +239,22 @@
- 				if (mPerSec)
- 				{
- 					left = (S32)((mStatp->getPrevPerSec(i) - mMinBar) * value_scale);
--					right = (S32)((mStatp->getPrevPerSec(i) - mMinBar) * value_scale) + 1;
--					gl_rect_2d(left, bottom+i+1, right, bottom+i, LLColor4(1.f, 0.f, 0.f, 1.f));
- 				}
- 				else
- 				{
- 					left = (S32)((mStatp->getPrev(i) - mMinBar) * value_scale);
--					right = (S32)((mStatp->getPrev(i) - mMinBar) * value_scale) + 1;
--					gl_rect_2d(left, bottom+i+1, right, bottom+i, LLColor4(1.f, 0.f, 0.f, 1.f));
--				}
-+				}	
-+				left = llclamp(0, left, width-1);
-+				right = left+1;
-+				gl_rect_2d(left, bottom+i+1, right, bottom+i, LLColor4(1.f, 0.f, 0.f, 1.f));
- 			}
- 		}
- 		else
- 		{
- 			// draw current
- 			left = (S32) ((current - mMinBar) * value_scale) - 1;
--			right = (S32) ((current - mMinBar) * value_scale) + 1;
-+			left = llclamp(0, left, width-1);
-+			right = left + 2;
- 			gl_rect_2d(left, top, right, bottom, LLColor4(1.f, 0.f, 0.f, 1.f));
- 		}
- 
diff --git a/debian/patches/0001_possible_crash_and_leak_llassetstorage.patch.diff b/debian/patches/0001_possible_crash_and_leak_llassetstorage.patch.diff
deleted file mode 100644
index 16fbfa0..0000000
--- a/debian/patches/0001_possible_crash_and_leak_llassetstorage.patch.diff
+++ /dev/null
@@ -1,141 +0,0 @@
-#! /bin/sh /usr/share/dpatch/dpatch-run
-## 0001_possible_crash_and_leak_llassetstorage.patch.dpatch by  <robin at debian>
-##
-## All lines beginning with `## DP:' are a description of the patch.
-## DP: 0001_possible_crash_and_leak_llassetstorage.patch
-
- at DPATCH@
-
---- linden/indra/llmessage/llassetstorage.cpp	2007-09-20 12:36:46.000000000 +0200
-+++ linden/indra/llmessage/llassetstorage.cpp	2007-10-08 00:10:17.828125000 +0200
-@@ -512,16 +512,19 @@
- 	S32 result,
- 	const LLUUID& file_id,
- 	LLAssetType::EType file_type,
--	void* user_data, LLExtStat ext_status)
-+	void* callback_parm_req, LLExtStat ext_status)
- {
- 	lldebugs << "LLAssetStorage::downloadCompleteCallback() for " << file_id
- 		 << "," << LLAssetType::lookup(file_type) << llendl;
--	LLAssetRequest* req = (LLAssetRequest*)user_data;
-+
-+	// be careful! req may be a ptr to memory already freed (a timeout does this)
-+	LLAssetRequest* req = (LLAssetRequest*)callback_parm_req;	
- 	if(!req)
- 	{
- 		llwarns << "LLAssetStorage::downloadCompleteCallback called without"
- 			"a valid request." << llendl;
--		return;
-+		// we can live with a null pointer, we're not allowed to deref the ptr anyway (see above)
-+		// return;  
- 	}
- 	if (!gAssetStorage)
- 	{
-@@ -529,12 +532,10 @@
- 		return;
- 	}
- 
--	req->setUUID(file_id);
--	req->setType(file_type);
- 	if (LL_ERR_NOERR == result)
- 	{
- 		// we might have gotten a zero-size file
--		LLVFile vfile(gAssetStorage->mVFS, req->getUUID(), req->getType());
-+		LLVFile vfile(gAssetStorage->mVFS, file_id, file_type);
- 		if (vfile.getSize() <= 0)
- 		{
- 			llwarns << "downloadCompleteCallback has non-existent or zero-size asset " << req->getUUID() << llendl;
-@@ -553,7 +554,7 @@
- 	{
- 		request_list_t::iterator curiter = iter++;
- 		LLAssetRequest* tmp = *curiter;
--		if ((tmp->getUUID() == req->getUUID()) && (tmp->getType()== req->getType()))
-+		if ((tmp->getUUID() == file_id) && (tmp->getType() == file_type))
- 		{
- 			requests.push_front(tmp);
- 			iter = gAssetStorage->mPendingDownloads.erase(curiter);
-@@ -566,7 +567,7 @@
- 		LLAssetRequest* tmp = *curiter;
- 		if (tmp->mDownCallback)
- 		{
--			tmp->mDownCallback(gAssetStorage->mVFS, req->getUUID(), req->getType(), tmp->mUserData, result, ext_status);
-+			tmp->mDownCallback(gAssetStorage->mVFS, tmp->getUUID(), tmp->getType(), tmp->mUserData, result, ext_status);
- 		}
- 		delete tmp;
- 	}
-@@ -662,10 +663,10 @@
- 	S32 result,
- 	const LLUUID& file_id,
- 	LLAssetType::EType file_type,
--	void* user_data,
-+	void* callback_parm_req,
- 	LLExtStat ext_status)
- {
--	LLEstateAssetRequest *req = (LLEstateAssetRequest*)user_data;
-+	LLEstateAssetRequest *req = (LLEstateAssetRequest*)callback_parm_req;
- 	if(!req)
- 	{
- 		llwarns << "LLAssetStorage::downloadEstateAssetCompleteCallback called"
-@@ -679,12 +680,10 @@
- 		return;
- 	}
- 
--	req->setUUID(file_id);
--	req->setType(file_type);
- 	if (LL_ERR_NOERR == result)
- 	{
- 		// we might have gotten a zero-size file
--		LLVFile vfile(gAssetStorage->mVFS, req->getUUID(), req->getAType());
-+		LLVFile vfile(gAssetStorage->mVFS, file_id, file_type);
- 		if (vfile.getSize() <= 0)
- 		{
- 			llwarns << "downloadCompleteCallback has non-existent or zero-size asset!" << llendl;
-@@ -694,7 +693,9 @@
- 		}
- 	}
- 
--	req->mDownCallback(gAssetStorage->mVFS, req->getUUID(), req->getAType(), req->mUserData, result, ext_status);
-+	req->mDownCallback(gAssetStorage->mVFS, file_id, file_type, req->mUserData, result, ext_status);
-+
-+	delete req;
- }
- 
- void LLAssetStorage::getInvItemAsset(const LLHost &object_sim, const LLUUID &agent_id, const LLUUID &session_id,
-@@ -799,10 +800,10 @@
- 	S32 result,
- 	const LLUUID& file_id,
- 	LLAssetType::EType file_type,
--	void* user_data,
-+	void* callback_parm_req,
- 	LLExtStat ext_status)
- {
--	LLInvItemRequest *req = (LLInvItemRequest*)user_data;
-+	LLInvItemRequest *req = (LLInvItemRequest*)callback_parm_req;
- 	if(!req)
- 	{
- 		llwarns << "LLAssetStorage::downloadEstateAssetCompleteCallback called"
-@@ -815,12 +816,10 @@
- 		return;
- 	}
- 
--	req->setUUID(file_id);
--	req->setType(file_type);
- 	if (LL_ERR_NOERR == result)
- 	{
- 		// we might have gotten a zero-size file
--		LLVFile vfile(gAssetStorage->mVFS, req->getUUID(), req->getType());
-+		LLVFile vfile(gAssetStorage->mVFS, file_id, file_type);
- 		if (vfile.getSize() <= 0)
- 		{
- 			llwarns << "downloadCompleteCallback has non-existent or zero-size asset!" << llendl;
-@@ -830,7 +829,9 @@
- 		}
- 	}
- 
--	req->mDownCallback(gAssetStorage->mVFS, req->getUUID(), req->getType(), req->mUserData, result, ext_status);
-+	req->mDownCallback(gAssetStorage->mVFS, file_id, file_type, req->mUserData, result, ext_status);
-+
-+	delete req;
- }
- 
- /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/debian/patches/0001_possible_crash_in_llviewerpartssim.diff b/debian/patches/0001_possible_crash_in_llviewerpartssim.diff
deleted file mode 100644
index 0da8d6a..0000000
--- a/debian/patches/0001_possible_crash_in_llviewerpartssim.diff
+++ /dev/null
@@ -1,34 +0,0 @@
-#! /bin/sh /usr/share/dpatch/dpatch-run
-## possible crash in llviewerpartssim.dpatch by  <root at debian>
-##
-## All lines beginning with `## DP:' are a description of the patch.
-## DP: No description.
-
- at DPATCH@
-
-Index: ./indra/newview/llviewerpartsim.cpp
-===================================================================
---- ./indra/newview/llviewerpartsim.cpp	(revision 368)
-+++ ./indra/newview/llviewerpartsim.cpp	(working copy)
-@@ -639,11 +639,18 @@
- 		S32 visirate = 1;
- 		if (vobj)
- 		{
--			LLSpatialGroup* group = vobj->mDrawable->getSpatialGroup();
--			if (group && !group->isVisible()) // && !group->isState(LLSpatialGroup::OBJECT_DIRTY))
-+			if(vobj->mDrawable)
- 			{
--				visirate = 8;
-+				LLSpatialGroup* group = vobj->mDrawable->getSpatialGroup();
-+				if (group && !group->isVisible()) // && !group->isState(LLSpatialGroup::OBJECT_DIRTY))
-+				{
-+					visirate = 8;
-+				}
- 			}
-+			else
-+			{
-+				llwarns << "Crash avoided, vobj->mDrawable is NULL" << llendl;
-+			}
- 		}
- 
- 		if ((LLDrawable::getCurrentFrame()+mViewerPartGroups[i]->mID)%visirate == 0)
diff --git a/debian/patches/1294_llworkerthread_when_terminating_program.patch.diff b/debian/patches/1294_llworkerthread_when_terminating_program.patch.diff
deleted file mode 100644
index 727ed53..0000000
--- a/debian/patches/1294_llworkerthread_when_terminating_program.patch.diff
+++ /dev/null
@@ -1,19 +0,0 @@
-#! /bin/sh /usr/share/dpatch/dpatch-run
-## 1294_llworkerthread_when_terminating_program.patch.dpatch by  <robin at debian>
-##
-## All lines beginning with `## DP:' are a description of the patch.
-## DP: 1294_llworkerthread_when_terminating_program.patch
-
- at DPATCH@
-
---- linden/indra/llcommon/llworkerthread.cpp	2007-08-02 14:16:42.000000000 +0200
-+++ linden/indra/llcommon/llworkerthread.cpp	2007-08-08 00:56:01.750000000 +0200
-@@ -105,7 +105,7 @@
- 		delete *iter;
- 	}
-     // delete and aborted entries mean there's still work to do
--	res += delete_list.size() + abort_list.size();
-+	res +=  !mDeleteList.empty() + !delete_list.empty();  // deleted entries mean there's still work to do
- 	return res;
- }
- 
diff --git a/debian/patches/1857_apr_thread_mutex_nested.patch.diff b/debian/patches/1857_apr_thread_mutex_nested.patch.diff
deleted file mode 100644
index 22f5517..0000000
--- a/debian/patches/1857_apr_thread_mutex_nested.patch.diff
+++ /dev/null
@@ -1,43 +0,0 @@
-#! /bin/sh /usr/share/dpatch/dpatch-run
-## 1857_apr_thread_mutex_nested.patch.dpatch by  <robin at debian.example.org>
-##
-## All lines beginning with `## DP:' are a description of the patch.
-## DP: 1857_apr_thread_mutex_nested.patch
-
- at DPATCH@
-
---- linden-orig/indra/llcommon/llapr.cpp	2007-09-13 15:35:18.000000000 +0200
-+++ linden/indra/llcommon/llapr.cpp	2007-09-16 17:59:54.640625000 +0200
-@@ -44,7 +44,7 @@
- 		apr_pool_create(&gAPRPoolp, NULL);
- 
- 		// Initialize the logging mutex
--		apr_thread_mutex_create(&gLogMutexp, APR_THREAD_MUTEX_UNNESTED, gAPRPoolp);
-+		apr_thread_mutex_create(&gLogMutexp, APR_THREAD_MUTEX_NESTED, gAPRPoolp);
- 	}
- }
- 
---- linden-orig/indra/llcommon/llthread.cpp	2007-09-13 15:35:18.000000000 +0200
-+++ linden/indra/llcommon/llthread.cpp	2007-09-16 17:59:53.203125000 +0200
-@@ -266,7 +266,7 @@
- 		mIsLocalPool = TRUE;
- 		apr_pool_create(&mAPRPoolp, NULL); // Create a subpool for this thread
- 	}
--	apr_thread_mutex_create(&mAPRMutexp, APR_THREAD_MUTEX_UNNESTED, mAPRPoolp);
-+	apr_thread_mutex_create(&mAPRMutexp, APR_THREAD_MUTEX_NESTED, mAPRPoolp);
- }
- 
- 
---- linden-orig/indra/llmessage/llpumpio.cpp	2007-09-13 15:35:18.000000000 +0200
-+++ linden/indra/llmessage/llpumpio.cpp	2007-09-16 17:59:51.656250000 +0200
-@@ -684,8 +684,8 @@
- 	if(!pool) return;
- #if LL_THREADS_APR
- 	// SJB: Windows defaults to NESTED and OSX defaults to UNNESTED, so use UNNESTED explicitly.
--	apr_thread_mutex_create(&mChainsMutex, APR_THREAD_MUTEX_UNNESTED, pool);
--	apr_thread_mutex_create(&mCallbackMutex, APR_THREAD_MUTEX_UNNESTED, pool);
-+	apr_thread_mutex_create(&mChainsMutex, APR_THREAD_MUTEX_NESTED, pool);
-+	apr_thread_mutex_create(&mCallbackMutex, APR_THREAD_MUTEX_NESTED, pool);
- #endif
- 	mPool = pool;
- }
diff --git a/debian/patches/2003_possible_crash_draganddrop.patch.diff b/debian/patches/2003_possible_crash_draganddrop.patch.diff
deleted file mode 100644
index 3d60804..0000000
--- a/debian/patches/2003_possible_crash_draganddrop.patch.diff
+++ /dev/null
@@ -1,23 +0,0 @@
-#! /bin/sh /usr/share/dpatch/dpatch-run
-## 2003_possible_crash_draganddrop.patch.dpatch by  <robin at debian>
-##
-## All lines beginning with `## DP:' are a description of the patch.
-## DP: 2003_possible_crash_draganddrop.patch
-
- at DPATCH@
-
---- linden/indra/newview/lltooldraganddrop.cpp	2007-07-11 15:19:48.000000000 +0200
-+++ linden/indra/newview/lltooldraganddrop.cpp	2007-08-03 21:09:45.109375000 +0200
-@@ -962,6 +962,12 @@
- 		{
- 			LLInventoryObject* cargo = locateInventory(item, cat);
- 
-+			if (!cargo) 
-+			{
-+				handled = FALSE;
-+				break;
-+			}
-+
- 			EAcceptance item_acceptance = ACCEPT_NO;
- 			handled = handled && root_view->handleDragAndDrop(x, y, mask, FALSE,
- 												mCargoTypes[mCurItemIndex],
diff --git a/debian/patches/24_always_test_vectorize.diff b/debian/patches/24_always_test_vectorize.diff
deleted file mode 100644
index ec8d8b7..0000000
--- a/debian/patches/24_always_test_vectorize.diff
+++ /dev/null
@@ -1,34 +0,0 @@
-#! /bin/sh /usr/share/dpatch/dpatch-run
-## update vectorize patch.dpatch by  <root at debian>
-##
-## All lines beginning with `## DP:' are a description of the patch.
-## DP: No description.
-
- at DPATCH@
-
-Index: slviewer/indra/newview/llappviewer.cpp
-===================================================================
---- slviewer.orig/indra/newview/llappviewer.cpp	2008-09-14 17:04:46.000000000 +0100
-+++ slviewer/indra/newview/llappviewer.cpp	2008-09-14 17:06:56.000000000 +0100
-@@ -432,7 +432,6 @@
- 	gDebugGL = gSavedSettings.getBOOL("RenderDebugGL");
- 	gDebugPipeline = gSavedSettings.getBOOL("RenderDebugPipeline");
- 	
--#if LL_VECTORIZE
- 	if (gSysCPU.hasAltivec())
- 	{
- 		gSavedSettings.setBOOL("VectorizeEnable", TRUE );
-@@ -458,13 +457,6 @@
- 		gSavedSettings.setU32("VectorizeProcessor", 0 );
- 		gSavedSettings.setBOOL("VectorizeSkin", FALSE);
- 	}
--#else
--	// This build target doesn't support SSE, don't test/run.
--	gSavedSettings.setBOOL("VectorizePerfTest", FALSE );
--	gSavedSettings.setBOOL("VectorizeEnable", FALSE );
--	gSavedSettings.setU32("VectorizeProcessor", 0 );
--	gSavedSettings.setBOOL("VectorizeSkin", FALSE);
--#endif
- }
- 
- void LLAppViewer::initGridChoice()
diff --git a/debian/patches/2543_possible_crash_in_group_voting_propsals.patch.diff b/debian/patches/2543_possible_crash_in_group_voting_propsals.patch.diff
deleted file mode 100644
index c587e47..0000000
--- a/debian/patches/2543_possible_crash_in_group_voting_propsals.patch.diff
+++ /dev/null
@@ -1,116 +0,0 @@
-#! /bin/sh /usr/share/dpatch/dpatch-run
-## 2543_possible_crash_in_group_voting_propsals.patch.dpatch by  <root at debian.example.org>
-##
-## All lines beginning with `## DP:' are a description of the patch.
-## DP: 2543_possible_crash_in_group_voting_propsals.patch
-
- at DPATCH@
-
---- linden-orig/indra/llui/llscrolllistctrl.cpp	2007-09-20 12:36:46.000000000 +0200
-+++ linden/indra/llui/llscrolllistctrl.cpp	2007-09-26 02:26:16.406250000 +0200
-@@ -543,6 +543,11 @@
- 
- LLScrollListItem* LLScrollListCtrl::getFirstSelected() const
- {
-+	if (!getCanSelect())
-+	{
-+		return NULL;
-+	}
-+
- 	item_list::const_iterator iter;
- 	for(iter = mItemList.begin(); iter != mItemList.end(); iter++)
- 	{
-@@ -558,6 +563,13 @@
- std::vector<LLScrollListItem*> LLScrollListCtrl::getAllSelected() const
- {
- 	std::vector<LLScrollListItem*> ret;
-+
-+	if (!getCanSelect())
-+	{
-+		return ret;
-+	}
-+
-+
- 	item_list::const_iterator iter;
- 	for(iter = mItemList.begin(); iter != mItemList.end(); iter++)
- 	{
-@@ -572,6 +584,12 @@
- 
- S32 LLScrollListCtrl::getFirstSelectedIndex() const
- {
-+	if (!getCanSelect())
-+	{
-+		return -1;
-+	}
-+
-+
- 	S32 CurSelectedIndex = 0;
- 	item_list::const_iterator iter;
- 	for (iter = mItemList.begin(); iter != mItemList.end(); iter++)
---- linden-orig/indra/newview/llpanelgroupvoting.cpp	2007-09-20 12:36:50.000000000 +0200
-+++ linden/indra/newview/llpanelgroupvoting.cpp	2007-09-26 02:14:20.218750000 +0200
-@@ -524,6 +524,7 @@
- 	//we're pining the server in high latency situations
- 	addPendingActiveScrollListItem(0, 0, ADD_BOTTOM);
- 	mProposals->setCanSelect(FALSE);
-+	mBtnViewProposalItem->setEnabled(FALSE);
- 
- 	LLMessageSystem *msg = gMessageSystem;
- 	msg->newMessageFast(_PREHASH_GroupActiveProposalsRequest);
-@@ -620,6 +621,7 @@
- 	//add some text so the user knows we're doing something
- 	addPendingHistoryScrollListItem(0, 0, ADD_BOTTOM);
- 	mVotesHistory->setCanSelect(FALSE);
-+	mBtnViewHistoryItem->setEnabled(FALSE);
- 
- 	LLMessageSystem *msg = gMessageSystem;
- 	msg->newMessageFast(_PREHASH_GroupVoteHistoryRequest);
-@@ -835,6 +837,7 @@
- 		//no active proposals and make the scroll list unselectable
- 		self->addNoActiveScrollListItem(ADD_BOTTOM);
- 		self->mProposals->setCanSelect(FALSE);
-+		self->mBtnViewProposalItem->setEnabled(FALSE);
- 	}
- 	else if ( (U32)received != num_expected )
- 	{
-@@ -842,6 +845,7 @@
- 											 num_expected,
- 											 ADD_BOTTOM);
- 		self->mProposals->setCanSelect(FALSE);
-+		self->mBtnViewProposalItem->setEnabled(FALSE);
- 	}
- 	else
- 	{
-@@ -855,6 +859,7 @@
- 		}
- 
- 		self->mProposals->setCanSelect(TRUE);
-+		self->mBtnViewProposalItem->setEnabled(TRUE);
- 	}
- }
- 
-@@ -904,7 +909,7 @@
- 		//no active proposals and make the scroll list unselectable
- 		self->addNoHistoryScrollListItem(ADD_BOTTOM);
- 		self->mVotesHistory->setCanSelect(FALSE);
--
-+		self->mBtnViewHistoryItem->setEnabled(FALSE);
- 		return;
- 	}
- 
-@@ -1024,6 +1029,7 @@
- 											  num_expected,
- 											  ADD_BOTTOM);
- 		self->mVotesHistory->setCanSelect(FALSE);
-+		self->mBtnViewHistoryItem->setEnabled(FALSE);
- 	}
- 	else
- 	{
-@@ -1037,6 +1043,7 @@
- 		}
- 
- 		self->mVotesHistory->setCanSelect(TRUE);
-+		self->mBtnViewHistoryItem->setEnabled(TRUE);
- 	}
- }
- 
diff --git a/debian/patches/2683_possible_crash_update_speaker_list.patch.diff b/debian/patches/2683_possible_crash_update_speaker_list.patch.diff
deleted file mode 100644
index 368754f..0000000
--- a/debian/patches/2683_possible_crash_update_speaker_list.patch.diff
+++ /dev/null
@@ -1,41 +0,0 @@
-#! /bin/sh /usr/share/dpatch/dpatch-run
-## 2683_possible_crash_update_speaker_list.patch.dpatch by  <root at debian.example.org>
-##
-## All lines beginning with `## DP:' are a description of the patch.
-## DP: 2683_possible_crash_update_speaker_list.patch
-
- at DPATCH@
-
---- linden/indra/newview/llfloateractivespeakers.cpp	2007-09-20 12:36:50.000000000 +0200
-+++ linden/indra/newview/llfloateractivespeakers.cpp	2007-10-01 16:39:42.562500000 +0200
-@@ -806,7 +903,7 @@
- 	for(avatar_it = LLCharacter::sInstances.begin(); avatar_it != LLCharacter::sInstances.end(); ++avatar_it)
- 	{
- 		LLVOAvatar* avatarp = (LLVOAvatar*)*avatar_it;
--		if (dist_vec(avatarp->getPositionAgent(), gAgent.getPositionAgent()) <= CHAT_NORMAL_RADIUS)
-+		if (!avatarp->isDead() &&  dist_vec(avatarp->getPositionAgent(), gAgent.getPositionAgent()) <= CHAT_NORMAL_RADIUS)
- 		{
- 			setSpeaker(avatarp->getID());
- 		}
-@@ -820,7 +917,7 @@
- 		if (speakerp->mStatus == LLSpeaker::STATUS_TEXT_ONLY)
- 		{
- 			LLVOAvatar* avatarp = (LLVOAvatar*)gObjectList.findObject(speaker_id);
--			if (!avatarp || dist_vec(avatarp->getPositionAgent(), gAgent.getPositionAgent()) > CHAT_NORMAL_RADIUS)
-+			if (!avatarp || avatarp->isDead() || dist_vec(avatarp->getPositionAgent(), gAgent.getPositionAgent()) > CHAT_NORMAL_RADIUS)
- 			{
- 				speakerp->mStatus = LLSpeaker::STATUS_NOT_IN_CHANNEL;
- 				speakerp->mDotColor = INACTIVE_COLOR;
---- linden/indra/newview/llviewerobjectlist.cpp	2007-09-20 12:36:50.000000000 +0200
-+++ linden/indra/newview/llviewerobjectlist.cpp	2007-10-01 16:45:38.562500000 +0200
-@@ -868,6 +868,10 @@
- 		if (objectp->mRegionp == regionp)
- 		{
- 			killObject(objectp);
-+
-+			// invalidate region pointer. region will become invalid, but 
-+			// refcounted objects may survive the cleanDeadObjects() call below
-+			objectp->mRegionp = NULL;	 
- 		}
- 	}
- 
diff --git a/debian/patches/50_get_cpu_clock_count_for_more_than_just_i386.diff b/debian/patches/50_get_cpu_clock_count_for_more_than_just_i386.diff
deleted file mode 100644
index 952e621..0000000
--- a/debian/patches/50_get_cpu_clock_count_for_more_than_just_i386.diff
+++ /dev/null
@@ -1,34 +0,0 @@
-#! /bin/sh /usr/share/dpatch/dpatch-run
-## 50_get_cpu_clock_count_for_more_than_just_i386.dpatch by Paul "TBBle" Hampson <Paul.Hampson at Pobox.com>
-##
-## All lines beginning with `## DP:' are a description of the patch.
-## DP: Drop RDTSC reads on Linux and Solaris, and fallback to
-## DP: gettimeofday()-based implementation
-
- at DPATCH@
-diff -urNad linden~/indra/llcommon/llfasttimer.cpp linden/indra/llcommon/llfasttimer.cpp
---- linden~/indra/llcommon/llfasttimer.cpp	2007-05-12 13:44:24.000000000 +1000
-+++ linden/indra/llcommon/llfasttimer.cpp	2007-05-13 11:22:49.000000000 +1000
-@@ -91,20 +91,8 @@
- #endif // LL_WINDOWS
- 
- 
--#if (LL_LINUX || LL_SOLARIS) && (defined(__i386__) || defined(__amd64__))
--U64 get_cpu_clock_count()
--{
--	U64 x;
--	__asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
--	return x;
--}
--#endif
--
--#if LL_DARWIN || (LL_SOLARIS && defined(__sparc__))
--//
--// Mac implementation of CPU clock
--//
--// Just use gettimeofday implementation for now
-+#if LL_LINUX || LL_DARWIN || LL_SOLARIS
-+// Both Linux and Mac use gettimeofday for accurate time
- 
- U64 get_cpu_clock_count()
- {
diff --git a/debian/patches/55_fix_the_locales.diff b/debian/patches/55_fix_the_locales.diff
deleted file mode 100644
index 1489a3e..0000000
--- a/debian/patches/55_fix_the_locales.diff
+++ /dev/null
@@ -1,55 +0,0 @@
-#! /bin/sh /usr/share/dpatch/dpatch-run
-## Why am i the only one with this locale bug.dpatch by  <robin at debian.example.org>
-##
-## All lines beginning with `## DP:' are a description of the patch.
-## DP: No description.
-
- at DPATCH@
-
-
-Index: ./indra/llxml/llxmlnode.cpp
-===================================================================
---- ./indra/llxml/llxmlnode.cpp	(revision 374)
-+++ ./indra/llxml/llxmlnode.cpp	(working copy)
-@@ -571,6 +571,9 @@
- 	LLXMLNodePtr& node,
- 	LLXMLNode* defaults_tree)
- {
-+
-+	std::string saved_locale = setlocale(LC_ALL,"C");
-+
- 	// Read file
- 	LLFILE* fp = LLFile::fopen(filename.c_str(), "rb");		/* Flawfinder: ignore */
- 	if (fp == NULL)
-@@ -589,6 +592,9 @@
- 
- 	bool rv = parseBuffer(buffer, nread, node, defaults_tree);
- 	delete [] buffer;
-+
-+	setlocale(LC_ALL, saved_locale.c_str() );
-+
- 	return rv;
- }
- 
-Index: ./indra/llxml/llxmlparser.cpp
-===================================================================
---- ./indra/llxml/llxmlparser.cpp	(revision 374)
-+++ ./indra/llxml/llxmlparser.cpp	(working copy)
-@@ -76,6 +76,7 @@
- 	llassert( !mDepth );
- 	
- 	BOOL success = TRUE;
-+	std::string saved_locale = setlocale(LC_ALL,"C");
- 
- 	LLFILE* file = LLFile::fopen(path.c_str(), "rb");		/* Flawfinder: ignore */
- 	if( !file )
-@@ -129,6 +130,9 @@
- 		llwarns << mAuxErrorString << llendl;
- 	}
- 
-+	setlocale(LC_ALL, saved_locale.c_str() );
-+
-+
- 	return success;
- }
- 
diff --git a/debian/patches/59_need_llpreprocessor_to_access_endian_macros.diff b/debian/patches/59_need_llpreprocessor_to_access_endian_macros.diff
deleted file mode 100644
index cf875ad..0000000
--- a/debian/patches/59_need_llpreprocessor_to_access_endian_macros.diff
+++ /dev/null
@@ -1,21 +0,0 @@
-#! /bin/sh /usr/share/dpatch/dpatch-run
-## 59_need_llpreprocessor_to_access_endian_macros.dpatch by Paul "TBBle" Hampson <Paul.Hampson at Pobox.com>
-##
-## All lines beginning with `## DP:' are a description of the patch.
-## DP: Message.h implements htonmemcpy, which uses the LL_BIG_ENDIAN macro
-## DP: to check if swizzle of the largely little-endian data is needed
-## DP: However, the LL_BIG_ENDIAN macro is not current dragged in by any headers
-## DP: already included
-
- at DPATCH@
-diff -urNad linden~/indra/llmessage/message.h linden/indra/llmessage/message.h
---- linden~/indra/llmessage/message.h	2007-05-20 22:07:39.000000000 +1000
-+++ linden/indra/llmessage/message.h	2007-05-20 22:17:14.000000000 +1000
-@@ -47,6 +47,7 @@
- #include "winsock2.h" // htons etc.
- #endif
- 
-+#include "llpreprocessor.h"
- #include "llerror.h"
- #include "net.h"
- #include "string_table.h"
diff --git a/debian/patches/71_use_debian_alternatives_for_www_browser.diff b/debian/patches/71_use_debian_alternatives_for_www_browser.diff
deleted file mode 100644
index 67e3229..0000000
--- a/debian/patches/71_use_debian_alternatives_for_www_browser.diff
+++ /dev/null
@@ -1,35 +0,0 @@
-#! /bin/sh /usr/share/dpatch/dpatch-run
-## Use Debian alternitives for web browser AND use system() and let system() do the forking.dpatch by  <robin at debian>
-##
-## All lines beginning with `## DP:' are a description of the patch.
-## DP: No description.
-
- at DPATCH@
-
-
-Index: ./indra/newview/linux_tools/launch_url.sh
-===================================================================
---- ./indra/newview/linux_tools/launch_url.sh	(revision 135)
-+++ ./indra/newview/linux_tools/launch_url.sh	(working copy)
-@@ -8,6 +8,7 @@
- # On Unixoids we try, in order of decreasing priority:
- # - $BROWSER if set (preferred)
- # - kfmclient openURL
-+# - gnome-open
- # - x-www-browser
- # - opera
- # - firefox
-@@ -48,6 +49,13 @@
-     exit
- fi
- 
-+# else gnome-open
-+# (embodies gnome concept of 'preferred browser')
-+if which gnome-open  >/dev/null; then
-+    gnome-open "$URL" &
-+    exit
-+fi
-+
- # else x-www-browser
- # (Debianesque idea of a working X browser)
- if which x-www-browser >/dev/null; then
diff --git a/debian/patches/75_use_debian-included_fonts.diff b/debian/patches/75_use_debian-included_fonts.diff
deleted file mode 100644
index 2b65ba1..0000000
--- a/debian/patches/75_use_debian-included_fonts.diff
+++ /dev/null
@@ -1,40 +0,0 @@
-#! /bin/sh /usr/share/dpatch/dpatch-run
-## fix fonts.dpatch by  <root at debian>
-##
-## All lines beginning with `## DP:' are a description of the patch.
-## DP: No description.
-
- at DPATCH@
-
-
-Index: ./indra/newview/app_settings/settings.xml
-===================================================================
---- ./indra/newview/app_settings/settings.xml	(revision 374)
-+++ ./indra/newview/app_settings/settings.xml	(working copy)
-@@ -3464,7 +3464,7 @@
-       <key>Type</key>
-       <string>String</string>
-       <key>Value</key>
--      <string>profontwindows.ttf</string>
-+      <string>/usr/share/fonts/truetype/ttf-dejavu/DejaVuSansMono.ttf</string>
-     </map>
-     <key>FontSansSerif</key>
-     <map>
-@@ -3475,7 +3475,7 @@
-       <key>Type</key>
-       <string>String</string>
-       <key>Value</key>
--      <string>MtBkLfRg.ttf</string>
-+      <string>/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf</string>
-     </map>
-     <key>FontSansSerifBold</key>
-     <map>
-@@ -3486,7 +3486,7 @@
-       <key>Type</key>
-       <string>String</string>
-       <key>Value</key>
--      <string>MtBdLfRg.ttf</string>
-+      <string>/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans-Bold.ttf</string>
-     </map>
-     <key>FontSansSerifFallback</key>
-     <map>
diff --git a/debian/patches/79_use_debian_channel.diff b/debian/patches/79_use_debian_channel.diff
deleted file mode 100644
index 8edfbae..0000000
--- a/debian/patches/79_use_debian_channel.diff
+++ /dev/null
@@ -1,18 +0,0 @@
-#! /bin/sh /usr/share/dpatch/dpatch-run
-## change channel version.dpatch by  <robin at debian>
-##
-## All lines beginning with `## DP:' are a description of the patch.
-## DP: No description.
-
- at DPATCH@
- 
- #endif
-Index: ./indra/llcommon/llversionviewer.h
-===================================================================
---- ./indra/llcommon/llversionviewer.h	(revision 217)
-+++ ./indra/llcommon/llversionviewer.h	(working copy)
-@@ -39,3 +39,3 @@
- 
--const char * const LL_CHANNEL = "Second Life Release";
-+const char * const LL_CHANNEL = "Open Metaverse Viewer";
- 
diff --git a/debian/patches/Allow-CXXFLAGS-to-specify-the-debug-flag.patch b/debian/patches/Allow-CXXFLAGS-to-specify-the-debug-flag.patch
deleted file mode 100644
index 2066d61..0000000
--- a/debian/patches/Allow-CXXFLAGS-to-specify-the-debug-flag.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake
-index 240853a..7a78be0 100644
---- a/indra/cmake/00-Common.cmake
-+++ b/indra/cmake/00-Common.cmake
-@@ -11,7 +11,7 @@ set(CMAKE_CXX_FLAGS_DEBUG "-D_DEBUG -DLL_DEBUG=1")
- set(CMAKE_CXX_FLAGS_RELEASE
-     "-DLL_RELEASE=1 -DLL_RELEASE_FOR_DOWNLOAD=1 -DNDEBUG")
- set(CMAKE_CXX_FLAGS_RELWITHDEBINFO 
--    "-DLL_RELEASE=1 -DNDEBUG -DLL_RELEASE_WITH_DEBUG_INFO=1")
-+    "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DLL_RELEASE=1 -DNDEBUG -DLL_RELEASE_WITH_DEBUG_INFO=1")
- 
- 
- # Don't bother with a MinSizeRel build.
-@@ -119,7 +119,6 @@ if (LINUX)
-       -fno-math-errno
-       -fno-strict-aliasing
-       -fsigned-char
--      -g
-       -pthread
-       )
- 
-@@ -154,7 +153,7 @@ if (LINUX)
-     endif (NOT STANDALONE)
-   endif (VIEWER)
- 
--  set(CMAKE_CXX_FLAGS_DEBUG "-fno-inline ${CMAKE_CXX_FLAGS_DEBUG}")
-+  set(CMAKE_CXX_FLAGS_DEBUG "-g -fno-inline ${CMAKE_CXX_FLAGS_DEBUG}")
-   set(CMAKE_CXX_FLAGS_RELEASE "-O2 ${CMAKE_CXX_FLAGS_RELEASE}")
- endif (LINUX)
- 
diff --git a/debian/patches/VWR-1815_top_corner_fix.diff b/debian/patches/VWR-1815_top_corner_fix.diff
deleted file mode 100644
index 94f4ccf..0000000
--- a/debian/patches/VWR-1815_top_corner_fix.diff
+++ /dev/null
@@ -1,57 +0,0 @@
-#! /bin/sh /usr/share/dpatch/dpatch-run
-## top corner workaround.dpatch by  <robin at debian>
-##
-## All lines beginning with `## DP:' are a description of the patch.
-## DP: No description.
-
- at DPATCH@
-
-
-Index: ./indra/newview/lltexturefetch.cpp
-===================================================================
---- ./indra/newview/lltexturefetch.cpp	(revision 374)
-+++ ./indra/newview/lltexturefetch.cpp	(working copy)
-@@ -54,6 +54,9 @@
- {
- friend class LLTextureFetch;
- 
-+public:
-+	BOOL mAccelerateDownloadStuckTexture;
-+
- private:
- #if 0
- 	class URLResponder : public LLHTTPClient::Responder
-@@ -1059,6 +1062,14 @@
- 		}
- 		bool have_all_data = mLastPacket >= mTotalPackets-1;
- 		llassert_always(mRequestedSize > 0);
-+		
-+		if((buffer_size >= mRequestedSize) && mRequestedDiscard <=0)
-+ 		{
-+			if(!mAccelerateDownloadStuckTexture);
-+				llwarns << "Accelerating download of a stuck texture :"<<mID << llendl
-+			mAccelerateDownloadStuckTexture=TRUE;
-+		}
-+
- 		if (buffer_size >= mRequestedSize || have_all_data)
- 		{
- 			/// We have enough (or all) data
-@@ -1552,6 +1563,7 @@
- 	const F32 LAZY_FLUSH_TIMEOUT = 15.f; // 10.0f // temp
- 	const F32 MIN_REQUEST_TIME = 1.0f;
- 	const F32 MIN_DELTA_PRIORITY = 1000.f;
-+	const F32 MIN_ACCEL_KICK = 0.5f;
- 
- 	LLMutexLock lock(&mQueueMutex);
- 	
-@@ -1582,7 +1594,9 @@
- 		F32 delta_priority = llabs(req->mRequestedPriority - req->mImagePriority);
- 		if ((req->mSimRequestedDiscard != req->mDesiredDiscard) ||
- 			(delta_priority > MIN_DELTA_PRIORITY && elapsed >= MIN_REQUEST_TIME) ||
--			(elapsed >= LAZY_FLUSH_TIMEOUT))
-+			(elapsed >= LAZY_FLUSH_TIMEOUT) ||
-+			(req->mAccelerateDownloadStuckTexture && (elapsed >=MIN_ACCEL_KICK))
-+			)
- 		{
- 			requests[req->mHost].insert(req);
- 		}
diff --git a/debian/patches/VWR-3766_llGetInventoryNumber_tooltip_missing_INVENTORY_ANIMATION.diff b/debian/patches/VWR-3766_llGetInventoryNumber_tooltip_missing_INVENTORY_ANIMATION.diff
deleted file mode 100644
index 7cdecaf..0000000
--- a/debian/patches/VWR-3766_llGetInventoryNumber_tooltip_missing_INVENTORY_ANIMATION.diff
+++ /dev/null
@@ -1,21 +0,0 @@
-#! /bin/sh /usr/share/dpatch/dpatch-run
-## llGetInventoryNumber tooltip missing INVENTORY_ANIMATION.dpatch by  <root at debian.example.org>
-##
-## All lines beginning with `## DP:' are a description of the patch.
-## DP: Patch by McCabe Maxsted
-
- at DPATCH@
-
-Index: ./indra/lscript/lscript_library/lscript_library.cpp
-===================================================================
---- ./indra/lscript/lscript_library/lscript_library.cpp	(revision 327)
-+++ ./indra/lscript/lscript_library/lscript_library.cpp	(working copy)
-@@ -221,7 +221,7 @@
- 	addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llBreakAllLinks", NULL, NULL, "llBreakAllLinks()\nDelinks all tasks in the link set (requires permission PERMISSION_CHANGE_LINKS be set)"));
- 	addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetLinkKey", "k", "i", "key llGetLinkKey(integer linknum)\nGet the key of linknumber in link set"));
- 	addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetLinkName", "s", "i", "string llGetLinkName(integer linknum)\nGet the name of linknumber in link set"));
--	addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetInventoryNumber", "i", "i", "integer llGetInventoryNumber(integer type)\nGet the number of items of a given type in the task's inventory.\nValid types: INVENTORY_TEXTURE, INVENTORY_SOUND, INVENTORY_OBJECT, INVENTORY_SCRIPT, INVENTORY_CLOTHING, INVENTORY_BODYPART, INVENTORY_NOTECARD, INVENTORY_LANDMARK, INVENTORY_ALL"));
-+	addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetInventoryNumber", "i", "i", "integer llGetInventoryNumber(integer type)\nGet the number of items of a given type in the task's inventory.\nValid types: INVENTORY_TEXTURE, INVENTORY_SOUND, INVENTORY_OBJECT, INVENTORY_SCRIPT, INVENTORY_CLOTHING, INVENTORY_BODYPART, INVENTORY_NOTECARD, INVENTORY_LANDMARK, INVENTORY_ANIMATION, INVENTORY_GESTURE, INVENTORY_ALL"));
- 	addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetInventoryName", "s", "ii", "string llGetInventoryName(integer type, integer number)\nGet the name of the inventory item number of type"));
- 	addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetScriptState", NULL, "si", "llSetScriptState(string name, integer run)\nControl the state of a script name."));
- 	addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetEnergy", "f", NULL, "float llGetEnergy()\nReturns how much energy is in the object as a percentage of maximum"));
diff --git a/debian/patches/VWR-5082_set_bulk_inv_permissions.diff b/debian/patches/VWR-5082_set_bulk_inv_permissions.diff
deleted file mode 100644
index fe69361..0000000
--- a/debian/patches/VWR-5082_set_bulk_inv_permissions.diff
+++ /dev/null
@@ -1,946 +0,0 @@
-Index: omvviewer-1.21.0/indra/newview/CMakeLists.txt
-===================================================================
---- omvviewer-1.21.0.orig/indra/newview/CMakeLists.txt	2008-09-01 21:00:07.000000000 +0100
-+++ omvviewer-1.21.0/indra/newview/CMakeLists.txt	2008-09-01 21:00:09.000000000 +0100
-@@ -126,6 +126,7 @@
-     llfloateravatarpicker.cpp
-     llfloateravatartextures.cpp
-     llfloaterbuildoptions.cpp
-+    llfloaterbulkpermission.cpp
-     llfloaterbump.cpp
-     llfloaterbuycontents.cpp
-     llfloaterbuy.cpp
-Index: omvviewer-1.21.0/indra/newview/llviewermenu.cpp
-===================================================================
---- omvviewer-1.21.0.orig/indra/newview/llviewermenu.cpp	2008-09-01 21:00:07.000000000 +0100
-+++ omvviewer-1.21.0/indra/newview/llviewermenu.cpp	2008-09-01 21:00:09.000000000 +0100
-@@ -86,6 +86,7 @@
- #include "llfloateravatarinfo.h"
- #include "llfloateravatartextures.h"
- #include "llfloaterbuildoptions.h"
-+#include "llfloaterbulkpermission.h"
- #include "llfloaterbump.h"
- #include "llfloaterbuy.h"
- #include "llfloaterbuycontents.h"
-@@ -6225,6 +6226,17 @@
- 	}
- }
- 
-+class LLToolsSetBulkPerms : public view_listener_t
-+{
-+	bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
-+	{
-+		LLFloaterBulkPermission* queue = NULL;
-+		queue = LLFloaterBulkPermission::create();
-+		return true;
-+	}
-+};
-+
-+
- class LLToolsSelectedScriptAction : public view_listener_t
- {
- 	bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
-@@ -7850,6 +7862,7 @@
- 	addMenu(new LLToolsSaveToInventory(), "Tools.SaveToInventory");
- 	addMenu(new LLToolsSaveToObjectInventory(), "Tools.SaveToObjectInventory");
- 	addMenu(new LLToolsSelectedScriptAction(), "Tools.SelectedScriptAction");
-+	addMenu(new LLToolsSetBulkPerms(), "Tools.SetBulkPerms");
- 
- 	addMenu(new LLToolsEnableToolNotPie(), "Tools.EnableToolNotPie");
- 	addMenu(new LLToolsEnableLink(), "Tools.EnableLink");
-Index: omvviewer-1.21.0/indra/newview/skins/default/xui/en-us/floater_bulk_perms.xml
-===================================================================
---- /dev/null	1970-01-01 00:00:00.000000000 +0000
-+++ omvviewer-1.21.0/indra/newview/skins/default/xui/en-us/floater_bulk_perms.xml	2008-09-01 21:49:41.000000000 +0100
-@@ -0,0 +1,127 @@
-+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-+<floater bottom="-554" can_close="true" can_drag_on_left="false" can_minimize="true"
-+     can_resize="false" can_tear_off="false" enabled="true" height="420"
-+     left="367" min_height="1000" min_width="460" mouse_opaque="true"
-+     name="floaterrecursiveperms" title="Bulk permission settings"
-+     width="460">
-+
-+<text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
-+			     bottom="-40" drop_shadow_visible="true" enabled="true" follows="left|top"
-+			     font="SansSerifSmall" h_pad="0" halign="left" height="10" left="10"
-+			     mouse_opaque="true" name="applyto" v_pad="0" width="206">Apply to</text>
-+
-+<check_box bottom="-70" enabled="true" follows="left|top" font="SansSerifSmall"
-+			     height="16" initial_value="false"
-+			     label="Scripts" left="10" mouse_opaque="true"
-+			     name="scripts" radio_style="false"
-+			     tool_tip="Apply bulk permissions to scripts"
-+			     width="219"/>
-+
-+<check_box bottom="-90" enabled="true" follows="left|top" font="SansSerifSmall"
-+			     height="16" initial_value="false"
-+			     label="Textures" left="10" mouse_opaque="true"
-+			     name="textures" radio_style="false"
-+			     tool_tip="Apply bulk permissions to textures"
-+			     width="219"/>
-+
-+<check_box bottom="-110" enabled="true" follows="left|top" font="SansSerifSmall"
-+			     height="16" initial_value="false"
-+			     label="Animations" left="10" mouse_opaque="true"
-+			     name="animations" radio_style="false"
-+			     tool_tip="Apply bulk permissions to animations"
-+			     width="219"/>
-+
-+<check_box bottom="-130" enabled="true" follows="left|top" font="SansSerifSmall"
-+			     height="16" initial_value="false"
-+			     label="Sounds" left="10" mouse_opaque="true"
-+			     name="sounds" radio_style="false"
-+			     tool_tip="Apply bulk permissions to sounds"
-+			     width="219"/>
-+
-+<check_box bottom="-150" enabled="true" follows="left|top" font="SansSerifSmall"
-+			     height="16" initial_value="false"
-+			     label="Contained objects" left="10" mouse_opaque="true"
-+			     name="objects" radio_style="false"
-+			     tool_tip="Apply bulk permissions to objects inside inventory"
-+			     width="219"/>
-+
-+<check_box bottom="-170" enabled="true" follows="left|top" font="SansSerifSmall"
-+			     height="16" initial_value="false"
-+			     label="Landmarks" left="10" mouse_opaque="true"
-+			     name="landmarks" radio_style="false"
-+			     tool_tip="Apply bulk permissions to landmarks"
-+			     width="219"/>
-+
-+<check_box bottom="-190" enabled="true" follows="left|top" font="SansSerifSmall"
-+			     height="16" initial_value="false"
-+			     label="Notecards" left="10" mouse_opaque="true"
-+			     name="notecards" radio_style="false"
-+			     tool_tip="Apply bulk permissions to notecards"
-+			     width="219"/>
-+
-+<check_box bottom="-210" enabled="true" follows="left|top" font="SansSerifSmall"
-+			     height="16" initial_value="false"
-+			     label="Gesture" left="10" mouse_opaque="true"
-+			     name="gestures" radio_style="false"
-+			     tool_tip="Apply bulk permissions to gestures"
-+			     width="219"/>
-+
-+<check_box bottom="-230" enabled="true" follows="left|top" font="SansSerifSmall"
-+			     height="16" initial_value="false"
-+			     label="Clothing" left="10" mouse_opaque="true"
-+			     name="clothing" radio_style="false"
-+			     tool_tip="Apply bulk permissions to clothing"
-+			     width="219"/>
-+
-+<check_box bottom="-250" enabled="true" follows="left|top" font="SansSerifSmall"
-+			     height="16" initial_value="false"
-+			     label="Bodypart" left="10" mouse_opaque="true"
-+			     name="bodyparts" radio_style="false"
-+			     tool_tip="Apply bulk permissions to bodyparts"
-+			     width="219"/>
-+
-+<text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
-+			     bottom="-40" drop_shadow_visible="true" enabled="true" follows="left|top"
-+			     font="SansSerifSmall" h_pad="0" halign="left" height="10" left="200"
-+			     mouse_opaque="true" name="applyto" v_pad="0" width="206">Permissions</text>
-+
-+
-+<check_box bottom="-110" enabled="true" follows="left|top" font="SansSerifSmall"
-+			     height="16" initial_value="false"
-+			     label="Copy" left="200" mouse_opaque="true"
-+			     name="Copy" radio_style="false"
-+			     tool_tip="Next owner can copy"
-+			     width="219"/>
-+
-+<check_box bottom="-130" enabled="true" follows="left|top" font="SansSerifSmall"
-+			     height="16" initial_value="false"
-+			     label="Modify" left="200" mouse_opaque="true"
-+			     name="Modify" radio_style="false"
-+			     tool_tip="Next owner can modify"
-+			     width="219"/>
-+
-+<check_box bottom="-150" enabled="true" follows="left|top" font="SansSerifSmall"
-+			     height="16" initial_value="false"
-+			     label="Trans" left="200" mouse_opaque="true"
-+			     name="Trans" radio_style="false"
-+			     tool_tip="Next owner can transfer"
-+			     width="219"/>
-+
-+<check_box bottom="-230" enabled="true" follows="left|top" font="SansSerifSmall"
-+			     height="16" initial_value="false"
-+			     label="Modify Parent Prims" left="200" mouse_opaque="true"
-+			     name="Parent" radio_style="false"
-+			     tool_tip="Modify parent prims not just inventory"
-+			     width="219" default="true"/>
-+
-+<scroll_list background_visible="true" bottom="-410" column_padding="5" draw_border="true"
-+	     draw_heading="false" draw_stripes="true" enabled="true"
-+	     follows="left|top|right|bottom" height="140" left="10" mouse_opaque="true"
-+	     multi_select="false" name="queue output" width="440" />
-+
-+<button bottom="-70" enabled="true" follows="left|top" font="SansSerif"
-+			     halign="center" height="20" label="Apply..."
-+			     label_selected="Apply..." left="295" mouse_opaque="true"
-+			     name="Apply..." scale_image="true" width="145" />
-+
-+</floater>
-Index: omvviewer-1.21.0/indra/newview/skins/default/xui/en-us/menu_viewer.xml
-===================================================================
---- omvviewer-1.21.0.orig/indra/newview/skins/default/xui/en-us/menu_viewer.xml	2008-09-01 21:00:07.000000000 +0100
-+++ omvviewer-1.21.0/indra/newview/skins/default/xui/en-us/menu_viewer.xml	2008-09-01 21:00:09.000000000 +0100
-@@ -771,6 +771,11 @@
- 			<on_click function="Tools.SelectedScriptAction" userdata="stop" />
- 			<on_enable function="EditableSelected" />
- 		</menu_item_call>
-+		<menu_item_call bottom="-468" enabled="false" height="19" label="Set permissions on selected task inventory"
-+		     left="0" mouse_opaque="true" name="Set permissions on selected task inventory" width="250">
-+			<on_click function="Tools.SetBulkPerms" userdata="" />
-+			<on_enable function="EditableSelected" />
-+		</menu_item_call>
- 	</menu>
- 	<menu bottom="219" create_jump_keys="true" drop_shadow="true" enabled="true"
- 	     height="317" label="Help" left="227" mouse_opaque="false" name="Help"
-Index: omvviewer-1.21.0/indra/newview/llfloaterbulkpermission.cpp
-===================================================================
---- /dev/null	1970-01-01 00:00:00.000000000 +0000
-+++ omvviewer-1.21.0/indra/newview/llfloaterbulkpermission.cpp	2008-09-01 22:07:08.000000000 +0100
-@@ -0,0 +1,595 @@
-+/** 
-+ * @file llfloaterbulkpermissions.cpp
-+ * @brief A floater which allows task inventory item's properties to be changed on mass.
-+ *
-+ * $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$
-+ */
-+
-+/* Allow multiple task inventory properties to be set in one go, by Michelle2 Zenovka */
-+
-+/* TODO
-+	
-+	* Add in the option to select objects or task inventory
-+s
-+
-+It would be nice to set the permissions on groups of prims as well as task inventory
-+
-+*/
-+
-+
-+#include "llviewerprecompiledheaders.h"
-+#include "llfloaterbulkpermission.h"
-+#include "llagent.h"
-+#include "llchat.h"
-+#include "llviewerwindow.h"
-+#include "llviewerobject.h"
-+#include "llviewerobjectlist.h"
-+#include "llviewerregion.h"
-+#include "lscript_rt_interface.h"
-+#include "llviewercontrol.h"
-+#include "llviewerobject.h"
-+#include "llviewerregion.h"
-+#include "llresmgr.h"
-+#include "llbutton.h"
-+#include "lldir.h"
-+#include "llfloaterchat.h"
-+#include "llviewerstats.h"
-+#include "lluictrlfactory.h"
-+#include "llselectmgr.h"
-+#include "llinventory.h"
-+
-+
-+#include <algorithm>
-+#include <functional>
-+#include "llcachename.h"
-+#include "lldbstrings.h"
-+#include "llinventory.h"
-+
-+#include "llagent.h"
-+#include "llbutton.h"
-+#include "llcheckboxctrl.h"
-+#include "llfloateravatarinfo.h"
-+#include "llfloatergroupinfo.h"
-+#include "llinventorymodel.h"
-+#include "lllineeditor.h"
-+#include "llradiogroup.h"
-+#include "llresmgr.h"
-+#include "roles_constants.h"
-+#include "llselectmgr.h"
-+#include "lltextbox.h"
-+#include "lluiconstants.h"
-+#include "llviewerinventory.h"
-+#include "llviewerobjectlist.h"
-+#include "llviewerregion.h"
-+#include "llviewercontrol.h"
-+
-+#include "lluictrlfactory.h"
-+
-+
-+const char* BULKPERM_QUEUE_TITLE = "Update Progress";
-+const char* BULKPERM_START_STRING = "update";
-+
-+namespace
-+{
-+	struct BulkQueueObjects : public LLSelectedObjectFunctor
-+	{
-+		BOOL scripted;
-+		BOOL modifiable;
-+		LLFloaterBulkPermission* mQueue;
-+		BulkQueueObjects(LLFloaterBulkPermission* q) : mQueue(q), scripted(FALSE), modifiable(FALSE) {}
-+		virtual bool apply(LLViewerObject* obj)
-+		{
-+			scripted = obj->flagScripted();
-+			modifiable = obj->permModify();
-+
-+			mQueue->addObject(obj->getID());
-+			return false;
-+			
-+		}
-+	};
-+}
-+
-+///----------------------------------------------------------------------------
-+/// Class LLFloaterBulkPermission
-+///----------------------------------------------------------------------------
-+
-+// static
-+LLMap<LLUUID, LLFloaterBulkPermission*> LLFloaterBulkPermission::sInstances;
-+
-+
-+// Default constructor
-+LLFloaterBulkPermission::LLFloaterBulkPermission(const std::string& name,
-+											 const LLRect& rect,
-+											 const char* title,
-+											 const char* start_string) :
-+	LLFloater(name, rect, title,
-+			  RESIZE_YES, DEFAULT_MIN_WIDTH, DEFAULT_MIN_HEIGHT,
-+			  DRAG_ON_TOP, MINIMIZE_YES, CLOSE_YES)
-+{
-+
-+	req_perm_mask=0; // This should match the default state the checkboxes are set to
-+	recurse=false;
-+
-+	LLUICtrlFactory::getInstance()->buildFloater(this,"floater_bulk_perms.xml");
-+
-+	childSetAction("Apply...",onApplyBtn,this);
-+	childSetEnabled("Apply...",TRUE);
-+
-+	childSetCommitCallback("Modify",&onCommitPermissions, this);
-+	childSetCommitCallback("Trans",&onCommitPermissions, this);
-+	childSetCommitCallback("Copy",&onCommitPermissions, this);
-+
-+	//childSetCommitCallback("Recurse",&onRecurse, this);
-+
-+	childSetCommitCallback("Parent",&onParent, this);
-+
-+	childSetCommitCallback("objects",&InvSelection, this);
-+	childSetCommitCallback("scripts",&InvSelection, this);
-+	childSetCommitCallback("textures",&InvSelection, this);
-+	childSetCommitCallback("sounds",&InvSelection, this);
-+	childSetCommitCallback("animations",&InvSelection, this);
-+	childSetCommitCallback("notecards",&InvSelection, this);
-+	childSetCommitCallback("landmarks",&InvSelection, this);
-+	childSetCommitCallback("bodyparts",&InvSelection, this);
-+	childSetCommitCallback("clothing",&InvSelection, this);
-+	childSetCommitCallback("gestures",&InvSelection, this);
-+
-+	//Set variable state to XUI default state consistancy
-+	processObject=getChild<LLCheckBoxCtrl>("objects")->get();
-+	processScript=getChild<LLCheckBoxCtrl>("scripts")->get();
-+	processTexture=getChild<LLCheckBoxCtrl>("textures")->get();
-+	processSound=getChild<LLCheckBoxCtrl>("sounds")->get();
-+	processAnimation=getChild<LLCheckBoxCtrl>("animations")->get();
-+	processNotecard=getChild<LLCheckBoxCtrl>("notecards")->get();
-+	processGesture=getChild<LLCheckBoxCtrl>("gestures")->get();
-+	processClothing=getChild<LLCheckBoxCtrl>("clothing")->get();
-+	processBodypart=getChild<LLCheckBoxCtrl>("bodyparts")->get();
-+	processLandmark=getChild<LLCheckBoxCtrl>("landmarks")->get();
-+	parent=getChild<LLCheckBoxCtrl>("Parent")->get();
-+
-+
-+	setTitle(title);
-+	
-+	if (!getHost())
-+	{
-+		LLRect curRect = getRect();
-+		translate(rect.mLeft - curRect.mLeft, rect.mTop - curRect.mTop);
-+	}
-+	
-+	mStartString = start_string;
-+	mDone = FALSE;
-+	sInstances.addData(mID, this);
-+
-+}
-+
-+void LLFloaterBulkPermission::doApply()
-+{
-+	// Its alive now do the nasty work that the ScriptQueue and friends try to do in the menu code
-+	// but first grab the user options
-+
-+	LLScrollListCtrl* list = getChild<LLScrollListCtrl>("queue output");
-+	list->deleteAllItems();
-+
-+	//Apply to selected objects if requested first
-+
-+	if(parent)
-+	{
-+		llinfos<< "Setting permission on parent items" << llendl;
-+		LLSelectMgr::getInstance()->selectionSetObjectPermissions(PERM_NEXT_OWNER,true, req_perm_mask);
-+		LLSelectMgr::getInstance()->selectionSetObjectPermissions(PERM_NEXT_OWNER,false, ~req_perm_mask); //How annoying need to set and unset
-+	}
-+
-+
-+	LLFloaterBulkPermission* q;
-+	q=(LLFloaterBulkPermission*)this;
-+
-+	BulkQueueObjects func(q);
-+	const bool firstonly = false;
-+	bool fail = LLSelectMgr::getInstance()->getSelection()->applyToObjects(&func, firstonly);
-+	if(fail)
-+	{
-+		if ( !func.modifiable )
-+		{
-+			gViewerWindow->alertXml("NO MODIFY");
-+		}
-+		else
-+		{
-+			llwarns << "Bad logic. Are there actualy any items in that prim?" << llendl;
-+		}
-+	}
-+	else
-+	{
-+		if (!q->start())
-+		{
-+			llwarns << "Unexpected failure attepmting to set permissions." << llendl;
-+		}
-+	}
-+}
-+
-+// Destroys the object
-+LLFloaterBulkPermission::~LLFloaterBulkPermission()
-+{
-+	sInstances.removeData(mID);
-+}
-+
-+// find an instance by ID. Return NULL if it does not exist.
-+// static
-+LLFloaterBulkPermission* LLFloaterBulkPermission::findInstance(const LLUUID& id)
-+{
-+	if(sInstances.checkData(id))
-+	{
-+		return sInstances.getData(id);
-+	}
-+	return NULL;
-+}
-+
-+
-+// This is the callback method for the viewer object currently being
-+// worked on.
-+// NOT static, virtual!
-+void LLFloaterBulkPermission::inventoryChanged(LLViewerObject* viewer_object,
-+											 InventoryObjectList* inv,
-+											 S32,
-+											 void* q_id)
-+{
-+	llinfos << "LLFloaterBulkPermission::inventoryChanged() for  object "
-+			<< viewer_object->getID() << llendl;
-+
-+	//Remove this listener from the object since its
-+	//listener callback is now being executed.
-+	
-+	//We remove the listener here because the function
-+	//removeVOInventoryListener removes the listener from a ViewerObject
-+	//which it internally stores.
-+	
-+	//If we call this further down in the function, calls to handleInventory
-+	//and nextObject may update the interally stored viewer object causing
-+	//the removal of the incorrect listener from an incorrect object.
-+	
-+	//Fixes SL-6119:Recompile scripts fails to complete
-+	removeVOInventoryListener();
-+
-+	if (viewer_object && inv && (viewer_object->getID() == mCurrentObjectID) )
-+	{
-+		handleInventory(viewer_object, inv);
-+	}
-+	else
-+	{
-+		// something went wrong...
-+		// note that we're not working on this one, and move onto the
-+		// next object in the list.
-+		llwarns << "No inventory for " << mCurrentObjectID
-+				<< llendl;
-+		nextObject();
-+	}
-+}
-+
-+void LLFloaterBulkPermission::onApplyBtn(void* user_data)
-+{
-+	LLFloaterBulkPermission* self = (LLFloaterBulkPermission*)user_data;
-+	self->doApply();
-+}
-+
-+
-+// static
-+void LLFloaterBulkPermission::InvSelection(LLUICtrl* ctrl, void* data)
-+{
-+	LLFloaterBulkPermission* self = (LLFloaterBulkPermission*)data;
-+
-+	self->processObject=self->getChild<LLCheckBoxCtrl>("objects")->get();
-+	self->processScript=self->getChild<LLCheckBoxCtrl>("scripts")->get();
-+	self->processTexture=self->getChild<LLCheckBoxCtrl>("textures")->get();
-+	self->processSound=self->getChild<LLCheckBoxCtrl>("sounds")->get();
-+	self->processAnimation=self->getChild<LLCheckBoxCtrl>("animations")->get();
-+	self->processNotecard=self->getChild<LLCheckBoxCtrl>("notecards")->get();
-+	self->processGesture=self->getChild<LLCheckBoxCtrl>("gestures")->get();
-+	self->processClothing=self->getChild<LLCheckBoxCtrl>("clothing")->get();
-+	self->processBodypart=self->getChild<LLCheckBoxCtrl>("bodyparts")->get();
-+	self->processLandmark=self->getChild<LLCheckBoxCtrl>("landmarks")->get();
-+
-+
-+}
-+
-+// static
-+void LLFloaterBulkPermission::onParent(LLUICtrl* ctrl, void* data)
-+{
-+	LLFloaterBulkPermission* self = (LLFloaterBulkPermission*)data;
-+	self->parent=self->getChild<LLCheckBoxCtrl>("Parent")->get();
-+}
-+
-+// static
-+void LLFloaterBulkPermission::onRecurse(LLUICtrl* ctrl, void* data)
-+{
-+	LLFloaterBulkPermission* self = (LLFloaterBulkPermission*)data;
-+	self->recurse=self->getChild<LLCheckBoxCtrl>("Recurse")->get();
-+}
-+
-+// static
-+void LLFloaterBulkPermission::onCommitPermissions(LLUICtrl* ctrl, void* data)
-+{
-+	LLFloaterBulkPermission* self = (LLFloaterBulkPermission*)data;
-+	LLCheckBoxCtrl* CheckModify = self->getChild<LLCheckBoxCtrl>("Modify");
-+	LLCheckBoxCtrl* CheckCopy = self->getChild<LLCheckBoxCtrl>("Copy");
-+	LLCheckBoxCtrl* CheckTrans = self->getChild<LLCheckBoxCtrl>("Trans");
-+
-+	self->req_perm_mask=0;
-+
-+	if(CheckModify->get())
-+	{
-+		self->req_perm_mask|=PERM_MODIFY;
-+	}
-+	else
-+	{
-+		self->req_perm_mask&=~PERM_MODIFY;
-+	}
-+
-+	if(CheckCopy->get())
-+	{
-+		self->req_perm_mask|=PERM_COPY;
-+	}
-+	else
-+	{
-+		self->req_perm_mask&=~PERM_COPY;
-+	}
-+
-+	if(CheckTrans->get())
-+	{
-+		self->req_perm_mask|=PERM_TRANSFER;
-+	}
-+	else
-+	{
-+		self->req_perm_mask&=~PERM_TRANSFER;
-+	}
-+
-+
-+}
-+
-+void LLFloaterBulkPermission::addObject(const LLUUID& id)
-+{
-+	mObjectIDs.put(id);
-+}
-+
-+BOOL LLFloaterBulkPermission::start()
-+{
-+	llinfos << "LLFloaterBulkPermission::start()" << llendl;
-+	char buffer[MAX_STRING]; 				/*Flawfinder: ignore*/
-+	snprintf(buffer, sizeof(buffer), "Starting %s of %d items.", mStartString, mObjectIDs.count()); 		/* Flawfinder: ignore */
-+
-+	LLScrollListCtrl* list = getChild<LLScrollListCtrl>("queue output");
-+	list->addCommentText(buffer);
-+
-+	return nextObject();
-+}
-+
-+BOOL LLFloaterBulkPermission::isDone() const
-+{
-+	return (mCurrentObjectID.isNull() || (mObjectIDs.count() == 0));
-+}
-+
-+// go to the next object. If no objects left, it falls out silently
-+// and waits to be killed by the window being closed.
-+BOOL LLFloaterBulkPermission::nextObject()
-+{
-+	S32 count;
-+	BOOL successful_start = FALSE;
-+	do
-+	{
-+		count = mObjectIDs.count();
-+		llinfos << "LLFloaterBulkPermission::nextObject() - " << count
-+				<< " objects left to process." << llendl;
-+		mCurrentObjectID.setNull();
-+		if(count > 0)
-+		{
-+			successful_start = popNext();
-+		}
-+		llinfos << "LLFloaterBulkPermission::nextObject() "
-+				<< (successful_start ? "successful" : "unsuccessful")
-+				<< llendl; 
-+	} while((mObjectIDs.count() > 0) && !successful_start);
-+
-+	if(isDone() && !mDone)
-+	{
-+		
-+		LLScrollListCtrl* list = getChild<LLScrollListCtrl>("queue output");
-+		mDone = TRUE;
-+		char buffer[MAX_STRING];		/*Flawfinder: ignore*/
-+		snprintf(buffer, sizeof(buffer), "Done.");				/* Flawfinder: ignore */
-+		list->addCommentText(buffer);
-+
-+	}
-+	return successful_start;
-+}
-+
-+// returns true if the queue has started, otherwise false.  This
-+// method pops the top object off of the queue.
-+BOOL LLFloaterBulkPermission::popNext()
-+{
-+	// get the first element off of the container, and attempt to get
-+	// the inventory.
-+	BOOL rv = FALSE;
-+	S32 count = mObjectIDs.count();
-+	if(mCurrentObjectID.isNull() && (count > 0))
-+	{
-+		mCurrentObjectID = mObjectIDs.get(0);
-+		llinfos << "LLFloaterBulkPermission::popNext() - mCurrentID: "
-+				<< mCurrentObjectID << llendl;
-+		mObjectIDs.remove(0);
-+		LLViewerObject* obj = gObjectList.findObject(mCurrentObjectID);
-+		if(obj)
-+		{
-+			llinfos << "LLFloaterBulkPermission::popNext() requesting inv for "
-+					<< mCurrentObjectID << llendl;
-+			LLUUID* id = new LLUUID(mID);
-+
-+			registerVOInventoryListener(obj,id);
-+			requestVOInventory();
-+			rv = TRUE;
-+		}
-+		else
-+		{
-+			llinfos<<"LLFloaterBulkPermission::popNext() returned a NULL LLViewerObject" <<llendl;
-+			//Arrrg what do we do here?
-+		}
-+	}
-+
-+	return rv;
-+}
-+
-+
-+// static
-+LLFloaterBulkPermission* LLFloaterBulkPermission::create()
-+{
-+	S32 left, top;
-+	gFloaterView->getNewFloaterPosition(&left, &top);
-+	LLRect rect = gSavedSettings.getRect("CompileOutputRect");
-+	rect.translate(left - rect.mLeft, top - rect.mTop);
-+	LLFloaterBulkPermission* new_queue = new LLFloaterBulkPermission("queue",rect,"Setting Bulk permissions","Results");
-+	new_queue->open();	 /*Flawfinder: ignore*/
-+	return new_queue;
-+}
-+
-+
-+void LLFloaterBulkPermission::handleInventory(LLViewerObject* viewer_obj, InventoryObjectList* inv)
-+{
-+	// find all of the lsl, leaving off duplicates. We'll remove
-+	// all matching asset uuids on compilation success.
-+
-+	llinfos<<"handleInventory"<<llendl;
-+
-+	char buffer[MAX_STRING];		 /*Flawfinder: ignore*/
-+	LLScrollListCtrl* list = getChild<LLScrollListCtrl>("queue output");
-+
-+	InventoryObjectList::const_iterator it = inv->begin();
-+	InventoryObjectList::const_iterator end = inv->end();
-+	for ( ; it != end; ++it)
-+	{
-+		llinfos<<"Doing iterator of inventory"<<llendl;
-+
-+		if(  ( (*it)->getType() == LLAssetType::AT_LSL_TEXT && processScript) ||
-+  		     ( (*it)->getType() == LLAssetType::AT_TEXTURE && processTexture) ||
-+	             ( (*it)->getType() == LLAssetType::AT_SOUND && processSound) ||
-+	             ( (*it)->getType() == LLAssetType::AT_LANDMARK && processLandmark) ||
-+    		     ( (*it)->getType() == LLAssetType::AT_CLOTHING && processClothing) ||
-+    		     ( (*it)->getType() == LLAssetType::AT_OBJECT && processObject) ||
-+   		     ( (*it)->getType() == LLAssetType::AT_NOTECARD && processNotecard) ||
-+   		     ( (*it)->getType() == LLAssetType::AT_BODYPART && processBodypart) ||
-+   		     ( (*it)->getType() == LLAssetType::AT_ANIMATION && processAnimation) ||
-+   		     ( (*it)->getType() == LLAssetType::AT_GESTURE && processGesture))
-+		{
-+
-+			LLViewerObject* object = gObjectList.findObject(viewer_obj->getID());
-+
-+			if (object)
-+			{
-+				LLInventoryItem* item = (LLInventoryItem*)((LLInventoryObject*)(*it));
-+				LLViewerInventoryItem* new_item = (LLViewerInventoryItem*)item;
-+				LLPermissions perm(new_item->getPermissions());
-+
-+				// chomp the inventory name so it fits in the scroll window nicely
-+				// and the user can see the [OK]
-+				std::string invname;
-+				invname=item->getName().substr(0,item->getName().size() < 30 ? item->getName().size() : 30 );
-+				
-+				// My attempt at checking valid permissions, CHECK ME
-+				// note its not actually bad to try to set permissions that are not allowed as the
-+				// server will protect against this, but it will piss the user off if its wrong
-+				if(
-+				(perm.getCreator()==gAgentID) ||
-+				(perm.getMaskOwner() & PERM_TRANSFER) && (perm.getMaskOwner() & PERM_MODIFY) || 
-+				(gAgent.getGroupID()==perm.getGroup() && (perm.getMaskGroup() & PERM_TRANSFER) && (perm.getMaskGroup() & PERM_MODIFY))
-+				){	
-+					llinfos<<"Setting perms"<<llendl;
-+					perm.setMaskNext(req_perm_mask);
-+					new_item->setPermissions(perm);
-+					updateInventory(object,new_item,TASK_INVENTORY_ITEM_KEY,FALSE);				
-+					snprintf(buffer, sizeof(buffer), "Setting perms on '%s' [OK]", invname.c_str());		 	/* Flawfinder: ignore */
-+				}
-+				else
-+				{
-+					llinfos<<"NOT setting perms"<<llendl;
-+					snprintf(buffer, sizeof(buffer), "Setting perms on '%s' [FAILED]", invname.c_str());		 	/* Flawfinder: ignore */
-+
-+				}
-+				
-+				list->addCommentText(buffer);
-+
-+				if(recurse &&  ( (*it)->getType() == LLAssetType::AT_OBJECT && processObject))
-+				{
-+					//Add this object back to the queue to be processed as it has inventory
-+					snprintf(buffer, sizeof(buffer), "Queueing object '%s' for open", invname.c_str());
-+					llwarns << "Queueing object "<<	invname.c_str() << " ID "<< (*it)->getUUID()<<llendl;
-+					mObjectIDs.put((*it)->getUUID());
-+					// This will not YET work. as this is not a viewer object the unpack will fail			
-+				}
-+
-+			}
-+		}
-+	}
-+
-+	nextObject();	
-+}
-+
-+
-+// Avoid inventory callbacks etc by just fire and forgetting the message with the permissions update
-+// we could do this via LLViewerObject::updateInventory but that uses inventory call backs and buggers
-+// us up and we would have a dodgy item iterator
-+
-+void LLFloaterBulkPermission::updateInventory(
-+	LLViewerObject* object,
-+	LLViewerInventoryItem* item,
-+	U8 key,
-+	bool is_new)
-+{
-+	LLMemType mt(LLMemType::MTYPE_OBJECT);
-+	
-+
-+	// This slices the object into what we're concerned about on the
-+	// viewer. The simulator will take the permissions and transfer
-+	// ownership.
-+	LLPointer<LLViewerInventoryItem> task_item =
-+		new LLViewerInventoryItem(item->getUUID(), mID, item->getPermissions(),
-+								  item->getAssetUUID(), item->getType(),
-+								  item->getInventoryType(),
-+								  item->getName(), item->getDescription(),
-+								  item->getSaleInfo(),
-+								  item->getFlags(),
-+								  item->getCreationDate());
-+	task_item->setTransactionID(item->getTransactionID());
-+	LLMessageSystem* msg = gMessageSystem;
-+	msg->newMessageFast(_PREHASH_UpdateTaskInventory);
-+	msg->nextBlockFast(_PREHASH_AgentData);
-+	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
-+	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-+	msg->nextBlockFast(_PREHASH_UpdateData);
-+	msg->addU32Fast(_PREHASH_LocalID, object->mLocalID);
-+	msg->addU8Fast(_PREHASH_Key, key);
-+	msg->nextBlockFast(_PREHASH_InventoryData);
-+	task_item->packMessage(msg);
-+	msg->sendReliable(object->getRegion()->getHost());
-+
-+}
-+
-Index: omvviewer-1.21.0/indra/newview/llfloaterbulkpermission.h
-===================================================================
---- /dev/null	1970-01-01 00:00:00.000000000 +0000
-+++ omvviewer-1.21.0/indra/newview/llfloaterbulkpermission.h	2008-09-01 21:00:09.000000000 +0100
-@@ -0,0 +1,143 @@
-+/** 
-+ * @file llfloaterbulkpermissions.h
-+ * @brief A floater which allows task inventory item's properties to be changed on mass.
-+ *
-+ * $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$
-+ */
-+
-+/* Allow multiple task inventory properties to be set in one go, by Michelle2 Zenovka */
-+
-+#ifndef LL_LLBULKPERMISSION_H
-+#define LL_LLBULKPERMISSION_H
-+
-+#include "lldarray.h"
-+#include "llinventory.h"
-+#include "llviewerobject.h"
-+#include "llvoinventorylistener.h"
-+#include "llmap.h"
-+#include "lluuid.h"
-+
-+#include "llfloater.h"
-+#include "llscrolllistctrl.h"
-+
-+#include "llviewerinventory.h"
-+
-+class LLFloaterBulkPermission : public LLFloater, public LLVOInventoryListener
-+{
-+public:
-+	// addObject() accepts an object id.
-+	void addObject(const LLUUID& id);
-+
-+	// start() returns TRUE if the queue has started, otherwise FALSE.
-+	BOOL start();
-+
-+	// Use this method to create a reset queue. Once created, it
-+	// will be responsible for it's own destruction.
-+	static LLFloaterBulkPermission * create();
-+
-+protected:
-+	LLFloaterBulkPermission(const std::string& name, const LLRect& rect,
-+						 const char* title, const char* start_string);
-+	virtual ~LLFloaterBulkPermission();
-+
-+	// This is the callback method for the viewer object currently
-+	// being worked on.
-+	/*virtual*/ void inventoryChanged(LLViewerObject* obj,
-+								 InventoryObjectList* inv,
-+								 S32 serial_num,
-+								 void* queue);
-+	
-+	// This is called by inventoryChanged
-+	void handleInventory(LLViewerObject* viewer_obj,
-+								InventoryObjectList* inv);
-+
-+
-+	void updateInventory(LLViewerObject* object,
-+								LLViewerInventoryItem* item,
-+								U8 key,
-+								bool is_new);
-+
-+
-+	static void onCloseBtn(void* user_data);
-+	static void onApplyBtn(void* user_data);
-+	static void onCommitPermissions(LLUICtrl* ctrl, void* data);
-+	static void InvSelection(LLUICtrl* ctrl, void* data);
-+	static void onRecurse(LLUICtrl* ctrl, void* data);	
-+	static void onParent(LLUICtrl* ctrl, void* data);
-+
-+	// returns true if this is done
-+	BOOL isDone() const;
-+
-+	//Read the settings and Apply the permissions
-+	void doApply();
-+
-+	// go to the next object. If no objects left, it falls out
-+	// silently and waits to be killed by the deleteIfDone() callback.
-+	BOOL nextObject();
-+	BOOL popNext();
-+
-+	// Get this instances ID.
-+	const LLUUID& getID() const { return mID; } 
-+
-+	// find an instance by ID. Return NULL if it does not exist.
-+	static LLFloaterBulkPermission* findInstance(const LLUUID& id);
-+
-+	U32 req_perm_mask;
-+
-+	BOOL processObject;
-+	BOOL processScript;
-+	BOOL processTexture;
-+	BOOL processSound;
-+	BOOL processAnimation;
-+	BOOL processCallingcard;
-+	BOOL processNotecard;
-+	BOOL processGesture;
-+	BOOL processClothing;
-+	BOOL processBodypart;
-+	BOOL processLandmark;
-+
-+	BOOL recurse;
-+	BOOL parent;
-+
-+protected:
-+	// UI
-+	LLScrollListCtrl* mMessages;
-+	LLButton* mCloseBtn;
-+
-+	// Object Queue
-+	LLDynamicArray<LLUUID> mObjectIDs;
-+	LLUUID mCurrentObjectID;
-+	BOOL mDone;
-+
-+	LLUUID mID;
-+	static LLMap<LLUUID, LLFloaterBulkPermission*> sInstances;
-+
-+	const char* mStartString;
-+
-+};
-+
-+#endif
diff --git a/debian/patches/VWR-5697_fix_startup_paths.diff b/debian/patches/VWR-5697_fix_startup_paths.diff
deleted file mode 100644
index 7772c94..0000000
--- a/debian/patches/VWR-5697_fix_startup_paths.diff
+++ /dev/null
@@ -1,70 +0,0 @@
-#! /bin/sh /usr/share/dpatch/dpatch-run
-## fix startup paths.dpatch by  <root at debian.example.org>
-##
-## All lines beginning with `## DP:' are a description of the patch.
-## DP: No description.
-
- at DPATCH@
-
-Index: ./indra/llvfs/lldir_solaris.cpp
-===================================================================
---- ./indra/llvfs/lldir_solaris.cpp	(revision 367)
-+++ ./indra/llvfs/lldir_solaris.cpp	(working copy)
-@@ -91,7 +91,9 @@
- 	mAppRODataDir = strdup(tmp_str);
- 	mOSUserDir = getCurrentUserHome(tmp_str);
- 	mOSUserAppDir = "";
--	mLindenUserDir = tmp_str;
-+	// Init this to a sensible location it will be updated once we try to login but it could
-+	// be used as a write location before then.
-+	mLindenUserDir = mOSUserDir;
- 
- 	char path [LL_MAX_PATH];	/* Flawfinder: ignore */ 
- 
-Index: ./indra/llvfs/lldir_linux.cpp
-===================================================================
---- ./indra/llvfs/lldir_linux.cpp	(revision 367)
-+++ ./indra/llvfs/lldir_linux.cpp	(working copy)
-@@ -96,8 +96,11 @@
- 	mAppRODataDir = tmp_str;
- 	mOSUserDir = getCurrentUserHome(tmp_str);
- 	mOSUserAppDir = "";
--	mLindenUserDir = tmp_str;
- 
-+	// Init this to a sensible location it will be updated once we try to login but it could
-+	// be used as a write location before then.
-+	mLindenUserDir = mOSUserDir;
-+
- 	char path [32];	/* Flawfinder: ignore */ 
- 
- 	// *NOTE: /proc/%d/exe doesn't work on FreeBSD. But that's ok,
-Index: ./indra/llvfs/lldir_mac.cpp
-===================================================================
---- ./indra/llvfs/lldir_mac.cpp	(revision 367)
-+++ ./indra/llvfs/lldir_mac.cpp	(working copy)
-@@ -168,6 +168,10 @@
- 		
- 		// mOSUserAppDir
- 		mOSUserAppDir = mOSUserDir;
-+
-+		// Init this to a sensible location it will be updated once we try to login but it could
-+		// be used as a write location before then.
-+		mLindenUserDir = mOSUserDir;
- 		
- 		// mTempDir
- 		error = FSFindFolder(kOnAppropriateDisk, kTemporaryFolderType, true, &fileRef);
-Index: ./indra/llvfs/lldir_win32.cpp
-===================================================================
---- ./indra/llvfs/lldir_win32.cpp	(revision 367)
-+++ ./indra/llvfs/lldir_win32.cpp	(working copy)
-@@ -58,6 +58,10 @@
- 
- 	mOSUserDir = utf16str_to_utf8str(llutf16string(w_str));
- 
-+	// Init this to a sensible location it will be updated once we try to login but it could
-+	// be used as a write location before then.
-+	mLindenUserDir = mOSUserDir;
-+
- 	// Local Settings\Application Data is where cache files should
- 	// go, they don't get copied to the server if the user moves his
- 	// profile around on the network. JC
diff --git a/debian/patches/VWR-8194_clamp_outline_for_broken_nvidia.diff b/debian/patches/VWR-8194_clamp_outline_for_broken_nvidia.diff
deleted file mode 100644
index 59b7a68..0000000
--- a/debian/patches/VWR-8194_clamp_outline_for_broken_nvidia.diff
+++ /dev/null
@@ -1,33 +0,0 @@
-#! /bin/sh /usr/share/dpatch/dpatch-run
-## VWR-8194 fix.dpatch by  <robin.cornelius at gmail.com>
-##
-## All lines beginning with `## DP:' are a description of the patch.
-## DP: Clamp selection outline to 660 nodes
-
- at DPATCH@
-
-Index: slviewer/indra/llrender/llrender.cpp
-===================================================================
---- slviewer.orig/indra/llrender/llrender.cpp	2008-09-02 21:12:34.000000000 +0100
-+++ slviewer/indra/llrender/llrender.cpp	2008-09-02 21:12:38.000000000 +0100
-@@ -669,6 +669,9 @@
- 
- void LLRender::texCoord2f(const GLfloat& x, const GLfloat& y)
- { 
-+	if (mCount >= 4096)
-+		return;
-+
- 	mTexcoordsp[mCount] = LLVector2(x,y);
- }
- 
-@@ -684,6 +687,10 @@
- 
- void LLRender::color4ub(const GLubyte& r, const GLubyte& g, const GLubyte& b, const GLubyte& a)
- {
-+
-+	if (mCount >= 4096)
-+		return;
-+
- 	mColorsp[mCount] = LLColor4U(r,g,b,a);
- }
- void LLRender::color4ubv(const GLubyte* c)
diff --git a/debian/patches/VWR-8751-Build-with-a-shared-llmozlib2.patch b/debian/patches/VWR-8751-Build-with-a-shared-llmozlib2.patch
deleted file mode 100644
index d2373f4..0000000
--- a/debian/patches/VWR-8751-Build-with-a-shared-llmozlib2.patch
+++ /dev/null
@@ -1,16 +0,0 @@
---- ./indra/cmake/Mozlib.cmake	2008-08-04 17:52:50.000000000 +0100
-+++ ./indra/cmake/Mozlib.cmake	2008-08-30 15:03:07.000000000 +0100
-@@ -18,13 +18,6 @@
-         link_directories(${CMAKE_SOURCE_DIR}/newview/app_settings/mozilla-runtime-linux-${ARCH})
-         set(MOZLIB_LIBRARIES
-             llmozlib2
--            mozjs
--            nspr4
--            plc4
--            plds4
--            xpcom
--            xul
--            profdirserviceprovider_s
-             )
-     elseif (WINDOWS)
-         if (MSVC71)
diff --git a/debian/patches/VWR-9557-EnableBuildWithNvidiaOrMesaHeaders.patch b/debian/patches/VWR-9557-EnableBuildWithNvidiaOrMesaHeaders.patch
deleted file mode 100644
index 5991d90..0000000
--- a/debian/patches/VWR-9557-EnableBuildWithNvidiaOrMesaHeaders.patch
+++ /dev/null
@@ -1,62 +0,0 @@
-diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
-index 843bc79..42d24bc 100644
---- a/indra/llrender/llgl.cpp
-+++ b/indra/llrender/llgl.cpp
-@@ -252,6 +252,12 @@ PFNWGLSWAPINTERVALEXTPROC			wglSwapIntervalEXT = NULL;
- PFNGLCOLORTABLEEXTPROC glColorTableEXT = NULL;
- #endif // LL_LINUX
- 
-+#if LL_LINUX && defined(WINGDIAPI)
-+PFNGLACTIVETEXTUREARBPROC	glActiveTextureARB=NULL;
-+PFNGLCLIENTACTIVETEXTUREARBPROC	glClientActiveTextureARB=NULL;
-+PFNGLDRAWRANGEELEMENTSPROC 	glDrawRangeElements=NULL;
-+#endif
-+
- #endif
- 
- LLGLManager gGLManager;
-@@ -779,15 +785,21 @@ void LLGLManager::initExtensions()
- 		glGetFramebufferAttachmentParameterivEXT = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glGetFramebufferAttachmentParameterivEXT");
- 		glGenerateMipmapEXT = (PFNGLGENERATEMIPMAPEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glGenerateMipmapEXT");
- 	}
--#if !LL_LINUX
--	// This is expected to be a static symbol on Linux GL implementations
-+#if !LL_LINUX || (LL_LINUX && defined(WINGDIAPI))
-+	// This is expected to be a static symbol on Linux GL implementations, except if we use the nvidia headers
- 	glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC)GLH_EXT_GET_PROC_ADDRESS("glDrawRangeElements");
- 	if (!glDrawRangeElements)
- 	{
- 		mGLMaxVertexRange = 0;
- 		mGLMaxIndexRange = 0;
- 	}
--#endif // !LL_LINUX
-+#endif //!LL_LINUX
-+
-+#if LL_LINUX && defined(WINGDIAPI)
-+	glActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC)GLH_EXT_GET_PROC_ADDRESS("glActiveTextureARB");
-+	glClientActiveTextureARB = (PFNGLCLIENTACTIVETEXTUREARBPROC)GLH_EXT_GET_PROC_ADDRESS("glClientActiveTextureARB");
-+#endif
-+
- #if LL_LINUX
- 	// On Linux we need to get glColorTableEXT dynamically.
- 	if (mHasPalettedTextures)
-diff --git a/indra/llrender/llglheaders.h b/indra/llrender/llglheaders.h
-index f047262..9d04f1c 100644
---- a/indra/llrender/llglheaders.h
-+++ b/indra/llrender/llglheaders.h
-@@ -76,6 +76,15 @@
- #undef Status
- #endif // LL_LINUX && !LL_MESA_HEADLESS
- 
-+#if LL_LINUX && defined(WINGDIAPI)
-+// WINGDIAPI gets set if we are using the linux nvidia gl.h header which needs the 
-+// functions below setting up
-+// Missing functions when using nvidia header
-+extern PFNGLACTIVETEXTUREARBPROC	glActiveTextureARB;
-+extern PFNGLCLIENTACTIVETEXTUREARBPROC	glClientActiveTextureARB;
-+extern PFNGLDRAWRANGEELEMENTSPROC 	glDrawRangeElements;
-+
-+#endif
- 
- // GL_ARB_vertex_buffer_object
- extern PFNGLBINDBUFFERARBPROC		glBindBufferARB;
diff --git a/debian/patches/VWR4070-openjpeg_check_number_of_components.diff b/debian/patches/VWR4070-openjpeg_check_number_of_components.diff
deleted file mode 100644
index af10856..0000000
--- a/debian/patches/VWR4070-openjpeg_check_number_of_components.diff
+++ /dev/null
@@ -1,125 +0,0 @@
-#! /bin/sh /usr/share/dpatch/dpatch-run
-## VWR4070.dpatch by  <root at debian>
-##
-## All lines beginning with `## DP:' are a description of the patch.
-## DP: No description.
-
- at DPATCH@
-
-
-Index: ./indra/llimagej2coj/llimagej2coj.cpp
-===================================================================
---- ./indra/llimagej2coj/llimagej2coj.cpp	(revision 367)
-+++ ./indra/llimagej2coj/llimagej2coj.cpp	(working copy)
-@@ -134,9 +134,15 @@
- 	/* open a byte stream */
- 	cio = opj_cio_open((opj_common_ptr)dinfo, base.getData(), base.getDataSize());
- 
--	/* decode the stream and fill the image structure */
--	image = opj_decode(dinfo, cio);
- 
-+	/* decode the stream and fill the image structure, also fill in an additional
-+	   structure to get the decoding result. This structure is a bit unusual in that
-+	   it is not received through opj, but still has some dynamically allocated fields
-+	   that need to be cleared up at the end by calling a destroy function. */
-+	opj_codestream_info_t cinfo;
-+	memset(&cinfo, 0, sizeof(opj_codestream_info_t));
-+	image = opj_decode_with_info(dinfo, cio, &cinfo);
-+	
- 	/* close the byte stream */
- 	opj_cio_close(cio);
- 
-@@ -146,30 +152,58 @@
- 		opj_destroy_decompress(dinfo);
- 	}
- 
--	// The image decode failed if the return was NULL or the component
--	// count was zero.  The latter is just a sanity check before we
--	// dereference the array.
-+	/* The image decode failed if the return was NULL or the component
-+	   count was zero.  The latter is just a sanity check before we
-+	   dereference the array. */
- 	if(!image || !image->numcomps)
- 	{
- 		fprintf(stderr, "ERROR -> decodeImpl: failed to decode image!\n");
- 		if (image)
-+		{
-+			opj_destroy_cstr_info(&cinfo);
- 			opj_image_destroy(image);
-+		}
- 
- 		return TRUE; // done
- 	}
- 
- 	// sometimes we get bad data out of the cache - check to see if the decode succeeded
--	for (S32 i = 0; i < image->numcomps; i++)
--	{
--		if (image->comps[i].factor != base.getRawDiscardLevel())
-+	int decompdifference = 0;
-+	if (cinfo.numdecompos) // sanity
-+	{	
-+		for (int comp = 0; comp < image->numcomps; comp++)
-+		{	/* get maximum decomposition level difference, first field is from the COD header and the second
-+			   is what is actually met in the codestream, NB: if everything was ok, this calculation will
-+			   return what was set in the cp_reduce value! */
-+			decompdifference = std::max(decompdifference, cinfo.numdecompos[comp] - image->comps[comp].resno_decoded);
-+		}
-+		if (decompdifference < 0) // sanity
- 		{
--			// if we didn't get the discard level we're expecting, fail
--			opj_image_destroy(image);
--			base.mDecoding = FALSE;
--			return TRUE;
-+			decompdifference = 0;
- 		}
- 	}
-+
-+	/* if OpenJPEG failed to decode all requested decomposition levels 
-+	   the difference will be greater than this level */
-+	if (decompdifference > base.getRawDiscardLevel())
-+	{
-+		llwarns << "not enough data for requested discard level, setting mDecoding to FALSE, difference: " << (decompdifference - base.getRawDiscardLevel()) << llendl;
-+		opj_destroy_cstr_info(&cinfo);
-+		opj_image_destroy(image);
-+			
-+		base.mDecoding = FALSE;
-+		return TRUE;
-+	}
- 	
-+	if(image->numcomps <= first_channel)
-+	{
-+		// sanity
-+		llwarns << "trying to decode more channels than are present in image: numcomps: " << image->numcomps << " first_channel: " << first_channel << llendl;
-+		opj_destroy_cstr_info(&cinfo);
-+		opj_image_destroy(image);			
-+		return TRUE;
-+	}
-+
- 	// Copy image data into our raw image format (instead of the separate channel format
- 
- 	S32 img_components = image->numcomps;
-@@ -191,6 +225,7 @@
- 	raw_image.resize(width, height, channels);
- 	U8 *rawp = raw_image.getData();
- 
-+
- 	// first_channel is what channel to start copying from
- 	// dest is what channel to copy to.  first_channel comes from the
- 	// argument, dest always starts writing at channel zero.
-@@ -212,13 +247,15 @@
- 		else // Some rare OpenJPEG versions have this bug.
- 		{
- 			fprintf(stderr, "ERROR -> decodeImpl: failed to decode image! (NULL comp data - OpenJPEG bug)\n");
-+			opj_destroy_cstr_info(&cinfo);
- 			opj_image_destroy(image);
- 
- 			return TRUE; // done
- 		}
- 	}
- 
--	/* free image data structure */
-+	/* free opj data structures */
-+	opj_destroy_cstr_info(&cinfo);
- 	opj_image_destroy(image);
- 
- 	return TRUE; // done
diff --git a/debian/patches/VWR5715_text_not_replaced_by_input_with_japanses_im.diff b/debian/patches/VWR5715_text_not_replaced_by_input_with_japanses_im.diff
deleted file mode 100644
index 0cb83f9..0000000
--- a/debian/patches/VWR5715_text_not_replaced_by_input_with_japanses_im.diff
+++ /dev/null
@@ -1,64 +0,0 @@
-#! /bin/sh /usr/share/dpatch/dpatch-run
-## Selected Text is not replaced by Input text when Japanese IM is on.dpatch by  <root at debian.example.org>
-##
-## All lines beginning with `## DP:' are a description of the patch.
-## DP: Patch by Alissa Sabre
-
- at DPATCH@
-
-Index: linden/indra/llui/lllineeditor.cpp
-===================================================================
---- linden/indra/llui/lllineeditor.cpp	(revision 535)
-+++ linden/indra/llui/lllineeditor.cpp	(revision 536)
-@@ -2315,14 +2315,20 @@
- 
- void LLLineEditor::resetPreedit()
- {
--	if (hasPreeditString())
-+	if (hasSelection())
- 	{
--		if (hasSelection())
-+		if (hasPreeditString())
- 		{
- 			llwarns << "Preedit and selection!" << llendl;
- 			deselect();
- 		}
--
-+		else
-+		{
-+			deleteSelection();
-+		}
-+	}
-+	if (hasPreeditString())
-+	{
- 		const S32 preedit_pos = mPreeditPositions.front();
- 		mText.erase(preedit_pos, mPreeditPositions.back() - preedit_pos);
- 		mText.insert(preedit_pos, mPreeditOverwrittenWString);
-Index: linden/indra/llui/lltexteditor.cpp
-===================================================================
---- linden/indra/llui/lltexteditor.cpp	(revision 535)
-+++ linden/indra/llui/lltexteditor.cpp	(revision 536)
-@@ -4333,14 +4333,20 @@
- 
- void LLTextEditor::resetPreedit()
- {
--	if (hasPreeditString())
-+	if (hasSelection())
- 	{
--		if (hasSelection())
-+		if (hasPreeditString())
- 		{
- 			llwarns << "Preedit and selection!" << llendl;
- 			deselect();
- 		}
--
-+		else
-+		{
-+			deleteSelection(FALSE);
-+		}
-+	}
-+	if (hasPreeditString())
-+	{
- 		mCursorPos = mPreeditPositions.front();
- 		removeStringNoUndo(mCursorPos, mPreeditPositions.back() - mCursorPos);
- 		insertStringNoUndo(mCursorPos, mPreeditOverwrittenWString);
diff --git a/debian/patches/VWR6800_motioncontroller_leak.diff b/debian/patches/VWR6800_motioncontroller_leak.diff
deleted file mode 100644
index 3e22d7a..0000000
--- a/debian/patches/VWR6800_motioncontroller_leak.diff
+++ /dev/null
@@ -1,34 +0,0 @@
-#! /bin/sh /usr/share/dpatch/dpatch-run
-## apply VWR6800.dpatch by  <root at debian>
-##
-## All lines beginning with `## DP:' are a description of the patch.
-## DP: No description.
-
- at DPATCH@
-
-Index: Branch_1-20-Viewer/indra/llcharacter/llmotioncontroller.cpp
-===================================================================
---- Branch_1-20-Viewer.orig/indra/llcharacter/llmotioncontroller.cpp	2008-04-24 00:13:22.000000000 +0200
-+++ Branch_1-20-Viewer/indra/llcharacter/llmotioncontroller.cpp	2008-04-24 00:19:42.000000000 +0200
-@@ -190,6 +190,11 @@
- 
- 	for_each(mAllMotions.begin(), mAllMotions.end(), DeletePairedPointer());
- 	mAllMotions.clear();
-+
-+	// LLMotion instances on this list were removed from the AllMotions map
-+	for_each(mDeprecatedMotions.begin(), mDeprecatedMotions.end(), DeletePointer());
-+	mDeprecatedMotions.clear();
-+	
- }
- 
- //-----------------------------------------------------------------------------
-@@ -379,7 +384,8 @@
- 	if (motion
- 		&& motion->canDeprecate()
- 		&& motion->getFadeWeight() > 0.01f // not LOD-ed out
--		&& (motion->isBlending() || motion->getStopTime() != 0.f))
-+		&& (motion->isBlending() || motion->getStopTime() != 0.f)
-+		&& motion->isActive())
- 	{
- 		deprecateMotionInstance(motion);
- 		// force creation of new instance
diff --git a/debian/patches/add_find_curl_cmake.patch b/debian/patches/add_find_curl_cmake.patch
deleted file mode 100644
index 21abdb3..0000000
--- a/debian/patches/add_find_curl_cmake.patch
+++ /dev/null
@@ -1,66 +0,0 @@
-Index: slviewer/indra/cmake/FindCURL.cmake
-===================================================================
---- /dev/null	1970-01-01 00:00:00.000000000 +0000
-+++ slviewer/indra/cmake/FindCURL.cmake	2008-09-05 16:13:47.000000000 +0100
-@@ -0,0 +1,39 @@
-+# -*- cmake -*-
-+
-+FIND_PATH(CURL_INCLUDE_DIR curl.h
-+/usr/local/include/curl
-+/usr/include/curl
-+)
-+
-+SET(CURL_NAMES ${CURL_NAMES} curl)
-+FIND_LIBRARY(CURL_LIBRARY
-+  NAMES ${CURL_NAMES}
-+  PATHS /usr/lib /usr/local/lib
-+  )
-+
-+IF (CURL_LIBRARY AND CURL_INCLUDE_DIR)
-+    SET(CURL_LIBRARIES ${CURL_LIBRARY})
-+    SET(CURL_FOUND "YES")
-+ELSE (CURL_LIBRARY CURL CURL_INCLUDE_DIR)
-+  SET(CURL_FOUND "NO")
-+ENDIF (CURL_LIBRARY AND CURL_INCLUDE_DIR)
-+
-+IF (CURL_FOUND)
-+   IF (NOT CURL_FIND_QUIETLY)
-+      MESSAGE(STATUS "Found CURL: ${CURL_LIBRARIES}")
-+   ENDIF (NOT CURL_FIND_QUIETLY)
-+ELSE (CURL_FOUND)
-+   IF (CURL_FIND_REQUIRED)
-+      MESSAGE(FATAL_ERROR "Could not find CURL library")
-+   ENDIF (CURL_FIND_REQUIRED)
-+ENDIF (CURL_FOUND)
-+
-+# Deprecated declarations.
-+SET (NATIVE_CURL_INCLUDE_PATH ${CURL_INCLUDE_DIR} )
-+GET_FILENAME_COMPONENT (NATIVE_CURL_LIB_PATH ${CURL_LIBRARY} PATH)
-+
-+MARK_AS_ADVANCED(
-+  CURL_LIBRARY
-+  CURL_INCLUDE_DIR
-+  )
-+
-Index: slviewer/indra/linux_crash_logger/CMakeLists.txt
-===================================================================
---- slviewer.orig/indra/linux_crash_logger/CMakeLists.txt	2008-09-05 16:13:50.000000000 +0100
-+++ slviewer/indra/linux_crash_logger/CMakeLists.txt	2008-09-05 16:13:59.000000000 +0100
-@@ -4,6 +4,8 @@
- 
- include(00-Common)
- include(Boost)
-+include(CURL)
-+include(APR)
- include(LLCommon)
- include(LLCrashLogger)
- include(LLMath)
-@@ -54,6 +56,8 @@
-     ${UI_LIBRARIES}
-     ${BOOST_SIGNALS_LIBRARY}
-     ${DB_LIBRARIES}
-+    ${CURL_LIBRAIES}
-+    ${APR_LIBRARIES}
-     )
- 
- add_custom_command(
diff --git a/debian/patches/dam_flex_2.5.34.diff b/debian/patches/dam_flex_2.5.34.diff
deleted file mode 100644
index 4882c61..0000000
--- a/debian/patches/dam_flex_2.5.34.diff
+++ /dev/null
@@ -1,22 +0,0 @@
-#! /bin/sh /usr/share/dpatch/dpatch-run
-## dam flex 2.5.34.dpatch by  <robin at debian>
-##
-## All lines beginning with `## DP:' are a description of the patch.
-## DP: No description.
-
- at DPATCH@
-
-Index: ./indra/lscript/lscript_compile/indra.l
-===================================================================
---- ./indra/lscript/lscript_compile/indra.l	(revision 178)
-+++ ./indra/lscript/lscript_compile/indra.l	(working copy)
-@@ -4,9 +4,6 @@
- H			[a-fA-F0-9]
- E			[Ee][+-]?{N}+
- FS			(f|F)
--%e 10000
--%n 4000
--%p 5000
- 
- %{
- #include "linden_common.h"
diff --git a/debian/patches/dont_depend_on_artwork_to_build.patch b/debian/patches/dont_depend_on_artwork_to_build.patch
deleted file mode 100644
index 68b8d40..0000000
--- a/debian/patches/dont_depend_on_artwork_to_build.patch
+++ /dev/null
@@ -1,13 +0,0 @@
-Index: slviewer/indra/newview/CMakeLists.txt
-===================================================================
---- slviewer.orig/indra/newview/CMakeLists.txt	2008-09-02 21:39:36.000000000 +0100
-+++ slviewer/indra/newview/CMakeLists.txt	2008-09-02 21:40:11.000000000 +0100
-@@ -1237,7 +1237,7 @@
- set_source_files_properties(${viewer_CHARACTER_FILES}
-                             PROPERTIES HEADER_FILE_ONLY TRUE)
- 
--list(APPEND viewer_SOURCE_FILES ${viewer_CHARACTER_FILES})
-+#list(APPEND viewer_SOURCE_FILES ${viewer_CHARACTER_FILES})
- 
- 
- if (OPENAL)
diff --git a/debian/patches/gcc_warning_on_llwindowsdl_var_not_set.patch b/debian/patches/gcc_warning_on_llwindowsdl_var_not_set.patch
deleted file mode 100644
index 0ea2ec4..0000000
--- a/debian/patches/gcc_warning_on_llwindowsdl_var_not_set.patch
+++ /dev/null
@@ -1,12 +0,0 @@
-Index: slviewer/indra/llwindow/llwindowsdl.cpp
-===================================================================
---- slviewer.orig/indra/llwindow/llwindowsdl.cpp	2008-09-10 12:44:33.000000000 +0100
-+++ slviewer/indra/llwindow/llwindowsdl.cpp	2008-09-10 12:45:21.000000000 +0100
-@@ -2637,6 +2637,7 @@
- 		orig_color.red = guint16(65535 * *r);
- 		orig_color.green= guint16(65535 * *g);
- 		orig_color.blue = guint16(65535 * *b);
-+		orig_color.pixel = -1; //Default this to something or the copy next will produce a gcc warning
- 		color = orig_color;
- 
- 		gtk_color_selection_set_previous_color (colorsel, &color);
diff --git a/debian/patches/glh_linear.patch b/debian/patches/glh_linear.patch
deleted file mode 100644
index bd15af8..0000000
--- a/debian/patches/glh_linear.patch
+++ /dev/null
@@ -1,1627 +0,0 @@
-diff --git a/indra/llwindow/glh/glh_linear.h b/indra/llwindow/glh/glh_linear.h
-new file mode 100755
-index 0000000..04ae1bd
---- /dev/null
-+++ b/indra/llwindow/glh/glh_linear.h
-@@ -0,0 +1,1621 @@
-+/*
-+    glh - is a platform-indepenedent C++ OpenGL helper library 
-+
-+
-+    Copyright (c) 2000 Cass Everitt
-+	Copyright (c) 2000 NVIDIA Corporation
-+    All rights reserved.
-+
-+    Redistribution and use in source and binary forms, with or
-+	without modification, are permitted provided that the following
-+	conditions are met:
-+
-+     * Redistributions of source code must retain the above
-+	   copyright notice, this list of conditions and the following
-+	   disclaimer.
-+
-+     * Redistributions in binary form must reproduce the above
-+	   copyright notice, this list of conditions and the following
-+	   disclaimer in the documentation and/or other materials
-+	   provided with the distribution.
-+
-+     * The names of contributors to this software may not be used
-+	   to endorse or promote products derived from this software
-+	   without specific prior written permission. 
-+
-+       THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-+	   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-+	   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
-+	   FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-+	   REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
-+	   INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
-+	   BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-+	   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-+	   CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-+	   LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
-+	   ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
-+	   POSSIBILITY OF SUCH DAMAGE. 
-+
-+
-+    Cass Everitt - cass at r3.nu
-+*/
-+
-+/*
-+glh_linear.h
-+*/
-+
-+// Author:  Cass W. Everitt
-+
-+#ifndef GLH_LINEAR_H
-+#define GLH_LINEAR_H
-+
-+#include <memory.h>
-+#include <math.h>
-+#include <assert.h>
-+
-+// only supports float for now...
-+#define GLH_REAL_IS_FLOAT
-+
-+#ifdef GLH_REAL_IS_FLOAT
-+# define GLH_REAL float
-+# define GLH_REAL_NAMESPACE ns_float
-+#endif
-+
-+#define     GLH_QUATERNION_NORMALIZATION_THRESHOLD  64
-+
-+#define     GLH_RAD_TO_DEG      GLH_REAL(57.2957795130823208767981548141052)
-+#define     GLH_DEG_TO_RAD      GLH_REAL(0.0174532925199432957692369076848861)
-+#define     GLH_ZERO            GLH_REAL(0.0)
-+#define     GLH_ONE             GLH_REAL(1.0)
-+#define     GLH_TWO             GLH_REAL(2.0)
-+#define     GLH_EPSILON         GLH_REAL(10e-6)
-+#define     GLH_PI              GLH_REAL(3.1415926535897932384626433832795)    
-+
-+#define     equivalent(a,b)     (((a < b + GLH_EPSILON) && (a > b - GLH_EPSILON)) ? true : false)
-+
-+namespace glh
-+{
-+
-+	inline GLH_REAL to_degrees(GLH_REAL radians) { return radians*GLH_RAD_TO_DEG; }
-+	inline GLH_REAL to_radians(GLH_REAL degrees) { return degrees*GLH_DEG_TO_RAD; }
-+
-+	// forward declarations for friend template functions.
-+	template <int N, class T> class vec;
-+	
-+	// forward declarations for friend template functions.
-+	template <int N, class T>
-+		bool operator == ( const vec<N,T> & v1, const vec<N,T> & v2 );
-+	
-+	// forward declarations for friend template functions.
-+	template <int N, class T>
-+		bool operator != ( const vec<N,T> & v1, const vec<N,T> & v2 );
-+
-+	template <int N, class T>	
-+	class vec
-+	{				
-+    public:
-+		int size() const { return N; }
-+		
-+		vec(const T & t = T()) 
-+		{ for(int i = 0; i < N; i++) v[i] = t; }
-+		vec(const T * tp)
-+		{ for(int i = 0; i < N; i++) v[i] = tp[i]; }
-+		
-+		const T * get_value() const
-+		{ return v; }
-+		
-+		
-+		T dot( const vec<N,T> & rhs ) const
-+		{ 
-+			T r = 0;
-+			for(int i = 0; i < N; i++) r += v[i]*rhs.v[i];
-+			return r;
-+		}
-+		
-+		T length() const
-+		{
-+			T r = 0;
-+			for(int i = 0; i < N; i++) r += v[i]*v[i]; 
-+			return T(sqrt(r));
-+		}	
-+		
-+		T square_norm() const
-+		{
-+			T r = 0;
-+			for(int i = 0; i < N; i++) r += v[i]*v[i]; 
-+			return r;
-+		}	
-+		
-+		void  negate()
-+		{ for(int i = 0; i < N; i++) v[i] = -v[i]; }
-+		
-+		
-+		T normalize() 
-+		{ 
-+			T sum(0);
-+			for(int i = 0; i < N; i++) 
-+                sum += v[i]*v[i];
-+			sum = T(sqrt(sum));
-+            if (sum > GLH_EPSILON)
-+			    for(int i = 0; i < N; i++) 
-+                    v[i] /= sum;
-+			return sum;
-+		}
-+		
-+		
-+		vec<N,T> & set_value( const T * rhs )
-+		{ for(int i = 0; i < N; i++) v[i] = rhs[i]; return *this; }
-+		
-+		T & operator [] ( int i )
-+		{ return v[i]; }
-+		
-+		const T & operator [] ( int i ) const
-+		{ return v[i]; }
-+
-+		vec<N,T> & operator *= ( T d )
-+		{ for(int i = 0; i < N; i++) v[i] *= d; return *this;}
-+		
-+		vec<N,T> & operator *= ( const vec<N,T> & u )
-+		{ for(int i = 0; i < N; i++) v[i] *= u[i]; return *this;}
-+		
-+		vec<N,T> & operator /= ( T d )
-+		{ if(d == 0) return *this; for(int i = 0; i < N; i++) v[i] /= d; return *this;}
-+		
-+		vec<N,T> & operator += ( const vec<N,T> & u )
-+		{ for(int i = 0; i < N; i++) v[i] += u.v[i]; return *this;}
-+		
-+		vec<N,T> & operator -= ( const vec<N,T> & u )
-+		{ for(int i = 0; i < N; i++) v[i] -= u.v[i]; return *this;}
-+		
-+		
-+		vec<N,T> operator - () const
-+		{ vec<N,T> rv = v; rv.negate(); return rv; }
-+		
-+		vec<N,T> operator + ( const vec<N,T> &v) const
-+		{ vec<N,T> rt(*this); return rt += v; }
-+		
-+		vec<N,T> operator - ( const vec<N,T> &v) const
-+		{ vec<N,T> rt(*this); return rt -= v; }
-+		
-+		vec<N,T> operator * ( T d) const
-+		{ vec<N,T> rt(*this); return rt *= d; }
-+		
-+		friend bool operator == <> ( const vec<N,T> &v1, const vec<N,T> &v2 );
-+		friend bool operator != <> ( const vec<N,T> &v1, const vec<N,T> &v2 );
-+		
-+		
-+	//protected:
-+		T v[N];
-+	};
-+	
-+	
-+	
-+	// vector friend operators
-+	
-+	template <int N, class T> inline
-+		vec<N,T> operator * ( const vec<N,T> & b, T d )
-+	{
-+		vec<N,T> rt(b);
-+		return rt *= d;
-+	}
-+
-+	template <int N, class T> inline
-+		vec<N,T> operator * ( T d, const vec<N,T> & b )
-+	{ return b*d; }
-+	
-+	template <int N, class T> inline
-+		vec<N,T> operator * ( const vec<N,T> & b, const vec<N,T> & d )
-+	{
-+		vec<N,T> rt(b);
-+		return rt *= d;
-+	}
-+
-+	template <int N, class T> inline
-+		vec<N,T> operator / ( const vec<N,T> & b, T d )
-+	{ vec<N,T> rt(b); return rt /= d; }
-+	
-+	template <int N, class T> inline
-+		vec<N,T> operator + ( const vec<N,T> & v1, const vec<N,T> & v2 )
-+	{ vec<N,T> rt(v1); return rt += v2; }
-+	
-+	template <int N, class T> inline
-+		vec<N,T> operator - ( const vec<N,T> & v1, const vec<N,T> & v2 )
-+	{ vec<N,T> rt(v1); return rt -= v2; }
-+	
-+	
-+	template <int N, class T> inline
-+		bool operator == ( const vec<N,T> & v1, const vec<N,T> & v2 )
-+	{
-+		for(int i = 0; i < N; i++)
-+			if(v1.v[i] != v2.v[i])
-+				return false;
-+			return true;
-+	}
-+	
-+	template <int N, class T> inline
-+		bool operator != ( const vec<N,T> & v1, const vec<N,T> & v2 )
-+	{ return !(v1 == v2); }
-+	
-+
-+	typedef vec<3,unsigned char> vec3ub;
-+	typedef vec<4,unsigned char> vec4ub;
-+
-+
-+
-+
-+
-+	namespace GLH_REAL_NAMESPACE
-+	{
-+	typedef GLH_REAL real;
-+
-+	class line;
-+	class plane;
-+	class matrix4;
-+	class quaternion;
-+	typedef quaternion rotation; 
-+  
-+	class vec2 : public vec<2,real>
-+	{
-+    public:
-+		vec2(const real & t = real()) : vec<2,real>(t)
-+		{}
-+		vec2(const vec<2,real> & t) : vec<2,real>(t)
-+		{}
-+		vec2(const real * tp) : vec<2,real>(tp)
-+		{}
-+		
-+		vec2(real x, real y )
-+		{ v[0] = x; v[1] = y; }
-+		
-+		void get_value(real & x, real & y) const
-+		{ x = v[0]; y = v[1]; }
-+		
-+		vec2 & set_value( const real & x, const real & y)
-+		{ v[0] = x; v[1] = y; return *this; }
-+		
-+	};
-+	
-+	
-+	class vec3 : public vec<3,real>
-+	{
-+    public:
-+		vec3(const real & t = real()) : vec<3,real>(t)
-+		{}
-+		vec3(const vec<3,real> & t) : vec<3,real>(t)
-+		{}
-+		vec3(const real * tp) : vec<3,real>(tp)
-+		{}
-+		
-+		vec3(real x, real y, real z)
-+		{ v[0] = x; v[1] = y; v[2] = z; }
-+		
-+		void get_value(real & x, real & y, real & z) const
-+		{ x = v[0]; y = v[1]; z = v[2]; }
-+		
-+		vec3 cross( const vec3 &rhs ) const
-+		{
-+			vec3 rt;
-+			rt.v[0] = v[1]*rhs.v[2]-v[2]*rhs.v[1];
-+			rt.v[1] = v[2]*rhs.v[0]-v[0]*rhs.v[2];
-+			rt.v[2] = v[0]*rhs.v[1]-v[1]*rhs.v[0];	
-+			return rt;
-+		}
-+		
-+		vec3 & set_value( const real & x, const real & y, const real & z)
-+		{ v[0] = x; v[1] = y; v[2] = z; return *this; }
-+		
-+	};
-+
-+  		
-+    class vec4 : public vec<4,real>
-+    {
-+    public:
-+        vec4(const real & t = real()) : vec<4,real>(t)
-+        {}
-+        vec4(const vec<4,real> & t) : vec<4,real>(t)
-+        {}
-+
-+        vec4(const vec<3,real> & t, real fourth)
-+
-+        { v[0] = t.v[0]; v[1] = t.v[1]; v[2] = t.v[2]; v[3] = fourth; }
-+        vec4(const real * tp) : vec<4,real>(tp)
-+        {}
-+        vec4(real x, real y, real z, real w)
-+        { v[0] = x; v[1] = y; v[2] = z; v[3] = w; }
-+
-+        void get_value(real & x, real & y, real & z, real & w) const
-+        { x = v[0]; y = v[1]; z = v[2]; w = v[3]; }
-+  
-+        vec4 & set_value( const real & x, const real & y, const real & z, const real & w)
-+        { v[0] = x; v[1] = y; v[2] = z; v[3] = w; return *this; }
-+    };
-+
-+    inline
-+    vec3 homogenize(const vec4 & v)
-+    {
-+      vec3 rt;
-+      assert(v.v[3] != GLH_ZERO);
-+      rt.v[0] = v.v[0]/v.v[3];
-+      rt.v[1] = v.v[1]/v.v[3];
-+      rt.v[2] = v.v[2]/v.v[3];
-+      return rt;
-+    }
-+  
-+
-+
-+    class line
-+    {
-+    public:
-+  
-+        line()
-+        { set_value(vec3(0,0,0),vec3(0,0,1)); }
-+
-+        line( const vec3 & p0, const vec3 &p1)
-+        { set_value(p0,p1); }
-+
-+        void set_value( const vec3 &p0, const vec3 &p1)
-+        {
-+          position = p0;
-+          direction = p1-p0;
-+          direction.normalize();
-+        }
-+  
-+        bool get_closest_points(const line &line2, 
-+					          vec3 &pointOnThis,
-+					          vec3 &pointOnThat)
-+        {
-+  
-+          // quick check to see if parallel -- if so, quit.
-+          if(fabs(direction.dot(line2.direction)) == 1.0)
-+	          return 0;
-+          line l2 = line2;
-+  
-+          // Algorithm: Brian Jean
-+          // 
-+          register real u;
-+          register real v;
-+          vec3 Vr = direction;
-+          vec3 Vs = l2.direction;
-+          register real Vr_Dot_Vs = Vr.dot(Vs);
-+          register real detA = real(1.0 - (Vr_Dot_Vs * Vr_Dot_Vs));
-+          vec3 C = l2.position - position;
-+          register real C_Dot_Vr =  C.dot(Vr);
-+          register real C_Dot_Vs =  C.dot(Vs);
-+  
-+          u = (C_Dot_Vr - Vr_Dot_Vs * C_Dot_Vs)/detA;
-+          v = (C_Dot_Vr * Vr_Dot_Vs - C_Dot_Vs)/detA;
-+  
-+          pointOnThis = position;
-+          pointOnThis += direction * u;
-+          pointOnThat = l2.position;
-+          pointOnThat += l2.direction * v;
-+  
-+          return 1;
-+        }
-+  
-+        vec3 get_closest_point(const vec3 &point)
-+        {
-+          vec3 np = point - position;
-+          vec3 rp = direction*direction.dot(np)+position;
-+          return rp;
-+        }
-+  
-+        const vec3 & get_position() const {return position;}
-+
-+        const vec3 & get_direction() const {return direction;}
-+  
-+    //protected:
-+        vec3 position;
-+        vec3 direction;
-+    };
-+  
-+  
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+  
-+  
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+  // matrix
-+
-+  
-+  class matrix4
-+  {
-+    
-+  public:
-+        
-+    matrix4() { make_identity(); }
-+    
-+	matrix4( real r ) 
-+	{ set_value(r); }
-+
-+	matrix4( real * m )
-+	{ set_value(m); }
-+    
-+    matrix4( real a00, real a01, real a02, real a03,
-+	       real a10, real a11, real a12, real a13,
-+		   real a20, real a21, real a22, real a23,
-+		   real a30, real a31, real a32, real a33 )
-+	{
-+		element(0,0) = a00;
-+		element(0,1) = a01;
-+		element(0,2) = a02;
-+		element(0,3) = a03;
-+		
-+		element(1,0) = a10;
-+		element(1,1) = a11;
-+		element(1,2) = a12;
-+		element(1,3) = a13;
-+		
-+		element(2,0) = a20;
-+		element(2,1) = a21;
-+		element(2,2) = a22;
-+		element(2,3) = a23;
-+		
-+		element(3,0) = a30;
-+		element(3,1) = a31;
-+		element(3,2) = a32;
-+		element(3,3) = a33;
-+	}
-+            
-+    
-+    void get_value( real * mp ) const
-+	{
-+		int c = 0;
-+		for(int j=0; j < 4; j++)
-+			for(int i=0; i < 4; i++)
-+				mp[c++] = element(i,j);
-+	}
-+    
-+    
-+    const real * get_value() const
-+	{ return m; }
-+    
-+	void set_value( real * mp)
-+	{
-+		int c = 0;
-+		for(int j=0; j < 4; j++)
-+			for(int i=0; i < 4; i++)
-+				element(i,j) = mp[c++];
-+	}
-+    
-+	void set_value( real r ) 
-+	{
-+		for(int i=0; i < 4; i++)
-+			for(int j=0; j < 4; j++)
-+				element(i,j) = r;
-+	}
-+    
-+    void make_identity()
-+	{
-+		element(0,0) = 1.0;
-+		element(0,1) = 0.0;
-+		element(0,2) = 0.0; 
-+		element(0,3) = 0.0;
-+		
-+		element(1,0) = 0.0;
-+		element(1,1) = 1.0; 
-+		element(1,2) = 0.0;
-+		element(1,3) = 0.0;
-+		
-+		element(2,0) = 0.0;
-+		element(2,1) = 0.0;
-+		element(2,2) = 1.0;
-+		element(2,3) = 0.0;
-+		
-+		element(3,0) = 0.0; 
-+		element(3,1) = 0.0; 
-+		element(3,2) = 0.0;
-+		element(3,3) = 1.0;
-+	}
-+	
-+	
-+    static matrix4 identity()
-+	{
-+		static matrix4 mident (
-+			1.0, 0.0, 0.0, 0.0,
-+			0.0, 1.0, 0.0, 0.0,
-+			0.0, 0.0, 1.0, 0.0,
-+			0.0, 0.0, 0.0, 1.0  );
-+		return mident;
-+	}
-+    
-+        
-+    void set_scale( real s )
-+	{
-+		element(0,0) = s;
-+		element(1,1) = s;
-+		element(2,2) = s;
-+	}
-+    
-+    void set_scale( const vec3 & s )
-+	{
-+		element(0,0) = s.v[0];
-+		element(1,1) = s.v[1];
-+		element(2,2) = s.v[2];
-+	}
-+    
-+    
-+    void set_translate( const vec3 & t )
-+	{
-+		element(0,3) = t.v[0];
-+		element(1,3) = t.v[1];
-+		element(2,3) = t.v[2];
-+	}
-+    
-+	void set_row(int r, const vec4 & t)
-+	{
-+		element(r,0) = t.v[0];
-+		element(r,1) = t.v[1];
-+		element(r,2) = t.v[2];
-+		element(r,3) = t.v[3];
-+	}
-+
-+	void set_column(int c, const vec4 & t)
-+	{
-+		element(0,c) = t.v[0];
-+		element(1,c) = t.v[1];
-+		element(2,c) = t.v[2];
-+		element(3,c) = t.v[3];
-+	}
-+
-+    
-+	void get_row(int r, vec4 & t) const
-+	{
-+		t.v[0] = element(r,0);
-+		t.v[1] = element(r,1);
-+		t.v[2] = element(r,2);
-+		t.v[3] = element(r,3);
-+	}
-+
-+	vec4 get_row(int r) const
-+	{
-+		vec4 v; get_row(r, v);
-+		return v;
-+	}
-+
-+	void get_column(int c, vec4 & t) const
-+	{
-+		t.v[0] = element(0,c);
-+		t.v[1] = element(1,c);
-+		t.v[2] = element(2,c);
-+		t.v[3] = element(3,c);
-+	}
-+
-+	vec4 get_column(int c) const
-+	{
-+		vec4 v; get_column(c, v);
-+		return v;
-+	}
-+
-+    matrix4 inverse() const
-+	{
-+		matrix4 minv;
-+		
-+		real r1[8], r2[8], r3[8], r4[8];
-+		real *s[4], *tmprow;
-+		
-+		s[0] = &r1[0];
-+		s[1] = &r2[0];
-+		s[2] = &r3[0];
-+		s[3] = &r4[0];
-+		
-+		register int i,j,p,jj;
-+		for(i=0;i<4;i++)
-+		{
-+			for(j=0;j<4;j++)
-+			{
-+				s[i][j] = element(i,j);
-+				if(i==j) s[i][j+4] = 1.0;
-+				else     s[i][j+4] = 0.0;
-+			}
-+		}
-+		real scp[4];
-+		for(i=0;i<4;i++)
-+		{
-+			scp[i] = real(fabs(s[i][0]));
-+			for(j=1;j<4;j++)
-+				if(real(fabs(s[i][j])) > scp[i]) scp[i] = real(fabs(s[i][j]));
-+				if(scp[i] == 0.0) return minv; // singular matrix!
-+		}
-+		
-+		int pivot_to;
-+		real scp_max;
-+		for(i=0;i<4;i++)
-+		{
-+			// select pivot row
-+			pivot_to = i;
-+			scp_max = real(fabs(s[i][i]/scp[i]));
-+			// find out which row should be on top
-+			for(p=i+1;p<4;p++)
-+				if(real(fabs(s[p][i]/scp[p])) > scp_max)
-+				{ scp_max = real(fabs(s[p][i]/scp[p])); pivot_to = p; }
-+				// Pivot if necessary
-+				if(pivot_to != i)
-+				{
-+					tmprow = s[i];
-+					s[i] = s[pivot_to];
-+					s[pivot_to] = tmprow;
-+					real tmpscp;
-+					tmpscp = scp[i];
-+					scp[i] = scp[pivot_to];
-+					scp[pivot_to] = tmpscp;
-+				}
-+				
-+				real mji;
-+				// perform gaussian elimination
-+				for(j=i+1;j<4;j++)
-+				{
-+					mji = s[j][i]/s[i][i];
-+					s[j][i] = 0.0;
-+					for(jj=i+1;jj<8;jj++)
-+						s[j][jj] -= mji*s[i][jj];
-+				}
-+		}
-+		if(s[3][3] == 0.0) return minv; // singular matrix!
-+		
-+		//
-+		// Now we have an upper triangular matrix.
-+		//
-+		//  x x x x | y y y y
-+		//  0 x x x | y y y y 
-+		//  0 0 x x | y y y y
-+		//  0 0 0 x | y y y y
-+		//
-+		//  we'll back substitute to get the inverse
-+		//
-+		//  1 0 0 0 | z z z z
-+		//  0 1 0 0 | z z z z
-+		//  0 0 1 0 | z z z z
-+		//  0 0 0 1 | z z z z 
-+		//
-+		
-+		real mij;
-+		for(i=3;i>0;i--)
-+		{
-+			for(j=i-1;j > -1; j--)
-+			{
-+				mij = s[j][i]/s[i][i];
-+				for(jj=j+1;jj<8;jj++)
-+					s[j][jj] -= mij*s[i][jj];
-+			}
-+		}
-+		
-+		for(i=0;i<4;i++)
-+			for(j=0;j<4;j++)
-+				minv(i,j) = s[i][j+4] / s[i][i];
-+			
-+			return minv;
-+	}
-+    
-+    
-+    matrix4 transpose() const
-+	{
-+		matrix4 mtrans;
-+		
-+		for(int i=0;i<4;i++)
-+			for(int j=0;j<4;j++)
-+				mtrans(i,j) = element(j,i);		
-+		return mtrans;
-+	}
-+    
-+    matrix4 & mult_right( const matrix4 & b )
-+	{
-+		matrix4 mt(*this);
-+		set_value(real(0));
-+
-+		for(int i=0; i < 4; i++)
-+			for(int j=0; j < 4; j++)
-+				for(int c=0; c < 4; c++)
-+					element(i,j) += mt(i,c) * b(c,j);
-+		return *this;
-+	}    
-+
-+    matrix4 & mult_left( const matrix4 & b )
-+	{
-+		matrix4 mt(*this);
-+		set_value(real(0));
-+
-+		for(int i=0; i < 4; i++)
-+			for(int j=0; j < 4; j++)
-+				for(int c=0; c < 4; c++)
-+					element(i,j) += b(i,c) * mt(c,j);
-+		return *this;
-+	}
-+	
-+	// dst = M * src
-+    void mult_matrix_vec( const vec3 &src, vec3 &dst ) const
-+	{
-+		real w = (
-+			src.v[0] * element(3,0) +
-+			src.v[1] * element(3,1) + 
-+			src.v[2] * element(3,2) +
-+			element(3,3)          );
-+        
-+        assert(w != GLH_ZERO);
-+
-+        dst.v[0]  = (
-+			src.v[0] * element(0,0) +
-+			src.v[1] * element(0,1) +
-+			src.v[2] * element(0,2) +
-+			element(0,3)          ) / w;
-+		dst.v[1]  = (
-+			src.v[0] * element(1,0) +
-+			src.v[1] * element(1,1) +
-+			src.v[2] * element(1,2) +
-+			element(1,3)          ) / w;
-+		dst.v[2]  = (
-+			src.v[0] * element(2,0) +
-+			src.v[1] * element(2,1) + 
-+			src.v[2] * element(2,2) +
-+			element(2,3)          ) / w;
-+	}
-+    
-+	void mult_matrix_vec( vec3 & src_and_dst) const
-+	{ mult_matrix_vec(vec3(src_and_dst), src_and_dst); }
-+
-+
-+    // dst = src * M
-+    void mult_vec_matrix( const vec3 &src, vec3 &dst ) const
-+	{
-+		real w = (
-+			src.v[0] * element(0,3) +
-+			src.v[1] * element(1,3) +
-+			src.v[2] * element(2,3) +
-+			element(3,3)          );
-+        
-+        assert(w != GLH_ZERO);
-+
-+		dst.v[0]  = (
-+			src.v[0] * element(0,0) +
-+			src.v[1] * element(1,0) + 
-+			src.v[2] * element(2,0) + 
-+			element(3,0)          ) / w;
-+		dst.v[1]  = (
-+			src.v[0] * element(0,1) +
-+			src.v[1] * element(1,1) +
-+			src.v[2] * element(2,1) +
-+			element(3,1)          ) / w;
-+		dst.v[2]  = (
-+			src.v[0] * element(0,2) +
-+			src.v[1] * element(1,2) +
-+			src.v[2] * element(2,2) +
-+			element(3,2)          ) / w;
-+	}
-+        
-+
-+	void mult_vec_matrix( vec3 & src_and_dst) const
-+	{ mult_vec_matrix(vec3(src_and_dst), src_and_dst); }
-+
-+	// dst = M * src
-+    void mult_matrix_vec( const vec4 &src, vec4 &dst ) const
-+	{
-+        dst.v[0]  = (
-+			src.v[0] * element(0,0) +
-+			src.v[1] * element(0,1) +
-+			src.v[2] * element(0,2) +
-+			src.v[3] * element(0,3));
-+		dst.v[1]  = (
-+			src.v[0] * element(1,0) +
-+			src.v[1] * element(1,1) +
-+			src.v[2] * element(1,2) +
-+			src.v[3] * element(1,3));
-+		dst.v[2]  = (
-+			src.v[0] * element(2,0) +
-+			src.v[1] * element(2,1) + 
-+			src.v[2] * element(2,2) +
-+			src.v[3] * element(2,3));
-+		dst.v[3] = (
-+			src.v[0] * element(3,0) +
-+			src.v[1] * element(3,1) + 
-+			src.v[2] * element(3,2) +
-+			src.v[3] * element(3,3));
-+	}
-+    
-+	void mult_matrix_vec( vec4 & src_and_dst) const
-+	{ mult_matrix_vec(vec4(src_and_dst), src_and_dst); }
-+
-+
-+    // dst = src * M
-+    void mult_vec_matrix( const vec4 &src, vec4 &dst ) const
-+	{
-+		dst.v[0]  = (
-+			src.v[0] * element(0,0) +
-+			src.v[1] * element(1,0) + 
-+			src.v[2] * element(2,0) + 
-+			src.v[3] * element(3,0));
-+		dst.v[1]  = (
-+			src.v[0] * element(0,1) +
-+			src.v[1] * element(1,1) +
-+			src.v[2] * element(2,1) +
-+			src.v[3] * element(3,1));
-+		dst.v[2]  = (
-+			src.v[0] * element(0,2) +
-+			src.v[1] * element(1,2) +
-+			src.v[2] * element(2,2) +
-+			src.v[3] * element(3,2));
-+		dst.v[3] = (
-+			src.v[0] * element(0,3) +
-+			src.v[1] * element(1,3) +
-+			src.v[2] * element(2,3) +
-+			src.v[3] * element(3,3));
-+	}
-+        
-+
-+	void mult_vec_matrix( vec4 & src_and_dst) const
-+	{ mult_vec_matrix(vec4(src_and_dst), src_and_dst); }
-+
-+    
-+    // dst = M * src
-+    void mult_matrix_dir( const vec3 &src, vec3 &dst ) const
-+	{
-+		dst.v[0]  = (
-+			src.v[0] * element(0,0) +
-+			src.v[1] * element(0,1) +
-+			src.v[2] * element(0,2) ) ;
-+		dst.v[1]  = ( 
-+			src.v[0] * element(1,0) +
-+			src.v[1] * element(1,1) +
-+			src.v[2] * element(1,2) ) ;
-+		dst.v[2]  = ( 
-+			src.v[0] * element(2,0) +
-+			src.v[1] * element(2,1) + 
-+			src.v[2] * element(2,2) ) ;
-+	}
-+        
-+
-+	void mult_matrix_dir( vec3 & src_and_dst) const
-+	{ mult_matrix_dir(vec3(src_and_dst), src_and_dst); }
-+
-+
-+	// dst = src * M
-+    void mult_dir_matrix( const vec3 &src, vec3 &dst ) const
-+	{
-+		dst.v[0]  = ( 
-+			src.v[0] * element(0,0) +
-+			src.v[1] * element(1,0) +
-+			src.v[2] * element(2,0) ) ;
-+		dst.v[1]  = ( 
-+			src.v[0] * element(0,1) +
-+			src.v[1] * element(1,1) +
-+			src.v[2] * element(2,1) ) ;
-+		dst.v[2]  = (
-+			src.v[0] * element(0,2) +
-+			src.v[1] * element(1,2) + 
-+			src.v[2] * element(2,2) ) ;
-+	}
-+    
-+    
-+	void mult_dir_matrix( vec3 & src_and_dst) const
-+	{ mult_dir_matrix(vec3(src_and_dst), src_and_dst); }
-+
-+
-+    real & operator () (int row, int col)
-+    { return element(row,col); }
-+
-+    const real & operator () (int row, int col) const
-+    { return element(row,col); }
-+
-+	real & element (int row, int col)
-+    { return m[row | (col<<2)]; }
-+
-+    const real & element (int row, int col) const
-+    { return m[row | (col<<2)]; }
-+
-+    matrix4 & operator *= ( const matrix4 & mat )
-+	{
-+		mult_right( mat );
-+		return *this;
-+	}
-+    
-+    matrix4 & operator *= ( const real & r )
-+	{
-+		for (int i = 0; i < 4; ++i)
-+        {
-+            element(0,i) *= r;
-+            element(1,i) *= r;
-+            element(2,i) *= r;
-+            element(3,i) *= r;
-+        }
-+		return *this;
-+	}
-+
-+    matrix4 & operator += ( const matrix4 & mat )
-+	{
-+		for (int i = 0; i < 4; ++i)
-+        {
-+            element(0,i) += mat.element(0,i);
-+            element(1,i) += mat.element(1,i);
-+            element(2,i) += mat.element(2,i);
-+            element(3,i) += mat.element(3,i);
-+        }
-+		return *this;
-+	}
-+
-+    friend matrix4 operator * ( const matrix4 & m1,	const matrix4 & m2 );
-+    friend bool operator == ( const matrix4 & m1, const matrix4 & m2 );
-+    friend bool operator != ( const matrix4 & m1, const matrix4 & m2 );
-+    
-+  //protected:
-+	  real m[16];
-+  };
-+  
-+  inline  
-+  matrix4 operator * ( const matrix4 & m1, const matrix4 & m2 )
-+  {
-+	  matrix4 product;
-+	  
-+	  product = m1;
-+	  product.mult_right(m2);
-+	  
-+	  return product;
-+  }
-+  
-+  inline
-+  bool operator ==( const matrix4 &m1, const matrix4 &m2 )
-+  {
-+	  return ( 
-+		  m1(0,0) == m2(0,0) &&
-+		  m1(0,1) == m2(0,1) &&
-+		  m1(0,2) == m2(0,2) &&
-+		  m1(0,3) == m2(0,3) &&
-+		  m1(1,0) == m2(1,0) &&
-+		  m1(1,1) == m2(1,1) &&
-+		  m1(1,2) == m2(1,2) &&
-+		  m1(1,3) == m2(1,3) &&
-+		  m1(2,0) == m2(2,0) &&
-+		  m1(2,1) == m2(2,1) &&
-+		  m1(2,2) == m2(2,2) &&
-+		  m1(2,3) == m2(2,3) &&
-+		  m1(3,0) == m2(3,0) &&
-+		  m1(3,1) == m2(3,1) &&
-+		  m1(3,2) == m2(3,2) &&
-+		  m1(3,3) == m2(3,3) );
-+  }
-+  
-+  inline
-+  bool operator != ( const matrix4 & m1, const matrix4 & m2 )
-+  { return !( m1 == m2 ); }  
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+
-+  
-+    class quaternion
-+    {
-+    public:
-+    
-+    quaternion()
-+    {
-+        *this = identity();
-+    }
-+
-+    quaternion( const real v[4] )
-+    {
-+        set_value( v );
-+    }
-+
-+
-+    quaternion( real q0, real q1, real q2, real q3 )
-+    {
-+        set_value( q0, q1, q2, q3 );
-+    }
-+
-+
-+    quaternion( const matrix4 & m )
-+    {
-+        set_value( m );
-+    }
-+
-+
-+    quaternion( const vec3 &axis, real radians )
-+    {
-+        set_value( axis, radians );
-+    }
-+
-+
-+    quaternion( const vec3 &rotateFrom, const vec3 &rotateTo )
-+    {
-+        set_value( rotateFrom, rotateTo );
-+    }
-+
-+    quaternion( const vec3 & from_look, const vec3 & from_up,
-+		      const vec3 & to_look, const vec3& to_up)
-+    {
-+	    set_value(from_look, from_up, to_look, to_up);
-+    }
-+
-+    const real * get_value() const
-+    {
-+        return  &q[0];
-+    }
-+
-+    void get_value( real &q0, real &q1, real &q2, real &q3 ) const
-+    {
-+        q0 = q[0];
-+        q1 = q[1];
-+        q2 = q[2];
-+        q3 = q[3];
-+    }
-+
-+    quaternion & set_value( real q0, real q1, real q2, real q3 )
-+    {
-+        q[0] = q0;
-+        q[1] = q1;
-+        q[2] = q2;
-+        q[3] = q3;
-+        counter = 0;
-+        return *this;
-+    }
-+
-+    void get_value( vec3 &axis, real &radians ) const
-+    {
-+        radians = real(acos( q[3] ) * GLH_TWO);
-+        if ( radians == GLH_ZERO )
-+            axis = vec3( 0.0, 0.0, 1.0 );
-+        else
-+        {
-+            axis.v[0] = q[0];
-+            axis.v[1] = q[1];
-+            axis.v[2] = q[2];
-+            axis.normalize();
-+        }
-+    }
-+
-+    void get_value( matrix4 & m ) const
-+    {
-+        real s, xs, ys, zs, wx, wy, wz, xx, xy, xz, yy, yz, zz;
-+
-+        real norm = q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3];
-+
-+        s = (equivalent(norm,GLH_ZERO)) ? GLH_ZERO : ( GLH_TWO / norm );
-+
-+        xs = q[0] * s;
-+        ys = q[1] * s;
-+        zs = q[2] * s;
-+
-+        wx = q[3] * xs;
-+        wy = q[3] * ys;
-+        wz = q[3] * zs;
-+
-+        xx = q[0] * xs;
-+        xy = q[0] * ys;
-+        xz = q[0] * zs;
-+
-+        yy = q[1] * ys;
-+        yz = q[1] * zs;
-+        zz = q[2] * zs;
-+
-+        m(0,0) = real( GLH_ONE - ( yy + zz ));
-+        m(1,0) = real ( xy + wz );
-+        m(2,0) = real ( xz - wy );
-+
-+        m(0,1) = real ( xy - wz );
-+        m(1,1) = real ( GLH_ONE - ( xx + zz ));
-+        m(2,1) = real ( yz + wx );
-+
-+        m(0,2) = real ( xz + wy );
-+        m(1,2) = real ( yz - wx );
-+        m(2,2) = real ( GLH_ONE - ( xx + yy ));
-+
-+        m(3,0) = m(3,1) = m(3,2) = m(0,3) = m(1,3) = m(2,3) = GLH_ZERO;
-+        m(3,3) = GLH_ONE;
-+    }
-+
-+    quaternion & set_value( const real * qp )
-+    {
-+        memcpy(q,qp,sizeof(real) * 4);
-+
-+        counter = 0;
-+        return *this;
-+    }
-+
-+    quaternion & set_value( const matrix4 & m )
-+    {
-+        real tr, s;
-+        int i, j, k;
-+        const int nxt[3] = { 1, 2, 0 };
-+
-+        tr = m(0,0) + m(1,1) + m(2,2);
-+
-+        if ( tr > GLH_ZERO )
-+        {
-+            s = real(sqrt( tr + m(3,3) ));
-+            q[3] = real ( s * 0.5 );
-+            s = real(0.5) / s;
-+
-+            q[0] = real ( ( m(1,2) - m(2,1) ) * s );
-+            q[1] = real ( ( m(2,0) - m(0,2) ) * s );
-+            q[2] = real ( ( m(0,1) - m(1,0) ) * s );
-+        }
-+        else
-+        {
-+            i = 0;
-+            if ( m(1,1) > m(0,0) )
-+              i = 1;
-+
-+            if ( m(2,2) > m(i,i) )
-+              i = 2;
-+
-+            j = nxt[i];
-+            k = nxt[j];
-+
-+            s = real(sqrt( ( m(i,j) - ( m(j,j) + m(k,k) )) + GLH_ONE ));
-+
-+            q[i] = real ( s * 0.5 );
-+            s = real(0.5 / s);
-+
-+            q[3] = real ( ( m(j,k) - m(k,j) ) * s );
-+            q[j] = real ( ( m(i,j) + m(j,i) ) * s );
-+            q[k] = real ( ( m(i,k) + m(k,i) ) * s );
-+        }
-+
-+        counter = 0;
-+        return *this;
-+    }
-+
-+    quaternion & set_value( const vec3 &axis, real theta )
-+    {
-+        real sqnorm = axis.square_norm();
-+
-+        if (sqnorm <= GLH_EPSILON)
-+        {
-+            // axis too small.
-+            x = y = z = 0.0;
-+            w = 1.0;
-+        } 
-+        else 
-+        {
-+            theta *= real(0.5);
-+            real sin_theta = real(sin(theta));
-+
-+            if (!equivalent(sqnorm,GLH_ONE)) 
-+              sin_theta /= real(sqrt(sqnorm));
-+            x = sin_theta * axis.v[0];
-+            y = sin_theta * axis.v[1];
-+            z = sin_theta * axis.v[2];
-+            w = real(cos(theta));
-+        }
-+        return *this;
-+    }
-+
-+    quaternion & set_value( const vec3 & rotateFrom, const vec3 & rotateTo )
-+    {
-+        vec3 p1, p2;
-+        real alpha;
-+
-+        p1 = rotateFrom; 
-+        p1.normalize();
-+        p2 = rotateTo;  
-+        p2.normalize();
-+
-+        alpha = p1.dot(p2);
-+
-+        if(equivalent(alpha,GLH_ONE))
-+        { 
-+            *this = identity(); 
-+            return *this; 
-+        }
-+
-+        // ensures that the anti-parallel case leads to a positive dot
-+        if(equivalent(alpha,-GLH_ONE))
-+        {
-+            vec3 v;
-+
-+            if(p1.v[0] != p1.v[1] || p1.v[0] != p1.v[2])
-+    	        v = vec3(p1.v[1], p1.v[2], p1.v[0]);
-+            else
-+    	        v = vec3(-p1.v[0], p1.v[1], p1.v[2]);
-+
-+            v -= p1 * p1.dot(v);
-+            v.normalize();
-+
-+            set_value(v, GLH_PI);
-+            return *this;
-+        }
-+
-+        p1 = p1.cross(p2);  
-+        p1.normalize();
-+        set_value(p1,real(acos(alpha)));
-+
-+        counter = 0;
-+        return *this;
-+    }
-+
-+    quaternion & set_value( const vec3 & from_look, const vec3 & from_up,
-+		      const vec3 & to_look, const vec3 & to_up)
-+    {
-+	    quaternion r_look = quaternion(from_look, to_look);
-+	    
-+	    vec3 rotated_from_up(from_up);
-+	    r_look.mult_vec(rotated_from_up);
-+	    
-+	    quaternion r_twist = quaternion(rotated_from_up, to_up);
-+	    
-+	    *this = r_twist;
-+	    *this *= r_look;
-+	    return *this;
-+    }
-+
-+    quaternion & operator *= ( const quaternion & qr )
-+    {
-+        quaternion ql(*this);
-+   
-+        w = ql.w * qr.w - ql.x * qr.x - ql.y * qr.y - ql.z * qr.z;
-+        x = ql.w * qr.x + ql.x * qr.w + ql.y * qr.z - ql.z * qr.y;
-+        y = ql.w * qr.y + ql.y * qr.w + ql.z * qr.x - ql.x * qr.z;
-+        z = ql.w * qr.z + ql.z * qr.w + ql.x * qr.y - ql.y * qr.x;
-+
-+        counter += qr.counter;
-+        counter++;
-+        counter_normalize();
-+        return *this;
-+    }
-+
-+    void normalize()
-+    {
-+        real rnorm = GLH_ONE / real(sqrt(w * w + x * x + y * y + z * z));
-+        if (equivalent(rnorm, GLH_ZERO))
-+            return;
-+        x *= rnorm;
-+        y *= rnorm;
-+        z *= rnorm;
-+        w *= rnorm;
-+        counter = 0;
-+    }
-+
-+    friend bool operator == ( const quaternion & q1, const quaternion & q2 );      
-+
-+    friend bool operator != ( const quaternion & q1, const quaternion & q2 );
-+
-+    friend quaternion operator * ( const quaternion & q1, const quaternion & q2 );
-+
-+    bool equals( const quaternion & r, real tolerance ) const
-+    {
-+        real t;
-+
-+        t = (
-+			(q[0]-r.q[0])*(q[0]-r.q[0]) +
-+            (q[1]-r.q[1])*(q[1]-r.q[1]) +
-+            (q[2]-r.q[2])*(q[2]-r.q[2]) +
-+            (q[3]-r.q[3])*(q[3]-r.q[3]) );
-+        if(t > GLH_EPSILON) 
-+            return false;
-+        return 1;
-+    }
-+
-+    quaternion & conjugate()
-+    {
-+        q[0] *= -GLH_ONE;
-+        q[1] *= -GLH_ONE;
-+        q[2] *= -GLH_ONE;
-+        return *this;
-+    }
-+
-+    quaternion & invert()
-+    {
-+        return conjugate();
-+    }
-+
-+    quaternion inverse() const
-+    {
-+        quaternion r = *this;
-+        return r.invert();
-+    }
-+
-+    //
-+    // Quaternion multiplication with cartesian vector
-+    // v' = q*v*q(star)
-+    //
-+    void mult_vec( const vec3 &src, vec3 &dst ) const
-+    {
-+        real v_coef = w * w - x * x - y * y - z * z;                     
-+        real u_coef = GLH_TWO * (src.v[0] * x + src.v[1] * y + src.v[2] * z);  
-+        real c_coef = GLH_TWO * w;                                       
-+
-+        dst.v[0] = v_coef * src.v[0] + u_coef * x + c_coef * (y * src.v[2] - z * src.v[1]);
-+        dst.v[1] = v_coef * src.v[1] + u_coef * y + c_coef * (z * src.v[0] - x * src.v[2]);
-+        dst.v[2] = v_coef * src.v[2] + u_coef * z + c_coef * (x * src.v[1] - y * src.v[0]);
-+    }
-+
-+    void mult_vec( vec3 & src_and_dst) const
-+    {
-+        mult_vec(vec3(src_and_dst), src_and_dst);
-+    }
-+
-+    void scale_angle( real scaleFactor )
-+    {
-+        vec3 axis;
-+        real radians;
-+
-+        get_value(axis, radians);
-+        radians *= scaleFactor;
-+        set_value(axis, radians);
-+    }
-+
-+    static quaternion slerp( const quaternion & p, const quaternion & q, real alpha )
-+    {
-+        quaternion r;
-+
-+        real cos_omega = p.x * q.x + p.y * q.y + p.z * q.z + p.w * q.w;
-+        // if B is on opposite hemisphere from A, use -B instead
-+      
-+        int bflip;
-+        if ( ( bflip = (cos_omega < GLH_ZERO)) )
-+            cos_omega = -cos_omega;
-+
-+        // complementary interpolation parameter
-+        real beta = GLH_ONE - alpha;     
-+
-+        if(cos_omega <= GLH_ONE - GLH_EPSILON)
-+            return p;
-+
-+        real omega = real(acos(cos_omega));
-+        real one_over_sin_omega = GLH_ONE / real(sin(omega));
-+
-+        beta    = real(sin(omega*beta)  * one_over_sin_omega);
-+        alpha   = real(sin(omega*alpha) * one_over_sin_omega);
-+
-+        if (bflip)
-+            alpha = -alpha;
-+
-+        r.x = beta * p.q[0]+ alpha * q.q[0];
-+        r.y = beta * p.q[1]+ alpha * q.q[1];
-+        r.z = beta * p.q[2]+ alpha * q.q[2];
-+        r.w = beta * p.q[3]+ alpha * q.q[3];
-+        return r;
-+    }
-+
-+    static quaternion identity()
-+    {
-+        static quaternion ident( vec3( 0.0, 0.0, 0.0 ), GLH_ONE );
-+        return ident;
-+    }
-+
-+    real & operator []( int i )
-+    {
-+        assert(i < 4);
-+        return q[i];
-+    }
-+
-+    const real & operator []( int i ) const
-+    {
-+        assert(i < 4);
-+        return q[i];
-+    }
-+
-+    protected:
-+
-+        void counter_normalize()
-+        {
-+            if (counter > GLH_QUATERNION_NORMALIZATION_THRESHOLD)
-+                normalize();
-+        }
-+
-+        union 
-+        {
-+            struct 
-+            {
-+                real q[4];
-+            };
-+            struct 
-+            {
-+                real x;
-+                real y;
-+                real z;
-+                real w;
-+            };
-+        };
-+
-+        // renormalization counter
-+        unsigned char counter;
-+    };
-+
-+    inline
-+    bool operator == ( const quaternion & q1, const quaternion & q2 )
-+    {
-+        return (equivalent(q1.x, q2.x) &&
-+		        equivalent(q1.y, q2.y) &&
-+		        equivalent(q1.z, q2.z) &&
-+		        equivalent(q1.w, q2.w) );
-+    }
-+
-+    inline
-+    bool operator != ( const quaternion & q1, const quaternion & q2 )
-+    { 
-+        return ! ( q1 == q2 ); 
-+    }
-+
-+    inline
-+    quaternion operator * ( const quaternion & q1, const quaternion & q2 )
-+    {	
-+        quaternion r(q1); 
-+        r *= q2; 
-+        return r; 
-+    }
-+  
-+      
-+    
-+
-+
-+
-+
-+
-+  
-+  
-+  class plane
-+  {
-+  public:
-+	  
-+	  plane()
-+      {
-+		  planedistance = 0.0;
-+		  planenormal.set_value( 0.0, 0.0, 1.0 );
-+      }
-+	  
-+	  
-+	  plane( const vec3 &p0, const vec3 &p1, const vec3 &p2 )
-+      {
-+		  vec3 v0 = p1 - p0;
-+		  vec3 v1 = p2 - p0;
-+		  planenormal = v0.cross(v1);  
-+		  planenormal.normalize();
-+		  planedistance = p0.dot(planenormal);
-+      }
-+	  
-+	  plane( const vec3 &normal, real distance )
-+      {
-+		  planedistance = distance;
-+		  planenormal = normal;
-+		  planenormal.normalize();
-+      }
-+	  
-+	  plane( const vec3 &normal, const vec3 &point )
-+      {
-+		  planenormal = normal;
-+		  planenormal.normalize();
-+		  planedistance = point.dot(planenormal);
-+      }
-+	  
-+	  void offset( real d )
-+      {
-+		  planedistance += d;
-+      }
-+	  
-+	  bool intersect( const line &l, vec3 &intersection ) const
-+      {
-+		  vec3 pos, dir;
-+		  vec3 pn = planenormal;
-+		  real pd = planedistance;
-+		  
-+		  pos = l.get_position();
-+		  dir = l.get_direction();
-+		  
-+		  if(dir.dot(pn) == 0.0) return 0;
-+		  pos -= pn*pd;
-+		  // now we're talking about a plane passing through the origin
-+		  if(pos.dot(pn) < 0.0) pn.negate();
-+		  if(dir.dot(pn) > 0.0) dir.negate();
-+		  vec3 ppos = pn * pos.dot(pn);
-+		  pos = (ppos.length()/dir.dot(-pn))*dir;
-+		  intersection = l.get_position();
-+		  intersection += pos;
-+		  return 1;
-+      }
-+	  void transform( const matrix4 &matrix )
-+      {
-+		  matrix4 invtr = matrix.inverse();
-+		  invtr = invtr.transpose();
-+		  
-+		  vec3 pntOnplane = planenormal * planedistance;
-+		  vec3 newPntOnplane;
-+		  vec3 newnormal;
-+		  
-+		  invtr.mult_dir_matrix(planenormal, newnormal);
-+		  matrix.mult_vec_matrix(pntOnplane, newPntOnplane);
-+		  
-+		  newnormal.normalize();
-+		  planenormal = newnormal;
-+		  planedistance = newPntOnplane.dot(planenormal);
-+      }
-+	  
-+	  bool is_in_half_space( const vec3 &point ) const
-+      {
-+		  
-+		  if(( point.dot(planenormal) - planedistance) < 0.0)
-+			  return 0;
-+		  return 1;
-+      }
-+	  
-+	  
-+	  real distance( const vec3 & point ) const 
-+      {
-+		  return planenormal.dot(point - planenormal*planedistance);
-+      }
-+	  
-+	  const vec3 &get_normal() const
-+      {
-+		  return planenormal;
-+      }
-+	  
-+	  
-+	  real get_distance_from_origin() const
-+      {
-+		  return planedistance;
-+      }
-+	  
-+	  
-+	  friend bool operator == ( const plane & p1, const plane & p2 );
-+	  
-+	  
-+	  friend bool operator != ( const plane & p1, const plane & p2 );
-+	  
-+  //protected:
-+	  vec3 planenormal;
-+	  real planedistance;
-+  };
-+  
-+  inline
-+  bool operator == (const plane & p1, const plane & p2 )
-+  {
-+	  return (  p1.planedistance == p2.planedistance && p1.planenormal == p2.planenormal);
-+  }
-+  
-+  inline
-+  bool operator != ( const plane & p1, const plane & p2 )
-+  { return  ! (p1 == p2); }
-+  
-+  
-+
-+  } // "ns_##GLH_REAL"
-+
-+  // make common typedefs...
-+#ifdef GLH_REAL_IS_FLOAT
-+  typedef GLH_REAL_NAMESPACE::vec2 vec2f;
-+  typedef GLH_REAL_NAMESPACE::vec3 vec3f;
-+  typedef GLH_REAL_NAMESPACE::vec4 vec4f;
-+  typedef GLH_REAL_NAMESPACE::quaternion quaternionf;
-+  typedef GLH_REAL_NAMESPACE::quaternion rotationf;
-+  typedef GLH_REAL_NAMESPACE::line linef;
-+  typedef GLH_REAL_NAMESPACE::plane planef;
-+  typedef GLH_REAL_NAMESPACE::matrix4 matrix4f;
-+#endif
-+
-+  
-+
-+
-+}  // namespace glh
-+
-+
-+
-+#endif
-+
diff --git a/debian/patches/linux_joystick.patch b/debian/patches/linux_joystick.patch
deleted file mode 100644
index 9db597c..0000000
--- a/debian/patches/linux_joystick.patch
+++ /dev/null
@@ -1,60 +0,0 @@
-Index: slviewer/indra/cmake/NDOF.cmake
-===================================================================
---- slviewer.orig/indra/cmake/NDOF.cmake	2008-09-24 11:43:23.000000000 +0200
-+++ slviewer/indra/cmake/NDOF.cmake	2008-09-24 11:44:02.000000000 +0200
-@@ -3,12 +3,12 @@
- 
- use_prebuilt_binary(ndofdev)
- 
--if (WINDOWS OR DARWIN)
-+if (WINDOWS OR DARWIN OR LINUX)
-   add_definitions(-DLIB_NDOF=1)
--endif (WINDOWS OR DARWIN)
-+endif (WINDOWS OR DARWIN OR LINUX)
- 
- if (WINDOWS)
-   set(NDOF_LIBRARY libndofdev)
--elseif (DARWIN)
-+elseif (DARWIN OR LINUX)
-   set(NDOF_LIBRARY ndofdev)
- endif (WINDOWS)
-Index: slviewer/indra/newview/llviewerjoystick.cpp
-===================================================================
---- slviewer.orig/indra/newview/llviewerjoystick.cpp	2008-09-24 11:44:28.000000000 +0200
-+++ slviewer/indra/newview/llviewerjoystick.cpp	2008-09-24 11:48:05.000000000 +0200
-@@ -973,7 +973,7 @@
- // -----------------------------------------------------------------------------
- void LLViewerJoystick::setSNDefaults()
- {
--#if LL_DARWIN 
-+#if LL_DARWIN || LL_LINUX
- #define kPlatformScale	20.f
- #else
- #define kPlatformScale	1.f
-@@ -990,8 +990,8 @@
- 	gSavedSettings.setS32("JoystickAxis5", 5); // yaw
- 	gSavedSettings.setS32("JoystickAxis6", -1);
- 	
--#if LL_DARWIN
--	// The SpaceNavigator doesn't act as a 3D cursor on OS X. 
-+#if LL_DARWIN || LL_LINUX
-+	// The SpaceNavigator doesn't act as a 3D cursor on OS X / Linux.
- 	gSavedSettings.setBOOL("Cursor3D", false);
- #else
- 	gSavedSettings.setBOOL("Cursor3D", true);
-Index: slviewer/install.xml
-===================================================================
---- slviewer.orig/install.xml	2008-09-24 11:42:25.000000000 +0200
-+++ slviewer/install.xml	2008-09-24 11:43:02.000000000 +0200
-@@ -773,9 +773,9 @@
-           <key>linux</key>
-           <map>
-             <key>md5sum</key>
--            <string>489612b246b2f4b2f239611d786c79de</string>
-+            <string>9469c3732a33a154fa0a2807b9f36ccc</string>
-             <key>url</key>
--            <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/ndofdev-linux-20080618.tar.bz2</uri>
-+			<uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/ndofdev-linux-0.2-20080828.tar.bz2</uri>
-           </map>
-           <key>windows</key>
-           <map>
diff --git a/debian/patches/lltemplatemessagereader_memcpy.patch b/debian/patches/lltemplatemessagereader_memcpy.patch
deleted file mode 100644
index fc39f62..0000000
--- a/debian/patches/lltemplatemessagereader_memcpy.patch
+++ /dev/null
@@ -1,14 +0,0 @@
-Index: slviewer/indra/llmessage/lltemplatemessagereader.cpp
-===================================================================
---- slviewer.orig/indra/llmessage/lltemplatemessagereader.cpp	2008-09-06 15:49:20.000000000 +0100
-+++ slviewer/indra/llmessage/lltemplatemessagereader.cpp	2008-09-06 15:50:46.000000000 +0100
-@@ -676,7 +676,8 @@
- 						// default to 0s.
- 						U32 size = mvci.getSize();
- 						std::vector<U8> data(size);
--						memset(&(data[0]), 0, size);
-+						if(size>0)
-+							memset(&(data[0]), 0, size);
- 						cur_data_block->addData(mvci.getName(), &(data[0]), 
- 												size, mvci.getType());
- 					}
diff --git a/debian/patches/no_old_school_typedefs.patch b/debian/patches/no_old_school_typedefs.patch
deleted file mode 100644
index 06e03d3..0000000
--- a/debian/patches/no_old_school_typedefs.patch
+++ /dev/null
@@ -1,13 +0,0 @@
-Index: slviewer/indra/llrender/llrender.h
-===================================================================
---- slviewer.orig/indra/llrender/llrender.h	2008-09-05 12:18:03.000000000 +0100
-+++ slviewer/indra/llrender/llrender.h	2008-09-05 12:18:25.000000000 +0100
-@@ -213,7 +213,7 @@
- 
- 	LLTexUnit* getTexUnit(U32 index);
- 
--	typedef struct Vertex
-+	struct Vertex
- 	{
- 		GLfloat v[3];
- 		GLubyte c[4];
diff --git a/debian/patches/openal_1.21.0.diff b/debian/patches/openal_1.21.0.diff
deleted file mode 100644
index 7e38e2d..0000000
--- a/debian/patches/openal_1.21.0.diff
+++ /dev/null
@@ -1,1051 +0,0 @@
-Index: slviewer/indra/llaudio/audioengine.cpp
-===================================================================
---- slviewer.orig/indra/llaudio/audioengine.cpp	2008-09-05 13:13:58.000000000 +0100
-+++ slviewer/indra/llaudio/audioengine.cpp	2008-09-05 13:43:07.000000000 +0100
-@@ -111,6 +111,8 @@
- 	// Initialize the decode manager
- 	gAudioDecodeMgrp = new LLAudioDecodeMgr;
- 
-+	llinfos << "LLAudioEngine::init() AudioEngine successfully initialized" << llendl;
-+
- 	return TRUE;
- }
- 
-@@ -1336,7 +1338,11 @@
- BOOL LLAudioSource::isDone()
- {
- 	const F32 MAX_AGE = 60.f;
-+#if LL_OPENAL
-+	const F32 MAX_UNPLAYED_AGE = 30.f;
-+#else
- 	const F32 MAX_UNPLAYED_AGE = 15.f;
-+#endif
- 	if (isLoop())
- 	{
- 		// Looped sources never die on their own.
-Index: slviewer/indra/llaudio/audioengine.h
-===================================================================
---- slviewer.orig/indra/llaudio/audioengine.h	2008-09-05 13:13:59.000000000 +0100
-+++ slviewer/indra/llaudio/audioengine.h	2008-09-05 13:43:07.000000000 +0100
-@@ -159,6 +159,10 @@
- 	static void assetCallback(LLVFS *vfs, const LLUUID &uuid, LLAssetType::EType type, void *user_data, S32 result_code, LLExtStat ext_status);
- 
- 
-+	#if LL_OPENAL
-+		virtual void InitStreamer() = 0;
-+	#endif
-+
- 	friend class LLPipeline; // For debugging
- public:
- 	F32 mMaxWindGain; // Hack.  Public to set before fade in?
-Index: slviewer/indra/llaudio/audioengine_openal.cpp
-===================================================================
---- /dev/null	1970-01-01 00:00:00.000000000 +0000
-+++ slviewer/indra/llaudio/audioengine_openal.cpp	2008-09-05 13:43:07.000000000 +0100
-@@ -0,0 +1,618 @@
-+/**
-+ * @file audioengine_openal.cpp
-+ * @brief implementation of audio engine using OpenAL
-+ * support as a OpenAL 3D implementation
-+ *
-+ * Copyright (c) 2002-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://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.
-+ */
-+
-+#include "linden_common.h"
-+
-+#include "audioengine_openal.h"
-+#include "listener_openal.h"
-+
-+
-+#if LL_OPENAL_WIND
-+// Variables and definitions for Wind
-+#define NO_WIND_BUFFERS 20
-+static ALuint wind_buffers[NO_WIND_BUFFERS];
-+static ALuint wind_sources[1];
-+static S16 *winddata=NULL;
-+
-+static BOOL first_wind=TRUE;
-+
-+ALfloat source0Vel[]={ 0.0, 0.0, 0.0};
-+
-+// These globals for the wind filter.  Blech!
-+F64 gbuf0 = 0.0;
-+F64 gbuf1 = 0.0;
-+F64 gbuf2 = 0.0;
-+F64 gbuf3 = 0.0;
-+F64 gbuf4 = 0.0;
-+F64 gbuf5 = 0.0;
-+F64 gY0 = 0.0;
-+F64 gY1 = 0.0;
-+
-+F32 gTargetGain = 0.f;
-+F32 gCurrentGain = 0.f;
-+F32 gTargetFreq = 100.f;
-+F32 gCurrentFreq = 100.f;
-+F32 gTargetPanGainR = 0.5f;
-+F32 gCurrentPanGainR = 0.5f;
-+#endif // LL_OPENAL_WIND
-+
-+LLAudioEngine_OpenAL::LLAudioEngine_OpenAL(){
-+
-+#if LL_GSTREAMER_ENABLED
-+	mMedia_data = new LLMediaManagerData;
-+	LLMediaImplGStreamer::startup( mMedia_data );	// initialize GStreamer
-+
-+	m_streamer=new LLMediaImplGStreamer ();
-+
-+	if(!m_streamer)
-+	{
-+		llwarns << "LLAudioEngine_OpenAL::LLAudioEngine_OpenAL() Failed to create our private gstreamer audio instance" << llendl;
-+	}
-+#endif
-+}
-+
-+LLAudioEngine_OpenAL::~LLAudioEngine_OpenAL(){
-+}
-+
-+BOOL LLAudioEngine_OpenAL::init(const S32 num_channels, void* userdata){
-+
-+	LLAudioEngine::init(num_channels, userdata);
-+
-+	if(!alutInit(NULL, NULL)){
-+		llwarns << "LLAudioEngine_OpenAL::init() ALUT initialization failed: " << alutGetErrorString (alutGetError ()) << llendl;
-+		return FALSE;
-+	}
-+
-+	initInternetStream();
-+
-+	llinfos << "LLAudioEngine_OpenAL::init() OpenAL successfully initialized" << llendl;
-+
-+	llinfos << "LLAudioEngine_OpenAL::init() Speed of sound is: " << alGetFloat(AL_SPEED_OF_SOUND) << llendl;
-+
-+	return TRUE;
-+}
-+
-+void LLAudioEngine_OpenAL::idle(F32 max_decode_time){
-+	LLAudioEngine::idle(max_decode_time);
-+#if LL_GSTREAMER_ENABLED
-+       if(m_streamer != NULL)
-+		m_streamer->updateMedia();
-+#endif
-+}
-+
-+void LLAudioEngine_OpenAL::allocateListener(){
-+	mListenerp = (LLListener *) new LLListener_OpenAL();
-+	if(!mListenerp){
-+		llwarns << "LLAudioEngine_OpenAL::allocateListener() Listener creation failed" << llendl;
-+	}
-+}
-+
-+void LLAudioEngine_OpenAL::shutdown(){
-+	LLAudioEngine::shutdown();
-+
-+	if(!alutExit()){
-+		llwarns << "LLAudioEngine_OpenAL::shutdown() ALUT shutdown failed: " << alutGetErrorString (alutGetError ()) << llendl;
-+	}
-+
-+	llinfos << "LLAudioEngine_OpenAL::shutdown() OpenAL successfully shut down" << llendl;
-+
-+	delete mListenerp;
-+	mListenerp = NULL;
-+
-+#if LL_GSTREAMER_ENABLED
-+	if(m_streamer){
-+		delete m_streamer;
-+		m_streamer = NULL;
-+	}
-+#endif
-+}
-+
-+LLAudioBuffer *LLAudioEngine_OpenAL::createBuffer(){
-+   return new LLAudioBufferOpenAL();
-+}
-+
-+LLAudioChannel *LLAudioEngine_OpenAL::createChannel(){
-+   return new LLAudioChannelOpenAL();
-+}
-+
-+void LLAudioEngine_OpenAL::setInternalGain(F32 gain){
-+	//llinfos << "LLAudioEngine_OpenAL::setInternalGain() Gain: " << gain << llendl;
-+	alListenerf(AL_GAIN, gain);
-+}
-+
-+LLAudioChannelOpenAL::LLAudioChannelOpenAL(){
-+	alGenSources(1, &ALSource);
-+}
-+
-+LLAudioChannelOpenAL::~LLAudioChannelOpenAL(){
-+	cleanup();
-+	alDeleteSources(1, &ALSource);
-+}
-+
-+void LLAudioChannelOpenAL::cleanup(){
-+	alSourceStop(ALSource);
-+	mCurrentBufferp = NULL;
-+}
-+
-+void LLAudioChannelOpenAL::play(){
-+	if(!isPlaying()){
-+		alSourcePlay(ALSource);
-+		getSource()->setPlayedOnce(TRUE);
-+	}
-+}
-+
-+void LLAudioChannelOpenAL::playSynced(LLAudioChannel *channelp){
-+	play();
-+}
-+
-+BOOL LLAudioChannelOpenAL::isPlaying(){
-+	ALint state;
-+	alGetSourcei(ALSource, AL_SOURCE_STATE, &state);
-+	if(state == AL_PLAYING){
-+		return TRUE;
-+	}
-+	return FALSE;
-+}
-+
-+BOOL LLAudioChannelOpenAL::updateBuffer(){
-+	if (LLAudioChannel::updateBuffer()){
-+		// Base class update returned TRUE, which means that we need to actually
-+		// set up the source for a different buffer.
-+		LLAudioBufferOpenAL *bufferp = (LLAudioBufferOpenAL *)mCurrentSourcep->getCurrentBuffer();
-+		alSourcei(ALSource, AL_BUFFER, bufferp->getBuffer());
-+		alSourcef(ALSource, AL_GAIN, mCurrentSourcep->getGain());
-+		alSourcei(ALSource, AL_LOOPING, mCurrentSourcep->isLoop() ? AL_TRUE : AL_FALSE);
-+	}
-+
-+	return TRUE;
-+}
-+
-+void LLAudioChannelOpenAL::update3DPosition(){
-+	if(!mCurrentSourcep){
-+		return;
-+	}
-+	if (mCurrentSourcep->isAmbient()){
-+		alSource3f(ALSource, AL_POSITION, 0.0, 0.0, 0.0);
-+		alSource3f(ALSource, AL_VELOCITY, 0.0, 0.0, 0.0);
-+		//alSource3f(ALSource, AL_DIRECTION, 0.0, 0.0, 0.0);
-+		alSourcef (ALSource, AL_ROLLOFF_FACTOR, 0.0);
-+		alSourcei (ALSource, AL_SOURCE_RELATIVE, AL_TRUE);
-+	}else{
-+		LLVector3 float_pos;
-+		float_pos.setVec(mCurrentSourcep->getPositionGlobal());
-+		alSourcefv(ALSource, AL_POSITION, float_pos.mV);
-+		//llinfos << "LLAudioChannelOpenAL::update3DPosition() Velocity: " << mCurrentSourcep->getVelocity() << llendl;
-+		alSourcefv(ALSource, AL_VELOCITY, mCurrentSourcep->getVelocity().mV);
-+		//alSource3f(ALSource, AL_DIRECTION, 0.0, 0.0, 0.0);
-+		alSourcef (ALSource, AL_ROLLOFF_FACTOR, 1.0);
-+		alSourcei (ALSource, AL_SOURCE_RELATIVE, AL_FALSE);
-+	}
-+	//llinfos << "LLAudioChannelOpenAL::update3DPosition() Gain: " << mCurrentSourcep->getGain() << llendl;
-+	alSourcef(ALSource, AL_GAIN, mCurrentSourcep->getGain());
-+}
-+
-+LLAudioBufferOpenAL::LLAudioBufferOpenAL(){
-+	ALBuffer = AL_NONE;
-+}
-+
-+LLAudioBufferOpenAL::~LLAudioBufferOpenAL(){
-+	cleanup();
-+}
-+
-+void LLAudioBufferOpenAL::cleanup(){
-+	if(ALBuffer != AL_NONE){
-+		alDeleteBuffers(1, &ALBuffer);
-+	}
-+}
-+
-+BOOL LLAudioBufferOpenAL::loadWAV(const std::string& filename){
-+	cleanup();
-+	ALBuffer = alutCreateBufferFromFile(filename.c_str());
-+	if(ALBuffer == AL_NONE){
-+		//ALenum error = alutGetError();
-+		//llwarns << "LLAudioBufferOpenAL::loadWAV() Error loading " << filename
-+		//	<< " " << alutGetErrorString(error) << llendl;
-+		return FALSE;
-+	}
-+
-+	return TRUE;
-+}
-+
-+U32 LLAudioBufferOpenAL::getLength(){
-+	if(ALBuffer == AL_NONE){
-+		return 0;
-+	}
-+	ALint length;
-+	alGetBufferi(ALBuffer, AL_SIZE, &length);
-+	return length >> 2;
-+}
-+
-+// ------------
-+
-+void LLAudioEngine_OpenAL::initWind(){
-+#if LL_OPENAL_WIND
-+	ALenum error;
-+       llinfos << "LLAudioEngine_OpenAL::initWind() start" << llendl;
-+
-+       alGetError(); /* clear error */
-+       alGenBuffers(NO_WIND_BUFFERS,wind_buffers);
-+       if((error=alGetError()) != AL_NO_ERROR)
-+       {
-+               llwarns << "LLAudioEngine_OpenAL::initWind() Error creating wind buffers: "<<error<<llendl;
-+       }
-+
-+       alGenSources(1,wind_sources);
-+
-+       if((error=alGetError()) != AL_NO_ERROR)
-+       {
-+               llwarns << "LLAudioEngine_OpenAL::initWind() Error creating wind sources: "<<error<<llendl;
-+       }
-+
-+       winddata=(S16*)malloc(sizeof(S16)*44100*0.2*2*2); //200ms @44100Hz Stereo
-+
-+       if(winddata==NULL)
-+       {
-+               llerrs << "LLAudioEngine_OpenAL::initWind() Error creating wind memory buffer" << llendl;
-+               mEnableWind=FALSE;
-+       }
-+
-+       llinfos << "LLAudioEngine_OpenAL::initWind() done" << llendl;
-+#endif
-+}
-+
-+void LLAudioEngine_OpenAL::cleanupWind(){
-+#if LL_OPENAL_WIND
-+       llinfos << "LLAudioEngine_OpenAL::cleanupWind()" << llendl;
-+
-+       alDeleteBuffers(NO_WIND_BUFFERS,wind_buffers);
-+
-+       alDeleteSources(1, wind_sources);
-+
-+       if(winddata)
-+               free(winddata);
-+#endif
-+}
-+
-+void LLAudioEngine_OpenAL::updateWind(LLVector3 wind_vec, F32 camera_altitude){
-+#if LL_OPENAL_WIND
-+       LLVector3 wind_pos;
-+       F64 pitch;
-+       F64 center_freq;
-+       ALenum error;
-+
-+       mMaxWindGain=1.0;
-+
-+       if (!mEnableWind)
-+               return;
-+
-+       if(!winddata)
-+               return;
-+
-+       if (mWindUpdateTimer.checkExpirationAndReset(LL_WIND_UPDATE_INTERVAL))
-+       {
-+
-+               // wind comes in as Linden coordinate (+X = forward, +Y = left, +Z = up)
-+               // need to convert this to the conventional orientation DS3D and OpenAL use
-+               // where +X = right, +Y = up, +Z = backwards
-+
-+               wind_vec.setVec(-wind_vec.mV[1], wind_vec.mV[2], -wind_vec.mV[0]);
-+
-+               // cerr << "Wind update" << endl;
-+
-+               pitch = 1.0 + mapWindVecToPitch(wind_vec);
-+               center_freq = 80.0 * pow(pitch,2.5*(mapWindVecToGain(wind_vec)+1.0));
-+
-+               gTargetFreq = (F32)center_freq;
-+               gTargetGain = (F32)mapWindVecToGain(wind_vec) * mMaxWindGain;
-+               gTargetPanGainR = (F32)mapWindVecToPan(wind_vec);
-+
-+               ALfloat source0Pos[]={mListenerp->getPosition().mV[0],mListenerp->getPosition().mV[1],mListenerp->getPosition().mV[2]};
-+
-+               alSourcef(wind_sources[0], AL_GAIN, gTargetGain);
-+               alSourcef(wind_sources[0], AL_PITCH, pitch);
-+               alSourcefv(wind_sources[0], AL_POSITION, source0Pos);
-+               alSourcefv(wind_sources[0], AL_VELOCITY, source0Vel);
-+               alSourcei(wind_sources[0], AL_LOOPING, AL_FALSE);
-+
-+       }
-+
-+       // ok lets make a wind buffer now
-+
-+       if(first_wind==TRUE)
-+       {
-+               llinfos << "LLAudioEngine_OpenAL::updateWind() making first buffer" << llendl;
-+               alGetError(); /* clear error */
-+
-+               for(int counter=0;counter<NO_WIND_BUFFERS;counter++)
-+               {
-+                       alBufferData(wind_buffers[counter],AL_FORMAT_STEREO16,windDSP((void*)winddata,2*44100*0.02),2*44100*0.02*sizeof(U16),44100);
-+                       if((error=alGetError()) != AL_NO_ERROR)
-+                       {
-+                               llwarns << "LLAudioEngine_OpenAL::initWind() Error creating INITAL WIND BUFFER 1: "<<error<<llendl;
-+                       }
-+               }
-+
-+               alSourceQueueBuffers(wind_sources[0], NO_WIND_BUFFERS, wind_buffers);
-+
-+               alSourcePlay(wind_sources[0]);
-+               if((error=alGetError()) != AL_NO_ERROR)
-+               {
-+                       llwarns << "LLAudioEngine_OpenAL::initWind() Error inital wind play: "<<error<<llendl;
-+               }
-+
-+               first_wind=FALSE;
-+               llinfos << "LLAudioEngine_OpenAL::updateWind() making first buffer DONE!" << llendl;
-+
-+       }
-+       else
-+       {
-+               int processed;
-+               alGetSourcei(wind_sources[0], AL_BUFFERS_PROCESSED, &processed);
-+
-+               while(processed--)
-+               {
-+                       ALuint buffer;
-+                       int error;
-+                       alSourceUnqueueBuffers(wind_sources[0], 1, &buffer);
-+                       error = alGetError();
-+                       if(error != AL_NO_ERROR)
-+                               llwarns << "LLAudioEngine_OpenAL::updateWind() error swapping buffers" << llendl;
-+
-+                       alBufferData(buffer,AL_FORMAT_STEREO16,windDSP((void*)winddata,44100*0.2),2*44100*0.2*sizeof(U16),44100);
-+                       error = alGetError();
-+                       if(error != AL_NO_ERROR)
-+                               llwarns << "LLAudioEngine_OpenAL::updateWind() error swapping buffers" << llendl;
-+
-+
-+                       alSourceQueueBuffers(wind_sources[0], 1, &buffer);
-+                       error = alGetError();
-+                       if(error != AL_NO_ERROR)
-+                               llwarns << "LLAudioEngine_OpenAL::updateWind() error swapping buffers" << llendl;
-+
-+
-+               }
-+
-+               int playing;
-+               alGetSourcei(wind_sources[0], AL_SOURCE_STATE, &playing);
-+
-+               if(playing==AL_STOPPED)
-+                       alSourcePlay(wind_sources[0]);
-+
-+       }
-+#endif //LL_OPENAL_WIND
-+}
-+
-+inline S16 clipSample(S16 sample, S16 min, S16 max)
-+{
-+#if LL_OPENAL_WIND
-+       if (sample > max)
-+               sample = max;
-+       else if (sample < min)
-+               sample = min;
-+
-+#endif
-+       return sample;
-+}
-+
-+void * LLAudioEngine_OpenAL::windDSP(void *newbuffer, int length)
-+{
-+#if LL_OPENAL_WIND
-+       // newbuffer = the buffer passed from the previous DSP unit.
-+       // length = length in samples at this mix time.
-+
-+       U8 *cursamplep = (U8*)newbuffer;
-+       U8   wordsize = 2;
-+
-+       double bandwidth = 50;
-+       double inputSamplingRate = 44100;
-+       double a0,b1,b2;
-+
-+       // calculate resonant filter coeffs
-+       b2 = exp(-(F_TWO_PI) * (bandwidth / inputSamplingRate));
-+
-+       while (length--)
-+       {
-+               gCurrentFreq = (float)((0.999 * gCurrentFreq) + (0.001 * gTargetFreq));
-+               gCurrentGain = (float)((0.999 * gCurrentGain) + (0.001 * gTargetGain));
-+               gCurrentPanGainR = (float)((0.999 * gCurrentPanGainR) + (0.001 * gTargetPanGainR));
-+               b1 = (-4.0 * b2) / (1.0 + b2) * cos(F_TWO_PI * (gCurrentFreq / inputSamplingRate));
-+               a0 = (1.0 - b2) * sqrt(1.0 - (b1 * b1) / (4.0 * b2));
-+               double nextSample;
-+
-+           // start with white noise
-+               nextSample = ll_frand(2.0f) - 1.0f;
-+
-+#if 1 // LLAE_WIND_PINK apply pinking filter
-+               gbuf0 = 0.997f * gbuf0 + 0.0126502f * nextSample;
-+               gbuf1 = 0.985f * gbuf1 + 0.0139083f * nextSample;
-+               gbuf2 = 0.950f * gbuf2 + 0.0205439f * nextSample;
-+               gbuf3 = 0.850f * gbuf3 + 0.0387225f * nextSample;
-+               gbuf4 = 0.620f * gbuf4 + 0.0465932f * nextSample;
-+               gbuf5 = 0.250f * gbuf5 + 0.1093477f * nextSample;
-+
-+                       nextSample = gbuf0 + gbuf1 + gbuf2 + gbuf3 + gbuf4 + gbuf5;
-+#endif
-+
-+#if 1 //LLAE_WIND_RESONANT // do a resonant filter on the noise
-+               nextSample = (double)( a0 * nextSample - b1 * gY0 - b2 * gY1 );
-+
-+               gY1 = gY0;
-+               gY0 = nextSample;
-+#endif
-+               nextSample *= gCurrentGain;
-+
-+               S16     sample;
-+
-+               sample = llfloor(((F32)nextSample*32768.f*(1.0f - gCurrentPanGainR))+0.5f);
-+               *(S16*)cursamplep = clipSample(sample, -32768, 32767);
-+
-+               cursamplep += wordsize;
-+
-+               sample = llfloor(((F32)nextSample*32768.f*gCurrentPanGainR)+0.5f);
-+
-+               sample = llfloor(((F32)nextSample*32768.f*gCurrentPanGainR)+0.5f);
-+               *(S16*)cursamplep = clipSample(sample, -32768, 32767);
-+               cursamplep += wordsize;
-+       }
-+
-+#endif //LL_OPENAL_WIND
-+       return newbuffer;
-+}
-+
-+// ------------
-+
-+void LLAudioEngine_OpenAL::InitStreamer()
-+{
-+#if LL_GSTREAMER_ENABLED
-+       m_streamer=new LLMediaImplGStreamer ();
-+
-+       if(!m_streamer)
-+       {
-+               llwarns << "LLAudioEngine_OpenAL::LLAudioEngine_OpenAL() Failed to create our private gstreamer audio instance" << llendl;
-+       }
-+
-+       if(m_streamer)
-+       {
-+               m_streamer->init ();
-+       }
-+#endif
-+}
-+
-+// ------------
-+
-+void LLAudioEngine_OpenAL::initInternetStream(){
-+	if(!mInternetStreamURL.empty())
-+		mInternetStreamURL.erase();
-+}
-+
-+void LLAudioEngine_OpenAL::startInternetStream(const std::string& url){
-+
-+#if LL_GSTREAMER_ENABLED
-+	if(!m_streamer)
-+		return;
-+// DCF_DEBUG
-+llinfos << "entered LLAudioEngine_OpenAL::startInternetStream()" << llendl;
-+	
-+
-+	if (!url.empty()) {
-+		llinfos << "LLAudioEngine_OpenAL::startInternetStream() Starting internet stream: " << url << llendl;
-+		mInternetStreamURL=url;
-+		m_streamer->navigateTo ( url );
-+		llinfos << "Playing....." << llendl;		
-+		m_streamer->addCommand(LLMediaBase::COMMAND_START);
-+		m_streamer->updateMedia();
-+
-+	}else{
-+		llinfos << "LLAudioEngine_OpenAL setting stream to NULL"<< llendl;
-+		mInternetStreamURL.erase();
-+		m_streamer->addCommand(LLMediaBase::COMMAND_STOP);
-+		m_streamer->updateMedia();
-+	}
-+#endif
-+}
-+
-+void LLAudioEngine_OpenAL::updateInternetStream(){
-+// DCF_DEBUG
-+llinfos << "entered LLAudioEngine_OpenAL::updateInternetStream()" << llendl;
-+	
-+}
-+
-+void LLAudioEngine_OpenAL::stopInternetStream(){
-+// DCF_DEBUG
-+llinfos << "entered LLAudioEngine_OpenAL::stopInternetStream()" << llendl;
-+	
-+#if LL_GSTREAMER_ENABLED
-+	if( ! m_streamer->addCommand(LLMediaBase::COMMAND_STOP)){
-+		llinfos << "attempting to stop stream failed!" << llendl;
-+	}
-+	m_streamer->updateMedia();
-+#endif
-+	mInternetStreamURL.erase();
-+}
-+
-+void LLAudioEngine_OpenAL::pauseInternetStream(int pause){
-+#if LL_GSTREAMER_ENABLED
-+	if(!m_streamer)
-+		return;
-+// DCF_DEBUG
-+llinfos << "entered LLAudioEngine_OpenAL::pauseInternetStream()" << llendl;
-+	
-+	if(pause){
-+		if(!m_streamer->addCommand(LLMediaBase::COMMAND_PAUSE)){
-+			llinfos << "attempting to pause stream failed!" << llendl;
-+		}
-+		m_streamer->updateMedia();
-+	}else{
-+		if( ! m_streamer->addCommand(LLMediaBase::COMMAND_START)){
-+			llinfos << "attempting to pause stream failed!" << llendl;
-+		}
-+		m_streamer->updateMedia();
-+	}
-+#endif
-+}
-+
-+int LLAudioEngine_OpenAL::isInternetStreamPlaying(){
-+
-+#if LL_GSTREAMER_ENABLED
-+	if(!m_streamer)
-+		return 0;
-+	
-+	if(m_streamer->getStatus() == LLMediaBase::STATUS_STARTED)
-+	{
-+		return 1; // Active and playing
-+	}	
-+
-+	if(m_streamer->getStatus() == LLMediaBase::STATUS_PAUSED)
-+	{
-+		return 2; // paused
-+	}
-+#endif
-+	return 0; // Stopped
-+}
-+
-+void LLAudioEngine_OpenAL::getInternetStreamInfo(char* artist_out, char* title_out){
-+}
-+
-+void LLAudioEngine_OpenAL::setInternetStreamGain(F32 vol){
-+#if LL_GSTREAMER_ENABLED
-+	// Set the gstreamer volume here
-+	if(!m_streamer)
-+		return;
-+
-+	vol = llclamp(vol, 0.f, 1.f);
-+	m_streamer->setVolume(vol);
-+	m_streamer->updateMedia();
-+
-+#endif
-+}
-+
-+const std::string& LLAudioEngine_OpenAL::getInternetStreamURL(){
-+	return mInternetStreamURL;
-+}
-+
-Index: slviewer/indra/llaudio/audioengine_openal.h
-===================================================================
---- /dev/null	1970-01-01 00:00:00.000000000 +0000
-+++ slviewer/indra/llaudio/audioengine_openal.h	2008-09-05 14:33:58.000000000 +0100
-@@ -0,0 +1,123 @@
-+/**
-+ * @file audioengine_openal.cpp
-+ * @brief implementation of audio engine using OpenAL
-+ * support as a OpenAL 3D implementation
-+ *
-+ * Copyright (c) 2002-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://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.
-+ */
-+
-+
-+#ifndef LL_AUDIOENGINE_OpenAL_H
-+#define LL_AUDIOENGINE_OpenAL_H
-+
-+#undef XMLCALL
-+
-+#include <string>
-+
-+#include "audioengine.h"
-+#include "listener_openal.h"
-+
-+
-+#if LL_GSTREAMER_ENABLED
-+#include "llmediamanager.h"
-+#include "llmediaimplgstreamer.h"
-+#endif
-+
-+#include "llrand.h"
-+
-+class LLAudioEngine_OpenAL : public LLAudioEngine{
-+	public:
-+		LLAudioEngine_OpenAL();
-+		virtual ~LLAudioEngine_OpenAL();
-+
-+		virtual BOOL init(const S32 num_channels, void *user_data);
-+		virtual void allocateListener();
-+
-+		virtual void shutdown();
-+
-+		virtual void idle(F32 max_decode_time = 0.f);
-+
-+		void setInternalGain(F32 gain);
-+
-+		LLAudioBuffer* createBuffer();
-+		LLAudioChannel* createChannel();
-+
-+		// Internet stream methods
-+		virtual void initInternetStream();
-+		virtual void startInternetStream(const std::string& url);
-+		virtual void stopInternetStream();
-+		virtual void updateInternetStream();
-+		virtual void pauseInternetStream(int pause);
-+		virtual int isInternetStreamPlaying();
-+		virtual void getInternetStreamInfo(char* artist, char* title);
-+		virtual void setInternetStreamGain(F32 vol);
-+		virtual const std::string& getInternetStreamURL();
-+		virtual void InitStreamer();
-+
-+		void initWind();
-+		void cleanupWind();
-+		void updateWind(LLVector3 direction, F32 camera_altitude);
-+
-+	protected:
-+		std::string mInternetStreamURL;
-+		void * windDSP(void *newbuffer, int length);
-+#if LL_GSTREAMER_ENABLED
-+		LLMediaManagerData * mMedia_data;
-+		LLMediaImplGStreamer * m_streamer;
-+#endif
-+};
-+
-+class LLAudioChannelOpenAL : public LLAudioChannel{
-+	public:
-+		LLAudioChannelOpenAL();
-+		virtual ~LLAudioChannelOpenAL();
-+	protected:
-+		void play();
-+		void playSynced(LLAudioChannel *channelp);
-+		void cleanup();
-+		BOOL isPlaying();
-+
-+		BOOL updateBuffer();
-+		void update3DPosition();
-+		void updateLoop(){};
-+
-+		ALuint ALSource;
-+};
-+
-+class LLAudioBufferOpenAL : public LLAudioBuffer{
-+	public:
-+		LLAudioBufferOpenAL();
-+		virtual ~LLAudioBufferOpenAL();
-+
-+		BOOL loadWAV(const std::string& filename);
-+		U32 getLength();
-+
-+		friend class LLAudioChannelOpenAL;
-+	protected:
-+		void cleanup();
-+		ALuint getBuffer(){return ALBuffer;}
-+		ALuint ALBuffer;
-+};
-+
-+#endif
-Index: slviewer/indra/llaudio/listener_openal.cpp
-===================================================================
---- /dev/null	1970-01-01 00:00:00.000000000 +0000
-+++ slviewer/indra/llaudio/listener_openal.cpp	2008-09-05 13:43:07.000000000 +0100
-@@ -0,0 +1,95 @@
-+/**
-+ * @file audioengine_openal.cpp
-+ * @brief implementation of audio engine using OpenAL
-+ * support as a OpenAL 3D implementation
-+ *
-+ * Copyright (c) 2002-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.
-+ */
-+
-+#include "linden_common.h"
-+#include "audioengine.h"
-+
-+#include "listener_openal.h"
-+
-+LLListener_OpenAL::LLListener_OpenAL(){
-+	init();
-+}
-+
-+LLListener_OpenAL::~LLListener_OpenAL(){
-+}
-+
-+void LLListener_OpenAL::translate(LLVector3 offset){
-+	LLListener::translate(offset);
-+	llinfos << "LLListener_OpenAL::translate() : " << offset << llendl;
-+}
-+
-+void LLListener_OpenAL::setPosition(LLVector3 pos){
-+	LLListener::setPosition(pos);
-+	//llinfos << "LLListener_OpenAL::setPosition() : " << pos << llendl;
-+}
-+
-+void LLListener_OpenAL::setVelocity(LLVector3 vel){
-+	LLListener::setVelocity(vel);
-+}
-+
-+void LLListener_OpenAL::orient(LLVector3 up, LLVector3 at){
-+	LLListener::orient(up, at);
-+	//llinfos << "LLListener_OpenAL::orient() up: " << up << " at: " << at << llendl;
-+}
-+
-+void LLListener_OpenAL::commitDeferredChanges(){
-+	ALfloat orientation[6];
-+	orientation[0] = mListenAt.mV[0];
-+	orientation[1] = mListenAt.mV[1];
-+	orientation[2] = mListenAt.mV[2];
-+	orientation[3] = mListenUp.mV[0];
-+	orientation[4] = mListenUp.mV[1];
-+	orientation[5] = mListenUp.mV[2];
-+
-+	// Why is this backwards?
-+	ALfloat velocity[3];
-+	velocity[0] = -mVelocity.mV[0];
-+	velocity[1] = -mVelocity.mV[1];
-+	velocity[2] = -mVelocity.mV[2];
-+
-+	alListenerfv(AL_ORIENTATION, orientation);
-+	alListenerfv(AL_POSITION, mPosition.mV);
-+	alListenerfv(AL_VELOCITY, velocity);
-+}
-+
-+void LLListener_OpenAL::setDopplerFactor(F32 factor){
-+	// Effect is way too strong by default, scale it down here.
-+	// Scaling the speed of sound up causes crashes.
-+	factor *= 0.01f;
-+	//llinfos << "LLListener_OpenAL::setDopplerFactor() : " << factor << llendl;
-+	alDopplerFactor(factor);
-+}
-+
-+F32 LLListener_OpenAL::getDopplerFactor(){
-+	ALfloat factor=0;
-+	alDopplerFactor(factor);
-+	llinfos << "LLListener_OpenAL::getDopplerFactor() : " << factor << llendl;
-+	return factor;
-+}
-+
-Index: slviewer/indra/llaudio/CMakeLists.txt
-===================================================================
---- slviewer.orig/indra/llaudio/CMakeLists.txt	2008-09-05 13:13:59.000000000 +0100
-+++ slviewer/indra/llaudio/CMakeLists.txt	2008-09-05 13:43:07.000000000 +0100
-@@ -9,6 +9,7 @@
- include(LLMath)
- include(LLMessage)
- include(LLVFS)
-+include(LLMedia)
- 
- include_directories(
-     ${FMOD_INCLUDE_DIR}
-@@ -20,6 +21,10 @@
-     ${VORBISENC_INCLUDE_DIRS}
-     ${VORBISFILE_INCLUDE_DIRS}
-     ${VORBIS_INCLUDE_DIRS}
-+    ${OPENAL_LIB_INCLUDE_DIRS}
-+    ${FREEAULT_LIB_INCLUDE_DIRS}
-+    ${LLMEDIA_INCLUDE_DIRS}
-+    ${GSTREAMER_INCLUDE_DIRS}
-     )
- 
- set(llaudio_SOURCE_FILES
-@@ -59,6 +64,19 @@
-     endif (LINUX)
- endif (FMOD)
- 
-+if (OPENAL)
-+	list(APPEND llaudio_SOURCE_FILES
-+	audioengine_openal.cpp
-+	listener_openal.cpp
-+	)
-+
-+	list(APPEND llaudio_HEADER_FILES
-+	audioengine_openal.h
-+	listener_openal.h
-+	)
-+  	
-+endif (OPENAL)
-+
- set_source_files_properties(${llaudio_HEADER_FILES}
-                             PROPERTIES HEADER_FILE_ONLY TRUE)
- 
-Index: slviewer/indra/newview/CMakeLists.txt
-===================================================================
---- slviewer.orig/indra/newview/CMakeLists.txt	2008-09-05 13:43:06.000000000 +0100
-+++ slviewer/indra/newview/CMakeLists.txt	2008-09-05 15:09:01.000000000 +0100
-@@ -8,6 +8,7 @@
- include(DirectX)
- include(ELFIO)
- include(FMOD)
-+include(OPENAL)
- include(FindOpenGL)
- include(LLAudio)
- include(LLCharacter)
-@@ -56,6 +57,7 @@
-     ${LLXML_INCLUDE_DIRS}
-     ${LSCRIPT_INCLUDE_DIRS}
-     ${LSCRIPT_INCLUDE_DIRS}/lscript_compile
-+    ${GSTREAMER_INCLUDE_DIRS}
-     )
- 
- set(viewer_SOURCE_FILES
-@@ -1238,6 +1240,11 @@
- 
- list(APPEND viewer_SOURCE_FILES ${viewer_CHARACTER_FILES})
- 
-+
-+if (OPENAL)
-+  set_source_files_properties(llstartup.cpp PROPERTIES COMPILE_FLAGS -DLL_OPENAL)
-+endif (OPENAL)
-+
- if (FMOD)
-   set_source_files_properties(llstartup.cpp PROPERTIES COMPILE_FLAGS -DLL_FMOD)
- 
-Index: slviewer/indra/cmake/OPENAL.cmake
-===================================================================
---- /dev/null	1970-01-01 00:00:00.000000000 +0000
-+++ slviewer/indra/cmake/OPENAL.cmake	2008-09-05 13:43:07.000000000 +0100
-@@ -0,0 +1,14 @@
-+
-+set(OPENAL OFF CACHE BOOL "Enable OpenAL")
-+
-+
-+if (OPENAL)
-+	include(FindPkgConfig)
-+	pkg_check_modules(OPENAL_LIB REQUIRED openal)
-+	pkg_check_modules(FREEAULT_LIB REQUIRED freealut)
-+	set(OPENAL_LIBRARIES 
-+		openal
-+		alut
-+	)
-+		
-+endif (OPENAL)
-Index: slviewer/indra/newview/llstartup.cpp
-===================================================================
---- slviewer.orig/indra/newview/llstartup.cpp	2008-09-05 13:13:59.000000000 +0100
-+++ slviewer/indra/newview/llstartup.cpp	2008-09-05 13:43:07.000000000 +0100
-@@ -17,7 +17,7 @@
-  * 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
-+ * online at http://secondlifegrid.net/programs/open_source/licensing/flossexceptionOP
-  * 
-  * By copying, modifying or distributing this software, you acknowledge
-  * that you have read and understood your obligations described above,
-@@ -45,6 +45,10 @@
- # include "audioengine_fmod.h"
- #endif
- 
-+#ifdef LL_OPENAL
-+#include "audioengine_openal.h"
-+#endif
-+
- #include "llares.h"
- #include "llcachename.h"
- #include "llviewercontrol.h"
-@@ -574,10 +578,14 @@
- 
- 		if (FALSE == gSavedSettings.getBOOL("NoAudio"))
- 		{
-+			gAudiop = NULL;
-+
- #ifdef LL_FMOD
- 			gAudiop = (LLAudioEngine *) new LLAudioEngine_FMOD();
--#else
--			gAudiop = NULL;
-+#endif
-+
-+#ifdef LL_OPENAL
-+			gAudiop = (LLAudioEngine *) new LLAudioEngine_OpenAL();
- #endif
- 
- 			if (gAudiop)
-Index: slviewer/indra/llaudio/listener_openal.h
-===================================================================
---- slviewer.orig/indra/llaudio/listener_openal.h	2008-09-05 13:13:59.000000000 +0100
-+++ slviewer/indra/llaudio/listener_openal.h	2008-09-05 13:43:07.000000000 +0100
-@@ -54,6 +54,10 @@
- 	virtual void setPosition(LLVector3 pos);
- 	virtual void setVelocity(LLVector3 vel);
- 	virtual void orient(LLVector3 up, LLVector3 at);
-+	virtual void commitDeferredChanges();
-+
-+	virtual void setDopplerFactor(F32 factor);
-+	virtual F32 getDopplerFactor();
- };
- 
- #endif
-Index: slviewer/indra/cmake/LLAudio.cmake
-===================================================================
---- slviewer.orig/indra/cmake/LLAudio.cmake	2008-09-05 15:12:13.000000000 +0100
-+++ slviewer/indra/cmake/LLAudio.cmake	2008-09-05 15:12:39.000000000 +0100
-@@ -12,4 +12,5 @@
-     ${VORBISFILE_LIBRARIES}
-     ${VORBIS_LIBRARIES}
-     ${OGG_LIBRARIES}
-+    ${OPENAL_LIBRARIES}
-     )
diff --git a/debian/patches/remove_as_needed.patch b/debian/patches/remove_as_needed.patch
deleted file mode 100644
index 9039d9f..0000000
--- a/debian/patches/remove_as_needed.patch
+++ /dev/null
@@ -1,21 +0,0 @@
---- ./indra/linux_crash_logger/CMakeLists.txt.orig	2008-09-06 23:49:39.623979478 +0200
-+++ ./indra/linux_crash_logger/CMakeLists.txt	2008-09-06 23:50:11.919980168 +0200
-@@ -41,8 +41,6 @@
-      ${linux_crash_logger_HEADER_FILES}
-      )
- 
--list(APPEND CMAKE_EXE_LINKER_FLAGS -Wl,--as-needed)
--
- add_executable(linux-crash-logger ${linux_crash_logger_SOURCE_FILES})
- 
- target_link_libraries(linux-crash-logger
---- ./indra/newview/CMakeLists.txt.orig	2008-09-06 23:49:31.719981203 +0200
-+++ ./indra/newview/CMakeLists.txt	2008-09-06 23:50:22.575979620 +0200
-@@ -874,7 +874,6 @@
- 
- if (LINUX)
-     LIST(APPEND viewer_SOURCE_FILES llappviewerlinux.cpp)
--    LIST(APPEND CMAKE_EXE_LINKER_FLAGS -Wl,--as-needed)
- 
-     set(viewer_LIBRARIES
-         Xinerama
diff --git a/debian/patches/rename_binary_cmake.patch b/debian/patches/rename_binary_cmake.patch
deleted file mode 100644
index 7069cc0..0000000
--- a/debian/patches/rename_binary_cmake.patch
+++ /dev/null
@@ -1,158 +0,0 @@
---- ./indra/newview/CMakeLists.txt	2008-08-21 01:01:19.000000000 +0100
-+++ ./indra/newview/CMakeLists.txt	2008-08-30 15:26:11.000000000 +0100
-@@ -430,6 +430,8 @@
-     pipeline.cpp
-     )
- 
-+set(BINARY_NAME CACHE STRING "secondlife-bin")
-+
- if (LINUX)
-   # We can't set these flags for Darwin, because they get passed to
-   # the PPC compiler.  Ugh.
-@@ -1264,15 +1266,15 @@
- set_source_files_properties(${viewer_HEADER_FILES}
-                             PROPERTIES HEADER_FILE_ONLY TRUE)
- 
--add_executable(secondlife-bin
-+add_executable(${BINARY_NAME}
-     WIN32
-     MACOSX_BUNDLE
-     ${viewer_SOURCE_FILES}
-     )
--check_message_template(secondlife-bin)
-+check_message_template(${BINARY_NAME})
- 
- if (LLKDU_LIBRARY)
--  add_dependencies(secondlife-bin ${LLKDU_LIBRARY})
-+  add_dependencies(${BINARY_NAME} ${LLKDU_LIBRARY})
- endif (LLKDU_LIBRARY)
- 
- set(PACKAGE OFF CACHE BOOL
-@@ -1280,12 +1282,12 @@
- 
- if (WINDOWS)
-     if(MSVC71)
--        set(release_flags "/MAP:Release/secondlife-bin.map /MAPINFO:LINES")
-+        set(release_flags "/MAP:Release/${BINARY_NAME}.map /MAPINFO:LINES")
-     else(MSVC71)
--        set(release_flags "/MAP:Release/secondlife-bin.map")
-+        set(release_flags "/MAP:Release/${BINARY_NAME}.map")
-     endif(MSVC71)
-     
--    set_target_properties(secondlife-bin
-+    set_target_properties(${BINARY_NAME}
-         PROPERTIES
-         LINK_FLAGS "/debug /NODEFAULTLIB:MSVCRT /SUBSYSTEM:WINDOWS"
-         LINK_FLAGS_DEBUG "/NODEFAULTLIB:LIBCMT /NODEFAULTLIB:MSVCRTD"
-@@ -1295,20 +1297,20 @@
-     # sets the 'working directory' for debugging from visual studio.
-     if (NOT UNATTENDED)
-         add_custom_command(
--            TARGET secondlife-bin PRE_BUILD
-+            TARGET ${BINARY_NAME} PRE_BUILD
-             COMMAND ${CMAKE_SOURCE_DIR}/tools/vstool/vstool.exe
-             ARGS
-               --solution 
-               ${CMAKE_BINARY_DIR}/${CMAKE_PROJECT_NAME}.sln
-               --workingdir
--              secondlife-bin
-+              ${BINARY_NAME}
-               ${CMAKE_CURRENT_SOURCE_DIR}
--            COMMENT "Setting the secondlife-bin working directory for debugging."
-+            COMMENT "Setting the ${BINARY_NAME} working directory for debugging."
-             )
-     endif (NOT UNATTENDED)
- 
-     add_custom_command(
--        TARGET secondlife-bin PRE_BUILD
-+        TARGET ${BINARY_NAME} PRE_BUILD
-         COMMAND ${CMAKE_COMMAND}
-         ARGS
-           -E
-@@ -1319,7 +1321,7 @@
-         )
- 
-     add_custom_command(
--        TARGET secondlife-bin PRE_BUILD
-+        TARGET ${BINARY_NAME} PRE_BUILD
-         COMMAND ${CMAKE_COMMAND}
-         ARGS
-           -E
-@@ -1329,10 +1331,10 @@
-         COMMENT "Copying message.xml to the runtime folder."
-         )
-        
--    add_dependencies(secondlife-bin copy_win_libs)
-+    add_dependencies(${BINARY_NAME} copy_win_libs)
- 
-     if (EXISTS ${CMAKE_SOURCE_DIR}/copy_win_scripts)
--      add_dependencies(secondlife-bin copy_win_scripts)
-+      add_dependencies(${BINARY_NAME} copy_win_scripts)
-     endif (EXISTS ${CMAKE_SOURCE_DIR}/copy_win_scripts)
-         
-     add_custom_command(
-@@ -1349,7 +1351,7 @@
-               --build=${CMAKE_CURRENT_BINARY_DIR}
-               --dest=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}
-               --touch=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/touched.bat
--        DEPENDS secondlife-bin ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
-+        DEPENDS ${BINARY_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
-         )
-     if (PACKAGE)
-       add_custom_target(package ALL DEPENDS ${CMAKE_CFG_INTDIR}/touched.bat)
-@@ -1357,7 +1359,7 @@
-     endif (PACKAGE)
- endif (WINDOWS)
- 
--target_link_libraries(secondlife-bin
-+target_link_libraries(${BINARY_NAME}
-     ${LLAUDIO_LIBRARIES}
-     ${LLCHARACTER_LIBRARIES}
-     ${LLIMAGE_LIBRARIES}
-@@ -1404,8 +1406,8 @@
-   add_custom_command(
-       OUTPUT secondlife-stripped
-       COMMAND strip
--      ARGS --strip-debug -o secondlife-stripped secondlife-bin
--      DEPENDS secondlife-bin
-+      ARGS --strip-debug -o secondlife-stripped ${BINARY_NAME}
-+      DEPENDS ${BINARY_NAME}
-       )
- 
-   set(product SecondLife-${ARCH}-${viewer_VERSION})
-@@ -1437,7 +1439,7 @@
- if (DARWIN)
-   set(product "Second Life")
-   set_target_properties(
--    secondlife-bin
-+    ${BINARY_NAME}
-     PROPERTIES
-     OUTPUT_NAME "${product}"
-     MACOSX_BUNDLE_INFO_STRING "info string - localize me"
-@@ -1451,7 +1453,7 @@
-     )
- 
-   add_custom_command(
--    TARGET secondlife-bin POST_BUILD
-+    TARGET ${BINARY_NAME} POST_BUILD
-     COMMAND ${PYTHON_EXECUTABLE}
-     ARGS
-       ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
-@@ -1462,7 +1464,7 @@
-       --artwork=${ARTWORK_DIR}
-       --build=${CMAKE_CURRENT_BINARY_DIR}
-       --dest=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${product}.app
--    DEPENDS secondlife-bin ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
-+    DEPENDS ${BINARY_NAME} ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
-     )
- 
-   if (PACKAGE)
-@@ -1480,7 +1482,7 @@
-         --dest=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${product}.app
-         --touch=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/.${product}.touched
-       DEPENDS
--        secondlife-bin
-+        ${BINARY_NAME}
-         ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
-       )
-       add_dependencies(package mac-updater mac-crash-logger)
diff --git a/debian/patches/series b/debian/patches/series
index e57177b..bc58a5f 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,38 +1,46 @@
-VWR-9557-EnableBuildWithNvidiaOrMesaHeaders.patch
-Allow-CXXFLAGS-to-specify-the-debug-flag.patch
-remove_as_needed.patch
-glh_linear.patch
-viewericon.patch
-rename_binary_cmake.patch
-24_always_test_vectorize.diff
-50_get_cpu_clock_count_for_more_than_just_i386.diff
-55_fix_the_locales.diff
-59_need_llpreprocessor_to_access_endian_macros.diff
-71_use_debian_alternatives_for_www_browser.diff
-75_use_debian-included_fonts.diff
-79_use_debian_channel.diff
-0001_possible_crash_and_leak_llassetstorage.patch.diff
-2543_possible_crash_in_group_voting_propsals.patch.diff
-2683_possible_crash_update_speaker_list.patch.diff
-1857_apr_thread_mutex_nested.patch.diff
-2003_possible_crash_draganddrop.patch.diff
-1294_llworkerthread_when_terminating_program.patch.diff
-0000_keep_statbars_from_overshooting.patch.diff
-dam_flex_2.5.34.diff
-VWR4070-openjpeg_check_number_of_components.diff
-VWR6800_motioncontroller_leak.diff
-VWR5715_text_not_replaced_by_input_with_japanses_im.diff
-VWR-3766_llGetInventoryNumber_tooltip_missing_INVENTORY_ANIMATION.diff
-VWR-1815_top_corner_fix.diff
-0001_possible_crash_in_llviewerpartssim.diff
-VWR-5697_fix_startup_paths.diff
-VWR-8194_clamp_outline_for_broken_nvidia.diff
-openal_1.21.0.diff
-VWR-5082_set_bulk_inv_permissions.diff
-use_c_locale_and_dont_spam_me_because_i_am_not_american.patch
-dont_depend_on_artwork_to_build.patch
-VWR-8751-Build-with-a-shared-llmozlib2.patch
-lltemplatemessagereader_memcpy.patch
-no_old_school_typedefs.patch
-gcc_warning_on_llwindowsdl_var_not_set.patch
-use_gtk_correctly.patch
+topic/debian/71_use_debian_alternatives_for_www_browser.diff -p1
+topic/debian/Allow_CXXFLAGS_to_specifiy_the_debug_flag.diff -p1
+topic/debian/VWR-8751-Build-with-a-shared-llmozlib2.diff -p1
+topic/debian/remove_as_needed.diff -p1
+topic/debian/trademark_compliance.diff -p1
+topic/debian/use_debian-included_fonts.diff -p1
+topic/debian/use_debian_channel.diff -p1
+topic/debian/viewericon.diff -p1
+topic/features/jira-backported/AvatarLoginList.diff -p1
+topic/features/jira-backported/VWR-11663_Save_Load_scripts.diff -p1
+topic/features/jira-backported/VWR-5082_set_bulk_inv_permissions.diff -p1
+topic/features/jira-backported/VWR-7531-Dynamic-Grid-List.diff -p1
+topic/features/jira-backported/avatar_list.diff -p1
+topic/features/jira-sent/24_always_test_vectorize.diff -p1
+topic/features/jira-sent/VWR-12678_add_crash_to_core_option.diff -p1
+topic/fixes/jira-backported/VWR-11103-FIx_local_ruler_on_linked_objects.diff -p1
+topic/fixes/jira-backported/VWR-11674_dont_download_muted_sounds.diff -p1
+topic/fixes/jira-backported/VWR-3766_llGetInventoryNumber_tooltip_missing_INVENTORY_ANIMATION.diff -p1
+topic/fixes/jira-backported/VWR5717_text_not_replaced_by_input_with_japanses_im.diff -p1
+topic/fixes/jira-backported/glh_linear.diff -p1
+topic/fixes/jira-sent/50_get_cpu_clock_count_for_more_than_just_i386.diff -p1
+topic/fixes/jira-sent/59_need_llpreprocessor_to_access_endian_macros.diff -p1
+topic/fixes/jira-sent/VWR-10759_delete_LLMediaImplGStreamer_mediaData_as_array.diff -p1
+topic/fixes/jira-sent/VWR-11128-Find_Python.diff -p1
+topic/fixes/jira-sent/VWR-11138_Develop_py_and_express_VS.diff -p1
+topic/fixes/jira-sent/VWR-12691_use_do_while_for_statement_macros.diff -p1
+topic/fixes/jira-sent/VWR-1815_top_corner_fix.diff -p1
+topic/fixes/jira-sent/VWR-8194_clamp_outline_for_broken_nvidia.diff -p1
+topic/fixes/jira-sent/VWR-9557-EnableBuildWithNvidiaOrMesaHeaders.diff -p1
+topic/fixes/jira-sent/correctly_find_dbus_headers_on_standalone.diff -p1
+topic/fixes/jira-sent/dont_depend_on_artwork_to_build.diff -p1
+topic/fixes/jira-sent/gcc_warning_on_llwindowsdl_var_not_set.diff -p1
+topic/fixes/jira-sent/lltemplatemessagereader_memcpy.diff -p1
+topic/fixes/jira-sent/no_format_or_string_literal.diff -p1
+topic/fixes/jira-sent/use_c_locale_and_dont_spam_me_because_i_am_not_american.diff -p1
+topic/fixes/new/allow_compilation_when_GST_DISABLE_GST_DEBUG_is_defined.diff -p1
+topic/fixes/new/delete_LLImageTGA_mColorMap_as_array.diff -p1
+topic/fixes/new/fix_cmake_install_target.diff -p1
+topic/fixes/thirdparty/0000_keep_statbars_from_overshooting.patch.diff -p1
+topic/fixes/thirdparty/0001_possible_crash_and_leak_llassetstorage.patch.diff -p1
+topic/fixes/thirdparty/0001_possible_crash_in_llviewerpartssim.diff -p1
+topic/fixes/thirdparty/1294_llworkerthread_when_terminating_program.patch.diff -p1
+topic/fixes/thirdparty/1857_apr_thread_mutex_nested.patch.diff -p1
+topic/fixes/thirdparty/2003_possible_crash_draganddrop.patch.diff -p1
+topic/fixes/thirdparty/2543_possible_crash_in_group_voting_propsals.patch.diff -p1
+topic/fixes/thirdparty/2683_possible_crash_update_speaker_list.patch.diff -p1
diff --git a/debian/patches/topic/debian/71_use_debian_alternatives_for_www_browser.diff b/debian/patches/topic/debian/71_use_debian_alternatives_for_www_browser.diff
new file mode 100644
index 0000000..849dc6a
--- /dev/null
+++ b/debian/patches/topic/debian/71_use_debian_alternatives_for_www_browser.diff
@@ -0,0 +1,39 @@
+From: Carlo Wood <carlo at alinoe.com>
+Subject: [PATCH] topic/debian/71_use_debian_alternatives_for_www_browser
+
+Fix the launch_url.sh script to use the debian system prefered browser choice.
+
+Signed-off-by: Carlo Wood <carlo at alinoe.com>
+
+---
+ indra/newview/linux_tools/launch_url.sh |    8 ++++++++
+ 1 files changed, 8 insertions(+), 0 deletions(-)
+
+diff --git a/indra/newview/linux_tools/launch_url.sh b/indra/newview/linux_tools/launch_url.sh
+index d2c8919..33cee0e 100755
+--- a/indra/newview/linux_tools/launch_url.sh
++++ b/indra/newview/linux_tools/launch_url.sh
+@@ -8,6 +8,7 @@
+ # On Unixoids we try, in order of decreasing priority:
+ # - $BROWSER if set (preferred)
+ # - kfmclient openURL
++# - gnome-open
+ # - x-www-browser
+ # - opera
+ # - firefox
+@@ -54,6 +55,13 @@ if which kfmclient >/dev/null; then
+     exit
+ fi
+ 
++# else gnome-open
++# (embodies gnome concept of 'preferred browser')
++if which gnome-open  >/dev/null; then
++    gnome-open "$URL" &
++    exit
++fi
++
+ # else x-www-browser
+ # (Debianesque idea of a working X browser)
+ if which x-www-browser >/dev/null; then
+-- 
+tg: (d7ba84b..) topic/debian/71_use_debian_alternatives_for_www_browser (depends on: upstream)
diff --git a/debian/patches/topic/debian/Allow_CXXFLAGS_to_specifiy_the_debug_flag.diff b/debian/patches/topic/debian/Allow_CXXFLAGS_to_specifiy_the_debug_flag.diff
new file mode 100644
index 0000000..ab23399
--- /dev/null
+++ b/debian/patches/topic/debian/Allow_CXXFLAGS_to_specifiy_the_debug_flag.diff
@@ -0,0 +1,43 @@
+From: Robin Cornelius <robin.cornelius at gmail.com>
+Subject: [PATCH] topic/debian/Allow_CXXFLAGS_to_specifiy_the_debug_flag
+
+Modify 00-Common.cmake to allow custom CXXFLAGS to take effect
+
+Signed-off-by: Robin Cornelius <robin.cornelius at gmail.com>
+
+---
+ indra/cmake/00-Common.cmake |    5 ++---
+ 1 files changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake
+index bf2d2c3..0d1092b 100644
+--- a/indra/cmake/00-Common.cmake
++++ b/indra/cmake/00-Common.cmake
+@@ -11,7 +11,7 @@ set(CMAKE_CXX_FLAGS_DEBUG "-D_DEBUG -DLL_DEBUG=1")
+ set(CMAKE_CXX_FLAGS_RELEASE
+     "-DLL_RELEASE=1 -DLL_RELEASE_FOR_DOWNLOAD=1 -DNDEBUG")
+ set(CMAKE_CXX_FLAGS_RELWITHDEBINFO 
+-    "-DLL_RELEASE=1 -DNDEBUG -DLL_RELEASE_WITH_DEBUG_INFO=1")
++    "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DLL_RELEASE=1 -DNDEBUG -DLL_RELEASE_WITH_DEBUG_INFO=1")
+ 
+ 
+ # Don't bother with a MinSizeRel build.
+@@ -123,7 +123,6 @@ if (LINUX)
+       -fno-math-errno
+       -fno-strict-aliasing
+       -fsigned-char
+-      -g
+       -pthread
+       )
+ 
+@@ -158,7 +157,7 @@ if (LINUX)
+     endif (NOT STANDALONE)
+   endif (VIEWER)
+ 
+-  set(CMAKE_CXX_FLAGS_DEBUG "-fno-inline ${CMAKE_CXX_FLAGS_DEBUG}")
++  set(CMAKE_CXX_FLAGS_DEBUG "-g -fno-inline ${CMAKE_CXX_FLAGS_DEBUG}")
+   set(CMAKE_CXX_FLAGS_RELEASE "-O2 ${CMAKE_CXX_FLAGS_RELEASE}")
+ endif (LINUX)
+ 
+-- 
+tg: (2c12fda..) topic/debian/Allow_CXXFLAGS_to_specifiy_the_debug_flag (depends on: upstream)
diff --git a/debian/patches/topic/debian/VWR-8751-Build-with-a-shared-llmozlib2.diff b/debian/patches/topic/debian/VWR-8751-Build-with-a-shared-llmozlib2.diff
new file mode 100644
index 0000000..6890009
--- /dev/null
+++ b/debian/patches/topic/debian/VWR-8751-Build-with-a-shared-llmozlib2.diff
@@ -0,0 +1,76 @@
+From: Carlo Wood <carlo at alinoe.com>
+Subject: [PATCH] topic/debian/VWR-8751-Build-with-a-shared-llmozlib2
+
+This allows us to use a dynamic libllmozlib library.
+Upstream are not currently interested in this.
+
+Signed-off-by: Carlo Wood <carlo at alinoe.com>
+
+---
+ indra/cmake/Mozlib.cmake         |   28 +++++++++++++++++++---------
+ indra/llmedia/llmediamanager.cpp |    2 ++
+ 2 files changed, 21 insertions(+), 9 deletions(-)
+
+diff --git a/indra/cmake/Mozlib.cmake b/indra/cmake/Mozlib.cmake
+index e9555df..3b10ccf 100644
+--- a/indra/cmake/Mozlib.cmake
++++ b/indra/cmake/Mozlib.cmake
+@@ -3,8 +3,25 @@ include(Linking)
+ include(Prebuilt)
+ 
+ if (STANDALONE)
+-    set(MOZLIB OFF CACHE BOOL 
+-        "Enable Mozilla support in the viewer (requires llmozlib library).")
++	set(MOZLIB OFF CACHE BOOL
++	    "Enable Mozilla support in the viewer (requires llmozlib library).")
++	FIND_PATH(MOZLIB_INCLUDE_DIR llmozlib2.h
++		/usr/local/include/
++		/usr/include/
++	)
++	SET(MOZLIB_NAMES ${MOZLIB_NAMES} llmozlib2)
++  	FIND_LIBRARY(MOZLIB_LIBRARY
++  		NAMES ${MOZLIB_NAMES}
++  		PATHS /usr/lib /usr/lib64 /usr/local/lib /usr/local/lib64 
++  	)
++	IF (MOZLIB_LIBRARY AND MOZLIB_INCLUDE_DIR AND MOZLIB)
++		MESSAGE ( STATUS "Enabled LLMOZLIB2" )
++		set(MOZLIB ON)
++	ELSE (MOZLIB_LIBRARY AND MOZLIB_INCLUDE_DIR)
++		MESSAGE ( STATUS "NOT USING LLMOZLIB2" )
++		set(MOZLIB OFF)
++	ENDIF (MOZLIB_LIBRARY AND MOZLIB_INCLUDE_DIR AND MOZLIB)
++   
+ else (STANDALONE)
+     use_prebuilt_binary(llmozlib)
+     set(MOZLIB ON CACHE BOOL
+@@ -18,13 +35,6 @@ if (MOZLIB)
+         link_directories(${CMAKE_SOURCE_DIR}/newview/app_settings/mozilla-runtime-linux-${ARCH})
+         set(MOZLIB_LIBRARIES
+             llmozlib2
+-            mozjs
+-            nspr4
+-            plc4
+-            plds4
+-            xpcom
+-            xul
+-            profdirserviceprovider_s
+             )
+     elseif (WINDOWS)
+         if (MSVC71)
+diff --git a/indra/llmedia/llmediamanager.cpp b/indra/llmedia/llmediamanager.cpp
+index 6db8dbe..ea02268 100644
+--- a/indra/llmedia/llmediamanager.cpp
++++ b/indra/llmedia/llmediamanager.cpp
+@@ -150,8 +150,10 @@ LLMediaManager* LLMediaManager::getInstance()
+ // (static)
+ void LLMediaManager::setBrowserUserAgent(std::string user_agent)
+ {
++#if LL_LLMOZLIB_ENABLED
+ 	// *HACK: Breaks encapsulation model, as initClass does above. JC
+ 	LLMediaImplLLMozLib::setBrowserUserAgent(user_agent);
++#endif
+ }
+ 
+ ////////////////////////////////////////////////////////////////////////////////
+-- 
+tg: (9d70d9f..) topic/debian/VWR-8751-Build-with-a-shared-llmozlib2 (depends on: upstream)
diff --git a/debian/patches/topic/debian/remove_as_needed.diff b/debian/patches/topic/debian/remove_as_needed.diff
new file mode 100644
index 0000000..4af7988
--- /dev/null
+++ b/debian/patches/topic/debian/remove_as_needed.diff
@@ -0,0 +1,39 @@
+From: Carlo Wood <carlo at alinoe.com>
+Subject: [PATCH] topic/debian/remove_as_needed
+
+This was needed to build on ubuntu, which i am keeping syncronised with as well.
+
+Signed-off-by: Carlo Wood <carlo at alinoe.com>
+
+---
+ indra/linux_crash_logger/CMakeLists.txt |    2 --
+ indra/newview/CMakeLists.txt            |    1 -
+ 2 files changed, 0 insertions(+), 3 deletions(-)
+
+diff --git a/indra/linux_crash_logger/CMakeLists.txt b/indra/linux_crash_logger/CMakeLists.txt
+index 6f6754e..0711791 100644
+--- a/indra/linux_crash_logger/CMakeLists.txt
++++ b/indra/linux_crash_logger/CMakeLists.txt
+@@ -38,8 +38,6 @@ list(APPEND linux_crash_logger_SOURCE_FILES
+      ${linux_crash_logger_HEADER_FILES}
+      )
+ 
+-list(APPEND CMAKE_EXE_LINKER_FLAGS -Wl,--as-needed)
+-
+ add_executable(linux-crash-logger ${linux_crash_logger_SOURCE_FILES})
+ 
+ target_link_libraries(linux-crash-logger
+diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
+index b95ba37..d1884ac 100644
+--- a/indra/newview/CMakeLists.txt
++++ b/indra/newview/CMakeLists.txt
+@@ -879,7 +879,6 @@ endif (DARWIN)
+ if (LINUX)
+     LIST(APPEND viewer_SOURCE_FILES llappviewerlinux.cpp)
+     LIST(APPEND viewer_SOURCE_FILES llappviewerlinux_api_dbus.cpp)
+-    LIST(APPEND CMAKE_EXE_LINKER_FLAGS -Wl,--as-needed)
+ 
+     set(viewer_LIBRARIES
+         Xinerama
+-- 
+tg: (defef87..) topic/debian/remove_as_needed (depends on: upstream)
diff --git a/debian/patches/topic/debian/trademark_compliance.diff b/debian/patches/topic/debian/trademark_compliance.diff
new file mode 100644
index 0000000..3645664
--- /dev/null
+++ b/debian/patches/topic/debian/trademark_compliance.diff
@@ -0,0 +1,49 @@
+From: Robin Cornelius <robin.cornelius at gmail.com>
+Subject: [PATCH] topic/debian/trademark_compliance
+
+Remove instances of Secondlife and replace with Omvviewer
+
+Signed-off-by: Robin Cornelius <robin.cornelius at gmail.com>
+
+---
+ indra/llwindow/llwindowsdl.cpp |    2 +-
+ indra/newview/llappviewer.cpp  |    4 ++--
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/indra/llwindow/llwindowsdl.cpp b/indra/llwindow/llwindowsdl.cpp
+index 777b32d..4eb3cf6 100644
+--- a/indra/llwindow/llwindowsdl.cpp
++++ b/indra/llwindow/llwindowsdl.cpp
+@@ -448,7 +448,7 @@ BOOL LLWindowSDL::createContext(int x, int y, int width, int height, int bits, B
+ 
+ 	// Set the application icon.
+ 	SDL_Surface *bmpsurface;
+-	bmpsurface = Load_BMP_Resource("ll_icon.BMP");
++	bmpsurface = Load_BMP_Resource("omvviewer.BMP");
+ 	if (bmpsurface)
+ 	{
+ 		// This attempts to give a black-keyed mask to the icon.
+diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
+index 09d1141..4acbf92 100644
+--- a/indra/newview/llappviewer.cpp
++++ b/indra/newview/llappviewer.cpp
+@@ -1876,7 +1876,7 @@ bool LLAppViewer::initConfiguration()
+     mYieldTime = gSavedSettings.getS32("YieldTime");
+              
+ 	// XUI:translate
+-	gSecondLife = "Second Life";
++	gSecondLife = "Open Metaverse Viewer";
+ 
+ 	// Read skin/branding settings if specified.
+ 	//if (! gDirUtilp->getSkinDir().empty() )
+@@ -2062,7 +2062,7 @@ bool LLAppViewer::initWindow()
+ 
+ 	// always start windowed
+ 	BOOL ignorePixelDepth = gSavedSettings.getBOOL("IgnorePixelDepth");
+-	gViewerWindow = new LLViewerWindow(gWindowTitle, "Second Life",
++	gViewerWindow = new LLViewerWindow(gWindowTitle, "Open Metaverse Viewer",
+ 		gSavedSettings.getS32("WindowX"), gSavedSettings.getS32("WindowY"),
+ 		gSavedSettings.getS32("WindowWidth"), gSavedSettings.getS32("WindowHeight"),
+ 		FALSE, ignorePixelDepth);
+-- 
+tg: (747e686..) topic/debian/trademark_compliance (depends on: upstream)
diff --git a/debian/patches/topic/debian/use_debian-included_fonts.diff b/debian/patches/topic/debian/use_debian-included_fonts.diff
new file mode 100644
index 0000000..c398f8b
--- /dev/null
+++ b/debian/patches/topic/debian/use_debian-included_fonts.diff
@@ -0,0 +1,44 @@
+From: Carlo Wood <carlo at alinoe.com>
+Subject: [PATCH] topic/debian/use_debian-included_fonts
+
+Choose fonts that are included on a debian system.
+
+Signed-off-by: Carlo Wood <carlo at alinoe.com>
+
+---
+ indra/newview/app_settings/settings.xml |    6 +++---
+ 1 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
+index 27eacfb..da0c8cb 100644
+--- a/indra/newview/app_settings/settings.xml
++++ b/indra/newview/app_settings/settings.xml
+@@ -3466,7 +3466,7 @@
+       <key>Type</key>
+       <string>String</string>
+       <key>Value</key>
+-      <string>profontwindows.ttf</string>
++      <string>/usr/share/fonts/truetype/ttf-dejavu/DejaVuSansMono.ttf</string>
+     </map>
+     <key>FontSansSerif</key>
+     <map>
+@@ -3477,7 +3477,7 @@
+       <key>Type</key>
+       <string>String</string>
+       <key>Value</key>
+-      <string>MtBkLfRg.ttf</string>
++      <string>/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans.ttf</string>
+     </map>
+     <key>FontSansSerifBold</key>
+     <map>
+@@ -3488,7 +3488,7 @@
+       <key>Type</key>
+       <string>String</string>
+       <key>Value</key>
+-      <string>MtBdLfRg.ttf</string>
++      <string>/usr/share/fonts/truetype/ttf-dejavu/DejaVuSans-Bold.ttf</string>
+     </map>
+     <key>FontSansSerifFallback</key>
+     <map>
+-- 
+tg: (dfb6a17..) topic/debian/use_debian-included_fonts (depends on: upstream)
diff --git a/debian/patches/topic/debian/use_debian_channel.diff b/debian/patches/topic/debian/use_debian_channel.diff
new file mode 100644
index 0000000..0bc2122
--- /dev/null
+++ b/debian/patches/topic/debian/use_debian_channel.diff
@@ -0,0 +1,25 @@
+From: Robin Cornelius <robin.cornelius at gmail.com>
+Subject: [PATCH] topic/debian/use_debian_channel
+
+Patch to use a custom viewer channel to connect to the SecondLife servers
+
+Signed-off-by: Robin Cornelius <robin.cornelius at gmail.com>
+
+---
+ indra/llcommon/llversionviewer.h |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/indra/llcommon/llversionviewer.h b/indra/llcommon/llversionviewer.h
+index 33e5fdc..53e574b 100644
+--- a/indra/llcommon/llversionviewer.h
++++ b/indra/llcommon/llversionviewer.h
+@@ -37,6 +37,6 @@ const S32 LL_VERSION_MINOR = 22;
+ const S32 LL_VERSION_PATCH = 11;
+ const S32 LL_VERSION_BUILD = 0;
+ 
+-const char * const LL_CHANNEL = "Second Life Release";
++const char * const LL_CHANNEL = "Open Metaverse Viewer";
+ 
+ #endif
+-- 
+tg: (58eae33..) topic/debian/use_debian_channel (depends on: upstream)
diff --git a/debian/patches/topic/debian/viewericon.diff b/debian/patches/topic/debian/viewericon.diff
new file mode 100644
index 0000000..123329a
--- /dev/null
+++ b/debian/patches/topic/debian/viewericon.diff
@@ -0,0 +1,717 @@
+From: Carlo Wood <carlo at alinoe.com>
+Subject: [PATCH] topic/debian/viewericon
+
+Adds an XPM icon to the build.
+This should be removed and the icon should be added directly in debian/ and not applied as a patch.
+
+Signed-off-by: Carlo Wood <carlo at alinoe.com>
+
+---
+ indra/newview/res/viewericon.xpm |  697 ++++++++++++++++++++++++++++++++++++++
+ 1 files changed, 697 insertions(+), 0 deletions(-)
+
+diff --git a/indra/newview/res/viewericon.xpm b/indra/newview/res/viewericon.xpm
+new file mode 100644
+index 0000000..7cf88ad
+--- /dev/null
++++ b/indra/newview/res/viewericon.xpm
+@@ -0,0 +1,697 @@
++/* XPM */
++static char * viewericon_xpm[] = {
++"32 32 662 2",
++"  	c None",
++". 	c #2594FF",
++"+ 	c #2693FF",
++"@ 	c #2894FF",
++"# 	c #2996FF",
++"$ 	c #2B98FF",
++"% 	c #2C9AFF",
++"& 	c #2E99FF",
++"* 	c #319AFF",
++"= 	c #319BFF",
++"- 	c #329CFF",
++"; 	c #339EFF",
++"> 	c #349EFF",
++", 	c #329DFF",
++"' 	c #3099FF",
++") 	c #2D99FF",
++"! 	c #2A97FF",
++"~ 	c #2191FF",
++"{ 	c #2692FF",
++"] 	c #2994FF",
++"^ 	c #2A96FF",
++"/ 	c #2B9AFF",
++"( 	c #329BFF",
++"_ 	c #359FFF",
++": 	c #35A0FF",
++"< 	c #36A0FF",
++"[ 	c #359EFF",
++"} 	c #2E98FF",
++"| 	c #2293FF",
++"1 	c #2995FF",
++"2 	c #339DFF",
++"3 	c #369FFF",
++"4 	c #2D9AFF",
++"5 	c #2394FF",
++"6 	c #2F98FF",
++"7 	c #38A2FF",
++"8 	c #39A2FF",
++"9 	c #3BA4FF",
++"0 	c #3AA3FF",
++"a 	c #38A1FF",
++"b 	c #37A1FF",
++"c 	c #309AFF",
++"d 	c #2593FF",
++"e 	c #2997FF",
++"f 	c #349FFF",
++"g 	c #3BA3FF",
++"h 	c #3CA4FF",
++"i 	c #3EA6FF",
++"j 	c #3EA7FF",
++"k 	c #3FA7FF",
++"l 	c #2D91FE",
++"m 	c #298BFC",
++"n 	c #298AFA",
++"o 	c #2989FA",
++"p 	c #2889FA",
++"q 	c #2688F8",
++"r 	c #2486F8",
++"s 	c #2386F8",
++"t 	c #2488FA",
++"u 	c #2E96FE",
++"v 	c #2893FF",
++"w 	c #3DA5FF",
++"x 	c #3FA8FF",
++"y 	c #2F96FE",
++"z 	c #1978F4",
++"A 	c #136DEE",
++"B 	c #126AEB",
++"C 	c #1269EA",
++"D 	c #116AE9",
++"E 	c #106AE8",
++"F 	c #1069E6",
++"G 	c #1068E6",
++"H 	c #116AEA",
++"I 	c #1C7BF7",
++"J 	c #2A94FF",
++"K 	c #3AA2FF",
++"L 	c #3DA6FF",
++"M 	c #40ADFF",
++"N 	c #41AEFF",
++"O 	c #43B0FF",
++"P 	c #2D95FD",
++"Q 	c #1472EF",
++"R 	c #0F69E6",
++"S 	c #0D67E2",
++"T 	c #0D66E1",
++"U 	c #0C65E0",
++"V 	c #0C64E0",
++"W 	c #0C63E0",
++"X 	c #0E64E2",
++"Y 	c #1874F2",
++"Z 	c #2C96FF",
++"` 	c #2E97FE",
++" .	c #2A91FE",
++"..	c #2C93FE",
++"+.	c #2F94FE",
++"@.	c #3097FE",
++"#.	c #3098FE",
++"$.	c #3197FE",
++"%.	c #359BFE",
++"&.	c #40ACFF",
++"*.	c #44B1FF",
++"=.	c #45B2FF",
++"-.	c #46B2FF",
++";.	c #47B3FF",
++">.	c #3098FD",
++",.	c #1475EE",
++"'.	c #0E6AE6",
++").	c #0C69E2",
++"!.	c #0C68E1",
++"~.	c #0C67E0",
++"{.	c #0C66E0",
++"].	c #0B63E0",
++"^.	c #0E65E2",
++"/.	c #1876F2",
++"(.	c #2C97FF",
++"_.	c #309BFF",
++":.	c #1473F6",
++"<.	c #1069F3",
++"[.	c #106CF3",
++"}.	c #1069F4",
++"|.	c #1068F8",
++"1.	c #106CF8",
++"2.	c #106DF6",
++"3.	c #116EF6",
++"4.	c #1475F8",
++"5.	c #39A3FE",
++"6.	c #3099FE",
++"7.	c #1478F0",
++"8.	c #0E6CE7",
++"9.	c #0C6AE4",
++"0.	c #0E67E2",
++"a.	c #1878F3",
++"b.	c #319BFE",
++"c.	c #116DF4",
++"d.	c #106AF3",
++"e.	c #106AF4",
++"f.	c #1067F7",
++"g.	c #106BF8",
++"h.	c #106DF8",
++"i.	c #106DF5",
++"j.	c #1271F7",
++"k.	c #1577F8",
++"l.	c #36A0FE",
++"m.	c #319AFE",
++"n.	c #147AF0",
++"o.	c #0E6EE8",
++"p.	c #0C6CE6",
++"q.	c #0C68E2",
++"r.	c #0E68E4",
++"s.	c #1A7BF4",
++"t.	c #2D97FF",
++"u.	c #329CFE",
++"v.	c #126EF4",
++"w.	c #1068F5",
++"x.	c #1069F8",
++"y.	c #106EF8",
++"z.	c #106EF4",
++"A.	c #1270F7",
++"B.	c #1477F8",
++"C.	c #1578F8",
++"D.	c #369FFE",
++"E.	c #319BFD",
++"F.	c #1479EF",
++"G.	c #0E6EE7",
++"H.	c #0C6BE5",
++"I.	c #0F6AE6",
++"J.	c #1B7CF5",
++"K.	c #1270F4",
++"L.	c #106BF3",
++"M.	c #1374F8",
++"N.	c #369EFE",
++"O.	c #3099FB",
++"P.	c #1272E8",
++"Q.	c #0C6ADF",
++"R.	c #0C6AE0",
++"S.	c #0C6CE4",
++"T.	c #0F6AE7",
++"U.	c #1C7CF5",
++"V.	c #3EA5FF",
++"W.	c #329DFE",
++"X.	c #106DF7",
++"Y.	c #106EF5",
++"Z.	c #1271F8",
++"`.	c #116DF0",
++" +	c #0D62DE",
++".+	c #0D60DB",
++"++	c #257DF0",
++"@+	c #318CF6",
++"#+	c #318EF9",
++"$+	c #328EF9",
++"%+	c #2079EA",
++"&+	c #0B5ACA",
++"*+	c #0857C6",
++"=+	c #0A61D3",
++"-+	c #0C6CE5",
++";+	c #1C7AF5",
++">+	c #3A91FA",
++",+	c #3D94FA",
++"'+	c #3A92FA",
++")+	c #1969EC",
++"!+	c #1761EE",
++"~+	c #1764F0",
++"{+	c #1767EE",
++"]+	c #1868ED",
++"^+	c #1A6AEE",
++"/+	c #0D48BD",
++"(+	c #0A42AC",
++"_+	c #0B40AB",
++":+	c #164DCE",
++"<+	c #1D54DB",
++"[+	c #1D54DC",
++"}+	c #134AC5",
++"|+	c #083B9F",
++"1+	c #083CA2",
++"2+	c #0C4BB6",
++"3+	c #1261D4",
++"4+	c #1465DD",
++"5+	c #1365DE",
++"6+	c #1564DE",
++"7+	c #1766E2",
++"8+	c #2476EF",
++"9+	c #4599FC",
++"0+	c #469BFC",
++"a+	c #3A93FC",
++"b+	c #5273EE",
++"c+	c #5574EE",
++"d+	c #5272EC",
++"e+	c #2F53D4",
++"f+	c #2C4ED6",
++"g+	c #2C52D7",
++"h+	c #2C52D5",
++"i+	c #2E54D6",
++"j+	c #3053D4",
++"k+	c #1E3BA8",
++"l+	c #1C38A3",
++"m+	c #1D38A3",
++"n+	c #2C40BC",
++"o+	c #3545C6",
++"p+	c #3544C6",
++"q+	c #283EB6",
++"r+	c #1A349B",
++"s+	c #193398",
++"t+	c #1E3AA3",
++"u+	c #2A4FC1",
++"v+	c #2C55CA",
++"w+	c #2B55CC",
++"x+	c #2C55CC",
++"y+	c #2C55CD",
++"z+	c #2F56CF",
++"A+	c #3E61DA",
++"B+	c #5C78F0",
++"C+	c #5E79F2",
++"D+	c #5272F5",
++"E+	c #5573EE",
++"F+	c #5271EC",
++"G+	c #2C4ED5",
++"H+	c #2D52D3",
++"I+	c #2E55D4",
++"J+	c #3154D3",
++"K+	c #1E3AA7",
++"L+	c #1C39A2",
++"M+	c #1C38A2",
++"N+	c #2C42BC",
++"O+	c #3444C4",
++"P+	c #3344C3",
++"Q+	c #2D42BF",
++"R+	c #203AA9",
++"S+	c #1C36A2",
++"T+	c #2440B0",
++"U+	c #385DD0",
++"V+	c #3C63D6",
++"W+	c #3B62D6",
++"X+	c #3C62D7",
++"Y+	c #3D64D8",
++"Z+	c #4C6FE4",
++"`+	c #5C78EE",
++" @	c #5170F2",
++".@	c #5272EB",
++"+@	c #5273EB",
++"@@	c #5172EA",
++"#@	c #385CD9",
++"$@	c #2E51D4",
++"%@	c #2E54D4",
++"&@	c #2F54D2",
++"*@	c #3056D4",
++"=@	c #3256D2",
++"-@	c #1E3AA6",
++";@	c #1D39A2",
++">@	c #1F3BA9",
++",@	c #2C43BE",
++"'@	c #3244C2",
++")@	c #3244C1",
++"!@	c #3247C5",
++"~@	c #314CCA",
++"{@	c #385AD4",
++"]@	c #557DEF",
++"^@	c #557EEF",
++"/@	c #547DEE",
++"(@	c #517EEE",
++"_@	c #507EEE",
++":@	c #4C7AEC",
++"<@	c #4C78EA",
++"[@	c #4770EE",
++"}@	c #5072E7",
++"|@	c #5173E7",
++"1@	c #5474E6",
++"2@	c #5574E7",
++"3@	c #5575E8",
++"4@	c #5776E8",
++"5@	c #5978E9",
++"6@	c #5B78EA",
++"7@	c #3147C2",
++"8@	c #2D42BD",
++"9@	c #2C42BE",
++"0@	c #3043BE",
++"a@	c #3144BE",
++"b@	c #3144BF",
++"c@	c #3153CC",
++"d@	c #3058CD",
++"e@	c #3661D5",
++"f@	c #4F7DEC",
++"g@	c #507EEC",
++"h@	c #4D7EEB",
++"i@	c #4C7EEB",
++"j@	c #4B7FEA",
++"k@	c #4B7FE9",
++"l@	c #4A7EEA",
++"m@	c #467BE9",
++"n@	c #467AE5",
++"o@	c #4370E8",
++"p@	c #4E72E2",
++"q@	c #4F72E2",
++"r@	c #5072E2",
++"s@	c #5574E2",
++"t@	c #5877E5",
++"u@	c #5878E5",
++"v@	c #5978E6",
++"w@	c #5C7DE8",
++"x@	c #5D7CE9",
++"y@	c #2F48C0",
++"z@	c #2A42BA",
++"A@	c #2D41BA",
++"B@	c #3042BA",
++"C@	c #3043BA",
++"D@	c #3043B9",
++"E@	c #3046BD",
++"F@	c #2E57C8",
++"G@	c #2E58C8",
++"H@	c #3460D0",
++"I@	c #4F7DE8",
++"J@	c #4C7EE6",
++"K@	c #4A7FE6",
++"L@	c #4A7FE5",
++"M@	c #4A7FE4",
++"N@	c #477CE4",
++"O@	c #457AE4",
++"P@	c #4478DE",
++"Q@	c #406FE4",
++"R@	c #4B70DE",
++"S@	c #4D72DE",
++"T@	c #4E72DE",
++"U@	c #5073DD",
++"V@	c #5675DF",
++"W@	c #5676E1",
++"X@	c #587AE2",
++"Y@	c #5A7CE4",
++"Z@	c #2E48BB",
++"`@	c #2942B6",
++" #	c #2A42B6",
++".#	c #2E42B5",
++"+#	c #2E43B5",
++"@#	c #2E42B4",
++"##	c #2D44B6",
++"$#	c #2C56C4",
++"%#	c #2C58C4",
++"&#	c #3260CC",
++"*#	c #4B7DE2",
++"=#	c #497DE0",
++"-#	c #477DE0",
++";#	c #487DE0",
++">#	c #467EE0",
++",#	c #467EDF",
++"'#	c #457DDE",
++")#	c #437ADD",
++"!#	c #4279DD",
++"~#	c #4177D9",
++"{#	c #3E6EDE",
++"]#	c #486ED8",
++"^#	c #4B71D9",
++"/#	c #4B72D9",
++"(#	c #4D72D8",
++"_#	c #5374DA",
++":#	c #5475DB",
++"<#	c #5578DC",
++"[#	c #567ADD",
++"}#	c #2C48B7",
++"|#	c #2742B1",
++"1#	c #2A42B1",
++"2#	c #2C42B1",
++"3#	c #2C42B0",
++"4#	c #2B44B2",
++"5#	c #2A56BF",
++"6#	c #2A57BF",
++"7#	c #315EC7",
++"8#	c #467CDC",
++"9#	c #457CDA",
++"0#	c #447CDA",
++"a#	c #437CDA",
++"b#	c #437CD8",
++"c#	c #427CD8",
++"d#	c #427AD8",
++"e#	c #4077D7",
++"f#	c #3F76D5",
++"g#	c #3F75D4",
++"h#	c #3C6FD8",
++"i#	c #466ED2",
++"j#	c #486ED4",
++"k#	c #4A70D4",
++"l#	c #4A70D3",
++"m#	c #4E72D4",
++"n#	c #5174D6",
++"o#	c #5074D6",
++"p#	c #5276D6",
++"q#	c #5277D6",
++"r#	c #2A46B2",
++"s#	c #2540AC",
++"t#	c #2840AC",
++"u#	c #2A42AC",
++"v#	c #2A41AC",
++"w#	c #2A44AE",
++"x#	c #2955BA",
++"y#	c #2856BA",
++"z#	c #2E5EC2",
++"A#	c #447AD6",
++"B#	c #437AD5",
++"C#	c #417AD4",
++"D#	c #407AD2",
++"E#	c #3F79D1",
++"F#	c #3E78D0",
++"G#	c #3E76D1",
++"H#	c #3E75D2",
++"I#	c #3C74CF",
++"J#	c #3B73CE",
++"K#	c #3A6FD5",
++"L#	c #436CCC",
++"M#	c #456ECE",
++"N#	c #466FCE",
++"O#	c #4A71CE",
++"P#	c #4E73D0",
++"Q#	c #4E74D0",
++"R#	c #4F74D0",
++"S#	c #4E74CF",
++"T#	c #2846AD",
++"U#	c #2440A8",
++"V#	c #2340A8",
++"W#	c #2640A7",
++"X#	c #2740A7",
++"Y#	c #2841A7",
++"Z#	c #2843A9",
++"`#	c #2652B5",
++" $	c #2552B5",
++".$	c #2B5CBC",
++"+$	c #417AD0",
++"@$	c #3F79CE",
++"#$	c #3E78CC",
++"$$	c #3C76CA",
++"%$	c #3B76C8",
++"&$	c #3B74C9",
++"*$	c #3B74CC",
++"=$	c #3A73CD",
++"-$	c #3871CA",
++";$	c #3870C9",
++">$	c #386ED0",
++",$	c #426CC7",
++"'$	c #426CC9",
++")$	c #446EC9",
++"!$	c #466FC9",
++"~$	c #4A72CA",
++"{$	c #4C73CC",
++"]$	c #4B72CB",
++"^$	c #2E4FB0",
++"/$	c #2340A4",
++"($	c #223FA4",
++"_$	c #223FA3",
++":$	c #233FA3",
++"<$	c #2442A5",
++"[$	c #224FB0",
++"}$	c #2350B2",
++"|$	c #2E62BC",
++"1$	c #3E79CB",
++"2$	c #3B77C8",
++"3$	c #3A76C5",
++"4$	c #3873C2",
++"5$	c #3771C2",
++"6$	c #3771C5",
++"7$	c #3771C8",
++"8$	c #3770C6",
++"9$	c #3670C5",
++"0$	c #366FC6",
++"a$	c #346CCD",
++"b$	c #3F6BC2",
++"c$	c #406BC2",
++"d$	c #426DC4",
++"e$	c #426EC4",
++"f$	c #456FC4",
++"g$	c #4A72C6",
++"h$	c #4A73C7",
++"i$	c #4A72C7",
++"j$	c #466EC3",
++"k$	c #3E65BC",
++"l$	c #4065BD",
++"m$	c #4166BD",
++"n$	c #4066BD",
++"o$	c #4066BC",
++"p$	c #3F66BD",
++"q$	c #346BBF",
++"r$	c #356DC0",
++"s$	c #3B76C6",
++"t$	c #3B78C4",
++"u$	c #3874C1",
++"v$	c #3672BE",
++"w$	c #3570BD",
++"x$	c #346EBF",
++"y$	c #346EC1",
++"z$	c #346DC1",
++"A$	c #346CC0",
++"B$	c #346DC0",
++"C$	c #346EC2",
++"D$	c #316AC9",
++"E$	c #3C6ABE",
++"F$	c #3D6BBE",
++"G$	c #3F6CC0",
++"H$	c #416CC0",
++"I$	c #426DC0",
++"J$	c #4570C0",
++"K$	c #4872C2",
++"L$	c #4A76C4",
++"M$	c #4E79C7",
++"N$	c #4F7AC7",
++"O$	c #507AC8",
++"P$	c #4E79C8",
++"Q$	c #3D79C4",
++"R$	c #3C7AC4",
++"S$	c #3A79C2",
++"T$	c #3776BF",
++"U$	c #3572BB",
++"V$	c #336FBA",
++"W$	c #326DBB",
++"X$	c #326CBD",
++"Y$	c #326ABD",
++"Z$	c #3169BB",
++"`$	c #3169BA",
++" %	c #316ABB",
++".%	c #2E66C3",
++"+%	c #396ABA",
++"@%	c #3C6BBA",
++"#%	c #3C6ABB",
++"$%	c #3E6CBD",
++"%%	c #406CBD",
++"&%	c #406DBD",
++"*%	c #426EBD",
++"=%	c #456FBD",
++"-%	c #4672BF",
++";%	c #4672C0",
++">%	c #4874C0",
++",%	c #4976C1",
++"'%	c #4B78C2",
++")%	c #4C78C3",
++"!%	c #4E78C3",
++"~%	c #4B78C3",
++"{%	c #3C78C1",
++"]%	c #3A79C1",
++"^%	c #3778BE",
++"/%	c #3673BA",
++"(%	c #326EB8",
++"_%	c #326DBA",
++":%	c #326BBB",
++"<%	c #316ABA",
++"[%	c #2F68B9",
++"}%	c #2E66B8",
++"|%	c #3067BB",
++"1%	c #2C63BF",
++"2%	c #3769B8",
++"3%	c #3969B8",
++"4%	c #3B6AB8",
++"5%	c #3C6AB8",
++"6%	c #3E6CBA",
++"7%	c #3F6DBA",
++"8%	c #416DBA",
++"9%	c #446FBB",
++"0%	c #4672BC",
++"a%	c #4672BD",
++"b%	c #4674BC",
++"c%	c #4674BD",
++"d%	c #4775BE",
++"e%	c #4575BE",
++"f%	c #3A76C0",
++"g%	c #3776BE",
++"h%	c #3573BB",
++"i%	c #326EB6",
++"j%	c #306CB7",
++"k%	c #316CBB",
++"l%	c #3068B8",
++"m%	c #2E66B9",
++"n%	c #2E66BA",
++"o%	c #3068BE",
++"p%	c #2B62C0",
++"q%	c #3769B6",
++"r%	c #3A68B6",
++"s%	c #3B69B6",
++"t%	c #406DBA",
++"u%	c #436EBA",
++"v%	c #4571BB",
++"w%	c #4372BC",
++"x%	c #3774BE",
++"y%	c #3875C3",
++"z%	c #316DB6",
++"A%	c #2F6BB5",
++"B%	c #306BB9",
++"C%	c #326ABB",
++"D%	c #3169BD",
++"E%	c #3169BF",
++"F%	c #3169C0",
++"G%	c #3067BE",
++"H%	c #2E66BC",
++"I%	c #285FBC",
++"J%	c #3667B5",
++"K%	c #3768B6",
++"L%	c #3C6BB9",
++"M%	c #416EBA",
++"N%	c #4470BA",
++"O%	c #4570BB",
++"P%	c #3873BD",
++"Q%	c #3A76C6",
++"R%	c #3974C3",
++"S%	c #336FBC",
++"T%	c #316CB9",
++"U%	c #326CBB",
++"V%	c #336CBD",
++"W%	c #346CC2",
++"X%	c #326AC2",
++"Y%	c #3068C1",
++"Z%	c #2B64B8",
++"`%	c #245AB6",
++" &	c #3466B5",
++".&	c #3668B5",
++"+&	c #3868B6",
++"@&	c #3F6CBA",
++"#&	c #426FBA",
++"$&	c #436FBA",
++"%&	c #4271BA",
++"&&	c #3772BB",
++"*&	c #3975C3",
++"=&	c #3974C4",
++"-&	c #3772C2",
++";&	c #346FBF",
++">&	c #326CBC",
++",&	c #3169BC",
++"'&	c #2D65BC",
++")&	c #2961B5",
++"!&	c #2861B4",
++"~&	c #2056B2",
++". . + @ # $ % % & * * * = - - ; ; > > ; , - - * * * ' ) % % ! ~ ",
++". { ] ^ / % ) ' * * ( , > > _ : < < < : : [ > ; - * * * } % % | ",
++"+ 1 ^ % % & * * ( 2 > 3 < < < < < < < < < < < 3 _ > - * * ' 4 5 ",
++"@ ^ % % 6 * * - > 3 < < < < 7 8 9 9 0 0 a b < < < < [ ; = * c d ",
++"e / % ' * * , f < < < 7 g h i j j j j j i i 9 8 b < < 3 > - * + ",
++"$ % & * * ; [ < < a 9 i j k k k k h l m n o p p q r s t u > - v ",
++"% ) * * , _ < < 8 w k k k k k k x y z A B C D E F G G H I [ > J ",
++"% ' * , [ < < K L k k k k x M N O P Q R S T U U V W W X Y > < Z ",
++"& * = `  . ...+. at .#.$.%.&.*.=.-.;.>.,.'.).!.~.{.U ].].^./.< < (.",
++"c * _.:.<.[.}.|.1.2.3.4.5.;.;.;.;.6.7.8.9.).).!.{.U V 0.a.8 b (.",
++"* ( b.c.d.e.f.g.h.i.j.k.l.;.;.;.;.m.n.o.p.p.9.).q.{.{.r.s.h b t.",
++"* , u.v.[.w.x.y.z.A.B.C.D.;.;.;.;.E.F.G.p.p.p.H.).q.~.I.J.w 9 } ",
++"* > u.K.L.f.1.2.3.M.C.C.N.;.;.;.;.O.P.Q.R.S.p.p.H.).).T.U.V.w 6 ",
++"- > W.K.w.|.X.Y.Z.`. +.+++ at +@+#+$+%+&+*+=+Q.-+p.p.9.).E ;+V.i - ",
++">+,+'+)+!+~+{+]+^+/+(+_+:+<+<+[+[+}+|+1+2+3+4+5+5+5+6+7+8+9+0+a+",
++"b+c+d+e+f+g+h+i+j+k+l+m+n+o+o+o+p+q+r+s+t+u+v+w+w+x+y+z+A+B+C+D+",
++"b+E+F+e+G+h+H+I+J+K+L+M+N+O+O+P+P+Q+R+S+T+U+V+V+W+W+X+Y+Z+`+`+ @",
++". at +@@@#@$@%@&@*@=@-@;@>@,@'@)@)@)@)@!@~@{@]@^@/@(@(@_ at _@_@:@<@[@",
++"}@|@|@1 at 2@3 at 4@5 at 6@7 at 8@9 at 0@a at a@a at a@b at c@d at e@f at g@h at i@j at j@k at l@m at n@o@",
++"p at q@r at s@t at u@v at w@x at y@z at A@B at C@D at D@D at E@F at G@H at I@J at K@L at L@L at M@N at O@P at Q@",
++"R at S@T at U@V at W@W at X@Y at Z@`@ #.#+#+#+#@###$#%#&#*#=#-#;#>#,#'#)#!#~#{#",
++"]#^#/#(#_#:#:#<#[#}#|#|#1#2#2#3#3#4#5#6#7#8#9#0#a#b#c#d#e#f#g#h#",
++"i#j#k#l#m#n#o#p#q#r#s#s#s#t#u#v#u#w#x#y#z#A#B#C#D#E#F#G#H#I#J#K#",
++"L#M#N#N#O#P#Q#R#S#T#U#U#V#V#W#X#Y#Z#`# $.$+$@$#$$$%$&$*$=$-$;$>$",
++",$'$)$)$!$~${${$]$^$/$($_$_$_$_$:$<$[$}$|$1$2$3$4$5$6$7$8$9$0$a$",
++"b$c$d$e$e$f$g$h$i$j$k$l$m$m$n$n$o$p$q$r$s$t$u$v$w$x$y$z$A$B$C$D$",
++"E$F$G$H$I$I$J$K$K$K$K$L$M$N$O$O$O$P$Q$R$S$T$U$V$W$X$Y$Z$`$ %Y$.%",
++"+%@%#%$%%%&%*%=%-%;%;%;%>%,%'%)%!%~%{%]%^%/%(%_%:%<%[%}%}%}%|%1%",
++"2%3%4%5%6%7%7%8%9%0%a%a%0%0%b%c%d%e%f%g%h%i%j%k%<%l%}%m%m%n%o%p%",
++"q%q%r%s%5%6%7%7%t%u%v%0%0%0%0%0%0%w%x%y%v$z%A%B%C%Z$D%E%F%G%H%I%",
++"J%q%K%s%s%L%6%7%7%7%M%N%O%0%0%0%0%w%P%Q%R%S%T%U%V%A$W%X%Y%H%Z%`%",
++" &.&q%+&s%s%5%6%@&7%7%t%t%#&$&N%N%%&&&*&=&-&;&>&C%,&o%'&)&!&!&~&"};
+-- 
+tg: (3916e0e..) topic/debian/viewericon (depends on: upstream)
diff --git a/debian/patches/topic/features/jira-backported/AvatarLoginList.diff b/debian/patches/topic/features/jira-backported/AvatarLoginList.diff
new file mode 100644
index 0000000..bd5d952
--- /dev/null
+++ b/debian/patches/topic/features/jira-backported/AvatarLoginList.diff
@@ -0,0 +1,516 @@
+From: Robin Cornelius <robin.cornelius at gmail.com>
+Subject: [PATCH] topic/features/jira-backported/AvatarLoginList
+
+Add login choice for multiple avatars
+
+Signed-off-by: Robin Cornelius <robin.cornelius at gmail.com>
+
+---
+ indra/llui/llcombobox.cpp                          |    8 ++
+ indra/llui/llcombobox.h                            |    1 +
+ indra/newview/app_settings/settings.xml            |   44 ++++++++++++
+ indra/newview/llpanelgeneral.cpp                   |    8 ++-
+ indra/newview/llpanellogin.cpp                     |   70 +++++++++++++++++++-
+ indra/newview/llpanellogin.h                       |    2 +
+ indra/newview/llstartup.cpp                        |   47 +++++++++++++
+ indra/newview/llviewercontrol.cpp                  |   28 ++++++++
+ .../skins/default/xui/en-us/panel_login.xml        |   12 ++--
+ .../xui/en-us/panel_preferences_general.xml        |   66 ++++++++++++-------
+ 10 files changed, 253 insertions(+), 33 deletions(-)
+
+diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp
+index 3aec2ee..27c1ace 100644
+--- a/indra/llui/llcombobox.cpp
++++ b/indra/llui/llcombobox.cpp
+@@ -450,6 +450,14 @@ void LLComboBox::setButtonVisible(BOOL visible)
+ 	}
+ }
+ 
++void LLComboBox::setTextEntryVisible(BOOL visible)
++{
++	if (mTextEntry)
++	{
++		mTextEntry->setVisible(visible);
++	}
++}
++
+ void LLComboBox::draw()
+ {
+ 	mButton->setEnabled(getEnabled() /*&& !mList->isEmpty()*/);
+diff --git a/indra/llui/llcombobox.h b/indra/llui/llcombobox.h
+index efcb798..5eac287 100644
+--- a/indra/llui/llcombobox.h
++++ b/indra/llui/llcombobox.h
+@@ -173,6 +173,7 @@ public:
+ 	void			setTextEntryCallback( void (*cb)(LLLineEditor*, void*) ) { mTextEntryCallback = cb; }
+ 
+ 	void			setButtonVisible(BOOL visible);
++	void			setTextEntryVisible(BOOL visible);
+ 
+ 	static void		onButtonDown(void *userdata);
+ 	static void		onItemSelected(LLUICtrl* item, void *userdata);
+diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
+index 27eacfb..bdb7bc2 100644
+--- a/indra/newview/app_settings/settings.xml
++++ b/indra/newview/app_settings/settings.xml
+@@ -4158,6 +4158,50 @@
+       <key>Value</key>
+       <integer>0</integer>
+     </map>
++    <key>LoginMRUClearPassword</key>
++    <map>
++      <key>Comment</key>
++      <string>Clear password upon changing the avatar name on the login screen</string>
++      <key>Persist</key>
++      <integer>1</integer>
++      <key>Type</key>
++      <string>Boolean</string>
++      <key>Value</key>
++      <integer>1</integer>
++    </map>
++    <key>LoginMRUEnabled</key>
++    <map>
++      <key>Comment</key>
++      <string>Allow saving a list of alternate avatar names upon login</string>
++      <key>Persist</key>
++      <integer>1</integer>
++      <key>Type</key>
++      <string>Boolean</string>
++      <key>Value</key>
++      <integer>0</integer>
++    </map>
++    <key>LoginMRUList</key>
++    <map>
++      <key>Comment</key>
++      <string>List of previous avatar names presented at login</string>
++      <key>Persist</key>
++      <integer>1</integer>
++      <key>Type</key>
++      <string>LLSD</string>
++      <key>Value</key>
++      <array/>
++    </map>
++    <key>LoginMRULength</key>
++    <map>
++      <key>Comment</key>
++      <string>Number of names to store in LoginMRUList</string>
++      <key>Persist</key>
++      <integer>1</integer>
++      <key>Type</key>
++      <string>S32</string>
++      <key>Value</key>
++      <integer>10</integer>
++    </map>
+     <key>LSLFindCaseInsensitivity</key>
+         <map>
+         <key>Comment</key>
+diff --git a/indra/newview/llpanelgeneral.cpp b/indra/newview/llpanelgeneral.cpp
+index f370116..0067369 100644
+--- a/indra/newview/llpanelgeneral.cpp
++++ b/indra/newview/llpanelgeneral.cpp
+@@ -40,6 +40,7 @@
+ #include "lluictrlfactory.h"
+ #include "llurlsimstring.h"
+ #include "llviewercontrol.h"
++#include "llstartup.h"
+ 
+ LLPanelGeneral::LLPanelGeneral()
+ {
+@@ -70,6 +71,9 @@ BOOL LLPanelGeneral::postBuild()
+ 	childSetValue("ui_scale_slider", gSavedSettings.getF32("UIScaleFactor"));
+ 	childSetValue("ui_auto_scale", gSavedSettings.getBOOL("UIAutoScale"));
+ 
++	childSetValue("save_names_checkbox", gSavedSettings.getBOOL("LoginMRUEnabled"));
++	childSetValue("clear_password_checkbox", gSavedSettings.getBOOL("LoginMRUClearPassword"));
++
+ 	LLComboBox* crash_behavior_combobox = getChild<LLComboBox>("crash_behavior_combobox");
+ 	crash_behavior_combobox->setCurrentByIndex(gCrashSettings.getS32(CRASH_BEHAVIOR_SETTING));
+ 	
+@@ -87,7 +91,9 @@ void LLPanelGeneral::apply()
+ {
+ 	LLComboBox* fade_out_combobox = getChild<LLComboBox>("fade_out_combobox");
+ 	gSavedSettings.setS32("RenderName", fade_out_combobox->getCurrentIndex());
+-	
++
++	gSavedSettings.setBOOL("LoginMRUEnabled", childGetValue("save_names_checkbox"));
++	gSavedSettings.setBOOL("LoginMRUClearPassword", childGetValue("clear_password_checkbox"));
+ 	gSavedSettings.setBOOL("LoginLastLocation", childGetValue("default_start_location").asString() == "MyLastLocation");
+ 	gSavedSettings.setBOOL("ShowStartLocation", childGetValue("show_location_checkbox"));
+ 	gSavedSettings.setBOOL("RenderHideGroupTitleAll", childGetValue("show_all_title_checkbox"));
+diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp
+index 64eecd6..cbdd42c 100644
+--- a/indra/newview/llpanellogin.cpp
++++ b/indra/newview/llpanellogin.cpp
+@@ -393,6 +393,33 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
+ 	childSetPrevalidate("first_name_edit", LLLineEditor::prevalidatePrintableNoSpace);
+ 	childSetPrevalidate("last_name_edit", LLLineEditor::prevalidatePrintableNoSpace);
+ 
++	LLComboBox* name_combo = getChild<LLComboBox>("name_combo");
++	// Only works as intended with this combination of flags,
++	// and in this order of setting them, therefore overriding xui
++	name_combo->setAllowTextEntry(TRUE);
++	name_combo->setTextEntryVisible(FALSE);
++	// Send it down the line, or the invisible text entry covers up our normal
++	// input fields if placed after them in xui
++	sendChildToBack(getChildView("name_combo"));
++
++	bool mru_enabled = gSavedSettings.getBOOL("LoginMRUEnabled");
++	if (mru_enabled)
++	{
++		LLSD name_list = gSavedSettings.getLLSD("LoginMRUList");
++		if (name_list.isArray())
++		{
++			for (LLSD::array_iterator iter = name_list.endArray() - 1; iter != name_list.beginArray()-1; --iter)
++			{
++				if (iter->isMap() && iter->has("first") && iter->has("last"))
++				{
++					name_combo->add((*iter)["first"].asString() + " " + (*iter)["last"].asString(), *iter);
++				}
++			}
++		}
++		childSetCommitCallback("name_combo", onSelectLoginMRU, this);
++	}
++	setLoginMRUEnabled(mru_enabled);
++
+ 	childSetCommitCallback("password_edit", mungePassword);
+ 	childSetKeystrokeCallback("password_edit", onPassKey, this);
+ 	childSetUserData("password_edit", this);
+@@ -941,8 +968,10 @@ void LLPanelLogin::loadLoginPage()
+ 	char* curl_channel = curl_escape(gSavedSettings.getString("VersionChannelName").c_str(), 0);
+ 	char* curl_version = curl_escape(version.c_str(), 0);
+ 
+-	oStr << "&channel=" << curl_channel;
+-	oStr << "&version=" << curl_version;
++        //Hide the channel and version from the webserver or else
++	//it does not return a nice picture for us ;-(
++	//oStr << "&channel=" << curl_channel;
++	//oStr << "&version=" << curl_version;
+ 
+ 	curl_free(curl_channel);
+ 	curl_free(curl_version);
+@@ -1214,3 +1243,40 @@ void LLPanelLogin::onServerComboLostFocus(LLFocusableElement* fe, void*)
+ 		onSelectServer(combo, NULL);	
+ 	}
+ }
++
++// static
++void LLPanelLogin::setLoginMRUEnabled(bool enabled)
++{
++	if (!sInstance)
++	{
++		return;
++	}
++
++	LLComboBox* combo = sInstance->getChild<LLComboBox>("name_combo");
++	if (!enabled) combo->removeall();
++	combo->setButtonVisible(enabled);
++	combo->setEnabled(enabled && combo->getItemCount() != 0);
++}
++
++//static
++void LLPanelLogin::onSelectLoginMRU(LLUICtrl* caller, void* user_data)
++{
++	LLPanelLogin* panel = (LLPanelLogin*) user_data;
++	LLComboBox* name_combo = (LLComboBox*) caller;
++	LLLineEditor* first_name_edit = panel->getChild<LLLineEditor>("first_name_edit");
++	LLLineEditor* last_name_edit = panel->getChild<LLLineEditor>("last_name_edit");
++	LLLineEditor* password_edit = panel->getChild<LLLineEditor>("password_edit");
++
++	LLSD selected_name = name_combo->getValue();
++	std::string first_name = selected_name["first"].asString();
++	std::string last_name = selected_name["last"].asString();
++
++	if (gSavedSettings.getBOOL("LoginMRUClearPassword")
++		&& (first_name_edit->getText() != first_name || last_name_edit->getText() != last_name))
++	{
++		password_edit->setText(LLStringUtil::null);
++	}
++	first_name_edit->setText(first_name);
++	last_name_edit->setText(last_name);
++	password_edit->setFocus(TRUE);
++}
+diff --git a/indra/newview/llpanellogin.h b/indra/newview/llpanellogin.h
+index dba6cf4..2de5dde 100644
+--- a/indra/newview/llpanellogin.h
++++ b/indra/newview/llpanellogin.h
+@@ -85,6 +85,7 @@ public:
+ 
+ 	static void setFields(const std::string& firstname, const std::string& lastname, 
+ 		const std::string& password, BOOL remember);
++	static void setLoginMRUEnabled(bool enabled);
+ 
+ 	static void addServer(const std::string& server, S32 domain_name);
+ 	static void refreshLocation( bool force_visible );
+@@ -115,6 +116,7 @@ private:
+ 	static void onPassKey(LLLineEditor* caller, void* user_data);
+ 	static void onSelectServer(LLUICtrl*, void*);
+ 	static void onServerComboLostFocus(LLFocusableElement*, void*);
++	static void onSelectLoginMRU(LLUICtrl*, void*);
+ 	
+ private:
+ 	LLPointer<LLUIImage> mLogoImage;
+diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
+index 5f25dc3..84c7b7f 100644
+--- a/indra/newview/llstartup.cpp
++++ b/indra/newview/llstartup.cpp
+@@ -1341,6 +1341,53 @@ bool idle_startup()
+ 			gSavedSettings.setString("FirstName", firstname);
+ 			gSavedSettings.setString("LastName", lastname);
+ 
++			if (gSavedSettings.getBOOL("LoginMRUEnabled"))
++			{
++				LLSD mru_list = gSavedSettings.getLLSD("LoginMRUList");
++				if (mru_list.isArray())
++				{
++					// Prepend the current login name to the MRU
++					LLSD login_entry(LLSD::emptyMap());
++					login_entry["first"] = firstname;
++					login_entry["last"] = lastname;
++					mru_list.insert(0, login_entry);
++
++					const S32 names_max = gSavedSettings.getS32("LoginMRULength");
++					for (S32 i = 1; i < mru_list.size(); )
++					{
++						// Trim excess entries
++						if (i >= names_max)
++						{
++							mru_list.erase(i);
++							continue;
++						}
++						// Remove any other instances of the current name
++						login_entry = mru_list[i];
++						if (login_entry.isMap() && login_entry.has("first") && login_entry.has("last"))
++						{
++							if (login_entry["first"].asString() == firstname
++								&& login_entry["last"].asString() == lastname)
++							{
++								mru_list.erase(i);
++							}
++							else
++							{
++								++i;
++							}
++						}
++						else
++						{
++							mru_list.erase(i);
++						}
++					}
++					gSavedSettings.setLLSD("LoginMRUList", mru_list);
++				}
++			}
++			else
++			{
++				gSavedSettings.setLLSD("LoginMRUList", LLSD::emptyArray());
++			}
++
+ 			if (remember_password)
+ 			{
+ 				   save_password_to_disk(password.c_str());
+diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
+index df39ee7..3bcfa12 100644
+--- a/indra/newview/llviewercontrol.cpp
++++ b/indra/newview/llviewercontrol.cpp
+@@ -70,6 +70,8 @@
+ #include "llvosurfacepatch.h"
+ #include "llvowlsky.h"
+ #include "llrender.h"
++#include "llstartup.h"
++#include "llpanellogin.h"
+ 
+ #ifdef TOGGLE_HACKED_GODLIKE_VIEWER
+ BOOL 				gHackGodmode = FALSE;
+@@ -429,6 +431,31 @@ bool handleVoiceClientPrefsChanged(const LLSD& newvalue)
+ 	return true;
+ }
+ 
++bool handleLoginMRUPrefsChanged(const LLSD& newvalue)
++{
++	bool enabled = newvalue.asBoolean();
++	if (enabled)
++	{
++		// Initialize the list with the current name if logged in
++		if (LLStartUp::getStartupState() >= STATE_WORLD_INIT)
++		{
++			// list was previously empty, no need to go through sorting
++			LLSD names = LLSD::emptyArray();
++			names.append(LLSD::emptyMap());
++			names[0]["first"] = gSavedSettings.getString("FirstName");
++			names[0]["last"] = gSavedSettings.getString("LastName");
++			gSavedSettings.setLLSD("LoginMRUList", names);
++		}
++	}
++	else
++	{
++		// Clear the list of avatar names when disabled
++		gSavedSettings.setLLSD("LoginMRUList", LLSD::emptyArray());
++	}
++	LLPanelLogin::setLoginMRUEnabled(enabled);
++	return true;
++}
++
+ ////////////////////////////////////////////////////////////////////////////
+ 
+ void settings_setup_listeners()
+@@ -556,6 +583,7 @@ void settings_setup_listeners()
+ 	gSavedSettings.getControl("VoiceOutputAudioDevice")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _1));
+ 	gSavedSettings.getControl("AudioLevelMic")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _1));
+ 	gSavedSettings.getControl("LipSyncEnabled")->getSignal()->connect(boost::bind(&handleVoiceClientPrefsChanged, _1));	
++	gSavedSettings.getControl("LoginMRUEnabled")->getSignal()->connect(boost::bind(&handleLoginMRUPrefsChanged, _1));	
+ }
+ 
+ template <> eControlType get_control_type<U32>(const U32& in, LLSD& out) 
+diff --git a/indra/newview/skins/default/xui/en-us/panel_login.xml b/indra/newview/skins/default/xui/en-us/panel_login.xml
+index 2122ee7..b048f94 100644
+--- a/indra/newview/skins/default/xui/en-us/panel_login.xml
++++ b/indra/newview/skins/default/xui/en-us/panel_login.xml
+@@ -11,26 +11,28 @@
+ 	<string name="forgot_password_url">
+ 		http://secondlife.com/account/request.php
+ 	</string>
++	<combo_box name="name_combo" allow_text_entry="true" follows="left|bottom"
++	     font="SansSerif" left="32" bottom="30" width="252" height="20" mouse_opaque="true"/>
+ 	<text bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
+ 	     bottom="54" drop_shadow_visible="true" follows="left|bottom"
+ 	     font="SansSerif" h_pad="0" halign="left" height="16"
+-	     left="32" mouse_opaque="true" name="first_name_text" v_pad="0" width="120">
++	     left="32" mouse_opaque="true" name="first_name_text" v_pad="0" width="114">
+ 		First Name:
+ 	</text>
+ 	<line_editor bevel_style="in" border_style="line" border_thickness="1" bottom_delta="-24"
+ 	     follows="left|bottom" font="SansSerif" handle_edit_keys_directly="true"
+ 	     height="20" left="32" max_length="31" mouse_opaque="true"
+-	     name="first_name_edit" select_all_on_focus_received="true" width="120" />
++	     name="first_name_edit" select_all_on_focus_received="true" width="118" />
+ 	<text bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
+ 	     bottom="54" drop_shadow_visible="true" follows="left|bottom"
+ 	     font="SansSerif" h_pad="0" halign="left" height="16"
+-	     left="164" mouse_opaque="true" name="last_name_text" v_pad="0" width="120">
++	     left_delta="117" mouse_opaque="true" name="last_name_text" v_pad="0" width="114">
+ 		Last Name:
+ 	</text>
+ 	<line_editor bevel_style="in" border_style="line" border_thickness="1" bottom_delta="-24"
+ 	     follows="left|bottom" font="SansSerif" handle_edit_keys_directly="true"
+-	     height="20" left="164" max_length="31" mouse_opaque="true"
+-	     name="last_name_edit" select_all_on_focus_received="true" width="120" />
++	     height="20" left_delta="0" max_length="31" mouse_opaque="true"
++	     name="last_name_edit" select_all_on_focus_received="true" width="114" />
+ 	<text bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
+ 	     bottom="54" drop_shadow_visible="true" follows="left|bottom"
+ 	     font="SansSerif" h_pad="0" halign="left" height="16"
+diff --git a/indra/newview/skins/default/xui/en-us/panel_preferences_general.xml b/indra/newview/skins/default/xui/en-us/panel_preferences_general.xml
+index ea04dfc..8a19967 100644
+--- a/indra/newview/skins/default/xui/en-us/panel_preferences_general.xml
++++ b/indra/newview/skins/default/xui/en-us/panel_preferences_general.xml
+@@ -2,22 +2,49 @@
+ <panel border="true" bottom="-409" enabled="true" follows="left|top|right|bottom"
+      height="408" label="General" left="102" mouse_opaque="true"
+      name="general_panel" width="517">
+-  <radio_group bottom="-45" draw_border="false" follows="left|bottom" height="40" left="151"
++	<text type="string" length="1" bottom="-25" follows="left|top" font="SansSerifSmall" h_pad="0"
++	     halign="left" height="16" left="10" name="alt_avatars_textbox" v_pad="0"
++	     width="394">
++		Recent Logins:
++	</text>
++	<check_box name="save_names_checkbox" follows="left|top"
++	     left="151" bottom_delta="0" width="149" height="16"
++	     label="Save name list" initial_value="true"
++	     radio_style="false" font="SansSerifSmall"
++	     tool_tip="Save a list of recently used avatar names.\nYou may wish to turn this off if more than one person has access to this computer."/>
++	<check_box bottom_delta="0" follows="left|top"
++	     font="SansSerifSmall" height="16" initial_value="false"
++	     label="Clear password when selecting" left_delta="105" mouse_opaque="true"
++		 tool_tip="Clears the password entry box when selecting a different avatar name at login."
++	     name="clear_password_checkbox" radio_style="false" width="200" />
++	<text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
++	     bottom_delta="-22" drop_shadow_visible="true" enabled="true" follows="left|top"
++	     font="SansSerifSmall" h_pad="0" halign="left" height="10" left="10"
++	     mouse_opaque="true" name="start_location_textbox" v_pad="0" width="394">
++		Start Location:
++	</text>
++  <radio_group bottom_delta="-22" draw_border="false" follows="left|bottom" height="40" left="151"
+ 	     name="default_start_location" width="220">
+     <radio_item bottom="-20" height="20" left="0" name="MyHome" width="50"
+ 		  tool_tip="Log into my home location by default.">
+       My Home
+     </radio_item>
+-    <radio_item bottom="-20" height="20" left="100" name="MyLastLocation" width="50"
++    <radio_item bottom="-20" height="20" left="105" name="MyLastLocation" width="50"
+ 		  tool_tip="Log into my last location by default.">
+       My Last Location
+     </radio_item>
+   </radio_group>
+-  <check_box bottom="-44" enabled="true" follows="left|top"
++	<check_box bottom_delta="0" enabled="true" follows="left|top"
+        font="SansSerifSmall" height="16" initial_value="true"
+        label="Show Start Location on Login Screen" left="151" mouse_opaque="true"
+        name="show_location_checkbox" radio_style="false" width="256" />
+-	<combo_box bottom_delta="-25" follows="left|top" height="18" left="155"
++	<text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
++	     bottom_delta="-25" drop_shadow_visible="true" enabled="true" follows="left|top"
++	     font="SansSerifSmall" h_pad="0" halign="left" height="10" left="10"
++	     mouse_opaque="true" name="show_names_textbox" v_pad="0" width="394">
++		Show Name Tags:
++	</text>
++	<combo_box bottom_delta="-4" follows="left|top" height="18" left="155"
+ 	     mouse_opaque="true" name="fade_out_combobox" width="146">
+ 		<combo_item name="Never" value="Never">
+ 			Never
+@@ -30,13 +57,14 @@
+ 		</combo_item>
+ 	</combo_box>
+ 	<check_box bottom_delta="-25" follows="left|top"
+-	     font="SansSerifSmall" height="16" initial_value="true"
+-	     label="Small Avatar Names" left="151" name="small_avatar_names_checkbox"
+-	     width="200" />
+-	<check_box bottom_delta="-18" follows="left|top"
+ 	     font="SansSerifSmall" height="16" initial_value="false"
+ 	     label="Hide My Name On My Screen" left="151" name="show_my_name_checkbox"
++	     width="180" />
++	<check_box bottom_delta="0" follows="left|top"
++	     font="SansSerifSmall" height="16" initial_value="true"
++	     label="Small Avatar Names" left_delta="180" name="small_avatar_names_checkbox"
+ 	     width="200" />
++	     width="149" />
+ 	<text type="string" length="1" bottom_delta="-24" follows="left|top" font="SansSerifSmall" h_pad="0"
+ 	     halign="left" height="16" left="10" name="group_titles_textbox" v_pad="0"
+ 	     width="394">
+@@ -44,12 +72,12 @@
+ 	</text>
+ 	<check_box bottom_delta="0" follows="left|top"
+ 	     font="SansSerifSmall" height="16" initial_value="false"
+-	     label="Hide All Group Titles" left="151" mouse_opaque="true"
+-	     name="show_all_title_checkbox" radio_style="false" width="256" />
+-	<check_box bottom_delta="-18" follows="left|top"
+-	     font="SansSerifSmall" height="16" initial_value="false"
+ 	     label="Hide My Group Title" left="151" name="show_my_title_checkbox"
+-	     radio_style="false" width="256" />
++	     radio_style="false" width="149" />
++	<check_box bottom_delta="0" follows="left|top"
++	     font="SansSerifSmall" height="16" initial_value="false"
++	     label="Hide All Group Titles" left_delta="180" mouse_opaque="true"
++	     name="show_all_title_checkbox" radio_style="false" width="200" />
+ 	<color_swatch border_color="0.45098 0.517647 0.607843 1" bottom="-210"
+ 	     can_apply_immediately="false" color="1 1 1 1"
+ 	     enabled="true" follows="left|top" height="48" label="" left="153"
+@@ -94,18 +122,6 @@
+ 	     name="show_search_panel" radio_style="false"
+ 	     tool_tip="Display the embedded search panel." width="256" />
+ 	<text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
+-	     bottom="-20" drop_shadow_visible="true" enabled="true" follows="left|top"
+-	     font="SansSerifSmall" h_pad="0" halign="left" height="10" left="10"
+-	     mouse_opaque="true" name="start_location_textbox" v_pad="0" width="394">
+-		Start Location:
+-	</text>
+-	<text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
+-	     bottom="-64" drop_shadow_visible="true" enabled="true" follows="left|top"
+-	     font="SansSerifSmall" h_pad="0" halign="left" height="10" left="10"
+-	     mouse_opaque="true" name="show_names_textbox" v_pad="0" width="394">
+-		Show Names:
+-	</text>
+-	<text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
+ 	     bottom="-184" drop_shadow_visible="true" enabled="true" follows="left|top"
+ 	     font="SansSerifSmall" h_pad="0" halign="left" height="10" left="10"
+ 	     mouse_opaque="true" name="effects_color_textbox" v_pad="0" width="394">
+-- 
+tg: (1836a2b..) topic/features/jira-backported/AvatarLoginList (depends on: upstream)
diff --git a/debian/patches/topic/features/jira-backported/VWR-11663_Save_Load_scripts.diff b/debian/patches/topic/features/jira-backported/VWR-11663_Save_Load_scripts.diff
new file mode 100644
index 0000000..68e9d1e
--- /dev/null
+++ b/debian/patches/topic/features/jira-backported/VWR-11663_Save_Load_scripts.diff
@@ -0,0 +1,210 @@
+From: Robin Cornelius <robin.cornelius at gmail.com>
+Subject: [PATCH] topic/features/jira-backported/VWR-11663_Save_Load_scripts
+
+<patch description>
+
+Signed-off-by: Robin Cornelius <robin.cornelius at gmail.com>
+
+---
+ indra/newview/llfilepicker.cpp                     |   17 +++++
+ indra/newview/llfilepicker.h                       |    3 +
+ indra/newview/llpreviewscript.cpp                  |   62 ++++++++++++++++++++
+ indra/newview/llpreviewscript.h                    |    2 +
+ .../default/xui/en-us/floater_script_ed_panel.xml  |    6 ++
+ .../silver/xui/en-us/floater_script_ed_panel.xml   |    8 ++-
+ 6 files changed, 97 insertions(+), 1 deletions(-)
+
+diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp
+index f9616ba..9522930 100644
+--- a/indra/newview/llfilepicker.cpp
++++ b/indra/newview/llfilepicker.cpp
+@@ -58,6 +58,7 @@ LLFilePicker LLFilePicker::sInstance;
+ #define XML_FILTER L"XML files (*.xml)\0*.xml\0"
+ #define SLOBJECT_FILTER L"Objects (*.slobject)\0*.slobject\0"
+ #define RAW_FILTER L"RAW files (*.raw)\0*.raw\0"
++#define TEXT_FILTER L"Text files (*.txt; *.rtf)\0*.txt;*.rtf;*.lsl\0"
+ #endif
+ 
+ //
+@@ -160,6 +161,10 @@ BOOL LLFilePicker::setupFilter(ELoadFilter filter)
+ 		ANIM_FILTER \
+ 		L"\0";
+ 		break;
++	case FFLOAD_TEXT:
++		mOFN.lpstrFilter = TEXT_FILTER \
++			L"\0";
++		break;
+ 	case FFLOAD_WAV:
+ 		mOFN.lpstrFilter = SOUND_FILTER \
+ 			L"\0";
+@@ -327,6 +332,18 @@ BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename)
+ 			L"Targa, Bitmap Images (*.tga; *.bmp)\0*.tga;*.bmp\0" \
+ 			L"\0";
+ 		break;
++	case FFSAVE_TEXT:
++		if (filename.empty())
++		{
++			wcsncpy( mFilesW,L"untitled.txt", FILENAME_BUFFER_SIZE);	/*Flawfinder: ignore*/
++		}
++		mOFN.lpstrDefExt = L"txt";
++		mOFN.lpstrFilter = 
++			L"Text files (*.txt)\0*.txt\0"
++			L"RTF Files (*.rtf)\0*.rtf\0"
++			L"LSL Files (*.lsl)\0*.lsl\0"
++			L"\0";
++		break;
+ 	case FFSAVE_WAV:
+ 		if (filename.empty())
+ 		{
+diff --git a/indra/newview/llfilepicker.h b/indra/newview/llfilepicker.h
+index aea414a..3dc0301 100644
+--- a/indra/newview/llfilepicker.h
++++ b/indra/newview/llfilepicker.h
+@@ -90,6 +90,8 @@ public:
+ 		FFLOAD_XML = 6,
+ 		FFLOAD_SLOBJECT = 7,
+ 		FFLOAD_RAW = 8,
++		FFLOAD_TEXT = 9,
++
+ 	};
+ 
+ 	enum ESaveFilter
+@@ -109,6 +111,7 @@ public:
+ 		FFSAVE_J2C = 12,
+ 		FFSAVE_PNG = 13,
+ 		FFSAVE_JPEG = 14,
++		FFSAVE_TEXT = 15,
+ 	};
+ 
+ 	// open the dialog. This is a modal operation
+diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp
+index af52a4b..a12369b 100644
+--- a/indra/newview/llpreviewscript.cpp
++++ b/indra/newview/llpreviewscript.cpp
+@@ -436,6 +436,14 @@ void LLScriptEdCore::initMenu()
+ 	menuItem->setMenuCallback(onBtnHelp, this);
+ 	menuItem->setEnabledCallback(NULL);
+ 
++	menuItem = getChild<LLMenuItemCallGL>("Load from Disc");
++	menuItem->setMenuCallback(onBtnLoadFromDisc, this);
++	menuItem->setEnabledCallback(NULL);
++
++	menuItem = getChild<LLMenuItemCallGL>("Save to Disc");
++	menuItem->setMenuCallback(onBtnSaveToDisc, this);
++	menuItem->setEnabledCallback(hasChanged);
++
+ 	menuItem = getChild<LLMenuItemCallGL>("LSL Wiki Help...");
+ 	menuItem->setMenuCallback(onBtnDynamicHelp, this);
+ 	menuItem->setEnabledCallback(NULL);
+@@ -823,6 +831,60 @@ void LLScriptEdCore::onBtnUndoChanges( void* userdata )
+ 	}
+ }
+ 
++void LLScriptEdCore::onBtnSaveToDisc( void* userdata )
++{
++
++	LLViewerStats::getInstance()->incStat( LLViewerStats::ST_LSL_SAVE_COUNT );
++
++   LLScriptEdCore* self = (LLScriptEdCore*) userdata;
++
++   if( self->mSaveCallback )
++   {
++      LLFilePicker& file_picker = LLFilePicker::instance();
++	if( !file_picker.getSaveFile( LLFilePicker::FFSAVE_TEXT ) )
++	{
++		return;
++	}
++	
++		std::string filename = file_picker.getFirstFile();
++      std::string scriptText=self->mEditor->getText();
++	  std::ofstream fout(filename.c_str());
++      fout<<(scriptText);
++      fout.close();
++      self->mSaveCallback( self->mUserdata, FALSE );
++         
++   }
++	
++}
++void LLScriptEdCore::onBtnLoadFromDisc( void* data )
++{
++
++	LLScriptEdCore* self = (LLScriptEdCore*) data;
++	
++	LLFilePicker& file_picker = LLFilePicker::instance();
++	if( !file_picker.getOpenFile( LLFilePicker::FFLOAD_TEXT ) )
++	{
++		return;
++	}
++	
++	std::string filename = file_picker.getFirstFile();
++
++	std::ifstream fin(filename.c_str());
++	
++	std::string line;
++	std::string linetotal;
++	self->mEditor->clear();
++	while (!fin.eof())
++	{ 
++		getline(fin,line);
++		line=line+"\n";
++		self->mEditor->insertText(line);
++
++	}
++	fin.close();
++	
++}
++
+ void LLScriptEdCore::onSearchMenu(void* userdata)
+ {
+ 	LLScriptEdCore* sec = (LLScriptEdCore*)userdata;
+diff --git a/indra/newview/llpreviewscript.h b/indra/newview/llpreviewscript.h
+index 7026482..97e721d 100644
+--- a/indra/newview/llpreviewscript.h
++++ b/indra/newview/llpreviewscript.h
+@@ -95,6 +95,8 @@ public:
+ 	static void		doSave( void* userdata, BOOL close_after_save );
+ 	static void		onBtnSave(void*);
+ 	static void		onBtnUndoChanges(void*);
++	static void		onBtnSaveToDisc(void*);
++	static void		onBtnLoadFromDisc(void*);
+ 	static void		onSearchMenu(void* userdata);
+ 
+ 	static void		onUndoMenu(void* userdata);
+diff --git a/indra/newview/skins/default/xui/en-us/floater_script_ed_panel.xml b/indra/newview/skins/default/xui/en-us/floater_script_ed_panel.xml
+index b83a6df..154cb1c 100644
+--- a/indra/newview/skins/default/xui/en-us/floater_script_ed_panel.xml
++++ b/indra/newview/skins/default/xui/en-us/floater_script_ed_panel.xml
+@@ -35,6 +35,12 @@
+ 			     width="138" />
+ 			<menu_item_call bottom_delta="-58" height="20" label="Revert All Changes" left="0"
+ 			     mouse_opaque="true" name="Revert All Changes" width="138" />
++      <menu_item_separator bottom_delta="-66" height="8" left="0" mouse_opaque="true" name="separator"
++     width="138" />
++      <menu_item_call bottom_delta="-76" height="20" label="Save to Disc" left="0"
++     mouse_opaque="true" name="Save to Disc" width="138" />
++      <menu_item_call bottom_delta="-96" height="20" label="Load from Disc" left="0"
++     mouse_opaque="true" name="Load from Disc" width="138" />
+ 		</menu>
+ 		<menu bottom="665" drop_shadow="true" enabled="true" height="198"
+ 		     left="222" mouse_opaque="false" name="Edit" opaque="true" tear_off="false"
+diff --git a/indra/newview/skins/silver/xui/en-us/floater_script_ed_panel.xml b/indra/newview/skins/silver/xui/en-us/floater_script_ed_panel.xml
+index 022065e..7d791c4 100644
+--- a/indra/newview/skins/silver/xui/en-us/floater_script_ed_panel.xml
++++ b/indra/newview/skins/silver/xui/en-us/floater_script_ed_panel.xml
+@@ -34,7 +34,13 @@
+ 			<menu_item_separator bottom_delta="-38" height="8" left="0" mouse_opaque="true" name="separator"
+ 			     width="138" />
+ 			<menu_item_call bottom_delta="-58" height="20" label="Revert All Changes" left="0"
+-			     mouse_opaque="true" name="Revert All Changes" width="138" />
++			     mouse_opaque="true" name="Revert All Changes" width="138" />
++                         <menu_item_separator bottom_delta="-66" height="8" left="0" mouse_opaque="true" name="separator"
++                             width="138" />
++                              <menu_item_call bottom_delta="-76" height="20" label="Save to Disc" left="0"
++                             mouse_opaque="true" name="Save to Disc" width="138" />
++                              <menu_item_call bottom_delta="-96" height="20" label="Load from Disc" left="0"
++                             mouse_opaque="true" name="Load from Disc" width="138" />
+ 		</menu>
+ 		<menu bottom="665" drop_shadow="true" enabled="true" height="198"
+ 		     left="222" mouse_opaque="false" name="Edit" opaque="true" tear_off="false"
+-- 
+tg: (1836a2b..) topic/features/jira-backported/VWR-11663_Save_Load_scripts (depends on: upstream)
diff --git a/debian/patches/topic/features/jira-backported/VWR-5082_set_bulk_inv_permissions.diff b/debian/patches/topic/features/jira-backported/VWR-5082_set_bulk_inv_permissions.diff
new file mode 100644
index 0000000..9ea7cc0
--- /dev/null
+++ b/debian/patches/topic/features/jira-backported/VWR-5082_set_bulk_inv_permissions.diff
@@ -0,0 +1,965 @@
+From: Carlo Wood <carlo at alinoe.com>
+Subject: [PATCH] topic/features/jira-backported/VWR-5082_set_bulk_inv_permissions
+
+This is applied upstream (in a feature branch) and allows multiple object inventory items to have permissions set in one go.
+
+Signed-off-by: Carlo Wood <carlo at alinoe.com>
+
+---
+ indra/newview/CMakeLists.txt                       |    1 +
+ indra/newview/llfloaterbulkpermission.cpp          |  594 ++++++++++++++++++++
+ indra/newview/llfloaterbulkpermission.h            |  143 +++++
+ indra/newview/llviewermenu.cpp                     |   12 +
+ .../skins/default/xui/en-us/floater_bulk_perms.xml |  127 +++++
+ .../skins/default/xui/en-us/menu_viewer.xml        |    5 +
+ 6 files changed, 882 insertions(+), 0 deletions(-)
+
+diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
+index b95ba37..35ae507 100644
+--- a/indra/newview/CMakeLists.txt
++++ b/indra/newview/CMakeLists.txt
+@@ -127,6 +127,7 @@ set(viewer_SOURCE_FILES
+     llfloateravatartextures.cpp
+     llfloaterbeacons.cpp
+     llfloaterbuildoptions.cpp
++    llfloaterbulkpermission.cpp
+     llfloaterbump.cpp
+     llfloaterbuycontents.cpp
+     llfloaterbuy.cpp
+diff --git a/indra/newview/llfloaterbulkpermission.cpp b/indra/newview/llfloaterbulkpermission.cpp
+new file mode 100644
+index 0000000..e66d1af
+--- /dev/null
++++ b/indra/newview/llfloaterbulkpermission.cpp
+@@ -0,0 +1,594 @@
++/** 
++ * @file llfloaterbulkpermissions.cpp
++ * @brief A floater which allows task inventory item's properties to be changed on mass.
++ *
++ * $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$
++ */
++
++/* Allow multiple task inventory properties to be set in one go, by Michelle2 Zenovka */
++
++/* TODO
++	
++	* Add in the option to select objects or task inventory
++s
++
++It would be nice to set the permissions on groups of prims as well as task inventory
++
++*/
++
++
++#include "llviewerprecompiledheaders.h"
++#include "llfloaterbulkpermission.h"
++#include "llagent.h"
++#include "llchat.h"
++#include "llviewerwindow.h"
++#include "llviewerobject.h"
++#include "llviewerobjectlist.h"
++#include "llviewerregion.h"
++#include "lscript_rt_interface.h"
++#include "llviewercontrol.h"
++#include "llviewerobject.h"
++#include "llviewerregion.h"
++#include "llresmgr.h"
++#include "llbutton.h"
++#include "lldir.h"
++#include "llfloaterchat.h"
++#include "llviewerstats.h"
++#include "lluictrlfactory.h"
++#include "llselectmgr.h"
++#include "llinventory.h"
++
++
++#include <algorithm>
++#include <functional>
++#include "llcachename.h"
++#include "lldbstrings.h"
++#include "llinventory.h"
++
++#include "llagent.h"
++#include "llbutton.h"
++#include "llcheckboxctrl.h"
++#include "llfloateravatarinfo.h"
++#include "llfloatergroupinfo.h"
++#include "llinventorymodel.h"
++#include "lllineeditor.h"
++#include "llradiogroup.h"
++#include "llresmgr.h"
++#include "roles_constants.h"
++#include "llselectmgr.h"
++#include "lltextbox.h"
++#include "lluiconstants.h"
++#include "llviewerinventory.h"
++#include "llviewerobjectlist.h"
++#include "llviewerregion.h"
++#include "llviewercontrol.h"
++
++#include "lluictrlfactory.h"
++
++
++const char* BULKPERM_QUEUE_TITLE = "Update Progress";
++const char* BULKPERM_START_STRING = "update";
++
++namespace
++{
++	struct BulkQueueObjects : public LLSelectedObjectFunctor
++	{
++		BOOL scripted;
++		BOOL modifiable;
++		LLFloaterBulkPermission* mQueue;
++		BulkQueueObjects(LLFloaterBulkPermission* q) : mQueue(q), scripted(FALSE), modifiable(FALSE) {}
++		virtual bool apply(LLViewerObject* obj)
++		{
++			scripted = obj->flagScripted();
++			modifiable = obj->permModify();
++
++			mQueue->addObject(obj->getID());
++			return false;
++			
++		}
++	};
++}
++
++///----------------------------------------------------------------------------
++/// Class LLFloaterBulkPermission
++///----------------------------------------------------------------------------
++
++// static
++LLMap<LLUUID, LLFloaterBulkPermission*> LLFloaterBulkPermission::sInstances;
++
++
++// Default constructor
++LLFloaterBulkPermission::LLFloaterBulkPermission(const std::string& name,
++											 const LLRect& rect,
++											 const char* title,
++											 const char* start_string) :
++	LLFloater(name, rect, title,
++			  RESIZE_YES, DEFAULT_MIN_WIDTH, DEFAULT_MIN_HEIGHT,
++			  DRAG_ON_TOP, MINIMIZE_YES, CLOSE_YES)
++{
++
++	req_perm_mask=0; // This should match the default state the checkboxes are set to
++	recurse=false;
++
++	LLUICtrlFactory::getInstance()->buildFloater(this,"floater_bulk_perms.xml");
++
++	childSetAction("Apply...",onApplyBtn,this);
++	childSetEnabled("Apply...",TRUE);
++
++	childSetCommitCallback("Modify",&onCommitPermissions, this);
++	childSetCommitCallback("Trans",&onCommitPermissions, this);
++	childSetCommitCallback("Copy",&onCommitPermissions, this);
++
++	//childSetCommitCallback("Recurse",&onRecurse, this);
++
++	childSetCommitCallback("Parent",&onParent, this);
++
++	childSetCommitCallback("objects",&InvSelection, this);
++	childSetCommitCallback("scripts",&InvSelection, this);
++	childSetCommitCallback("textures",&InvSelection, this);
++	childSetCommitCallback("sounds",&InvSelection, this);
++	childSetCommitCallback("animations",&InvSelection, this);
++	childSetCommitCallback("notecards",&InvSelection, this);
++	childSetCommitCallback("landmarks",&InvSelection, this);
++	childSetCommitCallback("bodyparts",&InvSelection, this);
++	childSetCommitCallback("clothing",&InvSelection, this);
++	childSetCommitCallback("gestures",&InvSelection, this);
++
++	//Set variable state to XUI default state consistancy
++	processObject=getChild<LLCheckBoxCtrl>("objects")->get();
++	processScript=getChild<LLCheckBoxCtrl>("scripts")->get();
++	processTexture=getChild<LLCheckBoxCtrl>("textures")->get();
++	processSound=getChild<LLCheckBoxCtrl>("sounds")->get();
++	processAnimation=getChild<LLCheckBoxCtrl>("animations")->get();
++	processNotecard=getChild<LLCheckBoxCtrl>("notecards")->get();
++	processGesture=getChild<LLCheckBoxCtrl>("gestures")->get();
++	processClothing=getChild<LLCheckBoxCtrl>("clothing")->get();
++	processBodypart=getChild<LLCheckBoxCtrl>("bodyparts")->get();
++	processLandmark=getChild<LLCheckBoxCtrl>("landmarks")->get();
++	parent=getChild<LLCheckBoxCtrl>("Parent")->get();
++
++
++	setTitle(title);
++	
++	if (!getHost())
++	{
++		LLRect curRect = getRect();
++		translate(rect.mLeft - curRect.mLeft, rect.mTop - curRect.mTop);
++	}
++	
++	mStartString = start_string;
++	mDone = FALSE;
++	sInstances.addData(mID, this);
++
++}
++
++void LLFloaterBulkPermission::doApply()
++{
++	// Its alive now do the nasty work that the ScriptQueue and friends try to do in the menu code
++	// but first grab the user options
++
++	LLScrollListCtrl* list = getChild<LLScrollListCtrl>("queue output");
++	list->deleteAllItems();
++
++	//Apply to selected objects if requested first
++
++	if(parent)
++	{
++		llinfos<< "Setting permission on parent items" << llendl;
++		LLSelectMgr::getInstance()->selectionSetObjectPermissions(PERM_NEXT_OWNER,true, req_perm_mask);
++		LLSelectMgr::getInstance()->selectionSetObjectPermissions(PERM_NEXT_OWNER,false, ~req_perm_mask); //How annoying need to set and unset
++	}
++
++
++	LLFloaterBulkPermission* q;
++	q=(LLFloaterBulkPermission*)this;
++
++	BulkQueueObjects func(q);
++	bool fail = LLSelectMgr::getInstance()->getSelection()->applyToObjects(&func);
++	if(fail)
++	{
++		if ( !func.modifiable )
++		{
++			gViewerWindow->alertXml("NO MODIFY");
++		}
++		else
++		{
++			llwarns << "Bad logic. Are there actualy any items in that prim?" << llendl;
++		}
++	}
++	else
++	{
++		if (!q->start())
++		{
++			llwarns << "Unexpected failure attepmting to set permissions." << llendl;
++		}
++	}
++}
++
++// Destroys the object
++LLFloaterBulkPermission::~LLFloaterBulkPermission()
++{
++	sInstances.removeData(mID);
++}
++
++// find an instance by ID. Return NULL if it does not exist.
++// static
++LLFloaterBulkPermission* LLFloaterBulkPermission::findInstance(const LLUUID& id)
++{
++	if(sInstances.checkData(id))
++	{
++		return sInstances.getData(id);
++	}
++	return NULL;
++}
++
++
++// This is the callback method for the viewer object currently being
++// worked on.
++// NOT static, virtual!
++void LLFloaterBulkPermission::inventoryChanged(LLViewerObject* viewer_object,
++											 InventoryObjectList* inv,
++											 S32,
++											 void* q_id)
++{
++	llinfos << "LLFloaterBulkPermission::inventoryChanged() for  object "
++			<< viewer_object->getID() << llendl;
++
++	//Remove this listener from the object since its
++	//listener callback is now being executed.
++	
++	//We remove the listener here because the function
++	//removeVOInventoryListener removes the listener from a ViewerObject
++	//which it internally stores.
++	
++	//If we call this further down in the function, calls to handleInventory
++	//and nextObject may update the interally stored viewer object causing
++	//the removal of the incorrect listener from an incorrect object.
++	
++	//Fixes SL-6119:Recompile scripts fails to complete
++	removeVOInventoryListener();
++
++	if (viewer_object && inv && (viewer_object->getID() == mCurrentObjectID) )
++	{
++		handleInventory(viewer_object, inv);
++	}
++	else
++	{
++		// something went wrong...
++		// note that we're not working on this one, and move onto the
++		// next object in the list.
++		llwarns << "No inventory for " << mCurrentObjectID
++				<< llendl;
++		nextObject();
++	}
++}
++
++void LLFloaterBulkPermission::onApplyBtn(void* user_data)
++{
++	LLFloaterBulkPermission* self = (LLFloaterBulkPermission*)user_data;
++	self->doApply();
++}
++
++
++// static
++void LLFloaterBulkPermission::InvSelection(LLUICtrl* ctrl, void* data)
++{
++	LLFloaterBulkPermission* self = (LLFloaterBulkPermission*)data;
++
++	self->processObject=self->getChild<LLCheckBoxCtrl>("objects")->get();
++	self->processScript=self->getChild<LLCheckBoxCtrl>("scripts")->get();
++	self->processTexture=self->getChild<LLCheckBoxCtrl>("textures")->get();
++	self->processSound=self->getChild<LLCheckBoxCtrl>("sounds")->get();
++	self->processAnimation=self->getChild<LLCheckBoxCtrl>("animations")->get();
++	self->processNotecard=self->getChild<LLCheckBoxCtrl>("notecards")->get();
++	self->processGesture=self->getChild<LLCheckBoxCtrl>("gestures")->get();
++	self->processClothing=self->getChild<LLCheckBoxCtrl>("clothing")->get();
++	self->processBodypart=self->getChild<LLCheckBoxCtrl>("bodyparts")->get();
++	self->processLandmark=self->getChild<LLCheckBoxCtrl>("landmarks")->get();
++
++
++}
++
++// static
++void LLFloaterBulkPermission::onParent(LLUICtrl* ctrl, void* data)
++{
++	LLFloaterBulkPermission* self = (LLFloaterBulkPermission*)data;
++	self->parent=self->getChild<LLCheckBoxCtrl>("Parent")->get();
++}
++
++// static
++void LLFloaterBulkPermission::onRecurse(LLUICtrl* ctrl, void* data)
++{
++	LLFloaterBulkPermission* self = (LLFloaterBulkPermission*)data;
++	self->recurse=self->getChild<LLCheckBoxCtrl>("Recurse")->get();
++}
++
++// static
++void LLFloaterBulkPermission::onCommitPermissions(LLUICtrl* ctrl, void* data)
++{
++	LLFloaterBulkPermission* self = (LLFloaterBulkPermission*)data;
++	LLCheckBoxCtrl* CheckModify = self->getChild<LLCheckBoxCtrl>("Modify");
++	LLCheckBoxCtrl* CheckCopy = self->getChild<LLCheckBoxCtrl>("Copy");
++	LLCheckBoxCtrl* CheckTrans = self->getChild<LLCheckBoxCtrl>("Trans");
++
++	self->req_perm_mask=0;
++
++	if(CheckModify->get())
++	{
++		self->req_perm_mask|=PERM_MODIFY;
++	}
++	else
++	{
++		self->req_perm_mask&=~PERM_MODIFY;
++	}
++
++	if(CheckCopy->get())
++	{
++		self->req_perm_mask|=PERM_COPY;
++	}
++	else
++	{
++		self->req_perm_mask&=~PERM_COPY;
++	}
++
++	if(CheckTrans->get())
++	{
++		self->req_perm_mask|=PERM_TRANSFER;
++	}
++	else
++	{
++		self->req_perm_mask&=~PERM_TRANSFER;
++	}
++
++
++}
++
++void LLFloaterBulkPermission::addObject(const LLUUID& id)
++{
++	mObjectIDs.put(id);
++}
++
++BOOL LLFloaterBulkPermission::start()
++{
++	llinfos << "LLFloaterBulkPermission::start()" << llendl;
++	char buffer[MAX_STRING]; 				/*Flawfinder: ignore*/
++	snprintf(buffer, sizeof(buffer), "Starting %s of %d items.", mStartString, mObjectIDs.count()); 		/* Flawfinder: ignore */
++
++	LLScrollListCtrl* list = getChild<LLScrollListCtrl>("queue output");
++	list->addCommentText(buffer);
++
++	return nextObject();
++}
++
++BOOL LLFloaterBulkPermission::isDone() const
++{
++	return (mCurrentObjectID.isNull() || (mObjectIDs.count() == 0));
++}
++
++// go to the next object. If no objects left, it falls out silently
++// and waits to be killed by the window being closed.
++BOOL LLFloaterBulkPermission::nextObject()
++{
++	S32 count;
++	BOOL successful_start = FALSE;
++	do
++	{
++		count = mObjectIDs.count();
++		llinfos << "LLFloaterBulkPermission::nextObject() - " << count
++				<< " objects left to process." << llendl;
++		mCurrentObjectID.setNull();
++		if(count > 0)
++		{
++			successful_start = popNext();
++		}
++		llinfos << "LLFloaterBulkPermission::nextObject() "
++				<< (successful_start ? "successful" : "unsuccessful")
++				<< llendl; 
++	} while((mObjectIDs.count() > 0) && !successful_start);
++
++	if(isDone() && !mDone)
++	{
++		
++		LLScrollListCtrl* list = getChild<LLScrollListCtrl>("queue output");
++		mDone = TRUE;
++		char buffer[MAX_STRING];		/*Flawfinder: ignore*/
++		snprintf(buffer, sizeof(buffer), "Done.");				/* Flawfinder: ignore */
++		list->addCommentText(buffer);
++
++	}
++	return successful_start;
++}
++
++// returns true if the queue has started, otherwise false.  This
++// method pops the top object off of the queue.
++BOOL LLFloaterBulkPermission::popNext()
++{
++	// get the first element off of the container, and attempt to get
++	// the inventory.
++	BOOL rv = FALSE;
++	S32 count = mObjectIDs.count();
++	if(mCurrentObjectID.isNull() && (count > 0))
++	{
++		mCurrentObjectID = mObjectIDs.get(0);
++		llinfos << "LLFloaterBulkPermission::popNext() - mCurrentID: "
++				<< mCurrentObjectID << llendl;
++		mObjectIDs.remove(0);
++		LLViewerObject* obj = gObjectList.findObject(mCurrentObjectID);
++		if(obj)
++		{
++			llinfos << "LLFloaterBulkPermission::popNext() requesting inv for "
++					<< mCurrentObjectID << llendl;
++			LLUUID* id = new LLUUID(mID);
++
++			registerVOInventoryListener(obj,id);
++			requestVOInventory();
++			rv = TRUE;
++		}
++		else
++		{
++			llinfos<<"LLFloaterBulkPermission::popNext() returned a NULL LLViewerObject" <<llendl;
++			//Arrrg what do we do here?
++		}
++	}
++
++	return rv;
++}
++
++
++// static
++LLFloaterBulkPermission* LLFloaterBulkPermission::create()
++{
++	S32 left, top;
++	gFloaterView->getNewFloaterPosition(&left, &top);
++	LLRect rect = gSavedSettings.getRect("CompileOutputRect");
++	rect.translate(left - rect.mLeft, top - rect.mTop);
++	LLFloaterBulkPermission* new_queue = new LLFloaterBulkPermission("queue",rect,"Setting Bulk permissions","Results");
++	new_queue->open();	 /*Flawfinder: ignore*/
++	return new_queue;
++}
++
++
++void LLFloaterBulkPermission::handleInventory(LLViewerObject* viewer_obj, InventoryObjectList* inv)
++{
++	// find all of the lsl, leaving off duplicates. We'll remove
++	// all matching asset uuids on compilation success.
++
++	llinfos<<"handleInventory"<<llendl;
++
++	char buffer[MAX_STRING];		 /*Flawfinder: ignore*/
++	LLScrollListCtrl* list = getChild<LLScrollListCtrl>("queue output");
++
++	InventoryObjectList::const_iterator it = inv->begin();
++	InventoryObjectList::const_iterator end = inv->end();
++	for ( ; it != end; ++it)
++	{
++		llinfos<<"Doing iterator of inventory"<<llendl;
++
++		if(  ( (*it)->getType() == LLAssetType::AT_LSL_TEXT && processScript) ||
++  		     ( (*it)->getType() == LLAssetType::AT_TEXTURE && processTexture) ||
++	             ( (*it)->getType() == LLAssetType::AT_SOUND && processSound) ||
++	             ( (*it)->getType() == LLAssetType::AT_LANDMARK && processLandmark) ||
++    		     ( (*it)->getType() == LLAssetType::AT_CLOTHING && processClothing) ||
++    		     ( (*it)->getType() == LLAssetType::AT_OBJECT && processObject) ||
++   		     ( (*it)->getType() == LLAssetType::AT_NOTECARD && processNotecard) ||
++   		     ( (*it)->getType() == LLAssetType::AT_BODYPART && processBodypart) ||
++   		     ( (*it)->getType() == LLAssetType::AT_ANIMATION && processAnimation) ||
++   		     ( (*it)->getType() == LLAssetType::AT_GESTURE && processGesture))
++		{
++
++			LLViewerObject* object = gObjectList.findObject(viewer_obj->getID());
++
++			if (object)
++			{
++				LLInventoryItem* item = (LLInventoryItem*)((LLInventoryObject*)(*it));
++				LLViewerInventoryItem* new_item = (LLViewerInventoryItem*)item;
++				LLPermissions perm(new_item->getPermissions());
++
++				// chomp the inventory name so it fits in the scroll window nicely
++				// and the user can see the [OK]
++				std::string invname;
++				invname=item->getName().substr(0,item->getName().size() < 30 ? item->getName().size() : 30 );
++				
++				// My attempt at checking valid permissions, CHECK ME
++				// note its not actually bad to try to set permissions that are not allowed as the
++				// server will protect against this, but it will piss the user off if its wrong
++				if(
++				(perm.getCreator()==gAgentID) ||
++				(perm.getMaskOwner() & PERM_TRANSFER) && (perm.getMaskOwner() & PERM_MODIFY) || 
++				(gAgent.getGroupID()==perm.getGroup() && (perm.getMaskGroup() & PERM_TRANSFER) && (perm.getMaskGroup() & PERM_MODIFY))
++				){	
++					llinfos<<"Setting perms"<<llendl;
++					perm.setMaskNext(req_perm_mask);
++					new_item->setPermissions(perm);
++					updateInventory(object,new_item,TASK_INVENTORY_ITEM_KEY,FALSE);				
++					snprintf(buffer, sizeof(buffer), "Setting perms on '%s' [OK]", invname.c_str());		 	/* Flawfinder: ignore */
++				}
++				else
++				{
++					llinfos<<"NOT setting perms"<<llendl;
++					snprintf(buffer, sizeof(buffer), "Setting perms on '%s' [FAILED]", invname.c_str());		 	/* Flawfinder: ignore */
++
++				}
++				
++				list->addCommentText(buffer);
++
++				if(recurse &&  ( (*it)->getType() == LLAssetType::AT_OBJECT && processObject))
++				{
++					//Add this object back to the queue to be processed as it has inventory
++					snprintf(buffer, sizeof(buffer), "Queueing object '%s' for open", invname.c_str());
++					llwarns << "Queueing object "<<	invname.c_str() << " ID "<< (*it)->getUUID()<<llendl;
++					mObjectIDs.put((*it)->getUUID());
++					// This will not YET work. as this is not a viewer object the unpack will fail			
++				}
++
++			}
++		}
++	}
++
++	nextObject();	
++}
++
++
++// Avoid inventory callbacks etc by just fire and forgetting the message with the permissions update
++// we could do this via LLViewerObject::updateInventory but that uses inventory call backs and buggers
++// us up and we would have a dodgy item iterator
++
++void LLFloaterBulkPermission::updateInventory(
++	LLViewerObject* object,
++	LLViewerInventoryItem* item,
++	U8 key,
++	bool is_new)
++{
++	LLMemType mt(LLMemType::MTYPE_OBJECT);
++	
++
++	// This slices the object into what we're concerned about on the
++	// viewer. The simulator will take the permissions and transfer
++	// ownership.
++	LLPointer<LLViewerInventoryItem> task_item =
++		new LLViewerInventoryItem(item->getUUID(), mID, item->getPermissions(),
++								  item->getAssetUUID(), item->getType(),
++								  item->getInventoryType(),
++								  item->getName(), item->getDescription(),
++								  item->getSaleInfo(),
++								  item->getFlags(),
++								  item->getCreationDate());
++	task_item->setTransactionID(item->getTransactionID());
++	LLMessageSystem* msg = gMessageSystem;
++	msg->newMessageFast(_PREHASH_UpdateTaskInventory);
++	msg->nextBlockFast(_PREHASH_AgentData);
++	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
++	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
++	msg->nextBlockFast(_PREHASH_UpdateData);
++	msg->addU32Fast(_PREHASH_LocalID, object->mLocalID);
++	msg->addU8Fast(_PREHASH_Key, key);
++	msg->nextBlockFast(_PREHASH_InventoryData);
++	task_item->packMessage(msg);
++	msg->sendReliable(object->getRegion()->getHost());
++
++}
++
+diff --git a/indra/newview/llfloaterbulkpermission.h b/indra/newview/llfloaterbulkpermission.h
+new file mode 100644
+index 0000000..3de871b
+--- /dev/null
++++ b/indra/newview/llfloaterbulkpermission.h
+@@ -0,0 +1,143 @@
++/** 
++ * @file llfloaterbulkpermissions.h
++ * @brief A floater which allows task inventory item's properties to be changed on mass.
++ *
++ * $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$
++ */
++
++/* Allow multiple task inventory properties to be set in one go, by Michelle2 Zenovka */
++
++#ifndef LL_LLBULKPERMISSION_H
++#define LL_LLBULKPERMISSION_H
++
++#include "lldarray.h"
++#include "llinventory.h"
++#include "llviewerobject.h"
++#include "llvoinventorylistener.h"
++#include "llmap.h"
++#include "lluuid.h"
++
++#include "llfloater.h"
++#include "llscrolllistctrl.h"
++
++#include "llviewerinventory.h"
++
++class LLFloaterBulkPermission : public LLFloater, public LLVOInventoryListener
++{
++public:
++	// addObject() accepts an object id.
++	void addObject(const LLUUID& id);
++
++	// start() returns TRUE if the queue has started, otherwise FALSE.
++	BOOL start();
++
++	// Use this method to create a reset queue. Once created, it
++	// will be responsible for it's own destruction.
++	static LLFloaterBulkPermission * create();
++
++protected:
++	LLFloaterBulkPermission(const std::string& name, const LLRect& rect,
++						 const char* title, const char* start_string);
++	virtual ~LLFloaterBulkPermission();
++
++	// This is the callback method for the viewer object currently
++	// being worked on.
++	/*virtual*/ void inventoryChanged(LLViewerObject* obj,
++								 InventoryObjectList* inv,
++								 S32 serial_num,
++								 void* queue);
++	
++	// This is called by inventoryChanged
++	void handleInventory(LLViewerObject* viewer_obj,
++								InventoryObjectList* inv);
++
++
++	void updateInventory(LLViewerObject* object,
++								LLViewerInventoryItem* item,
++								U8 key,
++								bool is_new);
++
++
++	static void onCloseBtn(void* user_data);
++	static void onApplyBtn(void* user_data);
++	static void onCommitPermissions(LLUICtrl* ctrl, void* data);
++	static void InvSelection(LLUICtrl* ctrl, void* data);
++	static void onRecurse(LLUICtrl* ctrl, void* data);	
++	static void onParent(LLUICtrl* ctrl, void* data);
++
++	// returns true if this is done
++	BOOL isDone() const;
++
++	//Read the settings and Apply the permissions
++	void doApply();
++
++	// go to the next object. If no objects left, it falls out
++	// silently and waits to be killed by the deleteIfDone() callback.
++	BOOL nextObject();
++	BOOL popNext();
++
++	// Get this instances ID.
++	const LLUUID& getID() const { return mID; } 
++
++	// find an instance by ID. Return NULL if it does not exist.
++	static LLFloaterBulkPermission* findInstance(const LLUUID& id);
++
++	U32 req_perm_mask;
++
++	BOOL processObject;
++	BOOL processScript;
++	BOOL processTexture;
++	BOOL processSound;
++	BOOL processAnimation;
++	BOOL processCallingcard;
++	BOOL processNotecard;
++	BOOL processGesture;
++	BOOL processClothing;
++	BOOL processBodypart;
++	BOOL processLandmark;
++
++	BOOL recurse;
++	BOOL parent;
++
++protected:
++	// UI
++	LLScrollListCtrl* mMessages;
++	LLButton* mCloseBtn;
++
++	// Object Queue
++	LLDynamicArray<LLUUID> mObjectIDs;
++	LLUUID mCurrentObjectID;
++	BOOL mDone;
++
++	LLUUID mID;
++	static LLMap<LLUUID, LLFloaterBulkPermission*> sInstances;
++
++	const char* mStartString;
++
++};
++
++#endif
+diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
+index 023c758..29f4cef 100644
+--- a/indra/newview/llviewermenu.cpp
++++ b/indra/newview/llviewermenu.cpp
+@@ -87,6 +87,7 @@
+ #include "llfloateravatartextures.h"
+ #include "llfloaterbeacons.h"
+ #include "llfloaterbuildoptions.h"
++#include "llfloaterbulkpermission.h"
+ #include "llfloaterbump.h"
+ #include "llfloaterbuy.h"
+ #include "llfloaterbuycontents.h"
+@@ -6024,6 +6025,16 @@ void queue_actions(LLFloaterScriptQueue* q, const std::string& noscriptmsg, cons
+ 	}
+ }
+ 
++class LLToolsSetBulkPerms : public view_listener_t
++{
++	bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
++	{
++		LLFloaterBulkPermission* queue = NULL;
++		queue = LLFloaterBulkPermission::create();
++		return true;
++	}
++};
++
+ void handle_compile_queue(std::string to_lang)
+ {
+ 	LLFloaterCompileQueue* queue;
+@@ -7516,6 +7527,7 @@ void initialize_menus()
+ 	addMenu(new LLToolsSaveToInventory(), "Tools.SaveToInventory");
+ 	addMenu(new LLToolsSaveToObjectInventory(), "Tools.SaveToObjectInventory");
+ 	addMenu(new LLToolsSelectedScriptAction(), "Tools.SelectedScriptAction");
++	addMenu(new LLToolsSetBulkPerms(), "Tools.SetBulkPerms");
+ 
+ 	addMenu(new LLToolsEnableToolNotPie(), "Tools.EnableToolNotPie");
+ 	addMenu(new LLToolsEnableLink(), "Tools.EnableLink");
+diff --git a/indra/newview/skins/default/xui/en-us/floater_bulk_perms.xml b/indra/newview/skins/default/xui/en-us/floater_bulk_perms.xml
+new file mode 100644
+index 0000000..3dd838a
+--- /dev/null
++++ b/indra/newview/skins/default/xui/en-us/floater_bulk_perms.xml
+@@ -0,0 +1,127 @@
++<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
++<floater bottom="-554" can_close="true" can_drag_on_left="false" can_minimize="true"
++     can_resize="false" can_tear_off="false" enabled="true" height="420"
++     left="367" min_height="1000" min_width="460" mouse_opaque="true"
++     name="floaterrecursiveperms" title="Bulk permission settings"
++     width="460">
++
++<text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
++			     bottom="-40" drop_shadow_visible="true" enabled="true" follows="left|top"
++			     font="SansSerifSmall" h_pad="0" halign="left" height="10" left="10"
++			     mouse_opaque="true" name="applyto" v_pad="0" width="206">Apply to</text>
++
++<check_box bottom="-70" enabled="true" follows="left|top" font="SansSerifSmall"
++			     height="16" initial_value="false"
++			     label="Scripts" left="10" mouse_opaque="true"
++			     name="scripts" radio_style="false"
++			     tool_tip="Apply bulk permissions to scripts"
++			     width="219"/>
++
++<check_box bottom="-90" enabled="true" follows="left|top" font="SansSerifSmall"
++			     height="16" initial_value="false"
++			     label="Textures" left="10" mouse_opaque="true"
++			     name="textures" radio_style="false"
++			     tool_tip="Apply bulk permissions to textures"
++			     width="219"/>
++
++<check_box bottom="-110" enabled="true" follows="left|top" font="SansSerifSmall"
++			     height="16" initial_value="false"
++			     label="Animations" left="10" mouse_opaque="true"
++			     name="animations" radio_style="false"
++			     tool_tip="Apply bulk permissions to animations"
++			     width="219"/>
++
++<check_box bottom="-130" enabled="true" follows="left|top" font="SansSerifSmall"
++			     height="16" initial_value="false"
++			     label="Sounds" left="10" mouse_opaque="true"
++			     name="sounds" radio_style="false"
++			     tool_tip="Apply bulk permissions to sounds"
++			     width="219"/>
++
++<check_box bottom="-150" enabled="true" follows="left|top" font="SansSerifSmall"
++			     height="16" initial_value="false"
++			     label="Contained objects" left="10" mouse_opaque="true"
++			     name="objects" radio_style="false"
++			     tool_tip="Apply bulk permissions to objects inside inventory"
++			     width="219"/>
++
++<check_box bottom="-170" enabled="true" follows="left|top" font="SansSerifSmall"
++			     height="16" initial_value="false"
++			     label="Landmarks" left="10" mouse_opaque="true"
++			     name="landmarks" radio_style="false"
++			     tool_tip="Apply bulk permissions to landmarks"
++			     width="219"/>
++
++<check_box bottom="-190" enabled="true" follows="left|top" font="SansSerifSmall"
++			     height="16" initial_value="false"
++			     label="Notecards" left="10" mouse_opaque="true"
++			     name="notecards" radio_style="false"
++			     tool_tip="Apply bulk permissions to notecards"
++			     width="219"/>
++
++<check_box bottom="-210" enabled="true" follows="left|top" font="SansSerifSmall"
++			     height="16" initial_value="false"
++			     label="Gesture" left="10" mouse_opaque="true"
++			     name="gestures" radio_style="false"
++			     tool_tip="Apply bulk permissions to gestures"
++			     width="219"/>
++
++<check_box bottom="-230" enabled="true" follows="left|top" font="SansSerifSmall"
++			     height="16" initial_value="false"
++			     label="Clothing" left="10" mouse_opaque="true"
++			     name="clothing" radio_style="false"
++			     tool_tip="Apply bulk permissions to clothing"
++			     width="219"/>
++
++<check_box bottom="-250" enabled="true" follows="left|top" font="SansSerifSmall"
++			     height="16" initial_value="false"
++			     label="Bodypart" left="10" mouse_opaque="true"
++			     name="bodyparts" radio_style="false"
++			     tool_tip="Apply bulk permissions to bodyparts"
++			     width="219"/>
++
++<text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
++			     bottom="-40" drop_shadow_visible="true" enabled="true" follows="left|top"
++			     font="SansSerifSmall" h_pad="0" halign="left" height="10" left="200"
++			     mouse_opaque="true" name="applyto" v_pad="0" width="206">Permissions</text>
++
++
++<check_box bottom="-110" enabled="true" follows="left|top" font="SansSerifSmall"
++			     height="16" initial_value="false"
++			     label="Copy" left="200" mouse_opaque="true"
++			     name="Copy" radio_style="false"
++			     tool_tip="Next owner can copy"
++			     width="219"/>
++
++<check_box bottom="-130" enabled="true" follows="left|top" font="SansSerifSmall"
++			     height="16" initial_value="false"
++			     label="Modify" left="200" mouse_opaque="true"
++			     name="Modify" radio_style="false"
++			     tool_tip="Next owner can modify"
++			     width="219"/>
++
++<check_box bottom="-150" enabled="true" follows="left|top" font="SansSerifSmall"
++			     height="16" initial_value="false"
++			     label="Trans" left="200" mouse_opaque="true"
++			     name="Trans" radio_style="false"
++			     tool_tip="Next owner can transfer"
++			     width="219"/>
++
++<check_box bottom="-230" enabled="true" follows="left|top" font="SansSerifSmall"
++			     height="16" initial_value="false"
++			     label="Modify Parent Prims" left="200" mouse_opaque="true"
++			     name="Parent" radio_style="false"
++			     tool_tip="Modify parent prims not just inventory"
++			     width="219" default="true"/>
++
++<scroll_list background_visible="true" bottom="-410" column_padding="5" draw_border="true"
++	     draw_heading="false" draw_stripes="true" enabled="true"
++	     follows="left|top|right|bottom" height="140" left="10" mouse_opaque="true"
++	     multi_select="false" name="queue output" width="440" />
++
++<button bottom="-70" enabled="true" follows="left|top" font="SansSerif"
++			     halign="center" height="20" label="Apply..."
++			     label_selected="Apply..." left="295" mouse_opaque="true"
++			     name="Apply..." scale_image="true" width="145" />
++
++</floater>
+diff --git a/indra/newview/skins/default/xui/en-us/menu_viewer.xml b/indra/newview/skins/default/xui/en-us/menu_viewer.xml
+index d2c4923..8b57505 100644
+--- a/indra/newview/skins/default/xui/en-us/menu_viewer.xml
++++ b/indra/newview/skins/default/xui/en-us/menu_viewer.xml
+@@ -704,6 +704,11 @@
+ 			<on_click function="Tools.SelectedScriptAction" userdata="stop" />
+ 			<on_enable function="EditableSelected" />
+ 		</menu_item_call>
++		<menu_item_call bottom="-468" enabled="false" height="19" label="Set permissions on selected task inventory"
++		     left="0" mouse_opaque="true" name="Set permissions on selected task inventory" width="250">
++			<on_click function="Tools.SetBulkPerms" userdata="" />
++			<on_enable function="EditableSelected" />
++		</menu_item_call>
+ 	</menu>
+ 	<menu bottom="219" create_jump_keys="true" drop_shadow="true" enabled="true"
+ 	     height="317" label="Help" left="227" mouse_opaque="false" name="Help"
+-- 
+tg: (1836a2b..) topic/features/jira-backported/VWR-5082_set_bulk_inv_permissions (depends on: upstream)
diff --git a/debian/patches/topic/features/jira-backported/VWR-7531-Dynamic-Grid-List.diff b/debian/patches/topic/features/jira-backported/VWR-7531-Dynamic-Grid-List.diff
new file mode 100644
index 0000000..495598c
--- /dev/null
+++ b/debian/patches/topic/features/jira-backported/VWR-7531-Dynamic-Grid-List.diff
@@ -0,0 +1,735 @@
+From: Robin Cornelius <robin.cornelius at gmail.com>
+Subject: [PATCH] topic/features/jira-backported/VWR-7531-Dynamic-Grid-List
+
+<patch description>
+
+Signed-off-by: Robin Cornelius <robin.cornelius at gmail.com>
+
+---
+ indra/newview/app_settings/grids.xml    |   24 +++
+ indra/newview/app_settings/settings.xml |    2 +-
+ indra/newview/llappviewer.cpp           |   25 ---
+ indra/newview/llpanellogin.cpp          |  122 ++-------------
+ indra/newview/llstartup.cpp             |    6 +-
+ indra/newview/llviewernetwork.cpp       |  260 +++++++++++++++----------------
+ indra/newview/llviewernetwork.h         |   48 ++----
+ 7 files changed, 186 insertions(+), 301 deletions(-)
+
+diff --git a/indra/newview/app_settings/grids.xml b/indra/newview/app_settings/grids.xml
+new file mode 100644
+index 0000000..24d1183
+--- /dev/null
++++ b/indra/newview/app_settings/grids.xml
+@@ -0,0 +1,24 @@
++<?xml version="1.0" encoding="utf-8" standalone="yes"?>
++<!-- this is the LLSD version -->
++<llsd>
++	<map>
++		<key>grids</key>
++		<array>
++			<map>
++				<key>name</key><string>util.aditi.lindenlab.com</string>
++				<key>label</key><string>Aditi</string>
++				<key>login_uri</key><string>https://login.aditi.lindenlab.com/cgi-bin/login.cgi</string>
++				<key>helper_uri</key><string>http://aditi-secondlife.webdev.lindenlab.com/helpers/</string>
++                                <key>login_page</key><string>http://secondlife.com/app/login/</string>
++			</map>
++			<map>
++				<key>name</key><string>osgrid</string>
++				<key>label</key><string>OSGrid</string>
++				<key>login_uri</key><string>http://osgrid.org:8002</string>
++				<key>helper_uri</key><string>http://osgrid.org/loginpage.htm</string>
++				<key>menu_color</key><string>green</string>
++                                <key>login_page</key><string>http://osgrid.org/</string>
++			</map>
++		</array>
++	</map>
++</llsd>
+diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
+index 27eacfb..9560f79 100644
+--- a/indra/newview/app_settings/settings.xml
++++ b/indra/newview/app_settings/settings.xml
+@@ -3587,7 +3587,7 @@
+       <key>Type</key>
+       <string>Boolean</string>
+       <key>Value</key>
+-      <integer>0</integer>
++      <integer>1</integer>
+     </map>
+     <key>ForceMandatoryUpdate</key>
+     <map>
+diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
+index 09d1141..d93e503 100644
+--- a/indra/newview/llappviewer.cpp
++++ b/indra/newview/llappviewer.cpp
+@@ -453,31 +453,6 @@ static void settings_modify()
+ 
+ void LLAppViewer::initGridChoice()
+ {
+-	// Load	up the initial grid	choice from:
+-	//	- hard coded defaults...
+-	//	- command line settings...
+-	//	- if dev build,	persisted settings...
+-
+-	// Set the "grid choice", this is specified	by command line.
+-	std::string	grid_choice	= gSavedSettings.getString("CmdLineGridChoice");
+-	LLViewerLogin::getInstance()->setGridChoice(grid_choice);
+-
+-	// Load last server choice by default 
+-	// ignored if the command line grid	choice has been	set
+-	if(grid_choice.empty())
+-	{
+-		S32	server = gSavedSettings.getS32("ServerChoice");
+-		server = llclamp(server, 0,	(S32)GRID_INFO_COUNT - 1);
+-		if(server == GRID_INFO_OTHER)
+-		{
+-			std::string custom_server = gSavedSettings.getString("CustomServer");
+-			LLViewerLogin::getInstance()->setGridChoice(custom_server);
+-		}
+-		else if(server != (S32)GRID_INFO_NONE)
+-		{
+-			LLViewerLogin::getInstance()->setGridChoice((EGridInfo)server);
+-		}
+-	}
+ }
+ 
+ //virtual
+diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp
+index 64eecd6..268ec23 100644
+--- a/indra/newview/llpanellogin.cpp
++++ b/indra/newview/llpanellogin.cpp
+@@ -131,103 +131,8 @@ void LLLoginHandler::parse(const LLSD& queryMap)
+ 	mWebLoginKey = queryMap["web_login_key"].asUUID();
+ 	mFirstName = queryMap["first_name"].asString();
+ 	mLastName = queryMap["last_name"].asString();
+-	
+-	EGridInfo grid_choice = GRID_INFO_NONE;
+-	if (queryMap["grid"].asString() == "aditi")
+-	{
+-		grid_choice = GRID_INFO_ADITI;
+-	}
+-	else if (queryMap["grid"].asString() == "agni")
+-	{
+-		grid_choice = GRID_INFO_AGNI;
+-	}
+-	else if (queryMap["grid"].asString() == "siva")
+-	{
+-		grid_choice = GRID_INFO_SIVA;
+-	}
+-	else if (queryMap["grid"].asString() == "damballah")
+-	{
+-		grid_choice = GRID_INFO_DAMBALLAH;
+-	}
+-	else if (queryMap["grid"].asString() == "durga")
+-	{
+-		grid_choice = GRID_INFO_DURGA;
+-	}
+-	else if (queryMap["grid"].asString() == "shakti")
+-	{
+-		grid_choice = GRID_INFO_SHAKTI;
+-	}
+-	else if (queryMap["grid"].asString() == "soma")
+-	{
+-		grid_choice = GRID_INFO_SOMA;
+-	}
+-	else if (queryMap["grid"].asString() == "ganga")
+-	{
+-		grid_choice = GRID_INFO_GANGA;
+-	}
+-	else if (queryMap["grid"].asString() == "vaak")
+-	{
+-		grid_choice = GRID_INFO_VAAK;
+-	}
+-	else if (queryMap["grid"].asString() == "uma")
+-	{
+-		grid_choice = GRID_INFO_UMA;
+-	}
+-	else if (queryMap["grid"].asString() == "mohini")
+-	{
+-		grid_choice = GRID_INFO_MOHINI;
+-	}
+-	else if (queryMap["grid"].asString() == "yami")
+-	{
+-		grid_choice = GRID_INFO_YAMI;
+-	}
+-	else if (queryMap["grid"].asString() == "nandi")
+-	{
+-		grid_choice = GRID_INFO_NANDI;
+-	}
+-	else if (queryMap["grid"].asString() == "mitra")
+-	{
+-		grid_choice = GRID_INFO_MITRA;
+-	}
+-	else if (queryMap["grid"].asString() == "radha")
+-	{
+-		grid_choice = GRID_INFO_RADHA;
+-	}
+-	else if (queryMap["grid"].asString() == "ravi")
+-	{
+-		grid_choice = GRID_INFO_RAVI;
+-	}
+-	else if (queryMap["grid"].asString() == "aruna")
+-	{
+-		grid_choice = GRID_INFO_ARUNA;
+-	}
+-	else if (queryMap["grid"].asString() == "bharati")
+-	{
+-		grid_choice = GRID_INFO_BHARATI;
+-	}
+-	else if (queryMap["grid"].asString() == "chandra")
+-	{
+-		grid_choice = GRID_INFO_CHANDRA;
+-	}
+-	else if (queryMap["grid"].asString() == "danu")
+-	{
+-		grid_choice = GRID_INFO_DANU;
+-	}
+-	else if (queryMap["grid"].asString() == "parvati")
+-	{
+-		grid_choice = GRID_INFO_PARVATI;
+-	}
+-	else if (queryMap["grid"].asString() == "skanda")
+-	{
+-		grid_choice = GRID_INFO_SKANDA;
+-	}
+ 
+-	if(grid_choice != GRID_INFO_NONE)
+-	{
+-		LLViewerLogin::getInstance()->setGridChoice(grid_choice);
+-	}
+-
+-	std::string startLocation = queryMap["location"].asString();
++ 	std::string startLocation = queryMap["location"].asString();
+ 
+ 	if (startLocation == "specify")
+ 	{
+@@ -909,11 +814,8 @@ void LLPanelLogin::loadLoginPage()
+ 	
+ 	std::ostringstream oStr;
+ 
+-	std::string login_page = gSavedSettings.getString("LoginPage");
+-	if (login_page.empty())
+-	{
+-		login_page = sInstance->getString( "real_url" );
+-	}
++	std::string login_page=LLViewerLogin::getInstance()->getGridPage();
++
+ 	oStr << login_page;
+ 	
+ 	// Use the right delimeter depending on how LLURI parses the URL
+@@ -953,6 +855,7 @@ void LLPanelLogin::loadLoginPage()
+ 	curl_free(curl_grid);
+ 
+ 	gViewerWindow->setMenuBackgroundColor(false, !LLViewerLogin::getInstance()->isInProductionGrid());
++	LLViewerLogin::getInstance()->setMenuColor();
+ 	gLoginMenuBarView->setBackgroundColor(gMenuBarView->getBackgroundColor());
+ 
+ 
+@@ -1175,7 +1078,7 @@ void LLPanelLogin::onSelectServer(LLUICtrl*, void*)
+ 	{
+ 		grid_index = combo->getValue().asInteger();
+ 
+-		if ((S32)GRID_INFO_OTHER == grid_index)
++		if ((S32)LLViewerLogin::getInstance()->getGridCount() == grid_index)
+ 		{
+ 			// This happens if the user specifies a custom grid
+ 			// via command line.
+@@ -1185,7 +1088,7 @@ void LLPanelLogin::onSelectServer(LLUICtrl*, void*)
+ 	else
+ 	{
+ 		// no valid selection, return other
+-		grid_index = (S32)GRID_INFO_OTHER;
++		grid_index = (S32)LLViewerLogin::getInstance()->getGridCount();
+ 		grid_label = combo_val.asString();
+ 	}
+ 
+@@ -1193,15 +1096,24 @@ void LLPanelLogin::onSelectServer(LLUICtrl*, void*)
+ 	// from the command line.
+ 	LLViewerLogin* vl = LLViewerLogin::getInstance();
+ 	vl->resetURIs();
+-	if(grid_index != GRID_INFO_OTHER)
++	if(grid_index != LLViewerLogin::getInstance()->getGridCount())
+ 	{
+-		vl->setGridChoice((EGridInfo)grid_index);
++		vl->setGridChoice(grid_index);
+ 	}
+ 	else
+ 	{
+ 		vl->setGridChoice(grid_label);
+ 	}
+ 
++	// clear the password if we are switching grids so we don't send
++	// the wrong pass to the wrong grid.
++	if (sInstance)
++	{
++		// no method to clear a text box?
++		const std::string nothing("");
++		sInstance->childSetText("password_edit", nothing);		
++	}	
++	
+ 	// grid changed so show new splash screen (possibly)
+ 	loadLoginPage();
+ }
+diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
+index 5f25dc3..92bd3d1 100644
+--- a/indra/newview/llstartup.cpp
++++ b/indra/newview/llstartup.cpp
+@@ -2525,12 +2525,12 @@ void login_show()
+ 	
+ 	LL_DEBUGS("AppInit") << "Setting Servers" << LL_ENDL;
+ 
+-	LLPanelLogin::addServer(LLViewerLogin::getInstance()->getGridLabel(), LLViewerLogin::getInstance()->getGridChoice());
++	//LLPanelLogin::addServer(LLViewerLogin::getInstance()->getGridLabel(), LLViewerLogin::getInstance()->getGridChoice());
+ 
+ 	LLViewerLogin* vl = LLViewerLogin::getInstance();
+-	for(int grid_index = GRID_INFO_ADITI; grid_index < GRID_INFO_OTHER; ++grid_index)
++	for(int grid_index = 1; grid_index < LLViewerLogin::getInstance()->getGridCount() ; ++grid_index)
+ 	{
+-		LLPanelLogin::addServer(vl->getKnownGridLabel((EGridInfo)grid_index), grid_index);
++		LLPanelLogin::addServer(vl->getKnownGridLabel(grid_index).c_str(), grid_index);
+ 	}
+ }
+ 
+diff --git a/indra/newview/llviewernetwork.cpp b/indra/newview/llviewernetwork.cpp
+index 1830b76..22a05c0 100644
+--- a/indra/newview/llviewernetwork.cpp
++++ b/indra/newview/llviewernetwork.cpp
+@@ -34,148 +34,126 @@
+ 
+ #include "llviewernetwork.h"
+ #include "llviewercontrol.h"
++#include "llsd.h"
++#include "llsdserialize.h"
++#include "llviewermenu.h"
+ 
+-struct LLGridData
+-{
+-	const char* mLabel;
+-	const char* mName;
+-	const char* mLoginURI;
+-	const char* mHelperURI;
+-};
++const int DEFAULT_GRID_CHOICE=1;
++const int GRID_INFO_NONE=0;
+ 
+-static LLGridData gGridInfo[GRID_INFO_COUNT] = 
+-{
+-	{ "None", "", "", ""},
+-	{ "Aditi", 
+-	  "util.aditi.lindenlab.com", 
+-	  "https://login.aditi.lindenlab.com/cgi-bin/login.cgi",
+-	  "http://aditi-secondlife.webdev.lindenlab.com/helpers/" },
+-	{ "Agni", 
+-	  "util.agni.lindenlab.com", 
+-	  "https://login.agni.lindenlab.com/cgi-bin/login.cgi",
+-	  "https://secondlife.com/helpers/" },
+-	{ "Aruna",
+-	  "util.aruna.lindenlab.com",
+-	  "https://login.aruna.lindenlab.com/cgi-bin/login.cgi",
+-	  "http://aruna-secondlife.webdev.lindenlab.com/helpers/" },
+-	{ "Bharati",
+-	  "util.bharati.lindenlab.com",
+-	  "https://login.bharati.lindenlab.com/cgi-bin/login.cgi",
+-	  "http://bharati-secondlife.webdev.lindenlab.com/helpers/" },
+-	{ "Chandra",
+-	  "util.chandra.lindenlab.com",
+-	  "https://login.chandra.lindenlab.com/cgi-bin/login.cgi",
+-	  "http://chandra-secondlife.webdev.lindenlab.com/helpers/" },
+-	{ "Damballah",
+-	  "util.damballah.lindenlab.com",
+-	  "https://login.damballah.lindenlab.com/cgi-bin/login.cgi",
+-	  "http://damballah-secondlife.webdev.lindenlab.com/helpers/" },
+-	{ "Danu",
+-	  "util.danu.lindenlab.com",
+-	  "https://login.danu.lindenlab.com/cgi-bin/login.cgi",
+-	  "http://danu-secondlife.webdev.lindenlab.com/helpers/" },
+-	{ "Durga",
+-	  "util.durga.lindenlab.com",
+-	  "https://login.durga.lindenlab.com/cgi-bin/login.cgi",
+-	  "http://durga-secondlife.webdev.lindenlab.com/helpers/" },
+-	{ "Ganga",
+-	  "util.ganga.lindenlab.com",
+-	  "https://login.ganga.lindenlab.com/cgi-bin/login.cgi",
+-	  "http://ganga-secondlife.webdev.lindenlab.com/helpers/" },
+-	{ "Mitra",
+-	  "util.mitra.lindenlab.com",
+-	  "https://login.mitra.lindenlab.com/cgi-bin/login.cgi",
+-	  "http://mitra-secondlife.webdev.lindenlab.com/helpers/" },
+-	{ "Mohini",
+-	  "util.mohini.lindenlab.com",
+-	  "https://login.mohini.lindenlab.com/cgi-bin/login.cgi",
+-	  "http://mohini-secondlife.webdev.lindenlab.com/helpers/" },
+-  	{ "Nandi",
+-	  "util.nandi.lindenlab.com",
+-	  "https://login.nandi.lindenlab.com/cgi-bin/login.cgi",
+-	  "http://nandi-secondlife.webdev.lindenlab.com/helpers/" },
+-	{ "Parvati",
+-	  "util.parvati.lindenlab.com",
+-	  "https://login.parvati.lindenlab.com/cgi-bin/login.cgi",
+-	  "http://parvati-secondlife.webdev.lindenlab.com/helpers/" },
+-	{ "Radha",
+-	  "util.radha.lindenlab.com",
+-	  "https://login.radha.lindenlab.com/cgi-bin/login.cgi",
+-	  "http://radha-secondlife.webdev.lindenlab.com/helpers/" },
+-	{ "Ravi",
+-	  "util.ravi.lindenlab.com",
+-	  "https://login.ravi.lindenlab.com/cgi-bin/login.cgi",
+-	  "http://ravi-secondlife.webdev.lindenlab.com/helpers/" },
+-	{ "Siva", 
+-	  "util.siva.lindenlab.com",
+-	  "https://login.siva.lindenlab.com/cgi-bin/login.cgi",
+-	  "http://siva-secondlife.webdev.lindenlab.com/helpers/" },
+-	{ "Shakti",
+-	  "util.shakti.lindenlab.com",
+-	  "https://login.shakti.lindenlab.com/cgi-bin/login.cgi",
+-	  "http://shakti-secondlife.webdev.lindenlab.com/helpers/" },
+-	{ "Skanda",
+-	  "util.skanda.lindenlab.com",
+-	  "https://login.skanda.lindenlab.com/cgi-bin/login.cgi",
+-	  "http://skanda-secondlife.webdev.lindenlab.com/helpers/" },
+-	{ "Soma",
+-	  "util.soma.lindenlab.com",
+-	  "https://login.soma.lindenlab.com/cgi-bin/login.cgi",
+-	  "http://soma-secondlife.webdev.lindenlab.com/helpers/" },
+-	{ "Uma",
+-	  "util.uma.lindenlab.com",
+-	  "https://login.uma.lindenlab.com/cgi-bin/login.cgi",
+-	  "http://uma-secondlife.webdev.lindenlab.com/helpers/" },
+-	{ "Vaak",
+-	  "util.vaak.lindenlab.com",
+-	  "https://login.vaak.lindenlab.com/cgi-bin/login.cgi",
+-	  "http://vaak-secondlife.webdev.lindenlab.com/helpers/" },
+-	{ "Yami",
+-	  "util.yami.lindenlab.com",
+-	  "https://login.yami.lindenlab.com/cgi-bin/login.cgi",
+-	  "http://yami-secondlife.webdev.lindenlab.com/helpers/" },
+-	{ "Local", 
+-	  "localhost", 
+-	  "https://login.dmz.lindenlab.com/cgi-bin/login.cgi",
+-	  "" },
+-	{ "Other", 
+-	  "", 
+-	  "https://login.dmz.lindenlab.com/cgi-bin/login.cgi",
+-	  "" }
+-};
++unsigned char gMACAddress[MAC_ADDRESS_BYTES];		/* Flawfinder: ignore */
+ 
+-const EGridInfo DEFAULT_GRID_CHOICE = GRID_INFO_AGNI;
++ LLViewerLogin::LLViewerLogin() :
++ 	mGridChoice(DEFAULT_GRID_CHOICE)
++ {
+ 
++	gridcount=0;
++	LLSD array = mGridList.emptyArray();
++	LLSD entry = mGridList.emptyMap();
++	entry.insert( "label", "None" );
++	entry.insert( "name", "" );
++	entry.insert( "login_uri", "" );
++	entry.insert( "helper_uri", "" );
++	entry.insert( "login_page", "" );
+ 
+-unsigned char gMACAddress[MAC_ADDRESS_BYTES];		/* Flawfinder: ignore */
++	array.append( entry );
++	gridcount++;
++	
++	entry = mGridList.emptyMap();
++	entry.insert( "label", "Agni" );
++	entry.insert( "name", "util.agni.lindenlab.com" );
++	entry.insert( "login_uri", "https://login.agni.lindenlab.com/cgi-bin/login.cgi" );
++	entry.insert( "helper_uri", "https://secondlife.com/helpers/" );
++	entry.insert( "login_page", "http://secondlife.com/app/login/" );
++	array.append( entry );
++	gridcount++;
++	
++	mGridList.insert("grids", array );
++
++	// load the linden grids if available
++	loadGridsLLSD( gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,"grids.xml") );
++	// see if we have a grids.xml file in "user_settings" to append
++	loadGridsLLSD( gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,"grids.xml") );
++}
++
++void LLViewerLogin::loadGridsLLSD( std::string xml_filename )
++{
++	LLSD other_grids;
++	llifstream llsd_xml;
++	llsd_xml.open( xml_filename.c_str(), std::ios::in | std::ios::binary );
++	
++	if( llsd_xml.is_open()) {
++		llinfos << "Reading grid info: " << xml_filename << llendl;
++		LLSDSerialize::fromXML( other_grids, llsd_xml );
++        for(LLSD::map_iterator grid_itr = other_grids.beginMap(); 
++			             grid_itr != other_grids.endMap(); 
++			             ++grid_itr)
++        {
++			LLSD::String key_name = grid_itr->first;
++			LLSD grid_array = grid_itr->second;
++			llinfos << "reading: " << key_name << llendl;
++			if( grid_array.isArray()) {
++				for( int i = 0; i < grid_array.size(); i++ ) {
++					LLSD gmap = grid_array[i];
++					if( gmap.has("name") && gmap.has("label") && 
++							gmap.has("login_uri") && gmap.has("helper_uri" )) {
++						mGridList["grids"].append( gmap );
++						gridcount++;
++						llinfos << "Added grid: " << gmap.get("name") << llendl;
++					}
++					else {
++						if( gmap.has("name")) {
++							llwarns << "Incomplete grid definition: " << gmap.get("name")<<llendl;													
++						} else {
++							llwarns << "Incomplete grid definition: no name specified" << llendl;					
++						}
++					}
++				}
++			} else {
++				llwarns << "\"grids\" is not an array" << llendl;										
++			}
++		}
++	llsd_xml.close();
++	}	
++}
+ 
+-LLViewerLogin::LLViewerLogin() :
+-	mGridChoice(DEFAULT_GRID_CHOICE)
++void LLViewerLogin::setMenuColor() const
+ {
++	if( mGridList["grids"][mGridChoice].has("menu_color")) {
++		std::string colorName = mGridList["grids"][mGridChoice].get("menu_color").asString();
++		LLColor4 color4;
++		LLColor4::parseColor( colorName.c_str(), &color4 );
++		if( color4 != LLColor4::black ) {
++			gMenuBarView->setBackgroundColor(color4);			
++		}
++	}
+ }
+ 
+-void LLViewerLogin::setGridChoice(EGridInfo grid)
++
++void LLViewerLogin::setGridChoice(int grid)
+ {	
+-	if(grid < 0 || grid >= GRID_INFO_COUNT)
++	if(grid < 0 || grid >= mGridList.get("grids").size())
+ 	{
+-		llerrs << "Invalid grid index specified." << llendl;
++		llwarns << "Invalid grid index specified." << llendl;
++		grid = DEFAULT_GRID_CHOICE;
+ 	}
+ 
+ 	if(mGridChoice != grid || gSavedSettings.getS32("ServerChoice") != grid)
+ 	{
+ 		mGridChoice = grid;
+-		if(GRID_INFO_LOCAL == mGridChoice)
++		if(mGridList.get("grids")[mGridChoice].get("label").asString() == "Local" )
+ 		{
+ 			mGridName = LOOPBACK_ADDRESS_STRING;
+ 		}
+-		else if(GRID_INFO_OTHER == mGridChoice)
++		else if(getGridCount() == mGridChoice)
+ 		{
+ 			// *FIX:Mani - could this possibly be valid?
+ 			mGridName = "other"; 
+ 		}
+ 		else
+ 		{
+-			mGridName = gGridInfo[mGridChoice].mLabel;
++			mGridName = mGridList.get("grids")[mGridChoice].get("label").asString();
++
+ 		}
+ 
+ 		gSavedSettings.setS32("ServerChoice", mGridChoice);
+@@ -193,20 +171,20 @@ void LLViewerLogin::setGridChoice(const std::string& grid_name)
+     {
+         // find the grid choice from the user setting.
+         int grid_index = GRID_INFO_NONE; 
+-        for(;grid_index < GRID_INFO_OTHER; ++grid_index)
++        for(;grid_index < mGridList["grids"].size(); ++grid_index)
+         {
+-            if(0 == LLStringUtil::compareInsensitive(gGridInfo[grid_index].mLabel, grid_name))
++           if(mGridList["grids"][grid_index].get("label").asString()==grid_name.c_str())
+             {
+ 				// Founding a matching label in the list...
+-				setGridChoice((EGridInfo)grid_index);
++				setGridChoice(grid_index);
+ 				break;
+             }
+         }
+ 
+-        if(GRID_INFO_OTHER == grid_index)
++        if(getGridCount() == grid_index)
+         {
+             // *FIX:MEP Can and should we validate that this is an IP address?
+-            mGridChoice = GRID_INFO_OTHER;
++            mGridChoice = getGridCount();
+             mGridName = grid_name;
+ 			gSavedSettings.setS32("ServerChoice", mGridChoice);
+ 			gSavedSettings.setString("CustomServer", mGridName);
+@@ -221,7 +199,7 @@ void LLViewerLogin::resetURIs()
+ 	gSavedSettings.setString("CmdLineHelperURI", "");
+ }
+ 
+-EGridInfo LLViewerLogin::getGridChoice() const
++int LLViewerLogin::getGridChoice() const
+ {
+ 	return mGridChoice;
+ }
+@@ -232,21 +210,37 @@ std::string LLViewerLogin::getGridLabel() const
+ 	{
+ 		return "None";
+ 	}
+-	else if(mGridChoice < GRID_INFO_OTHER)
++	else if(mGridChoice < getGridCount())
+ 	{
+-		return gGridInfo[mGridChoice].mLabel;
++		return mGridList["grids"][mGridChoice].get("label").asString();
+ 	}
+ 
+ 	return mGridName;
+ }
+ 
+-std::string LLViewerLogin::getKnownGridLabel(EGridInfo grid_index) const
++std::string LLViewerLogin::getGridPage() const
++{
++
++	
++	if(mGridChoice == GRID_INFO_NONE)
++	{
++		return "None";
++	}
++	else if(mGridChoice < getGridCount())
++	{
++		return mGridList["grids"][mGridChoice].get("login_page").asString();
++	}
++
++	return "None";
++}
++
++std::string LLViewerLogin::getKnownGridLabel(int grid_index) const
+ {
+-	if(grid_index > GRID_INFO_NONE && grid_index < GRID_INFO_OTHER)
++	if(grid_index > GRID_INFO_NONE && grid_index < getGridCount())
+ 	{
+-		return gGridInfo[grid_index].mLabel;
++		return mGridList.get("grids")[grid_index].get("label").asString();
+ 	}
+-	return gGridInfo[GRID_INFO_NONE].mLabel;
++	return mGridList.get("grids")[GRID_INFO_NONE].get("label").asString();
+ }
+ 
+ void LLViewerLogin::getLoginURIs(std::vector<std::string>& uris) const
+@@ -283,9 +277,9 @@ void LLViewerLogin::getLoginURIs(std::vector<std::string>& uris) const
+ 	{
+ 		// If its a known grid choice, get the uri from the table,
+ 		// else try the grid name.
+-		if(mGridChoice > GRID_INFO_NONE && mGridChoice < GRID_INFO_OTHER)
++		if(mGridChoice > GRID_INFO_NONE && mGridChoice < getGridCount())
+ 		{
+-			uris.push_back(gGridInfo[mGridChoice].mLoginURI);
++			uris.push_back(mGridList["grids"][mGridChoice].get("login_uri").asString());
+ 		}
+ 		else
+ 		{
+@@ -300,9 +294,9 @@ std::string LLViewerLogin::getHelperURI() const
+ 	if (helper_uri.empty())
+ 	{
+ 		// grab URI from selected grid
+-		if(mGridChoice > GRID_INFO_NONE && mGridChoice < GRID_INFO_OTHER)
++		if(mGridChoice > GRID_INFO_NONE && mGridChoice < getGridCount())
+ 		{
+-			helper_uri = gGridInfo[mGridChoice].mHelperURI;
++			helper_uri = mGridList["grids"][mGridChoice].get("helper_uri").asString();
+ 		}
+ 
+ 		if (helper_uri.empty())
+diff --git a/indra/newview/llviewernetwork.h b/indra/newview/llviewernetwork.h
+index 0bb298d..2573f0b 100644
+--- a/indra/newview/llviewernetwork.h
++++ b/indra/newview/llviewernetwork.h
+@@ -34,36 +34,7 @@
+ #define LL_LLVIEWERNETWORK_H
+ 
+ class LLHost;
+-
+-enum EGridInfo
+-{
+-	GRID_INFO_NONE,
+-	GRID_INFO_ADITI,
+-	GRID_INFO_AGNI,
+-	GRID_INFO_ARUNA,
+-	GRID_INFO_BHARATI,
+-	GRID_INFO_CHANDRA,
+-	GRID_INFO_DAMBALLAH,
+-	GRID_INFO_DANU,
+-	GRID_INFO_DURGA,
+-	GRID_INFO_GANGA,
+-	GRID_INFO_MITRA,
+-	GRID_INFO_MOHINI,
+-	GRID_INFO_NANDI,
+-	GRID_INFO_PARVATI,
+-	GRID_INFO_RADHA,
+-	GRID_INFO_RAVI,
+-	GRID_INFO_SIVA,
+-	GRID_INFO_SHAKTI,
+-	GRID_INFO_SKANDA,
+-	GRID_INFO_SOMA,
+-	GRID_INFO_UMA,
+-	GRID_INFO_VAAK,
+-	GRID_INFO_YAMI,
+-	GRID_INFO_LOCAL,
+-	GRID_INFO_OTHER, // IP address set via command line option
+-	GRID_INFO_COUNT
+-};
++class LLSD;
+ 
+ /**
+  * @brief A class to manage the viewer's login state.
+@@ -74,7 +45,7 @@ class LLViewerLogin : public LLSingleton<LLViewerLogin>
+ public:
+ 	LLViewerLogin();
+ 
+-	void setGridChoice(EGridInfo grid);
++	void setGridChoice(const int grid);
+ 	void setGridChoice(const std::string& grid_name);
+ 	void resetURIs();
+ 
+@@ -82,8 +53,10 @@ public:
+ 	* @brief Get the enumeration of the grid choice.
+ 	* Should only return values > 0 && < GRID_INFO_COUNT
+ 	**/
+-	EGridInfo getGridChoice() const;
++	int getGridChoice() const;
+ 
++	int getGridCount() const { return gridcount; }
++	
+ 	/**
+ 	* @brief Get a readable label for the grid choice.
+ 	* Returns the readable name for the grid choice. 
+@@ -91,17 +64,24 @@ public:
+ 	* the string used to specifiy the grid.
+ 	**/
+ 	std::string getGridLabel() const; 
++	std::string getGridPage() const;
+ 
+-	std::string getKnownGridLabel(EGridInfo grid_index) const; 
++	std::string getKnownGridLabel(const int grid_index) const; 
+ 
+ 	void getLoginURIs(std::vector<std::string>& uris) const;
+ 	std::string getHelperURI() const;
+ 
+ 	bool isInProductionGrid();
+ 
++	void setMenuColor() const;
++	
++	void loadGridsLLSD( std::string filename );
++	
+ private:
+-	EGridInfo mGridChoice;
++	int gridcount;
++	int mGridChoice;
+ 	std::string mGridName;
++	LLSD mGridList;
+ };
+ 
+ const S32 MAC_ADDRESS_BYTES = 6;
+-- 
+tg: (1836a2b..) topic/features/jira-backported/VWR-7531-Dynamic-Grid-List (depends on: upstream)
diff --git a/debian/patches/topic/features/jira-backported/avatar_list.diff b/debian/patches/topic/features/jira-backported/avatar_list.diff
new file mode 100644
index 0000000..6e5c07e
--- /dev/null
+++ b/debian/patches/topic/features/jira-backported/avatar_list.diff
@@ -0,0 +1,5211 @@
+From: Robin Cornelius <robin.cornelius at gmail.com>
+Subject: [PATCH] topic/features/jira-backported/avatar_list
+
+Dale Glass's avatar scanner as published on JIRA and rebased by Carjay
+
+Signed-off-by: Robin Cornelius <robin.cornelius at gmail.com>
+
+---
+ indra/llaudio/audioengine.h                        |    1 +
+ indra/llmessage/llmessagetemplate.h                |  111 +-
+ indra/llmessage/message.cpp                        |   28 +-
+ indra/llmessage/message.h                          |   18 +-
+ indra/llui/llscrolllistctrl.cpp                    |   41 +
+ indra/llui/llscrolllistctrl.h                      |    2 +
+ indra/newview/CMakeLists.txt                       |    3 +
+ indra/newview/app_settings/settings.xml            |   16 +
+ indra/newview/llagent.cpp                          |  121 +-
+ indra/newview/llagent.h                            |   14 +
+ indra/newview/llappviewer.cpp                      |    4 +
+ indra/newview/llchatbar.cpp                        |   34 +-
+ indra/newview/llfloateravatarlist.cpp              | 2187 ++++++++++++++++++++
+ indra/newview/llfloateravatarlist.h                |  868 ++++++++
+ indra/newview/llfloaterpreference.cpp              |    7 +
+ indra/newview/llfloaterpreference.h                |    2 +
+ indra/newview/llfloaterreporter.cpp                |   13 +-
+ indra/newview/llfloaterreporter.h                  |    2 +-
+ indra/newview/llpaneldatabase.cpp                  |  149 ++
+ indra/newview/llpaneldatabase.h                    |   65 +
+ indra/newview/llstartup.cpp                        |    2 +-
+ indra/newview/lltoolbar.cpp                        |    9 +
+ indra/newview/lltoolbar.h                          |    1 +
+ indra/newview/llviewermenu.cpp                     |   14 +
+ indra/newview/llviewermessage.cpp                  |    3 +
+ indra/newview/llviewerobject.h                     |    3 +-
+ indra/newview/llviewerwindow.cpp                   |    8 +-
+ indra/newview/llwebbrowserctrl.h                   |    2 +
+ indra/newview/pipeline.cpp                         |   42 +
+ indra/newview/skins/default/xui/en-us/alerts.xml   |  135 ++
+ .../default/xui/en-us/floater_avatar_scanner.xml   |  413 ++++
+ .../skins/default/xui/en-us/menu_viewer.xml        |   13 +
+ indra/newview/skins/default/xui/en-us/notify.xml   |    6 +
+ .../xui/en-us/panel_preferences_database.xml       |  166 ++
+ .../skins/default/xui/en-us/panel_toolbar.xml      |    7 +
+ 35 files changed, 4447 insertions(+), 63 deletions(-)
+
+diff --git a/indra/llaudio/audioengine.h b/indra/llaudio/audioengine.h
+index b582f14..0468862 100644
+--- a/indra/llaudio/audioengine.h
++++ b/indra/llaudio/audioengine.h
+@@ -313,6 +313,7 @@ public:
+ 	bool setupChannel();
+ 	bool play(const LLUUID &audio_id);	// Start the audio source playing
+ 
++	const LLUUID &getOwnerID()		{ return mOwnerID; }
+ 	bool hasPendingPreloads() const;	// Has preloads that haven't been done yet
+ 
+ 	friend class LLAudioEngine;
+diff --git a/indra/llmessage/llmessagetemplate.h b/indra/llmessage/llmessagetemplate.h
+index 2390eea..6638a75 100644
+--- a/indra/llmessage/llmessagetemplate.h
++++ b/indra/llmessage/llmessagetemplate.h
+@@ -35,7 +35,11 @@
+ #include "lldarray.h"
+ #include "message.h" // TODO: babbage: Remove...
+ #include "llstat.h"
++#include "llmsgvariabletype.h"
+ #include "llstl.h"
++#include <list>
++#include <algorithm>
++#include <functional>
+ 
+ class LLMsgVarData
+ {
+@@ -270,6 +274,30 @@ enum EMsgDeprecation
+ 	MD_DEPRECATED
+ };
+ 
++class LLMessageTemplateHandlerEntry
++{
++public:
++	LLMessageTemplateHandlerEntry(message_handler_func_t handler, void **userdata = NULL) :
++		mHandlerFunc(handler), mUserData(userdata) {}
++
++	void call(LLMessageSystem *msgsystem) const { mHandlerFunc(msgsystem, mUserData); }
++
++	bool operator==(const LLMessageTemplateHandlerEntry&a) { return mHandlerFunc == a.mHandlerFunc; }
++private:
++	// message handler function (this is set by each application)
++	message_handler_func_t mHandlerFunc;
++	void **mUserData;	
++};
++
++class callHandler : public std::unary_function<LLMessageTemplateHandlerEntry, void>
++{
++public:
++	callHandler(LLMessageSystem *msg) : mMsg(msg) {}
++	void operator()(const LLMessageTemplateHandlerEntry& a) const { a.call(mMsg); }
++private:
++	LLMessageSystem *mMsg;
++};
++
+ class LLMessageTemplate
+ {
+ public:
+@@ -291,9 +319,7 @@ public:
+ 		mTotalDecodeTime(0.f),
+ 		mMaxDecodeTimePerMsg(0.f),
+ 		mBanFromTrusted(false),
+-		mBanFromUntrusted(false),
+-		mHandlerFunc(NULL), 
+-		mUserData(NULL)
++		mBanFromUntrusted(false)
+ 	{ 
+ 		mName = LLMessageStringTable::getInstance()->getString(name);
+ 	}
+@@ -361,21 +387,84 @@ public:
+ 		return mDeprecation;
+ 	}
+ 	
+-	void setHandlerFunc(void (*handler_func)(LLMessageSystem *msgsystem, void **user_data), void **user_data)
++	/**
++	 * @brief Adds a handler
++	 * This function adds a new handler to be called when the message arrives.
++	 * Repeated additions of the same handler function will be ignored.
++	 * @note delHandlerFunc() must be called to remove the registration
++	 * @param handler Function to call
++	 * @param user_data User specified data to pass to the function
++	 */
++	void addHandlerFunc(message_handler_func_t handler, void **user_data)	
++	{
++		LLMessageTemplateHandlerEntry h(handler, user_data);
++
++		if ( std::find(mHandlers.begin(), mHandlers.end(), h ) != mHandlers.end() )
++		{
++			return;
++		}
++
++		mHandlers.push_back( h );
++	}
++
++	/**
++	 * @brief Sets a handler
++	 * This function sets a handler to be called when the message arrives.
++	 * Any existing handlers are unregistered.
++	 * @note delHandlerFunc() must be called to remove the registration
++	 * @param handler Function to call
++	 * @param user_data User specified data to pass to the function
++	 */
++	void setHandlerFunc(message_handler_func_t handler, void **user_data)
++	{
++		mHandlers.clear();
++		if( handler )
++		{
++			addHandlerFunc(handler, user_data);
++		}
++		else
++		{
++			llwarns << "code has reset handler for \"" << mName << "\" by setting it to NULL." << llendl;
++		}
++	}
++
++	/**
++	 * @brief Removes a handler
++	 * Removes a handler from the list of handlers.
++	 * Attempts to remove handlers that aren't in the list are silently
++	 * ignored.
++	 * @param handler Function to remove
++	 */
++	void delHandlerFunc(message_handler_func_t handler)
+ 	{
+-		mHandlerFunc = handler_func;
+-		mUserData = user_data;
++		mHandlers.remove( LLMessageTemplateHandlerEntry(handler) );
+ 	}
+ 
+ 	BOOL callHandlerFunc(LLMessageSystem *msgsystem) const
+ 	{
+-		if (mHandlerFunc)
++		if ( mHandlers.empty() )
++		{
++			return FALSE;
++		}
++		/* 
++		 * Be on the safe side and use for_each only when necessary. There is Linden code ("ReplyPayPrice") that
++		 * does not take the multiple reply handlers into account and simply tries to unregister
++		 * by setting the handler function to 0, unfortunately from within the reply handler so in this case
++		 * the for_each iterator inside std_algo.h is invalidated leading to a crash if the memory is reused
++		 * in between.
++		 */
++		else if( mHandlers.size() == 1 )
+ 		{
+             LLPerfBlock msg_cb_time("msg_cb", mName);
+-			mHandlerFunc(msgsystem, mUserData);
++			mHandlers.begin()->call(msgsystem);
++			return TRUE;
++		}
++		else
++		{
++            LLPerfBlock msg_cb_time("msg_cb", mName);
++			std::for_each(mHandlers.begin(), mHandlers.end(), callHandler(msgsystem));
+ 			return TRUE;
+ 		}
+-		return FALSE;
+ 	}
+ 
+ 	bool isUdpBanned() const
+@@ -420,9 +509,7 @@ public:
+ 	bool									mBanFromUntrusted;
+ 
+ private:
+-	// message handler function (this is set by each application)
+-	void									(*mHandlerFunc)(LLMessageSystem *msgsystem, void **user_data);
+-	void									**mUserData;
++	std::list<LLMessageTemplateHandlerEntry> mHandlers;
+ };
+ 
+ #endif // LL_LLMESSAGETEMPLATE_H
+diff --git a/indra/llmessage/message.cpp b/indra/llmessage/message.cpp
+index ccc3d79..30d7676 100644
+--- a/indra/llmessage/message.cpp
++++ b/indra/llmessage/message.cpp
+@@ -2972,7 +2972,7 @@ void LLMessageSystem::addTemplate(LLMessageTemplate *templatep)
+ }
+ 
+ 
+-void LLMessageSystem::setHandlerFuncFast(const char *name, void (*handler_func)(LLMessageSystem *msgsystem, void **user_data), void **user_data)
++void LLMessageSystem::setHandlerFuncFast(const char *name, message_handler_func_t handler_func, void **user_data)
+ {
+ 	LLMessageTemplate* msgtemplate = get_ptr_in_map(mMessageTemplates, name);
+ 	if (msgtemplate)
+@@ -2985,6 +2985,32 @@ void LLMessageSystem::setHandlerFuncFast(const char *name, void (*handler_func)(
+ 	}
+ }
+ 
++void LLMessageSystem::addHandlerFuncFast(const char *name, message_handler_func_t handler_func, void **user_data)
++{
++	LLMessageTemplate* msgtemplate = get_ptr_in_map(mMessageTemplates, name);
++	if (msgtemplate)
++	{
++		msgtemplate->addHandlerFunc(handler_func, user_data);
++	}
++	else
++	{
++		llerrs << name << " is not a known message name!" << llendl;
++	}
++}
++
++void LLMessageSystem::delHandlerFuncFast(const char *name, message_handler_func_t handler_func)
++{
++	LLMessageTemplate* msgtemplate = get_ptr_in_map(mMessageTemplates, name);
++	if (msgtemplate)
++	{
++		msgtemplate->delHandlerFunc(handler_func);
++	}
++	else
++	{
++		llerrs << name << " is not a known message name!" << llendl;
++	}
++}
++
+ bool LLMessageSystem::callHandler(const char *name,
+ 		bool trustedSource, LLMessageSystem* msg)
+ {
+diff --git a/indra/llmessage/message.h b/indra/llmessage/message.h
+index c503a58..bace5a1 100644
+--- a/indra/llmessage/message.h
++++ b/indra/llmessage/message.h
+@@ -179,7 +179,7 @@ enum EMessageException
+ 	MX_WROTE_PAST_BUFFER_SIZE // wrote past buffer size in zero code expand
+ };
+ typedef void (*msg_exception_callback)(LLMessageSystem*,void*,EMessageException);
+-
++typedef void (*message_handler_func_t)(LLMessageSystem *msgsystem, void **user_data);
+ 
+ // message data pieces are used to collect the data called for by the message template
+ class LLMsgData;
+@@ -299,12 +299,24 @@ public:
+ 
+ 
+ 	// methods for building, sending, receiving, and handling messages
+-	void	setHandlerFuncFast(const char *name, void (*handler_func)(LLMessageSystem *msgsystem, void **user_data), void **user_data = NULL);
+-	void	setHandlerFunc(const char *name, void (*handler_func)(LLMessageSystem *msgsystem, void **user_data), void **user_data = NULL)
++	void	setHandlerFuncFast(const char *name, message_handler_func_t, void **user_data = NULL);
++	void	setHandlerFunc(const char *name, message_handler_func_t handler_func, void **user_data = NULL)
+ 	{
+ 		setHandlerFuncFast(LLMessageStringTable::getInstance()->getString(name), handler_func, user_data);
+ 	}
+ 
++	void	addHandlerFuncFast(const char *name, message_handler_func_t, void **user_data = NULL);
++	void	addHandlerFunc(const char *name, message_handler_func_t handler_func, void **user_data = NULL)
++	{
++		addHandlerFuncFast(LLMessageStringTable::getInstance()->getString(name), handler_func, user_data);
++	}
++
++	void	delHandlerFuncFast(const char *name, message_handler_func_t);
++	void	delHandlerFunc(const char *name, message_handler_func_t handler_func)
++	{
++		delHandlerFuncFast(LLMessageStringTable::getInstance()->getString(name), handler_func);
++	}
++
+ 	// Set a callback function for a message system exception.
+ 	void setExceptionFunc(EMessageException exception, msg_exception_callback func, void* data = NULL);
+ 	// Call the specified exception func, and return TRUE if a
+diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
+index 7dba55f..8cff81e 100644
+--- a/indra/llui/llscrolllistctrl.cpp
++++ b/indra/llui/llscrolllistctrl.cpp
+@@ -703,6 +703,29 @@ std::vector<LLScrollListItem*> LLScrollListCtrl::getAllSelected() const
+ 	return ret;
+ }
+ 
++/**
++ * Returns the selected IDs
++ * @returns List of selected IDs
++ * @author Dale Glass
++ */
++LLDynamicArray<LLUUID> LLScrollListCtrl::getSelectedIDs()
++{
++	LLUUID selected_id;
++	LLDynamicArray<LLUUID> ret;
++
++	item_list::const_iterator iter;
++	for(iter = mItemList.begin(); iter != mItemList.end(); iter++)
++	{
++		LLScrollListItem* item  = *iter;
++		if (item->getSelected())
++		{
++			ret.push_back(item->getUUID());
++		}
++	}
++	return ret;
++}
++
++
+ S32 LLScrollListCtrl::getFirstSelectedIndex() const
+ {
+ 	S32 CurSelectedIndex = 0;
+@@ -2534,6 +2557,23 @@ void LLScrollListCtrl::onScrollChange( S32 new_pos, LLScrollbar* scrollbar, void
+ }
+ 
+ 
++/**
++ * Re-sorts the list
++ *
++ * This function allows to avoid multiple unnecessary sorts in the case where
++ * multiple elements will be added or removed at once.
++ * @author Dale Glass
++ */
++void LLScrollListCtrl::sort()
++{
++	// sort by column 0, in ascending order
++	std::stable_sort(
++		mItemList.begin(), 
++		mItemList.end(), 
++		SortScrollListItem(mSortColumns));
++}
++
++
+ void LLScrollListCtrl::sortByColumn(const std::string& name, BOOL ascending)
+ {
+ 	std::map<std::string, LLScrollListColumn>::iterator itor = mColumns.find(name);
+@@ -3851,3 +3891,4 @@ BOOL LLColumnHeader::canResize()
+ {
+ 	return getVisible() && (mHasResizableElement || mColumn->mDynamicWidth);
+ }
++
+diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h
+index f276562..859e6ae 100644
+--- a/indra/llui/llscrolllistctrl.h
++++ b/indra/llui/llscrolllistctrl.h
+@@ -421,6 +421,7 @@ public:
+ 	// Sets an array of column descriptors
+ 	void 	   		setColumnHeadings(LLSD headings);
+ 	void   			sortByColumnIndex(U32 column, BOOL ascending);
++	void            sort();
+ 	
+ 	// LLCtrlListInterface functions
+ 	virtual S32  getItemCount() const;
+@@ -518,6 +519,7 @@ public:
+ 	virtual S32			getFirstSelectedIndex() const;
+ 	std::vector<LLScrollListItem*> getAllSelected() const;
+ 	LLScrollListItem*	getLastSelectedItem() const { return mLastSelected; }
++ 	LLDynamicArray<LLUUID> 	getSelectedIDs();
+ 
+ 	// iterate over all items
+ 	LLScrollListItem*	getFirstData() const;
+diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
+index b95ba37..ec98c7c 100644
+--- a/indra/newview/CMakeLists.txt
++++ b/indra/newview/CMakeLists.txt
+@@ -123,6 +123,7 @@ set(viewer_SOURCE_FILES
+     llfloateranimpreview.cpp
+     llfloaterauction.cpp
+     llfloateravatarinfo.cpp
++    llfloateravatarlist.cpp
+     llfloateravatarpicker.cpp
+     llfloateravatartextures.cpp
+     llfloaterbeacons.cpp
+@@ -245,6 +246,7 @@ set(viewer_SOURCE_FILES
+     llpanelaudioprefs.cpp
+     llpanelaudiovolume.cpp
+     llpanelavatar.cpp
++    llpaneldatabase.cpp
+     llpanelclassified.cpp
+     llpanelcontents.cpp
+     llpaneldebug.cpp
+@@ -639,6 +641,7 @@ set(viewer_HEADER_FILES
+     llpanelaudioprefs.h
+     llpanelaudiovolume.h
+     llpanelavatar.h
++    llpaneldatabase.h
+     llpanelclassified.h
+     llpanelcontents.h
+     llpaneldebug.h
+diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
+index 27eacfb..225894c 100644
+--- a/indra/newview/app_settings/settings.xml
++++ b/indra/newview/app_settings/settings.xml
+@@ -2622,6 +2622,22 @@
+         <integer>0</integer>
+       </array>
+     </map>
++    <key>FloaterAvatarListRect</key>
++    <map>
++      <key>Comment</key>
++      <string>Rectangle avatar list window</string>
++      <key>Persist</key>
++      <integer>1</integer>
++      <key>Type</key>
++      <string>Rect</string>
++      <key>Value</key>
++      <array>
++        <integer>0</integer>
++        <integer>400</integer>
++        <integer>200</integer>
++        <integer>0</integer>
++      </array>
++    </map>
+     <key>FloaterAudioVolumeRect</key>
+     <map>
+       <key>Comment</key>
+diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
+index 301f00b..23982ee 100644
+--- a/indra/newview/llagent.cpp
++++ b/indra/newview/llagent.cpp
+@@ -67,6 +67,7 @@
+ #include "llfloater.h"
+ #include "llfloateractivespeakers.h"
+ #include "llfloateravatarinfo.h"
++#include "llfloateravatarlist.h"
+ #include "llfloaterbuildoptions.h"
+ #include "llfloatercamera.h"
+ #include "llfloaterchat.h"
+@@ -2747,7 +2748,18 @@ void LLAgent::startTyping()
+ 	{
+ 		sendAnimationRequest(ANIM_AGENT_TYPE, ANIM_REQUEST_START);
+ 	}
+-	gChatBar->sendChatFromViewer("", CHAT_TYPE_START, FALSE);
++	sendChat("", 0, CHAT_TYPE_START, false);
++
++	// Addition for avatar list support.
++	// Makes the fact that this avatar is typing appear in the list
++	if ( NULL != gFloaterAvatarList )
++	{
++		LLAvatarListEntry *ent = gFloaterAvatarList->getAvatarEntry(getID());
++		if ( NULL != ent )
++		{
++			ent->setActivity(ACTIVITY_TYPING);
++		}
++	}
+ }
+ 
+ //-----------------------------------------------------------------------------
+@@ -2759,7 +2771,7 @@ void LLAgent::stopTyping()
+ 	{
+ 		clearRenderState(AGENT_STATE_TYPING);
+ 		sendAnimationRequest(ANIM_AGENT_TYPE, ANIM_REQUEST_STOP);
+-		gChatBar->sendChatFromViewer("", CHAT_TYPE_STOP, FALSE);
++		sendChat("", 0, CHAT_TYPE_STOP, false);
+ 	}
+ }
+ 
+@@ -4585,10 +4597,16 @@ void LLAgent::heardChat(const LLUUID& id)
+ 	mChatTimer.reset();
+ }
+ 
++
++void LLAgent::lookAtLastChat()
++{
++	lookAtObject(mLastChatterID, CAMERA_POSITION_SELF);
++}
++
+ //-----------------------------------------------------------------------------
+ // lookAtLastChat()
+ //-----------------------------------------------------------------------------
+-void LLAgent::lookAtLastChat()
++void LLAgent::lookAtObject(LLUUID object_id, ECameraPosition camera_pos)
+ {
+ 	// Block if camera is animating or not in normal third person camera mode
+ 	if (mCameraAnimating || !cameraThirdPerson())
+@@ -4596,7 +4614,7 @@ void LLAgent::lookAtLastChat()
+ 		return;
+ 	}
+ 
+-	LLViewerObject *chatter = gObjectList.findObject(mLastChatterID);
++	LLViewerObject *chatter = gObjectList.findObject(object_id);
+ 	if (chatter)
+ 	{
+ 		LLVector3 delta_pos;
+@@ -4625,15 +4643,39 @@ void LLAgent::lookAtLastChat()
+ 			new_camera_pos -= delta_pos * 0.4f;
+ 			new_camera_pos += left * 0.3f;
+ 			new_camera_pos += up * 0.2f;
++
++			F32 radius = chatter_av->getVObjRadius();
++			LLVector3d view_dist(radius, radius, 0.0f);
++
+ 			if (chatter_av->mHeadp)
+ 			{
+-				setFocusGlobal(getPosGlobalFromAgent(chatter_av->mHeadp->getWorldPosition()), mLastChatterID);
++				setFocusGlobal(getPosGlobalFromAgent(chatter_av->mHeadp->getWorldPosition()), object_id);
+ 				mCameraFocusOffsetTarget = getPosGlobalFromAgent(new_camera_pos) - gAgent.getPosGlobalFromAgent(chatter_av->mHeadp->getWorldPosition());
++
++				switch(camera_pos)
++				{
++					case CAMERA_POSITION_SELF:
++						mCameraFocusOffsetTarget = getPosGlobalFromAgent(new_camera_pos) - gAgent.getPosGlobalFromAgent(chatter_av->mHeadp->getWorldPosition());
++						break;
++					case CAMERA_POSITION_OBJECT:
++						mCameraFocusOffsetTarget =  view_dist;
++						break;
++				}
+ 			}
+ 			else
+ 			{
+-				setFocusGlobal(chatter->getPositionGlobal(), mLastChatterID);
++				setFocusGlobal(chatter->getPositionGlobal(), object_id);
+ 				mCameraFocusOffsetTarget = getPosGlobalFromAgent(new_camera_pos) - chatter->getPositionGlobal();
++
++				switch(camera_pos)
++				{
++					case CAMERA_POSITION_SELF:
++						mCameraFocusOffsetTarget = getPosGlobalFromAgent(new_camera_pos) - chatter->getPositionGlobal();
++						break;
++					case CAMERA_POSITION_OBJECT:
++						mCameraFocusOffsetTarget = view_dist;
++						break;
++				}
+ 			}
+ 			setFocusOnAvatar(FALSE, TRUE);
+ 		}
+@@ -4655,8 +4697,20 @@ void LLAgent::lookAtLastChat()
+ 			new_camera_pos += left * 0.3f;
+ 			new_camera_pos += up * 0.2f;
+ 
+-			setFocusGlobal(chatter->getPositionGlobal(), mLastChatterID);
+-			mCameraFocusOffsetTarget = getPosGlobalFromAgent(new_camera_pos) - chatter->getPositionGlobal();
++			setFocusGlobal(chatter->getPositionGlobal(), object_id);
++
++			switch(camera_pos)
++			{
++				case CAMERA_POSITION_SELF:
++					mCameraFocusOffsetTarget = getPosGlobalFromAgent(new_camera_pos) - chatter->getPositionGlobal();
++					break;
++				case CAMERA_POSITION_OBJECT:
++					F32 radius = chatter->getVObjRadius();
++					LLVector3d view_dist(radius, radius, 0.0f);
++					mCameraFocusOffsetTarget = view_dist;
++					break;
++			}
++
+ 			setFocusOnAvatar(FALSE, TRUE);
+ 		}
+ 	}
+@@ -6012,6 +6066,57 @@ void LLAgent::setTeleportState(ETeleportState state)
+ 	}
+ }
+ 
++void LLAgent::sendChat(const std::string &text, S32 channel, EChatType type, bool animate)
++{
++
++	// Don't animate for chats people can't hear (chat to scripts)
++	if (animate && (channel == 0))
++	{
++		if (type == CHAT_TYPE_WHISPER)
++		{
++			lldebugs << "You whisper " << text << llendl;
++			sendAnimationRequest(ANIM_AGENT_WHISPER, ANIM_REQUEST_START);
++		}
++		else if (type == CHAT_TYPE_NORMAL)
++		{
++			lldebugs << "You say " << text << llendl;
++			sendAnimationRequest(ANIM_AGENT_TALK, ANIM_REQUEST_START);
++		}
++		else if (type == CHAT_TYPE_SHOUT)
++		{
++			lldebugs << "You shout " << text << llendl;
++			sendAnimationRequest(ANIM_AGENT_SHOUT, ANIM_REQUEST_START);
++		}
++		else
++		{
++			llinfos << "send_chat_from_viewer() - invalid volume" << llendl;
++			return;
++		}
++	}
++	else
++	{
++		if (type != CHAT_TYPE_START && type != CHAT_TYPE_STOP)
++		{
++			lldebugs << "Channel chat: " << text << llendl;
++		}
++	}
++
++	LLMessageSystem* msg = gMessageSystem;
++
++	msg->newMessageFast(_PREHASH_ChatFromViewer);
++	msg->nextBlockFast(_PREHASH_AgentData);
++	msg->addUUIDFast(_PREHASH_AgentID, getID());
++	msg->addUUIDFast(_PREHASH_SessionID, getSessionID());
++	msg->nextBlockFast(_PREHASH_ChatData);
++	msg->addStringFast(_PREHASH_Message, text);
++	msg->addU8Fast(_PREHASH_Type, type);
++	msg->addS32("Channel", channel);
++
++	gAgent.sendReliableMessage();
++
++	LLViewerStats::getInstance()->incStat(LLViewerStats::ST_CHAT_COUNT);
++}
++
+ void LLAgent::fidget()
+ {
+ 	if (!getAFK())
+diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h
+index 3d3a94b..2b325f9 100644
+--- a/indra/newview/llagent.h
++++ b/indra/newview/llagent.h
+@@ -36,6 +36,7 @@
+ 
+ #include "indra_constants.h"
+ #include "llmath.h"
++#include "llchat.h"
+ #include "llcontrol.h"
+ #include "llcoordframe.h"
+ #include "llevent.h"
+@@ -80,6 +81,15 @@ typedef enum e_camera_modes
+ 	CAMERA_MODE_FOLLOW
+ } ECameraMode;
+ 
++/**
++ * @brief When looking at an object, where is the camera offset from
++ */
++typedef enum e_camera_position
++{
++	CAMERA_POSITION_SELF, /** Camera positioned at our position */
++	CAMERA_POSITION_OBJECT /** Camera positioned at observed object's position */
++} ECameraPosition;
++
+ typedef enum e_anim_request
+ {
+ 	ANIM_REQUEST_START,
+@@ -206,6 +216,7 @@ public:
+ 
+ 	void			heardChat(const LLUUID& id);
+ 	void			lookAtLastChat();
++	void			lookAtObject(LLUUID avatar_id, ECameraPosition camera_pos);
+ 	F32			getTypingTime() { return mTypingTimer.getElapsedTimeF32(); }
+ 
+ 	void			setAFK();
+@@ -479,6 +490,9 @@ public:
+ 
+ 	const std::string getTeleportSourceSLURL() const { return mTeleportSourceSLURL; }
+ 
++	void sendChat(const std::string &text, S32 channel = 0, EChatType type = CHAT_TYPE_NORMAL, bool animate = false);
++	void sendChat(const std::wstring &text, S32 channel = 0, EChatType type = CHAT_TYPE_NORMAL, bool animate = false)
++		{ sendChat(wstring_to_utf8str(text), channel, type, animate); }
+ 
+ 	// Setting the ability for this avatar to proxy for another avatar.
+ 	//static void processAddModifyAbility(LLMessageSystem* msg, void**);
+diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
+index 09d1141..bdd0def 100644
+--- a/indra/newview/llappviewer.cpp
++++ b/indra/newview/llappviewer.cpp
+@@ -33,6 +33,7 @@
+ #include "llviewerprecompiledheaders.h"
+ #include "llappviewer.h"
+ #include "llprimitive.h"
++#include "llfloateravatarlist.h"
+ 
+ #include "llversionviewer.h"
+ #include "llfeaturemanager.h"
+@@ -3166,6 +3167,9 @@ void LLAppViewer::idle()
+ 		}
+ 		gFrameStats.addFrameData();
+ 	}
++
++	// Update avatar list
++	gFloaterAvatarList->updateAvatarList();
+ 	
+ 	if (!gDisconnected)
+ 	{
+diff --git a/indra/newview/llchatbar.cpp b/indra/newview/llchatbar.cpp
+index 84ebf98..1678bc3 100644
+--- a/indra/newview/llchatbar.cpp
++++ b/indra/newview/llchatbar.cpp
+@@ -585,39 +585,7 @@ void LLChatBar::sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL
+ 		utf8_text = utf8str_truncate(utf8_text, MAX_STRING - 1);
+ 	}
+ 
+-	// Don't animate for chats people can't hear (chat to scripts)
+-	if (animate && (channel == 0))
+-	{
+-		if (type == CHAT_TYPE_WHISPER)
+-		{
+-			lldebugs << "You whisper " << utf8_text << llendl;
+-			gAgent.sendAnimationRequest(ANIM_AGENT_WHISPER, ANIM_REQUEST_START);
+-		}
+-		else if (type == CHAT_TYPE_NORMAL)
+-		{
+-			lldebugs << "You say " << utf8_text << llendl;
+-			gAgent.sendAnimationRequest(ANIM_AGENT_TALK, ANIM_REQUEST_START);
+-		}
+-		else if (type == CHAT_TYPE_SHOUT)
+-		{
+-			lldebugs << "You shout " << utf8_text << llendl;
+-			gAgent.sendAnimationRequest(ANIM_AGENT_SHOUT, ANIM_REQUEST_START);
+-		}
+-		else
+-		{
+-			llinfos << "send_chat_from_viewer() - invalid volume" << llendl;
+-			return;
+-		}
+-	}
+-	else
+-	{
+-		if (type != CHAT_TYPE_START && type != CHAT_TYPE_STOP)
+-		{
+-			lldebugs << "Channel chat: " << utf8_text << llendl;
+-		}
+-	}
+-
+-	send_chat_from_viewer(utf8_out_text, type, channel);
++	gAgent.sendChat(utf8_out_text, channel, type, animate);
+ }
+ 
+ void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel)
+diff --git a/indra/newview/llfloateravatarlist.cpp b/indra/newview/llfloateravatarlist.cpp
+new file mode 100644
+index 0000000..e1656eb
+--- /dev/null
++++ b/indra/newview/llfloateravatarlist.cpp
+@@ -0,0 +1,2187 @@
++/** 
++ * @file llfloatermute.cpp
++ * @brief Container for mute list
++ *
++ * @author Dale Glass <dale at daleglass.net>, (C) 2007
++ */
++
++#include "llviewerprecompiledheaders.h" // must be first include
++
++#include "llavatarconstants.h"
++#include "llfloateravatarlist.h"
++
++#include "lluictrlfactory.h" // builds floaters from XML
++#include "llviewerwindow.h"
++#include "llscrolllistctrl.h"
++
++#include "llvoavatar.h"
++#include "llimview.h"
++#include "llfloateravatarinfo.h"
++#include "llregionflags.h"
++#include "llfloaterreporter.h"
++#include "llagent.h"
++#include "llviewerregion.h"
++#include "lltracker.h"
++#include "llviewercontrol.h"
++#include "llviewerstats.h"
++#include "llerror.h"
++#include "llchat.h"
++#include "llviewermessage.h"
++#include "llweb.h"
++#include "llviewerobjectlist.h"
++#include "llmutelist.h"
++#include "llviewerimagelist.h"
++#include "llworld.h"
++#include "llcachename.h"
++#include "llviewercamera.h"
++
++#include <time.h>
++#include <string.h>
++
++#include <map>
++
++
++// Timeouts
++/**
++ * @brief How long to keep showing an activity, in seconds
++ */
++const F32 ACTIVITY_TIMEOUT = 1.0f;
++
++
++/**
++ * @brief How many seconds to wait between data requests
++ *
++ * This is intended to avoid flooding the server with requests
++ */
++const F32 MIN_REQUEST_INTERVAL   = 1.0f;
++
++/**
++ * @brief How long to wait for a request to arrive during the first try in seconds
++ */
++const F32 FIRST_REQUEST_TIMEOUT  = 16.0f;
++
++/**
++ * @brief Delay is doubled on each attempt. This is as high as it'll go
++ */
++const F32 MAX_REQUEST_TIMEOUT    = 2048.0f;
++ 
++/**
++ * How long to wait for a request to arrive before assuming failure
++ * and showing the failure icon in the list. This is just for the user's
++ * information, if a reply arrives after this interval we'll accept it anyway.
++ */
++const F32 REQUEST_FAIL_TIMEOUT   = 15.0f;
++
++/**
++ * How long to keep people who are gone in the list. After this time is reached,
++ * they're not shown in the list anymore, but still kept in memory until
++ * CLEANUP_TIMEOUT is reached.
++ */
++const F32 DEAD_KEEP_TIME = 10.0f;
++
++/**
++ * @brief How long to keep entries around before removing them.
++ *
++ * @note Longer term, data like birth and payment info should be cached on disk.
++ */
++const F32 CLEANUP_TIMEOUT = 3600.0f;
++
++
++/**
++ * @brief TrustNet channel
++ * This is fixed in the adapter script.
++ */
++const S32 TRUSTNET_CHANNEL = 0x44470002;
++
++
++extern U32 gFrameCount;
++
++
++LLAvListTrustNetScore::LLAvListTrustNetScore(std::string type, F32 score)
++{
++	Score = score;
++	Type = type;	
++}
++
++LLAvatarInfo::LLAvatarInfo()
++{
++}
++
++LLAvatarInfo::LLAvatarInfo(PAYMENT_TYPE payment, ACCOUNT_TYPE account, struct tm birth)
++{
++	Payment = payment;
++	Account = account;
++	BirthDate = birth;
++}
++
++S32 LLAvatarInfo::getAge()
++{
++	time_t birth = mktime(&BirthDate);
++	time_t now = time(NULL);
++	return(S32)(difftime(now,birth) / (60*60*24));
++}
++
++void LLAvatarListEntry::setPosition(LLVector3d position)
++{
++	if ( mPosition != position )
++	{
++		setActivity(ACTIVITY_MOVING);
++	}
++
++	mPosition = position;
++	mFrame = gFrameCount;
++	mUpdateTimer.start();
++}
++
++LLVector3d LLAvatarListEntry::getPosition()
++{
++	return mPosition;
++}
++
++U32 LLAvatarListEntry::getEntryAgeFrames()
++{
++	return (gFrameCount - mFrame);
++}
++
++F32 LLAvatarListEntry::getEntryEnteredSeconds()
++{
++	return mEnteredTimer.getElapsedTimeF32();
++}
++
++F32 LLAvatarListEntry::getEntryAgeSeconds()
++{
++	return mUpdateTimer.getElapsedTimeF32();
++}
++
++void LLAvatarListEntry::setName(std::string name)
++{
++	if ( name.empty() || (name.compare(" ") == 0))
++	{
++		llwarns << "Trying to set empty name" << llendl;
++	}
++	mName = name;
++}
++
++std::string LLAvatarListEntry::getName()
++{
++	return mName;
++}
++
++LLUUID LLAvatarListEntry::getID()
++{
++	return mID;
++}
++
++void LLAvatarListEntry::setID(LLUUID id)
++{
++	if ( id.isNull() )
++	{
++		llwarns << "Trying to set null id" << llendl;
++	}
++	mID = id;
++}
++
++BOOL LLAvatarListEntry::getIsLinden()
++{
++	// Are there any employees that are not a Linden?
++	// I suppose this is a bit redundant.
++	return ( mIsLinden || ( mAvatarInfo.getValue().Account == ACCOUNT_EMPLOYEE ) );
++}
++
++void LLAvatarListEntry::setAccountCustomTitle(std::string &title)
++{
++	mAccountTitle = title;
++	mAvatarInfo.getValue().Account = ACCOUNT_CUSTOM;
++}
++
++std::string LLAvatarListEntry::getAccountCustomTitle()
++{
++	return mAccountTitle;
++}
++
++
++
++void LLAvatarListEntry::setActivity(ACTIVITY_TYPE activity)
++{
++	if ( activity >= mActivityType || mActivityTimer.getElapsedTimeF32() > ACTIVITY_TIMEOUT )
++	{
++		mActivityType = activity;
++		mActivityTimer.start();
++	}
++}
++
++ACTIVITY_TYPE LLAvatarListEntry::getActivity()
++{
++	if ( mActivityTimer.getElapsedTimeF32() > ACTIVITY_TIMEOUT )
++	{
++		mActivityType = ACTIVITY_NONE;
++	}
++	
++	return mActivityType;
++}
++
++void LLAvatarListEntry::toggleMark()
++{
++	mMarked = !mMarked;
++}
++
++BOOL LLAvatarListEntry::isMarked()
++{
++	return mMarked;
++}
++
++BOOL LLAvatarListEntry::isDead()
++{
++	return getEntryAgeSeconds() > DEAD_KEEP_TIME;
++}
++
++// Avatar list is global
++LLFloaterAvatarList* gFloaterAvatarList = NULL;
++
++
++
++
++LLFloaterAvatarList::LLFloaterAvatarList() :  LLFloater("avatar list")
++{
++
++	// Default values
++	mTracking = FALSE;
++	mTrackByLocation = FALSE;
++	mARLastFrame = 0;
++
++	// Create interface from XML
++	LLUICtrlFactory::getInstance()->buildFloater(this, "floater_avatar_scanner.xml");
++
++	// Floater starts hidden	
++	setVisible(FALSE);
++
++	// Set callbacks
++	//childSetAction("refresh_btn", onClickRefresh, this);
++	childSetAction("profile_btn", onClickProfile, this);
++	childSetAction("im_btn", onClickIM, this);
++	childSetAction("track_btn", onClickTrack, this);
++	childSetAction("mark_btn", onClickMark, this);
++
++	childSetAction("gowarn_btn", onClickGohomerWarn, this);
++	childSetAction("goeject_btn", onClickGohomerEject, this);
++	childSetAction("goaway_btn", onClickGohomerSendAway, this);
++	childSetAction("gohome_btn", onClickGohomerSendHome, this);
++	childSetAction("gohomeoff_btn", onClickGohomerOff, this);
++	childSetAction("gokey_btn", onClickGohomerSendHomeByKey, this);
++
++	childSetAction("prev_in_list_btn", onClickPrevInList, this);
++	childSetAction("next_in_list_btn", onClickNextInList, this);
++	childSetAction("prev_marked_btn", onClickPrevMarked, this);
++	childSetAction("next_marked_btn", onClickNextMarked, this);
++	
++	childSetAction("get_key_btn", onClickGetKey, this);
++
++	childSetAction("tn_rate_btn", onClickTrustNetRate, this);
++	childSetAction("tn_explain_btn", onClickTrustNetExplain, this);
++	childSetAction("tn_website_btn", onClickTrustNetWebsite, this);
++	childSetAction("tn_password_btn", onClickTrustNetGetPassword, this);
++	childSetAction("tn_renew_btn", onClickTrustNetRenew, this);
++
++	childSetAction("freeze_btn", onClickFreeze, this);
++	childSetAction("eject_btn", onClickEject, this);
++//	childSetAction("ban_btn", onClickBan, this);
++//	childSetAction("unban_btn", onClickUnban, this);
++	childSetAction("mute_btn", onClickMute, this);
++//	childSetAction("unmute_btn", onClickUnmute, this);
++	childSetAction("ar_btn", onClickAR, this);
++	childSetAction("teleport_btn", onClickTeleport, this);
++	childSetAction("estate_eject_btn", onClickEjectFromEstate, this);
++
++	setDefaultBtn("refresh_btn");
++
++	// Get a pointer to the scroll list from the interface
++	mAvatarList = getChild<LLScrollListCtrl>("avatar_list");
++
++	mAvatarList->setCallbackUserData(this);
++	mAvatarList->setDoubleClickCallback(onDoubleClick);
++	mAvatarList->sortByColumn("distance", TRUE);
++	mDataRequestTimer.start();
++	refreshAvatarList();
++
++	LLMessageSystem *msg = gMessageSystem;
++	msg->addHandlerFunc("AvatarPropertiesReply", processAvatarPropertiesReply);
++}
++
++LLFloaterAvatarList::~LLFloaterAvatarList()
++{
++	LLMessageSystem *msg = gMessageSystem;
++	if ( msg )
++	{
++		msg->delHandlerFunc("AvatarPropertiesReply", processAvatarPropertiesReply);
++	}
++	std::map< LLUUID, LLPointer< LLHUDObject > >::iterator it = mHudObjectMap.begin();
++	for ( ; it != mHudObjectMap.end(); ++it )
++	{ // clean up list
++		it->second->markDead();
++	}
++
++}
++
++
++void LLFloaterAvatarList::show()
++{
++	// Make sure we make a noise.
++	open();
++}
++
++//static
++void LLFloaterAvatarList::toggle(void*) {
++	if (!gFloaterAvatarList) {
++		llinfos << "No avatar list!" << llendl;
++		return;
++	}
++
++	if (gFloaterAvatarList->getVisible())
++	{
++		gFloaterAvatarList->close();
++	}
++	else
++	{
++		gFloaterAvatarList->show();
++	}
++}
++
++//static
++BOOL LLFloaterAvatarList::visible(void*)
++{
++	return (gFloaterAvatarList && gFloaterAvatarList->getVisible());
++}
++
++void LLFloaterAvatarList::updateFromCoarse()
++{
++	/*
++	 * Walk through remaining list of coarse update avatars in all known regions
++	 * this will not give us an accurate height since it's mod 2048 and least possible
++	 * increment is 4 meter. Coarse Update information is accurate instantly while
++	 * the object list is filled one by one.
++	 *
++	 * This also works for neighbour sims which makes it really handy :)
++	 */
++	
++	// first wipe the list clean from coarse entries
++	std::map<LLUUID, LLAvatarListEntry>::iterator iter;
++	for(iter = mAvatars.begin(); iter != mAvatars.end();)
++	{
++		LLAvatarListEntry entry = iter->second;
++		if ( entry.getIsCoarse() )
++		{
++			mAvatars.erase( iter++ );
++		}
++		else
++		{
++			++iter;
++		}
++	}
++
++	LLWorld::region_list_t regions = LLWorld::getInstance()->getRegionList();
++	LLWorld::region_list_t::const_iterator it = regions.begin();
++	
++	for ( ; it != regions.end(); ++it )
++	{
++		LLViewerRegion const *region = *it;
++		if ( !region )
++		{
++			llwarns << "null region while parsing region list" << llendl;
++			continue;
++		}
++
++		for (int idx = 0; idx < region->mMapAvatarIDs.count(); ++idx)
++		{
++			LLUUID avid = region->mMapAvatarIDs.get( idx );
++
++			if ( avid.isNull() )
++			{
++				continue;
++			}
++
++			// we need to accomodate for avatars that are stuck in the
++			// object list while still accurately received in the coarse
++			// location list
++			U32 modpos = region->mMapAvatars.get( idx );
++			LLVector3 localpos;
++			localpos[0] = (modpos >> 16) & 0xff;
++			localpos[1] = (modpos >>  8) & 0xff;
++			// scale z-position
++			localpos[2] = (modpos        & 0xff) << 2;
++			LLVector3d position = region->getPosGlobalFromRegion( localpos );
++			
++			if ( ( mAvatars.count( avid ) > 0 ) && ( !mAvatars[ avid ].isDead() ) )
++			{
++				// Avatar already in list but could be one of these "perpetual motion" avatars
++				// which would overlay the real coordinates, so we check for the distance disregarding
++				// the z axis
++				LLVector3d coarsepos = position;
++				coarsepos[2]     = 0.0;
++				LLVector3d vopos = mAvatars[ avid ].mPosition;
++				vopos[2]         = 0.0;
++				LLVector3d dist  = coarsepos - vopos;
++				if ( dist.magVecSquared() > ( 50.0 * 50.0 ) )
++				{
++					// Avatar already in list, but position info is
++					// out of sync so use coarse info, we can safely overwrite
++					// the info here since we are called after the VOlist has
++					// already been parsed. The only issue is that this will now
++					// show the avatar as perpetually moving
++					mAvatars[ avid ].setPosition( coarsepos );
++				}
++				// Avatar already in list, active and
++				// close enough to coarse info, so skip
++				continue;
++			}
++
++			// Avatar not there yet, add it
++			std::string name;
++			BOOL isLinden = FALSE;
++			if ( !gCacheName->getFullName( avid, name ) )
++			{
++				continue; // wait for proper name
++			}
++			else
++			{
++				std::string first, last;
++				gCacheName->getName( avid, first, last );
++				if ( last == "Linden" )
++				{
++					isLinden = TRUE;
++				}
++			}
++
++			std::string regionname;
++			if ( gAgent.getRegion() && ( region->getName() != gAgent.getRegion()->getName() ) )
++			{
++				regionname = region->getName();
++			}
++
++			// add as coarse info
++			LLAvatarListEntry entry(avid, name, position, isLinden, TRUE, regionname);
++			mAvatars[avid] = entry;
++
++			//llinfos << "avatar list refresh from coarse: adding " << name << llendl;
++
++		}
++	}
++}
++
++
++void LLFloaterAvatarList::purgeAvatarHUDMap()
++{
++	std::map< LLUUID, LLPointer< LLHUDObject > >::iterator huditer = mHudObjectMap.begin();
++	while ( huditer != mHudObjectMap.end() )
++	{
++		if ( mAvatars.count( huditer->first ) == 0 )
++		{
++			huditer->second->markDead();
++			mHudObjectMap.erase( huditer++ );
++		}
++		else
++		{
++			++huditer;
++		}
++	}
++}
++
++
++void LLFloaterAvatarList::updateAvatarList()
++{
++//	LLVOAvatar *avatarp;
++
++	//llinfos << "avatar list refresh: updating map" << llendl;
++
++	// Check whether updates are enabled
++	LLCheckboxCtrl* check;
++	check = getChild<LLCheckBoxCtrl>("update_enabled_cb");
++
++	if ( !check->getValue() )
++	{
++		return;
++	}
++
++	
++	/*
++	 * Iterate over all the avatars known at the time
++	 * NOTE: Is this the right way to do that? It does appear that LLVOAvatar::isInstances contains
++	 * the list of avatars known to the client. This seems to do the task of tracking avatars without
++	 * any additional requests.
++	 *
++	 * BUG: It looks like avatars sometimes get stuck in this list, and keep perpetually
++	 * moving in the same direction. My current guess is that somewhere else the client
++	 * doesn't notice an avatar disappeared, and keeps updating its position. This should
++	 * be solved at the source of the problem.
++	 */
++	for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
++		iter != LLCharacter::sInstances.end(); ++iter)
++	{
++		LLVOAvatar* avatarp = (LLVOAvatar*) *iter;
++
++		// Skip if avatar is dead(what's that?)
++		// or if the avatar is ourselves.
++		if (avatarp->isDead() || avatarp->isSelf())
++		{
++			continue;
++		}
++
++		// Get avatar data
++		LLVector3d position = gAgent.getPosGlobalFromAgent(avatarp->getCharacterPosition());
++		LLUUID avid = avatarp->getID();
++		std::string name = avatarp->getFullname();
++
++		// Apparently, sometimes the name comes out empty, with a " " name. This is because
++		// getFullname concatenates first and last name with a " " in the middle.
++		// This code will avoid adding a nameless entry to the list until it acquires a name.
++		if (name.empty() || (name.compare(" ") == 0))
++		{
++			llinfos << "Name empty for avatar " << avid << llendl;
++			continue;
++		}
++
++		if (avid.isNull())
++		{
++			llinfos << "Key empty for avatar " << name << llendl;
++			continue;
++		}
++
++		if ( ( mAvatars.count( avid ) > 0 ) && !mAvatars[avid].getIsCoarse() )
++		{
++			// Avatar already in list, update position
++			mAvatars[avid].setPosition(position);
++		}
++		else
++		{
++			// Avatar not there yet or only from coarse list, add it properly
++			BOOL isLinden = ( std::string( avatarp->getNVPair("LastName")->getString() ) == "Linden" );
++
++			LLAvatarListEntry entry(avid, name, position, isLinden);
++			mAvatars[avid] = entry;
++
++			sendAvatarPropertiesRequest(avid);
++			llinfos << "avatar list refresh: adding " << name << llendl;
++
++		}
++
++	}
++
++	updateFromCoarse();
++
++//	llinfos << "avatar list refresh: done" << llendl;
++
++	expireAvatarList();
++	refreshAvatarList();
++	
++	purgeAvatarHUDMap();
++	
++	checkTrackingStatus();
++	processARQueue();
++}
++
++void LLFloaterAvatarList::processARQueue()
++{
++	if ( mARQueue.empty() ) return;
++
++	LLUUID avatar_id = mARQueue.front();
++
++	if ( 0 == mARLastFrame )
++	{
++		// Start of the process: Move the camera to the avatar. This happens gradually,
++		// so we'll give it a few frames
++		gAgent.lookAtObject(avatar_id, CAMERA_POSITION_OBJECT);
++		mARLastFrame = gFrameCount;
++		return;
++	}
++
++	if ( gFrameCount - mARLastFrame >= 10 )
++	{
++		// Camera should be in position, show AR screen now
++		LLFloaterReporter *report = LLFloaterReporter::showFromObject(avatar_id, false);
++		report->setMinimized(TRUE);
++
++		mARReporterQueue.push(report);
++
++		mARQueue.pop();
++		mARLastFrame = 0;
++
++		if ( mARQueue.empty() )
++		{
++			// Now that all reports are taken, open them.
++
++			while( !mARReporterQueue.empty() )
++			{
++				LLFloaterReporter *r = mARReporterQueue.front();
++				mARReporterQueue.pop();
++
++				r->open();
++				r->setMinimized(FALSE);
++			}
++		}
++	}
++}
++
++void LLFloaterAvatarList::expireAvatarList()
++{
++//	llinfos << "avatar list: expiring" << llendl;
++	std::map<LLUUID, LLAvatarListEntry>::iterator iter;
++	std::queue<LLUUID> delete_queue;
++
++	for(iter = mAvatars.begin(); iter != mAvatars.end(); iter++)
++	{
++		LLAvatarListEntry *ent = &iter->second;
++		
++		if ( ent->getEntryAgeFrames() >= 2 )
++		{
++			ent->setActivity(ACTIVITY_DEAD);
++		}
++
++
++		if ( ent->getEntryAgeSeconds() > CLEANUP_TIMEOUT )
++		{
++			llinfos << "avatar list: expiring avatar " << ent->getName() << llendl;
++			LLUUID av_id = ent->getID();
++			delete_queue.push(av_id);
++		}
++	}
++
++	while(!delete_queue.empty())
++	{
++		mAvatars.erase(delete_queue.front());
++		if ( mHudObjectMap.count(delete_queue.front()) )
++		{
++			mHudObjectMap[delete_queue.front()]->markDead();
++			mHudObjectMap.erase(delete_queue.front());
++		}
++		delete_queue.pop();
++	}
++}
++
++/**
++ * Redraws the avatar list
++ * Only does anything if the avatar list is visible.
++ * @author Dale Glass
++ */
++void LLFloaterAvatarList::refreshAvatarList() 
++{
++
++
++
++	// Don't update list when interface is hidden
++	if (!LLFloaterAvatarList::visible(NULL))
++	{
++		return;
++	}
++
++
++	LLCheckboxCtrl* fetch_data;
++	fetch_data = getChild<LLCheckBoxCtrl>("fetch_avdata_enabled_cb");
++
++	//BOOL db_enabled = gSavedSettings.getBOOL("DBEnabled");
++	//std::string db_avatar = gSavedPerAccountSettings.getString("DBAvatarName");
++	//if ( db_avatar.empty() )
++	//{
++	//	db_enabled = FALSE;
++	//}
++
++
++
++	// We rebuild the list fully each time it's refreshed
++	
++	// The assumption is that it's faster to refill it and sort than
++	// to rebuild the whole list.
++	LLDynamicArray<LLUUID> selected = mAvatarList->getSelectedIDs();
++	S32 scrollpos = mAvatarList->getScrollPos();
++
++	mAvatarList->deleteAllItems();
++
++	LLVector3d mypos = gAgent.getPositionGlobal();
++
++	unsigned int counter = 0;
++
++	std::map<LLUUID, LLAvatarListEntry>::iterator iter;
++	for(iter = mAvatars.begin(); iter != mAvatars.end(); iter++)
++	{
++		LLSD element;
++		LLUUID av_id;
++
++		
++		LLAvatarListEntry *ent = &iter->second;
++
++		// Skip if avatar hasn't been around
++		if ( ent->isDead() )
++		{
++			continue;
++		}
++
++		av_id = ent->getID();
++
++		// Get avatar name, position
++		LLAvatarInfo avinfo = ent->mAvatarInfo.getValue();
++		//LLAvListTrustNetScore avscore = ent->mTrustNetScore.getValue();
++
++		DATA_STATUS avinfo_status = ent->mAvatarInfo.getStatus();
++		//DATA_STATUS avscore_status = ent->mTrustNetScore.getStatus();
++
++		LLVector3d position = ent->getPosition();
++		LLVector3d delta = position - mypos;
++		F32 distance = (F32)delta.magVec();
++
++		std::string icon = "";
++
++		// HACK: Workaround for an apparent bug:
++		// sometimes avatar entries get stuck, and are registered
++		// by the client as perpetually moving in the same direction.
++		// this makes sure they get removed from the visible list eventually.
++		// for the coarse list this is not necessary since it is always accurate
++		if ( distance > 1024 && !ent->getIsCoarse() )
++		{
++			continue;
++		}
++
++		if ( av_id.isNull() )
++		{
++			llwarns << "Avatar with null key somehow got into the list!" << llendl;
++			continue;
++		}
++
++		counter++;
++
++		element["id"] = av_id;
++
++		element["columns"][LIST_AVATAR_ICON]["column"] = "avatar_icon";
++		element["columns"][LIST_AVATAR_ICON]["type"] = "text";
++		if ( !ent->isMarked() )
++		{ // show counter if not marked
++			element["columns"][LIST_AVATAR_ICON]["value"] = llformat("%d", counter);
++		}
++		else
++		{
++			element["columns"][LIST_AVATAR_ICON]["type"] = "icon";
++			const LLUUID flag_blue("e39cbfe7-c4e7-3bad-5e5f-958082d55046");
++			element["columns"][LIST_AVATAR_ICON]["value"] = flag_blue.asString();
++		}
++
++
++		if ( ent->getIsLinden() )
++		{
++			element["columns"][LIST_AVATAR_NAME]["font-style"] = "BOLD";
++		}
++
++		if ( ent->getIsCoarse() )
++		{
++			element["columns"][LIST_AVATAR_NAME]["color"] = LLColor4::grey4.getValue();
++		}
++
++		if ( ent->isFocused() )
++		{
++			element["columns"][LIST_AVATAR_NAME]["color"] = LLColor4::cyan.getValue();
++		}
++
++		//element["columns"][LIST_AVATAR_NAME]["font-color"] = getAvatarColor(ent, distance).getValue();
++		element["columns"][LIST_AVATAR_NAME]["column"] = "avatar_name";
++		element["columns"][LIST_AVATAR_NAME]["type"] = "text";
++		std::string agentname = ent->getName();
++		if ( !ent->getIsSameRegion() )
++		{
++			agentname += " (" + ent->getRegionName() + ")";
++		}
++		element["columns"][LIST_AVATAR_NAME]["value"] = agentname.c_str();
++
++		char temp[32];
++		snprintf(temp, sizeof(temp), "%.2f", distance);
++
++		element["columns"][LIST_DISTANCE]["column"] = "distance";
++		element["columns"][LIST_DISTANCE]["type"] = "text";
++		element["columns"][LIST_DISTANCE]["value"] = temp;
++		element["columns"][LIST_DISTANCE]["color"] = getAvatarColor(ent, distance, CT_DISTANCE).getValue();
++
++		
++		if ( avinfo_status == DATA_RETRIEVED )
++		{
++			element["columns"][LIST_AGE]["column"] = "age";
++			element["columns"][LIST_AGE]["type"] = "text";
++			element["columns"][LIST_AGE]["value"] = avinfo.getAge();
++			element["columns"][LIST_AGE]["color"] = getAvatarColor(ent, distance, CT_AGE).getValue();
++		}
++
++		const LLUUID info_error("bbda234c-c76e-8617-0a32-46cc15c5ec42");
++		const LLUUID info_fetching("1468fae4-2f47-6e75-d39f-3ccbd443d31c");
++		const LLUUID info_unknown("0f2d532a-1fc8-01bb-eed3-ef60e7943d1e");
++		const LLUUID payment_info_charter("07bef5d9-31b2-4cc5-999e-c2cd8b5d3a69");
++		const LLUUID payment_info_filled("9d61c4d5-e8f6-78ec-a64f-490e3a4c03d5");
++		const LLUUID payment_info_used("49ac7ef9-caaa-750a-6ec1-51358f0a1672");
++
++		/*
++		element["columns"][LIST_SCORE]["column"] = "score";
++		element["columns"][LIST_SCORE]["type"] = "text";
++
++		icon = "";
++		switch(avscore_status)
++		{
++			case DATA_UNKNOWN:
++				icon = info_unknown.asString();
++				break;
++			case DATA_REQUESTING:
++				icon = info_fetching.asString();
++				break;
++			case DATA_ERROR:
++				icon =  info_error.asString();
++			case DATA_RETRIEVED:
++				element["columns"][LIST_SCORE]["value"] = avscore.Score;
++				element["columns"][LIST_SCORE]["color"] = getAvatarColor(ent, distance, CT_SCORE).getValue();
++				break;
++		}
++		
++		if (!icon.empty() )
++		{	
++			element["columns"][LIST_SCORE].erase("color");
++			element["columns"][LIST_SCORE]["type"] = "icon";
++			element["columns"][LIST_SCORE]["value"] = icon;
++		}*/
++	
++
++		// Get an icon for the payment data
++		// These should be replaced with something proper instead of reusing whatever
++		// LL-provided images happened to fit
++		icon = "";
++
++		switch(avinfo_status)
++		{
++			case DATA_UNKNOWN:
++				icon = info_unknown.asString();
++				break;
++			case DATA_REQUESTING:
++				icon = info_fetching.asString();
++				break;
++			case DATA_ERROR:
++				icon = info_error.asString();
++				break;
++			case DATA_RETRIEVED:
++				switch(avinfo.Payment)
++				{
++					case PAYMENT_NONE:
++						break;
++					case PAYMENT_ON_FILE:
++						icon =  payment_info_filled.asString();
++						break;
++					case PAYMENT_USED:
++						icon =  payment_info_used.asString();
++						break;
++					case PAYMENT_LINDEN:
++						// confusingly named icon, maybe use something else
++						icon =  "icon_top_pick.tga";
++						break;
++				}
++				break;
++		}
++
++		element["columns"][LIST_PAYMENT]["column"] = "payment_data";
++		element["columns"][LIST_PAYMENT]["type"] = "text";
++
++		// TODO: Add icon for "unknown" status
++		//if ( PAYMENT_NONE != avinfo.Payment && DATA_UNKNOWN != avinfo_status )
++		if ( !icon.empty() )
++		{
++			element["columns"][LIST_PAYMENT].erase("color");
++			element["columns"][LIST_PAYMENT]["type"] = "icon";
++			element["columns"][LIST_PAYMENT]["value"] =  icon;
++			//llinfos << "Payment icon: " << payment_icon << llendl;
++		}
++
++		const LLUUID avatar_gone("db4592d5-c8a5-9336-019c-fcbd282d5f33");
++		const LLUUID avatar_new("33d4b23e-a29c-ac03-f7f6-c2fa197b13fe");
++		const LLUUID avatar_typing("6f083c3c-1e88-d184-6add-95402b3e108f");
++		/*<avatar_sound.tga value = "439836e2-29f5-c12f-71d4-aa59283296e1"/>
++		<flag_blue.tga value="e39cbfe7-c4e7-3bad-5e5f-958082d55046"/>
++		<flag_green.tga value="78952758-1bef-f968-d382-b39094f85aa1"/>
++		<flag_orange.tga value="c72ca7d9-42cd-02f1-ce32-ca1ea5d1c25d"/>
++		<flag_pink.tga value="a3419a89-b8d9-293c-693e-12982e574304"/>
++		<flag_purple.tga value="7982fbf8-457a-77ce-61e6-b3c7d9500d2f"/>
++		<flag_red.tga value="11ba32bf-44fe-666e-073b-00768785b4d0"/>
++		<flag_yellow.tga value="98a5a29e-e933-eeed-bdd9-4d461f557d34"/>*/
++		
++		ACTIVITY_TYPE activity = ent->getActivity();
++		icon = "";
++		switch( activity )
++		{
++			case ACTIVITY_NONE:
++				break;
++			case ACTIVITY_MOVING:
++				icon = "inv_item_animation.tga";
++				break;
++			case ACTIVITY_GESTURING:
++				icon = "inv_item_gesture.tga";
++				break;
++			case ACTIVITY_SOUND:
++				icon = "inv_item_sound.tga";
++				break;
++			case ACTIVITY_REZZING:
++				icon = "ff_edit_theirs.tga";
++				break;
++			case ACTIVITY_PARTICLES:
++				// TODO: Replace with something better
++				icon = "account_id_green.tga";
++				break;
++			case ACTIVITY_NEW:
++				icon = avatar_new.asString();
++				break;
++			case ACTIVITY_TYPING:
++				icon = avatar_typing.asString();
++				break;
++			case ACTIVITY_DEAD:
++				// TODO: Replace, icon is quite inappropiate
++				icon = avatar_gone.asString();
++				break;
++		}
++
++		element["columns"][LIST_ACTIVITY]["column"] = "activity";
++		element["columns"][LIST_ACTIVITY]["type"] = "text";
++
++		if (!icon.empty() )
++		{	
++			element["columns"][LIST_ACTIVITY]["type"] = "icon";
++			element["columns"][LIST_ACTIVITY]["value"] = icon;
++			//llinfos << "Activity icon: " << activity_icon << llendl;
++		}
++		
++		char tempentered[32];
++		F32 entered = ent->getEntryEnteredSeconds();
++		snprintf(tempentered, sizeof(tempentered), "%u", (unsigned int)(entered/60.0));
++		element["columns"][LIST_ENTERED]["column"] = "entered";
++		element["columns"][LIST_ENTERED]["type"] = "text";
++		element["columns"][LIST_ENTERED]["value"] = tempentered;
++		element["columns"][LIST_ENTERED]["color"] = getAvatarColor(ent, distance, CT_ENTERED).getValue();
++
++		// Add to list
++		mAvatarList->addElement(element, ADD_BOTTOM);
++
++		// Request data only if fetching avatar data is enabled
++		if ( fetch_data->getValue() && ent->mAvatarInfo.requestIfNeeded() )
++		{
++			sendAvatarPropertiesRequest(av_id);
++			llinfos << "Data for avatar " << ent->getName() << " didn't arrive yet, retrying" << llendl;
++		}
++
++		/*if ( ent->mTrustNetScore.requestIfNeeded() )
++		{
++			requestTrustNetScore(av_id, ent->getName(), "behavior");
++			llinfos << "Requesting TrustNet score for " << ent->getName() << llendl;
++		}*/
++		
++		//if ( db_enabled && ent->mMiscInfo.requestIfNeeded() )
++		//{
++		//	requestMiscInfo(av_id, ent->getName());
++		//	llinfos << "Requesting misc info for " << ent->getName() << llendl;
++		//}
++	}
++
++	// finish
++	mAvatarList->sort();
++	mAvatarList->selectMultiple(selected);
++	mAvatarList->setScrollPos(scrollpos);
++
++//	llinfos << "avatar list refresh: done" << llendl;
++
++}
++
++// static
++void LLFloaterAvatarList::onClickIM(void* userdata)
++{
++	//llinfos << "LLFloaterFriends::onClickIM()" << llendl;
++	LLFloaterAvatarList *avlist = (LLFloaterAvatarList*)userdata;
++
++	LLDynamicArray<LLUUID> ids = avlist->mAvatarList->getSelectedIDs();
++	if(ids.size() > 0)
++	{
++		if(ids.size() == 1)
++		{
++			// Single avatar
++			LLUUID agent_id = ids[0];
++
++			char buffer[MAX_STRING];
++			snprintf(buffer, MAX_STRING, "%s", avlist->mAvatars[agent_id].getName().c_str());
++			gIMMgr->setFloaterOpen(TRUE);
++			gIMMgr->addSession(
++				buffer,
++				IM_NOTHING_SPECIAL,
++				agent_id);
++		}
++		else
++		{
++			// Group IM
++			LLUUID session_id;
++			session_id.generate();
++			gIMMgr->setFloaterOpen(TRUE);
++			gIMMgr->addSession("Avatars Conference", IM_SESSION_CONFERENCE_START, ids[0], ids);
++		}
++	}
++}
++
++void LLFloaterAvatarList::onClickTrack(void *userdata)
++{
++	LLFloaterAvatarList *avlist = (LLFloaterAvatarList*)userdata;
++	
++ 	LLScrollListItem *item =   avlist->mAvatarList->getFirstSelected();
++	if (!item) return;
++
++	LLUUID agent_id = item->getUUID();
++
++	if ( avlist->mTracking && avlist->mTrackedAvatar == agent_id ) {
++		LLTracker::stopTracking(NULL);
++		avlist->mTracking = FALSE;
++	}
++	else
++	{
++		avlist->mTracking = TRUE;
++		avlist->mTrackByLocation = FALSE;
++		avlist->mTrackedAvatar = agent_id;
++		LLTracker::trackAvatar(agent_id, avlist->mAvatars[agent_id].getName());
++	}
++}
++
++void LLFloaterAvatarList::sendAvatarPropertiesRequest(LLUUID avid)
++{
++	
++
++	lldebugs << "LLPanelAvatar::sendAvatarPropertiesRequest()" << llendl; 
++	LLMessageSystem *msg = gMessageSystem;
++
++	msg->newMessageFast(_PREHASH_AvatarPropertiesRequest);
++	msg->nextBlockFast( _PREHASH_AgentData);
++	msg->addUUIDFast(   _PREHASH_AgentID, gAgent.getID() );
++	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
++	msg->addUUIDFast(   _PREHASH_AvatarID, avid);
++	gAgent.sendReliableMessage();
++
++	mAvatars[avid].mAvatarInfo.requestStarted();
++}
++
++// static
++void LLFloaterAvatarList::processAvatarPropertiesReply(LLMessageSystem *msg, void**)
++{
++
++	
++	LLFloaterAvatarList* self = NULL;
++	LLAvatarInfo avinfo;
++
++	BOOL	identified = FALSE;
++	BOOL	transacted = FALSE;
++
++	LLUUID	agent_id;	// your id
++	LLUUID	avatar_id;	// target of this panel
++	U32	flags = 0x0;
++	char	born_on[DB_BORN_BUF_SIZE];
++	S32	charter_member_size = 0;
++
++	msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id);
++	msg->getUUIDFast(_PREHASH_AgentData, _PREHASH_AvatarID, avatar_id );
++
++	
++	self = gFloaterAvatarList;
++
++	// Verify that the avatar is in the list, if not, ignore.
++	if ( self->mAvatarList->getItemIndex(avatar_id) < 0 )
++	{
++		return;
++	}
++
++	LLAvatarListEntry *entry = &self->mAvatars[avatar_id];
++
++	msg->getStringFast(_PREHASH_PropertiesData, _PREHASH_BornOn, DB_BORN_BUF_SIZE, born_on);
++	msg->getU32Fast(_PREHASH_PropertiesData, _PREHASH_Flags, flags);
++
++	identified = (flags & AVATAR_IDENTIFIED);
++	transacted = (flags & AVATAR_TRANSACTED);
++
++	// What's this?
++	// Let's see if I understand correctly: CharterMember property is dual purpose:
++	// it either contains a number indicating an account type (usual value), or 
++	// it contains a string with a custom title. Probably that's where Philip Linden's
++	// "El Presidente" title comes from. Heh.
++	U8 caption_index = 0;
++	std::string caption_text;
++	charter_member_size = msg->getSize("PropertiesData", "CharterMember");
++
++	if(1 == charter_member_size)
++	{
++		msg->getBinaryData("PropertiesData", "CharterMember", &caption_index, 1);
++	}
++	else if(1 < charter_member_size)
++	{
++		char caption[MAX_STRING];
++		msg->getString("PropertiesData", "CharterMember", MAX_STRING, caption);
++
++		caption_text = caption;
++		entry->setAccountCustomTitle(caption_text);
++	}
++		
++
++	if(caption_text.empty())
++	{
++		
++		const enum ACCOUNT_TYPE ACCT_TYPE[] = {
++			ACCOUNT_RESIDENT,
++			ACCOUNT_TRIAL,
++			ACCOUNT_CHARTER_MEMBER,
++			ACCOUNT_EMPLOYEE
++		};
++
++		//enum ACCOUNT_TYPE acct =
++		avinfo.Account =  ACCT_TYPE[llclamp(caption_index, (U8)0, (U8)(sizeof(ACCT_TYPE)/sizeof(ACCT_TYPE[0])-1))];
++		//entry->setAccountType(acct);
++
++		
++		if ( avinfo.Account != ACCOUNT_EMPLOYEE )
++		{
++			if ( transacted )
++			{
++				avinfo.Payment = PAYMENT_USED;
++			}
++			else if ( identified )
++			{
++				avinfo.Payment = PAYMENT_ON_FILE;
++			}
++			else
++			{
++				avinfo.Payment = PAYMENT_NONE;
++			}
++		}
++		else
++		{
++			avinfo.Payment = PAYMENT_LINDEN;
++		}
++	}
++	
++	// Structure must be zeroed to have sane results, as we
++	// have an incomplete string for input
++	memset(&avinfo.BirthDate, 0, sizeof(avinfo.BirthDate));
++
++	int num_read = sscanf(born_on, "%d/%d/%d", &avinfo.BirthDate.tm_mon,
++	                                           &avinfo.BirthDate.tm_mday,
++	                                           &avinfo.BirthDate.tm_year);
++
++	if ( num_read == 3 && avinfo.BirthDate.tm_mon <= 12 )
++	{
++		avinfo.BirthDate.tm_year -= 1900;
++		avinfo.BirthDate.tm_mon--;
++	}
++	else
++	{
++		// Zero again to remove any partially read data
++		memset(&avinfo.BirthDate, 0, sizeof(avinfo.BirthDate));
++		llwarns << "Error parsing birth date: " << born_on << llendl;
++	}
++
++	entry->mAvatarInfo.setValue(avinfo);
++}
++
++void LLFloaterAvatarList::checkTrackingStatus()
++{
++
++	if ( mTracking && LLTracker::getTrackedPositionGlobal().isExactlyZero() )
++	{
++		// trying to track an avatar, but tracker stopped tracking		
++		if ( mAvatars.count( mTrackedAvatar ) > 0 && !mTrackByLocation )
++		{
++			llinfos << "Switching to location-based tracking" << llendl;
++			mTrackByLocation = TRUE;
++		}
++		else
++		{
++			// not found
++			llinfos << "Stopping tracking avatar, server-side didn't work, and not in list anymore." << llendl;
++			LLTracker::stopTracking(NULL);
++			mTracking = FALSE;
++		}
++	}
++
++	if ( mTracking && mTrackByLocation )
++	{
++		std::string name = mAvatars[mTrackedAvatar].getName();
++		std::string tooltip = "Tracking last known position";
++		name += " (near)";
++		LLTracker::trackLocation(mAvatars[mTrackedAvatar].getPosition(), name, tooltip);
++	}
++
++	//llinfos << "Tracking position: " << LLTracker::getTrackedPositionGlobal() << llendl;
++	
++}
++
++
++BOOL  LLFloaterAvatarList::avatarIsInList(LLUUID avatar)
++{
++	return ( mAvatars.count( avatar ) > 0 );
++}
++
++LLAvatarListEntry * LLFloaterAvatarList::getAvatarEntry(LLUUID avatar)
++{
++	if ( avatar.isNull() )
++	{
++		return NULL;
++	}
++
++	std::map<LLUUID, LLAvatarListEntry>::iterator iter;
++
++	iter = mAvatars.find(avatar);
++	if ( iter == mAvatars.end() )
++	{
++		return NULL;
++	}
++
++	return &iter->second;	
++	
++	//if ( mAvatars.count( avatar ) < 0 )
++	//{
++		//return NULL;
++	//}
++
++	//return &mAvatars[avatar];
++}
++
++void LLFloaterAvatarList::speakText(S32 channel, EChatType type, std::string text)
++{
++	LLMessageSystem* msg = gMessageSystem;
++
++	msg->newMessageFast(_PREHASH_ChatFromViewer);
++	msg->nextBlockFast(_PREHASH_AgentData);
++	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
++	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
++	msg->nextBlockFast(_PREHASH_ChatData);
++	msg->addStringFast(_PREHASH_Message, text);
++	msg->addU8Fast(_PREHASH_Type, type);
++	msg->addS32("Channel", channel);
++
++	gAgent.sendReliableMessage();
++
++	LLViewerStats::getInstance()->incStat(LLViewerStats::ST_CHAT_COUNT);
++}
++
++
++void LLFloaterAvatarList::requestTrustNetScore(LLUUID avatar, const std::string name, const std::string type)
++{
++	char *temp = new char[UUID_STR_LENGTH];
++	avatar.toString(temp);
++
++	std::string text = "GetScore|" + name + "|" + temp + "|" + type;
++	speakText(TRUSTNET_CHANNEL, CHAT_TYPE_WHISPER, text);
++}
++
++//static
++void LLFloaterAvatarList::replaceVars(std::string &str, LLUUID avatar, const std::string& name)
++{
++	char *temp = new char[UUID_STR_LENGTH];
++	avatar.toString(temp);
++
++	std::string vars[][2] = {
++		{"$NAME", name},
++		{"$KEY",  temp},
++	};
++
++	BOOL replaced = TRUE;
++
++	while( replaced )
++	{
++		replaced = FALSE;
++		for(U32 i=0;i<sizeof(vars)/sizeof(vars[0]);i++)
++		{
++			std::string::size_type pos = str.find(vars[i][0]);
++			if ( pos != std::string::npos )
++			{
++				str.replace(pos, vars[i][0].size(), vars[i][1]);
++				replaced = TRUE;
++			}
++		}
++	}
++
++}
++
++void LLFloaterAvatarList::requestMiscInfo(LLUUID avatar, const std::string name)
++{
++	//LLUUID   db_av_key;
++
++	//std::string message      = gSavedPerAccountSettings.getString("DBSendPattern");
++	//std::string db_av_name   = gSavedPerAccountSettings.getString("DBAvatarName");
++	//db_av_key.set(gSavedPerAccountSettings.getString("DBAvatarKey"));
++
++	
++	//llinfos << "Requesting info " << llendl;
++	//replaceVars(message, avatar, name);
++
++	//llinfos << "Request string: " << message << llendl;
++	//send_simple_im(db_av_key, message.c_str());
++ }
++
++//static
++BOOL LLFloaterAvatarList::handleIM(LLUUID from_id, const std::string message)
++{
++	LLUUID   db_av_key;
++	//db_av_key.set(gSavedPerAccountSettings.getString("DBAvatarKey"));
++
++	if ( db_av_key == from_id )
++	{
++		std::map<LLUUID, LLAvatarListEntry>::iterator iter;
++
++		for(iter = gFloaterAvatarList->mAvatars.begin(); iter != gFloaterAvatarList->mAvatars.end(); iter++)
++		{
++			LLAvatarListEntry *ent = &iter->second;
++		
++			// Check if the key, or the name are found in the reply.
++			// Name is only accepted if it's in the beginning of the message.
++			if ( message.find(ent->getID().asString()) != std::string::npos
++			     || message.find(ent->getName().c_str()) == 0 )
++			{
++				LLMiscDBInfo info;
++				info.data = message;
++
++				llinfos << "Database reply arrived for avatar " << ent->getName() << llendl;
++				ent->mMiscInfo.setValue(info);
++			}
++		}
++
++		return TRUE;
++	}
++	return FALSE;
++}
++
++//static
++void LLFloaterAvatarList::processTrustNetReply(char *reply)
++{
++	char *tokens[10];
++	char *tmp = &reply[0];
++	U32 count = 0;
++
++	llinfos << "TrustNet reply: " << reply << llendl;
++	
++
++	// Split into tokens
++	while( (NULL != (tmp = strtok(tmp, "|"))) && count < (sizeof(tokens)/sizeof(tokens[0])) )
++	{
++		tokens[count++] = tmp;
++		llinfos << "token: " << tmp << llendl;
++		tmp = NULL;
++	}
++
++	llinfos << "Got " << count << " tokens" << llendl;
++
++	if ( count >= 1 )
++	{
++		if (!strcmp(tokens[0], "Score") && count >= 4)
++		{
++			//format: key|type|score
++			LLUUID avatar(tokens[1]);
++			std::string type = tokens[2];
++			F32 score = (F32)strtod(tokens[3], NULL);
++			
++			LLAvatarListEntry *ent = gFloaterAvatarList->getAvatarEntry(avatar);
++			if ( ent != NULL )
++			{
++				LLAvListTrustNetScore s(type, score);
++				ent->mTrustNetScore.setValue(s);
++				llinfos << "Score arrived for avatar " << avatar << ": " << score << llendl;
++			}
++			else
++			{
++				llinfos << "Score arrived for avatar " << avatar << ", but it wasn't in the list anymore" << llendl;
++			}
++		}
++		else if (!strcmp(tokens[0], "WebAuthToken") && count >= 2)
++		{
++			std::string URL = LLWeb::escapeURL(llformat("http://trustnet.daleglass.net/?session=%s", tokens[1]));
++ 			LLWeb::loadURL(URL);
++		}
++		else if (!strcmp(tokens[0], "WebPassword") && count >= 2)
++		{
++			std::string password = tokens[1];
++			gViewerWindow->mWindow->copyTextToClipboard(utf8str_to_wstring(password));
++		}
++		else
++		{
++			llwarns << "Unrecognized TrustNet reply " << tokens[0] << llendl;
++		}
++	}
++}
++
++void LLFloaterAvatarList::luskwoodCommand(std::string cmd)
++{
++	LLDynamicArray<LLUUID> ids = mAvatarList->getSelectedIDs();
++
++	for(LLDynamicArray<LLUUID>::iterator itr = ids.begin(); itr != ids.end(); ++itr)
++	{
++		LLUUID avid = *itr;
++		LLAvatarListEntry *ent = getAvatarEntry(avid);
++		if ( ent != NULL )
++		{
++			//llinfos << "Would say: " << cmd << " " << ent->getName() << llendl;
++			// Use key got gokey, name for everything else
++			speakText(0, CHAT_TYPE_SHOUT, cmd + " " + ( cmd == "gokey" ? ent->getID().asString() :  ent->getName() ) );
++		}
++	}
++}
++
++//static
++void LLFloaterAvatarList::onClickMark(void *userdata)
++{
++	LLFloaterAvatarList *avlist = (LLFloaterAvatarList*)userdata;
++	LLDynamicArray<LLUUID> ids = avlist->mAvatarList->getSelectedIDs();
++
++	for(LLDynamicArray<LLUUID>::iterator itr = ids.begin(); itr != ids.end(); ++itr)
++	{
++		LLUUID avid = *itr;
++		LLAvatarListEntry *ent = avlist->getAvatarEntry(avid);
++		if ( ent != NULL )
++		{
++			ent->toggleMark();
++		}
++	}
++}
++
++void LLFloaterAvatarList::handleLuskwoodDialog(S32 option, void* data)
++{
++	LLFloaterAvatarList *self = (LLFloaterAvatarList*)data;
++	if ( 0 == option )
++	{
++		self->luskwoodCommand(self->mLuskwoodCommand);
++	}
++}
++
++void LLFloaterAvatarList::handleLuskwoodGohomerOffDialog(S32 option, void* data)
++{
++	LLFloaterAvatarList *self = (LLFloaterAvatarList*)data;
++	if ( 0 == option )
++	{
++		self->speakText(0, CHAT_TYPE_SHOUT, "gohome off");
++	}
++}
++
++//static
++void LLFloaterAvatarList::onClickGohomerWarn(void *data)
++{
++	LLFloaterAvatarList *self = (LLFloaterAvatarList*)data;
++
++	self->mLuskwoodCommand = "gowarn";
++	gViewerWindow->alertXml("LuskwoodGohomerWarn", handleLuskwoodDialog, self);
++
++}
++
++//static
++void LLFloaterAvatarList::onClickGohomerEject(void *data)
++{
++	LLFloaterAvatarList *self = (LLFloaterAvatarList*)data;
++
++	self->mLuskwoodCommand = "goeject";
++	gViewerWindow->alertXml("LuskwoodGohomerEject", handleLuskwoodDialog, self);
++}
++
++//static
++void LLFloaterAvatarList::onClickGohomerSendAway(void *data)
++{
++	LLFloaterAvatarList *self = (LLFloaterAvatarList*)data;
++
++	self->mLuskwoodCommand = "goaway";
++	gViewerWindow->alertXml("LuskwoodGohomerKeepAway", handleLuskwoodDialog, self);
++}
++
++//static
++void LLFloaterAvatarList::onClickGohomerSendHome(void *data)
++{
++	LLFloaterAvatarList *self = (LLFloaterAvatarList*)data;
++
++	self->mLuskwoodCommand = "gohome";
++	gViewerWindow->alertXml("LuskwoodGohomerSendHome", handleLuskwoodDialog, self);
++}
++
++//static
++void LLFloaterAvatarList::onClickGohomerSendHomeByKey(void *data)
++{
++	LLFloaterAvatarList *self = (LLFloaterAvatarList*)data;
++
++	self->mLuskwoodCommand = "gokey";
++	gViewerWindow->alertXml("LuskwoodGohomerSendHome", handleLuskwoodDialog, self);
++}
++
++
++//static
++void LLFloaterAvatarList::onClickGohomerOff(void *data)
++{
++	LLFloaterAvatarList *self = (LLFloaterAvatarList*)data;
++
++	gViewerWindow->alertXml("LuskwoodGohomerOff", handleLuskwoodGohomerOffDialog, self);
++}
++
++LLColor4 LLFloaterAvatarList::getAvatarColor(LLAvatarListEntry *ent, F32 distance, e_coloring_type type)
++{
++ 	F32 r = 0.0f, g = 0.0f, b = 0.0f, a = 1.0f;
++
++	switch(type)
++	{
++		case CT_NONE:
++			return LLColor4::black;
++			break;
++		case CT_DISTANCE:
++			if ( distance <= 10.0f )
++			{
++				// whisper range
++				g = 0.7f - ( distance / 20.0f );
++			}
++			else if ( distance > 10.0f && distance <= 20.0f )
++			{
++				// talk range
++				g = 0.7f - ( (distance - 10.0f) / 20.0f );
++				b = g;
++			}
++			else if ( distance > 20.0f && distance <= 96.0f )
++			{
++				// shout range
++				r = 0.7f - ( (distance - 20.0f) / 192.0f );
++				b = r;
++			}
++			else
++			{
++				// unreachable by chat
++				r = 1.0;
++			}
++			break;
++		case CT_AGE:
++			if ( ent->mAvatarInfo.getStatus() == DATA_RETRIEVED )
++			{
++				S32 age = ent->mAvatarInfo.getValue().getAge();
++				if ( age < 14 )
++				{
++					r = 0.7f - ( age / 28 );
++				}
++				else if ( age > 14 && age <= 30 )
++				{
++					r = 0.7f - ( (age-14) / 32 );
++					g = r;
++				}
++				else if ( age > 30 && age < 90 )
++				{
++					g = 0.7f - ( (age-30) / 120 );
++				}
++				else
++				{
++					b = 1.0f;
++				}
++			}
++			break;
++		case CT_SCORE:
++			if ( ent->mTrustNetScore.getStatus() == DATA_RETRIEVED )
++			{
++				F32 score = ent->mTrustNetScore.getValue().Score;
++
++				if ( score == 0.0 )
++				{
++					b = 1.0f;
++				}
++				else if ( score == 10.0f )
++				{
++					g = 1.0f;
++				}
++				else if ( score == -10.0f )
++				{
++					r = 1.0f;
++				}
++				else if ( score > 0.0f )
++				{
++					g = 0.2f + ( score / 20.0f );
++				}
++				else if ( score < 0.0f )
++				{ 
++					r = 0.2f + ( score / 20.0f );
++				}
++			}
++			break;
++		case CT_PAYMENT:
++			break;
++		case CT_ENTERED:
++			F32 entered = ent->getEntryEnteredSeconds();
++			if (distance <= 20.0f)
++			{
++				if ( entered <= ( 5.0f * 60.0f ) )
++				{
++					r = 0.7f - ( entered / ( 4.0f * 5.0f * 60.0f ) );
++					b = 1.0f - ( ( ( 5.0f * 60.0f ) - entered) / ( 5.0f * 60.0f ) );
++				}
++				else
++				{
++					b = 1.0f;
++				}
++			}
++			else
++			{
++				r = g = b = 0.5f;
++			}
++			break;
++	}
++
++	return LLColor4(r,g,b,a);
++}
++
++void LLFloaterAvatarList::onDoubleClick(void *userdata)
++{
++	LLFloaterAvatarList *self = (LLFloaterAvatarList*)userdata;
++ 	LLScrollListItem *item =   self->mAvatarList->getFirstSelected();
++	LLUUID agent_id = item->getUUID();
++	LLAvatarListEntry *ent = 0;
++
++	if ( self->mAvatars.count( agent_id ) )
++	{
++		ent = &self->mAvatars[ agent_id ];
++	}
++
++	if ( ent && ent->getIsCoarse() )
++	{
++		// nothing to look at, manipulate camera directly
++		LLQuaternion rot;
++		
++		LLMatrix3 mat(rot);
++
++		LLVector3 pos( ent->getPosition() );
++
++		LLViewerCamera::getInstance()->setView(1.0);
++		LLViewerCamera::getInstance()->setOrigin( pos );
++		LLViewerCamera::getInstance()->mXAxis = LLVector3(mat.mMatrix[0]);
++		LLViewerCamera::getInstance()->mYAxis = LLVector3(mat.mMatrix[1]);
++		LLViewerCamera::getInstance()->mZAxis = LLVector3(mat.mMatrix[2]);	}
++	else
++	{
++		gAgent.lookAtObject(agent_id, CAMERA_POSITION_OBJECT);
++	}
++}
++
++void LLFloaterAvatarList::removeFocusFromAll()
++{
++	std::map<LLUUID, LLAvatarListEntry>::iterator iter;
++
++	for(iter = mAvatars.begin(); iter != mAvatars.end(); iter++)
++	{
++		LLAvatarListEntry *ent = &iter->second;
++		ent->setFocus(FALSE);
++	}
++}
++
++void LLFloaterAvatarList::focusOnPrev(BOOL marked_only)
++{
++	std::map<LLUUID, LLAvatarListEntry>::iterator iter;
++	LLAvatarListEntry *prev = NULL;
++	LLAvatarListEntry *ent;
++
++	if ( mAvatars.size() == 0 )
++	{
++		return;
++	}
++
++	for(iter = mAvatars.begin(); iter != mAvatars.end(); iter++)
++	{
++		ent = &iter->second;
++
++		if ( ent->isDead() )
++			continue;
++
++		if ( (ent->getID() == mFocusedAvatar) && (prev != NULL)  )
++		{
++			removeFocusFromAll();
++			prev->setFocus(TRUE);
++			mFocusedAvatar = prev->getID();
++			gAgent.lookAtObject(mFocusedAvatar, CAMERA_POSITION_OBJECT);
++			return;
++		}
++
++		if ( (!marked_only) || ent->isMarked() )
++		{
++			prev = ent;
++		}
++	}
++
++	if (prev != NULL && ((!marked_only) || prev->isMarked()) )
++	{
++		removeFocusFromAll();
++		prev->setFocus(TRUE);
++		mFocusedAvatar = prev->getID();
++		gAgent.lookAtObject(mFocusedAvatar, CAMERA_POSITION_OBJECT);
++	}
++}
++
++void LLFloaterAvatarList::focusOnNext(BOOL marked_only)
++{
++
++	
++	std::map<LLUUID, LLAvatarListEntry>::iterator iter;
++	BOOL found = FALSE;
++	LLAvatarListEntry *first = NULL;
++	LLAvatarListEntry *ent;
++
++	if ( mAvatars.size() == 0 )
++	{
++		return;
++	}
++
++	for(iter = mAvatars.begin(); iter != mAvatars.end(); iter++)
++	{
++		ent = &iter->second;
++
++		if ( ent->isDead() )
++			continue;
++
++		if ( NULL == first && ((!marked_only) || ent->isMarked()))
++		{
++			first = ent;
++		}
++
++		if ( found && ((!marked_only) || ent->isMarked()) )
++		{
++			removeFocusFromAll();
++			ent->setFocus(TRUE);
++			mFocusedAvatar = ent->getID();
++			gAgent.lookAtObject(mFocusedAvatar, CAMERA_POSITION_OBJECT);
++			return;
++		}
++
++		if ( ent->getID() == mFocusedAvatar )
++		{
++			found = TRUE;
++		} 
++	}
++
++	if (first != NULL && ((!marked_only) || first->isMarked()))
++	{
++		removeFocusFromAll();
++		first->setFocus(TRUE);
++		mFocusedAvatar = first->getID();
++		gAgent.lookAtObject(mFocusedAvatar, CAMERA_POSITION_OBJECT);
++	}
++}
++//static
++void LLFloaterAvatarList::onClickPrevInList(void *userdata)
++{
++	LLFloaterAvatarList *self = (LLFloaterAvatarList*)userdata;
++	self->focusOnPrev(FALSE);
++}
++
++//static
++void LLFloaterAvatarList::onClickNextInList(void *userdata)
++{
++	LLFloaterAvatarList *self = (LLFloaterAvatarList*)userdata;
++	self->focusOnNext(FALSE);
++}
++
++//static
++void LLFloaterAvatarList::onClickPrevMarked(void *userdata)
++{
++	LLFloaterAvatarList *self = (LLFloaterAvatarList*)userdata;
++	self->focusOnPrev(TRUE);
++}
++
++//static
++void LLFloaterAvatarList::onClickNextMarked(void *userdata)
++{
++	LLFloaterAvatarList *self = (LLFloaterAvatarList*)userdata;
++	self->focusOnNext(TRUE);
++}
++
++//static
++void LLFloaterAvatarList::onClickTrustNetRate(void *userdata)
++{
++	// LLFloaterAvatarList *self = (LLFloaterAvatarList*)userdata;
++	llinfos << "Ratings not implemented yet" << llendl;
++}
++
++//static
++void LLFloaterAvatarList::onClickTrustNetExplain(void *userdata)
++{
++	LLFloaterAvatarList *self = (LLFloaterAvatarList*)userdata;
++	LLScrollListItem *item =   self->mAvatarList->getFirstSelected();
++
++	if ( item != NULL )
++	{
++		LLAvatarListEntry *ent = self->getAvatarEntry(item->getUUID());
++		self->speakText(TRUSTNET_CHANNEL, CHAT_TYPE_WHISPER, "Explain|" + ent->getName() + "|" + ent->getID().asString());
++	}
++}
++
++//static
++void LLFloaterAvatarList::onClickTrustNetWebsite(void *userdata)
++{
++	LLFloaterAvatarList *self = (LLFloaterAvatarList*)userdata;
++
++	self->speakText(TRUSTNET_CHANNEL, CHAT_TYPE_WHISPER, "GetWebAuthToken");
++}
++
++//static
++void LLFloaterAvatarList::onClickTrustNetGetPassword(void *userdata)
++{
++	LLFloaterAvatarList *self = (LLFloaterAvatarList*)userdata;
++
++	self->speakText(TRUSTNET_CHANNEL, CHAT_TYPE_WHISPER, "GetWebPassword");
++}
++
++//static
++void LLFloaterAvatarList::onClickTrustNetRenew(void *userdata)
++{
++	LLFloaterAvatarList *self = (LLFloaterAvatarList*)userdata;
++	self->speakText(TRUSTNET_CHANNEL, CHAT_TYPE_WHISPER, "RenewSubscription");
++}
++
++//static
++void LLFloaterAvatarList::onClickGetKey(void *userdata)
++{
++	LLFloaterAvatarList *self = (LLFloaterAvatarList*)userdata;
++ 	LLScrollListItem *item = self->mAvatarList->getFirstSelected();
++
++	if ( NULL == item ) return;
++
++	LLUUID agent_id = item->getUUID();
++
++	char buffer[UUID_STR_LENGTH];		/*Flawfinder: ignore*/
++	agent_id.toString(buffer);
++
++	gViewerWindow->mWindow->copyTextToClipboard(utf8str_to_wstring(buffer));
++}
++
++
++static void send_freeze(const LLUUID& avatar_id, bool freeze)
++{
++	U32 flags = 0x0;
++	if (!freeze)
++	{
++		// unfreeze
++		flags |= 0x1;
++	}
++
++	LLMessageSystem* msg = gMessageSystem;
++	LLViewerObject* avatar = gObjectList.findObject(avatar_id);
++
++	if (avatar)
++	{
++		msg->newMessage("FreezeUser");
++		msg->nextBlock("AgentData");
++		msg->addUUID("AgentID", gAgent.getID());
++		msg->addUUID("SessionID", gAgent.getSessionID());
++		msg->nextBlock("Data");
++		msg->addUUID("TargetID", avatar_id );
++		msg->addU32("Flags", flags );
++		msg->sendReliable( avatar->getRegion()->getHost() );
++	}
++}
++
++static void send_eject(const LLUUID& avatar_id, bool ban)
++{	
++	LLMessageSystem* msg = gMessageSystem;
++	LLViewerObject* avatar = gObjectList.findObject(avatar_id);
++
++	if (avatar)
++	{
++		U32 flags = 0x0;
++		if ( ban )
++		{
++			// eject and add to ban list
++			flags |= 0x1;
++		}
++
++		msg->newMessage("EjectUser");
++		msg->nextBlock("AgentData");
++		msg->addUUID("AgentID", gAgent.getID() );
++		msg->addUUID("SessionID", gAgent.getSessionID() );
++		msg->nextBlock("Data");
++		msg->addUUID("TargetID", avatar_id );
++		msg->addU32("Flags", flags );
++		msg->sendReliable( avatar->getRegion()->getHost() );
++	}
++}
++
++static void send_estate_message(
++	const char* request,
++	const LLUUID &target)
++{
++
++	LLMessageSystem* msg = gMessageSystem;
++	LLUUID invoice;
++
++	// This seems to provide an ID so that the sim can say which request it's
++	// replying to. I think this can be ignored for now.
++	invoice.generate();
++
++	llinfos << "Sending estate request '" << request << "'" << llendl;
++	msg->newMessage("EstateOwnerMessage");
++	msg->nextBlockFast(_PREHASH_AgentData);
++	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
++	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
++	msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used
++	msg->nextBlock("MethodData");
++	msg->addString("Method", request);
++	msg->addUUID("Invoice", invoice);
++
++	// Agent id
++	msg->nextBlock("ParamList");
++	msg->addString("Parameter", gAgent.getID().asString().c_str());
++
++	// Target
++	msg->nextBlock("ParamList");
++	msg->addString("Parameter", target.asString().c_str());
++
++	msg->sendReliable(gAgent.getRegion()->getHost());
++}
++
++static void send_estate_ban(const LLUUID& agent)
++{
++	LLUUID invoice;
++	U32 flags = ESTATE_ACCESS_BANNED_AGENT_ADD;
++
++	invoice.generate();
++
++	LLMessageSystem* msg = gMessageSystem;
++	msg->newMessage("EstateOwnerMessage");
++	msg->nextBlockFast(_PREHASH_AgentData);
++	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
++	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
++	msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null); //not used
++
++	msg->nextBlock("MethodData");
++	msg->addString("Method", "estateaccessdelta");
++	msg->addUUID("Invoice", invoice);
++
++	char buf[MAX_STRING];		/* Flawfinder: ignore*/
++	gAgent.getID().toString(buf);
++	msg->nextBlock("ParamList");
++	msg->addString("Parameter", buf);
++
++	snprintf(buf, MAX_STRING, "%u", flags);			/* Flawfinder: ignore */
++	msg->nextBlock("ParamList");
++	msg->addString("Parameter", buf);
++
++	agent.toString(buf);
++	msg->nextBlock("ParamList");
++	msg->addString("Parameter", buf);
++
++	gAgent.sendReliableMessage();
++}
++
++static void cmd_freeze(const LLUUID& avatar, const std::string &name)      { send_freeze(avatar, true); }
++static void cmd_unfreeze(const LLUUID& avatar, const std::string &name)    { send_freeze(avatar, false); }
++static void cmd_eject(const LLUUID& avatar, const std::string &name)       { send_eject(avatar, false); }
++static void cmd_ban(const LLUUID& avatar, const std::string &name)         { send_eject(avatar, true); }
++static void cmd_profile(const LLUUID& avatar, const std::string &name)     { LLFloaterAvatarInfo::showFromDirectory(avatar); }
++static void cmd_mute(const LLUUID&avatar, const std::string &name)         { LLMuteList::getInstance()->add(LLMute(avatar, name, LLMute::AGENT)); }
++static void cmd_unmute(const LLUUID&avatar, const std::string &name)       { LLMuteList::getInstance()->remove(LLMute(avatar, name, LLMute::AGENT)); }
++static void cmd_estate_eject(const LLUUID &avatar, const std::string &name){ send_estate_message("teleporthomeuser", avatar); }
++static void cmd_estate_ban(const LLUUID &avatar, const std::string &name)
++{
++	send_estate_message("teleporthomeuser", avatar); // Kick first, just to be sure
++	send_estate_ban(avatar);
++}
++
++void LLFloaterAvatarList::doCommand(void (*func)(const LLUUID &avatar, const std::string &name))
++{
++	LLDynamicArray<LLUUID> ids = mAvatarList->getSelectedIDs();
++
++	for(LLDynamicArray<LLUUID>::iterator itr = ids.begin(); itr != ids.end(); ++itr)
++	{
++		LLUUID avid = *itr;
++		LLAvatarListEntry *ent = getAvatarEntry(avid);
++		if ( ent != NULL )
++		{
++			llinfos << "Executing command on " << ent->getName() << llendl;
++			func(avid, ent->getName());
++		}
++	}
++}
++
++std::string LLFloaterAvatarList::getSelectedNames(const std::string& separator)
++{
++	std::string ret = "";
++	
++	LLDynamicArray<LLUUID> ids = mAvatarList->getSelectedIDs();
++	for(LLDynamicArray<LLUUID>::iterator itr = ids.begin(); itr != ids.end(); ++itr)
++	{
++		LLUUID avid = *itr;
++		LLAvatarListEntry *ent = getAvatarEntry(avid);
++		if ( ent != NULL )
++		{
++			if (!ret.empty()) ret += separator;
++			ret += ent->getName();
++		}
++	}
++
++	return ret;
++}
++
++//static 
++void LLFloaterAvatarList::callbackFreeze(S32 option, void *userdata) { 
++	LLFloaterAvatarList *avlist = (LLFloaterAvatarList*)userdata;
++
++	if ( option == 0 )
++	{
++		avlist->doCommand(cmd_freeze);
++	}
++	else if ( option == 1 )
++	{
++		avlist->doCommand(cmd_unfreeze);
++	}
++}
++
++//static 
++void LLFloaterAvatarList::callbackEject(S32 option, void *userdata) {
++	LLFloaterAvatarList *avlist = (LLFloaterAvatarList*)userdata;
++ 
++	if ( option == 0 )
++	{
++		avlist->doCommand(cmd_eject);
++	}
++	else if ( option == 1 )
++	{
++		avlist->doCommand(cmd_ban);
++	}
++}
++
++//static 
++void LLFloaterAvatarList::callbackMute(S32 option, void *userdata) {
++	LLFloaterAvatarList *avlist = (LLFloaterAvatarList*)userdata;
++
++	if ( option == 0 )
++	{
++		avlist->doCommand(cmd_mute);
++	} 
++	else if ( option == 1 )
++	{
++		avlist->doCommand(cmd_unmute);
++	}
++}
++
++//static 
++void LLFloaterAvatarList::callbackEjectFromEstate(S32 option, void *userdata) {
++	LLFloaterAvatarList *avlist = (LLFloaterAvatarList*)userdata;
++
++	if ( option == 0 )
++	{
++		avlist->doCommand(cmd_estate_eject);
++	} 
++	else if ( option == 1 )
++	{
++		avlist->doCommand(cmd_estate_ban);
++	}
++}
++
++//static
++void LLFloaterAvatarList::onClickFreeze(void *userdata)
++{
++	LLStringUtil::format_map_t args;
++	args["[NAMES]"] = ((LLFloaterAvatarList*)userdata)->getSelectedNames();
++	gViewerWindow->alertXml("AvatarListFreezeAvatars", args, callbackFreeze, userdata);
++}
++
++//static
++void LLFloaterAvatarList::onClickEject(void *userdata)
++{
++	LLStringUtil::format_map_t args;
++	args["[NAMES]"] = ((LLFloaterAvatarList*)userdata)->getSelectedNames();
++	gViewerWindow->alertXml("AvatarListEjectAvatars", args, callbackEject, userdata);
++}
++
++//static
++void LLFloaterAvatarList::onClickMute(void *userdata)
++{
++	LLStringUtil::format_map_t args;
++	args["[NAMES]"] = ((LLFloaterAvatarList*)userdata)->getSelectedNames();
++	gViewerWindow->alertXml("AvatarListMuteAvatars", args, callbackMute, userdata);
++}
++
++//static
++void LLFloaterAvatarList::onClickEjectFromEstate(void *userdata)
++{
++	LLStringUtil::format_map_t args;
++	args["[NAMES]"] = ((LLFloaterAvatarList*)userdata)->getSelectedNames();
++	gViewerWindow->alertXml("AvatarListEjectAvatarsFromEstate", args, callbackEjectFromEstate, userdata);
++}
++
++
++
++//static
++void LLFloaterAvatarList::onClickAR(void *userdata)
++{
++	LLFloaterAvatarList *avlist = (LLFloaterAvatarList*)userdata;
++	LLDynamicArray<LLUUID> ids = avlist->mAvatarList->getSelectedIDs();
++
++	for(LLDynamicArray<LLUUID>::iterator itr = ids.begin(); itr != ids.end(); ++itr)
++	{
++		LLUUID avid = *itr;
++		llinfos << "Adding " << avid << " to AR queue" << llendl;
++		avlist->mARQueue.push( avid );
++	}
++}
++
++// static
++void LLFloaterAvatarList::onClickProfile(void* userdata)
++{
++	LLFloaterAvatarList *avlist = (LLFloaterAvatarList*)userdata;
++	avlist->doCommand(cmd_profile);
++}
++
++//static
++void LLFloaterAvatarList::onClickTeleport(void* userdata)
++{
++	LLFloaterAvatarList *avlist = (LLFloaterAvatarList*)userdata;
++ 	LLScrollListItem *item =   avlist->mAvatarList->getFirstSelected();
++
++	if ( item )
++	{
++		LLUUID agent_id = item->getUUID();
++		LLAvatarListEntry *ent = avlist->getAvatarEntry(agent_id);
++		
++		if ( ent )
++		{
++			llinfos << "Trying to teleport to " << ent->getName() << " at " << ent->getPosition() << llendl;
++			gAgent.teleportViaLocation( ent->getPosition() );
++		}
++	}
++}
++
++
++void LLFloaterAvatarList::renderDebugBeacons()
++{
++	LLFastTimer t(LLFastTimer::FTM_TEMP1);
++	std::map<LLUUID, LLAvatarListEntry>::iterator iter;
++	for(iter = mAvatars.begin(); iter != mAvatars.end(); ++iter)
++	{
++		LLAvatarListEntry entry = iter->second;
++		if ( entry.isDead() )
++		{ // remove HUD Object if it exists
++			if ( mHudObjectMap.count(entry.getID()) )
++			{
++				mHudObjectMap[entry.getID()]->markDead();
++				mHudObjectMap.erase(entry.getID());
++			}
++			continue;
++		}
++
++		std::string name = entry.getName();
++		LLVector3d avpos = entry.getPosition();
++		LLVector3d mypos = gAgent.getPositionGlobal();
++		LLVector3d delta = avpos - mypos;
++		F32 distance = (F32)delta.magVec();
++		
++		std::string info = llformat( "%s %.02fm", name.c_str(), distance );
++		LLVector3 agentpos = gAgent.getPosAgentFromGlobal( avpos );
++
++		// roll our own HUD text since the debug beacons are rendered too late (after HUD update)
++		if (mHudObjectMap.count(entry.getID()) == 0)
++		{
++			mHudObjectMap[entry.getID()] = LLHUDObject::addHUDObject(LLHUDObject::LL_HUD_TEXT);
++		}
++		LLHUDText* hud_textp = (LLHUDText *)mHudObjectMap[entry.getID()].get(); // :-/
++		
++		hud_textp->setZCompare(FALSE);
++		hud_textp->setString(utf8str_to_wstring(info));
++		hud_textp->setColor(LLColor4::white);
++		hud_textp->setPositionAgent(agentpos);
++		hud_textp->setUseBubble(TRUE);
++		hud_textp->setMass(10.f);
++		hud_textp->setDoFade(FALSE);
++		//std::string posinfo = llformat("%f %f %f", agentpos[0], agentpos[1], agentpos[2]);
++		//hud_textp->setLabel(posinfo);
++
++		gObjectList.addDebugBeacon( agentpos, "", LLColor4(0.0f, 0.0f, 1.f, 0.5f), LLColor4::white, gSavedSettings.getS32("DebugBeaconLineWidth") );
++	}	
++}
++
++bool LLFloaterAvatarList::sRenderAvatarBeacons = true;
++
+diff --git a/indra/newview/llfloateravatarlist.h b/indra/newview/llfloateravatarlist.h
+new file mode 100644
+index 0000000..78df867
+--- /dev/null
++++ b/indra/newview/llfloateravatarlist.h
+@@ -0,0 +1,868 @@
++//
++// C++ Interface: llfloateravatarlist
++//
++// Description: 
++//
++//
++// Author: Dale Glass <dale at daleglass.net>, (C) 2007
++//
++// Copyright: See COPYING file that comes with this distribution
++//
++//
++#include "llfloater.h"
++#include "llfloaterreporter.h"
++#include "lluuid.h"
++#include "lltimer.h"
++#include "llchat.h"
++#include "llappviewer.h"
++#include "llscrolllistctrl.h"
++#include "llhudobject.h"
++
++#include <time.h>
++#include <map>
++
++class LLFloaterAvatarList;
++
++/**
++ * @brief Account type
++ */
++enum ACCOUNT_TYPE
++{
++	ACCOUNT_RESIDENT,         /** Normal resident */
++	ACCOUNT_TRIAL,            /** Trial account */
++	ACCOUNT_CHARTER_MEMBER,   /** Lifetime account obtained during beta */
++	ACCOUNT_EMPLOYEE,         /** Linden Lab employee */
++	ACCOUNT_CUSTOM            /** Custom account title specified. Seems to apply to Philip Linden */
++};
++
++/**
++ * @brief Payment data
++ */
++enum PAYMENT_TYPE
++{
++	PAYMENT_NONE,             /** No payment data on file */
++	PAYMENT_ON_FILE,          /** Payment data filled, but not used */
++	PAYMENT_USED,             /** Payment data used */
++	PAYMENT_LINDEN            /** Payment info doesn't apply (Linden, etc) */
++};
++
++
++/**
++ * @brief Activity
++ *
++ * This enum is ordered by priority, higher values have higher priority.
++ * Since we only have one column to show activity, priority decides what
++ * to show in case of conflict.
++ */
++enum ACTIVITY_TYPE
++{
++	ACTIVITY_NONE,           /** Avatar not doing anything */ 
++	ACTIVITY_MOVING,         /** Changing position */
++	ACTIVITY_GESTURING,	 /** Playing a gesture */
++	ACTIVITY_SOUND,          /** Playing a sound */
++	ACTIVITY_REZZING,        /** Rezzing objects */
++	ACTIVITY_PARTICLES,      /** Creating particles */
++	ACTIVITY_TYPING,         /** Typing */
++	ACTIVITY_NEW,            /** Avatar just appeared */
++	ACTIVITY_DEAD            /** Avatar isn't around anymore, and will be removed soon from the list */
++};
++
++enum DATA_STATUS
++{
++	DATA_UNKNOWN,
++	DATA_REQUESTING,
++	DATA_ERROR,
++	DATA_RETRIEVED
++};
++
++/**
++ * @brief How to color the user list
++ */
++enum e_coloring_type
++{
++	CT_NONE,
++	CT_DISTANCE,
++	CT_AGE,
++	CT_SCORE,
++	CT_PAYMENT,
++	CT_ENTERED
++};
++
++/**
++ * @brief Template class for a piece of data that must be retrieved
++ *
++ * This class handles the storage, retries and delays required to obtain a piece
++ * of data..
++ */
++template <class T> 
++class LLAvatarListDatum
++{
++public:
++	LLAvatarListDatum()
++	{
++		mMaxPending = 32;
++
++		mRetryDelay = 0.0f;
++		mRequestDelay = 1.0f;
++		mFirstRequestTimeout = 16.0f;
++		mMaxRequestTimeout = 8192.0f;
++
++		mRequestTimer.start();
++		mRequestDelayTimer.start();
++		mStatus = DATA_UNKNOWN;
++		
++	}
++
++	/**
++	 * @brief Determines whether a data re-request is needed
++	 * @returns TRUE if a re-request is needed
++	 *
++	 * This function takes the decision based on whether the data has
++	 * been already retrieved, the last data request was long enough ago,
++	 * and the request rate being low enough.
++	 *
++	 * A FALSE return value doesn't mean that everything is OK, only that
++	 * a retry shouldn't be made at this time.
++	 */
++	BOOL retryNeeded()
++	{
++		switch(mStatus)
++		{
++			case DATA_UNKNOWN:
++			case DATA_REQUESTING:
++			case DATA_ERROR:
++				// Don't request too many at once
++				if ( mPending >= mMaxPending )
++				{
++					return FALSE;
++				}
++
++				// Don't re-request if the requests would be made too fast
++				if ( mRequestDelayTimer.getElapsedTimeF32() < mRequestDelay )
++				{
++					return FALSE;
++				}
++
++				// Re-request if retry timeout was reached
++				return ( mRequestTimer.getElapsedTimeF32() > mRetryDelay );
++			case DATA_RETRIEVED:
++				return FALSE;
++		}
++
++		return FALSE;
++	}
++
++	/**
++	 * @brief Notifies the object that a request was started
++	 */
++	void requestStarted()
++	{
++
++		if ( mStatus != DATA_REQUESTING )
++		{
++			mPending++;
++			//llinfos << "Pe
++		}
++
++		mStatus = DATA_REQUESTING;
++
++		if ( mRetryDelay == 0 )
++		{
++			mRetryDelay = mFirstRequestTimeout;
++		}
++		else
++		{
++			if ( mRetryDelay < mMaxRequestTimeout )
++			{
++				mRetryDelay *= 2;
++			}
++		}
++
++		mRequestTimer.start();
++		mRequestDelayTimer.start();
++	}
++
++	/**
++	 * @brief retryNeeded and requestStarted combined
++	 * @returns TRUE if a re-request is needed
++	 */
++	BOOL requestIfNeeded()
++	{
++		BOOL ret = retryNeeded();
++		if ( ret )
++		{
++			requestStarted();
++		}
++
++		return ret;
++	}
++
++	/**
++	 * @brief Returns the request status
++	 */
++	DATA_STATUS getStatus()
++	{
++		if ( mStatus == DATA_REQUESTING 
++		     && mRequestTimer.getElapsedTimeF32() > mRetryDelay )
++		{
++			mStatus = DATA_ERROR;
++
++			// Consider this request failed, so the slot is free.
++			mPending--;
++		}
++
++		return mStatus;
++	}
++
++	T& getValue()
++	{
++		return mValue;
++	}
++
++	void setValue(T val)
++	{
++		if ( mStatus != DATA_RETRIEVED )
++		{
++			mPending--;
++		}
++
++		mValue = val;
++		mStatus = DATA_RETRIEVED;
++	}
++
++	void setRequestDelay(F32 delay)
++	{
++		mRequestDelay = delay;
++	}
++
++	void setMaxPending(U32 count)
++	{
++		mMaxPending = count;
++	}
++private:
++	friend class LLFloaterAvatarList;
++	T mValue;
++
++	DATA_STATUS mStatus;
++
++	
++	/**
++	 * @brief How long to wait before trying to re-request the data
++	 */
++	F32 mRetryDelay;
++
++	/**
++	 * @brief How long to wait on the first attempt to get data
++	 */
++	F32 mFirstRequestTimeout;
++
++	/**
++	 * @brief Maximum delay between retries
++	 *
++	 * On failure, timeout gets doubled until it reaches this value
++	 */
++	F32 mMaxRequestTimeout;
++
++	/**
++	 * @brief Timer for the current request
++	 */
++	LLTimer mRequestTimer;
++
++
++
++	/**
++	 * @brief Timer used to separate requests, to avoid flooding the server
++	 */
++	static LLTimer mRequestDelayTimer;
++
++	/**
++	 * @brief Amount of pending requests
++	 */
++	static U32 mPending;
++
++
++	/**
++	 * @brief Time between requests of the same type
++	 */
++	F32 mRequestDelay;
++
++	/**
++	 * @brief Maximum amount of pending requests
++	 */
++	U32 mMaxPending;
++};
++
++template <class T> LLTimer LLAvatarListDatum<T>::mRequestDelayTimer;
++template <class T> U32 LLAvatarListDatum<T>::mPending = 0;
++
++//template <class T> F32 LLAvatarListDatum<T>::mRequestDelay;
++
++
++
++/**
++ * @brief A TrustNet score
++ */
++struct LLAvListTrustNetScore
++{
++	F32 Score;
++	std::string Type;
++
++	LLAvListTrustNetScore(std::string type = "<uninitialized>", F32 score = 0.0f);
++};
++
++/**
++ * @brief Avatar payment information
++ */
++struct LLAvatarInfo
++{
++	PAYMENT_TYPE Payment;
++	ACCOUNT_TYPE Account;
++	struct tm    BirthDate;
++
++	LLAvatarInfo();
++	LLAvatarInfo(PAYMENT_TYPE payment, ACCOUNT_TYPE account, struct tm birth);
++	S32 getAge();
++};
++
++/**
++ * @brief Misc data about the avatar
++ * This class holds replies from third party databases. There's no fixed format,
++ * and interpretation is left to the end user.
++ */
++struct LLMiscDBInfo
++{
++	std::string data;
++
++	LLMiscDBInfo(std::string d)
++	{
++		data = d;
++	}
++
++	LLMiscDBInfo()
++	{
++		data = "";
++	}
++};
++
++
++/**
++ * @brief This class is used to hold data about avatars.
++ * We cache data about avatars to avoid repeating requests in this class.
++ * Instances are kept in a map<LLAvatarListEntry>. We keep track of the
++ * frame where the avatar was last seen. Avatars that are old enough are
++ * not added to the visible list, but still kept around to cache the account
++ * info data (like the birth date and the payment data)
++ */
++class LLAvatarListEntry {
++public:
++
++
++	/**
++	 * @brief Initializes a list entry
++	 * @param id Avatar's key
++	 * @param name Avatar's name
++	 * @param position Avatar's current position
++	 * @param isLinden TRUE if the avatar is a Linden
++	 * @param isCoarse TRUE if the avatar is only in the coarse location list
++	 * @param regionname if the region is not the same as the current agent region, else empty string
++	 */
++	LLAvatarListEntry(const LLUUID& id = LLUUID::null, const std::string &name = "", const LLVector3d &position = LLVector3d::zero, BOOL isLinden = FALSE, BOOL isCoarse = FALSE, std::string regionname = std::string() ) :
++		mID(id), mName(name), mPosition(position), mMarked(FALSE), mFocused(FALSE), mIsLinden(isLinden), mIsCoarse(isCoarse), mRegionName(regionname), mActivityType(ACTIVITY_NEW), mAccountTitle(""),
++		mUpdateTimer(), mActivityTimer(), mFrame(0)
++	{
++		mTrustNetScore.setRequestDelay(0.1f);
++		mTrustNetScore.setMaxPending(8);
++		mFrame = gFrameCount;
++		mEnteredTimer.start();
++	}
++
++	/**
++	 * Update world position.
++	 * Affects age.
++	 */	
++	void setPosition(LLVector3d position);
++
++	LLVector3d getPosition();
++
++	/**
++	 * @brief Returns the age of this entry in frames
++	 *
++	 * This is only used for determining whether the avatar is still around.
++	 * @see getEntryAgeSeconds
++	 */
++	U32 getEntryAgeFrames();
++
++	/**
++	 * @brief Returns the age of this entry in seconds
++	 */
++	F32 getEntryAgeSeconds();
++
++	/**
++	 * @brief Returns time when avatar entered the list
++	 */
++	F32 getEntryEnteredSeconds();
++
++	/**
++	 * @brief Returns the name of the avatar
++	 */
++	std::string getName();
++
++	void setName(std::string name);
++
++	LLUUID getID();
++
++	void setID(LLUUID id);
++
++	/**
++	 * @brief Whether the avatar is a Linden
++	 */
++	BOOL getIsLinden();
++
++	/**
++	 * @brief whether the avatar entry was taken from the coarse location update
++	 */
++	BOOL getIsCoarse() { return mIsCoarse; }
++
++	/**
++	 * @brief returns the agents region name or "" if same as main agent
++	 */
++	std::string &getRegionName() { return mRegionName; }
++
++	/**
++	 * @brief returns true if agent is on same region
++	 */
++	BOOL getIsSameRegion() { return mRegionName.empty(); }
++
++	/**
++	 * @brief returns reference to the HUDObject-pointer for this avatar if any
++	 */
++	LLPointer<LLHUDObject> &getHudObject() { return mHudObject; }
++
++	/**
++	 * @brief Sets a custom title for the account
++	 * @note Changes account type to ACCOUNT_CUSTOM
++	 */
++	void setAccountCustomTitle(std::string &title);
++
++	/**
++	 * @brief Gets the custom title for the account
++	 */
++	std::string getAccountCustomTitle();
++
++	/**
++	 * @brief Sets the activity type for this avatar
++	 *
++	 * Has no effect if the specified type is lower priority than the
++	 * current one.
++	 */
++	void setActivity(ACTIVITY_TYPE activity);
++
++	/**
++	 * @brief Returns the activity type
++	 */
++	ACTIVITY_TYPE getActivity();
++
++	/**
++	 * @brief Sets the 'focus' status on this entry (camera focused on this avatar)
++	 */
++	void setFocus(BOOL value) { mFocused = value; }
++
++	BOOL isFocused() { return mFocused; }
++
++
++	BOOL isMarked();
++
++	/**
++	 * @brief Returns whether the item is dead and shouldn't appear in the list
++	 * @returns TRUE if dead
++	 */
++	BOOL isDead();
++
++	void toggleMark();
++private:
++	friend class LLFloaterAvatarList;
++
++	LLUUID mID;
++	std::string mName;
++	LLVector3d mPosition;
++	BOOL mMarked;
++	BOOL mFocused;
++	BOOL mIsLinden;
++	BOOL mIsCoarse;
++	std::string mRegionName;
++	LLPointer<LLHUDObject> mHudObject; /* holds the text on screen, if we don't keep this it won't reach a stable position on-screen but gets recreated for each update */
++
++
++	ACTIVITY_TYPE mActivityType;
++
++	std::string mAccountTitle;
++
++	LLAvatarListDatum<LLAvListTrustNetScore> mTrustNetScore;
++	LLAvatarListDatum<LLAvatarInfo>   mAvatarInfo;
++	LLAvatarListDatum<LLMiscDBInfo> mMiscInfo;
++
++	/**
++	 * @brief Timer to keep track of whether avatars are still there
++	 */
++	LLTimer mUpdateTimer;
++
++	/**
++	 * @brief Timer for avatar activities
++	 */
++	LLTimer mActivityTimer;
++
++	/**
++	 * @brief Last frame when this avatar was updated
++	 */
++	U32 mFrame;
++	
++	/**
++	 * @brief Time when avatar entered the list
++	 */
++	LLTimer mEnteredTimer;
++};
++
++
++/**
++ * @brief Avatar List
++ * Implements an avatar scanner in the client.
++ *
++ * This is my first attempt to modify the SL source. This code is intended
++ * to have a dual purpose: doing the task, and providing an example of how
++ * to do it. For that reason, it's going to be commented as exhaustively
++ * as possible.
++ *
++ * Since I'm very new to C++ any suggestions on coding, style, etc are very
++ * welcome.
++ */
++class LLFloaterAvatarList : public LLFloater
++{
++public:
++	/**
++	 * @brief Creates and initializes the LLFloaterAvatarList
++	 * Here the interface is created, and callbacks are initialized.
++	 */
++	LLFloaterAvatarList();
++	~LLFloaterAvatarList();
++
++	void show();
++
++	/**
++	 * @brief Hide when user closes the list.
++	 */
++	virtual void onClose(bool app_quitting) { setVisible(FALSE); }
++
++	/**
++	 * @brief Toggles interface visibility
++	 * There is only one instance of the avatar scanner at any time.
++	 */
++	static void toggle(void*);
++
++	/**
++	 * @brief Returns floater visibility status
++	 */
++	static BOOL visible(void*);
++
++	/**
++	 * @brief Updates the internal avatar list with the currently present avatars.
++	 */
++	void updateAvatarList();
++
++	/**
++	 * @brief Refresh avatar list (display)
++	 */
++	void refreshAvatarList();
++
++	/**
++	 * @brief Process the reply to a request for avatar properties
++	 */
++	static void processAvatarPropertiesReply(LLMessageSystem *msg, void**);
++
++	/**
++	 * @brief Returns TRUE if the avatar is in the list of known avatars
++	 * @returns TRUE if the avatar is in the list
++	 */
++	BOOL avatarIsInList(LLUUID avatar);
++
++	/**
++	 * @brief Returns the entry for an avatar, if preset
++	 * @returns Pointer to avatar entry, NULL if not found.
++	 */
++	LLAvatarListEntry* getAvatarEntry(LLUUID avatar);
++
++	/**
++	 * @brief Requests a TrustNet score from the Adapter
++	 * @param avatar Avatar for which to request the score
++	 * @param name Avatar's name
++	 * @param type Score type ("behavior", etc)
++	 */
++	void requestTrustNetScore(LLUUID avatar, const std::string name, const std::string type);
++
++	/**
++	 * @brief Requests information about the avatar from the database
++	 * @param avatar Avatar about whom we need information
++	 * @param name Avatar's name
++	 */
++	void requestMiscInfo(LLUUID avatar, const std::string name);
++
++	/**
++	 * @brief Handles IM messages to process the ones that are replies to database requests
++	 * @param from_id Key of the avatar sending the message
++	 * @param message Content
++	 * @returns TRUE if the message was handled. This will suppress further processing in llviewermessage.cpp
++	 */
++	static BOOL handleIM(LLUUID from_id, const std::string message);
++
++	/**
++	 * @brief Process a reply from the TrustNet Adapter
++	 * This handles replies from the TrustNet adapter, such as score results.
++	 */
++	static void processTrustNetReply(char *reply);
++
++	/**
++	 * @brief Returns a string with the selected names in the list
++	 */
++	std::string getSelectedNames(const std::string& separator = ", ");
++
++	/** @brief render a debug beacon for the coarse avatars */
++	void renderDebugBeacons();
++
++	/** @brief if avatar beacons shall be rendered */
++	static bool getRenderAvatarBeacons(void *data) { return sRenderAvatarBeacons; }
++
++	/** @brief set if avatar beacons shall be rendered */
++	static void toggleRenderAvatarBeacons(void *data) { sRenderAvatarBeacons = !sRenderAvatarBeacons; }
++
++	/** @brief set if avatar beacons shall be rendered */
++	static void setRenderAvatarBeacons(bool do_render ) { sRenderAvatarBeacons = do_render; }
++
++private:
++	// when a line editor loses keyboard focus, it is committed.
++	// commit callbacks are named onCommitWidgetName by convention.
++	//void onCommitBaz(LLUICtrl* ctrl, void *userdata);
++	
++	enum AVATARS_COLUMN_ORDER
++	{
++		LIST_AVATAR_ICON,
++		LIST_AVATAR_NAME,
++		LIST_DISTANCE,
++		LIST_AGE,
++		/*LIST_SCORE,*/
++		LIST_PAYMENT,
++		LIST_ACTIVITY,
++		LIST_ENTERED,
++	};
++
++	typedef void (*avlist_command_t)(const LLUUID &avatar, const std::string &name);
++
++	void speakText(S32 channel, EChatType type, std::string text);
++
++	/**
++	 * @brief Removes focus status from all avatars in list
++	 */
++	void removeFocusFromAll();
++
++	/**
++	 * @brief Focus camera on previous avatar
++	 * @param marked_only Whether to choose only marked avatars
++	 */
++	void focusOnPrev(BOOL marked_only);
++
++	/**
++	 * @brief Focus camera on next avatar
++	 * @param marked_only Whether to choose only marked avatars
++	 */
++	void focusOnNext(BOOL marked_only);
++
++	/**
++	 * @brief Updates the internal avatar list from the coarse location list if not already present
++	 */
++	void updateFromCoarse();
++
++	/**
++	 * @brief Purge hud object map from entries no longer in the list
++	 */
++	void purgeAvatarHUDMap();
++
++	/**
++	 * @brief Handler for the "refresh" button click.
++	 * I am unsure whether this is actually necessary at the time.
++	 *
++	 * LL: By convention, button callbacks are named onClickButtonLabel
++	 * @param userdata Pointer to user data (LLFloaterAvatarList instance)
++	 */
++	//static void onClickRefresh(void* userdata);
++
++	static void onClickProfile(void *userdata);
++	static void onClickIM(void *userdata);
++	static void onClickTrack(void *userdata);
++	static void onClickMark(void *userdata);
++
++	static void onClickGohomerMark(void *userdata);
++	static void onClickGohomerWarn(void *userdata);
++	static void onClickGohomerEject(void *userdata);
++	static void onClickGohomerSendAway(void *userdata);
++	static void onClickGohomerSendHome(void *userdata);
++	static void onClickGohomerSendHomeByKey(void *userdata);
++
++	static void onClickGohomerOff(void *userdata);
++
++
++	static void onClickPrevInList(void *userdata);
++	static void onClickNextInList(void *userdata);
++	static void onClickPrevMarked(void *userdata);
++	static void onClickNextMarked(void *userdata);
++	static void onClickGetKey(void *userdata);
++
++	static void onClickTrustNetRate(void *userdata);
++	static void onClickTrustNetExplain(void *userdata);
++	static void onClickTrustNetWebsite(void *userdata);
++	static void onClickTrustNetGetPassword(void *userdata);
++	static void onClickTrustNetRenew(void *userdata);
++
++	static void onDoubleClick(void *userdata);
++
++	static void onClickFreeze(void *userdata);
++	static void onClickEject(void *userdata);
++//	static void onClickBan(void *userdata);
++//	static void onClickUnban(void *userdata);
++	static void onClickMute(void *userdata);
++//	static void onClickUnmute(void *userdata);
++	static void onClickAR(void *userdata);
++	static void onClickTeleport(void *userdata);
++	static void onClickEjectFromEstate(void *userdata);
++
++	static void callbackFreeze(S32 option, void *userdata);
++//	static void callbackUnfreeze(S32 option, void *userdata);
++	static void callbackEject(S32 option, void *userdata);
++//	static void callbackBan(S32 option, void *userdata);
++	static void callbackMute(S32 option, void *userdata);
++//	static void callbackUnmute(void *userdata);
++	static void callbackAR(void *userdata);
++	static void callbackEjectFromEstate(S32 option, void *userdata);
++
++	void doCommand(avlist_command_t cmd);
++
++	/**
++	 * @brief Cleanup avatar list, removing dead entries from it.
++	 * This lets dead entries remain for some time. This makes it possible
++	 * to keep people passing by in the list long enough that it's possible
++	 * to do something to them.
++	 */
++	void expireAvatarList();
++
++	/**
++	 * @brief Perform a Luskwood Gohomer command on the selected users
++	 * @param cmd Command (for example "gowarn")
++	 */
++	void luskwoodCommand(std::string cmd);
++
++	/**
++	 * @brief Handle the results of a gohomer confirmation dialog
++	 * @param option Option selected (0=ok, 1=cancel)
++	 * @param data this
++	 */
++	static void handleLuskwoodDialog(S32 option, void* data);
++
++	/**
++	 * @brief Handle the results of a gohomer turn off dialog
++	 * @param option Option selected (0=ok, 1=cancel)
++	 * @param data this
++	 */
++	static void handleLuskwoodGohomerOffDialog(S32 option, void* data);
++
++	/**
++	 * @brief Process the AR queue
++	 * This generates AR reports for the queued avatars
++	 */
++	void processARQueue();
++		
++private:
++	/**
++	 * @brief Pointer to the avatar scroll list
++	 */
++	LLScrollListCtrl*			mAvatarList;
++	std::map<LLUUID, LLAvatarListEntry>	mAvatars;
++
++	/**
++	 * @brief Queue of abuse reports
++	 */
++	std::queue<LLUUID> mARQueue;
++
++	/**
++	 * @brief List of AR screens opened
++	 * We don't open them on creation to capture a clean screenshot. They're
++	 * opened only after finishing the process.
++	 */
++	std::queue<LLFloaterReporter*> mARReporterQueue;
++
++	/**
++	 * @brief Last time during which an AR was submitted
++	 * Used to give the camera some time to move between avatars. Perhaps this way
++	 * of doing things isn't ideal, though.
++	 */
++	S32 mARLastFrame;
++	
++	
++	/**
++	 * @brief Request information about the specified avatar
++	 * @param avid Avatar id to request info about
++	 */
++	void sendAvatarPropertiesRequest(LLUUID avid);
++
++	void checkTrackingStatus();
++
++	/**
++	 * @brief Returns the color for the specified avatar entry
++	 * @param ent Avatar entry
++	 * @param distance Distance from the user
++	 */
++	//LLColor4 getAvatarColor(LLAvatarListEntry *ent, F32 distance);
++	LLColor4 getAvatarColor(LLAvatarListEntry *ent, F32 distance, e_coloring_type type);
++
++	/**
++	 * @brief Replace variables in string
++	 * @param str String to replace variables in
++	 * @param avatar Value for $KEY
++	 * @param name Value for $NAME
++	 */
++	static void replaceVars(std::string &str, LLUUID avatar, const std::string& name);
++
++	// tracking data
++	BOOL mTracking;             // tracking?
++	BOOL mTrackByLocation;      // TRUE if tracking by known position, FALSE for tracking a friend
++	LLUUID mTrackedAvatar;     // who we're tracking
++
++	/**
++	 * @brief Used to delay avatar data requests
++	 */
++	LLTimer mDataRequestTimer;
++
++	/**
++	 * @brief Used to delay trustnet requests
++	 */
++	LLTimer mTrustNetTimer;
++
++	/**
++	 * @brief Luskwood command to execute
++	 */
++	std::string mLuskwoodCommand;
++
++	/**
++	 * @brief Avatar the camera is focused on
++	 */
++	LLUUID mFocusedAvatar;
++
++	/** @brief holds state of avatar beacon render setup */
++	static bool sRenderAvatarBeacons;
++
++
++	std::map< LLUUID, LLPointer<LLHUDObject> > mHudObjectMap;
++};
++
++/**
++ * Pointer to global LLFloaterAvatarList instance.
++ * This is initialized in llviewerwindow.cpp
++ * @see llviewerwindow.cpp
++ */
++extern LLFloaterAvatarList* gFloaterAvatarList;
+diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
+index 5451ca0..754c839 100644
+--- a/indra/newview/llfloaterpreference.cpp
++++ b/indra/newview/llfloaterpreference.cpp
+@@ -60,6 +60,7 @@
+ #include "llpanelLCD.h"
+ #include "llpanelmsgs.h"
+ #include "llpanelweb.h"
++#include "llpaneldatabase.h"
+ #include "llpanelskins.h"
+ #include "llprefschat.h"
+ #include "llprefsvoice.h"
+@@ -190,6 +191,10 @@ LLPreferenceCore::LLPreferenceCore(LLTabContainer* tab_container, LLButton * def
+ 	mTabContainer->addTabPanel(mSkinsPanel, mSkinsPanel->getLabel(), FALSE, onTabChanged, mTabContainer);
+ 	mSkinsPanel->setDefaultBtn(default_btn);
+ 
++	mDBPanel = new LLPanelDatabase();
++	mTabContainer->addTabPanel(mDBPanel, mDBPanel->getLabel(), FALSE, onTabChanged, mTabContainer);
++	mDBPanel->setDefaultBtn(default_btn);
++
+ 	if (!mTabContainer->selectTab(gSavedSettings.getS32("LastPrefTab")))
+ 	{
+ 		mTabContainer->selectFirstTab();
+@@ -269,6 +274,7 @@ void LLPreferenceCore::apply()
+ 	LLFloaterHardwareSettings::instance()->apply();
+ 
+ 	mWebPanel->apply();
++	mDBPanel->apply();
+ #if LL_LCD_COMPILE
+ 	// only add this option if we actually have a logitech keyboard / speaker set
+ 	if (gLcdScreen->Enabled())
+@@ -297,6 +303,7 @@ void LLPreferenceCore::cancel()
+ 	LLFloaterHardwareSettings::instance()->cancel();
+ 
+ 	mWebPanel->cancel();
++	mDBPanel->cancel();
+ #if LL_LCD_COMPILE
+ 	// only add this option if we actually have a logitech keyboard / speaker set
+ 	if (gLcdScreen->Enabled())
+diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
+index bfa2499..e54b7f6 100644
+--- a/indra/newview/llfloaterpreference.h
++++ b/indra/newview/llfloaterpreference.h
+@@ -49,6 +49,7 @@ class LLPanelAudioPrefs;
+ class LLPanelDebug;
+ class LLPanelNetwork;
+ class LLPanelWeb;
++class LLPanelDatabase;
+ class LLMessageSystem;
+ class LLPrefsChat;
+ class LLPrefsVoice;
+@@ -91,6 +92,7 @@ private:
+ 	LLPanelWeb				*mWebPanel;
+ 	LLPanelMsgs				*mMsgPanel;
+ 	LLPanelLCD				*mLCDPanel;
++	LLPanelDatabase				*mDBPanel;
+ };
+ 
+ // Floater to control preferences (display, audio, bandwidth, general.
+diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp
+index 7e9632d..23f9ec5 100644
+--- a/indra/newview/llfloaterreporter.cpp
++++ b/indra/newview/llfloaterreporter.cpp
+@@ -540,7 +540,7 @@ void LLFloaterReporter::showFromMenu(EReportType report_type)
+ 
+ 
+ // static
+-void LLFloaterReporter::showFromObject(const LLUUID& object_id)
++LLFloaterReporter* LLFloaterReporter::showFromObject(const LLUUID& object_id, bool show)
+ {
+ 	LLFloaterReporter* f = createNewAbuseReporter();
+ 	f->center();
+@@ -557,7 +557,16 @@ void LLFloaterReporter::showFromObject(const LLUUID& object_id)
+ 	// Need to deselect on close
+ 	f->mDeselectOnClose = TRUE;
+ 
+-	f->open();		/* Flawfinder: ignore */
++	if ( show )
++	{
++		f->open();		/* Flawfinder: ignore */
++	}
++	else
++	{
++		gDialogVisible = FALSE;
++	}
++
++	return f;
+ }
+ 
+ 
+diff --git a/indra/newview/llfloaterreporter.h b/indra/newview/llfloaterreporter.h
+index ff7f112..1603dad 100644
+--- a/indra/newview/llfloaterreporter.h
++++ b/indra/newview/llfloaterreporter.h
+@@ -92,7 +92,7 @@ public:
+ 	// Enables all buttons
+ 	static void showFromMenu(EReportType report_type);
+ 
+-	static void showFromObject(const LLUUID& object_id);
++	static LLFloaterReporter* showFromObject(const LLUUID& object_id, bool show = true);
+ 
+ 	static void onClickSend			(void *userdata);
+ 	static void onClickCancel		(void *userdata);
+diff --git a/indra/newview/llpaneldatabase.cpp b/indra/newview/llpaneldatabase.cpp
+new file mode 100644
+index 0000000..f510130
+--- /dev/null
++++ b/indra/newview/llpaneldatabase.cpp
+@@ -0,0 +1,149 @@
++/** 
++ * @file llpaneldatabase.cpp
++ * @brief Database preferences panel
++ * @author Dale Glass
++ *
++ * Copyright (c) 2003-2007, Linden Research, Inc.
++ * 
++ * 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.
++ */
++
++#include "llviewerprecompiledheaders.h"
++
++#include "llpaneldatabase.h"
++
++#include "llscrolllistctrl.h"
++#include "llviewerwindow.h"
++#include "llviewercontrol.h"
++#include "lluictrlfactory.h"
++#include "llfloateravatarpicker.h"
++#include "llagentdata.h"
++#include "llnotify.h"
++
++//-----------------------------------------------------------------------------
++LLPanelDatabase::LLPanelDatabase() :
++	LLPanel("Messages Panel")
++{
++	LLUICtrlFactory::getInstance()->buildPanel(this, "panel_preferences_database.xml");
++	childSetAction("change_avatar_btn", onClickChangeAvatar, this);
++};
++
++//-----------------------------------------------------------------------------
++// postBuild()
++//-----------------------------------------------------------------------------
++
++void LLPanelDatabase::refresh() 
++{
++	llinfos << "Loading settings" << llendl;
++	//mAvatarName      = gSavedPerAccountSettings.getString("DBAvatarName");
++	//mAvatarKey.set(gSavedPerAccountSettings.getString("DBAvatarKey"));
++	//mURL             = gSavedSettings.getString("DBURL");;
++	//mUsername        = gSavedSettings.getString("DBURLUsername");;
++	//mPassword        = gSavedSettings.getString("DBURLPassword");;
++	//mSendPattern     = gSavedSettings.getString("DBSendPattern");;
++	//mPositivePattern = gSavedSettings.getString("DBPositivePattern");;
++	//mNegativePattern = gSavedSettings.getString("DBNegativePattern");;
++	//mDeniedPattern   = gSavedSettings.getString("DBDeniedPattern");;
++
++}
++
++BOOL LLPanelDatabase::postBuild()
++{
++	refresh();
++
++	llinfos << "Setting settings in window" << llendl;
++	childSetText("db_avatar"       ,mAvatarName );
++	childSetText("db_url"          ,mURL );
++	childSetText("db_url_username" ,mUsername );
++	childSetText("db_url_password" ,mPassword );
++	childSetText("send_pattern"    ,mSendPattern );
++	childSetText("positive_pattern",mPositivePattern );
++	childSetText("negative_pattern",mNegativePattern );
++	childSetText("denied_pattern"  ,mDeniedPattern );
++
++	return TRUE;
++}
++
++
++void LLPanelDatabase::draw()
++{
++	LLPanel::draw();
++}
++
++void LLPanelDatabase::apply()
++{
++	//llinfos << "Saving settings" << llendl;
++
++	//gSavedPerAccountSettings.setString("DBAvatarName", childGetText("db_avatar").c_str());
++	//gSavedPerAccountSettings.setString("DBAvatarKey", mAvatarKey.asString());
++	//gSavedSettings.setString("DBURL", childGetText("db_url").c_str());
++	//gSavedSettings.setString("DBURLUsername", childGetText("db_url_username").c_str());
++	//gSavedSettings.setString("DBURLPassword", childGetText("db_url_password").c_str());
++
++	//gSavedSettings.setString("DBSendPattern", childGetText("send_pattern").c_str());
++	//gSavedSettings.setString("DBPositivePattern", childGetText("positive_pattern").c_str());
++	//gSavedSettings.setString("DBNegativePattern", childGetText("negative_pattern").c_str());
++	//gSavedSettings.setString("DBDeniedPattern", childGetText("denied_pattern").c_str());	
++
++
++}
++
++void LLPanelDatabase::cancel()
++{
++	
++}
++
++//static
++void LLPanelDatabase::onClickChangeAvatar(void *userdata)
++{
++	LLFloaterAvatarPicker::show(onPickAvatar, userdata, FALSE, TRUE);
++}
++
++//static
++void LLPanelDatabase::onPickAvatar(const std::vector<std::string>& names,
++                                   const std::vector<LLUUID>& ids,
++                                   void* user_data)
++{
++	if (names.empty()) return;
++	if (ids.empty()) return;
++
++	LLPanelDatabase *self = (LLPanelDatabase*)user_data;
++
++#ifndef LL_DEBUG
++	// TODO: LL_DEBUG isn't the right one, what is it?
++	//
++	// Using yourself as the database avatar should work, and be useful
++	// for debugging, but it's not something a normal user should be able
++	// to do.
++	
++//	if(ids[0] == gAgentID)
++//	{
++//		LLNotifyBox::showXml("AddSelfDatabase");
++//		return;
++//	}
++#endif
++
++	self->childSetText("db_avatar", names[0]);
++	self->mAvatarName = names[0];
++	self->mAvatarKey = ids[0];
++}
++
++
+diff --git a/indra/newview/llpaneldatabase.h b/indra/newview/llpaneldatabase.h
+new file mode 100644
+index 0000000..e08a453
+--- /dev/null
++++ b/indra/newview/llpaneldatabase.h
+@@ -0,0 +1,65 @@
++/** 
++ * @file llprefschat.h
++ * @brief Database preferences panel
++ *
++ * Copyright (c) 2003-2007, Linden Research, Inc.
++ * 
++ * 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.
++ */
++
++#ifndef LLPREFSDB_H
++#define LLPREFSDB_H
++
++#include "llpanel.h"
++
++class LLPanelDatabase : public LLPanel
++{
++public:
++	LLPanelDatabase();
++	virtual ~LLPanelDatabase() {};
++
++	virtual BOOL postBuild();
++	virtual void draw();
++	virtual void refresh();
++
++	void apply();
++	void cancel();
++
++	static void onClickChangeAvatar(void *userdata);
++	static void onPickAvatar(const std::vector<std::string>& names,
++                                 const std::vector<LLUUID>& ids,
++                                 void* user_data);
++
++protected:
++	std::string mAvatarName;
++	LLUUID   mAvatarKey;
++	std::string mURL;
++	std::string mUsername;
++	std::string mPassword;
++	std::string mSendPattern;
++	std::string mPositivePattern;
++	std::string mNegativePattern;
++	std::string mDeniedPattern;
++
++};
++
++
++#endif // LL_PREFSDB_H
+diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
+index 5f25dc3..95e9f80 100644
+--- a/indra/newview/llstartup.cpp
++++ b/indra/newview/llstartup.cpp
+@@ -3034,7 +3034,7 @@ void register_viewer_callbacks(LLMessageSystem* msg)
+ 	msg->setHandlerFunc("ParcelDwellReply",
+ 		LLViewerParcelMgr::processParcelDwellReply);
+ 
+-	msg->setHandlerFunc("AvatarPropertiesReply",
++	msg->addHandlerFunc("AvatarPropertiesReply",
+ 						LLPanelAvatar::processAvatarPropertiesReply);
+ 	msg->setHandlerFunc("AvatarInterestsReply",
+ 						LLPanelAvatar::processAvatarInterestsReply);
+diff --git a/indra/newview/lltoolbar.cpp b/indra/newview/lltoolbar.cpp
+index 8202191..1d4c1b2 100644
+--- a/indra/newview/lltoolbar.cpp
++++ b/indra/newview/lltoolbar.cpp
+@@ -49,6 +49,7 @@
+ #include "llvoavatar.h"
+ #include "lltooldraganddrop.h"
+ #include "llinventoryview.h"
++#include "llfloateravatarlist.h"
+ #include "llfloaterchatterbox.h"
+ #include "llfloaterfriends.h"
+ #include "llfloatersnapshot.h"
+@@ -154,6 +155,9 @@ BOOL LLToolBar::postBuild()
+ 	childSetAction("inventory_btn", onClickInventory, this);
+ 	childSetControlName("inventory_btn", "ShowInventory");
+ 
++	childSetAction("avatar_list_btn", onClickAvatarList, this);
++	childSetControlName("inventory_btn", "ShowAvatarList");
++
+ 	for (child_list_const_iter_t child_iter = getChildList()->begin();
+ 		 child_iter != getChildList()->end(); ++child_iter)
+ 	{
+@@ -527,3 +531,8 @@ void LLToolBar::onClickInventory(void*)
+ 	handle_inventory(NULL);
+ }
+ 
++// static
++void LLToolBar::onClickAvatarList(void*)
++{
++	LLFloaterAvatarList::toggle(NULL);
++}
+diff --git a/indra/newview/lltoolbar.h b/indra/newview/lltoolbar.h
+index 720b9c0..b8f8c78 100644
+--- a/indra/newview/lltoolbar.h
++++ b/indra/newview/lltoolbar.h
+@@ -82,6 +82,7 @@ public:
+ 	static void onClickRadar(void* data);
+ 	static void onClickMap(void* data);
+ 	static void onClickInventory(void* data);
++	static void onClickAvatarList(void* data);
+ 
+ 	static F32 sInventoryAutoOpenTime;
+ 
+diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
+index 023c758..fb198d1 100644
+--- a/indra/newview/llviewermenu.cpp
++++ b/indra/newview/llviewermenu.cpp
+@@ -201,6 +201,7 @@
+ #include "pipeline.h"
+ #include "llappviewer.h"
+ #include "roles_constants.h"
++#include "llfloateravatarlist.h"
+ #include "llviewerjoystick.h"
+ #include "llwlanimator.h"
+ #include "llwlparammanager.h"
+@@ -5269,6 +5270,10 @@ class LLShowFloater : public view_listener_t
+ 		{
+ 			LLFloaterAbout::show(NULL);
+ 		}
++		else if (floater_name == "avatar list")
++		{
++			LLFloaterAvatarList::toggle(NULL);
++		}
+ 		else if (floater_name == "active speakers")
+ 		{
+ 			LLFloaterActiveSpeakers::toggleInstance(LLSD());
+@@ -7415,6 +7420,15 @@ static void addMenu(view_listener_t *menu, const std::string& name)
+ 	menu->registerListener(gMenuHolder, name);
+ }
+ 
++class LLViewAvatarList : public view_listener_t
++{
++	bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
++	{
++		llinfos << "LLViewAvatarList::handleEvent()" << llendl;
++		return true;
++	}
++};
++
+ void initialize_menus()
+ {
+ 	// File menu
+diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
+index 461a598..03b0a97 100644
+--- a/indra/newview/llviewermessage.cpp
++++ b/indra/newview/llviewermessage.cpp
+@@ -135,6 +135,9 @@
+ #include "llviewerdisplay.h"
+ #include "llkeythrottle.h"
+ 
++#include "llpanelavatar.h"
++#include "llfloateravatarlist.h"
++
+ #include <boost/tokenizer.hpp>
+ 
+ #if LL_WINDOWS // For Windows specific error handler
+diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
+index 340f279..059a877 100644
+--- a/indra/newview/llviewerobject.h
++++ b/indra/newview/llviewerobject.h
+@@ -598,8 +598,9 @@ protected:
+ 	TPACKETID		mLatestRecvPacketID;			// Latest time stamp on message from simulator
+ 	// extra data sent from the sim...currently only used for tree species info
+ 	U8* mData;
+-
++public:
+ 	LLPointer<LLViewerPartSourceScript>		mPartSourcep;	// Particle source associated with this object.
++protected:
+ 	LLAudioSourceVO* mAudioSourcep;
+ 	F32				mAudioGain;
+ 	
+diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
+index 1a9a208..e20bce9 100644
+--- a/indra/newview/llviewerwindow.cpp
++++ b/indra/newview/llviewerwindow.cpp
+@@ -106,6 +106,7 @@
+ #include "llfloatersnapshot.h"
+ #include "llfloatertools.h"
+ #include "llfloaterworldmap.h"
++#include "llfloateravatarlist.h"
+ #include "llfocusmgr.h"
+ #include "llframestatview.h"
+ #include "llgesturemgr.h"
+@@ -1866,9 +1867,14 @@ void LLViewerWindow::initWorldUI()
+ 		gMorphView->setVisible(FALSE);
+ 
+ 		// *Note: this is where gFloaterMute used to be initialized.
+-
++		gFloaterAvatarList = NULL;
+ 		LLWorldMapView::initClass();
+ 
++		gFloaterAvatarList = new LLFloaterAvatarList();
++		gFloaterAvatarList->setVisible(FALSE);
++
++		LLWorldMapView::initClass();
++		
+ 		adjust_rect_centered_partial_zoom("FloaterWorldMapRect2", full_window);
+ 
+ 		gFloaterWorldMap = new LLFloaterWorldMap();
+diff --git a/indra/newview/llwebbrowserctrl.h b/indra/newview/llwebbrowserctrl.h
+index e4ecea7..13332cf 100644
+--- a/indra/newview/llwebbrowserctrl.h
++++ b/indra/newview/llwebbrowserctrl.h
+@@ -32,6 +32,8 @@
+ #ifndef LL_LLWEBBROWSERCTRL_H
+ #define LL_LLWEBBROWSERCTRL_H
+ 
++#include "lluictrlfactory.h"
++
+ ////////////////////////////////////////////////////////////////////////////////
+ // data class that is passed with an event
+ class LLWebBrowserCtrlEvent
+diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
+index 13d8d09..9cc95d1 100644
+--- a/indra/newview/pipeline.cpp
++++ b/indra/newview/pipeline.cpp
+@@ -78,6 +78,7 @@
+ #include "llviewerimagelist.h"
+ #include "llviewerobject.h"
+ #include "llviewerobjectlist.h"
++#include "llviewerpartsource.h"
+ #include "llviewerparcelmgr.h"
+ #include "llviewerregion.h" // for audio debugging.
+ #include "llviewerwindow.h" // For getSpinAxis
+@@ -92,6 +93,7 @@
+ #include "llvopartgroup.h"
+ #include "llworld.h"
+ #include "llcubemap.h"
++#include "llfloateravatarlist.h"
+ #include "lldebugmessagebox.h"
+ #include "llviewershadermgr.h"
+ #include "llviewerjoystick.h"
+@@ -2009,6 +2011,27 @@ void renderSoundHighlights(LLDrawable* drawablep)
+ 	}
+ }
+ 
++/**
++ * @brief Add particle sources to avatar list
++ * This tells the avatar list floater who is emitting particles
++ */
++void addParticleSourcesToList(LLDrawable *drawablep)
++{
++	if ( NULL != gFloaterAvatarList )
++	{
++		LLViewerObject *vobj = drawablep->getVObj();
++		if (vobj && vobj->isParticleSource())
++		{
++			LLUUID id = vobj->mPartSourcep->getOwnerUUID();
++			LLAvatarListEntry *ent = gFloaterAvatarList->getAvatarEntry(id);
++			if ( NULL != ent )
++			{
++				ent->setActivity(ACTIVITY_PARTICLES);
++			}
++		}
++	}
++}
++
+ void LLPipeline::postSort(LLCamera& camera)
+ {
+ 	LLMemType mt(LLMemType::MTYPE_PIPELINE);
+@@ -2109,6 +2132,8 @@ void LLPipeline::postSort(LLCamera& camera)
+ 		std::sort(sCull->beginAlphaGroups(), sCull->endAlphaGroups(), LLSpatialGroup::CompareDepthGreater());
+ 	}
+ 
++	forAllVisibleDrawables(addParticleSourcesToList);
++
+ 	// only render if the flag is set. The flag is only set if we are in edit mode or the toggle is set in the menus
+ 	if (gSavedSettings.getBOOL("BeaconAlwaysOn"))
+ 	{
+@@ -2157,6 +2182,23 @@ void LLPipeline::postSort(LLCamera& camera)
+ 		}
+ 	}
+ 
++	// Avatar list support
++	if ( gFloaterAvatarList && gAudiop )
++	{
++		LLAudioEngine::source_map::iterator iter;
++		for (iter = gAudiop->mAllSources.begin(); iter != gAudiop->mAllSources.end(); ++iter)
++		{
++			LLAudioSource *sourcep = iter->second;
++			LLUUID uuid = sourcep->getOwnerID();
++			LLAvatarListEntry *ent = gFloaterAvatarList->getAvatarEntry(uuid);
++
++			if ( ent )
++			{
++				ent->setActivity(ACTIVITY_SOUND);
++			}
++		}
++	}
++
+ 	// If managing your telehub, draw beacons at telehub and currently selected spawnpoint.
+ 	if (LLFloaterTelehub::renderBeacons())
+ 	{
+diff --git a/indra/newview/skins/default/xui/en-us/alerts.xml b/indra/newview/skins/default/xui/en-us/alerts.xml
+index ff7a99c..18c0f9c 100644
+--- a/indra/newview/skins/default/xui/en-us/alerts.xml
++++ b/indra/newview/skins/default/xui/en-us/alerts.xml
+@@ -1374,6 +1374,23 @@ chat, or interact with the world.
+ 			Cancel
+ 		</option>
+ 	</alert>
++	<alert modal="true" name="AvatarListFreezeAvatars">
++		<message name="message">
++			Freeze these avatars?
++			[NAMES]
++			They will temporarily be unable to move,
++			chat, or interact with the world.
++		</message>
++		<option name="Freeze">
++			Freeze
++		</option>
++		<option name="Unfreeze">
++			Unfreeze
++		</option>
++		<option name="Cancel">
++			Cancel
++		</option>
++	</alert>	
+ 	<alert modal="true" name="EjectAvatar">
+ 		<message name="message">
+ 			Eject this avatar from your land?
+@@ -1402,6 +1419,52 @@ chat, or interact with the world.
+ 			Cancel
+ 		</option>
+ 	</alert>
++	<alert modal="true" name="AvatarListEjectAvatars">
++		<message name="message">
++			Eject these avatars from your land?
++			[NAMES]
++		</message>
++		<option name="Eject">
++			Eject
++		</option>
++		<option name="EjectandBan">
++			Eject and Ban
++		</option>
++		<option name="Cancel">
++			Cancel
++		</option>
++	</alert>
++	<alert modal="true" name="AvatarListEjectAvatarsFromEstate">
++		<message name="message">
++			Eject these avatars from this estate?
++			[NAMES]
++		</message>
++		<option name="Eject">
++			Eject
++		</option>
++		<option name="EjectandBan">
++			Eject and Ban
++		</option>
++		<option name="Cancel">
++			Cancel
++		</option>
++	</alert>
++	
++	<alert modal="true" name="AvatarListMuteAvatars">
++		<message name="message">
++			Mute these avatars?
++			[NAMES]
++		</message>
++		<option name="Mute">
++			Mute
++		</option>
++		<option name="Unmute">
++			Unmute
++		</option>		
++		<option name="Cancel">
++			Cancel
++		</option>
++	</alert>	
+     <alert modal="true" name="EjectAvatarNoBan">
+         <message name="message">
+             Eject this avatar from your land?
+@@ -4911,6 +4974,78 @@ they are part of an attachment.
+ 			No
+ 		</option>
+ 	</alert>
++	<!-- Luskwood functionality -->
++	<alert modal="true" name="LuskwoodGohomerWarn">
++		<message name="message">
++			Warn this avatar?
++			
++			This will show them a dialog asking to confirm that they understand
++			their behavior was found to be undesirable, and that they face
++			ejection or banning if it continues.
++		</message>
++		<option name="Warn">
++			Warn
++		</option>
++		<option default="true" name="Cancel">
++			Cancel
++		</option>
++	</alert>
++	<alert modal="true" name="LuskwoodGohomerEject">
++		<message name="message">
++			Eject this avatar?
++			
++			This avatar will be ejected from the area, but will be able to
++			return immediately.
++		</message>
++		<option name="Eject">
++			Eject
++		</option>
++		<option default="true" name="Cancel">
++			Cancel
++		</option>
++	</alert>
++	<alert modal="true" name="LuskwoodGohomerKeepAway">
++		<message name="message">
++			Eject this avatar and ban them for 2 hours?
++			
++			This avatar will be ejected from the area, and will be added to
++			the parcel's ban list for 2 hours.
++		</message>
++		<option name="KeepAway">
++			Keep Away
++		</option>
++		<option default="true" name="Cancel">
++			Cancel
++		</option>
++	</alert>
++	<alert modal="true" name="LuskwoodGohomerSendHome">
++		<message name="message">
++			Send this avatar home and ban them for 4 hours?
++			
++			This avatar will be sent home, and will be added to the parcel's
++			ban list for 4 hours.
++		</message>
++		<option name="KeepAway">
++			Send Home
++		</option>
++		<option default="true" name="Cancel">
++			Cancel
++		</option>
++	</alert>
++	<alert modal="true" name="LuskwoodGohomerOff">
++		<message name="message">
++			Turn off the gohomer?
++			
++			This will make it stop trying to send the last ejected avatar home,
++			but won't remove them from the ban list.
++		</message>
++		<option name="TurnOff">
++			Turn Off
++		</option>
++		<option default="true" name="Cancel">
++			Cancel
++		</option>
++	</alert>	
+ 	<alert modal="true" name="BadURL">
+ 		<message name="message">
+ 			Second Life doesn&apos;t know how to handle the link:
+diff --git a/indra/newview/skins/default/xui/en-us/floater_avatar_scanner.xml b/indra/newview/skins/default/xui/en-us/floater_avatar_scanner.xml
+new file mode 100644
+index 0000000..7156aa4
+--- /dev/null
++++ b/indra/newview/skins/default/xui/en-us/floater_avatar_scanner.xml
+@@ -0,0 +1,413 @@
++<?xml version="1.0" encoding="utf-8" standalone="yes"?>
++<floater
++	name="avatar list"
++	title="Avatar List"
++	can_resize="true"
++	can_minimize="true"
++	can_close="true"
++	can_drag_on_left="false"
++	rect_control="FloaterAvatarListRect"
++	min_width="400"
++	min_height="300"
++	>
++	<!-- <text
++		  name="help_label"
++		  bottom="-30"
++		  left="15"
++		  font="SansSerifSmall"
++		  follows="top|left"
++		  >
++	</text> -->
++	
++	<scroll_list
++		    name="avatar_list"
++		    left="10"
++		    right="-10"
++		    top="-20"
++		    bottom="150"
++		    column_padding="0"
++		    can_resize="true"
++		    follows="left|top|bottom|right"
++		    draw_heading="true"
++		    multi_select="true"
++		    search_column="1"
++		    tool_tip="Hold shift or control while clicking to select multiple avatars"
++		    >
++		<!-- Icons relating to the avatar, currently: tracking, and marked -->
++		<column name="avatar_icon" label="Icon" width="20" />
++		<column name="avatar_name" label="Name" dynamicwidth="true" />
++		<column name="distance" label="Distance" width="70"/>
++		<column name="age" label="Age" width="50"/>
++		<!-- <column name="payment_data" label="Payment" width="80"/> -->
++		<!-- TrustNet Score -->
++		<!-- <column name="score" label="Score" width="10"/> -->
++		<!-- Payment data icons -->
++		<column name="payment_data" label="" width="20" />
++		<!-- What the avatar is doing: producing sounds, rezzing, particles, etc -->
++		<column name="activity" label="" width="20" />
++		<!-- Time when avatar entered -->
++		<column name="entered" label="Entered" width="60"/>
++	</scroll_list>
++<!--	<panel 
++	       name="scanner_options"
++	       left="10"
++	       right="-10"	
++	       height="45"
++	       bottom="140"	
++	       border="true"
++	       mouse_opaque="true"
++	       bevel_style="in"
++	       background_visible="true"
++	       background_opaque="true"
++	       follows="left|right|bottom"
++	       bg_opaque_color="0,0,0,0.3"
++	       bg_alpha_color="blue"
++	       can_resize="false"
++	>
++	
++	</panel> -->
++	
++	<tab_container border="false" bottom_delta="-130" height="120" left="10" mouse_opaque="false"
++		       name="actions_tab_container" tab_position="top" follows="left|right|bottom">
++		<panel border="true" bottom_delta="-130" follows="left|top|right|bottom" height="255"
++		       label="Avatar" left="1" mouse_opaque="true"
++		     name="actions_tab" width="398">
++			<!-- upper row -->
++			<button
++			       name="profile_btn"
++			       label="Profile"
++			       tool_tip="Show picture, groups, and other information"
++			       left="10"
++			       bottom_delta="-190"
++			       width="80"
++			       height="20"
++			       font="SansSerifSmall"
++			       follows="bottom|left"
++			       />
++			<button
++			       name="im_btn"
++			       label="IM"
++			       tool_tip="Open Instant Message session"
++			       left_delta="90"
++			       bottom_delta="0"
++			       width="80"
++			       height="20"
++			       font="SansSerifSmall"
++			       follows="bottom|left"
++			       />
++			
++
++			<!--middle row -->
++			<button
++			       name="track_btn"
++			       label="Track"
++			       tool_tip="Track this avatar's position"
++			       left="10"
++			       bottom_delta="-24"
++			       width="80"
++			       height="20"
++			       font="SansSerifSmall"
++			       follows="bottom|left"
++			       />
++			<button
++			       name="mark_btn"
++			       label="Mark"
++			       tool_tip="Mark this avatar in the list"
++			       left_delta="90"
++			       bottom_delta="0"
++			       width="80"
++			       height="20"
++			       font="SansSerifSmall"
++			       follows="bottom|left"
++			       />
++			<button
++			       name="get_key_btn"
++			       label="Get Key"
++			       tool_tip="Copies avatar's key to the clipboard"
++			       left_delta="90"
++			       bottom_delta="0"
++			       width="80"
++			       height="20"
++			       font="SansSerifSmall"
++			       follows="bottom|left"
++			       />
++			<button
++			       name="teleport_btn"
++			       label="Teleport"
++			       tool_tip="Teleport to avatar's position"
++			       left_delta="90"
++			       bottom_delta="0"
++			       width="80"
++			       height="20"
++			       font="SansSerifSmall"
++			       follows="bottom|left"
++			       />			
++			<!-- lower row-->
++			<button
++			       name="prev_in_list_btn"
++			       label="Prev"
++			       tool_tip="Focus camera on previous avatar in list"
++			       left="10"
++			       bottom_delta="-24"
++			       width="80"
++			       height="20"
++			       font="SansSerifSmall"
++			       follows="bottom|left"
++			       />
++			<button
++			       name="next_in_list_btn"
++			       label="Next"
++			       tool_tip="Focus camera on next avatar in list"
++			       left_delta="90"
++			       bottom_delta="0"
++			       width="80"
++			       height="20"
++			       font="SansSerifSmall"
++			       follows="bottom|left"
++			       />
++			<button
++			       name="prev_marked_btn"
++			       label="Prev Marked"
++			       tool_tip="Focus camera on previous marked avatar"
++			       left_delta="90"
++			       bottom_delta="0"
++			       width="80"
++			       height="20"
++			       font="SansSerifSmall"
++			       follows="bottom|left"
++			       />
++			<button
++			       name="next_marked_btn"
++			       label="Next Marked"
++			       tool_tip="Focus camera on next marked avatar"
++			       left_delta="90"
++			       bottom_delta="0"
++			       width="80"
++			       height="20"
++			       font="SansSerifSmall"
++			       follows="bottom|left"
++			       />
++
++		</panel>
++		<panel border="true" bottom_delta="-130" follows="left|top|right|bottom" height="255"
++		       label="Moderation" left="1" mouse_opaque="true"
++		       name="land_tab" width="398">
++			
++			<!-- Upper row -->
++			<button
++			       name="freeze_btn"
++			       label="Freeze"
++			       tool_tip="Freeze the avatar, preventing it from moving"
++			       left="10"
++			       bottom_delta="-190"
++			       width="80"
++			       height="20"
++			       font="SansSerifSmall"
++			       follows="bottom|left"
++			       />
++			<button
++			       name="eject_btn"
++			       label="Eject"
++			       tool_tip="Eject the avatar from the parcel"
++			       left_delta="90"
++			       bottom_delta="0"
++			       width="80"
++			       height="20"
++			       font="SansSerifSmall"
++			       follows="bottom|left"
++			       />
++			
++			<button
++			       name="mute_btn"
++			       label="Mute"
++			       tool_tip="Mute this avatar"
++			       left_delta="90"
++			       bottom_delta="0"
++			       width="80"
++			       height="20"
++			       font="SansSerifSmall"
++			       follows="bottom|left"
++			       />
++			
++
++			<button
++			       name="ar_btn"
++			       label="AR"
++			       tool_tip="Report abuse on this avatar"
++			       left_delta="90"
++			       bottom_delta="0"
++			       width="80"
++			       height="20"
++			       font="SansSerifSmall"
++			       follows="bottom|left"
++			       />
++
++			<!-- middle row -->
++			<button
++			       name="estate_eject_btn"
++			       label="Eject from estate"
++			       tool_tip="Eject this avatar from the estate"
++			       left="10"
++			       bottom_delta="-24"
++			       width="170"
++			       height="20"
++			       font="SansSerifSmall"
++			       follows="bottom|left"
++			       />
++		</panel>
++		
++		<panel border="true" bottom_delta="-130" follows="left|top|right|bottom" height="255"
++		       label="TrustNet" left="1" mouse_opaque="true"
++		       name="trustnet_tab" width="398">
++			<!--TrustNet tools -->
++			<!-- upper row -->
++			<button
++			       name="tn_rate_btn"
++			       label="Rate"
++			       tool_tip="Give a TrustNet rating to this avatar"
++			       left="10"
++			       bottom_delta="-190"
++			       width="80"
++			       height="20"
++			       font="SansSerifSmall"
++			       follows="bottom|left"
++			       />
++			<button
++			       name="tn_explain_btn"
++			       label="Explain"
++			       tool_tip="Explain this avatar's score"
++			       left="100"
++			       bottom_delta="0"
++			       width="80"
++			       height="20"
++			       font="SansSerifSmall"
++			       follows="bottom|left"
++			       />
++			<!--lower row-->
++			<button
++			       name="tn_website_btn"
++			       label="Web"
++			       tool_tip="Open a web browser with the TrustNet website"
++			       left="10"
++			       bottom_delta="-24"
++			       width="80"
++			       height="20"
++			       font="SansSerifSmall"
++			       follows="bottom|left"
++			       />
++			<button
++			       name="tn_password_btn"
++			       label="Password"
++			       tool_tip="Get a password for the TrustNet website. A new password is generated every time."
++			       left="100"
++			       bottom_delta="0"
++			       width="80"
++			       height="20"
++			       font="SansSerifSmall"
++			       follows="bottom|left"
++			       />
++			<button
++			       name="tn_renew_btn"
++			       label="Renew"
++			       tool_tip="Renew the TrustNet subscription"
++			       left="190"
++			       bottom_delta="0"
++			       width="80"
++			       height="20"
++			       font="SansSerifSmall"
++			       follows="bottom|left"
++			       />
++			
++		</panel>
++		<panel border="true" bottom_delta="-130" follows="left|top|right|bottom" height="255"
++		       label="Luskwood" left="1" mouse_opaque="true"
++		     name="luskwood_tab" width="398">
++			<!--Luskwood tools, upper row-->
++			<button
++			       name="gowarn_btn"
++			       label="Warn"
++			       tool_tip="Give a warning to this avatar"
++			       left="10"
++			       bottom_delta="-190"
++			       width="80"
++			       height="20"
++			       font="SansSerifSmall"
++			       follows="bottom|left"
++			       />
++			<button
++			       name="goeject_btn"
++			       label="Eject"
++			       tool_tip="Eject this avatar"
++			       left="100"
++			       bottom_delta="0"
++			       width="80"
++			       height="20"
++			       font="SansSerifSmall"
++			       follows="bottom|left"
++			       />
++			<button
++			       name="goaway_btn"
++			       label="Keep away"
++			       tool_tip="Eject, and keep this avatar away for 2 hours"
++			       left="190"
++			       bottom_delta="0"
++			       width="80"
++			       height="20"
++			       font="SansSerifSmall"
++			       follows="bottom|left"
++			       />
++			<button
++			       name="gohome_btn"
++			       label="Send home"
++			       tool_tip="Send home, and keep this avatar away for 4 hours"
++			       left="280"
++			       bottom_delta="0"
++			       width="80"
++			       height="20"
++			       font="SansSerifSmall"
++			       follows="bottom|left"
++			       />
++			<!-- Middle row -->
++			<button
++			       name="gokey_btn"
++			       label="Ban by key"
++			       tool_tip="Turn off the send home function"
++			       left="10"
++			       bottom_delta="-24"
++			       width="80"
++			       height="20"
++			       font="SansSerifSmall"
++			       follows="bottom|left"
++			       />
++			<button
++			       name="gohomeoff_btn"
++			       label="Off"
++			       tool_tip="Turn off the send home function"
++			       left_delta="90"
++			       bottom_delta="0"
++			       width="80"
++			       height="20"
++			       font="SansSerifSmall"
++			       follows="bottom|left"
++			       />			
++		</panel>
++		<panel border="true" bottom_delta="-150" follows="left|top|right|bottom" height="255"
++		       label="Options" left="1" mouse_opaque="true"
++		     name="options_tab" width="398">
++			<check_box height="16" label="Update"
++				   left="10" bottom_delta="-190" name="update_enabled_cb" 
++				   width="200" follows="bottom|left"
++				   hidden="false" mouse_opaque="true" font="SansSerifSmall"
++				   initial_value="true" enabled="true" radio_style="false" 
++				   tool_tip="Set whether the avatar list should update" />
++			
++			<check_box height="16" label="Get avatar info"
++				   left="20" bottom_delta="-21" name="fetch_avdata_enabled_cb" 
++				   width="200" follows="bottom|left"
++				   hidden="false" mouse_opaque="true" font="SansSerifSmall"
++				   initial_value="true" enabled="true" radio_style="false" 
++			   tool_tip="Set whether avatar information should be retrieved" />			
++		</panel>
++	</tab_container>
++
++</floater>
+diff --git a/indra/newview/skins/default/xui/en-us/menu_viewer.xml b/indra/newview/skins/default/xui/en-us/menu_viewer.xml
+index d2c4923..9971454 100644
+--- a/indra/newview/skins/default/xui/en-us/menu_viewer.xml
++++ b/indra/newview/skins/default/xui/en-us/menu_viewer.xml
+@@ -221,6 +221,13 @@
+ 		     mouse_opaque="true" name="Preferences..." shortcut="control|P" width="153">
+ 			<on_click function="ShowFloater" userdata="preferences" />
+ 		</menu_item_call>
++		<menu_item_separator bottom="-46" enabled="true" height="8" hidden="false" label="-----------"
++		     left="0" mouse_opaque="true" name="separator6" width="211" />
++		<menu_item_check bottom="-65" enabled="true" height="19" hidden="false" label="Avatar List" left="0" mouse_opaque="true" name="Avatar List" width="211">
++			<on_click function="ShowFloater" userdata="avatar list" />
++			<on_check function="FloaterVisible" userdata="avatar list" />
++		</menu_item_check>
++
+ 	</menu>
+ 	<menu bottom="-1" create_jump_keys="true" drop_shadow="true" enabled="true"
+ 	     height="537" label="View" left="80" mouse_opaque="false" name="View"
+@@ -398,6 +405,12 @@
+ 		     mouse_opaque="true" name="Set UI Size to Default" width="188">
+ 			<on_click function="View.DefaultUISize" userdata="" />
+ 		</menu_item_call>
++		<menu_item_separator bottom="-46" enabled="true" height="8" hidden="false" label="-----------"
++		     left="0" mouse_opaque="true" name="separator6" width="211" />
++		<menu_item_check bottom="-65" enabled="true" height="19" hidden="false" label="Avatar List" left="0" mouse_opaque="true" name="Avatar List" width="211">
++			<on_click function="ShowFloater" userdata="avatar list" />
++			<on_check function="FloaterVisible" userdata="avatar list" />
++		</menu_item_check>
+ 	</menu>
+ 	<menu bottom="-18" create_jump_keys="true" drop_shadow="true" enabled="true"
+ 	     height="339" label="World" left="0" mouse_opaque="false" name="World"
+diff --git a/indra/newview/skins/default/xui/en-us/notify.xml b/indra/newview/skins/default/xui/en-us/notify.xml
+index 63396af..cf0056b 100644
+--- a/indra/newview/skins/default/xui/en-us/notify.xml
++++ b/indra/newview/skins/default/xui/en-us/notify.xml
+@@ -915,6 +915,12 @@ You can find example sculpted textures in the inventory library.
+ from this list.
+ 		</message>
+ 	</notify>
++	<!--Database preferences panel -->
++	<notify name="AddSelfDatabase" tip="false">
++		<message name="message">
++			You cannot use yourself as the database avatar.
++		</message>
++	</notify>	
+ 	<notify name="VoiceInviteP2P" tip="false" unique="true">
+ 		<message name="message">
+ 			[NAME] is inviting you to a Voice Chat call. 
+diff --git a/indra/newview/skins/default/xui/en-us/panel_preferences_database.xml b/indra/newview/skins/default/xui/en-us/panel_preferences_database.xml
+new file mode 100644
+index 0000000..314b02d
+--- /dev/null
++++ b/indra/newview/skins/default/xui/en-us/panel_preferences_database.xml
+@@ -0,0 +1,166 @@
++<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
++<panel border="true" bottom="-409" enabled="true" follows="left|top|right|bottom"
++       height="408" hidden="false" label="Database" left="102" mouse_opaque="true"
++       name="avatar_db" width="517">
++	
++	<!-- Options section -->
++	<text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
++	      bottom="-30" drop_shadow_visible="true" enabled="true" follows="left|top"
++	      font="SansSerifSmall" h_pad="0" halign="left" height="10" hidden="false"
++	      left="12" mouse_opaque="false" name="text_box" v_pad="0" width="300">
++		Options:
++	</text>
++
++	<check_box bottom_delta="0" control_name="DBEnabled" enabled="true"
++		   follows="left|top" font="SansSerifSmall" height="16" hidden="false"
++		   initial_value="false" label="Database enabled" left="148"
++		   mouse_opaque="true" name="database_enabled_cb" radio_style="false"
++	     width="256" />
++	
++	<radio_group bottom_delta="-110" control_name="DBRetrievalMode" draw_border="true" enabled="true"
++		     follows="left|top" height="100" hidden="false" left="148"
++		     mouse_opaque="true" name="Database access type" width="321">
++		<radio_item type="string" length="1" bottom="-20" enabled="true" follows="left|top" height="16" hidden="false"
++			    left="3" mouse_opaque="true" name="UseAvatar" width="315">
++			Avatar:
++		</radio_item>
++		<radio_item type="string" length="1" bottom_delta="-10" enabled="false" follows="left|top" height="16" hidden="false"
++			    left="3" mouse_opaque="true" name="UseURL" width="315">
++			URL:
++		</radio_item>
++	</radio_group>
++	
++	<!-- HACK: apparently line_editor can't go inside a radio_group, so we make it appear
++	     inside while not actually being in there -->
++	<button bottom_delta="78" follows="right|bottom" font="SansSerif" halign="center"
++		height="20" label="Change Avatar" label_selected="Change Avatar" left="260"
++	     mouse_opaque="true" name="change_avatar_btn" width="100" />
++	
++	<line_editor bevel_style="in" border_style="line" border_thickness="1" bottom_delta="0"
++		     follows="left|top|right" font="SansSerifSmall" height="16" hidden="false"
++		     left="348" max_length="254" mouse_opaque="true" name="db_avatar"
++		     select_on_focus="false" width="130" control_name="DBAvatar" enabled="false"/>
++	
++	<line_editor bevel_style="in" border_style="line" border_thickness="1" bottom_delta="-20"
++		     follows="left|top|right" font="SansSerifSmall" height="16" hidden="false"
++		     left="248" max_length="254" mouse_opaque="true" name="db_url"
++		     select_on_focus="false" width="230" enabled="false" control_name="DBURL" />	
++
++	<text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
++	      bottom_delta="-20" drop_shadow_visible="true" enabled="true" follows="left|top"
++	      font="SansSerifSmall" h_pad="0" halign="left" height="10" hidden="false"
++	      left="170" mouse_opaque="false" name="text_box" v_pad="0" width="300">
++		Username:
++	</text>	
++
++	<line_editor bevel_style="in" border_style="line" border_thickness="1" bottom_delta="0"
++		     follows="left|top|right" font="SansSerifSmall" height="16" hidden="false"
++		     left="248" max_length="254" mouse_opaque="true" name="db_url_username"
++		     select_on_focus="false" width="230" enabled="false" control_name="DBURLUsername" />
++	
++	<text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
++	      bottom_delta="-20" drop_shadow_visible="true" enabled="true" follows="left|top"
++	      font="SansSerifSmall" h_pad="0" halign="left" height="10" hidden="false"
++	      left="170" mouse_opaque="false" name="text_box" v_pad="0" width="300">
++		Password:
++	</text>	
++
++	<line_editor bevel_style="in" border_style="line" border_thickness="1" bottom_delta="0"
++		     follows="left|top|right" font="SansSerifSmall" height="16" hidden="false"
++		     left="248" max_length="254" mouse_opaque="true" name="db_url_password"
++		     select_on_focus="false" width="230" enabled="false" control_name="DBURLPassword" />
++
++	
++	<!--Patterns section-->
++	<text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
++	      bottom_delta="-30" drop_shadow_visible="true" enabled="true" follows="left|top"
++	      font="SansSerifSmall" h_pad="0" halign="left" height="10" hidden="false"
++	      left="12" mouse_opaque="false" name="text_box" v_pad="0" width="300">
++		Patterns:
++	</text>
++	
++
++	<text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
++	      bottom_delta="-20" drop_shadow_visible="true" enabled="true" follows="left|top"
++	      font="SansSerifSmall" h_pad="0" halign="left" height="10" hidden="false"
++	      left="148" mouse_opaque="false" name="text_box2" v_pad="0" width="300">
++		Send:
++	</text>
++	
++	<line_editor bevel_style="in" border_style="line" border_thickness="1" bottom_delta="0"
++		     follows="left|top|right" font="SansSerifSmall" height="16" hidden="false"
++		     left="248" max_length="254" mouse_opaque="true" name="send_pattern"
++		     select_on_focus="false" width="230" control_name="DBSendPattern" >
++		$NAME
++	</line_editor>
++
++	<text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
++	      bottom_delta="-20" drop_shadow_visible="true" enabled="true" follows="left|top"
++	      font="SansSerifSmall" h_pad="0" halign="left" height="10" hidden="false"
++	      left="148" mouse_opaque="false" name="text_box2" v_pad="0" width="300">
++		Positive contains:
++	</text>
++	
++	<line_editor bevel_style="in" border_style="line" border_thickness="1" bottom_delta="0"
++		     follows="left|top|right" font="SansSerifSmall" height="16" hidden="false"
++		     left="248" max_length="254" mouse_opaque="true" name="positive_pattern"
++		     select_on_focus="false" width="230"  control_name="DBPositivePattern" />
++	
++	
++	<text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
++	      bottom_delta="-20" drop_shadow_visible="true" enabled="true" follows="left|top"
++	      font="SansSerifSmall" h_pad="0" halign="left" height="10" hidden="false"
++	      left="148" mouse_opaque="false" name="text_box2" v_pad="0" width="300">
++		Negative contains:
++	</text>
++	
++	<line_editor bevel_style="in" border_style="line" border_thickness="1" bottom_delta="0"
++		     follows="left|top|right" font="SansSerifSmall" height="16" hidden="false"
++		     left="248" max_length="254" mouse_opaque="true" name="negative_pattern"
++		     select_on_focus="false" width="230"  control_name="DBNegativePattern" />
++	
++	
++	<text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
++	      bottom_delta="-20" drop_shadow_visible="true" enabled="true" follows="left|top"
++	      font="SansSerifSmall" h_pad="0" halign="left" height="10" hidden="false"
++	      left="148" mouse_opaque="false" name="text_box2" v_pad="0" width="300">
++		Denied contains:
++	</text>
++	
++	<line_editor bevel_style="in" border_style="line" border_thickness="1" bottom_delta="0"
++		     follows="left|top|right" font="SansSerifSmall" height="16" hidden="false"
++		     left="248" max_length="254" mouse_opaque="true" name="denied_pattern"
++		     select_on_focus="false" width="230"  control_name="DBDeniedPattern" />
++	
++	<!--Timeouts section-->
++	<text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
++	      bottom_delta="-30" drop_shadow_visible="true" enabled="true" follows="left|top"
++	      font="SansSerifSmall" h_pad="0" halign="left" height="10" hidden="false"
++	      left="12" mouse_opaque="false" name="text_box" v_pad="0" width="300">
++		Timeouts:
++	</text>
++		
++	<spinner bottom_delta="-20" control_name="DBMaxConcurrentRequests" decimal_digits="0" enabled="true"
++		 follows="left|top" height="16" hidden="false" increment="1"
++		 initial_val="4" label="Max concurrent requests:" label_width="138" left="148"
++		 max_val="32" min_val="1" mouse_opaque="true" name="max_concurrent_requests"
++		 width="202" />
++
++	<spinner bottom_delta="-20" control_name="DBDelayBetweenRequests" decimal_digits="0" enabled="true"
++		 follows="left|top" height="16" hidden="false" increment="1"
++		 initial_val="1" label="Delay between requests:" label_width="138" left="148"
++		 max_val="32" min_val="0" mouse_opaque="true" name="delay_between_requests"
++		 width="202" />
++	
++	<spinner bottom_delta="-20" control_name="DBRequestTimeout" decimal_digits="0" enabled="true"
++		 follows="left|top" height="16" hidden="false" increment="4"
++		 initial_val="64" label="Request timeout:" label_width="138" left="148"
++		 max_val="65536" min_val="16" mouse_opaque="true" name="request_timeout"
++		 width="202" />
++	
++	<spinner bottom_delta="-20" control_name="DBGiveUpAfter" decimal_digits="0" enabled="true"
++		 follows="left|top" height="16" hidden="false" increment="64"
++		 initial_val="4096" label="Give up after:" label_width="138" left="148"
++		 max_val="65536" min_val="64" mouse_opaque="true" name="give_up_after"
++		 width="202" />
++</panel>
+\ No newline at end of file
+diff --git a/indra/newview/skins/default/xui/en-us/panel_toolbar.xml b/indra/newview/skins/default/xui/en-us/panel_toolbar.xml
+index 9c57be0..b264e6e 100644
+--- a/indra/newview/skins/default/xui/en-us/panel_toolbar.xml
++++ b/indra/newview/skins/default/xui/en-us/panel_toolbar.xml
+@@ -18,6 +18,12 @@
+ 	       list_position="above"
+ 	       width="50" follows="left|right" user_resize="false"/>
+     <icon image_name="spacer24.tga" width="2" height="2" follows="left|right" auto_resize="false" color="0,0,0,0"/>
++ 	<button bottom="0" font="SansSerif" height="24" label="Avatars" left="0"
++ 	     name="avatar_list_btn" tool_tip="List of nearby avatars" width="50" 
++         image_selected="toolbar_btn_selected.tga" 
++         image_unselected="toolbar_btn_enabled.tga" scale_image="true"
++		 follows="left|right" user_resize="false" />	
++    <icon image_name="spacer24.tga" width="2" height="2" follows="left|right" auto_resize="false" color="0,0,0,0"/>
+     <button bottom="0" font="SansSerif" height="24" label="Fly"
+         image_overlay="icn_toolbar_fly.tga" image_overlay_alignment="left"
+                         image_selected="toolbar_btn_selected.tga"
+@@ -68,3 +74,4 @@
+   </layout_stack>
+ 
+ </panel>
++
+-- 
+tg: (747e686..) topic/features/jira-backported/avatar_list (depends on: master)
diff --git a/debian/patches/topic/features/jira-sent/24_always_test_vectorize.diff b/debian/patches/topic/features/jira-sent/24_always_test_vectorize.diff
new file mode 100644
index 0000000..07aef39
--- /dev/null
+++ b/debian/patches/topic/features/jira-sent/24_always_test_vectorize.diff
@@ -0,0 +1,39 @@
+From: Robin Cornelius <robin.cornelius at gmail.com>
+Subject: [PATCH] topic/features/jira-sent/24_always_test_vectorize
+
+Always test to see if CPU has sse/altivect expernsions, regardless of compile host.
+
+Signed-off-by: Robin Cornelius <robin.cornelius at gmail.com>
+
+---
+ indra/newview/llappviewer.cpp |    8 --------
+ 1 files changed, 0 insertions(+), 8 deletions(-)
+
+diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
+index 09d1141..e5db7e9 100644
+--- a/indra/newview/llappviewer.cpp
++++ b/indra/newview/llappviewer.cpp
+@@ -416,7 +416,6 @@ static void settings_modify()
+ 	gDebugGL = gSavedSettings.getBOOL("RenderDebugGL");
+ 	gDebugPipeline = gSavedSettings.getBOOL("RenderDebugPipeline");
+ 	
+-#if LL_VECTORIZE
+ 	if (gSysCPU.hasAltivec())
+ 	{
+ 		gSavedSettings.setBOOL("VectorizeEnable", TRUE );
+@@ -442,13 +441,6 @@ static void settings_modify()
+ 		gSavedSettings.setU32("VectorizeProcessor", 0 );
+ 		gSavedSettings.setBOOL("VectorizeSkin", FALSE);
+ 	}
+-#else
+-	// This build target doesn't support SSE, don't test/run.
+-	gSavedSettings.setBOOL("VectorizePerfTest", FALSE );
+-	gSavedSettings.setBOOL("VectorizeEnable", FALSE );
+-	gSavedSettings.setU32("VectorizeProcessor", 0 );
+-	gSavedSettings.setBOOL("VectorizeSkin", FALSE);
+-#endif
+ }
+ 
+ void LLAppViewer::initGridChoice()
+-- 
+tg: (1836a2b..) topic/features/jira-sent/24_always_test_vectorize (depends on: upstream)
diff --git a/debian/patches/topic/features/jira-sent/VWR-12678_add_crash_to_core_option.diff b/debian/patches/topic/features/jira-sent/VWR-12678_add_crash_to_core_option.diff
new file mode 100644
index 0000000..0c99383
--- /dev/null
+++ b/debian/patches/topic/features/jira-sent/VWR-12678_add_crash_to_core_option.diff
@@ -0,0 +1,111 @@
+From: Robin Cornelius <robin.cornelius at gmail.com>
+Subject: [PATCH] topic/features/jira-sent/VWR-12678_add_crash_to_core_option
+
+Allow crash to core instead of starting crashlogger
+
+Signed-off-by: Robin Cornelius <robin.cornelius at gmail.com>
+
+---
+ doc/contributions.txt                   |    1 +
+ indra/llcommon/llapp.cpp                |   12 ++++++++++++
+ indra/llcommon/llapp.h                  |    1 +
+ indra/newview/app_settings/cmd_line.xml |    8 ++++++++
+ indra/newview/llappviewer.cpp           |   10 ++++++++++
+ 5 files changed, 32 insertions(+), 0 deletions(-)
+
+diff --git a/doc/contributions.txt b/doc/contributions.txt
+index 5cc26c2..add58eb 100644
+--- a/doc/contributions.txt
++++ b/doc/contributions.txt
+@@ -340,6 +340,7 @@ Renault Clio
+ 	VWR-1976
+ Robin Cornelius
+ 	VWR-2488
++	VWR-12678
+ Ryozu Kojima
+ 	VWR-287
+ Sammy Frederix
+diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp
+index 6406d12..391055a 100644
+--- a/indra/llcommon/llapp.cpp
++++ b/indra/llcommon/llapp.cpp
+@@ -75,6 +75,9 @@ LLApp* LLApp::sApplication = NULL;
+ //static
+ BOOL LLApp::sLogInSignal = FALSE;
+ 
++//Allows the generation of core files for post mortum under gdb
++BOOL LLApp::sGenerateCores = FALSE; 
++
+ // static
+ LLApp::EAppStatus LLApp::sStatus = LLApp::APP_STATUS_STOPPED; // Keeps track of application status
+ LLAppErrorHandler LLApp::sErrorHandler = NULL;
+@@ -705,6 +708,15 @@ void default_unix_signal_handler(int signum, siginfo_t *info, void *)
+ 				llwarns << "Signal handler - Flagging error status and waiting for shutdown" << llendl;
+ 			}
+ 			// Flag status to ERROR, so thread_error does its work.
++			
++			if(LLApp::sGenerateCores)	//Don't gracefully handle any signals crash and core for a gdb post mortum
++			{
++				clear_signals();
++				llwarns << "Fatal signal recieved, not handling the crash here, passing back to operating system" << llendl;
++				raise(signum);
++				return;
++			}		
++
+ 			LLApp::setError();
+ 			// Block in the signal handler until somebody says that we're done.
+ 			while (LLApp::sErrorThreadRunning && !LLApp::isStopped())
+diff --git a/indra/llcommon/llapp.h b/indra/llcommon/llapp.h
+index b5e72f5..1620ad8 100644
+--- a/indra/llcommon/llapp.h
++++ b/indra/llcommon/llapp.h
+@@ -282,6 +282,7 @@ private:
+ 
+ public:
+ 	static BOOL sLogInSignal;
++	static BOOL sGenerateCores; // Generate a core on a crash rather than the signal handler crash logger route;
+ };
+ 
+ #endif // LL_LLAPP_H
+diff --git a/indra/newview/app_settings/cmd_line.xml b/indra/newview/app_settings/cmd_line.xml
+index db665b7..813830c 100644
+--- a/indra/newview/app_settings/cmd_line.xml
++++ b/indra/newview/app_settings/cmd_line.xml
+@@ -331,6 +331,14 @@
+       <string>Crashes on startup. For QA use.</string>
+       <key>map-to</key>
+       <string>CrashOnStartup</string>
++    </map>
++
++    <key>coreoncrash</key>
++    <map>
++      <key>desc</key>
++      <string>Disables the crash logger and creates a core file in the event of a crash</string>
++      <key>map-to</key>
++      <string>CoreOnCrash</string>
+     </map>
+ 
+   </map>
+diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
+index 09d1141..61c0230 100644
+--- a/indra/newview/llappviewer.cpp
++++ b/indra/newview/llappviewer.cpp
+@@ -1735,6 +1735,16 @@ bool LLAppViewer::initConfiguration()
+ 	// - apply command line settings 
+ 	clp.notify(); 
+ 
++	// Register the core crash option as soon as we can
++	// if we want gdb post-mortum on cores we need to be up and running
++	// ASAP or we might miss init issue etc.
++	
++	if(clp.hasOption("coreoncrash"))
++	{
++		llwarns << "Crashes will be handled by system, stack trace logs and crash logger are both disabled" <<llendl;
++		sGenerateCores=true;
++	}
++
+ 	// Handle initialization from settings.
+ 	// Start up	the	debugging console before handling other	options.
+ 	if (gSavedSettings.getBOOL("ShowConsoleWindow"))
+-- 
+tg: (1836a2b..) topic/features/jira-sent/VWR-12678_add_crash_to_core_option (depends on: upstream)
diff --git a/debian/patches/topic/fixes/jira-backported/VWR-11103-FIx_local_ruler_on_linked_objects.diff b/debian/patches/topic/fixes/jira-backported/VWR-11103-FIx_local_ruler_on_linked_objects.diff
new file mode 100644
index 0000000..5e06c69
--- /dev/null
+++ b/debian/patches/topic/fixes/jira-backported/VWR-11103-FIx_local_ruler_on_linked_objects.diff
@@ -0,0 +1,28 @@
+From: Robin Cornelius <robin.cornelius at gmail.com>
+Subject: [PATCH] topic/fixes/jira-backported/VWR-11103-FIx_local_ruler_on_linked_objects
+
+<patch description>
+
+Signed-off-by: Robin Cornelius <robin.cornelius at gmail.com>
+
+---
+ indra/newview/llselectmgr.cpp |    4 ++++
+ 1 files changed, 4 insertions(+), 0 deletions(-)
+
+diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
+index 0f5a98a..139c210 100644
+--- a/indra/newview/llselectmgr.cpp
++++ b/indra/newview/llselectmgr.cpp
+@@ -5501,6 +5501,10 @@ void LLSelectMgr::updateSelectionCenter()
+ 
+ 		std::vector < LLViewerObject *> jointed_objects;
+ 
++		// Initialize the bounding box to the root prim, so the BBox orientation
++		// matches the root prim's (affecting the orientation of the manipulators).
++		bbox.addBBoxAgent( (mSelectedObjects->getFirstRootObject(TRUE))->getBoundingBoxAgent() );
++
+ 		for (LLObjectSelection::iterator iter = mSelectedObjects->begin();
+ 			 iter != mSelectedObjects->end(); iter++)
+ 		{
+-- 
+tg: (1836a2b..) topic/fixes/jira-backported/VWR-11103-FIx_local_ruler_on_linked_objects (depends on: upstream)
diff --git a/debian/patches/topic/fixes/jira-backported/VWR-11674_dont_download_muted_sounds.diff b/debian/patches/topic/fixes/jira-backported/VWR-11674_dont_download_muted_sounds.diff
new file mode 100644
index 0000000..793ed63
--- /dev/null
+++ b/debian/patches/topic/fixes/jira-backported/VWR-11674_dont_download_muted_sounds.diff
@@ -0,0 +1,62 @@
+From: Robin Cornelius <robin.cornelius at gmail.com>
+Subject: [PATCH] topic/fixes/jira-backported/VWR-11674_dont_download_muted_sounds
+
+<patch description>
+
+Signed-off-by: Robin Cornelius <robin.cornelius at gmail.com>
+
+---
+ indra/llaudio/audioengine.cpp     |    3 ++-
+ indra/newview/llviewermessage.cpp |    9 ++++++++-
+ 2 files changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/indra/llaudio/audioengine.cpp b/indra/llaudio/audioengine.cpp
+index c5bc367..2713de6 100644
+--- a/indra/llaudio/audioengine.cpp
++++ b/indra/llaudio/audioengine.cpp
+@@ -873,7 +873,8 @@ void LLAudioEngine::triggerSound(const LLUUID &audio_uuid, const LLUUID& owner_i
+ 	// Create a new source (since this can't be associated with an existing source.
+ 	//llinfos << "Localized: " << audio_uuid << llendl;
+ 
+-	if (mMuted)
++	//If we cannot hear it, dont even try to load the sound.
++	if (mMuted || gain == 0.0)
+ 	{
+ 		return;
+ 	}
+diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
+index 461a598..1e4d8d2 100644
+--- a/indra/newview/llviewermessage.cpp
++++ b/indra/newview/llviewermessage.cpp
+@@ -3285,6 +3285,10 @@ void process_sound_trigger(LLMessageSystem *msg, void **)
+ 	msg->getVector3Fast(_PREHASH_SoundData, _PREHASH_Position, pos_local);
+ 	msg->getF32Fast(_PREHASH_SoundData, _PREHASH_Gain, gain);
+ 
++	//If we have sounds muted, don't even try to load or trigger the sound.
++	if(gSavedSettings.getBOOL("MuteSounds") || gain == 0.0)
++		return;
++
+ 	// adjust sound location to true global coords
+ 	LLVector3d	pos_global = from_region_handle(region_handle);
+ 	pos_global.mdV[VX] += pos_local.mV[VX];
+@@ -3313,7 +3317,7 @@ void process_sound_trigger(LLMessageSystem *msg, void **)
+ 
+ void process_preload_sound(LLMessageSystem *msg, void **user_data)
+ {
+-	if (!gAudiop)
++	if (!gAudiop || gSavedSettings.getBOOL("MuteSounds"))
+ 	{
+ 		return;
+ 	}
+@@ -3359,6 +3363,9 @@ void process_attached_sound(LLMessageSystem *msg, void **user_data)
+ 	msg->getF32Fast(_PREHASH_DataBlock, _PREHASH_Gain, gain);
+ 	msg->getU8Fast(_PREHASH_DataBlock, _PREHASH_Flags, flags);
+ 
++	if(gSavedSettings.getBOOL("MuteSounds") || gain == 0.0)
++		return;
++
+ 	LLViewerObject *objectp = gObjectList.findObject(object_id);
+ 	if (!objectp)
+ 	{
+-- 
+tg: (1836a2b..) topic/fixes/jira-backported/VWR-11674_dont_download_muted_sounds (depends on: upstream)
diff --git a/debian/patches/topic/fixes/jira-backported/VWR-3766_llGetInventoryNumber_tooltip_missing_INVENTORY_ANIMATION.diff b/debian/patches/topic/fixes/jira-backported/VWR-3766_llGetInventoryNumber_tooltip_missing_INVENTORY_ANIMATION.diff
new file mode 100644
index 0000000..38ff492
--- /dev/null
+++ b/debian/patches/topic/fixes/jira-backported/VWR-3766_llGetInventoryNumber_tooltip_missing_INVENTORY_ANIMATION.diff
@@ -0,0 +1,26 @@
+From: Robin Cornelius <robin.cornelius at gmail.com>
+Subject: [PATCH] topic/fixes/jira-backported/VWR-3766_llGetInventoryNumber_tooltip_missing_INVENTORY_ANIMATION
+
+Apply correct tooltips for script editing, adding some missing defines
+
+Signed-off-by: Robin Cornelius <robin.cornelius at gmail.com>
+
+---
+ indra/lscript/lscript_library/lscript_library.cpp |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/indra/lscript/lscript_library/lscript_library.cpp b/indra/lscript/lscript_library/lscript_library.cpp
+index 2ac45f0..9ce0d2a 100644
+--- a/indra/lscript/lscript_library/lscript_library.cpp
++++ b/indra/lscript/lscript_library/lscript_library.cpp
+@@ -221,7 +221,7 @@ void LLScriptLibrary::init()
+ 	addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llBreakAllLinks", NULL, NULL, "llBreakAllLinks()\nDelinks all tasks in the link set (requires permission PERMISSION_CHANGE_LINKS be set)"));
+ 	addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetLinkKey", "k", "i", "key llGetLinkKey(integer linknum)\nGet the key of linknumber in link set"));
+ 	addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetLinkName", "s", "i", "string llGetLinkName(integer linknum)\nGet the name of linknumber in link set"));
+-	addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetInventoryNumber", "i", "i", "integer llGetInventoryNumber(integer type)\nGet the number of items of a given type in the task's inventory.\nValid types: INVENTORY_TEXTURE, INVENTORY_SOUND, INVENTORY_OBJECT, INVENTORY_SCRIPT, INVENTORY_CLOTHING, INVENTORY_BODYPART, INVENTORY_NOTECARD, INVENTORY_LANDMARK, INVENTORY_ALL"));
++	addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetInventoryNumber", "i", "i", "integer llGetInventoryNumber(integer type)\nGet the number of items of a given type in the task's inventory.\nValid types: INVENTORY_TEXTURE, INVENTORY_SOUND, INVENTORY_OBJECT, INVENTORY_SCRIPT, INVENTORY_CLOTHING, INVENTORY_BODYPART, INVENTORY_NOTECARD, INVENTORY_LANDMARK, INVENTORY_ANIMATION, INVENTORY_GESTURE, INVENTORY_ALL"));
+ 	addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetInventoryName", "s", "ii", "string llGetInventoryName(integer type, integer number)\nGet the name of the inventory item number of type"));
+ 	addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llSetScriptState", NULL, "si", "llSetScriptState(string name, integer run)\nControl the state of a script name."));
+ 	addFunction(new LLScriptLibraryFunction(10.f, 0.f, dummy_func, "llGetEnergy", "f", NULL, "float llGetEnergy()\nReturns how much energy is in the object as a percentage of maximum"));
+-- 
+tg: (1836a2b..) topic/fixes/jira-backported/VWR-3766_llGetInventoryNumber_tooltip_missing_INVENTORY_ANIMATION (depends on: upstream)
diff --git a/debian/patches/topic/fixes/jira-backported/VWR5717_text_not_replaced_by_input_with_japanses_im.diff b/debian/patches/topic/fixes/jira-backported/VWR5717_text_not_replaced_by_input_with_japanses_im.diff
new file mode 100644
index 0000000..cfbe97d
--- /dev/null
+++ b/debian/patches/topic/fixes/jira-backported/VWR5717_text_not_replaced_by_input_with_japanses_im.diff
@@ -0,0 +1,70 @@
+From: Robin Cornelius <robin.cornelius at gmail.com>
+Subject: [PATCH] topic/fixes/jira-backported/VWR5717_text_not_replaced_by_input_with_japanses_im
+
+Fix to allow Japanese input, taken from VWR-5717
+
+Signed-off-by: Robin Cornelius <robin.cornelius at gmail.com>
+
+---
+ indra/llui/lllineeditor.cpp |   12 +++++++++---
+ indra/llui/lltexteditor.cpp |   12 +++++++++---
+ 2 files changed, 18 insertions(+), 6 deletions(-)
+
+diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp
+index 64b1284..da633dd 100644
+--- a/indra/llui/lllineeditor.cpp
++++ b/indra/llui/lllineeditor.cpp
+@@ -2370,14 +2370,20 @@ BOOL LLLineEditor::hasPreeditString() const
+ 
+ void LLLineEditor::resetPreedit()
+ {
+-	if (hasPreeditString())
++	if (hasSelection())
+ 	{
+-		if (hasSelection())
++		if (hasPreeditString())
+ 		{
+ 			llwarns << "Preedit and selection!" << llendl;
+ 			deselect();
+ 		}
+-
++		else
++		{
++			deleteSelection();
++		}
++	}
++	if (hasPreeditString())
++	{
+ 		const S32 preedit_pos = mPreeditPositions.front();
+ 		mText.erase(preedit_pos, mPreeditPositions.back() - preedit_pos);
+ 		mText.insert(preedit_pos, mPreeditOverwrittenWString);
+diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
+index 62064d9..89abb24 100644
+--- a/indra/llui/lltexteditor.cpp
++++ b/indra/llui/lltexteditor.cpp
+@@ -4410,14 +4410,20 @@ BOOL LLTextEditor::hasPreeditString() const
+ 
+ void LLTextEditor::resetPreedit()
+ {
+-	if (hasPreeditString())
++	if (hasSelection())
+ 	{
+-		if (hasSelection())
++		if (hasPreeditString())
+ 		{
+ 			llwarns << "Preedit and selection!" << llendl;
+ 			deselect();
+ 		}
+-
++		else
++		{
++			deleteSelection(FALSE);
++		}
++	}
++	if (hasPreeditString())
++	{
+ 		mCursorPos = mPreeditPositions.front();
+ 		removeStringNoUndo(mCursorPos, mPreeditPositions.back() - mCursorPos);
+ 		insertStringNoUndo(mCursorPos, mPreeditOverwrittenWString);
+-- 
+tg: (1836a2b..) topic/fixes/jira-backported/VWR5717_text_not_replaced_by_input_with_japanses_im (depends on: upstream)
diff --git a/debian/patches/topic/fixes/jira-backported/glh_linear.diff b/debian/patches/topic/fixes/jira-backported/glh_linear.diff
new file mode 100644
index 0000000..d87b654
--- /dev/null
+++ b/debian/patches/topic/fixes/jira-backported/glh_linear.diff
@@ -0,0 +1,1640 @@
+From: Carlo Wood <carlo at alinoe.com>
+Subject: [PATCH] topic/fixes/jira-backported/glh_linear
+
+Adds the missing glh_linear.h header.
+
+Signed-off-by: Carlo Wood <carlo at alinoe.com>
+
+---
+ indra/llwindow/glh/glh_linear.h | 1621 +++++++++++++++++++++++++++++++++++++++
+ 1 files changed, 1621 insertions(+), 0 deletions(-)
+
+diff --git a/indra/llwindow/glh/glh_linear.h b/indra/llwindow/glh/glh_linear.h
+new file mode 100644
+index 0000000..04ae1bd
+--- /dev/null
++++ b/indra/llwindow/glh/glh_linear.h
+@@ -0,0 +1,1621 @@
++/*
++    glh - is a platform-indepenedent C++ OpenGL helper library 
++
++
++    Copyright (c) 2000 Cass Everitt
++	Copyright (c) 2000 NVIDIA Corporation
++    All rights reserved.
++
++    Redistribution and use in source and binary forms, with or
++	without modification, are permitted provided that the following
++	conditions are met:
++
++     * Redistributions of source code must retain the above
++	   copyright notice, this list of conditions and the following
++	   disclaimer.
++
++     * Redistributions in binary form must reproduce the above
++	   copyright notice, this list of conditions and the following
++	   disclaimer in the documentation and/or other materials
++	   provided with the distribution.
++
++     * The names of contributors to this software may not be used
++	   to endorse or promote products derived from this software
++	   without specific prior written permission. 
++
++       THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
++	   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
++	   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
++	   FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
++	   REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
++	   INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
++	   BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
++	   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
++	   CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
++	   LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
++	   ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
++	   POSSIBILITY OF SUCH DAMAGE. 
++
++
++    Cass Everitt - cass at r3.nu
++*/
++
++/*
++glh_linear.h
++*/
++
++// Author:  Cass W. Everitt
++
++#ifndef GLH_LINEAR_H
++#define GLH_LINEAR_H
++
++#include <memory.h>
++#include <math.h>
++#include <assert.h>
++
++// only supports float for now...
++#define GLH_REAL_IS_FLOAT
++
++#ifdef GLH_REAL_IS_FLOAT
++# define GLH_REAL float
++# define GLH_REAL_NAMESPACE ns_float
++#endif
++
++#define     GLH_QUATERNION_NORMALIZATION_THRESHOLD  64
++
++#define     GLH_RAD_TO_DEG      GLH_REAL(57.2957795130823208767981548141052)
++#define     GLH_DEG_TO_RAD      GLH_REAL(0.0174532925199432957692369076848861)
++#define     GLH_ZERO            GLH_REAL(0.0)
++#define     GLH_ONE             GLH_REAL(1.0)
++#define     GLH_TWO             GLH_REAL(2.0)
++#define     GLH_EPSILON         GLH_REAL(10e-6)
++#define     GLH_PI              GLH_REAL(3.1415926535897932384626433832795)    
++
++#define     equivalent(a,b)     (((a < b + GLH_EPSILON) && (a > b - GLH_EPSILON)) ? true : false)
++
++namespace glh
++{
++
++	inline GLH_REAL to_degrees(GLH_REAL radians) { return radians*GLH_RAD_TO_DEG; }
++	inline GLH_REAL to_radians(GLH_REAL degrees) { return degrees*GLH_DEG_TO_RAD; }
++
++	// forward declarations for friend template functions.
++	template <int N, class T> class vec;
++	
++	// forward declarations for friend template functions.
++	template <int N, class T>
++		bool operator == ( const vec<N,T> & v1, const vec<N,T> & v2 );
++	
++	// forward declarations for friend template functions.
++	template <int N, class T>
++		bool operator != ( const vec<N,T> & v1, const vec<N,T> & v2 );
++
++	template <int N, class T>	
++	class vec
++	{				
++    public:
++		int size() const { return N; }
++		
++		vec(const T & t = T()) 
++		{ for(int i = 0; i < N; i++) v[i] = t; }
++		vec(const T * tp)
++		{ for(int i = 0; i < N; i++) v[i] = tp[i]; }
++		
++		const T * get_value() const
++		{ return v; }
++		
++		
++		T dot( const vec<N,T> & rhs ) const
++		{ 
++			T r = 0;
++			for(int i = 0; i < N; i++) r += v[i]*rhs.v[i];
++			return r;
++		}
++		
++		T length() const
++		{
++			T r = 0;
++			for(int i = 0; i < N; i++) r += v[i]*v[i]; 
++			return T(sqrt(r));
++		}	
++		
++		T square_norm() const
++		{
++			T r = 0;
++			for(int i = 0; i < N; i++) r += v[i]*v[i]; 
++			return r;
++		}	
++		
++		void  negate()
++		{ for(int i = 0; i < N; i++) v[i] = -v[i]; }
++		
++		
++		T normalize() 
++		{ 
++			T sum(0);
++			for(int i = 0; i < N; i++) 
++                sum += v[i]*v[i];
++			sum = T(sqrt(sum));
++            if (sum > GLH_EPSILON)
++			    for(int i = 0; i < N; i++) 
++                    v[i] /= sum;
++			return sum;
++		}
++		
++		
++		vec<N,T> & set_value( const T * rhs )
++		{ for(int i = 0; i < N; i++) v[i] = rhs[i]; return *this; }
++		
++		T & operator [] ( int i )
++		{ return v[i]; }
++		
++		const T & operator [] ( int i ) const
++		{ return v[i]; }
++
++		vec<N,T> & operator *= ( T d )
++		{ for(int i = 0; i < N; i++) v[i] *= d; return *this;}
++		
++		vec<N,T> & operator *= ( const vec<N,T> & u )
++		{ for(int i = 0; i < N; i++) v[i] *= u[i]; return *this;}
++		
++		vec<N,T> & operator /= ( T d )
++		{ if(d == 0) return *this; for(int i = 0; i < N; i++) v[i] /= d; return *this;}
++		
++		vec<N,T> & operator += ( const vec<N,T> & u )
++		{ for(int i = 0; i < N; i++) v[i] += u.v[i]; return *this;}
++		
++		vec<N,T> & operator -= ( const vec<N,T> & u )
++		{ for(int i = 0; i < N; i++) v[i] -= u.v[i]; return *this;}
++		
++		
++		vec<N,T> operator - () const
++		{ vec<N,T> rv = v; rv.negate(); return rv; }
++		
++		vec<N,T> operator + ( const vec<N,T> &v) const
++		{ vec<N,T> rt(*this); return rt += v; }
++		
++		vec<N,T> operator - ( const vec<N,T> &v) const
++		{ vec<N,T> rt(*this); return rt -= v; }
++		
++		vec<N,T> operator * ( T d) const
++		{ vec<N,T> rt(*this); return rt *= d; }
++		
++		friend bool operator == <> ( const vec<N,T> &v1, const vec<N,T> &v2 );
++		friend bool operator != <> ( const vec<N,T> &v1, const vec<N,T> &v2 );
++		
++		
++	//protected:
++		T v[N];
++	};
++	
++	
++	
++	// vector friend operators
++	
++	template <int N, class T> inline
++		vec<N,T> operator * ( const vec<N,T> & b, T d )
++	{
++		vec<N,T> rt(b);
++		return rt *= d;
++	}
++
++	template <int N, class T> inline
++		vec<N,T> operator * ( T d, const vec<N,T> & b )
++	{ return b*d; }
++	
++	template <int N, class T> inline
++		vec<N,T> operator * ( const vec<N,T> & b, const vec<N,T> & d )
++	{
++		vec<N,T> rt(b);
++		return rt *= d;
++	}
++
++	template <int N, class T> inline
++		vec<N,T> operator / ( const vec<N,T> & b, T d )
++	{ vec<N,T> rt(b); return rt /= d; }
++	
++	template <int N, class T> inline
++		vec<N,T> operator + ( const vec<N,T> & v1, const vec<N,T> & v2 )
++	{ vec<N,T> rt(v1); return rt += v2; }
++	
++	template <int N, class T> inline
++		vec<N,T> operator - ( const vec<N,T> & v1, const vec<N,T> & v2 )
++	{ vec<N,T> rt(v1); return rt -= v2; }
++	
++	
++	template <int N, class T> inline
++		bool operator == ( const vec<N,T> & v1, const vec<N,T> & v2 )
++	{
++		for(int i = 0; i < N; i++)
++			if(v1.v[i] != v2.v[i])
++				return false;
++			return true;
++	}
++	
++	template <int N, class T> inline
++		bool operator != ( const vec<N,T> & v1, const vec<N,T> & v2 )
++	{ return !(v1 == v2); }
++	
++
++	typedef vec<3,unsigned char> vec3ub;
++	typedef vec<4,unsigned char> vec4ub;
++
++
++
++
++
++	namespace GLH_REAL_NAMESPACE
++	{
++	typedef GLH_REAL real;
++
++	class line;
++	class plane;
++	class matrix4;
++	class quaternion;
++	typedef quaternion rotation; 
++  
++	class vec2 : public vec<2,real>
++	{
++    public:
++		vec2(const real & t = real()) : vec<2,real>(t)
++		{}
++		vec2(const vec<2,real> & t) : vec<2,real>(t)
++		{}
++		vec2(const real * tp) : vec<2,real>(tp)
++		{}
++		
++		vec2(real x, real y )
++		{ v[0] = x; v[1] = y; }
++		
++		void get_value(real & x, real & y) const
++		{ x = v[0]; y = v[1]; }
++		
++		vec2 & set_value( const real & x, const real & y)
++		{ v[0] = x; v[1] = y; return *this; }
++		
++	};
++	
++	
++	class vec3 : public vec<3,real>
++	{
++    public:
++		vec3(const real & t = real()) : vec<3,real>(t)
++		{}
++		vec3(const vec<3,real> & t) : vec<3,real>(t)
++		{}
++		vec3(const real * tp) : vec<3,real>(tp)
++		{}
++		
++		vec3(real x, real y, real z)
++		{ v[0] = x; v[1] = y; v[2] = z; }
++		
++		void get_value(real & x, real & y, real & z) const
++		{ x = v[0]; y = v[1]; z = v[2]; }
++		
++		vec3 cross( const vec3 &rhs ) const
++		{
++			vec3 rt;
++			rt.v[0] = v[1]*rhs.v[2]-v[2]*rhs.v[1];
++			rt.v[1] = v[2]*rhs.v[0]-v[0]*rhs.v[2];
++			rt.v[2] = v[0]*rhs.v[1]-v[1]*rhs.v[0];	
++			return rt;
++		}
++		
++		vec3 & set_value( const real & x, const real & y, const real & z)
++		{ v[0] = x; v[1] = y; v[2] = z; return *this; }
++		
++	};
++
++  		
++    class vec4 : public vec<4,real>
++    {
++    public:
++        vec4(const real & t = real()) : vec<4,real>(t)
++        {}
++        vec4(const vec<4,real> & t) : vec<4,real>(t)
++        {}
++
++        vec4(const vec<3,real> & t, real fourth)
++
++        { v[0] = t.v[0]; v[1] = t.v[1]; v[2] = t.v[2]; v[3] = fourth; }
++        vec4(const real * tp) : vec<4,real>(tp)
++        {}
++        vec4(real x, real y, real z, real w)
++        { v[0] = x; v[1] = y; v[2] = z; v[3] = w; }
++
++        void get_value(real & x, real & y, real & z, real & w) const
++        { x = v[0]; y = v[1]; z = v[2]; w = v[3]; }
++  
++        vec4 & set_value( const real & x, const real & y, const real & z, const real & w)
++        { v[0] = x; v[1] = y; v[2] = z; v[3] = w; return *this; }
++    };
++
++    inline
++    vec3 homogenize(const vec4 & v)
++    {
++      vec3 rt;
++      assert(v.v[3] != GLH_ZERO);
++      rt.v[0] = v.v[0]/v.v[3];
++      rt.v[1] = v.v[1]/v.v[3];
++      rt.v[2] = v.v[2]/v.v[3];
++      return rt;
++    }
++  
++
++
++    class line
++    {
++    public:
++  
++        line()
++        { set_value(vec3(0,0,0),vec3(0,0,1)); }
++
++        line( const vec3 & p0, const vec3 &p1)
++        { set_value(p0,p1); }
++
++        void set_value( const vec3 &p0, const vec3 &p1)
++        {
++          position = p0;
++          direction = p1-p0;
++          direction.normalize();
++        }
++  
++        bool get_closest_points(const line &line2, 
++					          vec3 &pointOnThis,
++					          vec3 &pointOnThat)
++        {
++  
++          // quick check to see if parallel -- if so, quit.
++          if(fabs(direction.dot(line2.direction)) == 1.0)
++	          return 0;
++          line l2 = line2;
++  
++          // Algorithm: Brian Jean
++          // 
++          register real u;
++          register real v;
++          vec3 Vr = direction;
++          vec3 Vs = l2.direction;
++          register real Vr_Dot_Vs = Vr.dot(Vs);
++          register real detA = real(1.0 - (Vr_Dot_Vs * Vr_Dot_Vs));
++          vec3 C = l2.position - position;
++          register real C_Dot_Vr =  C.dot(Vr);
++          register real C_Dot_Vs =  C.dot(Vs);
++  
++          u = (C_Dot_Vr - Vr_Dot_Vs * C_Dot_Vs)/detA;
++          v = (C_Dot_Vr * Vr_Dot_Vs - C_Dot_Vs)/detA;
++  
++          pointOnThis = position;
++          pointOnThis += direction * u;
++          pointOnThat = l2.position;
++          pointOnThat += l2.direction * v;
++  
++          return 1;
++        }
++  
++        vec3 get_closest_point(const vec3 &point)
++        {
++          vec3 np = point - position;
++          vec3 rp = direction*direction.dot(np)+position;
++          return rp;
++        }
++  
++        const vec3 & get_position() const {return position;}
++
++        const vec3 & get_direction() const {return direction;}
++  
++    //protected:
++        vec3 position;
++        vec3 direction;
++    };
++  
++  
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++  
++  
++
++
++
++
++
++
++
++
++
++
++
++  // matrix
++
++  
++  class matrix4
++  {
++    
++  public:
++        
++    matrix4() { make_identity(); }
++    
++	matrix4( real r ) 
++	{ set_value(r); }
++
++	matrix4( real * m )
++	{ set_value(m); }
++    
++    matrix4( real a00, real a01, real a02, real a03,
++	       real a10, real a11, real a12, real a13,
++		   real a20, real a21, real a22, real a23,
++		   real a30, real a31, real a32, real a33 )
++	{
++		element(0,0) = a00;
++		element(0,1) = a01;
++		element(0,2) = a02;
++		element(0,3) = a03;
++		
++		element(1,0) = a10;
++		element(1,1) = a11;
++		element(1,2) = a12;
++		element(1,3) = a13;
++		
++		element(2,0) = a20;
++		element(2,1) = a21;
++		element(2,2) = a22;
++		element(2,3) = a23;
++		
++		element(3,0) = a30;
++		element(3,1) = a31;
++		element(3,2) = a32;
++		element(3,3) = a33;
++	}
++            
++    
++    void get_value( real * mp ) const
++	{
++		int c = 0;
++		for(int j=0; j < 4; j++)
++			for(int i=0; i < 4; i++)
++				mp[c++] = element(i,j);
++	}
++    
++    
++    const real * get_value() const
++	{ return m; }
++    
++	void set_value( real * mp)
++	{
++		int c = 0;
++		for(int j=0; j < 4; j++)
++			for(int i=0; i < 4; i++)
++				element(i,j) = mp[c++];
++	}
++    
++	void set_value( real r ) 
++	{
++		for(int i=0; i < 4; i++)
++			for(int j=0; j < 4; j++)
++				element(i,j) = r;
++	}
++    
++    void make_identity()
++	{
++		element(0,0) = 1.0;
++		element(0,1) = 0.0;
++		element(0,2) = 0.0; 
++		element(0,3) = 0.0;
++		
++		element(1,0) = 0.0;
++		element(1,1) = 1.0; 
++		element(1,2) = 0.0;
++		element(1,3) = 0.0;
++		
++		element(2,0) = 0.0;
++		element(2,1) = 0.0;
++		element(2,2) = 1.0;
++		element(2,3) = 0.0;
++		
++		element(3,0) = 0.0; 
++		element(3,1) = 0.0; 
++		element(3,2) = 0.0;
++		element(3,3) = 1.0;
++	}
++	
++	
++    static matrix4 identity()
++	{
++		static matrix4 mident (
++			1.0, 0.0, 0.0, 0.0,
++			0.0, 1.0, 0.0, 0.0,
++			0.0, 0.0, 1.0, 0.0,
++			0.0, 0.0, 0.0, 1.0  );
++		return mident;
++	}
++    
++        
++    void set_scale( real s )
++	{
++		element(0,0) = s;
++		element(1,1) = s;
++		element(2,2) = s;
++	}
++    
++    void set_scale( const vec3 & s )
++	{
++		element(0,0) = s.v[0];
++		element(1,1) = s.v[1];
++		element(2,2) = s.v[2];
++	}
++    
++    
++    void set_translate( const vec3 & t )
++	{
++		element(0,3) = t.v[0];
++		element(1,3) = t.v[1];
++		element(2,3) = t.v[2];
++	}
++    
++	void set_row(int r, const vec4 & t)
++	{
++		element(r,0) = t.v[0];
++		element(r,1) = t.v[1];
++		element(r,2) = t.v[2];
++		element(r,3) = t.v[3];
++	}
++
++	void set_column(int c, const vec4 & t)
++	{
++		element(0,c) = t.v[0];
++		element(1,c) = t.v[1];
++		element(2,c) = t.v[2];
++		element(3,c) = t.v[3];
++	}
++
++    
++	void get_row(int r, vec4 & t) const
++	{
++		t.v[0] = element(r,0);
++		t.v[1] = element(r,1);
++		t.v[2] = element(r,2);
++		t.v[3] = element(r,3);
++	}
++
++	vec4 get_row(int r) const
++	{
++		vec4 v; get_row(r, v);
++		return v;
++	}
++
++	void get_column(int c, vec4 & t) const
++	{
++		t.v[0] = element(0,c);
++		t.v[1] = element(1,c);
++		t.v[2] = element(2,c);
++		t.v[3] = element(3,c);
++	}
++
++	vec4 get_column(int c) const
++	{
++		vec4 v; get_column(c, v);
++		return v;
++	}
++
++    matrix4 inverse() const
++	{
++		matrix4 minv;
++		
++		real r1[8], r2[8], r3[8], r4[8];
++		real *s[4], *tmprow;
++		
++		s[0] = &r1[0];
++		s[1] = &r2[0];
++		s[2] = &r3[0];
++		s[3] = &r4[0];
++		
++		register int i,j,p,jj;
++		for(i=0;i<4;i++)
++		{
++			for(j=0;j<4;j++)
++			{
++				s[i][j] = element(i,j);
++				if(i==j) s[i][j+4] = 1.0;
++				else     s[i][j+4] = 0.0;
++			}
++		}
++		real scp[4];
++		for(i=0;i<4;i++)
++		{
++			scp[i] = real(fabs(s[i][0]));
++			for(j=1;j<4;j++)
++				if(real(fabs(s[i][j])) > scp[i]) scp[i] = real(fabs(s[i][j]));
++				if(scp[i] == 0.0) return minv; // singular matrix!
++		}
++		
++		int pivot_to;
++		real scp_max;
++		for(i=0;i<4;i++)
++		{
++			// select pivot row
++			pivot_to = i;
++			scp_max = real(fabs(s[i][i]/scp[i]));
++			// find out which row should be on top
++			for(p=i+1;p<4;p++)
++				if(real(fabs(s[p][i]/scp[p])) > scp_max)
++				{ scp_max = real(fabs(s[p][i]/scp[p])); pivot_to = p; }
++				// Pivot if necessary
++				if(pivot_to != i)
++				{
++					tmprow = s[i];
++					s[i] = s[pivot_to];
++					s[pivot_to] = tmprow;
++					real tmpscp;
++					tmpscp = scp[i];
++					scp[i] = scp[pivot_to];
++					scp[pivot_to] = tmpscp;
++				}
++				
++				real mji;
++				// perform gaussian elimination
++				for(j=i+1;j<4;j++)
++				{
++					mji = s[j][i]/s[i][i];
++					s[j][i] = 0.0;
++					for(jj=i+1;jj<8;jj++)
++						s[j][jj] -= mji*s[i][jj];
++				}
++		}
++		if(s[3][3] == 0.0) return minv; // singular matrix!
++		
++		//
++		// Now we have an upper triangular matrix.
++		//
++		//  x x x x | y y y y
++		//  0 x x x | y y y y 
++		//  0 0 x x | y y y y
++		//  0 0 0 x | y y y y
++		//
++		//  we'll back substitute to get the inverse
++		//
++		//  1 0 0 0 | z z z z
++		//  0 1 0 0 | z z z z
++		//  0 0 1 0 | z z z z
++		//  0 0 0 1 | z z z z 
++		//
++		
++		real mij;
++		for(i=3;i>0;i--)
++		{
++			for(j=i-1;j > -1; j--)
++			{
++				mij = s[j][i]/s[i][i];
++				for(jj=j+1;jj<8;jj++)
++					s[j][jj] -= mij*s[i][jj];
++			}
++		}
++		
++		for(i=0;i<4;i++)
++			for(j=0;j<4;j++)
++				minv(i,j) = s[i][j+4] / s[i][i];
++			
++			return minv;
++	}
++    
++    
++    matrix4 transpose() const
++	{
++		matrix4 mtrans;
++		
++		for(int i=0;i<4;i++)
++			for(int j=0;j<4;j++)
++				mtrans(i,j) = element(j,i);		
++		return mtrans;
++	}
++    
++    matrix4 & mult_right( const matrix4 & b )
++	{
++		matrix4 mt(*this);
++		set_value(real(0));
++
++		for(int i=0; i < 4; i++)
++			for(int j=0; j < 4; j++)
++				for(int c=0; c < 4; c++)
++					element(i,j) += mt(i,c) * b(c,j);
++		return *this;
++	}    
++
++    matrix4 & mult_left( const matrix4 & b )
++	{
++		matrix4 mt(*this);
++		set_value(real(0));
++
++		for(int i=0; i < 4; i++)
++			for(int j=0; j < 4; j++)
++				for(int c=0; c < 4; c++)
++					element(i,j) += b(i,c) * mt(c,j);
++		return *this;
++	}
++	
++	// dst = M * src
++    void mult_matrix_vec( const vec3 &src, vec3 &dst ) const
++	{
++		real w = (
++			src.v[0] * element(3,0) +
++			src.v[1] * element(3,1) + 
++			src.v[2] * element(3,2) +
++			element(3,3)          );
++        
++        assert(w != GLH_ZERO);
++
++        dst.v[0]  = (
++			src.v[0] * element(0,0) +
++			src.v[1] * element(0,1) +
++			src.v[2] * element(0,2) +
++			element(0,3)          ) / w;
++		dst.v[1]  = (
++			src.v[0] * element(1,0) +
++			src.v[1] * element(1,1) +
++			src.v[2] * element(1,2) +
++			element(1,3)          ) / w;
++		dst.v[2]  = (
++			src.v[0] * element(2,0) +
++			src.v[1] * element(2,1) + 
++			src.v[2] * element(2,2) +
++			element(2,3)          ) / w;
++	}
++    
++	void mult_matrix_vec( vec3 & src_and_dst) const
++	{ mult_matrix_vec(vec3(src_and_dst), src_and_dst); }
++
++
++    // dst = src * M
++    void mult_vec_matrix( const vec3 &src, vec3 &dst ) const
++	{
++		real w = (
++			src.v[0] * element(0,3) +
++			src.v[1] * element(1,3) +
++			src.v[2] * element(2,3) +
++			element(3,3)          );
++        
++        assert(w != GLH_ZERO);
++
++		dst.v[0]  = (
++			src.v[0] * element(0,0) +
++			src.v[1] * element(1,0) + 
++			src.v[2] * element(2,0) + 
++			element(3,0)          ) / w;
++		dst.v[1]  = (
++			src.v[0] * element(0,1) +
++			src.v[1] * element(1,1) +
++			src.v[2] * element(2,1) +
++			element(3,1)          ) / w;
++		dst.v[2]  = (
++			src.v[0] * element(0,2) +
++			src.v[1] * element(1,2) +
++			src.v[2] * element(2,2) +
++			element(3,2)          ) / w;
++	}
++        
++
++	void mult_vec_matrix( vec3 & src_and_dst) const
++	{ mult_vec_matrix(vec3(src_and_dst), src_and_dst); }
++
++	// dst = M * src
++    void mult_matrix_vec( const vec4 &src, vec4 &dst ) const
++	{
++        dst.v[0]  = (
++			src.v[0] * element(0,0) +
++			src.v[1] * element(0,1) +
++			src.v[2] * element(0,2) +
++			src.v[3] * element(0,3));
++		dst.v[1]  = (
++			src.v[0] * element(1,0) +
++			src.v[1] * element(1,1) +
++			src.v[2] * element(1,2) +
++			src.v[3] * element(1,3));
++		dst.v[2]  = (
++			src.v[0] * element(2,0) +
++			src.v[1] * element(2,1) + 
++			src.v[2] * element(2,2) +
++			src.v[3] * element(2,3));
++		dst.v[3] = (
++			src.v[0] * element(3,0) +
++			src.v[1] * element(3,1) + 
++			src.v[2] * element(3,2) +
++			src.v[3] * element(3,3));
++	}
++    
++	void mult_matrix_vec( vec4 & src_and_dst) const
++	{ mult_matrix_vec(vec4(src_and_dst), src_and_dst); }
++
++
++    // dst = src * M
++    void mult_vec_matrix( const vec4 &src, vec4 &dst ) const
++	{
++		dst.v[0]  = (
++			src.v[0] * element(0,0) +
++			src.v[1] * element(1,0) + 
++			src.v[2] * element(2,0) + 
++			src.v[3] * element(3,0));
++		dst.v[1]  = (
++			src.v[0] * element(0,1) +
++			src.v[1] * element(1,1) +
++			src.v[2] * element(2,1) +
++			src.v[3] * element(3,1));
++		dst.v[2]  = (
++			src.v[0] * element(0,2) +
++			src.v[1] * element(1,2) +
++			src.v[2] * element(2,2) +
++			src.v[3] * element(3,2));
++		dst.v[3] = (
++			src.v[0] * element(0,3) +
++			src.v[1] * element(1,3) +
++			src.v[2] * element(2,3) +
++			src.v[3] * element(3,3));
++	}
++        
++
++	void mult_vec_matrix( vec4 & src_and_dst) const
++	{ mult_vec_matrix(vec4(src_and_dst), src_and_dst); }
++
++    
++    // dst = M * src
++    void mult_matrix_dir( const vec3 &src, vec3 &dst ) const
++	{
++		dst.v[0]  = (
++			src.v[0] * element(0,0) +
++			src.v[1] * element(0,1) +
++			src.v[2] * element(0,2) ) ;
++		dst.v[1]  = ( 
++			src.v[0] * element(1,0) +
++			src.v[1] * element(1,1) +
++			src.v[2] * element(1,2) ) ;
++		dst.v[2]  = ( 
++			src.v[0] * element(2,0) +
++			src.v[1] * element(2,1) + 
++			src.v[2] * element(2,2) ) ;
++	}
++        
++
++	void mult_matrix_dir( vec3 & src_and_dst) const
++	{ mult_matrix_dir(vec3(src_and_dst), src_and_dst); }
++
++
++	// dst = src * M
++    void mult_dir_matrix( const vec3 &src, vec3 &dst ) const
++	{
++		dst.v[0]  = ( 
++			src.v[0] * element(0,0) +
++			src.v[1] * element(1,0) +
++			src.v[2] * element(2,0) ) ;
++		dst.v[1]  = ( 
++			src.v[0] * element(0,1) +
++			src.v[1] * element(1,1) +
++			src.v[2] * element(2,1) ) ;
++		dst.v[2]  = (
++			src.v[0] * element(0,2) +
++			src.v[1] * element(1,2) + 
++			src.v[2] * element(2,2) ) ;
++	}
++    
++    
++	void mult_dir_matrix( vec3 & src_and_dst) const
++	{ mult_dir_matrix(vec3(src_and_dst), src_and_dst); }
++
++
++    real & operator () (int row, int col)
++    { return element(row,col); }
++
++    const real & operator () (int row, int col) const
++    { return element(row,col); }
++
++	real & element (int row, int col)
++    { return m[row | (col<<2)]; }
++
++    const real & element (int row, int col) const
++    { return m[row | (col<<2)]; }
++
++    matrix4 & operator *= ( const matrix4 & mat )
++	{
++		mult_right( mat );
++		return *this;
++	}
++    
++    matrix4 & operator *= ( const real & r )
++	{
++		for (int i = 0; i < 4; ++i)
++        {
++            element(0,i) *= r;
++            element(1,i) *= r;
++            element(2,i) *= r;
++            element(3,i) *= r;
++        }
++		return *this;
++	}
++
++    matrix4 & operator += ( const matrix4 & mat )
++	{
++		for (int i = 0; i < 4; ++i)
++        {
++            element(0,i) += mat.element(0,i);
++            element(1,i) += mat.element(1,i);
++            element(2,i) += mat.element(2,i);
++            element(3,i) += mat.element(3,i);
++        }
++		return *this;
++	}
++
++    friend matrix4 operator * ( const matrix4 & m1,	const matrix4 & m2 );
++    friend bool operator == ( const matrix4 & m1, const matrix4 & m2 );
++    friend bool operator != ( const matrix4 & m1, const matrix4 & m2 );
++    
++  //protected:
++	  real m[16];
++  };
++  
++  inline  
++  matrix4 operator * ( const matrix4 & m1, const matrix4 & m2 )
++  {
++	  matrix4 product;
++	  
++	  product = m1;
++	  product.mult_right(m2);
++	  
++	  return product;
++  }
++  
++  inline
++  bool operator ==( const matrix4 &m1, const matrix4 &m2 )
++  {
++	  return ( 
++		  m1(0,0) == m2(0,0) &&
++		  m1(0,1) == m2(0,1) &&
++		  m1(0,2) == m2(0,2) &&
++		  m1(0,3) == m2(0,3) &&
++		  m1(1,0) == m2(1,0) &&
++		  m1(1,1) == m2(1,1) &&
++		  m1(1,2) == m2(1,2) &&
++		  m1(1,3) == m2(1,3) &&
++		  m1(2,0) == m2(2,0) &&
++		  m1(2,1) == m2(2,1) &&
++		  m1(2,2) == m2(2,2) &&
++		  m1(2,3) == m2(2,3) &&
++		  m1(3,0) == m2(3,0) &&
++		  m1(3,1) == m2(3,1) &&
++		  m1(3,2) == m2(3,2) &&
++		  m1(3,3) == m2(3,3) );
++  }
++  
++  inline
++  bool operator != ( const matrix4 & m1, const matrix4 & m2 )
++  { return !( m1 == m2 ); }  
++
++
++
++
++
++
++
++
++
++
++
++
++  
++    class quaternion
++    {
++    public:
++    
++    quaternion()
++    {
++        *this = identity();
++    }
++
++    quaternion( const real v[4] )
++    {
++        set_value( v );
++    }
++
++
++    quaternion( real q0, real q1, real q2, real q3 )
++    {
++        set_value( q0, q1, q2, q3 );
++    }
++
++
++    quaternion( const matrix4 & m )
++    {
++        set_value( m );
++    }
++
++
++    quaternion( const vec3 &axis, real radians )
++    {
++        set_value( axis, radians );
++    }
++
++
++    quaternion( const vec3 &rotateFrom, const vec3 &rotateTo )
++    {
++        set_value( rotateFrom, rotateTo );
++    }
++
++    quaternion( const vec3 & from_look, const vec3 & from_up,
++		      const vec3 & to_look, const vec3& to_up)
++    {
++	    set_value(from_look, from_up, to_look, to_up);
++    }
++
++    const real * get_value() const
++    {
++        return  &q[0];
++    }
++
++    void get_value( real &q0, real &q1, real &q2, real &q3 ) const
++    {
++        q0 = q[0];
++        q1 = q[1];
++        q2 = q[2];
++        q3 = q[3];
++    }
++
++    quaternion & set_value( real q0, real q1, real q2, real q3 )
++    {
++        q[0] = q0;
++        q[1] = q1;
++        q[2] = q2;
++        q[3] = q3;
++        counter = 0;
++        return *this;
++    }
++
++    void get_value( vec3 &axis, real &radians ) const
++    {
++        radians = real(acos( q[3] ) * GLH_TWO);
++        if ( radians == GLH_ZERO )
++            axis = vec3( 0.0, 0.0, 1.0 );
++        else
++        {
++            axis.v[0] = q[0];
++            axis.v[1] = q[1];
++            axis.v[2] = q[2];
++            axis.normalize();
++        }
++    }
++
++    void get_value( matrix4 & m ) const
++    {
++        real s, xs, ys, zs, wx, wy, wz, xx, xy, xz, yy, yz, zz;
++
++        real norm = q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3];
++
++        s = (equivalent(norm,GLH_ZERO)) ? GLH_ZERO : ( GLH_TWO / norm );
++
++        xs = q[0] * s;
++        ys = q[1] * s;
++        zs = q[2] * s;
++
++        wx = q[3] * xs;
++        wy = q[3] * ys;
++        wz = q[3] * zs;
++
++        xx = q[0] * xs;
++        xy = q[0] * ys;
++        xz = q[0] * zs;
++
++        yy = q[1] * ys;
++        yz = q[1] * zs;
++        zz = q[2] * zs;
++
++        m(0,0) = real( GLH_ONE - ( yy + zz ));
++        m(1,0) = real ( xy + wz );
++        m(2,0) = real ( xz - wy );
++
++        m(0,1) = real ( xy - wz );
++        m(1,1) = real ( GLH_ONE - ( xx + zz ));
++        m(2,1) = real ( yz + wx );
++
++        m(0,2) = real ( xz + wy );
++        m(1,2) = real ( yz - wx );
++        m(2,2) = real ( GLH_ONE - ( xx + yy ));
++
++        m(3,0) = m(3,1) = m(3,2) = m(0,3) = m(1,3) = m(2,3) = GLH_ZERO;
++        m(3,3) = GLH_ONE;
++    }
++
++    quaternion & set_value( const real * qp )
++    {
++        memcpy(q,qp,sizeof(real) * 4);
++
++        counter = 0;
++        return *this;
++    }
++
++    quaternion & set_value( const matrix4 & m )
++    {
++        real tr, s;
++        int i, j, k;
++        const int nxt[3] = { 1, 2, 0 };
++
++        tr = m(0,0) + m(1,1) + m(2,2);
++
++        if ( tr > GLH_ZERO )
++        {
++            s = real(sqrt( tr + m(3,3) ));
++            q[3] = real ( s * 0.5 );
++            s = real(0.5) / s;
++
++            q[0] = real ( ( m(1,2) - m(2,1) ) * s );
++            q[1] = real ( ( m(2,0) - m(0,2) ) * s );
++            q[2] = real ( ( m(0,1) - m(1,0) ) * s );
++        }
++        else
++        {
++            i = 0;
++            if ( m(1,1) > m(0,0) )
++              i = 1;
++
++            if ( m(2,2) > m(i,i) )
++              i = 2;
++
++            j = nxt[i];
++            k = nxt[j];
++
++            s = real(sqrt( ( m(i,j) - ( m(j,j) + m(k,k) )) + GLH_ONE ));
++
++            q[i] = real ( s * 0.5 );
++            s = real(0.5 / s);
++
++            q[3] = real ( ( m(j,k) - m(k,j) ) * s );
++            q[j] = real ( ( m(i,j) + m(j,i) ) * s );
++            q[k] = real ( ( m(i,k) + m(k,i) ) * s );
++        }
++
++        counter = 0;
++        return *this;
++    }
++
++    quaternion & set_value( const vec3 &axis, real theta )
++    {
++        real sqnorm = axis.square_norm();
++
++        if (sqnorm <= GLH_EPSILON)
++        {
++            // axis too small.
++            x = y = z = 0.0;
++            w = 1.0;
++        } 
++        else 
++        {
++            theta *= real(0.5);
++            real sin_theta = real(sin(theta));
++
++            if (!equivalent(sqnorm,GLH_ONE)) 
++              sin_theta /= real(sqrt(sqnorm));
++            x = sin_theta * axis.v[0];
++            y = sin_theta * axis.v[1];
++            z = sin_theta * axis.v[2];
++            w = real(cos(theta));
++        }
++        return *this;
++    }
++
++    quaternion & set_value( const vec3 & rotateFrom, const vec3 & rotateTo )
++    {
++        vec3 p1, p2;
++        real alpha;
++
++        p1 = rotateFrom; 
++        p1.normalize();
++        p2 = rotateTo;  
++        p2.normalize();
++
++        alpha = p1.dot(p2);
++
++        if(equivalent(alpha,GLH_ONE))
++        { 
++            *this = identity(); 
++            return *this; 
++        }
++
++        // ensures that the anti-parallel case leads to a positive dot
++        if(equivalent(alpha,-GLH_ONE))
++        {
++            vec3 v;
++
++            if(p1.v[0] != p1.v[1] || p1.v[0] != p1.v[2])
++    	        v = vec3(p1.v[1], p1.v[2], p1.v[0]);
++            else
++    	        v = vec3(-p1.v[0], p1.v[1], p1.v[2]);
++
++            v -= p1 * p1.dot(v);
++            v.normalize();
++
++            set_value(v, GLH_PI);
++            return *this;
++        }
++
++        p1 = p1.cross(p2);  
++        p1.normalize();
++        set_value(p1,real(acos(alpha)));
++
++        counter = 0;
++        return *this;
++    }
++
++    quaternion & set_value( const vec3 & from_look, const vec3 & from_up,
++		      const vec3 & to_look, const vec3 & to_up)
++    {
++	    quaternion r_look = quaternion(from_look, to_look);
++	    
++	    vec3 rotated_from_up(from_up);
++	    r_look.mult_vec(rotated_from_up);
++	    
++	    quaternion r_twist = quaternion(rotated_from_up, to_up);
++	    
++	    *this = r_twist;
++	    *this *= r_look;
++	    return *this;
++    }
++
++    quaternion & operator *= ( const quaternion & qr )
++    {
++        quaternion ql(*this);
++   
++        w = ql.w * qr.w - ql.x * qr.x - ql.y * qr.y - ql.z * qr.z;
++        x = ql.w * qr.x + ql.x * qr.w + ql.y * qr.z - ql.z * qr.y;
++        y = ql.w * qr.y + ql.y * qr.w + ql.z * qr.x - ql.x * qr.z;
++        z = ql.w * qr.z + ql.z * qr.w + ql.x * qr.y - ql.y * qr.x;
++
++        counter += qr.counter;
++        counter++;
++        counter_normalize();
++        return *this;
++    }
++
++    void normalize()
++    {
++        real rnorm = GLH_ONE / real(sqrt(w * w + x * x + y * y + z * z));
++        if (equivalent(rnorm, GLH_ZERO))
++            return;
++        x *= rnorm;
++        y *= rnorm;
++        z *= rnorm;
++        w *= rnorm;
++        counter = 0;
++    }
++
++    friend bool operator == ( const quaternion & q1, const quaternion & q2 );      
++
++    friend bool operator != ( const quaternion & q1, const quaternion & q2 );
++
++    friend quaternion operator * ( const quaternion & q1, const quaternion & q2 );
++
++    bool equals( const quaternion & r, real tolerance ) const
++    {
++        real t;
++
++        t = (
++			(q[0]-r.q[0])*(q[0]-r.q[0]) +
++            (q[1]-r.q[1])*(q[1]-r.q[1]) +
++            (q[2]-r.q[2])*(q[2]-r.q[2]) +
++            (q[3]-r.q[3])*(q[3]-r.q[3]) );
++        if(t > GLH_EPSILON) 
++            return false;
++        return 1;
++    }
++
++    quaternion & conjugate()
++    {
++        q[0] *= -GLH_ONE;
++        q[1] *= -GLH_ONE;
++        q[2] *= -GLH_ONE;
++        return *this;
++    }
++
++    quaternion & invert()
++    {
++        return conjugate();
++    }
++
++    quaternion inverse() const
++    {
++        quaternion r = *this;
++        return r.invert();
++    }
++
++    //
++    // Quaternion multiplication with cartesian vector
++    // v' = q*v*q(star)
++    //
++    void mult_vec( const vec3 &src, vec3 &dst ) const
++    {
++        real v_coef = w * w - x * x - y * y - z * z;                     
++        real u_coef = GLH_TWO * (src.v[0] * x + src.v[1] * y + src.v[2] * z);  
++        real c_coef = GLH_TWO * w;                                       
++
++        dst.v[0] = v_coef * src.v[0] + u_coef * x + c_coef * (y * src.v[2] - z * src.v[1]);
++        dst.v[1] = v_coef * src.v[1] + u_coef * y + c_coef * (z * src.v[0] - x * src.v[2]);
++        dst.v[2] = v_coef * src.v[2] + u_coef * z + c_coef * (x * src.v[1] - y * src.v[0]);
++    }
++
++    void mult_vec( vec3 & src_and_dst) const
++    {
++        mult_vec(vec3(src_and_dst), src_and_dst);
++    }
++
++    void scale_angle( real scaleFactor )
++    {
++        vec3 axis;
++        real radians;
++
++        get_value(axis, radians);
++        radians *= scaleFactor;
++        set_value(axis, radians);
++    }
++
++    static quaternion slerp( const quaternion & p, const quaternion & q, real alpha )
++    {
++        quaternion r;
++
++        real cos_omega = p.x * q.x + p.y * q.y + p.z * q.z + p.w * q.w;
++        // if B is on opposite hemisphere from A, use -B instead
++      
++        int bflip;
++        if ( ( bflip = (cos_omega < GLH_ZERO)) )
++            cos_omega = -cos_omega;
++
++        // complementary interpolation parameter
++        real beta = GLH_ONE - alpha;     
++
++        if(cos_omega <= GLH_ONE - GLH_EPSILON)
++            return p;
++
++        real omega = real(acos(cos_omega));
++        real one_over_sin_omega = GLH_ONE / real(sin(omega));
++
++        beta    = real(sin(omega*beta)  * one_over_sin_omega);
++        alpha   = real(sin(omega*alpha) * one_over_sin_omega);
++
++        if (bflip)
++            alpha = -alpha;
++
++        r.x = beta * p.q[0]+ alpha * q.q[0];
++        r.y = beta * p.q[1]+ alpha * q.q[1];
++        r.z = beta * p.q[2]+ alpha * q.q[2];
++        r.w = beta * p.q[3]+ alpha * q.q[3];
++        return r;
++    }
++
++    static quaternion identity()
++    {
++        static quaternion ident( vec3( 0.0, 0.0, 0.0 ), GLH_ONE );
++        return ident;
++    }
++
++    real & operator []( int i )
++    {
++        assert(i < 4);
++        return q[i];
++    }
++
++    const real & operator []( int i ) const
++    {
++        assert(i < 4);
++        return q[i];
++    }
++
++    protected:
++
++        void counter_normalize()
++        {
++            if (counter > GLH_QUATERNION_NORMALIZATION_THRESHOLD)
++                normalize();
++        }
++
++        union 
++        {
++            struct 
++            {
++                real q[4];
++            };
++            struct 
++            {
++                real x;
++                real y;
++                real z;
++                real w;
++            };
++        };
++
++        // renormalization counter
++        unsigned char counter;
++    };
++
++    inline
++    bool operator == ( const quaternion & q1, const quaternion & q2 )
++    {
++        return (equivalent(q1.x, q2.x) &&
++		        equivalent(q1.y, q2.y) &&
++		        equivalent(q1.z, q2.z) &&
++		        equivalent(q1.w, q2.w) );
++    }
++
++    inline
++    bool operator != ( const quaternion & q1, const quaternion & q2 )
++    { 
++        return ! ( q1 == q2 ); 
++    }
++
++    inline
++    quaternion operator * ( const quaternion & q1, const quaternion & q2 )
++    {	
++        quaternion r(q1); 
++        r *= q2; 
++        return r; 
++    }
++  
++      
++    
++
++
++
++
++
++  
++  
++  class plane
++  {
++  public:
++	  
++	  plane()
++      {
++		  planedistance = 0.0;
++		  planenormal.set_value( 0.0, 0.0, 1.0 );
++      }
++	  
++	  
++	  plane( const vec3 &p0, const vec3 &p1, const vec3 &p2 )
++      {
++		  vec3 v0 = p1 - p0;
++		  vec3 v1 = p2 - p0;
++		  planenormal = v0.cross(v1);  
++		  planenormal.normalize();
++		  planedistance = p0.dot(planenormal);
++      }
++	  
++	  plane( const vec3 &normal, real distance )
++      {
++		  planedistance = distance;
++		  planenormal = normal;
++		  planenormal.normalize();
++      }
++	  
++	  plane( const vec3 &normal, const vec3 &point )
++      {
++		  planenormal = normal;
++		  planenormal.normalize();
++		  planedistance = point.dot(planenormal);
++      }
++	  
++	  void offset( real d )
++      {
++		  planedistance += d;
++      }
++	  
++	  bool intersect( const line &l, vec3 &intersection ) const
++      {
++		  vec3 pos, dir;
++		  vec3 pn = planenormal;
++		  real pd = planedistance;
++		  
++		  pos = l.get_position();
++		  dir = l.get_direction();
++		  
++		  if(dir.dot(pn) == 0.0) return 0;
++		  pos -= pn*pd;
++		  // now we're talking about a plane passing through the origin
++		  if(pos.dot(pn) < 0.0) pn.negate();
++		  if(dir.dot(pn) > 0.0) dir.negate();
++		  vec3 ppos = pn * pos.dot(pn);
++		  pos = (ppos.length()/dir.dot(-pn))*dir;
++		  intersection = l.get_position();
++		  intersection += pos;
++		  return 1;
++      }
++	  void transform( const matrix4 &matrix )
++      {
++		  matrix4 invtr = matrix.inverse();
++		  invtr = invtr.transpose();
++		  
++		  vec3 pntOnplane = planenormal * planedistance;
++		  vec3 newPntOnplane;
++		  vec3 newnormal;
++		  
++		  invtr.mult_dir_matrix(planenormal, newnormal);
++		  matrix.mult_vec_matrix(pntOnplane, newPntOnplane);
++		  
++		  newnormal.normalize();
++		  planenormal = newnormal;
++		  planedistance = newPntOnplane.dot(planenormal);
++      }
++	  
++	  bool is_in_half_space( const vec3 &point ) const
++      {
++		  
++		  if(( point.dot(planenormal) - planedistance) < 0.0)
++			  return 0;
++		  return 1;
++      }
++	  
++	  
++	  real distance( const vec3 & point ) const 
++      {
++		  return planenormal.dot(point - planenormal*planedistance);
++      }
++	  
++	  const vec3 &get_normal() const
++      {
++		  return planenormal;
++      }
++	  
++	  
++	  real get_distance_from_origin() const
++      {
++		  return planedistance;
++      }
++	  
++	  
++	  friend bool operator == ( const plane & p1, const plane & p2 );
++	  
++	  
++	  friend bool operator != ( const plane & p1, const plane & p2 );
++	  
++  //protected:
++	  vec3 planenormal;
++	  real planedistance;
++  };
++  
++  inline
++  bool operator == (const plane & p1, const plane & p2 )
++  {
++	  return (  p1.planedistance == p2.planedistance && p1.planenormal == p2.planenormal);
++  }
++  
++  inline
++  bool operator != ( const plane & p1, const plane & p2 )
++  { return  ! (p1 == p2); }
++  
++  
++
++  } // "ns_##GLH_REAL"
++
++  // make common typedefs...
++#ifdef GLH_REAL_IS_FLOAT
++  typedef GLH_REAL_NAMESPACE::vec2 vec2f;
++  typedef GLH_REAL_NAMESPACE::vec3 vec3f;
++  typedef GLH_REAL_NAMESPACE::vec4 vec4f;
++  typedef GLH_REAL_NAMESPACE::quaternion quaternionf;
++  typedef GLH_REAL_NAMESPACE::quaternion rotationf;
++  typedef GLH_REAL_NAMESPACE::line linef;
++  typedef GLH_REAL_NAMESPACE::plane planef;
++  typedef GLH_REAL_NAMESPACE::matrix4 matrix4f;
++#endif
++
++  
++
++
++}  // namespace glh
++
++
++
++#endif
++
+-- 
+tg: (1836a2b..) topic/fixes/jira-backported/glh_linear (depends on: upstream)
diff --git a/debian/patches/topic/fixes/jira-sent/50_get_cpu_clock_count_for_more_than_just_i386.diff b/debian/patches/topic/fixes/jira-sent/50_get_cpu_clock_count_for_more_than_just_i386.diff
new file mode 100644
index 0000000..c45c564
--- /dev/null
+++ b/debian/patches/topic/fixes/jira-sent/50_get_cpu_clock_count_for_more_than_just_i386.diff
@@ -0,0 +1,40 @@
+From: Robin Cornelius <robin.cornelius at gmail.com>
+Subject: [PATCH] topic/fixes/jira-sent/50_get_cpu_clock_count_for_more_than_just_i386
+
+Fix CPU clock count for non i386 based processors eg PPC.
+
+Signed-off-by: Robin Cornelius <robin.cornelius at gmail.com>
+
+---
+ indra/llcommon/llfasttimer.cpp |   16 ++--------------
+ 1 files changed, 2 insertions(+), 14 deletions(-)
+
+diff --git a/indra/llcommon/llfasttimer.cpp b/indra/llcommon/llfasttimer.cpp
+index 3304528..804d124 100644
+--- a/indra/llcommon/llfasttimer.cpp
++++ b/indra/llcommon/llfasttimer.cpp
+@@ -91,20 +91,8 @@ U64 get_cpu_clock_count()
+ #endif // LL_WINDOWS
+ 
+ 
+-#if (LL_LINUX || LL_SOLARIS) && (defined(__i386__) || defined(__amd64__))
+-U64 get_cpu_clock_count()
+-{
+-	U64 x;
+-	__asm__ volatile (".byte 0x0f, 0x31" : "=A" (x));
+-	return x;
+-}
+-#endif
+-
+-#if LL_DARWIN || (LL_SOLARIS && defined(__sparc__))
+-//
+-// Mac implementation of CPU clock
+-//
+-// Just use gettimeofday implementation for now
++#if LL_LINUX || LL_DARWIN || LL_SOLARIS
++// Both Linux and Mac use gettimeofday for accurate time
+ 
+ U64 get_cpu_clock_count()
+ {
+-- 
+tg: (1836a2b..) topic/fixes/jira-sent/50_get_cpu_clock_count_for_more_than_just_i386 (depends on: upstream)
diff --git a/debian/patches/topic/fixes/jira-sent/59_need_llpreprocessor_to_access_endian_macros.diff b/debian/patches/topic/fixes/jira-sent/59_need_llpreprocessor_to_access_endian_macros.diff
new file mode 100644
index 0000000..992cc28
--- /dev/null
+++ b/debian/patches/topic/fixes/jira-sent/59_need_llpreprocessor_to_access_endian_macros.diff
@@ -0,0 +1,25 @@
+From: Robin Cornelius <robin.cornelius at gmail.com>
+Subject: [PATCH] topic/fixes/jira-sent/59_need_llpreprocessor_to_access_endian_macros
+
+PPC compile fix, give access to endian macros
+
+Signed-off-by: Robin Cornelius <robin.cornelius at gmail.com>
+
+---
+ indra/llmessage/message.h |    1 +
+ 1 files changed, 1 insertions(+), 0 deletions(-)
+
+diff --git a/indra/llmessage/message.h b/indra/llmessage/message.h
+index c503a58..3fae382 100644
+--- a/indra/llmessage/message.h
++++ b/indra/llmessage/message.h
+@@ -48,6 +48,7 @@
+ #include "winsock2.h" // htons etc.
+ #endif
+ 
++#include "llpreprocessor.h"
+ #include "llerror.h"
+ #include "net.h"
+ #include "string_table.h"
+-- 
+tg: (1836a2b..) topic/fixes/jira-sent/59_need_llpreprocessor_to_access_endian_macros (depends on: upstream)
diff --git a/debian/patches/topic/fixes/jira-sent/VWR-10759_delete_LLMediaImplGStreamer_mediaData_as_array.diff b/debian/patches/topic/fixes/jira-sent/VWR-10759_delete_LLMediaImplGStreamer_mediaData_as_array.diff
new file mode 100644
index 0000000..505bde1
--- /dev/null
+++ b/debian/patches/topic/fixes/jira-sent/VWR-10759_delete_LLMediaImplGStreamer_mediaData_as_array.diff
@@ -0,0 +1,27 @@
+From: Carlo Wood <carlo at alinoe.com>
+Subject: [PATCH] topic/fixes/new/delete_LLMediaImplGStreamer_mediaData_as_array
+
+LLMediaImplGStreamer::mediaData is a pointer to an array.
+Delete with operator [] instead of operator delete.
+
+Signed-off-by: Carlo Wood <carlo at alinoe.com>
+
+---
+ indra/llmedia/llmediaimplgstreamer.cpp |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/indra/llmedia/llmediaimplgstreamer.cpp b/indra/llmedia/llmediaimplgstreamer.cpp
+index 51614c5..72d9662 100644
+--- a/indra/llmedia/llmediaimplgstreamer.cpp
++++ b/indra/llmedia/llmediaimplgstreamer.cpp
+@@ -433,7 +433,7 @@ unload ()
+ 
+ 	if (mediaData)
+ 	{
+-		delete mediaData;
++		delete [] mediaData;
+ 		mediaData = NULL;
+ 	}
+ 
+-- 
+tg: (0c171bf..) topic/fixes/jira-sent/VWR-10759_delete_LLMediaImplGStreamer_mediaData_as_array (depends on: upstream)
diff --git a/debian/patches/topic/fixes/jira-sent/VWR-11128-Find_Python.diff b/debian/patches/topic/fixes/jira-sent/VWR-11128-Find_Python.diff
new file mode 100644
index 0000000..072943e
--- /dev/null
+++ b/debian/patches/topic/fixes/jira-sent/VWR-11128-Find_Python.diff
@@ -0,0 +1,29 @@
+From: Robin Cornelius <robin.cornelius at gmail.com>
+Subject: [PATCH] topic/fixes/jira-sent/VWR-11128-Find_Python
+
+<patch description>
+
+Signed-off-by: Robin Cornelius <robin.cornelius at gmail.com>
+
+---
+ indra/cmake/Python.cmake |    5 +++++
+ 1 files changed, 5 insertions(+), 0 deletions(-)
+
+diff --git a/indra/cmake/Python.cmake b/indra/cmake/Python.cmake
+index 4f86d32..e23e2ca 100644
+--- a/indra/cmake/Python.cmake
++++ b/indra/cmake/Python.cmake
+@@ -13,6 +13,11 @@ if (WINDOWS)
+     [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.5\\InstallPath]
+     [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.4\\InstallPath]
+     [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.3\\InstallPath]
++    [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\2.6\\InstallPath]
++    [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\2.5\\InstallPath]
++    [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\2.4\\InstallPath]
++    [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\2.3\\InstallPath]
++
+     )
+ elseif (EXISTS /etc/debian_version)
+   # On Debian and Ubuntu, avoid Python 2.4 if possible.
+-- 
+tg: (1836a2b..) topic/fixes/jira-sent/VWR-11128-Find_Python (depends on: upstream)
diff --git a/debian/patches/topic/fixes/jira-sent/VWR-11138_Develop_py_and_express_VS.diff b/debian/patches/topic/fixes/jira-sent/VWR-11138_Develop_py_and_express_VS.diff
new file mode 100644
index 0000000..713219e
--- /dev/null
+++ b/debian/patches/topic/fixes/jira-sent/VWR-11138_Develop_py_and_express_VS.diff
@@ -0,0 +1,89 @@
+From: Robin Cornelius <robin.cornelius at gmail.com>
+Subject: [PATCH] topic/fixes/jira-sent/VWR-11138_Develop_py_and_express_VS
+
+<patch description>
+
+Signed-off-by: Robin Cornelius <robin.cornelius at gmail.com>
+
+---
+ indra/develop.py |   49 ++++++++++++++++++++++++++++++++++++++++++++++---
+ 1 files changed, 46 insertions(+), 3 deletions(-)
+
+diff --git a/indra/develop.py b/indra/develop.py
+index 29fe0e8..bb12437 100755
+--- a/indra/develop.py
++++ b/indra/develop.py
+@@ -464,8 +464,15 @@ class WindowsSetup(PlatformSetup):
+                     print 'Building with ', self.gens[version]['gen']
+                     break
+             else:
+-                print >> sys.stderr, 'Cannot find a Visual Studio installation!'
+-                eys.exit(1)
++                print >> sys.stderr, 'Cannot find a Visual Studio installation, testing for express editions'
++                for version in 'vc80 vc90 vc71'.split():
++                    if self.find_visual_studio_express(version):
++                        self._generator = version
++                        print 'Building with ', self.gens[version]['gen'] , "Express edition"
++                        break
++                else:
++                    print >> sys.stderr, 'Cannot find any Visual Studio installation'
++                    eys.exit(1)
+         return self._generator
+ 
+     def _set_generator(self, gen):
+@@ -515,6 +522,29 @@ class WindowsSetup(PlatformSetup):
+         except WindowsError, err:
+             print >> sys.stderr, "Didn't find ", self.gens[gen]['gen']
+             return ''
++        
++    def find_visual_studio_express(self, gen=None):
++        if gen is None:
++            gen = self._generator
++        gen = gen.lower()
++        try:
++            import _winreg
++            key_str = (r'SOFTWARE\Microsoft\VCEXpress\%s\Setup\VC' %
++                       self.gens[gen]['ver'])
++            value_str = (r'ProductDir')
++            print ('Reading VS environment from HKEY_LOCAL_MACHINE\%s\%s' %
++                   (key_str, value_str))
++            print key_str
++
++            reg = _winreg.ConnectRegistry(None, _winreg.HKEY_LOCAL_MACHINE)
++            key = _winreg.OpenKey(reg, key_str)
++            value = _winreg.QueryValueEx(key, value_str)[0]+"IDE"
++            print 'Found: %s' % value
++            return value
++        except WindowsError, err:
++            print >> sys.stderr, "Didn't find ", self.gens[gen]['gen']
++            return ''
++
+ 
+     def get_build_cmd(self):
+         if self.incredibuild:
+@@ -524,9 +554,22 @@ class WindowsSetup(PlatformSetup):
+ 
+             return "buildconsole Secondlife.sln /build %s" % config
+ 
++        environment = self.find_visual_studio()
++        if environment == '':
++            environment = self.find_visual_studio_express()
++            if environment == '':
++                 print >> sys.stderr, "Something went very wrong during build stage, could not find a Visual Studio?"
++            else:
++                 print >> sys.stderr, "\nSolution generation complete, as you are using an express edition the final\n stages will need to be completed by hand"
++                 build_dirs=self.build_dirs();
++                 print >> sys.stderr, "Solution can now be found in:", build_dirs[0]
++                 print >> sys.stderr, "Set secondlife-bin as startup project"
++                 print >> sys.stderr, "Set build target is Release or RelWithDbgInfo"
++                 exit(0)
++    
+         # devenv.com is CLI friendly, devenv.exe... not so much.
+         return ('"%sdevenv.com" Secondlife.sln /build %s' % 
+-                (self.find_visual_studio(), self.build_type))
++                (environment, self.build_type))
+ 
+     # this override of run exists because the PlatformSetup version
+     # uses Unix/Mac only calls. Freakin' os module!
+-- 
+tg: (1836a2b..) topic/fixes/jira-sent/VWR-11138_Develop_py_and_express_VS (depends on: upstream)
diff --git a/debian/patches/topic/fixes/jira-sent/VWR-12691_use_do_while_for_statement_macros.diff b/debian/patches/topic/fixes/jira-sent/VWR-12691_use_do_while_for_statement_macros.diff
new file mode 100644
index 0000000..682e4f5
--- /dev/null
+++ b/debian/patches/topic/fixes/jira-sent/VWR-12691_use_do_while_for_statement_macros.diff
@@ -0,0 +1,402 @@
+From: Carlo Wood <carlo at alinoe.com>
+Subject: [PATCH] topic/fixes/jira-sent/VWR-12691_use_do_while_for_statement_macros
+
+lllog and llendl are macros that together look like
+a statment (lllog() << ... << llendl). But the way
+they are defined currently, they are not.
+
+This patches fixes this.
+
+Signed-off-by: Carlo Wood <carlo at alinoe.com>
+
+---
+ indra/llcharacter/llgesture.cpp              |    2 +-
+ indra/llcharacter/lljointsolverrp3.cpp       |    2 +-
+ indra/llcommon/llerror.h                     |    4 ++--
+ indra/llmath/llvolume.cpp                    |    2 +-
+ indra/llmessage/lltemplatemessagebuilder.cpp |    2 +-
+ indra/llprimitive/llprimitive.cpp            |   26 +++++++++++++-------------
+ indra/llrender/llcubemap.cpp                 |    2 +-
+ indra/llrender/llfont.cpp                    |    2 +-
+ indra/llrender/llrender.cpp                  |    2 +-
+ indra/llwindow/llwindowmacosx.cpp            |    6 +++---
+ indra/llwindow/llwindowsdl.cpp               |   12 ++++++------
+ indra/newview/llmaniprotate.cpp              |    4 ++--
+ indra/newview/llpreviewgesture.cpp           |    2 +-
+ indra/newview/llpreviewscript.cpp            |    2 +-
+ indra/newview/llstatview.cpp                 |    2 +-
+ indra/newview/llvoiceclient.cpp              |    6 +++---
+ 16 files changed, 39 insertions(+), 39 deletions(-)
+
+diff --git a/indra/llcharacter/llgesture.cpp b/indra/llcharacter/llgesture.cpp
+index 7c55e92..367d876 100644
+--- a/indra/llcharacter/llgesture.cpp
++++ b/indra/llcharacter/llgesture.cpp
+@@ -303,7 +303,7 @@ BOOL LLGestureList::trigger(KEY key, MASK mask)
+ 		}
+ 		else
+ 		{
+-			llwarns << "NULL gesture in gesture list (" << i << ")" << llendl
++			llwarns << "NULL gesture in gesture list (" << i << ")" << llendl;
+ 		}
+ 	}
+ 	return FALSE;
+diff --git a/indra/llcharacter/lljointsolverrp3.cpp b/indra/llcharacter/lljointsolverrp3.cpp
+index f7e6dc7..a19759e 100644
+--- a/indra/llcharacter/lljointsolverrp3.cpp
++++ b/indra/llcharacter/lljointsolverrp3.cpp
+@@ -210,7 +210,7 @@ void LLJointSolverRP3::solve()
+ 	//-------------------------------------------------------------------------
+ 	LLVector3 abacCompOrthoVec = abVec - acVec * ((abVec * acVec)/(acVec * acVec));
+ 
+-//	llinfos << "abacCompOrthoVec : " << abacCompOrthoVec << llendl
++//	llinfos << "abacCompOrthoVec : " << abacCompOrthoVec << llendl;
+ 
+ 	//-------------------------------------------------------------------------
+ 	// compute the normal of the original ABC plane (and store for later)
+diff --git a/indra/llcommon/llerror.h b/indra/llcommon/llerror.h
+index 211f89f..9560cdb 100644
+--- a/indra/llcommon/llerror.h
++++ b/indra/llcommon/llerror.h
+@@ -204,7 +204,7 @@ typedef LLError::NoClassInfo _LL_CLASS_TO_LOG;
+ */
+ 
+ #define lllog(level, broadTag, narrowTag, once) \
+-	{ \
++	do { \
+ 		static LLError::CallSite _site( \
+ 			level, __FILE__, __LINE__, typeid(_LL_CLASS_TO_LOG), __FUNCTION__, broadTag, narrowTag, once);\
+ 		if (_site.shouldLog()) \
+@@ -217,7 +217,7 @@ typedef LLError::NoClassInfo _LL_CLASS_TO_LOG;
+ 			LLError::End(); \
+ 			LLError::Log::flush(_out, _site); \
+ 		} \
+-	}
++	} while(0)
+ 
+ // DEPRECATED: Use the new macros that allow tags and *look* like macros.
+ #define lldebugs	lllog(LLError::LEVEL_DEBUG, NULL, NULL, false)
+diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
+index 5603a9c..75968a3 100644
+--- a/indra/llmath/llvolume.cpp
++++ b/indra/llmath/llvolume.cpp
+@@ -4247,7 +4247,7 @@ LLFaceID LLVolume::generateFaceMask()
+ 		}
+ 		break;
+ 	default:
+-		llerrs << "Unknown profile!" << llendl
++		llerrs << "Unknown profile!" << llendl;
+ 		break;
+ 	}
+ 
+diff --git a/indra/llmessage/lltemplatemessagebuilder.cpp b/indra/llmessage/lltemplatemessagebuilder.cpp
+index 2d8f3cf..dd4ac9a 100644
+--- a/indra/llmessage/lltemplatemessagebuilder.cpp
++++ b/indra/llmessage/lltemplatemessagebuilder.cpp
+@@ -729,7 +729,7 @@ static S32 buildBlock(U8* buffer, S32 buffer_size, const LLMessageBlock* templat
+ 							<< "Attempted to pack "
+ 							<< result + mvci.getSize()
+ 							<< " bytes into a buffer with size "
+-							<< buffer_size << "." << llendl
++							<< buffer_size << "." << llendl;
+ 					}						
+ 				}
+ 			}
+diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp
+index dc389c1..0cf58d0 100644
+--- a/indra/llprimitive/llprimitive.cpp
++++ b/indra/llprimitive/llprimitive.cpp
+@@ -305,7 +305,7 @@ S32  LLPrimitive::setTETexture(const U8 te, const LLUUID &tex_id)
+     // if we're asking for a non-existent face, return null
+ 	if (te >= mNumTEs)
+ 	{
+-		llwarns << "setting non-existent te " << te << llendl
++		llwarns << "setting non-existent te " << te << llendl;
+ 		return 0;
+ 	}
+ 
+@@ -317,7 +317,7 @@ S32  LLPrimitive::setTEColor(const U8 te, const LLColor4 &color)
+     // if we're asking for a non-existent face, return null
+ 	if (te >= mNumTEs)
+ 	{
+-		llwarns << "setting non-existent te " << te << llendl
++		llwarns << "setting non-existent te " << te << llendl;
+ 		return 0;
+ 	}
+ 
+@@ -329,7 +329,7 @@ S32  LLPrimitive::setTEColor(const U8 te, const LLColor3 &color)
+     // if we're asking for a non-existent face, return null
+ 	if (te >= mNumTEs)
+ 	{
+-		llwarns << "setting non-existent te " << te << llendl
++		llwarns << "setting non-existent te " << te << llendl;
+ 		return 0;
+ 	}
+ 
+@@ -341,7 +341,7 @@ S32  LLPrimitive::setTEAlpha(const U8 te, const F32 alpha)
+     // if we're asking for a non-existent face, return null
+ 	if (te >= mNumTEs)
+ 	{
+-		llwarns << "setting non-existent te " << te << llendl
++		llwarns << "setting non-existent te " << te << llendl;
+ 		return 0;
+ 	}
+ 
+@@ -460,7 +460,7 @@ S32  LLPrimitive::setTEBumpShinyFullbright(const U8 te, const U8 bump)
+     // if we're asking for a non-existent face, return null
+ 	if (te >= mNumTEs)
+ 	{
+-		llwarns << "setting non-existent te " << te << llendl
++		llwarns << "setting non-existent te " << te << llendl;
+ 		return 0;
+ 	}
+ 
+@@ -472,7 +472,7 @@ S32  LLPrimitive::setTEMediaTexGen(const U8 te, const U8 media)
+     // if we're asking for a non-existent face, return null
+ 	if (te >= mNumTEs)
+ 	{
+-		llwarns << "setting non-existent te " << te << llendl
++		llwarns << "setting non-existent te " << te << llendl;
+ 		return 0;
+ 	}
+ 
+@@ -484,7 +484,7 @@ S32  LLPrimitive::setTEBumpmap(const U8 te, const U8 bump)
+     // if we're asking for a non-existent face, return null
+ 	if (te >= mNumTEs)
+ 	{
+-		llwarns << "setting non-existent te " << te << llendl
++		llwarns << "setting non-existent te " << te << llendl;
+ 		return 0;
+ 	}
+ 
+@@ -496,7 +496,7 @@ S32  LLPrimitive::setTEBumpShiny(const U8 te, const U8 bump_shiny)
+     // if we're asking for a non-existent face, return null
+ 	if (te >= mNumTEs)
+ 	{
+-		llwarns << "setting non-existent te " << te << llendl
++		llwarns << "setting non-existent te " << te << llendl;
+ 		return 0;
+ 	}
+ 
+@@ -508,7 +508,7 @@ S32  LLPrimitive::setTETexGen(const U8 te, const U8 texgen)
+     // if we're asking for a non-existent face, return null
+ 	if (te >= mNumTEs)
+ 	{
+-		llwarns << "setting non-existent te " << te << llendl
++		llwarns << "setting non-existent te " << te << llendl;
+ 		return 0;
+ 	}
+ 
+@@ -520,7 +520,7 @@ S32  LLPrimitive::setTEShiny(const U8 te, const U8 shiny)
+     // if we're asking for a non-existent face, return null
+ 	if (te >= mNumTEs)
+ 	{
+-		llwarns << "setting non-existent te " << te << llendl
++		llwarns << "setting non-existent te " << te << llendl;
+ 		return 0;
+ 	}
+ 
+@@ -532,7 +532,7 @@ S32  LLPrimitive::setTEFullbright(const U8 te, const U8 fullbright)
+     // if we're asking for a non-existent face, return null
+ 	if (te >= mNumTEs)
+ 	{
+-		llwarns << "setting non-existent te " << te << llendl
++		llwarns << "setting non-existent te " << te << llendl;
+ 		return 0;
+ 	}
+ 
+@@ -544,7 +544,7 @@ S32  LLPrimitive::setTEMediaFlags(const U8 te, const U8 media_flags)
+     // if we're asking for a non-existent face, return null
+ 	if (te >= mNumTEs)
+ 	{
+-		llwarns << "setting non-existent te " << te << llendl
++		llwarns << "setting non-existent te " << te << llendl;
+ 		return 0;
+ 	}
+ 
+@@ -556,7 +556,7 @@ S32 LLPrimitive::setTEGlow(const U8 te, const F32 glow)
+ 	// if we're asking for a non-existent face, return null
+ 	if (te >= mNumTEs)
+ 	{
+-		llwarns << "setting non-existent te " << te << llendl
++		llwarns << "setting non-existent te " << te << llendl;
+ 			return 0;
+ 	}
+ 
+diff --git a/indra/llrender/llcubemap.cpp b/indra/llrender/llcubemap.cpp
+index 60215f0..2b2f87c 100644
+--- a/indra/llrender/llcubemap.cpp
++++ b/indra/llrender/llcubemap.cpp
+@@ -105,7 +105,7 @@ void LLCubeMap::initGL()
+ 	}
+ 	else
+ 	{
+-		llwarns << "Using cube map without extension!" << llendl
++		llwarns << "Using cube map without extension!" << llendl;
+ 	}
+ }
+ 
+diff --git a/indra/llrender/llfont.cpp b/indra/llrender/llfont.cpp
+index d7310bd..d4a51cf 100644
+--- a/indra/llrender/llfont.cpp
++++ b/indra/llrender/llfont.cpp
+@@ -357,7 +357,7 @@ BOOL LLFont::addChar(const llwchar wch)
+ 		// Try looking it up in the backup Unicode font
+ 		if (mFallbackFontp)
+ 		{
+-			//llinfos << "Trying to add glyph from fallback font!" << llendl
++			//llinfos << "Trying to add glyph from fallback font!" << llendl;
+ 			LLFontList::iterator iter;
+ 			for(iter = mFallbackFontp->begin(); iter != mFallbackFontp->end(); iter++)
+ 			{
+diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
+index ff0a2db..6b4fc2e 100644
+--- a/indra/llrender/llrender.cpp
++++ b/indra/llrender/llrender.cpp
+@@ -221,7 +221,7 @@ bool LLTexUnit::bind(LLCubeMap* cubeMap)
+ 		}
+ 		else
+ 		{
+-			llwarns << "Using cube map without extension!" << llendl
++			llwarns << "Using cube map without extension!" << llendl;
+ 		}
+ 	}
+ 	return false;
+diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
+index 3ddf5e6..8d634ee 100644
+--- a/indra/llwindow/llwindowmacosx.cpp
++++ b/indra/llwindow/llwindowmacosx.cpp
+@@ -1377,11 +1377,11 @@ void LLWindowMacOSX::setMouseClipping( BOOL b )
+ 
+ 	if(b)
+ 	{
+-		//		llinfos << "setMouseClipping(TRUE)" << llendl
++		//		llinfos << "setMouseClipping(TRUE)" << llendl;
+ 	}
+ 	else
+ 	{
+-		//		llinfos << "setMouseClipping(FALSE)" << llendl
++		//		llinfos << "setMouseClipping(FALSE)" << llendl;
+ 	}
+ 
+ 	adjustCursorDecouple();
+@@ -1399,7 +1399,7 @@ BOOL LLWindowMacOSX::setCursorPosition(const LLCoordWindow position)
+ 
+ 	CGPoint newPosition;
+ 
+-	//	llinfos << "setCursorPosition(" << screen_pos.mX << ", " << screen_pos.mY << ")" << llendl
++	//	llinfos << "setCursorPosition(" << screen_pos.mX << ", " << screen_pos.mY << ")" << llendl;
+ 
+ 	newPosition.x = screen_pos.mX;
+ 	newPosition.y = screen_pos.mY;
+diff --git a/indra/llwindow/llwindowsdl.cpp b/indra/llwindow/llwindowsdl.cpp
+index 777b32d..57941dd 100644
+--- a/indra/llwindow/llwindowsdl.cpp
++++ b/indra/llwindow/llwindowsdl.cpp
+@@ -658,12 +658,12 @@ BOOL LLWindowSDL::createContext(int x, int y, int width, int height, int bits, B
+ 	glGetIntegerv(GL_DEPTH_BITS, &depthBits);
+ 	glGetIntegerv(GL_STENCIL_BITS, &stencilBits);
+ 	
+-	llinfos << "GL buffer:" << llendl
+-        llinfos << "  Red Bits " << S32(redBits) << llendl
+-        llinfos << "  Green Bits " << S32(greenBits) << llendl
+-        llinfos << "  Blue Bits " << S32(blueBits) << llendl
+-	llinfos	<< "  Alpha Bits " << S32(alphaBits) << llendl
+-	llinfos	<< "  Depth Bits " << S32(depthBits) << llendl
++	llinfos << "GL buffer:" << llendl;
++        llinfos << "  Red Bits " << S32(redBits) << llendl;
++        llinfos << "  Green Bits " << S32(greenBits) << llendl;
++        llinfos << "  Blue Bits " << S32(blueBits) << llendl;
++	llinfos	<< "  Alpha Bits " << S32(alphaBits) << llendl;
++	llinfos	<< "  Depth Bits " << S32(depthBits) << llendl;
+ 	llinfos	<< "  Stencil Bits " << S32(stencilBits) << llendl;
+ 
+ 	GLint colorBits = redBits + greenBits + blueBits + alphaBits;
+diff --git a/indra/newview/llmaniprotate.cpp b/indra/newview/llmaniprotate.cpp
+index 3ed4685..6b4ba27 100644
+--- a/indra/newview/llmaniprotate.cpp
++++ b/indra/newview/llmaniprotate.cpp
+@@ -1233,9 +1233,9 @@ LLVector3 LLManipRotate::getConstraintAxis()
+ 		else
+ 		{
+ #ifndef LL_RELEASE_FOR_DOWNLOAD
+-			llerrs << "Got bogus hit part in LLManipRotate::getConstraintAxis():" << mManipPart << llendl
++			llerrs << "Got bogus hit part in LLManipRotate::getConstraintAxis():" << mManipPart << llendl;
+ #else
+-			llwarns << "Got bogus hit part in LLManipRotate::getConstraintAxis():" << mManipPart << llendl
++			llwarns << "Got bogus hit part in LLManipRotate::getConstraintAxis():" << mManipPart << llendl;
+ #endif
+ 			axis.mV[0] = 1.f;
+ 		}
+diff --git a/indra/newview/llpreviewgesture.cpp b/indra/newview/llpreviewgesture.cpp
+index c018e4d..d004e7b 100644
+--- a/indra/newview/llpreviewgesture.cpp
++++ b/indra/newview/llpreviewgesture.cpp
+@@ -1238,7 +1238,7 @@ void LLPreviewGesture::onSaveComplete(const LLUUID& asset_uuid, void* user_data,
+ 			else
+ 			{
+ 				llwarns << "Inventory item for gesture " << info->mItemUUID
+-						<< " is no longer in agent inventory." << llendl
++						<< " is no longer in agent inventory." << llendl;
+ 			}
+ 		}
+ 		else
+diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp
+index af52a4b..9b104fb 100644
+--- a/indra/newview/llpreviewscript.cpp
++++ b/indra/newview/llpreviewscript.cpp
+@@ -1424,7 +1424,7 @@ void LLPreviewLSL::onSaveComplete(const LLUUID& asset_uuid, void* user_data, S32
+ 			else
+ 			{
+ 				llwarns << "Inventory item for script " << info->mItemUUID
+-					<< " is no longer in agent inventory." << llendl
++					<< " is no longer in agent inventory." << llendl;
+ 			}
+ 
+ 			// Find our window and close it if requested.
+diff --git a/indra/newview/llstatview.cpp b/indra/newview/llstatview.cpp
+index 7d20639..59feeb0 100644
+--- a/indra/newview/llstatview.cpp
++++ b/indra/newview/llstatview.cpp
+@@ -74,7 +74,7 @@ LLStatBar *LLStatView::addStat(const std::string& name, LLStat *statp)
+ 
+ //	if (getStatBar(name))
+ //	{
+-//		llinfos << "LLStatView::addStat - Stat already exists!" << llendl
++//		llinfos << "LLStatView::addStat - Stat already exists!" << llendl;
+ //		return NULL;
+ //	}
+ 
+diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp
+index 76ef87d..7e4253a 100644
+--- a/indra/newview/llvoiceclient.cpp
++++ b/indra/newview/llvoiceclient.cpp
+@@ -4881,7 +4881,7 @@ void LLVoiceClient::sessionState::removeAllParticipants()
+ 	
+ 	if(!mParticipantsByUUID.empty())
+ 	{
+-		LL_ERRS("Voice") << "Internal error: empty URI map, non-empty UUID map" << LL_ENDL
++		LL_ERRS("Voice") << "Internal error: empty URI map, non-empty UUID map" << LL_ENDL;
+ 	}
+ }
+ 
+@@ -6243,7 +6243,7 @@ void LLVoiceClient::deleteSession(sessionState *session)
+ 		{
+ 			if(iter->second != session)
+ 			{
+-				LL_ERRS("Voice") << "Internal error: session mismatch" << LL_ENDL
++				LL_ERRS("Voice") << "Internal error: session mismatch" << LL_ENDL;
+ 			}
+ 			mSessionsByHandle.erase(iter);
+ 		}
+@@ -6283,7 +6283,7 @@ void LLVoiceClient::deleteAllSessions()
+ 	
+ 	if(!mSessionsByHandle.empty())
+ 	{
+-		LL_ERRS("Voice") << "Internal error: empty session map, non-empty handle map" << LL_ENDL
++		LL_ERRS("Voice") << "Internal error: empty session map, non-empty handle map" << LL_ENDL;
+ 	}
+ }
+ 
+-- 
+tg: (1836a2b..) topic/fixes/jira-sent/VWR-12691_use_do_while_for_statement_macros (depends on: upstream)
diff --git a/debian/patches/topic/fixes/jira-sent/VWR-1815_top_corner_fix.diff b/debian/patches/topic/fixes/jira-sent/VWR-1815_top_corner_fix.diff
new file mode 100644
index 0000000..b0bb679
--- /dev/null
+++ b/debian/patches/topic/fixes/jira-sent/VWR-1815_top_corner_fix.diff
@@ -0,0 +1,68 @@
+From: Robin Cornelius <robin.cornelius at gmail.com>
+Subject: [PATCH] topic/fixes/jira-sent/VWR-1815_top_corner_fix
+
+Remains of the top corner texture fix, this part accellerates downloads
+for stuck textures
+
+Signed-off-by: Robin Cornelius <robin.cornelius at gmail.com>
+
+---
+ indra/newview/lltexturefetch.cpp |   22 +++++++++++++++++++++-
+ 1 files changed, 21 insertions(+), 1 deletions(-)
+
+diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp
+index 24046cc..c99c9bc 100644
+--- a/indra/newview/lltexturefetch.cpp
++++ b/indra/newview/lltexturefetch.cpp
+@@ -53,6 +53,9 @@ class LLTextureFetchWorker : public LLWorkerClass
+ {
+ friend class LLTextureFetch;
+ 
++public:
++	BOOL mAccelerateDownloadStuckTexture;
++
+ private:
+ #if 0
+ 	class URLResponder : public LLHTTPClient::Responder
+@@ -1074,6 +1077,20 @@ bool LLTextureFetchWorker::processSimulatorPackets()
+ 			buffer_size += mPackets[i]->mSize;
+ 		}
+ 		bool have_all_data = mLastPacket >= mTotalPackets-1;
++		//llassert_always(mRequestedSize > 0);
++		if(mRequestedSize<=0)
++		{
++			llwarns << "asserting mRequestedSize > 0, aborting this processSimulatorPackets run" << llendl;
++			return false;
++		}		
++
++		if((buffer_size >= mRequestedSize) && mRequestedDiscard <=0)
++ 		{
++			if(!mAccelerateDownloadStuckTexture);
++				llwarns << "Accelerating download of a stuck texture :"<<mID << llendl;
++			mAccelerateDownloadStuckTexture=TRUE;
++		}
++		
+ 		if (buffer_size >= mRequestedSize || have_all_data)
+ 		{
+ 			/// We have enough (or all) data
+@@ -1575,6 +1592,7 @@ void LLTextureFetch::sendRequestListToSimulators()
+ 	const F32 LAZY_FLUSH_TIMEOUT = 15.f; // 10.0f // temp
+ 	const F32 MIN_REQUEST_TIME = 1.0f;
+ 	const F32 MIN_DELTA_PRIORITY = 1000.f;
++	const F32 MIN_ACCEL_KICK = 0.5f;
+ 
+ 	LLMutexLock lock(&mQueueMutex);
+ 	
+@@ -1605,7 +1623,9 @@ void LLTextureFetch::sendRequestListToSimulators()
+ 		F32 delta_priority = llabs(req->mRequestedPriority - req->mImagePriority);
+ 		if ((req->mSimRequestedDiscard != req->mDesiredDiscard) ||
+ 			(delta_priority > MIN_DELTA_PRIORITY && elapsed >= MIN_REQUEST_TIME) ||
+-			(elapsed >= LAZY_FLUSH_TIMEOUT))
++			(elapsed >= LAZY_FLUSH_TIMEOUT) ||
++			(req->mAccelerateDownloadStuckTexture && (elapsed >=MIN_ACCEL_KICK))
++			)
+ 		{
+ 			requests[req->mHost].insert(req);
+ 		}
+-- 
+tg: (1836a2b..) topic/fixes/jira-sent/VWR-1815_top_corner_fix (depends on: upstream)
diff --git a/debian/patches/topic/fixes/jira-sent/VWR-8194_clamp_outline_for_broken_nvidia.diff b/debian/patches/topic/fixes/jira-sent/VWR-8194_clamp_outline_for_broken_nvidia.diff
new file mode 100644
index 0000000..c12e28d
--- /dev/null
+++ b/debian/patches/topic/fixes/jira-sent/VWR-8194_clamp_outline_for_broken_nvidia.diff
@@ -0,0 +1,38 @@
+From: Robin Cornelius <robin.cornelius at gmail.com>
+Subject: [PATCH] topic/fixes/jira-sent/VWR-8194_clamp_outline_for_broken_nvidia
+
+Prevent buffer overflow in temp GL matrix
+
+Signed-off-by: Robin Cornelius <robin.cornelius at gmail.com>
+
+---
+ indra/llrender/llrender.cpp |    7 +++++++
+ 1 files changed, 7 insertions(+), 0 deletions(-)
+
+diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
+index ff0a2db..f2b4352 100644
+--- a/indra/llrender/llrender.cpp
++++ b/indra/llrender/llrender.cpp
+@@ -899,6 +899,9 @@ void LLRender::vertex3fv(const GLfloat* v)
+ 
+ void LLRender::texCoord2f(const GLfloat& x, const GLfloat& y)
+ { 
++	if (mCount >= 4096)
++		return;
++
+ 	mTexcoordsp[mCount] = LLVector2(x,y);
+ }
+ 
+@@ -914,6 +917,10 @@ void LLRender::texCoord2fv(const GLfloat* tc)
+ 
+ void LLRender::color4ub(const GLubyte& r, const GLubyte& g, const GLubyte& b, const GLubyte& a)
+ {
++
++	if (mCount >= 4096)
++		return;
++
+ 	mColorsp[mCount] = LLColor4U(r,g,b,a);
+ }
+ void LLRender::color4ubv(const GLubyte* c)
+-- 
+tg: (1836a2b..) topic/fixes/jira-sent/VWR-8194_clamp_outline_for_broken_nvidia (depends on: upstream)
diff --git a/debian/patches/topic/fixes/jira-sent/VWR-9557-EnableBuildWithNvidiaOrMesaHeaders.diff b/debian/patches/topic/fixes/jira-sent/VWR-9557-EnableBuildWithNvidiaOrMesaHeaders.diff
new file mode 100644
index 0000000..00e7be1
--- /dev/null
+++ b/debian/patches/topic/fixes/jira-sent/VWR-9557-EnableBuildWithNvidiaOrMesaHeaders.diff
@@ -0,0 +1,75 @@
+From: Robin Cornelius <robin.cornelius at gmail.com>
+Subject: [PATCH] topic/fixes/jira-sent/VWR-9557-EnableBuildWithNvidiaOrMesaHeaders
+
+Enable the build to succeed with either the mesa gl.h or the nvidia gl.h headers
+
+Signed-off-by: Robin Cornelius <robin.cornelius at gmail.com>
+
+---
+ indra/llrender/llgl.cpp      |   17 ++++++++++++++---
+ indra/llrender/llglheaders.h |    9 +++++++++
+ 2 files changed, 23 insertions(+), 3 deletions(-)
+
+diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
+index a9cf073..88b1671 100644
+--- a/indra/llrender/llgl.cpp
++++ b/indra/llrender/llgl.cpp
+@@ -252,6 +252,12 @@ PFNWGLSWAPINTERVALEXTPROC			wglSwapIntervalEXT = NULL;
+ PFNGLCOLORTABLEEXTPROC glColorTableEXT = NULL;
+ #endif // LL_LINUX
+ 
++#if LL_LINUX && defined(WINGDIAPI)
++PFNGLACTIVETEXTUREARBPROC	glActiveTextureARB=NULL;
++PFNGLCLIENTACTIVETEXTUREARBPROC	glClientActiveTextureARB=NULL;
++PFNGLDRAWRANGEELEMENTSPROC 	glDrawRangeElements=NULL;
++#endif
++
+ #endif
+ 
+ LLGLManager gGLManager;
+@@ -762,15 +768,20 @@ void LLGLManager::initExtensions()
+ 		glGetFramebufferAttachmentParameterivEXT = (PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glGetFramebufferAttachmentParameterivEXT");
+ 		glGenerateMipmapEXT = (PFNGLGENERATEMIPMAPEXTPROC) GLH_EXT_GET_PROC_ADDRESS("glGenerateMipmapEXT");
+ 	}
+-#if !LL_LINUX
+-	// This is expected to be a static symbol on Linux GL implementations
++#if !LL_LINUX || (LL_LINUX && defined(WINGDIAPI))
++	// This is expected to be a static symbol on Linux GL implementations, except if we use the nvidia headers
+ 	glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC)GLH_EXT_GET_PROC_ADDRESS("glDrawRangeElements");
+ 	if (!glDrawRangeElements)
+ 	{
+ 		mGLMaxVertexRange = 0;
+ 		mGLMaxIndexRange = 0;
+ 	}
+-#endif // !LL_LINUX
++#endif //!LL_LINUX
++
++#if LL_LINUX && defined(WINGDIAPI)
++	glActiveTextureARB = (PFNGLACTIVETEXTUREARBPROC)GLH_EXT_GET_PROC_ADDRESS("glActiveTextureARB");
++	glClientActiveTextureARB = (PFNGLCLIENTACTIVETEXTUREARBPROC)GLH_EXT_GET_PROC_ADDRESS("glClientActiveTextureARB");
++#endif
+ 
+ 	if (mHasOcclusionQuery)
+ 	{
+diff --git a/indra/llrender/llglheaders.h b/indra/llrender/llglheaders.h
+index 20a420b..c3035e0 100644
+--- a/indra/llrender/llglheaders.h
++++ b/indra/llrender/llglheaders.h
+@@ -76,6 +76,15 @@
+ #undef Status
+ #endif // LL_LINUX && !LL_MESA_HEADLESS
+ 
++#if LL_LINUX && defined(WINGDIAPI)
++// WINGDIAPI gets set if we are using the linux nvidia gl.h header which needs the 
++// functions below setting up
++// Missing functions when using nvidia header
++extern PFNGLACTIVETEXTUREARBPROC	glActiveTextureARB;
++extern PFNGLCLIENTACTIVETEXTUREARBPROC	glClientActiveTextureARB;
++extern PFNGLDRAWRANGEELEMENTSPROC 	glDrawRangeElements;
++
++#endif
+ 
+ // GL_ARB_vertex_buffer_object
+ extern PFNGLBINDBUFFERARBPROC		glBindBufferARB;
+-- 
+tg: (1836a2b..) topic/fixes/jira-sent/VWR-9557-EnableBuildWithNvidiaOrMesaHeaders (depends on: upstream)
diff --git a/debian/patches/topic/fixes/jira-sent/correctly_find_dbus_headers_on_standalone.diff b/debian/patches/topic/fixes/jira-sent/correctly_find_dbus_headers_on_standalone.diff
new file mode 100644
index 0000000..fdfb2dc
--- /dev/null
+++ b/debian/patches/topic/fixes/jira-sent/correctly_find_dbus_headers_on_standalone.diff
@@ -0,0 +1,42 @@
+From: Robin Cornelius <robin.cornelius at gmail.com>
+Subject: [PATCH] topic/fixes/jira-sent/correctly_find_dbus_headers_on_standalone
+
+Correctly find the DBUS headers in cmake, patch sent up stream to LL and in the queue to be applied
+
+Signed-off-by: Robin Cornelius <robin.cornelius at gmail.com>
+
+---
+ doc/contributions.txt        |    1 +
+ indra/newview/CMakeLists.txt |    5 +++++
+ 2 files changed, 6 insertions(+), 0 deletions(-)
+
+diff --git a/doc/contributions.txt b/doc/contributions.txt
+index 5cc26c2..5f77f91 100644
+--- a/doc/contributions.txt
++++ b/doc/contributions.txt
+@@ -236,6 +236,7 @@ Michelle2 Zenovka
+ 	VWR-8889
+ 	VWR-8310
+ 	VWR-4022
++	VWR-9499
+ Mm Alder
+ 	VWR-3777
+ 	VWR-4794
+diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
+index b95ba37..60fec36 100644
+--- a/indra/newview/CMakeLists.txt
++++ b/indra/newview/CMakeLists.txt
+@@ -60,6 +60,11 @@ include_directories(
+     ${LSCRIPT_INCLUDE_DIRS}/lscript_compile
+     )
+ 
++if (LINUX)
++    include_directories (${DBUSGLIB_INCLUDE_DIRS})
++endif (LINUX)
++
++
+ set(viewer_SOURCE_FILES
+     llagent.cpp
+     llagentdata.cpp
+-- 
+tg: (1836a2b..) topic/fixes/jira-sent/correctly_find_dbus_headers_on_standalone (depends on: upstream)
diff --git a/debian/patches/topic/fixes/jira-sent/dont_depend_on_artwork_to_build.diff b/debian/patches/topic/fixes/jira-sent/dont_depend_on_artwork_to_build.diff
new file mode 100644
index 0000000..d5dec08
--- /dev/null
+++ b/debian/patches/topic/fixes/jira-sent/dont_depend_on_artwork_to_build.diff
@@ -0,0 +1,28 @@
+From: Robin Cornelius <robin.cornelius at gmail.com>
+Subject: [PATCH] topic/fixes/jira-sent/dont_depend_on_artwork_to_build
+
+Do not require the artwork to be present in the cmake tree, sent
+upstream and discussed with BoS expected to be fixed upstream at
+some point.
+
+Signed-off-by: Robin Cornelius <robin.cornelius at gmail.com>
+
+---
+ indra/newview/CMakeLists.txt |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
+index b95ba37..509bfad 100644
+--- a/indra/newview/CMakeLists.txt
++++ b/indra/newview/CMakeLists.txt
+@@ -1245,7 +1245,7 @@ source_group("Character File" FILES ${viewer_CHARACTER_FILES})
+ set_source_files_properties(${viewer_CHARACTER_FILES}
+                             PROPERTIES HEADER_FILE_ONLY TRUE)
+ 
+-list(APPEND viewer_SOURCE_FILES ${viewer_CHARACTER_FILES})
++#list(APPEND viewer_SOURCE_FILES ${viewer_CHARACTER_FILES})
+ 
+ if (WINDOWS)
+   file(GLOB viewer_INSTALLER_FILES installers/windows/*.nsi)
+-- 
+tg: (1836a2b..) topic/fixes/jira-sent/dont_depend_on_artwork_to_build (depends on: upstream)
diff --git a/debian/patches/topic/fixes/jira-sent/gcc_warning_on_llwindowsdl_var_not_set.diff b/debian/patches/topic/fixes/jira-sent/gcc_warning_on_llwindowsdl_var_not_set.diff
new file mode 100644
index 0000000..03d3016
--- /dev/null
+++ b/debian/patches/topic/fixes/jira-sent/gcc_warning_on_llwindowsdl_var_not_set.diff
@@ -0,0 +1,25 @@
+From: Robin Cornelius <robin.cornelius at gmail.com>
+Subject: [PATCH] topic/fixes/jira-sent/gcc_warning_on_llwindowsdl_var_not_set
+
+Prevent FTBFS error with gcc and a wild variable.
+
+Signed-off-by: Robin Cornelius <robin.cornelius at gmail.com>
+
+---
+ indra/llwindow/llwindowsdl.cpp |    1 +
+ 1 files changed, 1 insertions(+), 0 deletions(-)
+
+diff --git a/indra/llwindow/llwindowsdl.cpp b/indra/llwindow/llwindowsdl.cpp
+index 777b32d..f3f3c04 100644
+--- a/indra/llwindow/llwindowsdl.cpp
++++ b/indra/llwindow/llwindowsdl.cpp
+@@ -2644,6 +2644,7 @@ BOOL LLWindowSDL::dialog_color_picker ( F32 *r, F32 *g, F32 *b)
+ 		orig_color.red = guint16(65535 * *r);
+ 		orig_color.green= guint16(65535 * *g);
+ 		orig_color.blue = guint16(65535 * *b);
++		orig_color.pixel = -1; //Default this to something or the copy next will produce a gcc warning
+ 		color = orig_color;
+ 
+ 		gtk_color_selection_set_previous_color (colorsel, &color);
+-- 
+tg: (1836a2b..) topic/fixes/jira-sent/gcc_warning_on_llwindowsdl_var_not_set (depends on: upstream)
diff --git a/debian/patches/topic/fixes/jira-sent/lltemplatemessagereader_memcpy.diff b/debian/patches/topic/fixes/jira-sent/lltemplatemessagereader_memcpy.diff
new file mode 100644
index 0000000..33e0ed4
--- /dev/null
+++ b/debian/patches/topic/fixes/jira-sent/lltemplatemessagereader_memcpy.diff
@@ -0,0 +1,27 @@
+From: Robin Cornelius <robin.cornelius at gmail.com>
+Subject: [PATCH] topic/fixes/jira-sent/lltemplatemessagereader_memcpy
+
+Fix gcc FTBFS bug, possibly a gcc bug.
+
+Signed-off-by: Robin Cornelius <robin.cornelius at gmail.com>
+
+---
+ indra/llmessage/lltemplatemessagereader.cpp |    3 ++-
+ 1 files changed, 2 insertions(+), 1 deletions(-)
+
+diff --git a/indra/llmessage/lltemplatemessagereader.cpp b/indra/llmessage/lltemplatemessagereader.cpp
+index 7a7d3bb..aef2d33 100644
+--- a/indra/llmessage/lltemplatemessagereader.cpp
++++ b/indra/llmessage/lltemplatemessagereader.cpp
+@@ -676,7 +676,8 @@ BOOL LLTemplateMessageReader::decodeData(const U8* buffer, const LLHost& sender
+ 						// default to 0s.
+ 						U32 size = mvci.getSize();
+ 						std::vector<U8> data(size);
+-						memset(&(data[0]), 0, size);
++						if(size>0)
++							memset(&(data[0]), 0, size);
+ 						cur_data_block->addData(mvci.getName(), &(data[0]), 
+ 												size, mvci.getType());
+ 					}
+-- 
+tg: (1836a2b..) topic/fixes/jira-sent/lltemplatemessagereader_memcpy (depends on: upstream)
diff --git a/debian/patches/topic/fixes/jira-sent/no_format_or_string_literal.diff b/debian/patches/topic/fixes/jira-sent/no_format_or_string_literal.diff
new file mode 100644
index 0000000..b669aa1
--- /dev/null
+++ b/debian/patches/topic/fixes/jira-sent/no_format_or_string_literal.diff
@@ -0,0 +1,27 @@
+From: Guillermo Gutiérrez Herrera <terrex at xiterrex.net>
+Subject: [PATCH] topic/fixes/jira-sent/no_format_or_string_literal
+
+Correcty pass format specifier to string via string literal
+
+Signed-off-by: Robin Cornelius <robin.cornelius at gmail.com>
+Signed-off-by: Guillermo Gutiérrez Herrera <terrex at xiterrex.net>
+
+---
+ indra/linux_crash_logger/llcrashloggerlinux.cpp |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/indra/linux_crash_logger/llcrashloggerlinux.cpp b/indra/linux_crash_logger/llcrashloggerlinux.cpp
+index 0896814..2dd5e61 100644
+--- a/indra/linux_crash_logger/llcrashloggerlinux.cpp
++++ b/indra/linux_crash_logger/llcrashloggerlinux.cpp
+@@ -90,7 +90,7 @@ static BOOL do_ask_dialog(void)
+ 
+ 	win = gtk_message_dialog_new(NULL,
+ 				     flags, messagetype, buttons,
+-				     dialog_text);
++				     "%s", dialog_text);
+ 	gtk_window_set_type_hint(GTK_WINDOW(win),
+ 				 GDK_WINDOW_TYPE_HINT_DIALOG);
+ 	gtk_window_set_title(GTK_WINDOW(win), dialog_title);
+-- 
+tg: (1836a2b..) topic/fixes/jira-sent/no_format_or_string_literal (depends on: upstream)
diff --git a/debian/patches/topic/fixes/jira-sent/use_c_locale_and_dont_spam_me_because_i_am_not_american.diff b/debian/patches/topic/fixes/jira-sent/use_c_locale_and_dont_spam_me_because_i_am_not_american.diff
new file mode 100644
index 0000000..0b52d12
--- /dev/null
+++ b/debian/patches/topic/fixes/jira-sent/use_c_locale_and_dont_spam_me_because_i_am_not_american.diff
@@ -0,0 +1,29 @@
+From: Robin Cornelius <robin.cornelius at gmail.com>
+Subject: [PATCH] topic/fixes/jira-sent/use_c_locale_and_dont_spam_me_because_i_am_not_american
+
+Better protection of locales, and don't enforce en_US.UTF-8
+
+Signed-off-by: Robin Cornelius <robin.cornelius at gmail.com>
+
+---
+ indra/llui/llresmgr.cpp |    5 ++++-
+ 1 files changed, 4 insertions(+), 1 deletions(-)
+
+diff --git a/indra/llui/llresmgr.cpp b/indra/llui/llresmgr.cpp
+index d111bd6..9d8c283 100644
+--- a/indra/llui/llresmgr.cpp
++++ b/indra/llui/llresmgr.cpp
+@@ -446,7 +446,10 @@ const std::string LLLocale::SYSTEM_LOCALE("en_US.iso8859-1");
+ const std::string LLLocale::USER_LOCALE("en_US.ISO8859-1");
+ const std::string LLLocale::SYSTEM_LOCALE("C");
+ #else // LL_LINUX likes this
+-const std::string LLLocale::USER_LOCALE("en_US.utf8");
++//const std::string LLLocale::USER_LOCALE("en_US.utf8");
++// this is a good chance that I AM NOT AN AMERICAN don't assume that i am and
++// assume i have an american locale installed, C should do for the viewer
++const std::string LLLocale::USER_LOCALE("C");
+ const std::string LLLocale::SYSTEM_LOCALE("C");
+ #endif
+ 
+-- 
+tg: (1836a2b..) topic/fixes/jira-sent/use_c_locale_and_dont_spam_me_because_i_am_not_american (depends on: upstream)
diff --git a/debian/patches/topic/fixes/new/allow_compilation_when_GST_DISABLE_GST_DEBUG_is_defined.diff b/debian/patches/topic/fixes/new/allow_compilation_when_GST_DISABLE_GST_DEBUG_is_defined.diff
new file mode 100644
index 0000000..8aaac07
--- /dev/null
+++ b/debian/patches/topic/fixes/new/allow_compilation_when_GST_DISABLE_GST_DEBUG_is_defined.diff
@@ -0,0 +1,44 @@
+From: Carlo Wood <carlo at alinoe.com>
+Subject: [PATCH] topic/fixes/new/allow_compilation_when_GST_DISABLE_GST_DEBUG_is_defined
+
+Allow compilation when GST_DISABLE_GST_DEBUG is defined.
+
+Signed-off-by: Carlo Wood <carlo at alinoe.com>
+
+---
+ indra/llmedia/llmediaimplgstreamer_syms.h       |    2 ++
+ indra/llmedia/llmediaimplgstreamer_syms_raw.inc |    2 ++
+ 2 files changed, 4 insertions(+), 0 deletions(-)
+
+diff --git a/indra/llmedia/llmediaimplgstreamer_syms.h b/indra/llmedia/llmediaimplgstreamer_syms.h
+index 6957b1c..29ac00d 100644
+--- a/indra/llmedia/llmediaimplgstreamer_syms.h
++++ b/indra/llmedia/llmediaimplgstreamer_syms.h
+@@ -67,8 +67,10 @@ void ungrab_gst_syms();
+ #define GST_TYPE_VIDEO_SINK (llgst_video_sink_get_type())
+ #undef _gst_debug_register_funcptr
+ #define _gst_debug_register_funcptr ll_gst_debug_register_funcptr
++#ifndef GST_DISABLE_GST_DEBUG
+ #undef _gst_debug_category_new
+ #define _gst_debug_category_new ll_gst_debug_category_new
++#endif
+ #undef __gst_debug_enabled
+ #define __gst_debug_enabled (0)
+ 
+diff --git a/indra/llmedia/llmediaimplgstreamer_syms_raw.inc b/indra/llmedia/llmediaimplgstreamer_syms_raw.inc
+index 08ba6df..eb2b3ee 100644
+--- a/indra/llmedia/llmediaimplgstreamer_syms_raw.inc
++++ b/indra/llmedia/llmediaimplgstreamer_syms_raw.inc
+@@ -19,8 +19,10 @@ LL_GST_SYM(true, gst_element_class_add_pad_template, void, GstElementClass *klas
+ LL_GST_SYM(true, gst_element_class_set_details, void, GstElementClass *klass, const GstElementDetails *details);
+ LL_GST_SYM(true, gst_caps_unref, void, GstCaps* caps);
+ LL_GST_SYM(true, gst_caps_ref, GstCaps *, GstCaps* caps);
++#ifndef GST_DISABLE_GST_DEBUG
+ LL_GST_SYM(true, _gst_debug_register_funcptr, void, GstDebugFuncPtr func, gchar* ptrname);
+ LL_GST_SYM(true, _gst_debug_category_new, GstDebugCategory *, gchar *name, guint color, gchar *description);
++#endif
+ LL_GST_SYM(true, gst_caps_is_empty, gboolean, const GstCaps *caps);
+ LL_GST_SYM(true, gst_caps_from_string, GstCaps *, const gchar *string);
+ LL_GST_SYM(true, gst_caps_replace, void, GstCaps **caps, GstCaps *newcaps);
+-- 
+tg: (1836a2b..) topic/fixes/new/allow_compilation_when_GST_DISABLE_GST_DEBUG_is_defined (depends on: upstream)
diff --git a/debian/patches/topic/fixes/new/delete_LLImageTGA_mColorMap_as_array.diff b/debian/patches/topic/fixes/new/delete_LLImageTGA_mColorMap_as_array.diff
new file mode 100644
index 0000000..c6c9940
--- /dev/null
+++ b/debian/patches/topic/fixes/new/delete_LLImageTGA_mColorMap_as_array.diff
@@ -0,0 +1,26 @@
+From: Carlo Wood <carlo at alinoe.com>
+Subject: [PATCH] topic/fixes/new/delete_LLImageTGA_mColorMap_as_array
+
+The destructor of LLImageTGA should delete mColorMap with 'operator delete[]', not 'operator delete'.
+
+Signed-off-by: Carlo Wood <carlo at alinoe.com>
+
+---
+ indra/llimage/llimagetga.cpp |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/indra/llimage/llimagetga.cpp b/indra/llimage/llimagetga.cpp
+index 853a0dc..c72a1cd 100644
+--- a/indra/llimage/llimagetga.cpp
++++ b/indra/llimage/llimagetga.cpp
+@@ -104,7 +104,7 @@ LLImageTGA::LLImageTGA(const std::string& file_name)
+ 
+ LLImageTGA::~LLImageTGA()
+ {
+-	delete mColorMap;
++	delete [] mColorMap;
+ }
+ 
+ BOOL LLImageTGA::updateData()
+-- 
+tg: (1836a2b..) topic/fixes/new/delete_LLImageTGA_mColorMap_as_array (depends on: upstream)
diff --git a/debian/patches/topic/fixes/new/fix_cmake_install_target.diff b/debian/patches/topic/fixes/new/fix_cmake_install_target.diff
new file mode 100644
index 0000000..e2aa82b
--- /dev/null
+++ b/debian/patches/topic/fixes/new/fix_cmake_install_target.diff
@@ -0,0 +1,23 @@
+From: Robin Cornelius <robin.cornelius at gmail.com>
+Subject: [PATCH] topic/fixes/new/fix_cmake_install_target
+
+Fix install cmake target for renamed binaries
+
+Signed-off-by: Robin Cornelius <robin.cornelius at gmail.com>
+
+---
+ indra/newview/ViewerInstall.cmake |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/indra/newview/ViewerInstall.cmake b/indra/newview/ViewerInstall.cmake
+index 55069ad..8168e91 100644
+--- a/indra/newview/ViewerInstall.cmake
++++ b/indra/newview/ViewerInstall.cmake
+@@ -1,4 +1,4 @@
+-install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/secondlife-bin
++install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/${VIEWER_BINARY_NAME}
+         DESTINATION ${APP_BINARY_DIR}
+         )
+ 
+-- 
+tg: (1836a2b..) topic/fixes/new/fix_cmake_install_target (depends on: upstream)
diff --git a/debian/patches/topic/fixes/thirdparty/0000_keep_statbars_from_overshooting.patch.diff b/debian/patches/topic/fixes/thirdparty/0000_keep_statbars_from_overshooting.patch.diff
new file mode 100644
index 0000000..b257b64
--- /dev/null
+++ b/debian/patches/topic/fixes/thirdparty/0000_keep_statbars_from_overshooting.patch.diff
@@ -0,0 +1,54 @@
+From: Robin Cornelius <robin.cornelius at gmail.com>
+Subject: [PATCH] topic/fixes/thirdparty/0000_keep_statbars_from_overshooting.patch
+
+fix an issue with status bars overshooting their window
+
+Signed-off-by: Robin Cornelius <robin.cornelius at gmail.com>
+
+---
+ indra/newview/llstatbar.cpp |   13 +++++++------
+ 1 files changed, 7 insertions(+), 6 deletions(-)
+
+diff --git a/indra/newview/llstatbar.cpp b/indra/newview/llstatbar.cpp
+index 2673166..88b329a 100644
+--- a/indra/newview/llstatbar.cpp
++++ b/indra/newview/llstatbar.cpp
+@@ -213,6 +213,7 @@ void LLStatBar::draw()
+ 		}
+ 
+ 		right = (S32) ((max - mMinBar) * value_scale);
++		right = llclamp(0, right, width);
+ 		gl_rect_2d(left, top, right, bottom, LLColor4(1.f, 0.f, 0.f, 0.25f));
+ 
+ 		S32 num_values = mStatp->getNumValues() - 1;
+@@ -228,22 +229,22 @@ void LLStatBar::draw()
+ 				if (mPerSec)
+ 				{
+ 					left = (S32)((mStatp->getPrevPerSec(i) - mMinBar) * value_scale);
+-					right = (S32)((mStatp->getPrevPerSec(i) - mMinBar) * value_scale) + 1;
+-					gl_rect_2d(left, bottom+i+1, right, bottom+i, LLColor4(1.f, 0.f, 0.f, 1.f));
+ 				}
+ 				else
+ 				{
+ 					left = (S32)((mStatp->getPrev(i) - mMinBar) * value_scale);
+-					right = (S32)((mStatp->getPrev(i) - mMinBar) * value_scale) + 1;
+-					gl_rect_2d(left, bottom+i+1, right, bottom+i, LLColor4(1.f, 0.f, 0.f, 1.f));
+-				}
++				}	
++				left = llclamp(0, left, width-1);
++				right = left+1;
++				gl_rect_2d(left, bottom+i+1, right, bottom+i, LLColor4(1.f, 0.f, 0.f, 1.f));
+ 			}
+ 		}
+ 		else
+ 		{
+ 			// draw current
+ 			left = (S32) ((current - mMinBar) * value_scale) - 1;
+-			right = (S32) ((current - mMinBar) * value_scale) + 1;
++			left = llclamp(0, left, width-1);
++			right = left + 2;
+ 			gl_rect_2d(left, top, right, bottom, LLColor4(1.f, 0.f, 0.f, 1.f));
+ 		}
+ 
+-- 
+tg: (1836a2b..) topic/fixes/thirdparty/0000_keep_statbars_from_overshooting.patch (depends on: upstream)
diff --git a/debian/patches/topic/fixes/thirdparty/0001_possible_crash_and_leak_llassetstorage.patch.diff b/debian/patches/topic/fixes/thirdparty/0001_possible_crash_and_leak_llassetstorage.patch.diff
new file mode 100644
index 0000000..ecabc58
--- /dev/null
+++ b/debian/patches/topic/fixes/thirdparty/0001_possible_crash_and_leak_llassetstorage.patch.diff
@@ -0,0 +1,148 @@
+From: Robin Cornelius <robin.cornelius at gmail.com>
+Subject: [PATCH] topic/fixes/thirdparty/0001_possible_crash_and_leak_llassetstorage.patch
+
+possible crash and memory leak
+
+Signed-off-by: Robin Cornelius <robin.cornelius at gmail.com>
+
+---
+ indra/llmessage/llassetstorage.cpp |   41 ++++++++++++++++++-----------------
+ 1 files changed, 21 insertions(+), 20 deletions(-)
+
+diff --git a/indra/llmessage/llassetstorage.cpp b/indra/llmessage/llassetstorage.cpp
+index a89a786..5970a34 100644
+--- a/indra/llmessage/llassetstorage.cpp
++++ b/indra/llmessage/llassetstorage.cpp
+@@ -522,16 +522,19 @@ void LLAssetStorage::downloadCompleteCallback(
+ 	S32 result,
+ 	const LLUUID& file_id,
+ 	LLAssetType::EType file_type,
+-	void* user_data, LLExtStat ext_status)
++	void* callback_parm_req, LLExtStat ext_status)
+ {
+ 	lldebugs << "LLAssetStorage::downloadCompleteCallback() for " << file_id
+ 		 << "," << LLAssetType::lookup(file_type) << llendl;
+-	LLAssetRequest* req = (LLAssetRequest*)user_data;
++
++	// be careful! req may be a ptr to memory already freed (a timeout does this)
++	LLAssetRequest* req = (LLAssetRequest*)callback_parm_req;	
+ 	if(!req)
+ 	{
+ 		llwarns << "LLAssetStorage::downloadCompleteCallback called without"
+ 			"a valid request." << llendl;
+-		return;
++		// we can live with a null pointer, we're not allowed to deref the ptr anyway (see above)
++		// return;  
+ 	}
+ 	if (!gAssetStorage)
+ 	{
+@@ -539,12 +542,10 @@ void LLAssetStorage::downloadCompleteCallback(
+ 		return;
+ 	}
+ 
+-	req->setUUID(file_id);
+-	req->setType(file_type);
+ 	if (LL_ERR_NOERR == result)
+ 	{
+ 		// we might have gotten a zero-size file
+-		LLVFile vfile(gAssetStorage->mVFS, req->getUUID(), req->getType());
++		LLVFile vfile(gAssetStorage->mVFS, file_id, file_type);
+ 		if (vfile.getSize() <= 0)
+ 		{
+ 			llwarns << "downloadCompleteCallback has non-existent or zero-size asset " << req->getUUID() << llendl;
+@@ -563,7 +564,7 @@ void LLAssetStorage::downloadCompleteCallback(
+ 	{
+ 		request_list_t::iterator curiter = iter++;
+ 		LLAssetRequest* tmp = *curiter;
+-		if ((tmp->getUUID() == req->getUUID()) && (tmp->getType()== req->getType()))
++		if ((tmp->getUUID() == file_id) && (tmp->getType() == file_type))
+ 		{
+ 			requests.push_front(tmp);
+ 			iter = gAssetStorage->mPendingDownloads.erase(curiter);
+@@ -576,7 +577,7 @@ void LLAssetStorage::downloadCompleteCallback(
+ 		LLAssetRequest* tmp = *curiter;
+ 		if (tmp->mDownCallback)
+ 		{
+-			tmp->mDownCallback(gAssetStorage->mVFS, req->getUUID(), req->getType(), tmp->mUserData, result, ext_status);
++			tmp->mDownCallback(gAssetStorage->mVFS, tmp->getUUID(), tmp->getType(), tmp->mUserData, result, ext_status);
+ 		}
+ 		delete tmp;
+ 	}
+@@ -672,10 +673,10 @@ void LLAssetStorage::downloadEstateAssetCompleteCallback(
+ 	S32 result,
+ 	const LLUUID& file_id,
+ 	LLAssetType::EType file_type,
+-	void* user_data,
++	void* callback_parm_req,
+ 	LLExtStat ext_status)
+ {
+-	LLEstateAssetRequest *req = (LLEstateAssetRequest*)user_data;
++	LLEstateAssetRequest *req = (LLEstateAssetRequest*)callback_parm_req;
+ 	if(!req)
+ 	{
+ 		llwarns << "LLAssetStorage::downloadEstateAssetCompleteCallback called"
+@@ -689,12 +690,10 @@ void LLAssetStorage::downloadEstateAssetCompleteCallback(
+ 		return;
+ 	}
+ 
+-	req->setUUID(file_id);
+-	req->setType(file_type);
+ 	if (LL_ERR_NOERR == result)
+ 	{
+ 		// we might have gotten a zero-size file
+-		LLVFile vfile(gAssetStorage->mVFS, req->getUUID(), req->getAType());
++		LLVFile vfile(gAssetStorage->mVFS, file_id, file_type);
+ 		if (vfile.getSize() <= 0)
+ 		{
+ 			llwarns << "downloadCompleteCallback has non-existent or zero-size asset!" << llendl;
+@@ -704,7 +703,9 @@ void LLAssetStorage::downloadEstateAssetCompleteCallback(
+ 		}
+ 	}
+ 
+-	req->mDownCallback(gAssetStorage->mVFS, req->getUUID(), req->getAType(), req->mUserData, result, ext_status);
++	req->mDownCallback(gAssetStorage->mVFS, file_id, file_type, req->mUserData, result, ext_status);
++
++	delete req;
+ }
+ 
+ void LLAssetStorage::getInvItemAsset(const LLHost &object_sim, const LLUUID &agent_id, const LLUUID &session_id,
+@@ -809,10 +810,10 @@ void LLAssetStorage::downloadInvItemCompleteCallback(
+ 	S32 result,
+ 	const LLUUID& file_id,
+ 	LLAssetType::EType file_type,
+-	void* user_data,
++	void* callback_parm_req,
+ 	LLExtStat ext_status)
+ {
+-	LLInvItemRequest *req = (LLInvItemRequest*)user_data;
++	LLInvItemRequest *req = (LLInvItemRequest*)callback_parm_req;
+ 	if(!req)
+ 	{
+ 		llwarns << "LLAssetStorage::downloadEstateAssetCompleteCallback called"
+@@ -825,12 +826,10 @@ void LLAssetStorage::downloadInvItemCompleteCallback(
+ 		return;
+ 	}
+ 
+-	req->setUUID(file_id);
+-	req->setType(file_type);
+ 	if (LL_ERR_NOERR == result)
+ 	{
+ 		// we might have gotten a zero-size file
+-		LLVFile vfile(gAssetStorage->mVFS, req->getUUID(), req->getType());
++		LLVFile vfile(gAssetStorage->mVFS, file_id, file_type);
+ 		if (vfile.getSize() <= 0)
+ 		{
+ 			llwarns << "downloadCompleteCallback has non-existent or zero-size asset!" << llendl;
+@@ -840,7 +839,9 @@ void LLAssetStorage::downloadInvItemCompleteCallback(
+ 		}
+ 	}
+ 
+-	req->mDownCallback(gAssetStorage->mVFS, req->getUUID(), req->getType(), req->mUserData, result, ext_status);
++	req->mDownCallback(gAssetStorage->mVFS, file_id, file_type, req->mUserData, result, ext_status);
++
++	delete req;
+ }
+ 
+ /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+-- 
+tg: (1836a2b..) topic/fixes/thirdparty/0001_possible_crash_and_leak_llassetstorage.patch (depends on: upstream)
diff --git a/debian/patches/topic/fixes/thirdparty/0001_possible_crash_in_llviewerpartssim.diff b/debian/patches/topic/fixes/thirdparty/0001_possible_crash_in_llviewerpartssim.diff
new file mode 100644
index 0000000..201c2e0
--- /dev/null
+++ b/debian/patches/topic/fixes/thirdparty/0001_possible_crash_in_llviewerpartssim.diff
@@ -0,0 +1,38 @@
+From: Robin Cornelius <robin.cornelius at gmail.com>
+Subject: [PATCH] topic/fixes/thirdparty/0001_possible_crash_in_llviewerpartssim
+
+Another possible crash fix
+
+Signed-off-by: Robin Cornelius <robin.cornelius at gmail.com>
+
+---
+ indra/newview/llviewerpartsim.cpp |   13 ++++++++++---
+ 1 files changed, 10 insertions(+), 3 deletions(-)
+
+diff --git a/indra/newview/llviewerpartsim.cpp b/indra/newview/llviewerpartsim.cpp
+index c303fc5..2c79791 100644
+--- a/indra/newview/llviewerpartsim.cpp
++++ b/indra/newview/llviewerpartsim.cpp
+@@ -714,10 +714,17 @@ void LLViewerPartSim::updateSimulation()
+ 		S32 visirate = 1;
+ 		if (vobj)
+ 		{
+-			LLSpatialGroup* group = vobj->mDrawable->getSpatialGroup();
+-			if (group && !group->isVisible()) // && !group->isState(LLSpatialGroup::OBJECT_DIRTY))
++			if(vobj->mDrawable)
+ 			{
+-				visirate = 8;
++				LLSpatialGroup* group = vobj->mDrawable->getSpatialGroup();
++				if (group && !group->isVisible()) // && !group->isState(LLSpatialGroup::OBJECT_DIRTY))
++				{
++					visirate = 8;
++				}
++			}
++			else
++			{
++				llwarns << "Crash avoided, vobj->mDrawable is NULL" << llendl;
+ 			}
+ 		}
+ 
+-- 
+tg: (1836a2b..) topic/fixes/thirdparty/0001_possible_crash_in_llviewerpartssim (depends on: upstream)
diff --git a/debian/patches/topic/fixes/thirdparty/1294_llworkerthread_when_terminating_program.patch.diff b/debian/patches/topic/fixes/thirdparty/1294_llworkerthread_when_terminating_program.patch.diff
new file mode 100644
index 0000000..92e7795
--- /dev/null
+++ b/debian/patches/topic/fixes/thirdparty/1294_llworkerthread_when_terminating_program.patch.diff
@@ -0,0 +1,26 @@
+From: Robin Cornelius <robin.cornelius at gmail.com>
+Subject: [PATCH] topic/fixes/thirdparty/1294_llworkerthread_when_terminating_program.patch
+
+Kill a llworker thread when exiting
+
+Signed-off-by: Robin Cornelius <robin.cornelius at gmail.com>
+
+---
+ indra/llcommon/llworkerthread.cpp |    2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/indra/llcommon/llworkerthread.cpp b/indra/llcommon/llworkerthread.cpp
+index 96a957b..a28259b 100644
+--- a/indra/llcommon/llworkerthread.cpp
++++ b/indra/llcommon/llworkerthread.cpp
+@@ -111,7 +111,7 @@ S32 LLWorkerThread::update(U32 max_time_ms)
+ 	}
+ 	LLWorkerClass::sDeleteLock = FALSE ;
+     // delete and aborted entries mean there's still work to do
+-	res += delete_list.size() + abort_list.size();
++	res +=  !mDeleteList.empty() + !delete_list.empty();  // deleted entries mean there's still work to do
+ 	return res;
+ }
+ 
+-- 
+tg: (1836a2b..) topic/fixes/thirdparty/1294_llworkerthread_when_terminating_program.patch (depends on: upstream)
diff --git a/debian/patches/topic/fixes/thirdparty/1857_apr_thread_mutex_nested.patch.diff b/debian/patches/topic/fixes/thirdparty/1857_apr_thread_mutex_nested.patch.diff
new file mode 100644
index 0000000..9e2dab9
--- /dev/null
+++ b/debian/patches/topic/fixes/thirdparty/1857_apr_thread_mutex_nested.patch.diff
@@ -0,0 +1,56 @@
+From: Robin Cornelius <robin.cornelius at gmail.com>
+Subject: [PATCH] topic/fixes/thirdparty/1857_apr_thread_mutex_nested.patch
+
+Fix issue with nested apt thread mutex
+
+Signed-off-by: Robin Cornelius <robin.cornelius at gmail.com>
+
+---
+ indra/llcommon/llapr.cpp     |    2 +-
+ indra/llcommon/llthread.cpp  |    2 +-
+ indra/llmessage/llpumpio.cpp |    4 ++--
+ 3 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/indra/llcommon/llapr.cpp b/indra/llcommon/llapr.cpp
+index 589d3f5..0613df5 100644
+--- a/indra/llcommon/llapr.cpp
++++ b/indra/llcommon/llapr.cpp
+@@ -47,7 +47,7 @@ void ll_init_apr()
+ 		apr_pool_create(&gAPRPoolp, NULL);
+ 
+ 		// Initialize the logging mutex
+-		apr_thread_mutex_create(&gLogMutexp, APR_THREAD_MUTEX_UNNESTED, gAPRPoolp);
++		apr_thread_mutex_create(&gLogMutexp, APR_THREAD_MUTEX_NESTED, gAPRPoolp);
+ 	}
+ }
+ 
+diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp
+index b31c9ab..b187e50 100644
+--- a/indra/llcommon/llthread.cpp
++++ b/indra/llcommon/llthread.cpp
+@@ -276,7 +276,7 @@ LLMutex::LLMutex(apr_pool_t *poolp) :
+ 		mIsLocalPool = TRUE;
+ 		apr_pool_create(&mAPRPoolp, NULL); // Create a subpool for this thread
+ 	}
+-	apr_thread_mutex_create(&mAPRMutexp, APR_THREAD_MUTEX_UNNESTED, mAPRPoolp);
++	apr_thread_mutex_create(&mAPRMutexp, APR_THREAD_MUTEX_NESTED, mAPRPoolp);
+ }
+ 
+ 
+diff --git a/indra/llmessage/llpumpio.cpp b/indra/llmessage/llpumpio.cpp
+index 01a43ec..bb754c2 100644
+--- a/indra/llmessage/llpumpio.cpp
++++ b/indra/llmessage/llpumpio.cpp
+@@ -830,8 +830,8 @@ void LLPumpIO::initialize(apr_pool_t* pool)
+ 	if(!pool) return;
+ #if LL_THREADS_APR
+ 	// SJB: Windows defaults to NESTED and OSX defaults to UNNESTED, so use UNNESTED explicitly.
+-	apr_thread_mutex_create(&mChainsMutex, APR_THREAD_MUTEX_UNNESTED, pool);
+-	apr_thread_mutex_create(&mCallbackMutex, APR_THREAD_MUTEX_UNNESTED, pool);
++	apr_thread_mutex_create(&mChainsMutex, APR_THREAD_MUTEX_NESTED, pool);
++	apr_thread_mutex_create(&mCallbackMutex, APR_THREAD_MUTEX_NESTED, pool);
+ #endif
+ 	mPool = pool;
+ }
+-- 
+tg: (1836a2b..) topic/fixes/thirdparty/1857_apr_thread_mutex_nested.patch (depends on: upstream)
diff --git a/debian/patches/topic/fixes/thirdparty/2003_possible_crash_draganddrop.patch.diff b/debian/patches/topic/fixes/thirdparty/2003_possible_crash_draganddrop.patch.diff
new file mode 100644
index 0000000..8d4f190
--- /dev/null
+++ b/debian/patches/topic/fixes/thirdparty/2003_possible_crash_draganddrop.patch.diff
@@ -0,0 +1,30 @@
+From: Robin Cornelius <robin.cornelius at gmail.com>
+Subject: [PATCH] topic/fixes/thirdparty/2003_possible_crash_draganddrop.patch
+
+Possible crash fix
+
+Signed-off-by: Robin Cornelius <robin.cornelius at gmail.com>
+
+---
+ indra/newview/lltooldraganddrop.cpp |    6 ++++++
+ 1 files changed, 6 insertions(+), 0 deletions(-)
+
+diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp
+index c83d0f4..efd8060 100644
+--- a/indra/newview/lltooldraganddrop.cpp
++++ b/indra/newview/lltooldraganddrop.cpp
+@@ -850,6 +850,12 @@ void LLToolDragAndDrop::dragOrDrop( S32 x, S32 y, MASK mask, BOOL drop,
+ 		{
+ 			LLInventoryObject* cargo = locateInventory(item, cat);
+ 
++			if (!cargo) 
++			{
++				handled = FALSE;
++				break;
++			}
++
+ 			EAcceptance item_acceptance = ACCEPT_NO;
+ 			handled = handled && root_view->handleDragAndDrop(x, y, mask, FALSE,
+ 												mCargoTypes[mCurItemIndex],
+-- 
+tg: (1836a2b..) topic/fixes/thirdparty/2003_possible_crash_draganddrop.patch (depends on: upstream)
diff --git a/debian/patches/topic/fixes/thirdparty/2543_possible_crash_in_group_voting_propsals.patch.diff b/debian/patches/topic/fixes/thirdparty/2543_possible_crash_in_group_voting_propsals.patch.diff
new file mode 100644
index 0000000..d177dc7
--- /dev/null
+++ b/debian/patches/topic/fixes/thirdparty/2543_possible_crash_in_group_voting_propsals.patch.diff
@@ -0,0 +1,126 @@
+From: Robin Cornelius <robin.cornelius at gmail.com>
+Subject: [PATCH] topic/fixes/thirdparty/2543_possible_crash_in_group_voting_propsals.patch
+
+Possible crash fix
+
+Signed-off-by: Robin Cornelius <robin.cornelius at gmail.com>
+
+---
+ indra/llui/llscrolllistctrl.cpp      |   18 ++++++++++++++++++
+ indra/newview/llpanelgroupvoting.cpp |    9 ++++++++-
+ 2 files changed, 26 insertions(+), 1 deletions(-)
+
+diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
+index 7dba55f..4691701 100644
+--- a/indra/llui/llscrolllistctrl.cpp
++++ b/indra/llui/llscrolllistctrl.cpp
+@@ -676,6 +676,11 @@ void LLScrollListCtrl::clearRows()
+ 
+ LLScrollListItem* LLScrollListCtrl::getFirstSelected() const
+ {
++	if (!getCanSelect())
++	{
++		return NULL;
++	}
++
+ 	item_list::const_iterator iter;
+ 	for(iter = mItemList.begin(); iter != mItemList.end(); iter++)
+ 	{
+@@ -691,6 +696,13 @@ LLScrollListItem* LLScrollListCtrl::getFirstSelected() const
+ std::vector<LLScrollListItem*> LLScrollListCtrl::getAllSelected() const
+ {
+ 	std::vector<LLScrollListItem*> ret;
++
++	if (!getCanSelect())
++	{
++		return ret;
++	}
++
++
+ 	item_list::const_iterator iter;
+ 	for(iter = mItemList.begin(); iter != mItemList.end(); iter++)
+ 	{
+@@ -705,6 +717,12 @@ std::vector<LLScrollListItem*> LLScrollListCtrl::getAllSelected() const
+ 
+ S32 LLScrollListCtrl::getFirstSelectedIndex() const
+ {
++	if (!getCanSelect())
++	{
++		return -1;
++	}
++
++
+ 	S32 CurSelectedIndex = 0;
+ 	item_list::const_iterator iter;
+ 	for (iter = mItemList.begin(); iter != mItemList.end(); iter++)
+diff --git a/indra/newview/llpanelgroupvoting.cpp b/indra/newview/llpanelgroupvoting.cpp
+index 41650ad..d3783d5 100644
+--- a/indra/newview/llpanelgroupvoting.cpp
++++ b/indra/newview/llpanelgroupvoting.cpp
+@@ -592,6 +592,7 @@ void LLPanelGroupVoting::impl::sendGroupProposalsRequest(const LLUUID& group_id)
+ 	//we're pining the server in high latency situations
+ 	addPendingActiveScrollListItem(0, 0, ADD_BOTTOM);
+ 	mProposals->setCanSelect(FALSE);
++	mBtnViewProposalItem->setEnabled(FALSE);
+ 
+ 	LLMessageSystem *msg = gMessageSystem;
+ 	msg->newMessageFast(_PREHASH_GroupActiveProposalsRequest);
+@@ -870,6 +871,7 @@ void LLPanelGroupVoting::impl::sendGroupVoteHistoryRequest(const LLUUID& group_i
+ 	//add some text so the user knows we're doing something
+ 	addPendingHistoryScrollListItem(0, 0, ADD_BOTTOM);
+ 	mVotesHistory->setCanSelect(FALSE);
++	mBtnViewHistoryItem->setEnabled(FALSE);
+ 
+ 	LLMessageSystem *msg = gMessageSystem;
+ 	msg->newMessageFast(_PREHASH_GroupVoteHistoryRequest);
+@@ -1066,6 +1068,7 @@ void LLPanelGroupVoting::impl::processGroupActiveProposalItemReply(LLMessageSyst
+ 		//no active proposals and make the scroll list unselectable
+ 		self->addNoActiveScrollListItem(ADD_BOTTOM);
+ 		self->mProposals->setCanSelect(FALSE);
++		self->mBtnViewProposalItem->setEnabled(FALSE);
+ 	}
+ 	else if ( (U32)received != num_expected )
+ 	{
+@@ -1073,6 +1076,7 @@ void LLPanelGroupVoting::impl::processGroupActiveProposalItemReply(LLMessageSyst
+ 											 num_expected,
+ 											 ADD_BOTTOM);
+ 		self->mProposals->setCanSelect(FALSE);
++		self->mBtnViewProposalItem->setEnabled(FALSE);
+ 	}
+ 	else
+ 	{
+@@ -1086,6 +1090,7 @@ void LLPanelGroupVoting::impl::processGroupActiveProposalItemReply(LLMessageSyst
+ 		}
+ 
+ 		self->mProposals->setCanSelect(TRUE);
++		self->mBtnViewProposalItem->setEnabled(TRUE);
+ 	}
+ }
+ 
+@@ -1134,7 +1139,7 @@ void LLPanelGroupVoting::impl::processGroupVoteHistoryItemReply(LLMessageSystem
+ 		//no active proposals and make the scroll list unselectable
+ 		self->addNoHistoryScrollListItem(ADD_BOTTOM);
+ 		self->mVotesHistory->setCanSelect(FALSE);
+-
++		self->mBtnViewHistoryItem->setEnabled(FALSE);
+ 		return;
+ 	}
+ 
+@@ -1248,6 +1253,7 @@ void LLPanelGroupVoting::impl::processGroupVoteHistoryItemReply(LLMessageSystem
+ 											  num_expected,
+ 											  ADD_BOTTOM);
+ 		self->mVotesHistory->setCanSelect(FALSE);
++		self->mBtnViewHistoryItem->setEnabled(FALSE);
+ 	}
+ 	else
+ 	{
+@@ -1261,6 +1267,7 @@ void LLPanelGroupVoting::impl::processGroupVoteHistoryItemReply(LLMessageSystem
+ 		}
+ 
+ 		self->mVotesHistory->setCanSelect(TRUE);
++		self->mBtnViewHistoryItem->setEnabled(TRUE);
+ 	}
+ }
+ 
+-- 
+tg: (1836a2b..) topic/fixes/thirdparty/2543_possible_crash_in_group_voting_propsals.patch (depends on: upstream)
diff --git a/debian/patches/topic/fixes/thirdparty/2683_possible_crash_update_speaker_list.patch.diff b/debian/patches/topic/fixes/thirdparty/2683_possible_crash_update_speaker_list.patch.diff
new file mode 100644
index 0000000..03a80b5
--- /dev/null
+++ b/debian/patches/topic/fixes/thirdparty/2683_possible_crash_update_speaker_list.patch.diff
@@ -0,0 +1,51 @@
+From: Robin Cornelius <robin.cornelius at gmail.com>
+Subject: [PATCH] topic/fixes/thirdparty/2683_possible_crash_update_speaker_list.patch
+
+Possible crash fix
+
+Signed-off-by: Robin Cornelius <robin.cornelius at gmail.com>
+
+---
+ indra/newview/llfloateractivespeakers.cpp |    4 ++--
+ indra/newview/llviewerobjectlist.cpp      |    4 ++++
+ 2 files changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/indra/newview/llfloateractivespeakers.cpp b/indra/newview/llfloateractivespeakers.cpp
+index 0a19fb2..a8f3f91 100644
+--- a/indra/newview/llfloateractivespeakers.cpp
++++ b/indra/newview/llfloateractivespeakers.cpp
+@@ -1386,7 +1386,7 @@ void LLLocalSpeakerMgr::updateSpeakerList()
+ 	for(avatar_it = LLCharacter::sInstances.begin(); avatar_it != LLCharacter::sInstances.end(); ++avatar_it)
+ 	{
+ 		LLVOAvatar* avatarp = (LLVOAvatar*)*avatar_it;
+-		if (dist_vec(avatarp->getPositionAgent(), gAgent.getPositionAgent()) <= CHAT_NORMAL_RADIUS)
++		if (!avatarp->isDead() &&  dist_vec(avatarp->getPositionAgent(), gAgent.getPositionAgent()) <= CHAT_NORMAL_RADIUS)
+ 		{
+ 			setSpeaker(avatarp->getID());
+ 		}
+@@ -1400,7 +1400,7 @@ void LLLocalSpeakerMgr::updateSpeakerList()
+ 		if (speakerp->mStatus == LLSpeaker::STATUS_TEXT_ONLY)
+ 		{
+ 			LLVOAvatar* avatarp = (LLVOAvatar*)gObjectList.findObject(speaker_id);
+-			if (!avatarp || dist_vec(avatarp->getPositionAgent(), gAgent.getPositionAgent()) > CHAT_NORMAL_RADIUS)
++			if (!avatarp || avatarp->isDead() || dist_vec(avatarp->getPositionAgent(), gAgent.getPositionAgent()) > CHAT_NORMAL_RADIUS)
+ 			{
+ 				speakerp->mStatus = LLSpeaker::STATUS_NOT_IN_CHANNEL;
+ 				speakerp->mDotColor = INACTIVE_COLOR;
+diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
+index e28a768..9b85fec 100644
+--- a/indra/newview/llviewerobjectlist.cpp
++++ b/indra/newview/llviewerobjectlist.cpp
+@@ -873,6 +873,10 @@ void LLViewerObjectList::killObjects(LLViewerRegion *regionp)
+ 		if (objectp->mRegionp == regionp)
+ 		{
+ 			killObject(objectp);
++
++			// invalidate region pointer. region will become invalid, but 
++			// refcounted objects may survive the cleanDeadObjects() call below
++			objectp->mRegionp = NULL;	 
+ 		}
+ 	}
+ 
+-- 
+tg: (1836a2b..) topic/fixes/thirdparty/2683_possible_crash_update_speaker_list.patch (depends on: upstream)
diff --git a/debian/patches/use_c_locale_and_dont_spam_me_because_i_am_not_american.patch b/debian/patches/use_c_locale_and_dont_spam_me_because_i_am_not_american.patch
deleted file mode 100644
index 9466381..0000000
--- a/debian/patches/use_c_locale_and_dont_spam_me_because_i_am_not_american.patch
+++ /dev/null
@@ -1,16 +0,0 @@
-Index: omvviewer-1.21.0/indra/llui/llresmgr.cpp
-===================================================================
---- omvviewer-1.21.0.orig/indra/llui/llresmgr.cpp	2008-09-01 21:49:27.000000000 +0100
-+++ omvviewer-1.21.0/indra/llui/llresmgr.cpp	2008-09-01 21:50:52.000000000 +0100
-@@ -446,7 +446,10 @@
- const std::string LLLocale::USER_LOCALE("en_US.ISO8859-1");
- const std::string LLLocale::SYSTEM_LOCALE("C");
- #else // LL_LINUX likes this
--const std::string LLLocale::USER_LOCALE("en_US.utf8");
-+//const std::string LLLocale::USER_LOCALE("en_US.utf8");
-+// this is a good chance that I AM NOT AN AMERICAN don't assume that i am and
-+// assume i have an american locale installed, C should do for the viewer
-+const std::string LLLocale::USER_LOCALE("C");
- const std::string LLLocale::SYSTEM_LOCALE("C");
- #endif
- 
diff --git a/debian/patches/use_gtk_correctly.patch b/debian/patches/use_gtk_correctly.patch
deleted file mode 100644
index dedc330..0000000
--- a/debian/patches/use_gtk_correctly.patch
+++ /dev/null
@@ -1,13 +0,0 @@
-diff --git a/indra/llwindow/llwindowsdl.cpp b/indra/llwindow/llwindowsdl.cpp
-index e5d15c4..f624111 100644
---- a/indra/llwindow/llwindowsdl.cpp
-+++ b/indra/llwindow/llwindowsdl.cpp
-@@ -2530,7 +2530,7 @@ S32 OSMessageBoxSDL(const std::string& text, const std::string& caption, U32 typ
- 			buttons = GTK_BUTTONS_YES_NO;
- 			break;
- 		}
--		win = gtk_message_dialog_new(NULL,flags, messagetype, buttons, text.c_str());
-+		win = gtk_message_dialog_new(NULL,flags, messagetype, buttons, "%s",text.c_str());
- 
- # if LL_X11
- 		// Make GTK tell the window manager to associate this
diff --git a/debian/patches/viewericon.patch b/debian/patches/viewericon.patch
deleted file mode 100644
index 819c0c2..0000000
--- a/debian/patches/viewericon.patch
+++ /dev/null
@@ -1,703 +0,0 @@
-diff --git a/indra/newview/res/viewericon.xpm b/indra/newview/res/viewericon.xpm
-new file mode 100644
-index 0000000..7cf88ad
---- /dev/null
-+++ b/indra/newview/res/viewericon.xpm
-@@ -0,0 +1,697 @@
-+/* XPM */
-+static char * viewericon_xpm[] = {
-+"32 32 662 2",
-+"  	c None",
-+". 	c #2594FF",
-+"+ 	c #2693FF",
-+"@ 	c #2894FF",
-+"# 	c #2996FF",
-+"$ 	c #2B98FF",
-+"% 	c #2C9AFF",
-+"& 	c #2E99FF",
-+"* 	c #319AFF",
-+"= 	c #319BFF",
-+"- 	c #329CFF",
-+"; 	c #339EFF",
-+"> 	c #349EFF",
-+", 	c #329DFF",
-+"' 	c #3099FF",
-+") 	c #2D99FF",
-+"! 	c #2A97FF",
-+"~ 	c #2191FF",
-+"{ 	c #2692FF",
-+"] 	c #2994FF",
-+"^ 	c #2A96FF",
-+"/ 	c #2B9AFF",
-+"( 	c #329BFF",
-+"_ 	c #359FFF",
-+": 	c #35A0FF",
-+"< 	c #36A0FF",
-+"[ 	c #359EFF",
-+"} 	c #2E98FF",
-+"| 	c #2293FF",
-+"1 	c #2995FF",
-+"2 	c #339DFF",
-+"3 	c #369FFF",
-+"4 	c #2D9AFF",
-+"5 	c #2394FF",
-+"6 	c #2F98FF",
-+"7 	c #38A2FF",
-+"8 	c #39A2FF",
-+"9 	c #3BA4FF",
-+"0 	c #3AA3FF",
-+"a 	c #38A1FF",
-+"b 	c #37A1FF",
-+"c 	c #309AFF",
-+"d 	c #2593FF",
-+"e 	c #2997FF",
-+"f 	c #349FFF",
-+"g 	c #3BA3FF",
-+"h 	c #3CA4FF",
-+"i 	c #3EA6FF",
-+"j 	c #3EA7FF",
-+"k 	c #3FA7FF",
-+"l 	c #2D91FE",
-+"m 	c #298BFC",
-+"n 	c #298AFA",
-+"o 	c #2989FA",
-+"p 	c #2889FA",
-+"q 	c #2688F8",
-+"r 	c #2486F8",
-+"s 	c #2386F8",
-+"t 	c #2488FA",
-+"u 	c #2E96FE",
-+"v 	c #2893FF",
-+"w 	c #3DA5FF",
-+"x 	c #3FA8FF",
-+"y 	c #2F96FE",
-+"z 	c #1978F4",
-+"A 	c #136DEE",
-+"B 	c #126AEB",
-+"C 	c #1269EA",
-+"D 	c #116AE9",
-+"E 	c #106AE8",
-+"F 	c #1069E6",
-+"G 	c #1068E6",
-+"H 	c #116AEA",
-+"I 	c #1C7BF7",
-+"J 	c #2A94FF",
-+"K 	c #3AA2FF",
-+"L 	c #3DA6FF",
-+"M 	c #40ADFF",
-+"N 	c #41AEFF",
-+"O 	c #43B0FF",
-+"P 	c #2D95FD",
-+"Q 	c #1472EF",
-+"R 	c #0F69E6",
-+"S 	c #0D67E2",
-+"T 	c #0D66E1",
-+"U 	c #0C65E0",
-+"V 	c #0C64E0",
-+"W 	c #0C63E0",
-+"X 	c #0E64E2",
-+"Y 	c #1874F2",
-+"Z 	c #2C96FF",
-+"` 	c #2E97FE",
-+" .	c #2A91FE",
-+"..	c #2C93FE",
-+"+.	c #2F94FE",
-+"@.	c #3097FE",
-+"#.	c #3098FE",
-+"$.	c #3197FE",
-+"%.	c #359BFE",
-+"&.	c #40ACFF",
-+"*.	c #44B1FF",
-+"=.	c #45B2FF",
-+"-.	c #46B2FF",
-+";.	c #47B3FF",
-+">.	c #3098FD",
-+",.	c #1475EE",
-+"'.	c #0E6AE6",
-+").	c #0C69E2",
-+"!.	c #0C68E1",
-+"~.	c #0C67E0",
-+"{.	c #0C66E0",
-+"].	c #0B63E0",
-+"^.	c #0E65E2",
-+"/.	c #1876F2",
-+"(.	c #2C97FF",
-+"_.	c #309BFF",
-+":.	c #1473F6",
-+"<.	c #1069F3",
-+"[.	c #106CF3",
-+"}.	c #1069F4",
-+"|.	c #1068F8",
-+"1.	c #106CF8",
-+"2.	c #106DF6",
-+"3.	c #116EF6",
-+"4.	c #1475F8",
-+"5.	c #39A3FE",
-+"6.	c #3099FE",
-+"7.	c #1478F0",
-+"8.	c #0E6CE7",
-+"9.	c #0C6AE4",
-+"0.	c #0E67E2",
-+"a.	c #1878F3",
-+"b.	c #319BFE",
-+"c.	c #116DF4",
-+"d.	c #106AF3",
-+"e.	c #106AF4",
-+"f.	c #1067F7",
-+"g.	c #106BF8",
-+"h.	c #106DF8",
-+"i.	c #106DF5",
-+"j.	c #1271F7",
-+"k.	c #1577F8",
-+"l.	c #36A0FE",
-+"m.	c #319AFE",
-+"n.	c #147AF0",
-+"o.	c #0E6EE8",
-+"p.	c #0C6CE6",
-+"q.	c #0C68E2",
-+"r.	c #0E68E4",
-+"s.	c #1A7BF4",
-+"t.	c #2D97FF",
-+"u.	c #329CFE",
-+"v.	c #126EF4",
-+"w.	c #1068F5",
-+"x.	c #1069F8",
-+"y.	c #106EF8",
-+"z.	c #106EF4",
-+"A.	c #1270F7",
-+"B.	c #1477F8",
-+"C.	c #1578F8",
-+"D.	c #369FFE",
-+"E.	c #319BFD",
-+"F.	c #1479EF",
-+"G.	c #0E6EE7",
-+"H.	c #0C6BE5",
-+"I.	c #0F6AE6",
-+"J.	c #1B7CF5",
-+"K.	c #1270F4",
-+"L.	c #106BF3",
-+"M.	c #1374F8",
-+"N.	c #369EFE",
-+"O.	c #3099FB",
-+"P.	c #1272E8",
-+"Q.	c #0C6ADF",
-+"R.	c #0C6AE0",
-+"S.	c #0C6CE4",
-+"T.	c #0F6AE7",
-+"U.	c #1C7CF5",
-+"V.	c #3EA5FF",
-+"W.	c #329DFE",
-+"X.	c #106DF7",
-+"Y.	c #106EF5",
-+"Z.	c #1271F8",
-+"`.	c #116DF0",
-+" +	c #0D62DE",
-+".+	c #0D60DB",
-+"++	c #257DF0",
-+"@+	c #318CF6",
-+"#+	c #318EF9",
-+"$+	c #328EF9",
-+"%+	c #2079EA",
-+"&+	c #0B5ACA",
-+"*+	c #0857C6",
-+"=+	c #0A61D3",
-+"-+	c #0C6CE5",
-+";+	c #1C7AF5",
-+">+	c #3A91FA",
-+",+	c #3D94FA",
-+"'+	c #3A92FA",
-+")+	c #1969EC",
-+"!+	c #1761EE",
-+"~+	c #1764F0",
-+"{+	c #1767EE",
-+"]+	c #1868ED",
-+"^+	c #1A6AEE",
-+"/+	c #0D48BD",
-+"(+	c #0A42AC",
-+"_+	c #0B40AB",
-+":+	c #164DCE",
-+"<+	c #1D54DB",
-+"[+	c #1D54DC",
-+"}+	c #134AC5",
-+"|+	c #083B9F",
-+"1+	c #083CA2",
-+"2+	c #0C4BB6",
-+"3+	c #1261D4",
-+"4+	c #1465DD",
-+"5+	c #1365DE",
-+"6+	c #1564DE",
-+"7+	c #1766E2",
-+"8+	c #2476EF",
-+"9+	c #4599FC",
-+"0+	c #469BFC",
-+"a+	c #3A93FC",
-+"b+	c #5273EE",
-+"c+	c #5574EE",
-+"d+	c #5272EC",
-+"e+	c #2F53D4",
-+"f+	c #2C4ED6",
-+"g+	c #2C52D7",
-+"h+	c #2C52D5",
-+"i+	c #2E54D6",
-+"j+	c #3053D4",
-+"k+	c #1E3BA8",
-+"l+	c #1C38A3",
-+"m+	c #1D38A3",
-+"n+	c #2C40BC",
-+"o+	c #3545C6",
-+"p+	c #3544C6",
-+"q+	c #283EB6",
-+"r+	c #1A349B",
-+"s+	c #193398",
-+"t+	c #1E3AA3",
-+"u+	c #2A4FC1",
-+"v+	c #2C55CA",
-+"w+	c #2B55CC",
-+"x+	c #2C55CC",
-+"y+	c #2C55CD",
-+"z+	c #2F56CF",
-+"A+	c #3E61DA",
-+"B+	c #5C78F0",
-+"C+	c #5E79F2",
-+"D+	c #5272F5",
-+"E+	c #5573EE",
-+"F+	c #5271EC",
-+"G+	c #2C4ED5",
-+"H+	c #2D52D3",
-+"I+	c #2E55D4",
-+"J+	c #3154D3",
-+"K+	c #1E3AA7",
-+"L+	c #1C39A2",
-+"M+	c #1C38A2",
-+"N+	c #2C42BC",
-+"O+	c #3444C4",
-+"P+	c #3344C3",
-+"Q+	c #2D42BF",
-+"R+	c #203AA9",
-+"S+	c #1C36A2",
-+"T+	c #2440B0",
-+"U+	c #385DD0",
-+"V+	c #3C63D6",
-+"W+	c #3B62D6",
-+"X+	c #3C62D7",
-+"Y+	c #3D64D8",
-+"Z+	c #4C6FE4",
-+"`+	c #5C78EE",
-+" @	c #5170F2",
-+".@	c #5272EB",
-+"+@	c #5273EB",
-+"@@	c #5172EA",
-+"#@	c #385CD9",
-+"$@	c #2E51D4",
-+"%@	c #2E54D4",
-+"&@	c #2F54D2",
-+"*@	c #3056D4",
-+"=@	c #3256D2",
-+"-@	c #1E3AA6",
-+";@	c #1D39A2",
-+">@	c #1F3BA9",
-+",@	c #2C43BE",
-+"'@	c #3244C2",
-+")@	c #3244C1",
-+"!@	c #3247C5",
-+"~@	c #314CCA",
-+"{@	c #385AD4",
-+"]@	c #557DEF",
-+"^@	c #557EEF",
-+"/@	c #547DEE",
-+"(@	c #517EEE",
-+"_@	c #507EEE",
-+":@	c #4C7AEC",
-+"<@	c #4C78EA",
-+"[@	c #4770EE",
-+"}@	c #5072E7",
-+"|@	c #5173E7",
-+"1@	c #5474E6",
-+"2@	c #5574E7",
-+"3@	c #5575E8",
-+"4@	c #5776E8",
-+"5@	c #5978E9",
-+"6@	c #5B78EA",
-+"7@	c #3147C2",
-+"8@	c #2D42BD",
-+"9@	c #2C42BE",
-+"0@	c #3043BE",
-+"a@	c #3144BE",
-+"b@	c #3144BF",
-+"c@	c #3153CC",
-+"d@	c #3058CD",
-+"e@	c #3661D5",
-+"f@	c #4F7DEC",
-+"g@	c #507EEC",
-+"h@	c #4D7EEB",
-+"i@	c #4C7EEB",
-+"j@	c #4B7FEA",
-+"k@	c #4B7FE9",
-+"l@	c #4A7EEA",
-+"m@	c #467BE9",
-+"n@	c #467AE5",
-+"o@	c #4370E8",
-+"p@	c #4E72E2",
-+"q@	c #4F72E2",
-+"r@	c #5072E2",
-+"s@	c #5574E2",
-+"t@	c #5877E5",
-+"u@	c #5878E5",
-+"v@	c #5978E6",
-+"w@	c #5C7DE8",
-+"x@	c #5D7CE9",
-+"y@	c #2F48C0",
-+"z@	c #2A42BA",
-+"A@	c #2D41BA",
-+"B@	c #3042BA",
-+"C@	c #3043BA",
-+"D@	c #3043B9",
-+"E@	c #3046BD",
-+"F@	c #2E57C8",
-+"G@	c #2E58C8",
-+"H@	c #3460D0",
-+"I@	c #4F7DE8",
-+"J@	c #4C7EE6",
-+"K@	c #4A7FE6",
-+"L@	c #4A7FE5",
-+"M@	c #4A7FE4",
-+"N@	c #477CE4",
-+"O@	c #457AE4",
-+"P@	c #4478DE",
-+"Q@	c #406FE4",
-+"R@	c #4B70DE",
-+"S@	c #4D72DE",
-+"T@	c #4E72DE",
-+"U@	c #5073DD",
-+"V@	c #5675DF",
-+"W@	c #5676E1",
-+"X@	c #587AE2",
-+"Y@	c #5A7CE4",
-+"Z@	c #2E48BB",
-+"`@	c #2942B6",
-+" #	c #2A42B6",
-+".#	c #2E42B5",
-+"+#	c #2E43B5",
-+"@#	c #2E42B4",
-+"##	c #2D44B6",
-+"$#	c #2C56C4",
-+"%#	c #2C58C4",
-+"&#	c #3260CC",
-+"*#	c #4B7DE2",
-+"=#	c #497DE0",
-+"-#	c #477DE0",
-+";#	c #487DE0",
-+">#	c #467EE0",
-+",#	c #467EDF",
-+"'#	c #457DDE",
-+")#	c #437ADD",
-+"!#	c #4279DD",
-+"~#	c #4177D9",
-+"{#	c #3E6EDE",
-+"]#	c #486ED8",
-+"^#	c #4B71D9",
-+"/#	c #4B72D9",
-+"(#	c #4D72D8",
-+"_#	c #5374DA",
-+":#	c #5475DB",
-+"<#	c #5578DC",
-+"[#	c #567ADD",
-+"}#	c #2C48B7",
-+"|#	c #2742B1",
-+"1#	c #2A42B1",
-+"2#	c #2C42B1",
-+"3#	c #2C42B0",
-+"4#	c #2B44B2",
-+"5#	c #2A56BF",
-+"6#	c #2A57BF",
-+"7#	c #315EC7",
-+"8#	c #467CDC",
-+"9#	c #457CDA",
-+"0#	c #447CDA",
-+"a#	c #437CDA",
-+"b#	c #437CD8",
-+"c#	c #427CD8",
-+"d#	c #427AD8",
-+"e#	c #4077D7",
-+"f#	c #3F76D5",
-+"g#	c #3F75D4",
-+"h#	c #3C6FD8",
-+"i#	c #466ED2",
-+"j#	c #486ED4",
-+"k#	c #4A70D4",
-+"l#	c #4A70D3",
-+"m#	c #4E72D4",
-+"n#	c #5174D6",
-+"o#	c #5074D6",
-+"p#	c #5276D6",
-+"q#	c #5277D6",
-+"r#	c #2A46B2",
-+"s#	c #2540AC",
-+"t#	c #2840AC",
-+"u#	c #2A42AC",
-+"v#	c #2A41AC",
-+"w#	c #2A44AE",
-+"x#	c #2955BA",
-+"y#	c #2856BA",
-+"z#	c #2E5EC2",
-+"A#	c #447AD6",
-+"B#	c #437AD5",
-+"C#	c #417AD4",
-+"D#	c #407AD2",
-+"E#	c #3F79D1",
-+"F#	c #3E78D0",
-+"G#	c #3E76D1",
-+"H#	c #3E75D2",
-+"I#	c #3C74CF",
-+"J#	c #3B73CE",
-+"K#	c #3A6FD5",
-+"L#	c #436CCC",
-+"M#	c #456ECE",
-+"N#	c #466FCE",
-+"O#	c #4A71CE",
-+"P#	c #4E73D0",
-+"Q#	c #4E74D0",
-+"R#	c #4F74D0",
-+"S#	c #4E74CF",
-+"T#	c #2846AD",
-+"U#	c #2440A8",
-+"V#	c #2340A8",
-+"W#	c #2640A7",
-+"X#	c #2740A7",
-+"Y#	c #2841A7",
-+"Z#	c #2843A9",
-+"`#	c #2652B5",
-+" $	c #2552B5",
-+".$	c #2B5CBC",
-+"+$	c #417AD0",
-+"@$	c #3F79CE",
-+"#$	c #3E78CC",
-+"$$	c #3C76CA",
-+"%$	c #3B76C8",
-+"&$	c #3B74C9",
-+"*$	c #3B74CC",
-+"=$	c #3A73CD",
-+"-$	c #3871CA",
-+";$	c #3870C9",
-+">$	c #386ED0",
-+",$	c #426CC7",
-+"'$	c #426CC9",
-+")$	c #446EC9",
-+"!$	c #466FC9",
-+"~$	c #4A72CA",
-+"{$	c #4C73CC",
-+"]$	c #4B72CB",
-+"^$	c #2E4FB0",
-+"/$	c #2340A4",
-+"($	c #223FA4",
-+"_$	c #223FA3",
-+":$	c #233FA3",
-+"<$	c #2442A5",
-+"[$	c #224FB0",
-+"}$	c #2350B2",
-+"|$	c #2E62BC",
-+"1$	c #3E79CB",
-+"2$	c #3B77C8",
-+"3$	c #3A76C5",
-+"4$	c #3873C2",
-+"5$	c #3771C2",
-+"6$	c #3771C5",
-+"7$	c #3771C8",
-+"8$	c #3770C6",
-+"9$	c #3670C5",
-+"0$	c #366FC6",
-+"a$	c #346CCD",
-+"b$	c #3F6BC2",
-+"c$	c #406BC2",
-+"d$	c #426DC4",
-+"e$	c #426EC4",
-+"f$	c #456FC4",
-+"g$	c #4A72C6",
-+"h$	c #4A73C7",
-+"i$	c #4A72C7",
-+"j$	c #466EC3",
-+"k$	c #3E65BC",
-+"l$	c #4065BD",
-+"m$	c #4166BD",
-+"n$	c #4066BD",
-+"o$	c #4066BC",
-+"p$	c #3F66BD",
-+"q$	c #346BBF",
-+"r$	c #356DC0",
-+"s$	c #3B76C6",
-+"t$	c #3B78C4",
-+"u$	c #3874C1",
-+"v$	c #3672BE",
-+"w$	c #3570BD",
-+"x$	c #346EBF",
-+"y$	c #346EC1",
-+"z$	c #346DC1",
-+"A$	c #346CC0",
-+"B$	c #346DC0",
-+"C$	c #346EC2",
-+"D$	c #316AC9",
-+"E$	c #3C6ABE",
-+"F$	c #3D6BBE",
-+"G$	c #3F6CC0",
-+"H$	c #416CC0",
-+"I$	c #426DC0",
-+"J$	c #4570C0",
-+"K$	c #4872C2",
-+"L$	c #4A76C4",
-+"M$	c #4E79C7",
-+"N$	c #4F7AC7",
-+"O$	c #507AC8",
-+"P$	c #4E79C8",
-+"Q$	c #3D79C4",
-+"R$	c #3C7AC4",
-+"S$	c #3A79C2",
-+"T$	c #3776BF",
-+"U$	c #3572BB",
-+"V$	c #336FBA",
-+"W$	c #326DBB",
-+"X$	c #326CBD",
-+"Y$	c #326ABD",
-+"Z$	c #3169BB",
-+"`$	c #3169BA",
-+" %	c #316ABB",
-+".%	c #2E66C3",
-+"+%	c #396ABA",
-+"@%	c #3C6BBA",
-+"#%	c #3C6ABB",
-+"$%	c #3E6CBD",
-+"%%	c #406CBD",
-+"&%	c #406DBD",
-+"*%	c #426EBD",
-+"=%	c #456FBD",
-+"-%	c #4672BF",
-+";%	c #4672C0",
-+">%	c #4874C0",
-+",%	c #4976C1",
-+"'%	c #4B78C2",
-+")%	c #4C78C3",
-+"!%	c #4E78C3",
-+"~%	c #4B78C3",
-+"{%	c #3C78C1",
-+"]%	c #3A79C1",
-+"^%	c #3778BE",
-+"/%	c #3673BA",
-+"(%	c #326EB8",
-+"_%	c #326DBA",
-+":%	c #326BBB",
-+"<%	c #316ABA",
-+"[%	c #2F68B9",
-+"}%	c #2E66B8",
-+"|%	c #3067BB",
-+"1%	c #2C63BF",
-+"2%	c #3769B8",
-+"3%	c #3969B8",
-+"4%	c #3B6AB8",
-+"5%	c #3C6AB8",
-+"6%	c #3E6CBA",
-+"7%	c #3F6DBA",
-+"8%	c #416DBA",
-+"9%	c #446FBB",
-+"0%	c #4672BC",
-+"a%	c #4672BD",
-+"b%	c #4674BC",
-+"c%	c #4674BD",
-+"d%	c #4775BE",
-+"e%	c #4575BE",
-+"f%	c #3A76C0",
-+"g%	c #3776BE",
-+"h%	c #3573BB",
-+"i%	c #326EB6",
-+"j%	c #306CB7",
-+"k%	c #316CBB",
-+"l%	c #3068B8",
-+"m%	c #2E66B9",
-+"n%	c #2E66BA",
-+"o%	c #3068BE",
-+"p%	c #2B62C0",
-+"q%	c #3769B6",
-+"r%	c #3A68B6",
-+"s%	c #3B69B6",
-+"t%	c #406DBA",
-+"u%	c #436EBA",
-+"v%	c #4571BB",
-+"w%	c #4372BC",
-+"x%	c #3774BE",
-+"y%	c #3875C3",
-+"z%	c #316DB6",
-+"A%	c #2F6BB5",
-+"B%	c #306BB9",
-+"C%	c #326ABB",
-+"D%	c #3169BD",
-+"E%	c #3169BF",
-+"F%	c #3169C0",
-+"G%	c #3067BE",
-+"H%	c #2E66BC",
-+"I%	c #285FBC",
-+"J%	c #3667B5",
-+"K%	c #3768B6",
-+"L%	c #3C6BB9",
-+"M%	c #416EBA",
-+"N%	c #4470BA",
-+"O%	c #4570BB",
-+"P%	c #3873BD",
-+"Q%	c #3A76C6",
-+"R%	c #3974C3",
-+"S%	c #336FBC",
-+"T%	c #316CB9",
-+"U%	c #326CBB",
-+"V%	c #336CBD",
-+"W%	c #346CC2",
-+"X%	c #326AC2",
-+"Y%	c #3068C1",
-+"Z%	c #2B64B8",
-+"`%	c #245AB6",
-+" &	c #3466B5",
-+".&	c #3668B5",
-+"+&	c #3868B6",
-+"@&	c #3F6CBA",
-+"#&	c #426FBA",
-+"$&	c #436FBA",
-+"%&	c #4271BA",
-+"&&	c #3772BB",
-+"*&	c #3975C3",
-+"=&	c #3974C4",
-+"-&	c #3772C2",
-+";&	c #346FBF",
-+">&	c #326CBC",
-+",&	c #3169BC",
-+"'&	c #2D65BC",
-+")&	c #2961B5",
-+"!&	c #2861B4",
-+"~&	c #2056B2",
-+". . + @ # $ % % & * * * = - - ; ; > > ; , - - * * * ' ) % % ! ~ ",
-+". { ] ^ / % ) ' * * ( , > > _ : < < < : : [ > ; - * * * } % % | ",
-+"+ 1 ^ % % & * * ( 2 > 3 < < < < < < < < < < < 3 _ > - * * ' 4 5 ",
-+"@ ^ % % 6 * * - > 3 < < < < 7 8 9 9 0 0 a b < < < < [ ; = * c d ",
-+"e / % ' * * , f < < < 7 g h i j j j j j i i 9 8 b < < 3 > - * + ",
-+"$ % & * * ; [ < < a 9 i j k k k k h l m n o p p q r s t u > - v ",
-+"% ) * * , _ < < 8 w k k k k k k x y z A B C D E F G G H I [ > J ",
-+"% ' * , [ < < K L k k k k x M N O P Q R S T U U V W W X Y > < Z ",
-+"& * = `  . ...+. at .#.$.%.&.*.=.-.;.>.,.'.).!.~.{.U ].].^./.< < (.",
-+"c * _.:.<.[.}.|.1.2.3.4.5.;.;.;.;.6.7.8.9.).).!.{.U V 0.a.8 b (.",
-+"* ( b.c.d.e.f.g.h.i.j.k.l.;.;.;.;.m.n.o.p.p.9.).q.{.{.r.s.h b t.",
-+"* , u.v.[.w.x.y.z.A.B.C.D.;.;.;.;.E.F.G.p.p.p.H.).q.~.I.J.w 9 } ",
-+"* > u.K.L.f.1.2.3.M.C.C.N.;.;.;.;.O.P.Q.R.S.p.p.H.).).T.U.V.w 6 ",
-+"- > W.K.w.|.X.Y.Z.`. +.+++ at +@+#+$+%+&+*+=+Q.-+p.p.9.).E ;+V.i - ",
-+">+,+'+)+!+~+{+]+^+/+(+_+:+<+<+[+[+}+|+1+2+3+4+5+5+5+6+7+8+9+0+a+",
-+"b+c+d+e+f+g+h+i+j+k+l+m+n+o+o+o+p+q+r+s+t+u+v+w+w+x+y+z+A+B+C+D+",
-+"b+E+F+e+G+h+H+I+J+K+L+M+N+O+O+P+P+Q+R+S+T+U+V+V+W+W+X+Y+Z+`+`+ @",
-+". at +@@@#@$@%@&@*@=@-@;@>@,@'@)@)@)@)@!@~@{@]@^@/@(@(@_ at _@_@:@<@[@",
-+"}@|@|@1 at 2@3 at 4@5 at 6@7 at 8@9 at 0@a at a@a at a@b at c@d at e@f at g@h at i@j at j@k at l@m at n@o@",
-+"p at q@r at s@t at u@v at w@x at y@z at A@B at C@D at D@D at E@F at G@H at I@J at K@L at L@L at M@N at O@P at Q@",
-+"R at S@T at U@V at W@W at X@Y at Z@`@ #.#+#+#+#@###$#%#&#*#=#-#;#>#,#'#)#!#~#{#",
-+"]#^#/#(#_#:#:#<#[#}#|#|#1#2#2#3#3#4#5#6#7#8#9#0#a#b#c#d#e#f#g#h#",
-+"i#j#k#l#m#n#o#p#q#r#s#s#s#t#u#v#u#w#x#y#z#A#B#C#D#E#F#G#H#I#J#K#",
-+"L#M#N#N#O#P#Q#R#S#T#U#U#V#V#W#X#Y#Z#`# $.$+$@$#$$$%$&$*$=$-$;$>$",
-+",$'$)$)$!$~${${$]$^$/$($_$_$_$_$:$<$[$}$|$1$2$3$4$5$6$7$8$9$0$a$",
-+"b$c$d$e$e$f$g$h$i$j$k$l$m$m$n$n$o$p$q$r$s$t$u$v$w$x$y$z$A$B$C$D$",
-+"E$F$G$H$I$I$J$K$K$K$K$L$M$N$O$O$O$P$Q$R$S$T$U$V$W$X$Y$Z$`$ %Y$.%",
-+"+%@%#%$%%%&%*%=%-%;%;%;%>%,%'%)%!%~%{%]%^%/%(%_%:%<%[%}%}%}%|%1%",
-+"2%3%4%5%6%7%7%8%9%0%a%a%0%0%b%c%d%e%f%g%h%i%j%k%<%l%}%m%m%n%o%p%",
-+"q%q%r%s%5%6%7%7%t%u%v%0%0%0%0%0%0%w%x%y%v$z%A%B%C%Z$D%E%F%G%H%I%",
-+"J%q%K%s%s%L%6%7%7%7%M%N%O%0%0%0%0%w%P%Q%R%S%T%U%V%A$W%X%Y%H%Z%`%",
-+" &.&q%+&s%s%5%6%@&7%7%t%t%#&$&N%N%%&&&*&=&-&;&>&C%,&o%'&)&!&!&~&"};
diff --git a/debian/rules b/debian/rules
index 671fb10..9ed125b 100755
--- a/debian/rules
+++ b/debian/rules
@@ -2,6 +2,7 @@
 # -*- makefile -*-
 
 include /usr/share/quilt/quilt.make
+#include debian/tg2quilt.mk
 
 # Always use verbose incase we have an autobuild fail and need to check a log
 export VERBOSE=1
@@ -34,23 +35,35 @@ endif
 DEB_BUILD_ARCH=$(shell dpkg-architecture -qDEB_BUILD_ARCH)
 SLVIEWER_ARCH=$(subst amd64,x86_64,$(subst i386,i686,$(DEB_BUILD_ARCH)))
 
+CMAKE_CURRENT_BINARY_DIR := $(BUILD_DIR:$(shell pwd)/build)
+
 #Architecture 
 build: build-arch build-indep
 
 configure: patch
 	dh_testdir
-	-mkdir -p indra/build
+	DEB_BUILD_OPTIONS="$(DEB_BUILD_OPTIONS)"; \
+	CXXFLAGS="$(CXXFLAGS)"; \
+	DBGFLAGS="$(DBGFLAGS)"; \
+	CONFFILE_CMAKE_ARGUMENTS=""; \
+	for conffile in $$(ls debian/conffiles); do . debian/conffiles/$$conffile; done && \
+	echo "CXXFLAGS is \"$$CXXFLAGS\"" && \
+	echo "DBGFLAGS is \"$$DBGFLAGS\"" && \
+	echo "CONFFILE_CMAKE_ARGUMENTS is \"$$CONFFILE_CMAKE_ARGUMENTS\"" && \
+	mkdir -p indra/build && \
 	cd indra/build && \
 	cmake -DUNATTENDED:BOOl=FALSE -DSTANDALONE:BOOL=TRUE \
 	-DCMAKE_BUILD_TYPE:STRING=RELWITHDEBINFO -DSERVER:BOOL=FALSE \
+	-DCMAKE_CURRENT_BINARY_DIR:STRING=$(CMAKE_CURRENT_BINARY_DIR) \
 	-DVIEWER:BOOL=TRUE -DMOZLIB:BOOL=true -DINSTALL:BOOL=TRUE \
 	-DAPP_SHARE_DIR:STRING=/usr/share/omvviewer/ \
 	-DAPP_BINARY_DIR:STRING=/usr/games/ \
 	-DCMAKE_INSTALL_PREFIX:STRING=debian/ \
-	-DBINARY_NAME:STRING=omvviewer \
+	-DVIEWER_BINARY_NAME:STRING=omvviewer \
 	-DOPENAL:BOOL=TRUE \
-	-DCMAKE_CXX_FLAGS:STRING="$(CXXFLAGS)" \
-	-DCMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING="$(DBGFLAGS)" \
+	-DCMAKE_CXX_FLAGS:STRING="$$CXXFLAGS" \
+	-DCMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING="$$DBGFLAGS" \
+	$$CONFFILE_CMAKE_ARGUMENTS \
 	..
 
 build-arch: build-arch-stamp
diff --git a/debian/watch b/debian/watch
index cbd74a5..b35177d 100644
--- a/debian/watch
+++ b/debian/watch
@@ -1,5 +1,5 @@
 # Compulsory line, this is a version 3 file
 version=3
-opts=uversionmangle=s/-/./g \
-http://wiki.secondlife.com/wiki/Source_archive http://secondlife.com/developers/opensource/downloads/.*/.*/slviewer-src-Branch_(.*)-Viewer-.*.tar.gz
+#opts=uversionmangle=s/-/./g \
+http://wiki.secondlife.com/wiki/Source_downloads http://secondlife.com/developers/opensource/downloads/.*/.*/slviewer-src-viewer-(.*)-.*.tar.gz
 

-- 
A client for connecting to 3D metaverses such as Linden Labs Secondlife(tm) and OpenSim grids



More information about the Pkg-games-commits mailing list