diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp
index 986f3362b7726fcef27e0c81ecb5dcd981f8ace5..5c8c30e6ac8c2d11182f99f080ffc67b3c1c9162 100644
--- a/indra/llui/llmenugl.cpp
+++ b/indra/llui/llmenugl.cpp
@@ -212,6 +212,12 @@ LLSD LLMenuItemGL::getValue() const
 	return getLabel();
 }
 
+//virtual
+bool LLMenuItemGL::hasAccelerator(const KEY &key, const MASK &mask) const
+{
+	return (mAcceleratorKey == key) && (mAcceleratorMask == mask);
+}
+
 //virtual
 BOOL LLMenuItemGL::handleAcceleratorKey(KEY key, MASK mask)
 {
@@ -1017,6 +1023,11 @@ BOOL LLMenuItemBranchGL::handleMouseUp(S32 x, S32 y, MASK mask)
 	return TRUE;
 }
 
+bool LLMenuItemBranchGL::hasAccelerator(const KEY &key, const MASK &mask) const
+{
+	return getBranch() && getBranch()->hasAccelerator(key, mask);
+}
+
 BOOL LLMenuItemBranchGL::handleAcceleratorKey(KEY key, MASK mask)
 {
 	return getBranch() && getBranch()->handleAcceleratorKey(key, mask);
@@ -3001,6 +3012,27 @@ void LLMenuGL::updateParent(LLView* parentp)
 	}
 }
 
+bool LLMenuGL::hasAccelerator(const KEY &key, const MASK &mask) const
+{
+	if (key == KEY_NONE)
+	{
+		return false;
+	}
+	// Note: checking this way because mAccelerators seems to be broken
+	// mAccelerators probably needs to be cleaned up or fixed
+	// It was used for dupplicate accelerator avoidance.
+	item_list_t::const_iterator item_iter;
+	for (item_iter = mItems.begin(); item_iter != mItems.end(); ++item_iter)
+	{
+		LLMenuItemGL* itemp = *item_iter;
+		if (itemp->hasAccelerator(key, mask))
+		{
+			return true;
+		}
+	}
+	return false;
+}
+
 BOOL LLMenuGL::handleAcceleratorKey(KEY key, MASK mask)
 {
 	// don't handle if not enabled
@@ -3514,27 +3546,6 @@ S32 LLMenuBarGL::getRightmostMenuEdge()
 	return (*item_iter)->getRect().mRight;
 }
 
-bool LLMenuBarGL::hasAccelerator(const KEY &key, const MASK &mask) const
-{
-    if (key == KEY_NONE)
-    {
-        return false;
-    }
-
-    LLMenuKeyboardBinding *accelerator = NULL;
-    std::list<LLMenuKeyboardBinding*>::const_iterator list_it;
-    for (list_it = mAccelerators.begin(); list_it != mAccelerators.end(); ++list_it)
-    {
-        accelerator = *list_it;
-        if ((accelerator->mKey == key) && (accelerator->mMask == (mask & MASK_NORMALKEYS)))
-        {
-            return true;
-        }
-    }
-
-    return false;
-}
-
 // add a vertical separator to this menu
 BOOL LLMenuBarGL::addSeparator()
 {
diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h
index 06538648923f65c2105f445376ec638c48c72877..f3844af507439bf6f699e310c6050e86f3f2a341 100644
--- a/indra/llui/llmenugl.h
+++ b/indra/llui/llmenugl.h
@@ -98,6 +98,7 @@ class LLMenuItemGL: public LLUICtrl, public ll::ui::SearchableControl
 	/*virtual*/ void setValue(const LLSD& value);
 	/*virtual*/ LLSD getValue() const;
 
+	virtual bool hasAccelerator(const KEY &key, const MASK &mask) const;
 	virtual BOOL handleAcceleratorKey(KEY key, MASK mask);
 
 	LLColor4 getHighlightBgColor() { return mHighlightBackground.get(); }
@@ -443,7 +444,8 @@ class LLMenuGL
 	/*virtual*/ bool addChild(LLView* view, S32 tab_group = 0);
 	/*virtual*/ void removeChild( LLView* ctrl);
 	/*virtual*/ BOOL postBuild();
-
+	
+	virtual bool hasAccelerator(const KEY &key, const MASK &mask) const;
 	virtual BOOL handleAcceleratorKey(KEY key, MASK mask);
 
 	LLMenuGL* findChildMenuByName(const std::string& name, BOOL recurse) const;
@@ -632,6 +634,7 @@ class LLMenuItemBranchGL : public LLMenuItemGL
 	
 	virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask);
 
+	virtual bool hasAccelerator(const KEY &key, const MASK &mask) const;
 	virtual BOOL handleAcceleratorKey(KEY key, MASK mask);
 
 	// check if we've used these accelerators already
@@ -792,8 +795,6 @@ class LLMenuBarGL : public LLMenuGL
 
 	void resetMenuTrigger() { mAltKeyTrigger = FALSE; }
 
-	bool hasAccelerator(const KEY &key, const MASK &mask) const;
-
 private:
 	// add a menu - this will create a drop down menu.
 	virtual BOOL appendMenu( LLMenuGL* menu );
diff --git a/indra/newview/llkeyconflict.cpp b/indra/newview/llkeyconflict.cpp
index 71ba0d37b3611b1ee9f43bea7b49c11b89c027a6..fcf1a7953c00d8f6954eed799e921229d16bf878 100644
--- a/indra/newview/llkeyconflict.cpp
+++ b/indra/newview/llkeyconflict.cpp
@@ -174,17 +174,23 @@ bool LLKeyConflictHandler::canAssignControl(const std::string &control_name)
 // static
 bool LLKeyConflictHandler::isReservedByMenu(const KEY &key, const MASK &mask)
 {
-    return gMenuBarView->hasAccelerator(key, mask) || gLoginMenuBarView->hasAccelerator(key, mask);
+    if (key == KEY_NONE)
+    {
+        return false;
+    }
+    return (gMenuBarView && gMenuBarView->hasAccelerator(key, mask))
+           || (gLoginMenuBarView && gLoginMenuBarView->hasAccelerator(key, mask));
 }
 
 // static
 bool LLKeyConflictHandler::isReservedByMenu(const LLKeyData &data)
 {
-    if (data.mMouse != CLICK_NONE)
+    if (data.mMouse != CLICK_NONE || data.mKey == KEY_NONE)
     {
         return false;
     }
-    return gMenuBarView->hasAccelerator(data.mKey, data.mMask) || gLoginMenuBarView->hasAccelerator(data.mKey, data.mMask);
+    return (gMenuBarView && gMenuBarView->hasAccelerator(data.mKey, data.mMask))
+           || (gLoginMenuBarView && gLoginMenuBarView->hasAccelerator(data.mKey, data.mMask));
 }
 
 bool LLKeyConflictHandler::registerControl(const std::string &control_name, U32 index, EMouseClickType mouse, KEY key, MASK mask, bool ignore_mask)
diff --git a/indra/newview/llsetkeybinddialog.cpp b/indra/newview/llsetkeybinddialog.cpp
index 320f1f297df8a53cad387593b64056b281061433..806c70aa03784a3a65f01aa703b19d58f752f395 100644
--- a/indra/newview/llsetkeybinddialog.cpp
+++ b/indra/newview/llsetkeybinddialog.cpp
@@ -28,11 +28,10 @@
 
 #include "llsetkeybinddialog.h"
 
-//#include "llkeyboard.h"
-
 #include "llbutton.h"
 #include "llcheckboxctrl.h"
 #include "lleventtimer.h"
+#include "llfloaterreg.h"
 #include "llfocusmgr.h"
 #include "llkeyconflict.h"
 
@@ -65,6 +64,8 @@ class LLSetKeyBindDialog::Updater : public LLEventTimer
     callback_t mCallback;
 };
 
+bool LLSetKeyBindDialog::sRecordKeys = false;
+
 LLSetKeyBindDialog::LLSetKeyBindDialog(const LLSD& key)
     : LLModalDialog(key),
     pParent(NULL),
@@ -93,9 +94,17 @@ BOOL LLSetKeyBindDialog::postBuild()
     return TRUE;
 }
 
+//virtual
+void LLSetKeyBindDialog::onOpen(const LLSD& data)
+{
+     sRecordKeys = true;
+     LLModalDialog::onOpen(data);
+}
+
 //virtual
 void LLSetKeyBindDialog::onClose(bool app_quiting)
 {
+    sRecordKeys = false;
     if (pParent)
     {
         pParent->onCancelKeyBind();
@@ -145,20 +154,41 @@ void LLSetKeyBindDialog::setParent(LLKeyBindResponderInterface* parent, LLView*
     pCheckBox->setValue(false);
 }
 
-BOOL LLSetKeyBindDialog::handleKeyHere(KEY key, MASK mask)
+// static
+bool LLSetKeyBindDialog::recordKey(KEY key, MASK mask)
+{
+    if (sRecordKeys)
+    {
+        LLSetKeyBindDialog* dialog = LLFloaterReg::getTypedInstance<LLSetKeyBindDialog>("keybind_dialog", LLSD());
+        if (dialog && dialog->getVisible())
+        {
+            return dialog->recordAndHandleKey(key, mask);
+        }
+        else
+        {
+            LL_WARNS() << "Key recording was set despite no open dialog" << LL_ENDL;
+            sRecordKeys = false;
+        }
+    }
+    return false;
+}
+
+bool LLSetKeyBindDialog::recordAndHandleKey(KEY key, MASK mask)
 {
     if ((key == 'Q' && mask == MASK_CONTROL)
         || key == KEY_ESCAPE)
     {
+        sRecordKeys = false;
         closeFloater();
-        return TRUE;
+        return true;
     }
 
     if (key == KEY_DELETE)
     {
         setKeyBind(CLICK_NONE, KEY_NONE, MASK_NONE, false);
+        sRecordKeys = false;
         closeFloater();
-        return FALSE;
+        return false;
     }
 
     // forbidden keys
@@ -166,36 +196,37 @@ BOOL LLSetKeyBindDialog::handleKeyHere(KEY key, MASK mask)
         || key == KEY_RETURN
         || key == KEY_BACKSPACE)
     {
-        return FALSE;
+        return false;
     }
 
     if ((mKeyFilterMask & ALLOW_MASKS) == 0
         && (key == KEY_CONTROL || key == KEY_SHIFT || key == KEY_ALT))
     {
         // mask by themself are not allowed
-        return FALSE;
+        return false;
     }
     else if ((mKeyFilterMask & ALLOW_KEYS) == 0)
     {
         // basic keys not allowed
-        return FALSE;
+        return false;
     }
     else if ((mKeyFilterMask & ALLOW_MASK_KEYS) == 0 && mask != 0)
     {
         // masked keys not allowed
-        return FALSE;
+        return false;
     }
 
     if (LLKeyConflictHandler::isReservedByMenu(key, mask))
     {
         pDesription->setText(getString("reserved_by_menu"));
         pDesription->setTextArg("[KEYSTR]", LLKeyboard::stringFromAccelerator(mask,key));
-        return TRUE;
+        return true;
     }
 
     setKeyBind(CLICK_NONE, key, mask, pCheckBox->getValue().asBoolean());
+    sRecordKeys = false;
     closeFloater();
-    return TRUE;
+    return true;
 }
 
 BOOL LLSetKeyBindDialog::handleAnyMouseClick(S32 x, S32 y, MASK mask, EMouseClickType clicktype, BOOL down)
diff --git a/indra/newview/llsetkeybinddialog.h b/indra/newview/llsetkeybinddialog.h
index 8faa2cc363d452f4544b4975c5c8a697f8791350..16a2d768e4a797617346eafa3849ae626e9121f6 100644
--- a/indra/newview/llsetkeybinddialog.h
+++ b/indra/newview/llsetkeybinddialog.h
@@ -62,12 +62,16 @@ class LLSetKeyBindDialog : public LLModalDialog, public LLDrawFrustum
     ~LLSetKeyBindDialog();
 
     /*virtual*/ BOOL postBuild();
+    /*virtual*/ void onOpen(const LLSD& data);
     /*virtual*/ void onClose(bool app_quiting);
     /*virtual*/ void draw();
 
     void setParent(LLKeyBindResponderInterface* parent, LLView* frustum_origin, U32 key_mask = DEFAULT_KEY_FILTER);
 
-    BOOL handleKeyHere(KEY key, MASK mask);
+    // Wrapper around recordAndHandleKey
+    // It does not record, it handles, but handleKey function is already in use
+    static bool recordKey(KEY key, MASK mask);
+
     BOOL handleAnyMouseClick(S32 x, S32 y, MASK mask, EMouseClickType clicktype, BOOL down);
     static void onCancel(void* user_data);
     static void onBlank(void* user_data);
@@ -77,6 +81,7 @@ class LLSetKeyBindDialog : public LLModalDialog, public LLDrawFrustum
     class Updater;
 
 private:
+    bool recordAndHandleKey(KEY key, MASK mask);
     void setKeyBind(EMouseClickType click, KEY key, MASK mask, bool ignore);
     LLKeyBindResponderInterface *pParent;
     LLCheckBoxCtrl *pCheckBox;
@@ -84,6 +89,8 @@ class LLSetKeyBindDialog : public LLModalDialog, public LLDrawFrustum
 
     U32 mKeyFilterMask;
     Updater *pUpdater;
+
+    static bool sRecordKeys; // for convinience and not to check instance each time
 };
 
 
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 3c2ec369ecdb68889edf2bd9222d2bfd80eae838..c2a89819a6a9944e4f43ef5c2413b210db1ab989 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -45,6 +45,7 @@
 #include "llmeshrepository.h"
 #include "llnotificationhandler.h"
 #include "llpanellogin.h"
+#include "llsetkeybinddialog.h"
 #include "llviewerinput.h"
 #include "llviewermenu.h"
 
@@ -2716,6 +2717,14 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
 	// hide tooltips on keypress
 	LLToolTipMgr::instance().blockToolTips();
 
+    // let menus handle navigation keys for navigation
+    if (LLSetKeyBindDialog::recordKey(key, mask))
+    {
+        LL_DEBUGS() << "Key handled by LLSetKeyBindDialog" << LL_ENDL;
+        LLViewerEventRecorder::instance().logKeyEvent(key,mask);
+        return TRUE;
+    }
+
     LLFocusableElement* keyboard_focus = gFocusMgr.getKeyboardFocus();
 
     if (keyboard_focus