diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp
index 74b8885e1ff4dad35cabe8dbfcc2677e3657954d..a01dccc7ab5a307df3ad0b0a7da911c00abe76fe 100644
--- a/indra/llui/llbutton.cpp
+++ b/indra/llui/llbutton.cpp
@@ -115,7 +115,7 @@ LLButton::Params::Params()
 
 LLButton::LLButton(const LLButton::Params& p)
 :	LLUICtrl(p),
-	LLBadgeOwner(LLView::getHandle()),
+	LLBadgeOwner(getHandle()),
 	mMouseDownFrame(0),
 	mMouseHeldDownCount(0),
 	mBorderEnabled( FALSE ),
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index 432397d3e9fb0fa902ffded0768d305e3d195976..07d2e1ed5f0afb3349e5525b16e52c6a4d628836 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -111,7 +111,6 @@ LLFloater::click_callback LLFloater::sButtonCallbacks[BUTTON_COUNT] =
 
 LLMultiFloater* LLFloater::sHostp = NULL;
 BOOL			LLFloater::sQuitting = FALSE; // Flag to prevent storing visibility controls while quitting
-LLFloater::handle_map_t	LLFloater::sFloaterMap;
 
 LLFloaterView* gFloaterView = NULL;
 
@@ -268,7 +267,6 @@ LLFloater::LLFloater(const LLSD& key, const LLFloater::Params& p)
 	mMinimizeSignal(NULL)
 //	mNotificationContext(NULL)
 {
-	mHandle.bind(this);
 //	mNotificationContext = new LLFloaterNotificationContext(getHandle());
 
 	// Clicks stop here.
@@ -323,9 +321,6 @@ void LLFloater::initFloater(const Params& p)
 	// Floaters are created in the invisible state	
 	setVisible(FALSE);
 
-	// add self to handle->floater map
-	sFloaterMap[mHandle] = this;
-
 	if (!getParent())
 	{
 		gFloaterView->addChild(this);
@@ -532,8 +527,6 @@ LLFloater::~LLFloater()
 	// correct, non-minimized positions.
 	setMinimized( FALSE );
 
-	sFloaterMap.erase(mHandle);
-
 	delete mDragHandle;
 	for (S32 i = 0; i < 4; i++) 
 	{
@@ -1038,7 +1031,9 @@ BOOL LLFloater::canSnapTo(const LLView* other_view)
 	if (other_view != getParent())
 	{
 		const LLFloater* other_floaterp = dynamic_cast<const LLFloater*>(other_view);		
-		if (other_floaterp && other_floaterp->getSnapTarget() == getHandle() && mDependents.find(other_floaterp->getHandle()) != mDependents.end())
+		if (other_floaterp 
+			&& other_floaterp->getSnapTarget() == getHandle() 
+			&& mDependents.find(other_floaterp->getHandle()) != mDependents.end())
 		{
 			// this is a dependent that is already snapped to us, so don't snap back to it
 			return FALSE;
@@ -1677,18 +1672,17 @@ void LLFloater::onClickHelp( LLFloater* self )
 LLFloater* LLFloater::getClosableFloaterFromFocus()
 {
 	LLFloater* focused_floater = NULL;
-
-	handle_map_iter_t iter;
-	for(iter = sFloaterMap.begin(); iter != sFloaterMap.end(); ++iter)
+	LLInstanceTracker<LLFloater>::instance_iter it = beginInstances();
+	LLInstanceTracker<LLFloater>::instance_iter end_it = endInstances();
+	for (; it != end_it; ++it)
 	{
-		focused_floater = iter->second;
-		if (focused_floater->hasFocus())
+		if (it->hasFocus())
 		{
 			break;
 		}
 	}
 
-	if (iter == sFloaterMap.end())
+	if (it == endInstances())
 	{
 		// nothing found, return
 		return NULL;
diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h
index 73e9c9e83107721223d15bf32678f9fac7deb2a2..b24ae1beb9c9a7bb8f6ec4df13eb8374a5842a8e 100644
--- a/indra/llui/llfloater.h
+++ b/indra/llui/llfloater.h
@@ -83,7 +83,7 @@ namespace LLInitParam
 }
 
 
-class LLFloater : public LLPanel
+class LLFloater : public LLPanel, public LLInstanceTracker<LLFloater>
 {
 	friend class LLFloaterView;
 	friend class LLFloaterReg;
@@ -282,7 +282,7 @@ class LLFloater : public LLPanel
 	void			clearSnapTarget() { mSnappedTo.markDead(); }
 	LLHandle<LLFloater>	getSnapTarget() const { return mSnappedTo; }
 
-	LLHandle<LLFloater> getHandle() const { return mHandle; }
+	LLHandle<LLFloater> getHandle() const { return getDerivedHandle<LLFloater>(); }
 	const LLSD& 	getKey() { return mKey; }
 	virtual bool	matchesKey(const LLSD& key) { return mSingleInstance || KeyCompare::equate(key, mKey); }
 	
@@ -460,16 +460,9 @@ class LLFloater : public LLPanel
 	typedef void(*click_callback)(LLFloater*);
 	static click_callback sButtonCallbacks[BUTTON_COUNT];
 
-	typedef std::map<LLHandle<LLFloater>, LLFloater*> handle_map_t;
-	typedef std::map<LLHandle<LLFloater>, LLFloater*>::iterator handle_map_iter_t;
-	static handle_map_t	sFloaterMap;
-
 	BOOL			mHasBeenDraggedWhileMinimized;
 	S32				mPreviousMinimizedBottom;
 	S32				mPreviousMinimizedLeft;
-
-//	LLFloaterNotificationContext* mNotificationContext;
-	LLRootHandle<LLFloater>		mHandle;	
 };
 
 
diff --git a/indra/llui/llhandle.h b/indra/llui/llhandle.h
index 8c000eee48cc6fe4f682cd33e88dd09e52da94f5..c8fff72110e13ad0a31634e76061cdceb5a6959f 100644
--- a/indra/llui/llhandle.h
+++ b/indra/llui/llhandle.h
@@ -28,17 +28,18 @@
 #define LLHANDLE_H
 
 #include "llpointer.h"
+#include <boost/type_traits/is_convertible.hpp>
+#include <boost/utility/enable_if.hpp>
 
-template <typename T>
 class LLTombStone : public LLRefCount
 {
 public:
-	LLTombStone(T* target = NULL) : mTarget(target) {}
+	LLTombStone(void* target = NULL) : mTarget(target) {}
 
-	void setTarget(T* target) { mTarget = target; }
-	T* getTarget() const { return mTarget; }
+	void setTarget(void* target) { mTarget = target; }
+	void* getTarget() const { return mTarget; }
 private:
-	T* mTarget;
+	mutable void* mTarget;
 };
 
 //	LLHandles are used to refer to objects whose lifetime you do not control or influence.  
@@ -53,13 +54,15 @@ class LLTombStone : public LLRefCount
 template <typename T>
 class LLHandle
 {
+	template <typename U> friend class LLHandle;
+	template <typename U> friend class LLHandleProvider;
 public:
 	LLHandle() : mTombStone(getDefaultTombStone()) {}
-	const LLHandle<T>& operator =(const LLHandle<T>& other)  
-	{ 
-		mTombStone = other.mTombStone;
-		return *this; 
-	}
+
+	template<typename U>
+	LLHandle(const LLHandle<U>& other, typename boost::enable_if< typename boost::is_convertible<U*, T*> >::type* dummy = 0)
+	: mTombStone(other.mTombStone)
+	{}
 
 	bool isDead() const 
 	{ 
@@ -73,7 +76,7 @@ class LLHandle
 
 	T* get() const
 	{
-		return mTombStone->getTarget();
+		return reinterpret_cast<T*>(mTombStone->getTarget());
 	}
 
 	friend bool operator== (const LLHandle<T>& lhs, const LLHandle<T>& rhs)
@@ -94,12 +97,13 @@ class LLHandle
 	}
 
 protected:
-	LLPointer<LLTombStone<T> > mTombStone;
+	LLPointer<LLTombStone> mTombStone;
 
 private:
-	static LLPointer<LLTombStone<T> >& getDefaultTombStone()
+	typedef T* pointer_t;
+	static LLPointer<LLTombStone>& getDefaultTombStone()
 	{
-		static LLPointer<LLTombStone<T> > sDefaultTombStone = new LLTombStone<T>;
+		static LLPointer<LLTombStone> sDefaultTombStone = new LLTombStone;
 		return sDefaultTombStone;
 	}
 };
@@ -108,23 +112,26 @@ template <typename T>
 class LLRootHandle : public LLHandle<T>
 {
 public:
+	typedef LLRootHandle<T> self_t;
+	typedef LLHandle<T> base_t;
+
 	LLRootHandle(T* object) { bind(object); }
 	LLRootHandle() {};
 	~LLRootHandle() { unbind(); }
 
-	// this is redundant, since a LLRootHandle *is* an LLHandle
-	LLHandle<T> getHandle() { return LLHandle<T>(*this); }
+	// this is redundant, since an LLRootHandle *is* an LLHandle
+	//LLHandle<T> getHandle() { return LLHandle<T>(*this); }
 
 	void bind(T* object) 
 	{ 
 		// unbind existing tombstone
 		if (LLHandle<T>::mTombStone.notNull())
 		{
-			if (LLHandle<T>::mTombStone->getTarget() == object) return;
+			if (LLHandle<T>::mTombStone->getTarget() == (void*)object) return;
 			LLHandle<T>::mTombStone->setTarget(NULL);
 		}
 		// tombstone reference counted, so no paired delete
-		LLHandle<T>::mTombStone = new LLTombStone<T>(object);
+		LLHandle<T>::mTombStone = new LLTombStone((void*)object);
 	}
 
 	void unbind() 
@@ -142,6 +149,15 @@ class LLRootHandle : public LLHandle<T>
 template <typename T>
 class LLHandleProvider
 {
+public:
+	LLHandle<T> getHandle() const
+	{ 
+		// perform lazy binding to avoid small tombstone allocations for handle
+		// providers whose handles are never referenced
+		mHandle.bind(static_cast<T*>(const_cast<LLHandleProvider<T>* >(this))); 
+		return mHandle; 
+	}
+
 protected:
 	typedef LLHandle<T> handle_type_t;
 	LLHandleProvider() 
@@ -149,16 +165,17 @@ class LLHandleProvider
 		// provided here to enforce T deriving from LLHandleProvider<T>
 	} 
 
-	LLHandle<T> getHandle() 
-	{ 
-		// perform lazy binding to avoid small tombstone allocations for handle
-		// providers whose handles are never referenced
-		mHandle.bind(static_cast<T*>(this)); 
-		return mHandle; 
+	template <typename U>
+	typename LLHandle<U> getDerivedHandle(typename boost::enable_if< typename boost::is_convertible<U*, T*> >::type* dummy = 0) const
+	{
+		LLHandle<U> downcast_handle;
+		downcast_handle.mTombStone = mHandle.mTombStone;
+		return downcast_handle;
 	}
 
+
 private:
-	LLRootHandle<T> mHandle;
+	mutable LLRootHandle<T> mHandle;
 };
 
 #endif
diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h
index bdae899933b6c0b5e9cf47a2a3fa19512683affe..36f3ba34b9b5e45c3271563e0efc7224acbb86fe 100644
--- a/indra/llui/llmenugl.h
+++ b/indra/llui/llmenugl.h
@@ -681,7 +681,7 @@ class LLContextMenu
 
 			BOOL	appendContextSubMenu(LLContextMenu *menu);
 
-			LLHandle<LLContextMenu> getHandle() { mHandle.bind(this); return mHandle; }
+			LLHandle<LLContextMenu> getHandle() { return getDerivedHandle<LLContextMenu>(); }
 
 protected:
 	BOOL						mHoveredAnyItem;
diff --git a/indra/llui/llpanel.cpp b/indra/llui/llpanel.cpp
index a45b617c2ecb8f5d2af50c13c203c653b391fdaa..00318cec6b0b3043863eae2754ad9565b0ae1c38 100644
--- a/indra/llui/llpanel.cpp
+++ b/indra/llui/llpanel.cpp
@@ -122,8 +122,6 @@ LLPanel::LLPanel(const LLPanel::Params& p)
 	{
 		addBorder(p.border);
 	}
-	
-	mPanelHandle.bind(this);
 }
 
 LLPanel::~LLPanel()
diff --git a/indra/llui/llpanel.h b/indra/llui/llpanel.h
index ab1c87caffeb571417a5c003d1045a3ab26ff841..cd33938226375ff07efe7d382ad66cef9533bf89 100644
--- a/indra/llui/llpanel.h
+++ b/indra/llui/llpanel.h
@@ -153,7 +153,7 @@ class LLPanel : public LLUICtrl, public LLBadgeHolder
 	
 	void			setCtrlsEnabled(BOOL b);
 
-	LLHandle<LLPanel>	getHandle() const { return mPanelHandle; }
+	LLHandle<LLPanel>	getHandle() const { return getDerivedHandle<LLPanel>(); }
 
 	const LLCallbackMap::map_t& getFactoryMap() const { return mFactoryMap; }
 	
@@ -278,7 +278,6 @@ class LLPanel : public LLUICtrl, public LLBadgeHolder
 	LLViewBorder*	mBorder;
 	LLButton*		mDefaultBtn;
 	LLUIString		mLabel;
-	LLRootHandle<LLPanel> mPanelHandle;
 
 	typedef std::map<std::string, std::string> ui_string_map_t;
 	ui_string_map_t	mUIStrings;
diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp
index 2fa260ded1e537c4ed6c5d32055ba303f4207650..b9c843e931c4aa657eec7a3f3bed2d127870b230 100644
--- a/indra/llui/lluictrl.cpp
+++ b/indra/llui/lluictrl.cpp
@@ -118,7 +118,6 @@ LLUICtrl::LLUICtrl(const LLUICtrl::Params& p, const LLViewModelPtr& viewmodel)
 	mDoubleClickSignal(NULL),
 	mTransparencyType(TT_DEFAULT)
 {
-	mUICtrlHandle.bind(this);
 }
 
 void LLUICtrl::initFromParams(const Params& p)
@@ -460,7 +459,7 @@ void LLUICtrl::setControlVariable(LLControlVariable* control)
 	if (control)
 	{
 		mControlVariable = control;
-		mControlConnection = mControlVariable->getSignal()->connect(boost::bind(&controlListener, _2, getUICtrlHandle(), std::string("value")));
+		mControlConnection = mControlVariable->getSignal()->connect(boost::bind(&controlListener, _2, getHandle(), std::string("value")));
 		setValue(mControlVariable->getValue());
 	}
 }
@@ -491,7 +490,7 @@ void LLUICtrl::setEnabledControlVariable(LLControlVariable* control)
 	if (control)
 	{
 		mEnabledControlVariable = control;
-		mEnabledControlConnection = mEnabledControlVariable->getSignal()->connect(boost::bind(&controlListener, _2, getUICtrlHandle(), std::string("enabled")));
+		mEnabledControlConnection = mEnabledControlVariable->getSignal()->connect(boost::bind(&controlListener, _2, getHandle(), std::string("enabled")));
 		setEnabled(mEnabledControlVariable->getValue().asBoolean());
 	}
 }
@@ -506,7 +505,7 @@ void LLUICtrl::setDisabledControlVariable(LLControlVariable* control)
 	if (control)
 	{
 		mDisabledControlVariable = control;
-		mDisabledControlConnection = mDisabledControlVariable->getSignal()->connect(boost::bind(&controlListener, _2, getUICtrlHandle(), std::string("disabled")));
+		mDisabledControlConnection = mDisabledControlVariable->getSignal()->connect(boost::bind(&controlListener, _2, getHandle(), std::string("disabled")));
 		setEnabled(!(mDisabledControlVariable->getValue().asBoolean()));
 	}
 }
@@ -521,7 +520,7 @@ void LLUICtrl::setMakeVisibleControlVariable(LLControlVariable* control)
 	if (control)
 	{
 		mMakeVisibleControlVariable = control;
-		mMakeVisibleControlConnection = mMakeVisibleControlVariable->getSignal()->connect(boost::bind(&controlListener, _2, getUICtrlHandle(), std::string("visible")));
+		mMakeVisibleControlConnection = mMakeVisibleControlVariable->getSignal()->connect(boost::bind(&controlListener, _2, getHandle(), std::string("visible")));
 		setVisible(mMakeVisibleControlVariable->getValue().asBoolean());
 	}
 }
@@ -536,7 +535,7 @@ void LLUICtrl::setMakeInvisibleControlVariable(LLControlVariable* control)
 	if (control)
 	{
 		mMakeInvisibleControlVariable = control;
-		mMakeInvisibleControlConnection = mMakeInvisibleControlVariable->getSignal()->connect(boost::bind(&controlListener, _2, getUICtrlHandle(), std::string("invisible")));
+		mMakeInvisibleControlConnection = mMakeInvisibleControlVariable->getSignal()->connect(boost::bind(&controlListener, _2, getHandle(), std::string("invisible")));
 		setVisible(!(mMakeInvisibleControlVariable->getValue().asBoolean()));
 	}
 }
diff --git a/indra/llui/lluictrl.h b/indra/llui/lluictrl.h
index 3e055a9d06229c671de929b0feb93646acdd7b7d..fb2196bb1640a164a23b390a27c9927a3d7f7e61 100644
--- a/indra/llui/lluictrl.h
+++ b/indra/llui/lluictrl.h
@@ -223,7 +223,7 @@ class LLUICtrl
 	BOOL	focusLastItem(BOOL prefer_text_fields = FALSE);
 
 	// Non Virtuals
-	LLHandle<LLUICtrl> getUICtrlHandle() const { return mUICtrlHandle; }
+	LLHandle<LLUICtrl> getHandle() const { return getDerivedHandle<LLUICtrl>(); }
 	BOOL			getIsChrome() const;
 	
 	void			setTabStop( BOOL b );
@@ -313,7 +313,6 @@ class LLUICtrl
 	BOOL			mRequestsFront;
 	BOOL			mTabStop;
 	BOOL			mTentative;
-	LLRootHandle<LLUICtrl> mUICtrlHandle;
 
 	ETypeTransparency mTransparencyType;
 
diff --git a/indra/llui/llview.h b/indra/llui/llview.h
index 08828e55e6a0ae216be8328b99f0453af0cd6ae9..13f118abecb700f1a208a31c66bae7859e94fa7c 100644
--- a/indra/llui/llview.h
+++ b/indra/llui/llview.h
@@ -97,7 +97,11 @@ class LLViewDrawContext
 	static std::vector<LLViewDrawContext*> sDrawContextStack;
 };
 
-class LLView : public LLMouseHandler, public LLMortician, public LLFocusableElement
+class LLView 
+:	public LLMouseHandler,			// handles mouse events
+	public LLFocusableElement,		// handles keyboard events
+	public LLMortician,				// lazy deletion
+	public LLHandleProvider<LLView>	// passes out weak references to self
 {
 public:
 	struct Follows : public LLInitParam::ChoiceBlock<Follows>
@@ -306,8 +310,6 @@ class LLView : public LLMouseHandler, public LLMortician, public LLFocusableElem
 	void			popVisible()				{ setVisible(mLastVisible); }
 	BOOL			getLastVisible()	const	{ return mLastVisible; }
 
-	LLHandle<LLView>	getHandle()				{ mHandle.bind(this); return mHandle; }
-
 	U32			getFollows() const				{ return mReshapeFlags; }
 	BOOL		followsLeft() const				{ return mReshapeFlags & FOLLOWS_LEFT; }
 	BOOL		followsRight() const			{ return mReshapeFlags & FOLLOWS_RIGHT; }
@@ -606,7 +608,6 @@ class LLView : public LLMouseHandler, public LLMortician, public LLFocusableElem
 	BOOL		mIsFocusRoot;
 	BOOL		mUseBoundingRect; // hit test against bounding rectangle that includes all child elements
 
-	LLRootHandle<LLView> mHandle;
 	BOOL		mLastVisible;
 
 	S32			mNextInsertionOrdinal;
diff --git a/indra/newview/llfloatercamera.cpp b/indra/newview/llfloatercamera.cpp
index b33dea4890fabbe6bfb219b15781f341539c3944..8c2dd73bd9470b5a41c4bc84475fe0d011e1f4e1 100644
--- a/indra/newview/llfloatercamera.cpp
+++ b/indra/newview/llfloatercamera.cpp
@@ -346,7 +346,7 @@ LLFloaterCamera::LLFloaterCamera(const LLSD& val)
 	mCurrMode(CAMERA_CTRL_MODE_PAN),
 	mPrevMode(CAMERA_CTRL_MODE_PAN)
 {
-	LLHints::registerHintTarget("view_popup", LLView::getHandle());
+	LLHints::registerHintTarget("view_popup", getHandle());
 	mCommitCallbackRegistrar.add("CameraPresets.ChangeView", boost::bind(&LLFloaterCamera::onClickCameraItem, _2));
 }
 
diff --git a/indra/newview/llnavigationbar.cpp b/indra/newview/llnavigationbar.cpp
index fc264db5af96ee9350e9f2e26af14afab69f29a6..12428681bd021f15b98255b2ba9493f21669d978 100644
--- a/indra/newview/llnavigationbar.cpp
+++ b/indra/newview/llnavigationbar.cpp
@@ -318,7 +318,7 @@ BOOL LLNavigationBar::postBuild()
 	LLTeleportHistory::getInstance()->setHistoryChangedCallback(
 			boost::bind(&LLNavigationBar::onTeleportHistoryChanged, this));
 
-	LLHints::registerHintTarget("nav_bar", LLView::getHandle());
+	LLHints::registerHintTarget("nav_bar", getHandle());
 
 	return TRUE;
 }
diff --git a/indra/newview/lltoast.h b/indra/newview/lltoast.h
index 242f786bf2e9dfbbd34d49111e7e93304adbaac4..380c2c391ab8ae8ff6401a18c92080521313f30d 100644
--- a/indra/newview/lltoast.h
+++ b/indra/newview/lltoast.h
@@ -196,7 +196,7 @@ class LLToast : public LLModalDialog
 
 	virtual S32	notifyParent(const LLSD& info);
 
-	LLHandle<LLToast> getHandle() { mHandle.bind(this); return mHandle; }
+	LLHandle<LLToast> getHandle() const { return getDerivedHandle<LLToast>(); }
 
 protected:
 	void updateTransparency();
@@ -215,7 +215,7 @@ class LLToast : public LLModalDialog
 	LLUUID				mSessionID;
 	LLNotificationPtr	mNotification;
 
-	LLRootHandle<LLToast>	mHandle;
+	//LLRootHandle<LLToast>	mHandle;
 		
 	LLPanel* mWrapperPanel;