/// <summary>
        /// Called after key was changed - adds undo unit and performs refactoring of code
        /// </summary>
        public void KeyRenamed(ResXStringGridRow row, string newKey)
        {
            string oldKey = row.Status == KEY_STATUS.ERROR ? null : row.DataSourceItem.Name;

            GridRenameKeyUndoUnit unit = new GridRenameKeyUndoUnit(row, editorControl, oldKey, newKey);

            editorControl.Editor.AddUndoUnit(unit);

            if (VisualLocalizerPackage.Instance.DTE.Solution.ContainsProjectItem(editorControl.Editor.ProjectItem.InternalProjectItem))
            {
                // obtain ResX project item
                ResXProjectItem resxItem = editorControl.Editor.ProjectItem;
                resxItem.ResolveNamespaceClass(resxItem.InternalProjectItem.ContainingProject.GetResXItemsAround(false, true));

                if (row.ConflictItems.Count == 0 && resxItem != null && !resxItem.IsCultureSpecific() && !string.IsNullOrEmpty(newKey))
                {
                    int errors = 0;
                    int count  = row.CodeReferences.Count;

                    // set new key
                    row.CodeReferences.ForEach((item) => { item.KeyAfterRename = newKey.CreateIdentifier(resxItem.DesignerLanguage); });

                    // run the replacer
                    try {
                        editorControl.ReferenceCounterThreadSuspended = true;
                        BatchReferenceReplacer replacer = new BatchReferenceReplacer();
                        replacer.Inline(row.CodeReferences, true, ref errors);
                    } finally {
                        editorControl.ReferenceCounterThreadSuspended = false;
                    }
                    VLOutputWindow.VisualLocalizerPane.WriteLine("Renamed {0} key references in code, {1} errors", count, errors);
                }
            }
        }