public static void ShowWindow (ICompletionWidget widget, CodeCompletionContext ctx, IParameterDataProvider provider)
		{
			if (provider.OverloadCount == 0)
				return;
			
			// There can be several method parameter lists open at the same time, so
			// they have to be queued. The last one of queue is the one being shown
			// in the information window.
			
			MethodData md = new MethodData ();
			md.MethodProvider = provider;
			md.CurrentOverload = 0;
			md.CompletionContext = ctx;
			methods.Add (md);
			UpdateWindow (widget);
		}
		internal static void HideWindow (CompletionTextEditorExtension ext, ICompletionWidget widget)
		{
			currentMethodGroup = null;
			if (window != null)
				window.ChangeOverload ();
			UpdateWindow (ext, widget);
		}
		internal static async void UpdateCursorPosition (CompletionTextEditorExtension ext, ICompletionWidget widget)
		{
			updateSrc.Cancel ();
			updateSrc = new CancellationTokenSource ();
			var token = updateSrc.Token;
			// Called after the key has been processed by the editor
			if (currentMethodGroup == null)
				return;
	
			var actualMethodGroup = new MethodData ();
			actualMethodGroup.CompletionContext = widget.CurrentCodeCompletionContext;
			actualMethodGroup.MethodProvider = await ext.ParameterCompletionCommand (widget.CurrentCodeCompletionContext);
			if (actualMethodGroup.MethodProvider != null && !actualMethodGroup.MethodProvider.Equals (currentMethodGroup.MethodProvider)) 
				currentMethodGroup = actualMethodGroup;

			int pos = await ext.GetCurrentParameterIndex (currentMethodGroup.MethodProvider.StartOffset, token);
			if (pos == -1) {
				if (actualMethodGroup.MethodProvider == null) {
					currentMethodGroup = null;
				} else {
					pos = await ext.GetCurrentParameterIndex (actualMethodGroup.MethodProvider.StartOffset, token);
					currentMethodGroup = pos >= 0 ? actualMethodGroup : null;
				}
			}

			// If the user enters more parameters than the current overload has,
			// look for another overload with more parameters.
			UpdateOverload (ext, widget);
			
			// Refresh.
			UpdateWindow (ext, widget);
		}
		internal static void ShowWindow (CompletionTextEditorExtension ext, ICompletionWidget widget, CodeCompletionContext ctx, ParameterHintingResult provider)
		{
			if (provider.Count == 0)
				return;
			
			// There can be several method parameter lists open at the same time, so
			// they have to be queued. The last one of queue is the one being shown
			// in the information window.
			
			MethodData md = new MethodData ();
			md.MethodProvider = provider;
			md.CurrentOverload = 0;
			md.CompletionContext = ctx;
			currentMethodGroup = md;
			UpdateOverload (ext, widget);
			UpdateWindow (ext, widget);
		}
        internal static void UpdateWindow(ICompletionWidget widget)
        {
            // Updates the parameter information window from the information
            // of the current method overload
            if (window == null && methods.Count > 0)
            {
                window   = new ParameterInformationWindow();
                wasAbove = false;
            }

            if (methods.Count == 0)
            {
                if (window != null)
                {
                    window.Hide();
                    wasAbove = false;
                }
                return;
            }
            var        ctx    = widget.CurrentCodeCompletionContext;
            MethodData md     = methods[methods.Count - 1];
            int        cparam = md.MethodProvider.GetCurrentParameterIndex(widget, md.CompletionContext);

            Gtk.Requisition reqSize = window.ShowParameterInfo(md.MethodProvider, md.CurrentOverload, cparam - 1);
            X = md.CompletionContext.TriggerXCoord;
            if (CompletionWindowManager.IsVisible)
            {
                // place above
                Y = ctx.TriggerYCoord - ctx.TriggerTextHeight - reqSize.Height - 10;
            }
            else
            {
                // place below
                Y = ctx.TriggerYCoord;
            }

            Gdk.Rectangle geometry = DesktopService.GetUsableMonitorGeometry(window.Screen, window.Screen.GetMonitorAtPoint(X, Y));

            if (X + reqSize.Width > geometry.Right)
            {
                X = geometry.Right - reqSize.Width;
            }

            if (Y < geometry.Top)
            {
                Y = ctx.TriggerYCoord;
            }

            if (wasAbove || Y + reqSize.Height > geometry.Bottom)
            {
                Y        = Y - ctx.TriggerTextHeight - reqSize.Height - 4;
                wasAbove = true;
            }

            if (CompletionWindowManager.IsVisible)
            {
                Rectangle completionWindow = new Rectangle(CompletionWindowManager.X, CompletionWindowManager.Y,
                                                           CompletionWindowManager.Wnd.Allocation.Width, CompletionWindowManager.Wnd.Allocation.Height);
                if (completionWindow.IntersectsWith(new Rectangle(X, Y, reqSize.Width, reqSize.Height)))
                {
                    X = completionWindow.X;
                    Y = completionWindow.Y - reqSize.Height - 6;
                    if (Y < 0)
                    {
                        Y = completionWindow.Bottom + 6;
                    }
                }
            }

            window.Move(X, Y);
            window.Show();
        }