anchor.diff:  open MonoDevelop.Core
   open MonoDevelop.Projects
   open Microsoft.FSharp.Compiler.SourceCodeServices
  -open ExtCore
  -open ExtCore.Caching
  -open ExtCore.Control
  -
  -module Symbols =
  -
  -  ///Given a column and line string returns the identifier portion of the string
  -  let lastIdent column lineString =
  -      match FSharp.CompilerBinding.Parsing.findLongIdents(column, lineString) with
  -      | Some (_, identIsland) -> Seq.last identIsland
  -      | None -> ""
  -
  -  ///Returns a TextSegment that is trimmed to only include the identifier
  -  let getTextSegment (doc:TextDocument) (symbolUse:FSharpSymbolUse) column line =
  -    let lastIdent = lastIdent  column line
  -    let (startLine, startColumn), (endLine, endColumn) = FSharp.CompilerBinding.Symbols.trimSymbolRegion symbolUse lastIdent
  -
  -    let startOffset = doc.LocationToOffset(startLine, startColumn+1)
  -    let endOffset = doc.LocationToOffset(endLine, endColumn+1)
  -    TextSegment.FromBounds(startOffset, endOffset)
  -
  -/// Formatting of tool-tip information displayed in F# IntelliSense
  -module internal TipFormatter =
  -
  -  ///lru based memoize
  -  let memoize f n =
  -      let lru = ref (LruCache.create n)
  -      fun x -> match (!lru).TryFind x with
  -               | Some entry, cache ->
  -                   lru := cache
  -                   entry
  -               | None, cache ->
  -                   let res = f x
  -                   lru := cache.Add (x, res)
  -                   LoggingService.LogInfo <| sprintf "cache contains %i entries\n%A" (!lru).Count ( (!lru).ToArray () |> Array.map (fst >> Path.GetFileName))
  -                   res
  -
  -  /// Memoize the objects that manage access to XML files, keeping only 20 most used
  -  // @todo consider if this needs to be a weak table in some way
  -  let xmlDocProvider =
  -      memoize (fun x ->
  -          try Some (ICSharpCode.NRefactory.Documentation.XmlDocumentationProvider(x))
  -          with exn -> None) 20u
  -
  -  let tryExt file ext = Option.condition File.Exists (Path.ChangeExtension(file,ext))
  -
  -  /// Return the XmlDocumentationProvider for an assembly
  -  let findXmlDocProviderForAssembly file  =
  -      maybe {let! xmlFile = Option.coalesce (tryExt file "xml") (tryExt file "XML")
  -             return! xmlDocProvider xmlFile }
  -            
  -  let findXmlDocProviderForEntity (file, key:string)  =
  -      maybe {let! docReader = findXmlDocProviderForAssembly file
  -             let doc = docReader.GetDocumentation key
  -             if String.IsNullOrEmpty doc then return! None
  -             else return doc}
  -
  -  let (|MemberName|_|) (name:string) =
  -      let dotRight = name.LastIndexOf '.'
  -      if dotRight < 1 || dotRight >= name.Length - 1 then None else
  -      let typeName = name.[0..dotRight-1]
  -      let elemName = name.[dotRight+1..]
  -      Some ("T:" + typeName, elemName)
  -
  -  let (|Method|_|) (key:string) =
  -     if key.StartsWith "M:" then
  -         let key = key.[2..]
  -         let name,count,args =
  -             if not (key.Contains "(") then key, 0, [| |] else
  -
  -             let pieces = key.Split( [|'('; ')' |], StringSplitOptions.RemoveEmptyEntries)
  -             if pieces.Length < 2 then key, 0, [| |] else
  -             let nameAndCount = pieces.[0]
  -             let argsText = pieces.[1].Replace(")","")
  -             let args = argsText.Split(',')
  -             if nameAndCount.Contains "`" then
  -                 let ps = nameAndCount.Split( [| '`' |],StringSplitOptions.RemoveEmptyEntries)
  -                 let noArgs =
  -                     try int (ps.[1].Split([| '.' |], StringSplitOptions.RemoveEmptyEntries).[0] )
  -                     with _ -> 0
  -
  -                 nameAndCount, noArgs, args
  -             else
  -                 nameAndCount, 0, args
  -
  -         match name with
  -         | MemberName(typeName,elemName) -> Some (typeName, elemName, count, args)
  -         | _ -> None
  -     else None
  -
  -  let (|FieldPropertyOrEvent|_|) (key:string) =
  -     if key.StartsWith "P:" || key.StartsWith "F:" || key.StartsWith "E:" then
  -         let name = key.[2..]
  -         match name with
  -         | MemberName(typeName,elemName) -> Some (typeName, elemName)
  -         | _ -> None
  -     else None
  -
  -  let (|Type|_|) (key:string) =
  -     if key.StartsWith "T:" then
  -        Some key
  -     else None
  -
  -  let trySelectOverload (nodes: XmlNodeList, argsFromKey:string[]) =
  -
  -      if (nodes.Count = 1) then Some nodes.[0] else
  -
  -      let result =
  -        [ for x in nodes -> x ] |> Seq.tryFind (fun curNode ->
  -          let paramList = curNode.SelectNodes ("Parameters/*")
  -          let paramTypes = [| for p in paramList -> p.Attributes.GetNamedItem("Type").Value |]
  -          (paramList <> null) && (argsFromKey.Length = paramList.Count) && paramTypes = argsFromKey )
  -
  -      match result with
  -      | None -> None
  -      | Some node ->
  -          let docs = node.SelectSingleNode ("Docs")
  -          if docs = null then None else Some docs
  -
  -  ///check helpxml exist
  -  let tryGetDoc key =
  -    let helpTree = MonoDevelop.Projects.HelpService.HelpTree
  -    if helpTree = null then None else
  -    try
  -        let helpxml = helpTree.GetHelpXml(key)
  -        if helpxml = null then None else Some(helpxml)
  -    with ex ->
  -        LoggingService.LogError (sprintf "GetHelpXml failed for key %s" key, ex)
  -        None
  -
  -  let typeMemberFormatter name =
  -      if name = "#ctor" then "/Type/Members/Member[@MemberName='.ctor']"
  -      else "/Type/Members/Member[@MemberName='" + name + "']"
  -
  -  /// Try to find the MonoDoc documentation for a file/key pair representing an entity with documentation
  -  let findMonoDocProviderForEntity (_file, key) =
  -
  -      match key with
  -      | Type(typ) ->
  -          maybe {let! docXml = tryGetDoc typ
  -                 return docXml.OuterXml}
  -      | FieldPropertyOrEvent (parentId, name) ->
  -          maybe {let! doc = tryGetDoc (parentId)
  -                 let docXml = doc.SelectSingleNode (typeMemberFormatter name)
  -                 return docXml.OuterXml }
  -      | Method(parentId, name, _count, args) ->
  -          maybe {
  -                  let! doc = tryGetDoc (parentId)
  -                  let nodeXmls = doc.SelectNodes (typeMemberFormatter name)
  -                  let! docXml = trySelectOverload (nodeXmls, args)
  -                  return docXml.OuterXml }
  -      | _ -> LoggingService.LogWarning <| sprintf "findMonoDocProviderForEntity, No match for key = %s" key
  -             None
  -
  -  /// Find the documentation for a file/key pair representing an entity with documentation
  -  let findDocForEntity (file, key)  =
  -      match findXmlDocProviderForEntity (file, key) with
  -      | Some doc -> Some doc
  -      | None -> findMonoDocProviderForEntity (file, key)
  -
  -  /// Format some of the data returned by the F# compiler
  -  let private buildFormatComment cmt =
  -    match cmt with
  -    | FSharpXmlDoc.Text(s) -> Tooltips.getTooltip Styles.simpleMarkup <| s.Trim()
  -    | FSharpXmlDoc.XmlDocFileSignature(file,key) ->
  -        match findDocForEntity (file, key) with
  -        | None -> String.Empty
  -        | Some doc -> Tooltips.getTooltip Styles.simpleMarkup doc
  -    | _ -> String.Empty
  -
  -  /// Format some of the data returned by the F# compiler
  -  let private buildFormatElement el =
  -    let signatureB, commentB = StringBuilder(), StringBuilder()
  -    match el with
  -    | FSharpToolTipElement.None -> ()
  -    | FSharpToolTipElement.Single(it, comment) ->
  -        Debug.WriteLine("DataTipElement: " + it)
  -        signatureB.Append(GLib.Markup.EscapeText (it)) |> ignore
  -        let html = buildFormatComment comment
  -        if not (String.IsNullOrWhiteSpace html) then
  -            commentB.Append(html) |> ignore
  -    | FSharpToolTipElement.Group(items) ->
  -        let items, msg =
  -          if items.Length > 10 then
  -            (items |> Seq.take 10 |> List.ofSeq), sprintf "   <i>(+%d other overloads)</i>" (items.Length - 10)
  -          else items, null
  -        if (items.Length > 1) then
  -          signatureB.AppendLine("Multiple overloads") |> ignore
  -        items |> Seq.iteri (fun i (it,comment) ->
  -          signatureB.Append(GLib.Markup.EscapeText (it))  |> ignore
  -          if i = 0 then
  -              let html = buildFormatComment comment
  -              if not (String.IsNullOrWhiteSpace html) then
  -                  commentB.AppendLine(html) |> ignore
  -                  commentB.Append(GLib.Markup.EscapeText "\n")  |> ignore )
  -        if msg <> null then signatureB.Append(msg) |> ignore
  -    | FSharpToolTipElement.CompositionError(err) ->
  -        signatureB.Append("Composition error: " + GLib.Markup.EscapeText(err)) |> ignore
  -    signatureB.ToString().Trim(), commentB.ToString().Trim()
  -
  -  /// Format tool-tip that we get from the language service as string
  -  //
  -  // TODO: Use the current projects policy to get line length
  -  // Document.Project.Policies.Get<TextStylePolicy>(types) or fall back to:
  -  // MonoDevelop.Projects.Policies.PolicyService.GetDefaultPolicy<TextStylePolicy (types)
  -  let formatTip (FSharpToolTipText(list)) =
  -      [ for item in list ->
  -          let signature, summary = buildFormatElement item
  -          signature, summary ]
  -
  -  /// For elements with XML docs, the parameter descriptions are buried in the XML. Fetch it.
  -  let private extractParamTipFromComment paramName comment =
  -    match comment with
  -    | FSharpXmlDoc.Text(s) -> Tooltips.getParameterTip Styles.simpleMarkup s paramName
  -    // For 'FSharpXmlDoc.XmlDocFileSignature' we can get documentation from 'xml' files, and via MonoDoc on Mono
  -    | FSharpXmlDoc.XmlDocFileSignature(file,key) ->
  -        maybe {let! docReader = findXmlDocProviderForAssembly file
  -               let doc = docReader.GetDocumentation(key)
  -               if String.IsNullOrEmpty doc then return! None else
  -               let parameterTip = Tooltips.getParameterTip Styles.simpleMarkup doc paramName
  -               return! parameterTip}
  -    | _ -> None
  -
  -  /// For elements with XML docs, the parameter descriptions are buried in the XML. Fetch it.
  -  let private extractParamTipFromElement paramName element =
  -      match element with
  -      | FSharpToolTipElement.None -> None
  -      | FSharpToolTipElement.Single (_it, comment) -> extractParamTipFromComment paramName comment
  -      | FSharpToolTipElement.Group items -> List.tryPick (snd >> extractParamTipFromComment paramName) items
  -      | FSharpToolTipElement.CompositionError _err -> None
  -
  -  /// For elements with XML docs, the parameter descriptions are buried in the XML. Fetch it.
  -  let extractParamTip paramName (FSharpToolTipText elements) =
  -      List.tryPick (extractParamTipFromElement paramName) elements
  -
  +open Microsoft.FSharp.Compiler.AbstractIL.Internal.Library
   
   module internal MonoDevelop =
       let getLineInfoFromOffset (offset, doc:Mono.TextEditor.TextDocument) =
  
positive.code:         | _ -> filename, [|filename|], [||]
  
  /// Provides functionality for working with the F# interactive checker running in background
  open Microsoft.FSharp.Compiler.AbstractIL.Internal.Library
  type MDLanguageService() =
    /// Single instance of the language service. We don't want the VFS during tests, so set it to blank from tests
    /// before Instance is evaluated
  
negative.code:         let _ = vfs.Force()
          new FSharp.CompilerBinding.LanguageService(
              (fun changedfile ->
                  try
                      let doc = IdeApp.Workbench.ActiveDocument
                      if doc <> null && doc.FileName.FullPath.ToString() = changedfile then
                          LoggingService.LogInfo("FSharp Language Service: Compiler notifying document '{0}' is dirty and needs reparsing.  Reparsing as its the active document.", (Path.GetFileName changedfile))
                          doc.ReparseDocument()
                  with exn  -> 
                     LoggingService.LogInfo("FSharp Language Service: Error while attempting to notify document '{0}' needs reparsing", (Path.GetFileName changedfile), exn) ))
  
    static member Instance with get () = instance.Force ()
                           and  set v  = instance <- lazy v
  