anchor.diff:  open System.Diagnostics
   open MonoDevelop.Core
   open MonoDevelop.Debugger
  +open MonoDevelop.Ide
  +open MonoDevelop.Ide.Editor.Extension
  +open MonoDevelop.Ide.Gui
   open MonoDevelop.Ide.Gui.Content
   open MonoDevelop.Ide.CodeCompletion
   open MonoDevelop.Ide.CodeTemplates
   open Microsoft.FSharp.Compiler
   open Microsoft.FSharp.Compiler.SourceCodeServices
   open FSharp.CompilerBinding
  -open ICSharpCode.NRefactory.Completion
   open MonoDevelop.FSharp.NRefactory
   open ICSharpCode.NRefactory.TypeSystem
   open ExtCore.Control
  
positive.code:             | EmptyDoc -> toolTipInfo
        | _ -> TooltipInformation()
  
  /// Completion data representing a delayed fetch of completion data
  type internal FSharpTryAgainMemberCompletionData() =
      inherit CompletionData(CompletionText = "", DisplayText="Declarations list not yet available...", DisplayFlags = DisplayFlags.None )
      override x.Description = "The declaration list is not yet available or the operation timed out. Try again?"     
      override x.Icon =  new MonoDevelop.Core.IconId("md-event")
  
  /// Completion data representing a failure in the ability to get completion data
  type internal FSharpErrorCompletionData(exn:exn) =
      inherit CompletionData(CompletionText = "", DisplayText=exn.Message, DisplayFlags = DisplayFlags.None )
      let text = exn.ToString()
      override x.Description = text
      override x.Icon =  new MonoDevelop.Core.IconId("md-event")
  
  /// Provide information to the 'method overloads' windows that comes up when you type '('
  type ParameterDataProvider(nameStart: int, name, meths : FSharpMethodGroupItem array) = 
      inherit MonoDevelop.Ide.CodeCompletion.ParameterDataProvider (nameStart)
      override x.Count = meths.Length
          /// Returns the markup to use to represent the specified method overload
          /// in the parameter information window.
      override x.CreateTooltipInformation (overload:int, currentParameter:int, _smartWrap:bool) = 
          // Get the lower part of the text for the display of an overload
          let meth = meths.[overload]
          let signature, comment =
              match TooltipFormatting.formatTip meth.Description with
              | [signature,comment] -> signature,comment
              //With multiple tips just take the head.  
              //This shouldnt happen anyway as we split them in the resolver provider
              | multiple -> multiple |> List.head |> (fun (signature,comment) -> signature,comment)
  
          let description =
              let param = 
                  meth.Parameters |> Array.mapi (fun i param -> 
                      let paramDesc = 
                          // Sometimes the parameter decription is hidden in the XML docs
                          match TooltipFormatting.extractParamTip param.ParameterName meth.Description with 
                          | Some(tip) -> tip
                          | None -> param.Description
                      let name = if i = currentParameter then  "<b>" + param.ParameterName + "</b>" else param.ParameterName
                      let text = name + ": " + GLib.Markup.EscapeText paramDesc
                      text )
              if String.IsNullOrEmpty comment then String.Join("\n", param)
              else comment + "\n" + String.Join("\n", param)
              
          
          // Returns the text to use to represent the specified parameter
          let paramDescription = 
              let meth = meths.[overload]
              if currentParameter < 0 || currentParameter >= meth.Parameters.Length  then "" else 
              let param = meth.Parameters.[currentParameter]
              param.ParameterName 
  
          let heading = 
  
              let lines = signature.Split [| '\n';'\r' |]
  
              // Try to highlight the current parameter in bold. Hack apart the text based on (, comma, and ), then
              // put it back together again.
              //
              // @todo This will not be perfect when the text contains generic types with more than one type parameter
              // since they will have extra commas. 
  
              let text = if lines.Length = 0 then name else  lines.[0]
              let textL = text.Split '('
              if textL.Length <> 2 then text else
              let text0 = textL.[0]
              let text1 = textL.[1]
              let text1L = text1.Split ')'
              if text1L.Length <> 2 then text else
              let text10 = text1L.[0]
              let text11 = text1L.[1]
              let text10L =  text10.Split ','
              let text10L = text10L |> Array.mapi (fun i x -> if i = currentParameter then "<b>" + x + "</b>" else x)
              textL.[0] + "(" + String.Join(",", text10L) + ")" + text11
  
          let tooltipInfo = TooltipInformation(SummaryMarkup   = description,
                                               SignatureMarkup = heading,
                                               FooterMarkup    = paramDescription)
          tooltipInfo
  
      /// Returns the number of parameters of the specified method
      override x.GetParameterCount(overload:int) = 
          let meth = meths.[overload]
          meth.Parameters.Length
          
      // @todo should return 'true' for param-list methods
      override x.AllowParameterList (_overload: int) = 
          false
  
      override x.GetParameterName (overload:int, paramIndex:int) =
          let meth = meths.[overload]
          let prm = meth.Parameters.[paramIndex]
          prm.ParameterName
  
  type Category(category) =
      inherit CompletionCategory(category, null)
      override x.CompareTo other =
  
negative.code:       //      (abc + def).PPP.
        
        let allowAnyStale = 
            match completionChar with 
            | '.' -> 
                let docText = x.Editor.Text
                if docText = null then true else
                let offset = context.TriggerOffset
                offset > 1 && Char.IsLetter (docText.[offset-2])
            | _ -> true
  
        Debug.WriteLine("allowAnyStale = {0}", allowAnyStale)
        x.CodeCompletionCommandImpl(context, allowAnyStale, token, true, false, completionChar)
  
    /// Completion was triggered explicitly using Ctrl+Space or by the function above  
    override x.CodeCompletionCommand(context) =
        let completionChar = x.Editor.GetCharAt(context.TriggerOffset - 1)
        let completionIsDot = completionChar = '.'
        x.CodeCompletionCommandImpl(context, true, Async.DefaultCancellationToken, completionIsDot, true, completionChar)
         .Result
  
    member x.CodeCompletionCommandImpl(context, allowAnyStale, token, dottedInto, ctrlSpace, completionChar) =
      Async.StartAsTask (cancellationToken = token, computation = async {
      let result = CompletionDataList()
      let fileName = x.DocumentContext.Name
      try
        let projFile, files, args = MonoDevelop.getCheckerArgs(x.DocumentContext.Project, fileName)
        // Try to get typed information from LanguageService (with the specified timeout)
        let stale = if allowAnyStale then AllowStaleResults.MatchingFileName else AllowStaleResults.MatchingSource
        let! typedParseResults = MDLanguageService.Instance.GetTypedParseResultWithTimeout(projFile, fileName, x.Editor.Text, files, args, stale, ServiceSettings.blockingTimeout)
  
        match typedParseResults with
        | None       -> () //TODOresult.Add(FSharpTryAgainMemberCompletionData())
        | Some tyRes ->
          // Get declarations and generate list for MonoDevelop
          let line, col, lineStr = MonoDevelop.getLineInfoFromOffset(context.TriggerOffset, x.Editor)
          match tyRes.GetDeclarationSymbols(line, col, lineStr) with
          | Some (symbols, _residue) ->
              let data = getCompletionData symbols
              result.AddRange data
          | None -> ()
      with
      | :? System.Threading.Tasks.TaskCanceledException -> ()
      | e ->
          LoggingService.LogError ("FSharpTextEditorCompletion, An error occured in CodeCompletionCommandImpl", e)
          () //TODOresult.Add(FSharpErrorCompletionData(e))
      
      if completionChar = '.' then lastCharDottedInto <- dottedInto
      else
          // Add the code templates and compiler generated identifiers if the completion char is not '.'
          CodeTemplates.CodeTemplateService.AddCompletionDataForMime ("text/x-fsharp", result)
          result.AddRange (compilerIdentifiers)
  
      //If we are forcing completion ensure that AutoCompleteUniqueMatch is set
      if ctrlSpace then
          result.AutoCompleteUniqueMatch <- true
      return result :> ICompletionDataList})
  
  
    // Returns the index of the parameter where the cursor is currently positioned.
    // -1 means the cursor is outside the method parameter list
    // 0 means no parameter entered
    // > 0 is the index of the parameter (1-based)
    override x.GetCurrentParameterIndex (startOffset: int) = 
        let editor = x.Editor
        let cursor = editor.CaretOffset 
        let i = startOffset // the original context
        if (i < 0 || i >= editor.Length || editor.GetCharAt (i) = ')') then -1 
        elif (i + 1 = cursor && (match editor.GetCharAt(i) with '(' | '<' -> true | _ -> false)) then 0
        else 
            // The first character is a '('
            // Note this will be confused by comments.
            let rec loop depth i parameterIndex = 
                if (i = cursor) then parameterIndex
                elif (i > cursor) then -1 
                elif (i >= editor.Length) then  parameterIndex else
                let ch = editor.GetCharAt(i)
                if (ch = '(' || ch = '{' || ch = '[') then loop (depth+1) (i+1) parameterIndex
                elif ((ch = ')' || ch = '}' || ch = ']') && depth > 1 ) then loop (depth-1) (i+1) parameterIndex
                elif (ch = ',' && depth = 1) then loop depth (i+1) (parameterIndex+1)
  