You are viewing a plain text version of this content. The canonical link for it is here.
Posted to npanday-commits@incubator.apache.org by lc...@apache.org on 2011/11/07 20:38:24 UTC

svn commit: r1198920 - in /incubator/npanday/trunk/dotnet/assemblies/NPanday.VisualStudio.Addin/src/main/csharp: ./ NPanday/VisualStudio/Addin/ NPanday/VisualStudio/Addin/Commands/ NPanday/VisualStudio/Addin/Helper/

Author: lcorneliussen
Date: Mon Nov  7 20:38:24 2011
New Revision: 1198920

URL: http://svn.apache.org/viewvc?rev=1198920&view=rev
Log:
Began refactoring of Connect; Command-Pattern and non-locale-dependent finder for commands. Will continue tomorrow.

Added:
    incubator/npanday/trunk/dotnet/assemblies/NPanday.VisualStudio.Addin/src/main/csharp/NPanday/VisualStudio/Addin/Commands/
    incubator/npanday/trunk/dotnet/assemblies/NPanday.VisualStudio.Addin/src/main/csharp/NPanday/VisualStudio/Addin/Commands/AddArtifactsCommand.cs
    incubator/npanday/trunk/dotnet/assemblies/NPanday.VisualStudio.Addin/src/main/csharp/NPanday/VisualStudio/Addin/Commands/ButtonCommand.cs
    incubator/npanday/trunk/dotnet/assemblies/NPanday.VisualStudio.Addin/src/main/csharp/NPanday/VisualStudio/Addin/Commands/ButtonCommandRegistry.cs
    incubator/npanday/trunk/dotnet/assemblies/NPanday.VisualStudio.Addin/src/main/csharp/NPanday/VisualStudio/Addin/Commands/IButtonCommandContext.cs
    incubator/npanday/trunk/dotnet/assemblies/NPanday.VisualStudio.Addin/src/main/csharp/NPanday/VisualStudio/Addin/Commands/VSCommandCaptions.cs
    incubator/npanday/trunk/dotnet/assemblies/NPanday.VisualStudio.Addin/src/main/csharp/NPanday/VisualStudio/Addin/Helper/
    incubator/npanday/trunk/dotnet/assemblies/NPanday.VisualStudio.Addin/src/main/csharp/NPanday/VisualStudio/Addin/Helper/BuiltinCommandFinder.cs
Modified:
    incubator/npanday/trunk/dotnet/assemblies/NPanday.VisualStudio.Addin/src/main/csharp/NPanday.VisualStudio.Addin.csproj
    incubator/npanday/trunk/dotnet/assemblies/NPanday.VisualStudio.Addin/src/main/csharp/NPanday/VisualStudio/Addin/Connect.cs

Modified: incubator/npanday/trunk/dotnet/assemblies/NPanday.VisualStudio.Addin/src/main/csharp/NPanday.VisualStudio.Addin.csproj
URL: http://svn.apache.org/viewvc/incubator/npanday/trunk/dotnet/assemblies/NPanday.VisualStudio.Addin/src/main/csharp/NPanday.VisualStudio.Addin.csproj?rev=1198920&r1=1198919&r2=1198920&view=diff
==============================================================================
--- incubator/npanday/trunk/dotnet/assemblies/NPanday.VisualStudio.Addin/src/main/csharp/NPanday.VisualStudio.Addin.csproj (original)
+++ incubator/npanday/trunk/dotnet/assemblies/NPanday.VisualStudio.Addin/src/main/csharp/NPanday.VisualStudio.Addin.csproj Mon Nov  7 20:38:24 2011
@@ -73,6 +73,11 @@ under the License.
     <Compile Include="NPanday\VisualStudio\Addin\ChangeMavenSettingsXmlForm.Designer.cs">
       <DependentUpon>ChangeMavenSettingsXmlForm.cs</DependentUpon>
     </Compile>
+    <Compile Include="NPanday\VisualStudio\Addin\Commands\ButtonCommandRegistry.cs" />
+    <Compile Include="NPanday\VisualStudio\Addin\Commands\AddArtifactsCommand.cs" />
+    <Compile Include="NPanday\VisualStudio\Addin\Commands\ButtonCommand.cs" />
+    <Compile Include="NPanday\VisualStudio\Addin\Commands\IButtonCommandContext.cs" />
+    <Compile Include="NPanday\VisualStudio\Addin\Commands\VSCommandCaptions.cs" />
     <Compile Include="NPanday\VisualStudio\Addin\ConfigureMavenRepositoryForm.cs">
       <SubType>Form</SubType>
     </Compile>
@@ -81,6 +86,7 @@ under the License.
     </Compile>
     <Compile Include="NPanday\VisualStudio\Addin\Connect.cs" />
     <Compile Include="NPanday\VisualStudio\Addin\FolderWatcher.cs" />
+    <Compile Include="NPanday\VisualStudio\Addin\Helper\BuiltinCommandFinder.cs" />
     <Compile Include="NPanday\VisualStudio\Addin\LoginForm.cs">
       <SubType>Form</SubType>
     </Compile>

Added: incubator/npanday/trunk/dotnet/assemblies/NPanday.VisualStudio.Addin/src/main/csharp/NPanday/VisualStudio/Addin/Commands/AddArtifactsCommand.cs
URL: http://svn.apache.org/viewvc/incubator/npanday/trunk/dotnet/assemblies/NPanday.VisualStudio.Addin/src/main/csharp/NPanday/VisualStudio/Addin/Commands/AddArtifactsCommand.cs?rev=1198920&view=auto
==============================================================================
--- incubator/npanday/trunk/dotnet/assemblies/NPanday.VisualStudio.Addin/src/main/csharp/NPanday/VisualStudio/Addin/Commands/AddArtifactsCommand.cs (added)
+++ incubator/npanday/trunk/dotnet/assemblies/NPanday.VisualStudio.Addin/src/main/csharp/NPanday/VisualStudio/Addin/Commands/AddArtifactsCommand.cs Mon Nov  7 20:38:24 2011
@@ -0,0 +1,53 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using EnvDTE;
+using System.IO;
+using System.Windows.Forms;
+
+namespace NPanday.VisualStudio.Addin.Commands
+{
+    public class AddArtifactsCommand : ButtonCommand
+    {
+        public override string Caption
+        {
+            get
+            {
+                return Messages.MSG_C_ADD_MAVEN_ARTIFACT;
+            }
+        }
+
+        public override void Execute(IButtonCommandContext context)
+        {
+            //First selected project
+            foreach (Project project in (Array)Application.ActiveSolutionProjects)
+            {
+                FileInfo currentPom = context.CurrentSelectedProjectPom;
+                if (currentPom == null || Path.GetDirectoryName(currentPom.FullName) != Path.GetDirectoryName(project.FullName))
+                {
+                    DialogResult result = MessageBox.Show("Pom file not found, do you want to import the projects first before adding Maven Artifact?", "Add Maven Artifact", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
+                    if (result == DialogResult.Cancel)
+                        return;
+                    else if (result == DialogResult.OK)
+                    {
+                        context.ExecuteCommand(VSCommandCaptions.Standard_SaveAll);
+
+                        NPandayImportProjectForm frm = new NPandayImportProjectForm(Application, context.Logger);
+                        frm.SetOutputWindowPane(context.OutputWindowPane);
+                        frm.ShowDialog();
+                        currentPom = context.CurrentSelectedProjectPom;
+
+                        // if import failed
+                        if (currentPom == null || Path.GetDirectoryName(currentPom.FullName) != Path.GetDirectoryName(project.FullName))
+                        {
+                            return;
+                        }
+                    }
+                }
+                AddArtifactsForm form = new AddArtifactsForm(project, context.ArtifactContext, context.Logger, currentPom);
+                form.Show();
+                break;
+            }
+        }
+    }
+}

Added: incubator/npanday/trunk/dotnet/assemblies/NPanday.VisualStudio.Addin/src/main/csharp/NPanday/VisualStudio/Addin/Commands/ButtonCommand.cs
URL: http://svn.apache.org/viewvc/incubator/npanday/trunk/dotnet/assemblies/NPanday.VisualStudio.Addin/src/main/csharp/NPanday/VisualStudio/Addin/Commands/ButtonCommand.cs?rev=1198920&view=auto
==============================================================================
--- incubator/npanday/trunk/dotnet/assemblies/NPanday.VisualStudio.Addin/src/main/csharp/NPanday/VisualStudio/Addin/Commands/ButtonCommand.cs (added)
+++ incubator/npanday/trunk/dotnet/assemblies/NPanday.VisualStudio.Addin/src/main/csharp/NPanday/VisualStudio/Addin/Commands/ButtonCommand.cs Mon Nov  7 20:38:24 2011
@@ -0,0 +1,32 @@
+using Microsoft.VisualStudio.CommandBars;
+using EnvDTE80;
+
+namespace NPanday.VisualStudio.Addin.Commands
+{
+    /// <summary>
+    /// TODO: For now we only have buttons and when migrating to VSIX this 
+    /// has to be changed dramatically anyway.
+    /// </summary>
+    public abstract class ButtonCommand
+    {
+        private DTE2 _application;
+        public DTE2 Application
+        {
+            get
+            {
+                return _application;
+            }
+            internal set
+            {
+                _application = value;
+            }
+        }
+
+        public abstract string Caption
+        { 
+            get;
+        }
+
+        public abstract void Execute(IButtonCommandContext context);
+    }
+}

Added: incubator/npanday/trunk/dotnet/assemblies/NPanday.VisualStudio.Addin/src/main/csharp/NPanday/VisualStudio/Addin/Commands/ButtonCommandRegistry.cs
URL: http://svn.apache.org/viewvc/incubator/npanday/trunk/dotnet/assemblies/NPanday.VisualStudio.Addin/src/main/csharp/NPanday/VisualStudio/Addin/Commands/ButtonCommandRegistry.cs?rev=1198920&view=auto
==============================================================================
--- incubator/npanday/trunk/dotnet/assemblies/NPanday.VisualStudio.Addin/src/main/csharp/NPanday/VisualStudio/Addin/Commands/ButtonCommandRegistry.cs (added)
+++ incubator/npanday/trunk/dotnet/assemblies/NPanday.VisualStudio.Addin/src/main/csharp/NPanday/VisualStudio/Addin/Commands/ButtonCommandRegistry.cs Mon Nov  7 20:38:24 2011
@@ -0,0 +1,70 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Microsoft.VisualStudio.CommandBars;
+using EnvDTE80;
+
+namespace NPanday.VisualStudio.Addin.Commands
+{
+    public delegate IButtonCommandContext BuildCommandContext();
+
+    /// <summary>
+    /// Manages and registers NPanday commands.
+    /// </summary>
+    public class ButtonCommandRegistry
+    {
+        List<CommandBarControl> _keepReferences = new List<CommandBarControl>();
+
+        Dictionary<Type, ButtonCommand> _commands = new Dictionary<Type, ButtonCommand>();
+
+        private readonly DTE2 _application;
+        private BuildCommandContext _buildContext;
+
+        public ButtonCommandRegistry(DTE2 application, BuildCommandContext buildContext)
+        {
+            _application = application;
+            _buildContext = buildContext;
+        }
+
+        public TCommand AddBefore<TCommand>(CommandBarControl barControl)
+            where TCommand : ButtonCommand, new()
+        {
+            return Add<TCommand>(barControl.Parent, barControl.Index);
+        }
+
+        public TCommand Add<TCommand>(CommandBar bar, int atIndex)
+            where TCommand : ButtonCommand, new()
+        {
+            TCommand command = getOrCreate<TCommand>();
+
+            CommandBarButton ctl = (CommandBarButton)
+                  bar.Controls.Add(MsoControlType.msoControlButton,
+                                   System.Type.Missing, System.Type.Missing, atIndex, true);
+            ctl.Click += delegate(CommandBarButton btn, ref bool Cancel)
+                {
+                    command.Execute(_buildContext()); 
+                };
+            ctl.Caption = command.Caption;
+            ctl.Visible = true;
+
+            _keepReferences.Add(ctl);
+
+            return command;
+        }
+
+        private TCommand getOrCreate<TCommand>()
+            where TCommand : ButtonCommand, new()
+        {
+            ButtonCommand command;
+            if (_commands.TryGetValue(typeof(TCommand), out command))
+            {
+                return (TCommand)command;
+            }
+
+            command = new TCommand();
+            command.Application = _application;
+            _commands[typeof (TCommand)] = command;
+            return (TCommand)command;
+        }
+    }
+}

Added: incubator/npanday/trunk/dotnet/assemblies/NPanday.VisualStudio.Addin/src/main/csharp/NPanday/VisualStudio/Addin/Commands/IButtonCommandContext.cs
URL: http://svn.apache.org/viewvc/incubator/npanday/trunk/dotnet/assemblies/NPanday.VisualStudio.Addin/src/main/csharp/NPanday/VisualStudio/Addin/Commands/IButtonCommandContext.cs?rev=1198920&view=auto
==============================================================================
--- incubator/npanday/trunk/dotnet/assemblies/NPanday.VisualStudio.Addin/src/main/csharp/NPanday/VisualStudio/Addin/Commands/IButtonCommandContext.cs (added)
+++ incubator/npanday/trunk/dotnet/assemblies/NPanday.VisualStudio.Addin/src/main/csharp/NPanday/VisualStudio/Addin/Commands/IButtonCommandContext.cs Mon Nov  7 20:38:24 2011
@@ -0,0 +1,17 @@
+using System.IO;
+using EnvDTE;
+using NPanday.Artifact;
+using NPanday.Logging;
+
+namespace NPanday.VisualStudio.Addin.Commands
+{
+    public interface IButtonCommandContext
+    {
+        FileInfo CurrentSelectedProjectPom { get; }
+        ArtifactContext ArtifactContext { get; }
+        Logger Logger { get; }
+        OutputWindowPane OutputWindowPane { get; }
+
+        bool ExecuteCommand(string barAndCaption);
+    }
+}

Added: incubator/npanday/trunk/dotnet/assemblies/NPanday.VisualStudio.Addin/src/main/csharp/NPanday/VisualStudio/Addin/Commands/VSCommandCaptions.cs
URL: http://svn.apache.org/viewvc/incubator/npanday/trunk/dotnet/assemblies/NPanday.VisualStudio.Addin/src/main/csharp/NPanday/VisualStudio/Addin/Commands/VSCommandCaptions.cs?rev=1198920&view=auto
==============================================================================
--- incubator/npanday/trunk/dotnet/assemblies/NPanday.VisualStudio.Addin/src/main/csharp/NPanday/VisualStudio/Addin/Commands/VSCommandCaptions.cs (added)
+++ incubator/npanday/trunk/dotnet/assemblies/NPanday.VisualStudio.Addin/src/main/csharp/NPanday/VisualStudio/Addin/Commands/VSCommandCaptions.cs Mon Nov  7 20:38:24 2011
@@ -0,0 +1,13 @@
+namespace NPanday.VisualStudio.Addin.Commands
+{
+    public class VSCommandCaptions
+    {
+        public const string AddReference = "Add &Reference...";
+        public const string Clean = "Clea&n";
+        public const string ConfigurationManager = "C&onfiguration Manager...";
+        public const string PublishSelection = "Publis&h Selection";
+        public const string PublishWebSite = "Publis&h Web Site";
+        public const string Standard_SaveAll = "Standard->Save All";
+        public const string Tools = "Tools";
+    }
+}
\ No newline at end of file

Modified: incubator/npanday/trunk/dotnet/assemblies/NPanday.VisualStudio.Addin/src/main/csharp/NPanday/VisualStudio/Addin/Connect.cs
URL: http://svn.apache.org/viewvc/incubator/npanday/trunk/dotnet/assemblies/NPanday.VisualStudio.Addin/src/main/csharp/NPanday/VisualStudio/Addin/Connect.cs?rev=1198920&r1=1198919&r2=1198920&view=diff
==============================================================================
--- incubator/npanday/trunk/dotnet/assemblies/NPanday.VisualStudio.Addin/src/main/csharp/NPanday/VisualStudio/Addin/Connect.cs (original)
+++ incubator/npanday/trunk/dotnet/assemblies/NPanday.VisualStudio.Addin/src/main/csharp/NPanday/VisualStudio/Addin/Connect.cs Mon Nov  7 20:38:24 2011
@@ -41,7 +41,6 @@ using System.Xml.Serialization;
 using System.Xml.XPath;
 
 using Microsoft.VisualStudio.CommandBars;
-
 using VSLangProj;
 
 using NPanday.Artifact;
@@ -56,6 +55,8 @@ using NPanday.Utils;
 using System.Runtime.CompilerServices;
 using VSLangProj80;
 using System.Text;
+using NPanday.VisualStudio.Addin.Commands;
+using NPanday.VisualStudio.Addin.Helper;
 
 
 #endregion
@@ -74,7 +75,11 @@ namespace NPanday.VisualStudio.Addin
     {
         public const string MSG_E_NOTIMPLEMENTED = "The method or operation is not implemented.";
         public const string MSG_L_NPANDAY_ALREADY_STARTED = "\nNPanday Addin Has Already Started.";
-        public const string MSG_L_NPANDAY_ADDIN_STARTED = "\n{0} Successfully Started.";
+        public const string MSG_L_NPANDAY_ADDIN_STARTED = "\nNPanday Addin {0} Successfully Started (in {1:0.00} seconds).";
+        public const string MSG_L_UNABLE_TO_REGISTER_ADD_ARTIFACT_MENU = "\nCould not register the menu for adding artifacts.";
+        public const string MSG_L_UNABLE_TO_REGISTER_STOP_BUILD_MENU = "\nCould not register the menu for stopping maven builds.";
+        public const string MSG_L_UNABLE_TO_REGISTER_NPANDAY_MENUS = "\nCould not register the default NPanday menus.";
+        public const string MSG_L_UNABLE_TO_REGISTER_ALL_PROJECTS_MENU = "\nCould not register the menu for global actions on all projects.";
         public const string MSG_E_NPANDAY_REMOVE_DEPENDENCY_ERROR = "NPanday Remove Dependency Error:";
         public const string MSG_Q_STOP_MAVEN_BUILD = "Do you want to stop the NPanday Build?";
         public const string MSG_EF_NOT_A_PROJECT_POM = "Not A Project Pom Error: {0} is not a project Pom, the pom is a parent pom type.";
@@ -201,7 +206,7 @@ namespace NPanday.VisualStudio.Addin
         //to hold eventhandler for projectItemsEvents
         void ProjectItemEvents_ItemAdded(ProjectItem projectItem)
         {
-            if (_applicationObject != null && projectItem!= null)
+            if (_applicationObject != null && projectItem != null)
             {
                 PomHelperUtility pomUtil = new PomHelperUtility(_applicationObject.Solution, CurrentSelectedProject);
 
@@ -215,7 +220,7 @@ namespace NPanday.VisualStudio.Addin
                     {
                         addWebReference(pomUtil, projectItem.Name, refType + "\\" + projectItem.Name + "\\" + reference, string.Empty);
                     }
-                }                
+                }
 
                 //determine which plugin the projectItem belongs to
 
@@ -283,16 +288,16 @@ namespace NPanday.VisualStudio.Addin
                     string fullPath = projectItem.get_FileNames(1);
                     string refType = Messages.MSG_D_WEB_REF;
 
-                    if ( fullPath.StartsWith(Path.GetDirectoryName(projectItem.ContainingProject.FullName) + "\\" + Messages.MSG_D_SERV_REF))
+                    if (fullPath.StartsWith(Path.GetDirectoryName(projectItem.ContainingProject.FullName) + "\\" + Messages.MSG_D_SERV_REF))
                     {
-                        refType = Messages.MSG_D_SERV_REF;                            
+                        refType = Messages.MSG_D_SERV_REF;
                     }
 
                     string reference = GetReference(projectItem, refType);
                     if (reference != null)
                     {
-                         string path = GetReferencePath(projectItem, refType);
-                         pomUtil.RemoveWebReference(path, projectItem.Name);
+                        string path = GetReferencePath(projectItem, refType);
+                        pomUtil.RemoveWebReference(path, projectItem.Name);
                     }
 
                     if (projectItem.Name.Contains(".cs") || projectItem.Name.Contains(".vb"))
@@ -326,8 +331,8 @@ namespace NPanday.VisualStudio.Addin
                 if (projectItem.Name.Contains(".resx"))
                 {
                     string resxName = projectItem.ContainingProject.Name + "." + projectItem.Name.Replace(".resx", "");
-                    string oldResxName = projectItem.ContainingProject.Name+"."+oldName.Replace(".resx","");
-                    pomUtil.RenameMavenResxPluginConfiguration("org.apache.npanday.plugins", "maven-resgen-plugin", "embeddedResources", "embeddedResource", oldName, oldResxName ,projectItem.Name,resxName);
+                    string oldResxName = projectItem.ContainingProject.Name + "." + oldName.Replace(".resx", "");
+                    pomUtil.RenameMavenResxPluginConfiguration("org.apache.npanday.plugins", "maven-resgen-plugin", "embeddedResources", "embeddedResource", oldName, oldResxName, projectItem.Name, resxName);
                 }
             }
 
@@ -347,16 +352,16 @@ namespace NPanday.VisualStudio.Addin
                 return projectUri.MakeRelativeUri(fullPathUri).ToString().Replace("%20", " ");
             }
             return projectItem.Name;
-        }    
+        }
 
         private static string GetReferencePath(ProjectItem projectItem, string refType)
         {
-            return Path.GetDirectoryName(projectItem.ContainingProject.FullName) + "\\" + refType + "\\" + projectItem.Name;            
+            return Path.GetDirectoryName(projectItem.ContainingProject.FullName) + "\\" + refType + "\\" + projectItem.Name;
         }
- 
+
         private static string GetReference(ProjectItem projectItem, string refType)
         {
-            string path = GetReferencePath(projectItem, refType); 
+            string path = GetReferencePath(projectItem, refType);
             if (Directory.Exists(path))
             {
                 string[] files = Directory.GetFiles(path, "*.wsdl");
@@ -365,7 +370,7 @@ namespace NPanday.VisualStudio.Addin
                 {
                     return Path.GetFileName(files[0]);
                 }
-            }          
+            }
 
             return null;
         }
@@ -374,7 +379,7 @@ namespace NPanday.VisualStudio.Addin
         {
             if (item.ContainingProject.Object is VSProject)
             {
-                ProjectItem webrefs = ((VSProject) item.ContainingProject.Object).WebReferencesFolder;
+                ProjectItem webrefs = ((VSProject)item.ContainingProject.Object).WebReferencesFolder;
                 if (webrefs != null && webrefs.ProjectItems != null)
                 {
                     foreach (ProjectItem webref in webrefs.ProjectItems)
@@ -398,6 +403,7 @@ namespace NPanday.VisualStudio.Addin
         private CommandBarControl saveAllControl;
 
 
+
         /// <summary>
         /// Implements the OnConnection method of the IDTExtensibility2 interface.
         /// Receives notification that the Add-in is being loaded.
@@ -408,15 +414,38 @@ namespace NPanday.VisualStudio.Addin
         /// <seealso class='IDTExtensibility2' />
         public void OnConnection(object application, ext_ConnectMode connectMode, object addInInst, ref Array custom)
         {
-
             _applicationObject = (DTE2)application;
             mavenRunner = new MavenRunner(_applicationObject);
             mavenRunner.RunnerStopped += new EventHandler(mavenRunner_RunnerStopped);
             _addInInstance = (AddIn)addInInst;
-            Command command = null;
+            EnvDTE.Command command = null;
             mavenConnected = true;
-            
-            //next two lines add a eventhandler to handle beforeclosing a solution
+
+            string paneName = "NPanday Build System";
+
+            outputWindowPane = getOrCreateOutputPane(paneName);
+
+            OutputWindowPaneHandler handler = new OutputWindowPaneHandler();
+            handler.SetOutputWindowPaneHandler(outputWindowPane);
+
+            logger = NPanday.Logging.Logger.GetLogger("UC");
+            logger.AddHandler(handler);
+
+            if (_addInInstance.Name.Contains("SNAPSHOT"))
+            {
+                OutputWindowPaneHandler debugHandler = new OutputWindowPaneHandler();
+                debugHandler.SetOutputWindowPaneHandler(getOrCreateOutputPane(paneName + " (DEBUG)"));
+                debugHandler.SetLevel(Level.DEBUG);
+                logger.AddHandler(debugHandler);
+            }
+
+            logger.Log(Level.DEBUG, "Intialized panes; connect mode is " + connectMode);
+
+            _buttonCommandRegistry = new ButtonCommandRegistry(_applicationObject, buildCommandContext);
+
+            _finder = new BuiltinCommandFinder(_applicationObject, logger);
+
+
             globalSolutionEvents = (EnvDTE.SolutionEvents)((Events2)_applicationObject.Events).SolutionEvents;
             globalSolutionEvents.BeforeClosing += new _dispSolutionEvents_BeforeClosingEventHandler(SolutionEvents_BeforeClosing);
             globalSolutionEvents.Opened += new _dispSolutionEvents_OpenedEventHandler(SolutionEvents_Opened);
@@ -432,25 +461,7 @@ namespace NPanday.VisualStudio.Addin
 
                 object[] contextGUIDS = new object[] { };
                 Commands2 commands = (Commands2)_applicationObject.Commands;
-                string toolsMenuName;
-
-                try
-                {
-                    //If you would like to move the command to a different menu, change the word "Tools" to the
-                    //  English version of the menu. This code will take the culture, append on the name of the menu
-                    //  then add the command to that menu. You can find a list of all the top-level menus in the file
-                    //  CommandBar.resx.
-                    ResourceManager resourceManager = new ResourceManager("IDEAddin.CommandBar", Assembly.GetExecutingAssembly());
-                    CultureInfo cultureInfo = new System.Globalization.CultureInfo(_applicationObject.LocaleID);
-                    string resourceName = String.Concat(cultureInfo.TwoLetterISOLanguageName, "Tools");
-                    toolsMenuName = resourceManager.GetString(resourceName);
-                }
-                catch
-                {
-                    //We tried to find a localized version of the word Tools, but one was not found.
-                    //  Default to the en-US word, which may work for the current culture.
-                    toolsMenuName = "Tools";
-                }
+                string toolsMenuName = VSCommandCaptions.Tools;
 
                 //Place the command on the tools menu.
                 //Find the MenuBar command bar, which is the top-level command bar holding all the main menu items:
@@ -460,9 +471,11 @@ namespace NPanday.VisualStudio.Addin
                 CommandBarControl toolsControl = menuBarCommandBar.Controls[toolsMenuName];
                 CommandBarPopup toolsPopup = (CommandBarPopup)toolsControl;
 
-                if ( toolsPopup == null )
+                if (toolsPopup == null)
                 {
-                    MessageBox.Show( "Will skip adding control, as the tools popup could not be found with name '" + toolsMenuName + "'" );
+                    string message = "Will skip adding control, as the tools popup could not be found with name '" + toolsMenuName + "'";
+                    logger.Log(Level.WARNING, message);
+                    MessageBox.Show(message);
                 }
 
                 //This try/catch block can be duplicated if you wish to add multiple commands to be handled by your Add-in,
@@ -483,7 +496,9 @@ namespace NPanday.VisualStudio.Addin
                     }
                     else
                     {
-                        MessageBox.Show("Skipped adding control as the NPanday start command could not be found." );
+                        string message = "Skipped adding control as the NPanday start command could not be found.";
+                        logger.Log(Level.WARNING, message);
+                        MessageBox.Show(message);
                     }
                 }
                 catch (System.ArgumentException ex)
@@ -491,7 +506,7 @@ namespace NPanday.VisualStudio.Addin
                     //If we are here, then the exception is probably because a command with that name
                     //  already exists. If so there is no need to recreate the command and we can
                     //  safely ignore the exception.
-                    MessageBox.Show(ex.Message, "Exception adding NPanday to the Tools menu");
+                    logger.Log(Level.WARNING, "Exception occured when adding NPanday to the Tools menu: " + ex.Message);
                 }
 
             }
@@ -501,6 +516,72 @@ namespace NPanday.VisualStudio.Addin
             }
         }
 
+        private OutputWindowPane getOrCreateOutputPane(string paneName)
+        {
+            Window win = _applicationObject.Windows.Item(EnvDTE.Constants.vsWindowKindOutput);
+            OutputWindow outputWindow = (OutputWindow)win.Object;
+            OutputWindowPanes panes = outputWindow.OutputWindowPanes;
+
+            foreach (OutputWindowPane outputPane in panes)
+            {
+                if (outputPane.Name == paneName)
+                {
+                    return outputPane;
+                }
+            }
+            return outputWindow.OutputWindowPanes.Add(paneName);
+        }
+
+        private IButtonCommandContext buildCommandContext()
+        {
+            return new ButtonCommandContext(this);
+        }
+
+        private class ButtonCommandContext : IButtonCommandContext
+        {
+            private Connect _this;
+            public ButtonCommandContext(Connect connect)
+            {
+                _this = connect;
+            }
+
+            public FileInfo CurrentSelectedProjectPom
+            {
+                get { return _this.CurrentSelectedProjectPom; }
+            }
+
+            public ArtifactContext ArtifactContext
+            {
+                get { return _this.container; }
+            }
+
+            public Logger Logger
+            {
+                get { return _this.logger; }
+            }
+
+            public OutputWindowPane OutputWindowPane
+            {
+                get { return _this.outputWindowPane; }
+            }
+
+            public bool ExecuteCommand(string barAndCaption)
+            {
+                CommandBarControl[] controls;
+                if (_this._finder.TryFindCommands(barAndCaption, out controls))
+                {
+                    // best guess
+                    controls[0].Execute();
+                    return true;
+                }
+                else
+                {
+                    Logger.Log(Level.SEVERE, "Could not find and execute command: " + barAndCaption);
+                    return false;
+                }
+            }
+        }
+
         void mavenRunner_RunnerStopped(object sender, EventArgs e)
         {
             //stopButton.Enabled = false;
@@ -517,7 +598,7 @@ namespace NPanday.VisualStudio.Addin
             if (project == null)
             {
                 return isWebProject;
-            } 
+            }
 
             // compare the project kind to the web project guid
             if (String.Compare(project.Kind, WEB_PROJECT_KIND_GUID, true) == 0)
@@ -647,20 +728,20 @@ namespace NPanday.VisualStudio.Addin
                     {
                         if (item.InnerText.Contains("maven-compile-plugin"))
                         {
-                           configurationNode = item.LastChild;
+                            configurationNode = item.LastChild;
                         }
                     }
 
                     //isSigned adding keyfile tag
-                    if (!configurationNode.InnerText.Contains(".snk") && key!=string.Empty)
+                    if (!configurationNode.InnerText.Contains(".snk") && key != string.Empty)
                     {
                         //add keyfile tag
-                        InsertKeyTag(pomFilePath,key);
+                        InsertKeyTag(pomFilePath, key);
                     }
 
                     //!isSigned removing keyfile tag
-                    if (configurationNode.InnerText.Contains(".snk") && !isSigned )
-                    { 
+                    if (configurationNode.InnerText.Contains(".snk") && !isSigned)
+                    {
                         //delete keyfile tag
                         configurationNode.RemoveChild(configurationNode.LastChild);
 
@@ -862,7 +943,7 @@ namespace NPanday.VisualStudio.Addin
                         {
                             a = Assembly.ReflectionOnlyLoad(new System.Reflection.AssemblyName(refs[0]).FullName);
                         }
- 
+
                         if (a != null)
                         {
                             refType = GacUtility.GetNPandayGacType(a.ImageRuntimeVersion, a.GetName().ProcessorArchitecture, refToken);
@@ -893,7 +974,7 @@ namespace NPanday.VisualStudio.Addin
                 dep.groupId = refGroupId;
                 dep.version = refVersion;
                 dep.type = refType;
-                
+
 
                 if (!string.IsNullOrEmpty(refToken))
                     dep.classifier = refToken;
@@ -971,11 +1052,11 @@ namespace NPanday.VisualStudio.Addin
             try
             {
                 Solution2 solution = (Solution2)_applicationObject.Solution;
-                
+
                 //wait for the files to be created
                 WebReferencesClasses wrc = new WebReferencesClasses(e.ReferenceDirectory);
                 wrc.WaitForClasses(e.Namespace);
-                
+
                 e.Init(projectReferenceFolder(CurrentSelectedProject));
 
                 PomHelperUtility pomUtil = new PomHelperUtility(_applicationObject.Solution, CurrentSelectedProject);
@@ -984,7 +1065,7 @@ namespace NPanday.VisualStudio.Addin
                     pomUtil.AddWebReference(e.Namespace, e.WsdlFile, string.Empty, logger);
                 }
 
- 
+
             }
             catch (Exception ex)
             {
@@ -1077,111 +1158,136 @@ namespace NPanday.VisualStudio.Addin
 
         private void launchNPandayBuildSystem()
         {
-            // just to be safe, check if NPanday is already launched
-            if (_npandayLaunched)
-            {
-                //outputWindowPane.OutputString(Messages.MSG_L_NPANDAY_ALREADY_STARTED);
-                return;
-            }
-
-            Window win = _applicationObject.Windows.Item(EnvDTE.Constants.vsWindowKindOutput);
-            OutputWindow outputWindow = (OutputWindow)win.Object;
-            OutputWindowPanes panes = outputWindow.OutputWindowPanes;
-
-            // Reuse the existing pane (if it exists)
-            Boolean paneExists = false;
-            foreach(OutputWindowPane outputPane in panes)
+            try
             {
-                if (outputPane.Name == "NPanday Build System")
+                // just to be safe, check if NPanday is already launched
+                if (_npandayLaunched)
                 {
-                    paneExists = true;
-                    outputWindowPane = outputPane;
-                    break;
+                    outputWindowPane.OutputString(Messages.MSG_L_NPANDAY_ALREADY_STARTED);
+                    return;
                 }
-            }
-            if (!paneExists)
-            {
-                outputWindowPane = outputWindow.OutputWindowPanes.Add("NPanday Build System");
-            }
 
-            //outputWindowPane = OutputWindowPanes.Add("NPanday Build System");
+                Stopwatch swStartingBuildSystem = new Stopwatch();
+                swStartingBuildSystem.Start();
 
-            OutputWindowPaneHandler handler = new OutputWindowPaneHandler();
-            handler.SetOutputWindowPaneHandler(outputWindowPane);
+                container = new ArtifactContext();
 
-            logger = NPanday.Logging.Logger.GetLogger("UC");
-            logger.AddHandler(handler);
+                EnvDTE80.Windows2 windows2 = (EnvDTE80.Windows2)_applicationObject.Windows;
 
-            container = new ArtifactContext();
+                DTE2 dte2 = _applicationObject;
 
+                addReferenceControls = new List<CommandBarButton>();
+                buildControls = new List<CommandBarControl>();
 
+                bool placedAddStopBuildMenu = false;
+                bool placedNPandayMenus = false;
+                bool placedAllProjectMenu = false;
 
-            EnvDTE80.Windows2 windows2 = (EnvDTE80.Windows2)_applicationObject.Windows;
+                _finder.IndexCommands();
 
-            DTE2 dte2 = _applicationObject;
+                CommandBarControl[] barControls;
 
-            addReferenceControls = new List<CommandBarButton>();
-            buildControls = new List<CommandBarControl>();
-            foreach (CommandBar commandBar in (CommandBars)dte2.CommandBars)
-            {
-				IList<CommandBarControl> barControls = new List<CommandBarControl>();
-				foreach (CommandBarControl control in commandBar.Controls)
-				{
-					barControls.Add(control);
-				}
-				foreach (CommandBarControl control in barControls)
+                if (_finder.TryFindCommands(VSCommandCaptions.AddReference, out barControls))
                 {
-                    if (control.Caption.Equals(Messages.MSG_C_ADD_REFERENCE))
+                    foreach (CommandBarControl barControl in barControls)
                     {
-                        CommandBarButton ctl = (CommandBarButton)
-                            commandBar.Controls.Add(MsoControlType.msoControlButton,
-                            System.Type.Missing, System.Type.Missing, control.Index, true);
-                        ctl.Click += new _CommandBarButtonEvents_ClickEventHandler(cbShowAddArtifactsForm_Click);
-                        ctl.Caption = Messages.MSG_C_ADD_MAVEN_ARTIFACT;
-                        ctl.Visible = true;
-                        addReferenceControls.Add(ctl);
-
+                        _buttonCommandRegistry.AddBefore<AddArtifactsCommand>(barControl);
                     }
-                    else if (control.Caption.Equals("C&onfiguration Manager..."))
-                    {
-                        //add solution menu
-                        createStopBuildMenu(commandBar, control);
-                        createNPandayMenus(commandBar, control);
-                        createAllProjectMenu(commandBar, control);
+                }
+                else
+                {
+                    outputWindowPane.OutputString(Messages.MSG_L_UNABLE_TO_REGISTER_ADD_ARTIFACT_MENU);
+                }
 
-                    }
-                    // included build web site to support web site projects
-                    else if ((control.Caption.Equals("Clea&n")) || (control.Caption.Equals("Publis&h Selection")) || (control.Caption.Equals("Publis&h Web Site")))
+                foreach (CommandBar commandBar in (CommandBars)dte2.CommandBars)
+                {
+                    foreach (CommandBarControl control in commandBar.Controls)
                     {
-                        // Add the stop maven build button here
+                        if (control.Caption.Equals(Messages.MSG_C_ADD_REFERENCE))
+                        {
+                            CommandBarButton ctl = (CommandBarButton)
+                                                   commandBar.Controls.Add(MsoControlType.msoControlButton,
+                                                                           System.Type.Missing, System.Type.Missing,
+                                                                           control.Index, true);
+                            ctl.Click += new _CommandBarButtonEvents_ClickEventHandler(cbShowAddArtifactsForm_Click);
+                            ctl.Caption = Messages.MSG_C_ADD_MAVEN_ARTIFACT;
+                            ctl.Visible = true;
+                            addReferenceControls.Add(ctl);
+
+                        }
+                        else if (control.Caption.Equals("C&onfiguration Manager..."))
+                        {
+                            //add solution menu
+                            createStopBuildMenu(commandBar, control);
+                            placedAddStopBuildMenu = true;
+
+                            createNPandayMenus(commandBar, control);
+                            placedNPandayMenus = true;
 
-                        createStopBuildMenu(commandBar, control);
-                        createNPandayMenus(commandBar, control);
+                            createAllProjectMenu(commandBar, control);
+                            placedAllProjectMenu = true;
 
-                        CommandBarPopup ctl = (CommandBarPopup)
-                            commandBar.Controls.Add(MsoControlType.msoControlPopup,
-                            System.Type.Missing, System.Type.Missing, control.Index + 1, true);
-                        ctl.Caption = Messages.MSG_C_CUR_PROJECT;
-                        ctl.Visible = true;
+                        }
+                        // included build web site to support web site projects
+                        else if (
+                            _finder.IsThisCommand(control, VSCommandCaptions.Clean)
+                            || _finder.IsThisCommand(control, VSCommandCaptions.PublishSelection)
+                            || _finder.IsThisCommand(control, VSCommandCaptions.PublishWebSite))
+                        {
+                            // Add the stop maven build button here
 
-                        buildControls.Add(ctl);
+                            createStopBuildMenu(commandBar, control);
+                            placedAddStopBuildMenu = true;
+                            createNPandayMenus(commandBar, control);
+                            placedNPandayMenus = true;
 
-                        createAllProjectMenu(commandBar, control);
+                            CommandBarPopup ctl = (CommandBarPopup)
+                                                  commandBar.Controls.Add(MsoControlType.msoControlPopup,
+                                                                          System.Type.Missing, System.Type.Missing,
+                                                                          control.Index + 1, true);
+                            ctl.Caption = Messages.MSG_C_CUR_PROJECT;
+                            ctl.Visible = true;
 
-                        createCurrentProjectMenu(ctl);
+                            buildControls.Add(ctl);
 
+                            createAllProjectMenu(commandBar, control);
+                            placedAllProjectMenu = true;
 
+                            createCurrentProjectMenu(ctl);
+                        }
                     }
                 }
+                nunitControls = new List<CommandBarButton>();
+                Window solutionExplorerWindow = dte2.Windows.Item(Constants.vsWindowKindSolutionExplorer);
+                _selectionEvents = dte2.Events.SelectionEvents;
+                _selectionEvents.OnChange += new _dispSelectionEvents_OnChangeEventHandler(this.OnChange);
+                _npandayLaunched = true;
+                // outputWindowPane.Clear();
+
+                if (!placedAddStopBuildMenu)
+                    outputWindowPane.OutputString(Messages.MSG_L_UNABLE_TO_REGISTER_STOP_BUILD_MENU);
+                if (!placedNPandayMenus) outputWindowPane.OutputString(Messages.MSG_L_UNABLE_TO_REGISTER_NPANDAY_MENUS);
+                if (!placedAllProjectMenu)
+                    outputWindowPane.OutputString(Messages.MSG_L_UNABLE_TO_REGISTER_ALL_PROJECTS_MENU);
+
+                swStartingBuildSystem.Stop();
+
+                string[] nameParts = _addInInstance.Name.Split(' ');
+                // Version should be the second "word" in the name.
+                string NPandayVersion = (nameParts.Length > 1) ? nameParts[1] : "UNKNOWN";
+                outputWindowPane.OutputString(string.Format(Messages.MSG_L_NPANDAY_ADDIN_STARTED, NPandayVersion,
+                                                            swStartingBuildSystem.Elapsed.TotalSeconds));
+
+            }
+            catch (Exception e)
+            {
+                if (logger != null)
+                {
+                    logger.Log(Level.SEVERE, "NPanday Build System failed to start up: " + e.ToString());
+                }
+
+                MessageBox.Show("Error thrown: " + e.Message + Environment.NewLine + Environment.NewLine + "Consulte the log for details.", "NPanday Build System failed to start up!");
             }
-            nunitControls = new List<CommandBarButton>();
-            Window solutionExplorerWindow = dte2.Windows.Item(Constants.vsWindowKindSolutionExplorer);
-            _selectionEvents = dte2.Events.SelectionEvents;
-            _selectionEvents.OnChange += new _dispSelectionEvents_OnChangeEventHandler(this.OnChange);
-            _npandayLaunched = true;
-            outputWindowPane.Clear();
-            string NPandayVersion = _addInInstance.Description.Substring(0,_addInInstance.Description.IndexOf(" provides"));
-            outputWindowPane.OutputString(string.Format(Messages.MSG_L_NPANDAY_ADDIN_STARTED,NPandayVersion));
 
             if (_applicationObject.Solution != null)
                 attachReferenceEvent();
@@ -1309,7 +1415,7 @@ namespace NPanday.VisualStudio.Addin
         void refmanager_OnError(object sender, ReferenceErrorEventArgs e)
         {
             refManagerHasError = true;
-            outputWindowPane.OutputString("\n[WARNING] "+ e.Message);
+            outputWindowPane.OutputString("\n[WARNING] " + e.Message);
         }
 
         private void createStopBuildMenu(CommandBar commandBar, CommandBarControl control)
@@ -1379,7 +1485,7 @@ namespace NPanday.VisualStudio.Addin
         private void createAllProjectMenu(CommandBar commandBar, CommandBarControl control)
         {
 
-            ctlAll = (CommandBarPopup) commandBar.Controls.Add(MsoControlType.msoControlPopup,
+            ctlAll = (CommandBarPopup)commandBar.Controls.Add(MsoControlType.msoControlPopup,
                 System.Type.Missing, System.Type.Missing, control.Index + 1, true);
             ctlAll.Caption = Messages.MSG_C_ALL_PROJECTS;
             ctlAll.Visible = true;
@@ -1613,7 +1719,7 @@ namespace NPanday.VisualStudio.Addin
         public void OnDisconnection(ext_DisconnectMode disconnectMode, ref Array custom)
         {
             //check if NPanday is already closed
-            if ( _applicationObject == null )
+            if (_applicationObject == null)
             {
                 return;
             }
@@ -1678,7 +1784,7 @@ namespace NPanday.VisualStudio.Addin
             {
                 s.Stop();
             }
-            
+
             if (disconnectMode != Extensibility.ext_DisconnectMode.ext_dm_HostShutdown)
             {
                 this.OnBeginShutdown(ref custom);
@@ -1764,8 +1870,10 @@ namespace NPanday.VisualStudio.Addin
             ProjectImporter.NPandayImporter.ReImportProject(solution.FullName, ref warningMsg);
         }
 
+        [Obsolete]
         private void SaveAllDocuments()
         {
+            // TODO: Hook up for non-English
             SigningEvents_SignatureAdded();
 
             if (saveAllControl == null)
@@ -1788,13 +1896,13 @@ namespace NPanday.VisualStudio.Addin
 
             string errStr = null;
 
-            if (pomFile==null)
+            if (pomFile == null)
             {
-                errStr = string.Format("Pom File {0} not found!", project.FullName.Substring(0,project.FullName.LastIndexOf('\\'))+"\\pom.xml");
+                errStr = string.Format("Pom File {0} not found!", project.FullName.Substring(0, project.FullName.LastIndexOf('\\')) + "\\pom.xml");
                 throw new Exception(errStr);
             }
 
-            
+
 
             if ("pom".Equals(pomUtility.Packaging, StringComparison.OrdinalIgnoreCase))
             {
@@ -2319,6 +2427,9 @@ namespace NPanday.VisualStudio.Addin
         private bool _npandayLaunched = false;
         private CommandBarButton stopButton;
 
+        private ButtonCommandRegistry _buttonCommandRegistry;
+        private BuiltinCommandFinder _finder;
+
 
         List<WebServicesReferenceWatcher> wsRefWatcher = new List<WebServicesReferenceWatcher>();
         List<WebServicesReferenceWatcher> svRefWatcher = new List<WebServicesReferenceWatcher>();
@@ -2447,10 +2558,10 @@ namespace NPanday.VisualStudio.Addin
 
     public interface IWebServiceRefInfo
     {
-        string Name { get; set;}
-        string WSDLUrl { get; set;}
-        string OutputFile { get; set;}
-        string WsdlFile { get; set;}
+        string Name { get; set; }
+        string WSDLUrl { get; set; }
+        string OutputFile { get; set; }
+        string WsdlFile { get; set; }
     }
 
     public class WebServiceRefInfo : IWebServiceRefInfo

Added: incubator/npanday/trunk/dotnet/assemblies/NPanday.VisualStudio.Addin/src/main/csharp/NPanday/VisualStudio/Addin/Helper/BuiltinCommandFinder.cs
URL: http://svn.apache.org/viewvc/incubator/npanday/trunk/dotnet/assemblies/NPanday.VisualStudio.Addin/src/main/csharp/NPanday/VisualStudio/Addin/Helper/BuiltinCommandFinder.cs?rev=1198920&view=auto
==============================================================================
--- incubator/npanday/trunk/dotnet/assemblies/NPanday.VisualStudio.Addin/src/main/csharp/NPanday/VisualStudio/Addin/Helper/BuiltinCommandFinder.cs (added)
+++ incubator/npanday/trunk/dotnet/assemblies/NPanday.VisualStudio.Addin/src/main/csharp/NPanday/VisualStudio/Addin/Helper/BuiltinCommandFinder.cs Mon Nov  7 20:38:24 2011
@@ -0,0 +1,295 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Text;
+using EnvDTE;
+using EnvDTE80;
+using Microsoft.VisualStudio.CommandBars;
+using NPanday.Logging;
+
+namespace NPanday.VisualStudio.Addin.Helper
+{
+    public class BuiltinCommandFinder
+    {
+        private readonly DTE2 _application;
+        private readonly Logger _logger;
+
+        IDictionary<string, List<string>> _containingCommandBarsByControlCaption = new Dictionary<string, List<string>>();
+        IDictionary<string, List<string>> _containingCommandBarsByCammandName = new Dictionary<string, List<string>>();
+
+        IDictionary<string, CommandBarControl> _controlByCaptionPath = new Dictionary<string, CommandBarControl>();
+        IDictionary<string, CommandBarControl> _controlByBarAndCommandNamePath = new Dictionary<string, CommandBarControl>();
+        private bool _indexed = false;
+
+
+        public BuiltinCommandFinder(DTE2 application, Logger logger)
+        {
+            _application = application;
+            _logger = logger;
+        }
+
+        /// <summary>
+        /// Finds command controls using a <paramref name="lookup"/>.
+        /// </summary>
+        /// <param name="lookup">
+        /// Possible Formats:
+        ///   "buttoncaption", "commandname", "barname->buttoncaption", "barname->buttoncaption"
+        /// </param>
+        public bool TryFindCommands(string lookup, out CommandBarControl[] controls)
+        {
+            ensureIsIndexed();
+            CommandBars bars = ((CommandBars)_application.CommandBars);
+            if (!lookup.Contains("->"))
+            {
+                List<string> barNames;
+                if (_containingCommandBarsByCammandName.TryGetValue(lookup, out barNames))
+                {
+                    List<CommandBarControl> controlList = new List<CommandBarControl>();
+                    foreach (string barName in barNames)
+                    {
+                        CommandBarControl commandOrNull = FindCommandOrNull(bars[barName], lookup);
+                        Debug.Assert(commandOrNull != null, "controls index seems to be incositent");
+                        controlList.Add(commandOrNull);
+                    }
+                    controls = controlList.ToArray();
+
+                    _logger.Log(Level.DEBUG,
+                                string.Format("Found {0} command bars containing a control bound to command '{1}': {2}",
+                                barNames.Count, lookup, String.Join(",", barNames.ToArray())));
+
+                    return true;
+                }
+
+                string normalizedCaption = normalizeControlCaption(lookup);
+                if (_containingCommandBarsByControlCaption.TryGetValue(normalizedCaption, out barNames))
+                {
+                    List<CommandBarControl> controlList = new List<CommandBarControl>();
+                    foreach (string barName in barNames)
+                    {
+                        CommandBarControl commandOrNull = FindCommandOrNull(bars[barName], normalizedCaption);
+                        Debug.Assert(commandOrNull != null, "controls index seems to be incositent");
+                        controlList.Add(commandOrNull);
+                    }
+                    controls = controlList.ToArray();
+
+                    _logger.Log(Level.DEBUG,
+                                string.Format("Found {0} command bars containing a control with caption '{1}': {2}",
+                                barNames.Count, normalizedCaption, String.Join(",", barNames.ToArray())));
+
+                    return true;
+                }
+
+                controls = new CommandBarControl[0];
+                _logger.Log(Level.DEBUG, "Could not find any command bar containing a command or caption named: '" + lookup + "'.");
+                return false;
+            }
+
+
+            string[] parts = lookup.Split(new string[] { "=>" }, 2, StringSplitOptions.RemoveEmptyEntries);
+            string commandBarName = parts[0];
+            string controlCaptionOrCommandName = parts[1];
+
+            CommandBar commandBar = bars[commandBarName];
+
+            if (commandBar == null)
+            {
+                controls = new CommandBarControl[0];
+                _logger.Log(Level.DEBUG, "Could not find any command bar named: '" + commandBarName + "', and hence no contained command or caption named: " + controlCaptionOrCommandName + ".");
+                return false;
+            }
+
+
+            CommandBarControl control = FindCommandOrNull(commandBar, controlCaptionOrCommandName);
+
+            if (control == null)
+            {
+                controls = new CommandBarControl[0];
+                _logger.Log(Level.DEBUG, "Found commandbar '" + commandBarName + "', but it did not contain a control with command name or caption '" + controlCaptionOrCommandName + "'.");
+                return false;
+            }
+
+            controls = new CommandBarControl[] { control };
+            return true;
+        }
+
+        public CommandBarControl FindCommandOrNull(CommandBar commandBar, string controlCaptionOrCommandName)
+        {
+            ensureIsIndexed();
+            CommandBarControl control;
+
+            if (_controlByBarAndCommandNamePath.TryGetValue(buildCommandCaptionPath(commandBar, controlCaptionOrCommandName), out control))
+            {
+                string commandName = getButtonTargetCommand(control).Name;
+                if (!string.IsNullOrEmpty(commandName))
+                {
+                    _logger.Log(Level.DEBUG,
+                                "Control found using it's caption; its better to use the command name: " + commandName);
+                }
+                return control;
+            }
+
+
+            if (_controlByCaptionPath.TryGetValue(buildCommandCaptionPath(commandBar, controlCaptionOrCommandName), out control))
+            {
+                string commandName = getButtonTargetCommand(control).Name;
+                if (!string.IsNullOrEmpty(commandName))
+                {
+                    _logger.Log(Level.DEBUG,
+                                "Control found using it's caption; its better to use the command name: " + commandName);
+                }
+                return control;
+            }
+
+            return null;
+        }
+
+        private static string buildCommandCaptionPath(CommandBar commandBar, string controlCaptionOrCommandName)
+        {
+            return commandBar.Name + "->" + controlCaptionOrCommandName.Replace("&", "");
+        }
+
+        public void IndexCommands()
+        {
+            _indexed = true;
+
+            Stopwatch watch = new Stopwatch();
+            watch.Start();
+            CommandBars commandBars = (CommandBars)_application.CommandBars;
+            foreach (CommandBar commandBar in commandBars)
+            {
+                try
+                {
+                    // sometimes accessing the commandbar name fails
+                    string dummy = commandBar.Name;
+                }
+                catch
+                {
+                    // if this is the case, we simply omit it from the index
+                    continue;
+                }
+
+                foreach (CommandBarControl control in commandBar.Controls)
+                {
+                    try
+                    {
+                        if (control is CommandBarButton)
+                        {
+                            string captionPath = indexByCaption(commandBar, control);
+
+                            indexByCommandName(captionPath, commandBar, control);
+
+                            //_logger.Log(Level.DEBUG, commandBar.Name + "->" + control.Caption + " -> " + command.Name);
+                        }
+                        else if (control is CommandBarPopup)
+                        {
+                            // TODO: Handle submenus
+                            // http://www.mztools.com/articles/2010/MZ2010001.aspx
+                        }
+                    }
+                    catch (Exception e)
+                    {
+                        _logger.Log(Level.DEBUG, "Error on getting details for " + commandBar.Name + "->" + control.Caption + ":" + e.Message);
+                    }
+                }
+            }
+            watch.Stop();
+            _logger.Log(Level.DEBUG, string.Format("Indexed {0} command items in {1:0.00} seconds.", 0, watch.Elapsed.TotalSeconds));
+        }
+
+        private void indexByCommandName(string captionPath, CommandBar commandBar, CommandBarControl control)
+        {
+            Command command = getButtonTargetCommand(control);
+            if (!string.IsNullOrEmpty(command.Name))
+            {
+                ensureValueForKey(_containingCommandBarsByCammandName, command.Name).Add(commandBar.Name);
+                string commandPath = buildCommandCaptionPath(commandBar, command.Name);
+                if (_controlByBarAndCommandNamePath.ContainsKey(commandPath))
+                {
+                    _logger.Log(Level.DEBUG,
+                                "Command path " + commandPath + " is ambiguous; " + captionPath +
+                                " ignored, first occurance wins.");
+                }
+                else
+                {
+                    _controlByBarAndCommandNamePath.Add(commandPath, control);
+                }
+            }
+        }
+
+        private string indexByCaption(CommandBar commandBar, CommandBarControl control)
+        {
+            ensureValueForKey(_containingCommandBarsByControlCaption, normalizeControlCaption(control.Caption)).Add(
+                commandBar.Name);
+
+            string captionPath = buildCommandCaptionPath(commandBar, control.Caption);
+            ;
+            if (_controlByCaptionPath.ContainsKey(captionPath))
+            {
+                _logger.Log(Level.DEBUG, "Caption path '" + captionPath + "' is ambiguous; first occurance wins.");
+            }
+            else
+            {
+                _controlByCaptionPath[captionPath] = control;
+            }
+            return captionPath;
+        }
+
+        private Command getButtonTargetCommand(CommandBarControl control)
+        {
+            string guid;
+            int id;
+            _application.Commands.CommandInfo(control, out guid, out id);
+            Command command = _application.Commands.Item(guid, id);
+            return command;
+        }
+
+        public bool IsThisCommand(CommandBarControl control, string commandCaption)
+        {
+            CommandBar bar = control.Parent;
+            string caption = control.Caption;
+
+            if (string.IsNullOrEmpty(caption))
+                return false;
+
+            if (control.Caption == commandCaption)
+                return true;
+
+            if (normalizeControlCaption(caption) == commandCaption)
+                return true;
+
+            try
+            {
+                string barName = bar.Name; // fails sometimes
+            }
+            catch
+            {
+                return false;
+            }
+
+            return (buildCommandCaptionPath(bar, caption) == commandCaption);
+        }
+
+        private static string normalizeControlCaption(string caption)
+        {
+            return caption.Replace("&", "");
+        }
+
+        private void ensureIsIndexed()
+        {
+            if (!_indexed)
+            {
+                throw new InvalidOperationException("Please make sure IndexControls() ran, before any other methods are called.");
+            }
+        }
+
+        private static TValue ensureValueForKey<TKey, TValue>(IDictionary<TKey, TValue> dict, TKey key) where TValue : new()
+        {
+            TValue list;
+            if (!dict.TryGetValue(key, out list))
+            {
+                dict.Add(key, list = new TValue());
+            }
+            return list;
+        }
+    }
+}