anchor.diff:  module LanguageService =
       module internal Types =
           type PlainNotification= { content: string }
  +
  +        type ConfigValue<'a> =
  +        | UserSpecified of 'a
  +        | Implied of 'a
  +
  +        type [<RequireQualifiedAccess>] FSACTargetRuntime =
  +        | NET
  +        | NetcoreFdd
   
           /// Position in a text document expressed as zero-based line and zero-based character offset.
           /// A position is between two characters like an ‘insert’ cursor in a editor.
  
positive.code:                 return fsacPaths.MSBuild
          }
  
      let start (c : ExtensionContext) =
          promise {
  
  
              let ionidePluginPath = VSCodeExtension.ionidePluginPath () + "/bin_netcore/fsautocomplete.dll"
              let args =
                  [
  
negative.code:                     "--mode"
                      "lsp"
                  ] |> ResizeArray
  
              createObj [
                  "command" ==> dotnet
                  "args" ==> args
                  "transport" ==> 0
              ]
  
          let spawnNetWin () =
              let ionidePluginPath = VSCodeExtension.ionidePluginPath () + "/bin/fsautocomplete.exe"
              let args =
                  [
                      "--mode"
                      "lsp"
                  ] |> ResizeArray
  
              createObj [
                  "command" ==> ionidePluginPath
                  "args" ==> args
                  "transport" ==> 0
              ]
  
          let spawnNetMono mono =
              let ionidePluginPath = VSCodeExtension.ionidePluginPath () + "/bin/fsautocomplete.exe"
              let args =
                  [
                      ionidePluginPath
                      "--mode"
                      "lsp"
                  ] |> ResizeArray
  
              createObj [
                  "command" ==> mono
                  "args" ==> args
                  "transport" ==> 0
              ]
  
          let! mono = Environment.mono
          let! dotnet = Environment.dotnet
  
          printfn "RUNTIME: %A, MONO: %A, DOTNET: %A" targetRuntime mono dotnet
          // The matrix here is a 2x3 table: .Net/.Net Core target on one axis, Windows/Mono/Dotnet execution environment on the other
          match targetRuntime, mono, dotnet with
          // for any configuration, if the user specifies the framework to use do not suggest another framework for them
  
          // .Net framework handling
          | Types.UserSpecified Types.FSACTargetRuntime.NET, _ , _ when Environment.isWin ->
              return spawnNetWin ()
          | Types.UserSpecified Types.FSACTargetRuntime.NET, Some mono, _ ->
              return spawnNetMono mono
          | Types.UserSpecified Types.FSACTargetRuntime.NET, None, _ ->
              return! monoNotFound ()
  
          // dotnet SDK handling
          | Types.UserSpecified Types.FSACTargetRuntime.NetcoreFdd, _, Some dotnet ->
              return spawnNetCore dotnet
          | Types.UserSpecified Types.FSACTargetRuntime.NetcoreFdd, _, None ->
              return! dotnetNotFound ()
  
          // when we infer a runtime then we can suggest to the user our other options
          // .NET framework handling (looks similar to above just with suggestion)
          | Types.Implied Types.FSACTargetRuntime.NET, None, Some _dotnet when Environment.isWin ->
              suggestNetCore() |> ignore
              return spawnNetWin ()
          | Types.Implied Types.FSACTargetRuntime.NET, Some mono, Some _dotnet ->
              suggestNetCore() |> ignore
              return spawnNetMono mono
          | Types.Implied Types.FSACTargetRuntime.NET, None, Some _dotnet ->
              suggestNetCore() |> ignore
              return! monoNotFound ()
  
          // these case actually never happens right now (see the `targetRuntime` calculation above), but it's here for completeness,
          // IE a scenario in which dotnet isn't found but we have located the proper execution environment for .Net framework
          | Types.Implied Types.FSACTargetRuntime.NetcoreFdd, None, None when Environment.isWin ->
              suggestNet () |> ignore
              return! dotnetNotFound ()
          | Types.Implied Types.FSACTargetRuntime.NetcoreFdd, Some mono, None when not Environment.isWin ->
              suggestNet () |> ignore
              return! dotnetNotFound ()
  
          | runtime, mono, dotnet ->
              return failwithf "unsupported combination of runtime/mono/dotnet: %O/%O/%O" runtime mono dotnet
  
      }
  
      let readyClient (cl: LanguageClient) =
          cl.onReady ()
          |> Promise.onSuccess (fun _ ->
              cl.onNotification("fsharp/notifyWorkspace", (fun (a: Types.PlainNotification) ->
                  match Notifications.notifyWorkspaceHandler with
                  | None -> ()
                  | Some cb ->
                      let onMessage res =
                          match res?Kind |> unbox with
                          | "project" ->
                              res |> unbox<ProjectResult> |> deserializeProjectResult |> Choice1Of4 |> cb
                          | "projectLoading" ->
                              res |> unbox<ProjectLoadingResult> |> Choice2Of4 |> cb
                          | "error" ->
                              res?Data |> parseError |> Choice3Of4 |> cb
                          | "workspaceLoad" ->
                              res?Data?Status |> unbox<string> |> Choice4Of4 |> cb
                          | _ ->
                              ()
                      let res = a.content |> ofJson<obj>
                      onMessage res
              ))
          )
  
  
      let start (c : ExtensionContext) =
          promise {
  
              let! startOpts = getOptions ()
              let cl = createClient startOpts
              c.subscriptions.Add (cl.start ())
              let! _ = readyClient cl
              return ()
  
          }
  
      let stop () =
          promise {
              match client with
              | Some cl -> return! cl.stop()
              | None -> return ()
          }