Index: src/common/TShellExtMenuConfig.cpp
===================================================================
diff -u -N -r3921d82d9605d98b2281f3f42d9f9c8385b89a3e -r3189e42eda9bd42d44d59b85b80bf4c7010e0b5a
--- src/common/TShellExtMenuConfig.cpp	(.../TShellExtMenuConfig.cpp)	(revision 3921d82d9605d98b2281f3f42d9f9c8385b89a3e)
+++ src/common/TShellExtMenuConfig.cpp	(.../TShellExtMenuConfig.cpp)	(revision 3189e42eda9bd42d44d59b85b80bf4c7010e0b5a)
@@ -27,6 +27,7 @@
 #include <boost/assert.hpp>
 #include <boost/lexical_cast.hpp>
 #include "../libchengine/TConfigArray.h"
+#include <map>
 
 using namespace chcore;
 using namespace chengine;
@@ -267,7 +268,7 @@
 
 void TShellMenuItem::SetLocalName(const string::TString& strLocalName)
 {
-	m_strLocalName = strLocalName;
+	m_strLocalName = strLocalName + m_strWorkaroundSuffix.c_str();
 }
 
 void TShellMenuItem::InitSeparatorItem()
@@ -302,6 +303,44 @@
 	m_strItemTip = wstrItemTip;
 }
 
+// function tries to make item names unique by setting a text suffix composed of spaces that will be used
+// to display shell context menu;
+// This workaround is required due to specific way of handling menus for more than 16 items (files/folders)
+// selected in explorer - when invoking specific menu item, explorer forces shell extension to re-add all
+// menu items to a menu, and then invokes the first one with the name matching the one clicked by user.
+// Final effect was that a wrong menu item was selected when there were duplicate names in menu.
+void TShellMenuItem::CalculateWorkaroundSuffixes()
+{
+	std::map<std::wstring, std::wstring> mapNames;
+	std::list<TShellMenuItemPtr> listToProcess;
+	listToProcess.insert(listToProcess.end(), m_vChildItems.begin(), m_vChildItems.end());
+
+	while(!listToProcess.empty())
+	{
+		TShellMenuItemPtr spItem = listToProcess.front();
+		listToProcess.pop_front();
+
+		if(spItem->GetItemType() == eStandardItem)
+		{
+			auto iterFnd = mapNames.find(spItem->GetName().c_str());
+			if(iterFnd == mapNames.end())
+			{
+				mapNames.emplace(spItem->GetName().c_str(), L"");
+				spItem->SetWorkaroundSuffix(L"");
+			}
+			else
+			{
+				iterFnd->second += L" ";
+				spItem->SetWorkaroundSuffix(iterFnd->second);
+			}
+		}
+		else if(spItem->GetItemType() == eGroupItem)
+		{
+			listToProcess.insert(listToProcess.end(), spItem->m_vChildItems.begin(), spItem->m_vChildItems.end());
+		}
+	}
+}
+
 bool TShellMenuItem::SpecifiesDestinationPath() const
 {
 	return !IsGroupItem() && (m_tDestinationPath.GetDstPathSource() == TDestinationPathInfo::eDstType_Specified);
@@ -529,8 +568,11 @@
 
 	if(!m_spDragAndDropRoot->ReadFromConfig(rConfig, Concat(strBuffer, pszNodeName, _T("DragAndDropRootItem"))))
 		return false;
+	m_spDragAndDropRoot->CalculateWorkaroundSuffixes();
+
 	if(!m_spNormalRoot->ReadFromConfig(rConfig, Concat(strBuffer, pszNodeName, _T("NormalRootItem"))))
 		return false;
+	m_spNormalRoot->CalculateWorkaroundSuffixes();
 
 	return true;
 }