/// <summary>
        /// Called from context menu of Solution Explorer, processes given list of ProjectItems
        /// </summary>
        /// <param name="selectedItems">Items selected in Solution Explorer - to be searched</param>
        /// <param name="verbose">True if processing info should be printed to the output</param>
        public override void Process(Array selectedItems, bool verbose)
        {
            if (verbose)
            {
                VLOutputWindow.VisualLocalizerPane.WriteLine("Batch Move to Resources command started on selected items from Solution Explorer");
            }
            if (verbose)
            {
                ProgressBarHandler.StartIndeterminate(Microsoft.VisualStudio.Shell.Interop.Constants.SBAI_Find);
            }

            try {
                Results = new List <CodeStringResultItem>();

                base.Process(selectedItems, verbose);

                // remove empty strings
                Results.RemoveAll((item) => { return(item.Value.Trim().Length == 0); });

                // set each source file as readonly
                Results.ForEach((item) => {
                    VLDocumentViewsManager.SetFileReadonly(item.SourceItem.GetFullPath(), true);
                });
            } finally {
                if (verbose)
                {
                    ProgressBarHandler.StopIndeterminate(Microsoft.VisualStudio.Shell.Interop.Constants.SBAI_Find);
                }
            }

            if (verbose)
            {
                VLOutputWindow.VisualLocalizerPane.WriteLine("Batch Move to Resources completed - found {0} items to be moved", Results.Count);
            }
        }
        /// <summary>
        /// Called from context menu of a code file, processes selected block of code
        /// </summary>
        /// <param name="verbose">True if processing info should be printed to the output</param>
        public override void ProcessSelection(bool verbose)
        {
            base.ProcessSelection(verbose);

            if (verbose)
            {
                VLOutputWindow.VisualLocalizerPane.WriteLine("Batch Inline command started on text selection of active document ");
            }
            if (verbose)
            {
                ProgressBarHandler.StartIndeterminate(Microsoft.VisualStudio.Shell.Interop.Constants.SBAI_Find);
            }

            try {
                Results = new List <CodeReferenceResultItem>();

                Process(currentlyProcessedItem, IntersectsWithSelection, verbose);

                // remove items laying outside the selection
                Results.RemoveAll((item) => {
                    return(IsItemOutsideSelection(item));
                });

                // set each source file as readonly
                Results.ForEach((item) => {
                    VLDocumentViewsManager.SetFileReadonly(item.SourceItem.GetFullPath(), true);
                });
            } finally {
                // clear cached data
                trieCache.Clear();
                trieCache.Clear();
                codeUsingsCache.Clear();

                if (verbose)
                {
                    ProgressBarHandler.StopIndeterminate(Microsoft.VisualStudio.Shell.Interop.Constants.SBAI_Find);
                }
            }
            if (verbose)
            {
                VLOutputWindow.VisualLocalizerPane.WriteLine("Found {0} items to be moved", Results.Count);
            }
        }
        /// <summary>
        /// Called from context menu of a code file, processes selected block of code
        /// </summary>
        /// <param name="verbose">True if processing info should be printed to the output</param>
        public override void ProcessSelection(bool verbose)
        {
            base.ProcessSelection(verbose); // initialize class variables

            if (verbose)
            {
                VLOutputWindow.VisualLocalizerPane.WriteLine("Batch Move to Resources command started on text selection of active document ");
            }
            if (verbose)
            {
                ProgressBarHandler.StartIndeterminate(Microsoft.VisualStudio.Shell.Interop.Constants.SBAI_Find);
            }

            try {
                Results = new List <CodeStringResultItem>();

                Process(currentlyProcessedItem, IntersectsWithSelection, verbose); // process active document, leaving only those items that have non-empty intersection with the selection

                // remove empty strings and result items laying outside the selection
                Results.RemoveAll((item) => {
                    bool empty = item.Value.Trim().Length == 0;
                    return(empty || IsItemOutsideSelection(item));
                });

                // set each source file as readonly
                Results.ForEach((item) => {
                    VLDocumentViewsManager.SetFileReadonly(item.SourceItem.GetFullPath(), true);
                });
            } finally {
                if (verbose)
                {
                    ProgressBarHandler.StopIndeterminate(Microsoft.VisualStudio.Shell.Interop.Constants.SBAI_Find);
                }
            }

            if (verbose)
            {
                VLOutputWindow.VisualLocalizerPane.WriteLine("Found {0} items to be moved", Results.Count);
            }
        }
        /// <summary>
        /// Called from context menu of a code file, processes current document
        /// </summary>
        /// <param name="verbose">True if processing info should be printed to the output</param>
        public override void Process(bool verbose)
        {
            base.Process(verbose); // initialize class variables

            if (verbose)
            {
                VLOutputWindow.VisualLocalizerPane.WriteLine("Batch Inline command started on active document... ");
            }
            if (verbose)
            {
                ProgressBarHandler.StartIndeterminate(Microsoft.VisualStudio.Shell.Interop.Constants.SBAI_Find);
            }

            try {
                Results = new List <CodeReferenceResultItem>();

                Process(currentlyProcessedItem, verbose);

                // set each source file as readonly
                Results.ForEach((item) => {
                    VLDocumentViewsManager.SetFileReadonly(item.SourceItem.GetFullPath(), true);
                });
            } finally {
                // clear cached data
                trieCache.Clear();
                codeUsingsCache.Clear();

                if (verbose)
                {
                    ProgressBarHandler.StopIndeterminate(Microsoft.VisualStudio.Shell.Interop.Constants.SBAI_Find);
                }
            }
            if (verbose)
            {
                VLOutputWindow.VisualLocalizerPane.WriteLine("Found {0} items to be moved", Results.Count);
            }
        }
        /// <summary>
        /// Called from context menu of a code file, processes current document
        /// </summary>
        /// <param name="verbose">True if processing info should be printed to the output</param>
        public override void Process(bool verbose)
        {
            base.Process(verbose); // initialize class variables

            if (verbose)
            {
                VLOutputWindow.VisualLocalizerPane.WriteLine("Batch Move to Resources command started on active document... ");
            }
            if (verbose)
            {
                ProgressBarHandler.StartIndeterminate(Microsoft.VisualStudio.Shell.Interop.Constants.SBAI_Find);
            }

            try {
                Results = new List <CodeStringResultItem>();

                Process(currentlyProcessedItem, verbose);                                // process active document

                Results.RemoveAll((item) => { return(item.Value.Trim().Length == 0); }); // remove empty strings

                // set each source file as readonly
                Results.ForEach((item) => {
                    VLDocumentViewsManager.SetFileReadonly(item.SourceItem.GetFullPath(), true);
                });
            } finally {
                if (verbose)
                {
                    ProgressBarHandler.StopIndeterminate(Microsoft.VisualStudio.Shell.Interop.Constants.SBAI_Find);
                }
            }

            if (verbose)
            {
                VLOutputWindow.VisualLocalizerPane.WriteLine("Found {0} items to be moved", Results.Count);
            }
        }
        /// <summary>
        /// Starts the command, taking array of selected project items as a parameter
        /// </summary>
        public void Process(Array array)
        {
            try {
                searchedProjectItems.Clear();
                loadedResxItems.Clear();

                // find all ResX files contained within selected project items
                List <GlobalTranslateProjectItem> resxFiles = new List <GlobalTranslateProjectItem>();
                foreach (UIHierarchyItem o in array)
                {
                    if (o.Object is ProjectItem)
                    {
                        ProjectItem item = (ProjectItem)o.Object;
                        SearchForResxFiles(item, resxFiles);
                    }
                    else if (o.Object is Project)
                    {
                        Project proj = (Project)o.Object;
                        SearchForResxFiles(proj.ProjectItems, resxFiles);
                    }
                    else if (o.Object is Solution)
                    {
                        Solution s = (Solution)o.Object;
                        SearchForResxFiles(s.Projects, resxFiles);
                    }
                    else
                    {
                        throw new Exception("Unexpected project item type: " + o.Object.GetVisualBasicType());
                    }
                }

                // display form, allowing user to choose source and target language and select ResX files, where translation should be performed
                GlobalTranslateForm form = new GlobalTranslateForm(resxFiles);
                if (form.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    List <AbstractTranslateInfoItem> data = new List <AbstractTranslateInfoItem>();
                    try {
                        // collect string data from checked ResX files
                        ProgressBarHandler.StartIndeterminate(Microsoft.VisualStudio.Shell.Interop.Constants.SBAI_Find);
                        foreach (GlobalTranslateProjectItem item in resxFiles)
                        {
                            if (item.Checked)
                            {
                                AddDataForTranslation(item, data);
                            }
                        }
                        ProgressBarHandler.StopIndeterminate(Microsoft.VisualStudio.Shell.Interop.Constants.SBAI_Find);

                        // translate collected data using given language pair
                        TranslationHandler.Translate(data, form.Provider, form.LanguagePair.FromLanguage, form.LanguagePair.ToLanguage);

                        // replace original texts with the translated ones
                        ProgressBarHandler.StartIndeterminate(Microsoft.VisualStudio.Shell.Interop.Constants.SBAI_Find);
                        foreach (AbstractTranslateInfoItem i in data)
                        {
                            i.ApplyTranslation();
                        }
                    } finally {
                        // unloads all ResX files that were originally closed
                        foreach (ResXProjectItem item in loadedResxItems)
                        {
                            item.Flush();
                            item.Unload();
                        }
                        ProgressBarHandler.StopIndeterminate(Microsoft.VisualStudio.Shell.Interop.Constants.SBAI_Find);
                    }
                }
            } finally {
                MenuManager.OperationInProgress = false;
            }
        }