protected override void Update(CommandArrayInfo info)
        {
            if (caps.Update ()) {
                if (caps.resultResolutionAttempt != DResolver.NodeResolutionAttempt.RawSymbolLookup) {
                    var refactoringMenu = new CommandInfoSet { Text = GettextCatalog.GetString ("Refactoring") };

                    if(caps.lastResults.Any(t => t is DSymbol && DRenameRefactoring.CanRenameNode ((t as DSymbol).Definition)))
                        refactoringMenu.CommandInfos.Add (IdeApp.CommandService.GetCommandInfo (EditCommands.Rename), new Action (caps.RenameSymbol));

                    if (refactoringMenu.CommandInfos.Count > 0)
                        info.Add (refactoringMenu);

                    info.Add (IdeApp.CommandService.GetCommandInfo (RefactoryCommands.GotoDeclaration), new Action (caps.GotoDeclaration));
                    info.Add (IdeApp.CommandService.GetCommandInfo (RefactoryCommands.FindReferences), new Action (() => caps.FindReferences (false)));

                    if (caps.lastResults.Any (t => t is DSymbol && (t as DSymbol).Definition.Parent is DClassLike))
                        info.Add (IdeApp.CommandService.GetCommandInfo (RefactoryCommands.FindAllReferences), new Action (() => caps.FindReferences (true)));

                    if (caps.lastResults.Any (t => {
                        var ds = DResolver.StripMemberSymbols (t);
                        return ds is ClassType || ds is InterfaceType;
                    }))
                        info.Add (IdeApp.CommandService.GetCommandInfo (RefactoryCommands.FindDerivedClasses), new Action (caps.FindDerivedClasses));
                } else {
                    var importSymbolMenu = new CommandInfoSet { Text = GettextCatalog.GetString ("Resolve") };

                    var alreadyAddedItems = new List<INode> ();
                    foreach (var t in caps.lastResults) {
                        var ds = t as DSymbol;
                        if (ds == null)
                            continue;
                        var m = ds.Definition.NodeRoot as DModule;
                        if (m != null && !alreadyAddedItems.Contains (m)) {
                            alreadyAddedItems.Add (m);
                            importSymbolMenu.CommandInfos.Add (new CommandInfo {
                                Text = "import " + AbstractNode.GetNodePath (m, true) + ";",
                                Icon = MonoDevelop.Ide.Gui.Stock.AddNamespace
                            }, new object[]{ "a", ds.Definition });
                        }
                    }

                    if (importSymbolMenu.CommandInfos.Count > 0) {
                        // To explicitly show the Ctrl+Alt+Space hint.
                        importSymbolMenu.CommandInfos.AddSeparator ();
                        importSymbolMenu.CommandInfos.Add (IdeApp.CommandService.GetCommandInfo (RefactoryCommands.ImportSymbol), new Action (caps.TryImportMissingSymbol));

                        info.Add (importSymbolMenu);
                    }
                }
            }

            if(SortImportsCommandHandler.CanSortImports(caps.lastDoc))
                info.Add (IdeApp.CommandService.GetCommandInfo (RefactoryCommands.SortImports), new Action(()=>SortImportsCommandHandler.SortImports(caps.lastDoc)));
        }
		protected override void Update (CommandArrayInfo ainfo)
		{
			var doc = IdeApp.Workbench.ActiveDocument;
			if (doc == null || doc.FileName == FilePath.Null || doc.ParsedDocument == null)
				return;

			ResolveResult resolveResult;
			AstNode node;
			if (!ResolveAt (doc, out resolveResult, out node))
				return;

			var resolveMenu = new CommandInfoSet ();
			resolveMenu.Text = GettextCatalog.GetString ("Resolve");
			
			var possibleNamespaces = GetPossibleNamespaces (doc, node, resolveResult);

			bool addUsing = !(resolveResult is AmbiguousTypeResolveResult);
			if (addUsing) {
				foreach (string ns in possibleNamespaces) {
					var info = resolveMenu.CommandInfos.Add (
						string.Format ("using {0};", ns),
						new System.Action (new AddImport (doc, resolveResult, ns, true).Run)
					);
					info.Icon = MonoDevelop.Ide.Gui.Stock.AddNamespace;
				}
			}
			
			bool resolveDirect = !(resolveResult is UnknownMemberResolveResult);
			if (resolveDirect) {
				if (resolveMenu.CommandInfos.Count > 0)
					resolveMenu.CommandInfos.AddSeparator ();
				if (node is ObjectCreateExpression)
					node = ((ObjectCreateExpression)node).Type;
				foreach (string ns in possibleNamespaces) {
					resolveMenu.CommandInfos.Add (string.Format ("{0}", ns + "." + doc.Editor.GetTextBetween (node.StartLocation, node.EndLocation)), new System.Action (new AddImport (doc, resolveResult, ns, false).Run));
				}
			}
			
			if (resolveMenu.CommandInfos.Count > 0)
				ainfo.Insert (0, resolveMenu);
		}
		protected override void Update (CommandArrayInfo ainfo)
		{
			var doc = IdeApp.Workbench.ActiveDocument;
			if (doc == null || doc.FileName == FilePath.Null || doc.ParsedDocument == null)
				return;
			var caretOffset = doc.Editor.Caret.Offset;
			
			DomRegion region;
			var resolveResult = doc.GetLanguageItem (caretOffset, out region);
			if (resolveResult == null)
				return;

			var resolveMenu = new CommandInfoSet ();
			resolveMenu.Text = GettextCatalog.GetString ("Resolve");
			
			var possibleNamespaces = GetPossibleNamespaces (doc, resolveResult);

			bool addUsing = !(resolveResult is AmbiguousTypeResolveResult);
			if (addUsing) {
				foreach (string ns in possibleNamespaces) {
					var info = resolveMenu.CommandInfos.Add (GettextCatalog.GetString ("Import Namespace {0}", ns), new System.Action (new AddImport (doc, resolveResult, ns, true).Run));
					info.Icon = MonoDevelop.Ide.Gui.Stock.AddNamespace;
				}
			}
			
			bool resolveDirect = !(resolveResult is UnknownMemberResolveResult);
			if (resolveDirect) {
				if (resolveMenu.CommandInfos.Count > 0)
					resolveMenu.CommandInfos.AddSeparator ();
				
				foreach (string ns in possibleNamespaces) {
					resolveMenu.CommandInfos.Add (GettextCatalog.GetString ("Use {0}", ns + "." + doc.Editor.GetTextBetween (region.Begin, region.End)), new System.Action (new AddImport (doc, resolveResult, ns, false).Run));
				}
			}
			
			if (resolveMenu.CommandInfos.Count > 0)
				ainfo.Insert (0, resolveMenu);
		}
		protected override void Update (CommandArrayInfo ainfo)
		{
			var doc = IdeApp.Workbench.ActiveDocument;
			if (doc == null || doc.FileName == FilePath.Null)
				return;
			
			var parsedDocument = doc.ParsedDocument;
			if (parsedDocument == null || parsedDocument.IsInvalid)
				return;
			
			ResolveResult resolveResult;
			object item = GetItem (doc, out resolveResult);
			bool added = false;

			var options = new RefactoringOptions (doc) {
				ResolveResult = resolveResult,
				SelectedItem = item
			};
			
			var ciset = new CommandInfoSet ();
			ciset.Text = GettextCatalog.GetString ("Refactor");

			bool canRename;
			if (item is IVariable || item is IParameter) {
				canRename = true; 
			} else if (item is ITypeDefinition) { 
				canRename = !((ITypeDefinition)item).Region.IsEmpty;
			} else if (item is IType) { 
				canRename = ((IType)item).Kind == TypeKind.TypeParameter;
			} else if (item is IMember) {
				canRename = !((IMember)item).Region.IsEmpty;
			} else if (item is INamespace) {
				canRename = true;
			} else {
				canRename = false;
			}
			if (canRename) {
				ciset.CommandInfos.Add (IdeApp.CommandService.GetCommandInfo (MonoDevelop.Ide.Commands.EditCommands.Rename), new Action (delegate {
					new MonoDevelop.Refactoring.Rename.RenameHandler ().Start (null);
				}));
				added = true;
			}
			
			foreach (var refactoring in RefactoringService.Refactorings) {
				if (refactoring.IsValid (options)) {
					CommandInfo info = new CommandInfo (refactoring.GetMenuDescription (options));
					info.AccelKey = refactoring.AccelKey;
					ciset.CommandInfos.Add (info, new Action (new RefactoringOperationWrapper (refactoring, options).Operation));
				}
			}
			var refactoringInfo = doc.Annotation<RefactoringDocumentInfo> ();
			if (refactoringInfo == null) {
				refactoringInfo = new RefactoringDocumentInfo ();
				doc.AddAnnotation (refactoringInfo);
			}
			var loc = doc.Editor.Caret.Location;
			bool first = true;
			if (refactoringInfo.lastDocument != doc.ParsedDocument || loc != lastLocation) {
				try {
					refactoringInfo.validActions = RefactoringService.GetValidActions (doc, loc, new CancellationTokenSource (500).Token);
				} catch (TaskCanceledException) {
				} catch (AggregateException ae) {
					ae.Flatten ().Handle (x => x is TaskCanceledException); 
				}
	
				lastLocation = loc;
				refactoringInfo.lastDocument = doc.ParsedDocument;
			}
			if (refactoringInfo.validActions != null && refactoringInfo.lastDocument != null && refactoringInfo.lastDocument.CreateRefactoringContext != null) {
				var context = refactoringInfo.lastDocument.CreateRefactoringContext (doc, CancellationToken.None);

				foreach (var fix_ in refactoringInfo.validActions.OrderByDescending (i => Tuple.Create (CodeActionEditorExtension.IsAnalysisOrErrorFix(i), (int)i.Severity, CodeActionEditorExtension.GetUsage (i.IdString)))) {
					if (CodeActionEditorExtension.IsAnalysisOrErrorFix (fix_))
						continue;
					var fix = fix_;
					if (first) {
						first = false;
						if (ciset.CommandInfos.Count > 0)
							ciset.CommandInfos.AddSeparator ();
					}

					ciset.CommandInfos.Add (fix.Title, new Action (() => RefactoringService.ApplyFix (fix, context)));
				}
			}

			if (ciset.CommandInfos.Count > 0) {
				ainfo.Add (ciset, null);
				added = true;
			}
			
			if (IdeApp.ProjectOperations.CanJumpToDeclaration (item)) {
				var type = item as IType;
				if (type != null && type.GetDefinition ().Parts.Count > 1) {
					var declSet = new CommandInfoSet ();
					declSet.Text = GettextCatalog.GetString ("_Go to Declaration");
					var ct = type.GetDefinition ();
					foreach (var part in ct.Parts)
						declSet.CommandInfos.Add (string.Format (GettextCatalog.GetString ("{0}, Line {1}"), FormatFileName (part.Region.FileName), part.Region.BeginLine), new System.Action (new JumpTo (part).Run));
					ainfo.Add (declSet);
				} else {
					ainfo.Add (IdeApp.CommandService.GetCommandInfo (RefactoryCommands.GotoDeclaration), new System.Action (new JumpTo (item).Run));
				}
				added = true;
			}

			if (item is IMember) {
				var member = (IMember)item;
				if (member.IsOverride || member.ImplementedInterfaceMembers.Any ()) {
					ainfo.Add (GettextCatalog.GetString ("Go to _Base Symbol"), new System.Action (new GotoBase (member).Run));
					added = true;
				}
			}

			if (!(item is IMethod && ((IMethod)item).SymbolKind == SymbolKind.Operator) && (item is IEntity || item is ITypeParameter || item is IVariable || item is INamespace)) {

				ainfo.Add (IdeApp.CommandService.GetCommandInfo (RefactoryCommands.FindReferences), new System.Action (new FindRefs (item, false).Run));
				if (doc.HasProject && HasOverloads (doc.Project.ParentSolution, item))
					ainfo.Add (IdeApp.CommandService.GetCommandInfo (RefactoryCommands.FindAllReferences), new System.Action (new FindRefs (item, true).Run));
				added = true;
			}

			if (item is IMember) {
				var member = (IMember)item;
				var handler = new FindDerivedSymbolsHandler (member);
				if (handler.IsValid) {
					var a = ainfo.Add (GettextCatalog.GetString ("Find Derived Symbols"), new Action (handler.Run));
					a.AccelKey = IdeApp.CommandService.GetCommandInfo (RefactoryCommands.FindDerivedClasses).AccelKey;
					added = true;
				}
			}
			if (item is IMember) {
				var member = (IMember)item;
				if (member.SymbolKind == SymbolKind.Method || member.SymbolKind == SymbolKind.Indexer) {
					var findMemberOverloadsHandler = new FindMemberOverloadsHandler (doc, member);
					if (findMemberOverloadsHandler.IsValid) {
						ainfo.Add (GettextCatalog.GetString ("Find Member Overloads"), new System.Action (findMemberOverloadsHandler.Run));
						added = true;
					}
				}
			}

			if (item is ITypeDefinition) {
				ITypeDefinition cls = (ITypeDefinition)item;
				foreach (var bc in cls.DirectBaseTypes) {
					if (bc != null && bc.GetDefinition () != null && bc.GetDefinition ().Kind != TypeKind.Interface/* TODO: && IdeApp.ProjectOperations.CanJumpToDeclaration (bc)*/) {
						ainfo.Add (GettextCatalog.GetString ("Go to _Base"), new System.Action (new GotoBase ((ITypeDefinition)item).Run));
						break;
					}
				}
				if ((cls.Kind == TypeKind.Class && !cls.IsSealed) || cls.Kind == TypeKind.Interface) {
					var label = cls.Kind != TypeKind.Interface ? GettextCatalog.GetString ("Find _derived classes") : GettextCatalog.GetString ("Find _implementor classes");
					var a = ainfo.Add (label, new System.Action (new FindDerivedClasses (cls).Run));
					a.AccelKey = IdeApp.CommandService.GetCommandInfo (RefactoryCommands.FindDerivedClasses).AccelKey;
				}
				ainfo.Add (GettextCatalog.GetString ("Find Extension Methods"), new System.Action (new FindExtensionMethodHandler (doc, cls).Run));
				added = true;

			}

			if (added)
				ainfo.AddSeparator ();
		}
Exemple #5
0
		protected override void Update (CommandArrayInfo info)
		{
			for (int i = 0; i < IdeApp.Workbench.Pads.Count; i++) {
				Pad pad = IdeApp.Workbench.Pads[i];

				CommandInfo ci = new CommandInfo(pad.Title);
				ci.Icon = pad.Icon;
				ci.UseMarkup = true;
				ci.Description = GettextCatalog.GetString ("Show {0}", pad.Title);

				ActionCommand cmd = IdeApp.CommandService.GetActionCommand ("Pad|" + pad.Id);
				if (cmd != null) ci.AccelKey = cmd.AccelKey; 

				CommandArrayInfo list = info;
				if (pad.Categories != null) {
					for (int j = 0; j < pad.Categories.Length; j++) {
						bool found = false;
						for (int k = list.Count - 1; k >= 0; k--) {
							if (list[k].Text == pad.Categories[j] && list[k] is CommandInfoSet) {
								list = ((CommandInfoSet)list[k]).CommandInfos;
								found = true;
								break;
							}
						}
						if (!found) {
							CommandInfoSet set = new CommandInfoSet();
							set.Text = pad.Categories[j];
							set.Description = GettextCatalog.GetString ("Show {0}", set.Text);
							list.Add (set);
							list = set.CommandInfos;
						}
					}
				}
				for (int j = list.Count - 1; j >= 0; j--) {
					if (!(list[j] is CommandInfoSet)) {
						list.Insert (j + 1, ci, pad);
						pad = null;
						break;
					}
				}
				if (pad != null) list.Insert (0, ci, pad); 
			}
		}
Exemple #6
0
		static void BuildDynamicSubMenu (IntPtr rootMenu, IntPtr parentMenu, ushort index, uint macCmdID, CommandInfoSet cinfoSet)
		{
			IntPtr menuRef = HIToolbox.CreateMenu (idSeq++, GetCleanCommandText (cinfoSet), MenuAttributes.CondenseSeparators);
			objectsToDestroyOnMenuClose.Add (new DestructableMenu (menuRef));
			HIToolbox.CheckResult (HIToolbox.SetMenuItemHierarchicalMenu (parentMenu, index, menuRef));
			
			ushort count = (ushort) cinfoSet.CommandInfos.Count;
			for (ushort i = 1, j = 0; i <= count; i++) {
				CommandInfo ci = cinfoSet.CommandInfos[j++];
				if (ci.IsArraySeparator) {
					HIToolbox.AppendMenuSeparator (menuRef);
				} else {
					HIToolbox.AppendMenuItem (menuRef, ci.Text, 0, macCmdID);
					UpdateMenuItem (rootMenu, menuRef, ref i, ref count, macCmdID, ci);
					
					objectsToDestroyOnMenuClose.Add (ci.DataItem);
					uint refcon = (uint)objectsToDestroyOnMenuClose.Count;
					HIToolbox.SetMenuItemReferenceConstant (new HIMenuItem (menuRef, i), refcon);
				}
			}
		}
		protected override void Update (CommandArrayInfo info)
		{
			string group;
			var lastListGroup = new Dictionary <CommandArrayInfo, string>();
			var descFormat = GettextCatalog.GetString ("Show {0}");
			foreach (Pad pad in IdeApp.Workbench.Pads.OrderBy (p => p.Group, StringComparer.InvariantCultureIgnoreCase)) {

				CommandInfo ci = new CommandInfo(pad.Title);
				ci.Icon = pad.Icon;
				ci.UseMarkup = true;
				ci.Description = string.Format (descFormat, pad.Title);

				ActionCommand cmd = IdeApp.CommandService.GetActionCommand ("Pad|" + pad.Id);
				if (cmd != null) ci.AccelKey = cmd.AccelKey; 

				CommandArrayInfo list = info;
				if (pad.Categories != null) {
					for (int j = 0; j < pad.Categories.Length; j++) {
						bool found = false;
						for (int k = list.Count - 1; k >= 0; k--) {
							if (list[k].Text == pad.Categories[j] && list[k] is CommandInfoSet) {
								list = ((CommandInfoSet)list[k]).CommandInfos;
								found = true;
								break;
							}
						}
						if (!found) {
							CommandInfoSet set = new CommandInfoSet();
							set.Text = pad.Categories[j];
							set.Description = string.Format (descFormat, set.Text);
							list.Add (set);
							list = set.CommandInfos;
						}
					}
				}

				int atIndex = 0;
				for (int j = list.Count - 1; j >= 0; j--) {
					if (!(list [j] is CommandInfoSet)) {
						atIndex = j + 1;
						break;
					}
				}

				list.Insert (atIndex, ci, pad);
				lastListGroup.TryGetValue (list, out group);
				if (group != pad.Group) {
					lastListGroup [list] = pad.Group;
					if (atIndex > 0) {
						CommandInfo sep = new CommandInfo ("-");
						sep.IsArraySeparator = true;
						list.Insert (atIndex, sep, null);
					}
				}
			}
		}
		public void Add (CommandInfoSet infoSet)
		{
			Add (infoSet, null);
		}
Exemple #9
0
        void Update(CommandInfo cmdInfo)
        {
            if (lastCmdInfo != null)
            {
                lastCmdInfo.CancelAsyncUpdate();
                lastCmdInfo.Changed -= CommandInfoChanged;
            }
            lastCmdInfo          = cmdInfo;
            lastCmdInfo.Changed += CommandInfoChanged;

            if (isArray && !isArrayItem)
            {
                this.Visible = false;
                Gtk.Menu menu = (Gtk.Menu)Parent;

                if (itemArray != null)
                {
                    foreach (Gtk.MenuItem item in itemArray)
                    {
                        menu.Remove(item);
                    }
                }

                itemArray = new ArrayList();
                int i = Array.IndexOf(menu.Children, this);

                if (cmdInfo.ArrayInfo != null)
                {
                    foreach (CommandInfo info in cmdInfo.ArrayInfo)
                    {
                        Gtk.MenuItem item;
                        if (info.IsArraySeparator)
                        {
                            item = new Gtk.SeparatorMenuItem();
                            item.Show();
                        }
                        else
                        {
                            item = CommandEntry.CreateMenuItem(commandManager, commandId, false);
                            ICommandMenuItem mi = (ICommandMenuItem)item;
                            mi.SetUpdateInfo(info, initialTarget);
                        }
                        menu.Insert(item, ++i);
                        itemArray.Add(item);
                    }
                }
            }
            else
            {
                Gtk.Widget child = Child;
                if (child == null)
                {
                    return;
                }

                Gtk.Label accel_label = null;
                Gtk.Label label       = null;

                if (!(child is Gtk.HBox))
                {
                    child       = new Gtk.HBox(false, 0);
                    accel_label = new Gtk.Label("");
                    accel_label.UseUnderline = false;
                    accel_label.Xalign       = 1.0f;
                    accel_label.Show();

                    label = new Gtk.Label("");
                    label.UseUnderline = true;
                    label.Xalign       = 0.0f;
                    label.Show();

                    ((Gtk.Box)child).PackStart(label);
                    ((Gtk.Box)child).PackStart(accel_label);
                    child.Show();

                    this.Remove(Child);
                    this.Add(child);
                }
                else
                {
                    accel_label = (Gtk.Label)((Gtk.Box)child).Children[1];
                    label       = (Gtk.Label)((Gtk.Box)child).Children[0];
                }

                if (cmdInfo.AccelKey != null)
                {
                    accel_label.Text = "    " + KeyBindingManager.BindingToDisplayLabel(cmdInfo.AccelKey, true);
                }
                else
                {
                    accel_label.Text = String.Empty;
                }

                if (cmdInfo.UseMarkup)
                {
                    label.Markup    = overrideLabel ?? cmdInfo.Text;
                    label.UseMarkup = true;
                }
                else
                {
                    label.Text      = overrideLabel ?? cmdInfo.Text;
                    label.UseMarkup = false;
                }

                if (!string.IsNullOrEmpty(cmdInfo.Description) && label.TooltipText != cmdInfo.Description)
                {
                    label.TooltipText = cmdInfo.Description;
                }
                label.UseUnderline = true;

                this.Sensitive = cmdInfo.Enabled;
                this.Visible   = cmdInfo.Visible && (disabledVisible || cmdInfo.Enabled);

                if (!cmdInfo.Icon.IsNull && cmdInfo.Icon != lastIcon)
                {
                    Image    = new ImageView(cmdInfo.Icon, Gtk.IconSize.Menu);
                    lastIcon = cmdInfo.Icon;
                }

                if (cmdInfo is CommandInfoSet)
                {
                    CommandInfoSet ciset = (CommandInfoSet)cmdInfo;
                    Gtk.Menu       smenu = new Gtk.Menu();
                    Submenu = smenu;
                    foreach (CommandInfo info in ciset.CommandInfos)
                    {
                        Gtk.MenuItem item;
                        if (info.IsArraySeparator)
                        {
                            item = new Gtk.SeparatorMenuItem();
                            item.Show();
                        }
                        else
                        {
                            item = CommandEntry.CreateMenuItem(commandManager, commandId, false);
                            ICommandMenuItem mi = (ICommandMenuItem)item;
                            mi.SetUpdateInfo(info, initialTarget);
                        }
                        smenu.Add(item);
                    }
                }
            }
        }
 public void Insert(int index, CommandInfoSet infoSet)
 {
     Insert(index, infoSet, null);
 }
 public void Add(CommandInfoSet infoSet)
 {
     Add(infoSet, null);
 }
		protected override void Update (CommandArrayInfo ainfo)
		{
			var doc = IdeApp.Workbench.ActiveDocument;
			if (doc == null || doc.FileName == FilePath.Null)
				return;
			
			var parsedDocument = doc.ParsedDocument;
			if (parsedDocument == null || parsedDocument.IsInvalid)
				return;
			
			ResolveResult resolveResult;
			object item = GetItem (doc, out resolveResult);
			bool added = false;

			var options = new RefactoringOptions (doc) {
				ResolveResult = resolveResult,
				SelectedItem = item
			};
			
			var ciset = new CommandInfoSet ();
			ciset.Text = GettextCatalog.GetString ("Refactor");

			bool canRename;
			if (item is IVariable || item is IParameter) {
				canRename = true; 
			} else if (item is ITypeDefinition) { 
				canRename = !((ITypeDefinition)item).Region.IsEmpty;
			} else if (item is IType) { 
				canRename = ((IType)item).Kind == TypeKind.TypeParameter;
			} else if (item is IMember) {
				canRename = !((IMember)item).Region.IsEmpty;
			} else if (item is INamespace) {
				canRename = true;
			} else {
				canRename = false;
			}
			if (canRename) {
				ciset.CommandInfos.Add (IdeApp.CommandService.GetCommandInfo (MonoDevelop.Ide.Commands.EditCommands.Rename), new Action (delegate {
					new MonoDevelop.Refactoring.Rename.RenameHandler ().Start (null);
				}));
				added = true;
			}
			
			foreach (var refactoring in RefactoringService.Refactorings) {
				if (refactoring.IsValid (options)) {
					CommandInfo info = new CommandInfo (refactoring.GetMenuDescription (options));
					info.AccelKey = refactoring.AccelKey;
					ciset.CommandInfos.Add (info, new Action (new RefactoringOperationWrapper (refactoring, options).Operation));
				}
			}

			var loc = doc.Editor.Caret.Location;
			bool first = true;
			if (lastDocument != doc.ParsedDocument || loc != lastLocation) {

				if (QuickTaskStrip.EnableFancyFeatures) {
					var ext = doc.GetContent <CodeActionEditorExtension> ();
					validActions = ext != null ? ext.GetCurrentFixes () : null;
				} else {
					validActions = RefactoringService.GetValidActions (doc, loc).Result;
				}

				lastLocation = loc;
				lastDocument = doc.ParsedDocument;
			}
			if (validActions != null) {
				foreach (var fix_ in validActions) {
					var fix = fix_;
					if (first) {
						first = false;
						if (ciset.CommandInfos.Count > 0)
							ciset.CommandInfos.AddSeparator ();
					}
					ciset.CommandInfos.Add (fix.Title, new Action (() => fix.Run (doc, loc)));
				}
			}

			if (ciset.CommandInfos.Count > 0) {
				ainfo.Add (ciset, null);
				added = true;
			}
			
			if (IdeApp.ProjectOperations.CanJumpToDeclaration (item)) {
				var type = item as IType;
				if (type != null && type.GetDefinition ().Parts.Count > 1) {
					var declSet = new CommandInfoSet ();
					declSet.Text = GettextCatalog.GetString ("_Go to declaration");
					var ct = type.GetDefinition ();
					foreach (var part in ct.Parts)
						declSet.CommandInfos.Add (string.Format (GettextCatalog.GetString ("{0}, Line {1}"), FormatFileName (part.Region.FileName), part.Region.BeginLine), new System.Action (new JumpTo (part).Run));
					ainfo.Add (declSet);
				} else {
					ainfo.Add (IdeApp.CommandService.GetCommandInfo (RefactoryCommands.GotoDeclaration), new System.Action (new JumpTo (item).Run));
				}
				added = true;
			}

			if (item is IEntity || item is ITypeParameter || item is IVariable || item is INamespace) {
				ainfo.Add (IdeApp.CommandService.GetCommandInfo (RefactoryCommands.FindReferences), new System.Action (new FindRefs (item, false).Run));
				if (doc.HasProject && HasOverloads (doc.Project.ParentSolution, item))
					ainfo.Add (IdeApp.CommandService.GetCommandInfo (RefactoryCommands.FindAllReferences), new System.Action (new FindRefs (item, true).Run));
				added = true;
			}
			
			if (item is IMethod) {
				IMethod method = item as IMethod;
				if (method.IsOverride) {
					ainfo.Add (GettextCatalog.GetString ("Go to _base"), new System.Action (new GotoBase ((IMethod)item).Run));
					added = true;
				}
			} else if (item is ITypeDefinition) {
				ITypeDefinition cls = (ITypeDefinition)item;
				foreach (var bc in cls.DirectBaseTypes) {
					if (bc != null && bc.GetDefinition () != null && bc.GetDefinition ().Kind != TypeKind.Interface/* TODO: && IdeApp.ProjectOperations.CanJumpToDeclaration (bc)*/) {
						ainfo.Add (GettextCatalog.GetString ("Go to _base"), new System.Action (new GotoBase ((ITypeDefinition)item).Run));
						break;
					}
				}
				if ((cls.Kind == TypeKind.Class && !cls.IsSealed) || cls.Kind == TypeKind.Interface) {
					ainfo.Add (cls.Kind != TypeKind.Interface ? GettextCatalog.GetString ("Find _derived classes") : GettextCatalog.GetString ("Find _implementor classes"), new System.Action (new FindDerivedClasses (cls).Run));
				}
			}

			if (added)
				ainfo.AddSeparator ();
		}
		static CommandInfoSet CreateFixMenu (TextEditor editor, DocumentContext ctx, CodeActionContainer container)
		{
			if (editor == null)
				throw new ArgumentNullException ("editor");
			if (ctx == null)
				throw new ArgumentNullException ("ctx");
			if (container == null)
				throw new ArgumentNullException ("container");
			var result = new CommandInfoSet ();
			result.Text = GettextCatalog.GetString ("Fix");
			foreach (var diagnostic in container.CodeFixActions) {
				var info = new CommandInfo (diagnostic.CodeAction.Title);
				result.CommandInfos.Add (info, new Action (new CodeActionEditorExtension.ContextActionRunner (diagnostic.CodeAction, editor, ctx).Run));
			}
			if (result.CommandInfos.Count == 0)
				return result;
			bool firstDiagnosticOption = true;
			foreach (var fix in container.DiagnosticsAtCaret) {

				var inspector = BuiltInCodeDiagnosticProvider.GetCodeDiagnosticDescriptor (fix.Id);
				if (inspector == null)
					continue;

				if (firstDiagnosticOption) {
					result.CommandInfos.AddSeparator ();
					firstDiagnosticOption = false;
				}

				var label = GettextCatalog.GetString ("_Options for \"{0}\"", fix.GetMessage ());
				var subMenu = new CommandInfoSet ();
				subMenu.Text = label;

//				if (inspector.CanSuppressWithAttribute) {
//					var menuItem = new FixMenuEntry (GettextCatalog.GetString ("_Suppress with attribute"),
//						delegate {
//							
//							inspector.SuppressWithAttribute (Editor, DocumentContext, GetTextSpan (fix.Item2)); 
//						});
//					subMenu.Add (menuItem);
//				}

				if (inspector.CanDisableWithPragma) {
					var info = new CommandInfo (GettextCatalog.GetString ("_Suppress with #pragma"));
					subMenu.CommandInfos.Add (info, new Action (() => inspector.DisableWithPragma (editor, ctx, fix)));

					info = new CommandInfo (GettextCatalog.GetString ("_Suppress with file"));
					subMenu.CommandInfos.Add (info, new Action (() => inspector.DisableWithFile (editor, ctx, fix)));
				}

				var configInfo = new CommandInfo (GettextCatalog.GetString ("_Configure Rule"));
				subMenu.CommandInfos.Add (configInfo, new Action (() => {
					IdeApp.Workbench.ShowGlobalPreferencesDialog (null, "C#", dialog => {
						var panel = dialog.GetPanel<CodeIssuePanel> ("C#");
						if (panel == null)
							return;
						panel.Widget.SelectCodeIssue (inspector.IdString);
					});
				}));

				foreach (var fix2 in container.CodeFixActions) {

					var provider = fix2.Diagnostic.GetCodeFixProvider ().GetFixAllProvider ();
					if (provider == null)
						continue;
					if (!provider.GetSupportedFixAllScopes ().Contains (FixAllScope.Document))
						continue;
					var subMenu2 = new CommandInfoSet ();
					subMenu2.Text = GettextCatalog.GetString ("Fix all");
					var diagnosticAnalyzer = fix2.Diagnostic.GetCodeDiagnosticDescriptor (LanguageNames.CSharp).GetProvider ();
					if (!diagnosticAnalyzer.SupportedDiagnostics.Contains (fix.Descriptor))
						continue;

					var info = new CommandInfo (GettextCatalog.GetString ("In _Document"));
					subMenu2.CommandInfos.Add (info, new Action (async delegate {
						
						var fixAllDiagnosticProvider = new CodeActionEditorExtension.FixAllDiagnosticProvider (diagnosticAnalyzer.SupportedDiagnostics.Select (d => d.Id).ToImmutableHashSet (), async (Microsoft.CodeAnalysis.Document doc, ImmutableHashSet<string> diagnostics, CancellationToken token) => {

							var model = await doc.GetSemanticModelAsync (token);
							var compilationWithAnalyzer = model.Compilation.WithAnalyzers (new [] { diagnosticAnalyzer }.ToImmutableArray (), null, token);

							return await compilationWithAnalyzer.GetAnalyzerSemanticDiagnosticsAsync (model, null, token);
						}, (arg1, arg2, arg3, arg4) => {
							return Task.FromResult ((IEnumerable<Diagnostic>)new Diagnostic[] { });
						});
						var ctx2 = new FixAllContext (
							ctx.AnalysisDocument,
							fix2.Diagnostic.GetCodeFixProvider (),
							FixAllScope.Document,
							fix2.CodeAction.EquivalenceKey,
							diagnosticAnalyzer.SupportedDiagnostics.Select (d => d.Id),
							fixAllDiagnosticProvider,
							default (CancellationToken)
						);
						var fixAll = await provider.GetFixAsync (ctx2);
						using (var undo = editor.OpenUndoGroup ()) {
							CodeDiagnosticDescriptor.RunAction (ctx, fixAll, default (CancellationToken));
						}
					}));
					subMenu.CommandInfos.Add (subMenu2);
				}
				result.CommandInfos.Add (subMenu);
			}

			return result;
		}
		protected override void Update (CommandArrayInfo ainfo)
		{
			var doc = IdeApp.Workbench.ActiveDocument;
			if (doc == null || doc.FileName == FilePath.Null || doc.ParsedDocument == null)
				return;
			var semanticModel = doc.ParsedDocument.GetAst<SemanticModel> ();
			if (semanticModel == null)
				return;
			var info = RefactoringSymbolInfo.GetSymbolInfoAsync (doc, doc.Editor.CaretOffset).Result;
			bool added = false;

			var ext = doc.GetContent<CodeActionEditorExtension> ();

			if (ext != null && !ext.GetCurrentFixes ().IsEmpty) {
				var fixMenu = CreateFixMenu (doc.Editor, doc, ext.GetCurrentFixes ());
				if (fixMenu.CommandInfos.Count > 0) {
					ainfo.Add (fixMenu, null);
					added = true;
				}
			}
			var ciset = new CommandInfoSet ();
			ciset.Text = GettextCatalog.GetString ("Refactor");

			bool canRename = RenameHandler.CanRename (info.Symbol ?? info.DeclaredSymbol);
			if (canRename) {
				ciset.CommandInfos.Add (IdeApp.CommandService.GetCommandInfo (MonoDevelop.Ide.Commands.EditCommands.Rename), new Action (delegate {
					new MonoDevelop.Refactoring.Rename.RenameRefactoring ().Rename (info.Symbol ?? info.DeclaredSymbol);
				}));
				added = true;
			}
			bool first = true;
			if (ext != null) {
				foreach (var fix in ext.GetCurrentFixes ().CodeRefactoringActions) {
					if (added & first && ciset.CommandInfos.Count > 0)
						ciset.CommandInfos.AddSeparator ();
					var info2 = new CommandInfo (fix.CodeAction.Title);
					ciset.CommandInfos.Add (info2, new Action (new CodeActionEditorExtension.ContextActionRunner (fix.CodeAction, doc.Editor, doc).Run));
					added = true;
					first = false;
				}
			}

			if (ciset.CommandInfos.Count > 0) {
				ainfo.Add (ciset, null);
				added = true;
			}

			var gotoDeclarationSymbol = info.Symbol;
			if (gotoDeclarationSymbol == null && info.DeclaredSymbol != null && info.DeclaredSymbol.Locations.Length > 1)
				gotoDeclarationSymbol = info.DeclaredSymbol;
			if (IdeApp.ProjectOperations.CanJumpToDeclaration (gotoDeclarationSymbol) || gotoDeclarationSymbol == null && IdeApp.ProjectOperations.CanJumpToDeclaration (info.CandidateSymbols.FirstOrDefault ())) {
				
				var type = (gotoDeclarationSymbol ?? info.CandidateSymbols.FirstOrDefault ()) as INamedTypeSymbol;
				if (type != null && type.Locations.Length > 1) {
					var declSet = new CommandInfoSet ();
					declSet.Text = GettextCatalog.GetString ("_Go to Declaration");
					foreach (var part in type.Locations) {
						var loc = part.GetLineSpan ();
						declSet.CommandInfos.Add (string.Format (GettextCatalog.GetString ("{0}, Line {1}"), FormatFileName (part.SourceTree.FilePath), loc.StartLinePosition.Line + 1), new Action (() => IdeApp.ProjectOperations.JumpTo (type, part, doc.Project)));
					}
					ainfo.Add (declSet);
				} else {
					ainfo.Add (IdeApp.CommandService.GetCommandInfo (RefactoryCommands.GotoDeclaration), new Action (() => GotoDeclarationHandler.Run (doc)));
				}
				added = true;
			}


			if (info.DeclaredSymbol != null && GotoBaseDeclarationHandler.CanGotoBase (info.DeclaredSymbol)) {
				ainfo.Add (GotoBaseDeclarationHandler.GetDescription (info.DeclaredSymbol), new Action (() => GotoBaseDeclarationHandler.GotoBase (doc, info.DeclaredSymbol)));
				added = true;
			}

			var sym = info.Symbol ?? info.DeclaredSymbol;
			if (doc.HasProject && sym != null) {
				ainfo.Add (IdeApp.CommandService.GetCommandInfo (RefactoryCommands.FindReferences), new System.Action (() => FindReferencesHandler.FindRefs (sym)));
				try {
					if (Microsoft.CodeAnalysis.FindSymbols.SymbolFinder.FindSimilarSymbols (sym, semanticModel.Compilation).Count () > 1)
						ainfo.Add (IdeApp.CommandService.GetCommandInfo (RefactoryCommands.FindAllReferences), new System.Action (() => FindAllReferencesHandler.FindRefs (info.Symbol, semanticModel.Compilation)));
				} catch (Exception) {
					// silently ignore roslyn bug.
				}
			}
			added = true;

			if (info.DeclaredSymbol != null) {
				string description;
				if (FindDerivedSymbolsHandler.CanFindDerivedSymbols (info.DeclaredSymbol, out description)) {
					ainfo.Add (description, new Action (() => FindDerivedSymbolsHandler.FindDerivedSymbols (info.DeclaredSymbol)));
					added = true;
				}

				if (FindMemberOverloadsHandler.CanFindMemberOverloads (info.DeclaredSymbol, out description)) {
					ainfo.Add (description, new Action (() => FindMemberOverloadsHandler.FindOverloads (info.DeclaredSymbol)));
					added = true;
				}

				if (FindExtensionMethodHandler.CanFindExtensionMethods (info.DeclaredSymbol, out description)) {
					ainfo.Add (description, new Action (() => FindExtensionMethodHandler.FindExtensionMethods (info.DeclaredSymbol)));
					added = true;
				}
			}
		}
		public static void PopulateInfos (CommandArrayInfo infos, Document doc, IEnumerable<FixableResult> results)
		{
			//FIXME: ellipsize long messages
			int mnemonic = 1;
			foreach (var result in results) {
				bool firstAction = true;
				foreach (var action in GetActions (doc, result)) {
					if (firstAction) {
						//FIXME: make this header item insensitive but not greyed out
						infos.Add (new CommandInfo (result.Message.Replace ("_", "__"), false, false) {
							Icon = GetIcon (result.Level)
						}, null);
						firstAction = false;
					}
					var escapedLabel = action.Label.Replace ("_", "__");
					var label = (mnemonic <= 10)
						? "_" + (mnemonic++ % 10).ToString () + " " + escapedLabel
						: "  " + escapedLabel;
					infos.Add (label, action);
				}
				if (result.HasOptionsDialog) {
					var declSet = new CommandInfoSet ();
					declSet.Text = GettextCatalog.GetString ("_Options for \"{0}\"", result.OptionsTitle);

					var ir = result as InspectorResults;
					if (ir != null) {
						var inspector = ir.Inspector;

						if (inspector.CanSuppressWithAttribute) {
							declSet.CommandInfos.Add (GettextCatalog.GetString ("_Suppress with attribute"), new System.Action(delegate {
								inspector.SuppressWithAttribute (doc, ir.Region); 
							}));
						}

						if (inspector.CanDisableWithPragma) {
							declSet.CommandInfos.Add (GettextCatalog.GetString ("_Suppress with #pragma"), new System.Action(delegate {
								inspector.DisableWithPragma (doc, ir.Region); 
							}));
						}

						if (inspector.CanDisableOnce) {
							declSet.CommandInfos.Add (GettextCatalog.GetString ("_Disable once with comment"), new System.Action(delegate {
								inspector.DisableOnce (doc, ir.Region); 
							}));
						}

						if (inspector.CanDisableAndRestore) {
							declSet.CommandInfos.Add (GettextCatalog.GetString ("Disable _and restore with comments"), new System.Action(delegate {
								inspector.DisableAndRestore (doc, ir.Region); 
							}));
						}
					}

					declSet.CommandInfos.Add (GettextCatalog.GetString ("_Configure inspection severity"), result);

					infos.Add (declSet);
				}
			}
		}
		protected override void Update (CommandArrayInfo ainfo)
		{
			var doc = IdeApp.Workbench.ActiveDocument;
			if (doc == null || doc.FileName == FilePath.Null)
				return;
			
			var parsedDocument = doc.ParsedDocument;
			if (parsedDocument == null || parsedDocument.IsInvalid)
				return;
			
			ResolveResult resolveResult;
			object item = GetItem (doc, out resolveResult);
			bool added = false;

			var options = new RefactoringOptions (doc) {
				ResolveResult = resolveResult,
				SelectedItem = item
			};
			
			var ciset = new CommandInfoSet ();
			ciset.Text = GettextCatalog.GetString ("Refactor");
			
			
			bool canRename;
			if (item is IVariable || item is IParameter) {
				canRename = true; 
			} else if (item is ITypeDefinition) { 
				canRename = !((ITypeDefinition)item).Region.IsEmpty;
			} else if (item is IType) { 
				canRename = ((IType)item).Kind == TypeKind.TypeParameter;
			} else if (item is IMember) {
				canRename = !((IMember)item).Region.IsEmpty;
			} else {
				canRename = false;
			}
			if (canRename) {
				ciset.CommandInfos.Add (IdeApp.CommandService.GetCommandInfo (MonoDevelop.Ide.Commands.EditCommands.Rename), new System.Action (delegate {
					new MonoDevelop.Refactoring.Rename.RenameHandler ().Start (null);
				}));
				added = true;
			}
			
			foreach (var refactoring in RefactoringService.Refactorings) {
				if (refactoring.IsValid (options)) {
					CommandInfo info = new CommandInfo (refactoring.GetMenuDescription (options));
					info.AccelKey = refactoring.AccelKey;
					ciset.CommandInfos.Add (info, new System.Action (new RefactoringOperationWrapper (refactoring, options).Operation));
				}
			}

			var loc = doc.Editor.Caret.Location;
			bool first = true;
			if (lastDocument != doc.ParsedDocument || loc != lastLocation) {
				validActions = RefactoringService.GetValidActions (doc, loc).Result;
				lastLocation = loc;
				lastDocument = doc.ParsedDocument;
			}
			foreach (var fix_ in validActions) {
				var fix = fix_;
				if (first) {
					first = false;
					if (ciset.CommandInfos.Count > 0)
						ciset.CommandInfos.AddSeparator ();
				}
				ciset.CommandInfos.Add (fix.Title, new System.Action (() => fix.Run (doc, loc)));
			}

			if (ciset.CommandInfos.Count > 0) {
				ainfo.Add (ciset, null);
				added = true;
			}
			
			if (IdeApp.ProjectOperations.CanJumpToDeclaration (item)) {
				var type = item as ICSharpCode.NRefactory.TypeSystem.IType;
				if (type != null && type.GetDefinition ().Parts.Count > 1) {
					var declSet = new CommandInfoSet ();
					declSet.Text = GettextCatalog.GetString ("_Go to declaration");
					var ct = type.GetDefinition ();
					foreach (var part in ct.Parts)
						declSet.CommandInfos.Add (string.Format (GettextCatalog.GetString ("{0}, Line {1}"), FormatFileName (part.Region.FileName), part.Region.BeginLine), new System.Action (new JumpTo (part).Run));
					ainfo.Add (declSet);
				} else {
					ainfo.Add (IdeApp.CommandService.GetCommandInfo (RefactoryCommands.GotoDeclaration), new System.Action (new JumpTo (item).Run));
				}
				added = true;
			}

			if (item is IEntity || item is ITypeParameter || item is IVariable) {
				ainfo.Add (IdeApp.CommandService.GetCommandInfo (RefactoryCommands.FindReferences), new System.Action (new FindRefs (item, false).Run));
				if (doc.HasProject && ReferenceFinder.HasOverloads (doc.Project.ParentSolution, item))
					ainfo.Add (IdeApp.CommandService.GetCommandInfo (RefactoryCommands.FindAllReferences), new System.Action (new FindRefs (item, true).Run));
				added = true;
			}
			
			if (item is IMethod) {
				IMethod method = item as IMethod;
				if (method.IsOverride) {
					ainfo.Add (GettextCatalog.GetString ("Go to _base"), new System.Action (new GotoBase ((IMethod)item).Run));
					added = true;
				}
			} else if (item is ITypeDefinition) {
				ITypeDefinition cls = (ITypeDefinition)item;
				foreach (var bc in cls.DirectBaseTypes) {
					if (bc != null && bc.GetDefinition () != null && bc.GetDefinition ().Kind != TypeKind.Interface/* TODO: && IdeApp.ProjectOperations.CanJumpToDeclaration (bc)*/) {
						ainfo.Add (GettextCatalog.GetString ("Go to _base"), new System.Action (new GotoBase ((ITypeDefinition)item).Run));
						break;
					}
				}
				if ((cls.Kind == TypeKind.Class && !cls.IsSealed) || cls.Kind == TypeKind.Interface) {
					ainfo.Add (cls.Kind != TypeKind.Interface ? GettextCatalog.GetString ("Find _derived classes") : GettextCatalog.GetString ("Find _implementor classes"), new System.Action (new FindDerivedClasses (cls).Run));
				}
//				if (baseConstructor != null) {
//					Refactorer refactorer2 = new Refactorer (ctx, pinfo, baseConstructor.DeclaringType, baseConstructor, null);
//					ainfo.Add (GettextCatalog.GetString ("Go to _base"), new RefactoryOperation (refactorer2.GoToBase));
//				}
			}
			
			
			

			
			if (resolveResult != null) {
//				List<string> namespaces = QuickFixHandler.GetResolveableNamespaces (options, out resolveDirect);
//			
//				if (item == null || namespaces.Count > 1) {
//					if (item == null) {
//						foreach (string ns in namespaces) {
//							// remove used namespaces for conflict resolving. 
//							if (options.Document.CompilationUnit.IsNamespaceUsedAt (ns, options.ResolveResult.ResolvedExpression.Region.Start))
//								continue;
//							CommandInfo info = resolveMenu.CommandInfos.Add ("using " + ns + ";", new RefactoryOperation (new ResolveNameOperation (ctx, doc, resolveResult, ns).AddImport));
//							info.Icon = MonoDevelop.Ide.Gui.Stock.AddNamespace;
//						}
//						// remove all unused namespaces (for resolving conflicts)
//						namespaces.RemoveAll (ns => !doc.CompilationUnit.IsNamespaceUsedAt (ns, resolveResult.ResolvedExpression.Region.Start));
//					}
//					
//					if (namespaces.Count > (item == null ? 0 : 1))
//						ainfo.Add (resolveMenu, null);
//				}
			}
			
			
//				
//				if (cls.GetSourceProject () != null && includeModifyCommands && ((cls.ClassType == ClassType.Class) || (cls.ClassType == ClassType.Struct))) {
//					ciset.CommandInfos.Add (GettextCatalog.GetString ("_Encapsulate Fields..."), new RefactoryOperation (refactorer.EncapsulateField));
//					ciset.CommandInfos.Add (GettextCatalog.GetString ("Override/Implement members..."), new RefactoryOperation (refactorer.OverrideOrImplementMembers));
//				}
//				
//				ainfo.Add (IdeApp.CommandService.GetCommandInfo (RefactoryCommands.FindReferences), new RefactoryOperation (refactorer.FindReferences));
//				
//				if (canRename && cls.ClassType == ClassType.Interface && eclass != null) {
//					// is now provided by the refactoring command infrastructure:
////					ciset.CommandInfos.Add (GettextCatalog.GetString ("Implement Interface (explicit)"), new RefactoryOperation (refactorer.ImplementExplicitInterface));
////					ciset.CommandInfos.Add (GettextCatalog.GetString ("Implement Interface (implicit)"), new RefactoryOperation (refactorer.ImplementImplicitInterface));
//				} else if (canRename && includeModifyCommands && cls.BaseType != null && cls.ClassType != ClassType.Interface && cls == eclass) {
//					// Class might have interfaces... offer to implement them
//					CommandInfoSet impset = new CommandInfoSet ();
//					CommandInfoSet expset = new CommandInfoSet ();
//					CommandInfoSet abstactset = new CommandInfoSet ();
//					bool ifaceAdded = false;
//					bool abstractAdded = false;
//					
//					foreach (IReturnType rt in cls.BaseTypes) {
//						IType iface = ctx.GetType (rt);
//						if (iface == null)
//							continue;
//						if (iface.ClassType == ClassType.Interface) {
//							Refactorer ifaceRefactorer = new Refactorer (ctx, pinfo, cls, iface, rt);
//							impset.CommandInfos.Add (ambience.GetString (rt, OutputFlags.IncludeGenerics), new RefactoryOperation (ifaceRefactorer.ImplementImplicitInterface));
//							expset.CommandInfos.Add (ambience.GetString (rt, OutputFlags.IncludeGenerics), new RefactoryOperation (ifaceRefactorer.ImplementExplicitInterface));
//							ifaceAdded = true;
//						} else if (ContainsAbstractMembers (iface)) {
//							Refactorer ifaceRefactorer = new Refactorer (ctx, pinfo, cls, iface, rt);
//							abstactset.CommandInfos.Add (ambience.GetString (rt, OutputFlags.IncludeGenerics), new RefactoryOperation (ifaceRefactorer.ImplementAbstractMembers));
//							abstractAdded = true;
//						}
//					}
//					
//					if (ifaceAdded) {
//						impset.Text = GettextCatalog.GetString ("Implement Interface (implicit)");
//						ciset.CommandInfos.Add (impset, null);
//						
//						expset.Text = GettextCatalog.GetString ("Implement Interface (explicit)");
//						ciset.CommandInfos.Add (expset, null);
//					}
//					if (abstractAdded) {
//						abstactset.Text = GettextCatalog.GetString ("Implement abstract members");
//						ciset.CommandInfos.Add (abstactset, null);
//					}
//				}
//			} 
			
			
//			IMember eitem = resolveResult != null ? (resolveResult.CallingMember ?? resolveResult.CallingType) : null;
//			
//			string itemName = null;
//			if (item is IMember)
//				itemName = ((IMember)item).Name;
//
//			if (item != null && eitem != null && (eitem.Equals (item) || (eitem.Name == itemName && !(eitem is IProperty) && !(eitem is IMethod)))) {
//				// If this occurs, then @item is either its own enclosing item, in
//				// which case, we don't want to show it twice, or it is the base-class
//				// version of @eitem, in which case we don't want to show the base-class
//				// @item, we'd rather show the item the user /actually/ requested, @eitem.
//				item = eitem;
//				eitem = null;
//			}
//
//			IType eclass = null;
//
//			if (item is IType) {
//				if (((IType)item).ClassType == ClassType.Interface)
//					eclass = FindEnclosingClass (ctx, editor.Name, line, column); else
//					eclass = (IType)item;
//				if (eitem is IMethod && ((IMethod)eitem).IsConstructor && eitem.DeclaringType.Equals (item)) {
//					item = eitem;
//					eitem = null;
//				}
//			}
//			
//			INode realItem = item;
//			if (item is InstantiatedType)
//				realItem = ((InstantiatedType)item).UninstantiatedType;
//			if (realItem is CompoundType) {
//				editor.GetLineColumnFromPosition (editor.CursorPosition, out line, out column);
//				((CompoundType)realItem).SetMainPart (doc.FileName, line, column);
//				item = realItem;
//			}
//			
//			
//			
//			var unit = doc.CompilationUnit;
//			if (unit != null && unit.Usings != null && unit.Usings.Any (u => !u.IsFromNamespace && u.Region.Contains (line, column))) {
//				CommandInfoSet organizeUsingsMenu = new CommandInfoSet ();
//				organizeUsingsMenu.Text = GettextCatalog.GetString ("_Organize Usings");
//				organizeUsingsMenu.CommandInfos.Add (IdeApp.CommandService.GetCommandInfo (RefactoryCommands.RemoveUnusedImports), new RefactoryOperation (delegate {
//					new RemoveUnusedImportsHandler ().Start (options);
//				}));
//				organizeUsingsMenu.CommandInfos.Add (IdeApp.CommandService.GetCommandInfo (MonoDevelop.Refactoring.RefactoryCommands.SortImports), new RefactoryOperation (delegate {
//					new SortImportsHandler ().Start (options);
//				}));
//				organizeUsingsMenu.CommandInfos.Add (IdeApp.CommandService.GetCommandInfo (MonoDevelop.Refactoring.RefactoryCommands.RemoveSortImports), new RefactoryOperation (delegate {
//					new RemoveSortImportsHandler ().Start (options);
//				}));
//				ainfo.Add (organizeUsingsMenu, null);
//				added = true;
//			}
//			
//			IUnresolvedFile pinfo = doc.CompilationUnit;
//			if (pinfo == null)
//				return;
//			
//			
//			Refactorer refactorer = new Refactorer (ctx, pinfo, eclass, realItem, null);
//			Ambience ambience = AmbienceService.GetAmbienceForFile (pinfo.FileName);
//			bool includeModifyCommands = this.IsModifiable (item);
//			
//			
//			// case: clicked on base in "constructor" - so pointing to the base constructor using argument count
//			// not 100% correct, but it's the fastest thing to do.
//			if (resolveResult is BaseResolveResult && eitem is IMethod && ((IMethod)eitem).IsConstructor) {
//				IType type = item as IType;
//				IMethod baseConstructor = null;
//				int idx1 = resolveResult.ResolvedExpression.Expression.IndexOf ('(');
//				int idx2 = resolveResult.ResolvedExpression.Expression.IndexOf (')');
//				int paramCount = 0;
//				if (idx1 > 0 && idx2 > 0) {
//					if (idx2 - idx1 > 1)
//						paramCount++;
//					for (int i=idx1; i < idx2; i++) {
//						if (resolveResult.ResolvedExpression.Expression[i] == ',') 
//							paramCount++;
//					}
//				}
//				foreach (IMethod m in type.Methods) {
//					if (m.IsConstructor && m.Parameters.Count == paramCount)
//						baseConstructor = m;
//				}
//				Refactorer refactorer2 = new Refactorer (ctx, pinfo, baseConstructor.DeclaringType, baseConstructor, null);
//				ainfo.Add (GettextCatalog.GetString ("Go to _base"), new RefactoryOperation (refactorer2.GoToBase));
//			}
//			
//				else if (item is IField) {
//				if (includeModifyCommands) {
//					if (canRename)
//						ciset.CommandInfos.Add (GettextCatalog.GetString ("_Encapsulate Field..."), new RefactoryOperation (refactorer.EncapsulateField));
//				}
//			} else 
			
			if (added)
				ainfo.AddSeparator ();
			/*
			while (item != null) {
				CommandInfo ci;

				// case: clicked on base in "constructor" - so pointing to the base constructor using argument count
				// not 100% correct, but it's the fastest thing to do.
				if (resolveResult is BaseResolveResult && eitem is IMethod && ((IMethod)eitem).IsConstructor) {
					IType type = item as IType;
					IMethod baseConstructor = null;
					int idx1 = resolveResult.ResolvedExpression.Expression.IndexOf ('(');
					int idx2 = resolveResult.ResolvedExpression.Expression.IndexOf (')');
					int paramCount = 0;
					if (idx1 > 0 && idx2 > 0) {
						if (idx2 - idx1 > 1)
							paramCount++;
						for (int i=idx1; i < idx2; i++) {
							if (resolveResult.ResolvedExpression.Expression[i] == ',') 
								paramCount++;
						}
					}
					foreach (IMethod m in type.Methods) {
						if (m.IsConstructor && m.Parameters.Count == paramCount)
							baseConstructor = m;
					}
					if (baseConstructor != null && (ci = BuildRefactoryMenuForItem (ctx, doc.CompilationUnit, null, baseConstructor, true)) != null) {
						ainfo.Add (ci, null);
						added = true;
					}
				}
			
				// Add the selected item
				if ((ci = BuildRefactoryMenuForItem (ctx, doc.CompilationUnit, eclass, item, IsModifiable (item))) != null) {
					ainfo.Add (ci, null);
					added = true;
				}
				if (item is IParameter) {
					// Add the encompasing method for the previous item in the menu
					item = ((IParameter) item).DeclaringMember;
					if (item != null && (ci = BuildRefactoryMenuForItem (ctx, doc.CompilationUnit, null, item, true)) != null) {
						ainfo.Add (ci, null);
						added = true;
					}
				}
				
				
				if (item is IMember && !(eitem != null && eitem is IMember)) {
					// Add the encompasing class for the previous item in the menu
					item = ((IMember) item).DeclaringType;
					if (item != null && (ci = BuildRefactoryMenuForItem (ctx, doc.CompilationUnit, null, item, IsModifiable (item))) != null) {
						ainfo.Add (ci, null);
						added = true;
					}
				}
				
				item = eitem;
				eitem = null;
				eclass = null;
			}
			
			if (added)
				ainfo.AddSeparator ();*/
		}
		protected override void Update (CommandArrayInfo ainfo)
		{
			Document doc = IdeApp.Workbench.ActiveDocument;
			if (doc == null || doc.FileName == FilePath.Null || IdeApp.ProjectOperations.CurrentSelectedSolution == null)
				return;

			ITextBuffer editor = doc.GetContent<ITextBuffer> ();
			if (editor == null)
				return;

			bool added = false;
			int line, column;
			editor.GetLineColumnFromPosition (editor.CursorPosition, out line, out column);
			ProjectDom ctx = doc.Dom;
			ResolveResult resolveResult;
			INode item;
			GetItem (ctx, doc, editor, out resolveResult, out item);
			IMember eitem = resolveResult != null ? (resolveResult.CallingMember ?? resolveResult.CallingType) : null;
			
			string itemName = null;
			if (item is IMember)
				itemName = ((IMember)item).Name;

			if (item != null && eitem != null && (eitem.Equals (item) || (eitem.Name == itemName && !(eitem is IProperty) && !(eitem is IMethod)))) {
				// If this occurs, then @item is either its own enclosing item, in
				// which case, we don't want to show it twice, or it is the base-class
				// version of @eitem, in which case we don't want to show the base-class
				// @item, we'd rather show the item the user /actually/ requested, @eitem.
				item = eitem;
				eitem = null;
			}

			IType eclass = null;

			if (item is IType) {
				if (((IType)item).ClassType == ClassType.Interface)
					eclass = FindEnclosingClass (ctx, editor.Name, line, column); else
					eclass = (IType)item;
				if (eitem is IMethod && ((IMethod)eitem).IsConstructor && eitem.DeclaringType.Equals (item)) {
					item = eitem;
					eitem = null;
				}
			}
			
			INode realItem = item;
			if (item is InstantiatedType)
				realItem = ((InstantiatedType)item).UninstantiatedType;
			if (realItem is CompoundType) {
				editor.GetLineColumnFromPosition (editor.CursorPosition, out line, out column);
				((CompoundType)realItem).SetMainPart (doc.FileName, line, column);
				item = realItem;
			}
			
			RefactoringOptions options = new RefactoringOptions () {
				Document = doc,
				Dom = ctx,
				ResolveResult = resolveResult,
				SelectedItem = realItem
			};
			
			if (resolveResult != null  && resolveResult.ResolvedExpression != null && !string.IsNullOrEmpty (resolveResult.ResolvedExpression.Expression)) {
				bool resolveDirect;
				List<string> namespaces = QuickFixHandler.GetResolveableNamespaces (options, out resolveDirect);
			
				if (item == null || namespaces.Count > 1) {
					CommandInfoSet resolveMenu = new CommandInfoSet ();
					resolveMenu.Text = GettextCatalog.GetString ("Resolve");
					if (item == null) {
						foreach (string ns in namespaces) {
							// remove used namespaces for conflict resolving. 
							if (options.Document.CompilationUnit.IsNamespaceUsedAt (ns, options.ResolveResult.ResolvedExpression.Region.Start))
								continue;
							CommandInfo info = resolveMenu.CommandInfos.Add ("using " + ns + ";", new RefactoryOperation (new ResolveNameOperation (ctx, doc, resolveResult, ns).AddImport));
							info.Icon = MonoDevelop.Ide.Gui.Stock.AddNamespace;
						}
						if (!(resolveResult is UnresolvedMemberResolveResult))
							resolveMenu.CommandInfos.AddSeparator ();
					} else {
						// remove all unused namespaces (for resolving conflicts)
						namespaces.RemoveAll (ns => !doc.CompilationUnit.IsNamespaceUsedAt (ns, resolveResult.ResolvedExpression.Region.Start));
					}
					
					if (resolveDirect) {
						foreach (string ns in namespaces) {
							resolveMenu.CommandInfos.Add (ns, new RefactoryOperation (new ResolveNameOperation (ctx, doc, resolveResult, ns).ResolveName));
						}
					}
					if (namespaces.Count > (item == null ? 0 : 1))
						ainfo.Add (resolveMenu, null);
				}
			}
			
			var unit = doc.CompilationUnit;
			if (unit != null && unit.Usings != null && unit.Usings.Any (u => !u.IsFromNamespace && u.Region.Contains (line, column))) {
				CommandInfoSet organizeUsingsMenu = new CommandInfoSet ();
				organizeUsingsMenu.Text = GettextCatalog.GetString ("_Organize Usings");
				organizeUsingsMenu.CommandInfos.Add (IdeApp.CommandService.GetCommandInfo (RefactoryCommands.RemoveUnusedImports), new RefactoryOperation (delegate {
					new RemoveUnusedImportsHandler ().Start (options);
				}));
				organizeUsingsMenu.CommandInfos.Add (IdeApp.CommandService.GetCommandInfo (MonoDevelop.Refactoring.RefactoryCommands.SortImports), new RefactoryOperation (delegate {
					new SortImportsHandler ().Start (options);
				}));
				organizeUsingsMenu.CommandInfos.Add (IdeApp.CommandService.GetCommandInfo (MonoDevelop.Refactoring.RefactoryCommands.RemoveSortImports), new RefactoryOperation (delegate {
					new RemoveSortImportsHandler ().Start (options);
				}));
				ainfo.Add (organizeUsingsMenu, null);
				added = true;
			}
			
			CommandInfoSet ciset = new CommandInfoSet ();
			ciset.Text = GettextCatalog.GetString ("Refactor");
			foreach (var refactoring in RefactoringService.Refactorings) {
				if (refactoring.IsValid (options)) {
					CommandInfo info = new CommandInfo (refactoring.GetMenuDescription (options));
					info.AccelKey = refactoring.AccelKey;
					ciset.CommandInfos.Add (info, new RefactoryOperation (new RefactoringOperationWrapper (refactoring, options).Operation));
				}
			}
			
			if (ciset.CommandInfos.Count > 0) {
				ainfo.Add (ciset, null);
				added = true;
			}
			ICompilationUnit pinfo = doc.CompilationUnit;
			if (pinfo == null)
				return;
			
			
			Refactorer refactorer = new Refactorer (ctx, pinfo, eclass, realItem, null);
			
			if (IdeApp.ProjectOperations.CanJumpToDeclaration (item)) {
				if (item is CompoundType) {
					CommandInfoSet declSet = new CommandInfoSet ();
					declSet.Text = GettextCatalog.GetString ("_Go to declaration");
					CompoundType ct = (CompoundType)item;
					foreach (IType part in ct.Parts) {
						Refactorer partRefactorer = new Refactorer (ctx, pinfo, eclass, part, null);
						declSet.CommandInfos.Add (string.Format (GettextCatalog.GetString ("{0}, Line {1}"), FormatFileName (part.CompilationUnit.FileName), part.Location.Line), new RefactoryOperation (partRefactorer.GoToDeclaration));
					}
					ainfo.Add (declSet);
				} else {
					ainfo.Add (IdeApp.CommandService.GetCommandInfo (RefactoryCommands.GotoDeclaration), new RefactoryOperation (refactorer.GoToDeclaration));
				}
				added = true;
			}
			
			if ((item is IMember || item is LocalVariable || item is IParameter) && !(item is IType))
				ainfo.Add (IdeApp.CommandService.GetCommandInfo (RefactoryCommands.FindReferences), new RefactoryOperation (refactorer.FindReferences));
			
			Ambience ambience = AmbienceService.GetAmbienceForFile (pinfo.FileName);
			bool includeModifyCommands = this.IsModifiable (item);
			
			bool canRename;
			if ((item is LocalVariable) || (item is IParameter)) {
				canRename = true; 
			} else if (item is IType) { 
				canRename = ((IType)item).SourceProject != null; 
			} else if (item is IMember) {
				IType cls = ((IMember)item).DeclaringType;
				canRename = cls != null && cls.SourceProject != null;
			} else {
				canRename = false;
			}
			
			// case: clicked on base in "constructor" - so pointing to the base constructor using argument count
			// not 100% correct, but it's the fastest thing to do.
			if (resolveResult is BaseResolveResult && eitem is IMethod && ((IMethod)eitem).IsConstructor) {
				IType type = item as IType;
				IMethod baseConstructor = null;
				int idx1 = resolveResult.ResolvedExpression.Expression.IndexOf ('(');
				int idx2 = resolveResult.ResolvedExpression.Expression.IndexOf (')');
				int paramCount = 0;
				if (idx1 > 0 && idx2 > 0) {
					if (idx2 - idx1 > 1)
						paramCount++;
					for (int i=idx1; i < idx2; i++) {
						if (resolveResult.ResolvedExpression.Expression[i] == ',') 
							paramCount++;
					}
				}
				foreach (IMethod m in type.Methods) {
					if (m.IsConstructor && m.Parameters.Count == paramCount)
						baseConstructor = m;
				}
				Refactorer refactorer2 = new Refactorer (ctx, pinfo, baseConstructor.DeclaringType, baseConstructor, null);
				ainfo.Add (GettextCatalog.GetString ("Go to _base"), new RefactoryOperation (refactorer2.GoToBase));
			}
			
			if (item is IType) {
				IType cls = (IType) item;
				if (cls.BaseType != null && cls.ClassType == ClassType.Class) {
					foreach (IReturnType rt in cls.BaseTypes) {
						IType bc = ctx.GetType (rt);
						if (bc != null && bc.ClassType != ClassType.Interface/* TODO: && IdeApp.ProjectOperations.CanJumpToDeclaration (bc)*/) {
							ainfo.Add (GettextCatalog.GetString ("Go to _base"), new RefactoryOperation (refactorer.GoToBase));
							break;
						}
					}
				}
				
				if ((cls.ClassType == ClassType.Class && !cls.IsSealed) || cls.ClassType == ClassType.Interface) {
					ainfo.Add (cls.ClassType != ClassType.Interface ? GettextCatalog.GetString ("Find _derived classes") : GettextCatalog.GetString ("Find _implementor classes"), new RefactoryOperation (refactorer.FindDerivedClasses));
				}

				if (cls.SourceProject != null && includeModifyCommands && ((cls.ClassType == ClassType.Class) || (cls.ClassType == ClassType.Struct))) {
					ciset.CommandInfos.Add (GettextCatalog.GetString ("_Encapsulate Fields..."), new RefactoryOperation (refactorer.EncapsulateField));
					ciset.CommandInfos.Add (GettextCatalog.GetString ("Override/Implement members..."), new RefactoryOperation (refactorer.OverrideOrImplementMembers));
				}
				
				ainfo.Add (IdeApp.CommandService.GetCommandInfo (RefactoryCommands.FindReferences), new RefactoryOperation (refactorer.FindReferences));
				
//				if (canRename)
//					ciset.CommandInfos.Add (GettextCatalog.GetString ("_Rename"), new RefactoryOperation (refactorer.Rename));
				
				if (canRename && cls.ClassType == ClassType.Interface && eclass != null) {
					// is now provided by the refactoring command infrastructure:
//					ciset.CommandInfos.Add (GettextCatalog.GetString ("Implement Interface (explicit)"), new RefactoryOperation (refactorer.ImplementExplicitInterface));
//					ciset.CommandInfos.Add (GettextCatalog.GetString ("Implement Interface (implicit)"), new RefactoryOperation (refactorer.ImplementImplicitInterface));
				} else if (canRename && includeModifyCommands && cls.BaseType != null && cls.ClassType != ClassType.Interface && cls == eclass) {
					// Class might have interfaces... offer to implement them
					CommandInfoSet impset = new CommandInfoSet ();
					CommandInfoSet expset = new CommandInfoSet ();
					CommandInfoSet abstactset = new CommandInfoSet ();
					bool ifaceAdded = false;
					bool abstractAdded = false;
					
					foreach (IReturnType rt in cls.BaseTypes) {
						IType iface = ctx.GetType (rt);
						if (iface == null)
							continue;
						if (iface.ClassType == ClassType.Interface) {
							Refactorer ifaceRefactorer = new Refactorer (ctx, pinfo, cls, iface, rt);
							impset.CommandInfos.Add (ambience.GetString (rt, OutputFlags.IncludeGenerics), new RefactoryOperation (ifaceRefactorer.ImplementImplicitInterface));
							expset.CommandInfos.Add (ambience.GetString (rt, OutputFlags.IncludeGenerics), new RefactoryOperation (ifaceRefactorer.ImplementExplicitInterface));
							ifaceAdded = true;
						} else if (ContainsAbstractMembers (iface)) {
							Refactorer ifaceRefactorer = new Refactorer (ctx, pinfo, cls, iface, rt);
							abstactset.CommandInfos.Add (ambience.GetString (rt, OutputFlags.IncludeGenerics), new RefactoryOperation (ifaceRefactorer.ImplementAbstractMembers));
							abstractAdded = true;
						}
					}
					
					if (ifaceAdded) {
						impset.Text = GettextCatalog.GetString ("Implement Interface (implicit)");
						ciset.CommandInfos.Add (impset, null);
						
						expset.Text = GettextCatalog.GetString ("Implement Interface (explicit)");
						ciset.CommandInfos.Add (expset, null);
					}
					if (abstractAdded) {
						abstactset.Text = GettextCatalog.GetString ("Implement abstract members");
						ciset.CommandInfos.Add (abstactset, null);
					}
				}
			} else if (item is IField) {
				if (includeModifyCommands) {
					if (canRename)
						ciset.CommandInfos.Add (GettextCatalog.GetString ("_Encapsulate Field..."), new RefactoryOperation (refactorer.EncapsulateField));
				}
			} else if (item is IMethod) {
				IMethod method = item as IMethod;
				if (method.IsOverride) {
					ainfo.Add (GettextCatalog.GetString ("Go to _base"), new RefactoryOperation (refactorer.GoToBase));
					added = true;
				}
			}
			
			if (added)
				ainfo.AddSeparator ();
			
			
			
			/*
			while (item != null) {
				CommandInfo ci;

				// case: clicked on base in "constructor" - so pointing to the base constructor using argument count
				// not 100% correct, but it's the fastest thing to do.
				if (resolveResult is BaseResolveResult && eitem is IMethod && ((IMethod)eitem).IsConstructor) {
					IType type = item as IType;
					IMethod baseConstructor = null;
					int idx1 = resolveResult.ResolvedExpression.Expression.IndexOf ('(');
					int idx2 = resolveResult.ResolvedExpression.Expression.IndexOf (')');
					int paramCount = 0;
					if (idx1 > 0 && idx2 > 0) {
						if (idx2 - idx1 > 1)
							paramCount++;
						for (int i=idx1; i < idx2; i++) {
							if (resolveResult.ResolvedExpression.Expression[i] == ',') 
								paramCount++;
						}
					}
					foreach (IMethod m in type.Methods) {
						if (m.IsConstructor && m.Parameters.Count == paramCount)
							baseConstructor = m;
					}
					if (baseConstructor != null && (ci = BuildRefactoryMenuForItem (ctx, doc.CompilationUnit, null, baseConstructor, true)) != null) {
						ainfo.Add (ci, null);
						added = true;
					}
				}
			
				// Add the selected item
				if ((ci = BuildRefactoryMenuForItem (ctx, doc.CompilationUnit, eclass, item, IsModifiable (item))) != null) {
					ainfo.Add (ci, null);
					added = true;
				}
				if (item is IParameter) {
					// Add the encompasing method for the previous item in the menu
					item = ((IParameter) item).DeclaringMember;
					if (item != null && (ci = BuildRefactoryMenuForItem (ctx, doc.CompilationUnit, null, item, true)) != null) {
						ainfo.Add (ci, null);
						added = true;
					}
				}
				
				
				if (item is IMember && !(eitem != null && eitem is IMember)) {
					// Add the encompasing class for the previous item in the menu
					item = ((IMember) item).DeclaringType;
					if (item != null && (ci = BuildRefactoryMenuForItem (ctx, doc.CompilationUnit, null, item, IsModifiable (item))) != null) {
						ainfo.Add (ci, null);
						added = true;
					}
				}
				
				item = eitem;
				eitem = null;
				eclass = null;
			}
			
			if (added)
				ainfo.AddSeparator ();*/
		}
		public static void PopulateInfos (CommandArrayInfo infos, Document doc, IEnumerable<FixableResult> results)
		{
			//FIXME: ellipsize long messages
			int mnemonic = 1;

			var codeActionExtension = doc.GetContent <CodeActionEditorExtension> ();
			var fixes = codeActionExtension.GetCurrentFixes ();
			if (fixes != null) {
				foreach (var _fix in fixes.Where (CodeActionEditorExtension.IsAnalysisOrErrorFix)) {
					var fix = _fix;
					if (fix is AnalysisContextActionProvider.AnalysisCodeAction)
						continue;
					var escapedLabel = fix.Title.Replace ("_", "__");
					var label = (mnemonic <= 10)
						? "_" + (mnemonic++ % 10).ToString () + " " + escapedLabel
							: "  " + escapedLabel;
					infos.Add (label, fix);
				}
			}

			foreach (var result in results) {
				bool firstAction = true;
				foreach (var action in GetActions (doc, result)) {
					if (firstAction) {
						//FIXME: make this header item insensitive but not greyed out
						infos.Add (new CommandInfo (result.Message.Replace ("_", "__"), false, false) {
							Icon = GetIcon (result.Level)
						}, null);
						firstAction = false;
					}
					var escapedLabel = action.Label.Replace ("_", "__");
					var label = (mnemonic <= 10)
						? "_" + (mnemonic++ % 10).ToString () + " " + escapedLabel
						: "  " + escapedLabel;
					infos.Add (label, action);
				}
				if (result.HasOptionsDialog) {
					var declSet = new CommandInfoSet ();
					declSet.Text = GettextCatalog.GetString ("_Options for \"{0}\"", result.OptionsTitle);

					bool hasBatchFix = false;
					foreach (var fix in result.Fixes.OfType<IAnalysisFixAction> ().Where (f => f.SupportsBatchFix)) {
						hasBatchFix = true;
						var title = string.Format (GettextCatalog.GetString ("Apply in file: {0}"), fix.Label);
						declSet.CommandInfos.Add (title, new System.Action(fix.BatchFix));
					}
					if (hasBatchFix)
						declSet.CommandInfos.AddSeparator ();

					var ir = result as InspectorResults;
					if (ir != null) {
						var inspector = ir.Inspector;

						if (inspector.CanSuppressWithAttribute) {
							declSet.CommandInfos.Add (GettextCatalog.GetString ("_Suppress with attribute"), new System.Action(delegate {
								inspector.SuppressWithAttribute (doc, ir.Region); 
							}));
						}

						if (inspector.CanDisableWithPragma) {
							declSet.CommandInfos.Add (GettextCatalog.GetString ("_Suppress with #pragma"), new System.Action(delegate {
								inspector.DisableWithPragma (doc, ir.Region); 
							}));
						}

						if (inspector.CanDisableOnce) {
							declSet.CommandInfos.Add (GettextCatalog.GetString ("_Disable Once"), new System.Action(delegate {
								inspector.DisableOnce (doc, ir.Region); 
							}));
						}

						if (inspector.CanDisableAndRestore) {
							declSet.CommandInfos.Add (GettextCatalog.GetString ("Disable _and Restore"), new System.Action(delegate {
								inspector.DisableAndRestore (doc, ir.Region); 
							}));
						}
					}

					declSet.CommandInfos.Add (GettextCatalog.GetString ("_Configure Rule"), result);

					infos.Add (declSet);
				}
			}
		}
		protected override void Update (CommandArrayInfo ainfo)
		{
			var doc = IdeApp.Workbench.ActiveDocument;
			if (doc == null || doc.FileName == FilePath.Null || doc.ParsedDocument == null)
				return;

			ResolveResult resolveResult;
			AstNode node;
			if (!ResolveAt (doc, out resolveResult, out node))
				return;
			var resolveMenu = new CommandInfoSet ();
			resolveMenu.Text = GettextCatalog.GetString ("Resolve");
			
			var possibleNamespaces = GetPossibleNamespaces (doc, node, ref resolveResult);

			foreach (var t in possibleNamespaces.Where (tp => tp.OnlyAddReference)) {
				var reference = t.Reference;
				var info = resolveMenu.CommandInfos.Add (
					t.GetImportText (),
					new System.Action (new AddImport (doc, resolveResult, null, reference, true, node).Run)
					);
				info.Icon = MonoDevelop.Ide.Gui.Stock.AddNamespace;
			
			}


			bool addUsing = !(resolveResult is AmbiguousTypeResolveResult);
			if (addUsing) {
				foreach (var t in possibleNamespaces.Where (tp => tp.IsAccessibleWithGlobalUsing)) {
					string ns = t.Namespace;
					var reference = t.Reference;
					var info = resolveMenu.CommandInfos.Add (
						t.GetImportText (),
						new System.Action (new AddImport (doc, resolveResult, ns, reference, true, node).Run)
						);
					info.Icon = MonoDevelop.Ide.Gui.Stock.AddNamespace;
				}
			}
			
			bool resolveDirect = !(resolveResult is UnknownMemberResolveResult);
			if (resolveDirect) {
				if (resolveMenu.CommandInfos.Count > 0)
					resolveMenu.CommandInfos.AddSeparator ();
				foreach (var t in possibleNamespaces) {
					string ns = t.Namespace;
					var reference = t.Reference;
					resolveMenu.CommandInfos.Add (t.GetInsertNamespaceText (doc.Editor.GetTextBetween (node.StartLocation, node.EndLocation)), new System.Action (new AddImport (doc, resolveResult, ns, reference, false, node).Run));
				}
			}
			
			if (resolveMenu.CommandInfos.Count > 0)
				ainfo.Insert (0, resolveMenu);
		}
		public void Insert (int index, CommandInfoSet infoSet)
		{
			Insert (index, infoSet, null);
		}