anchor.diff:              projectContext.AddSourceFile(fileName)
               
               let project = projectContext :?> AbstractProject
  -            let documentId = project.GetCurrentDocumentFromPath(fileName).Id
  -
  -            let rec onDocumentClosed = EventHandler<DocumentEventArgs> (fun _ args ->
  -                if args.Document.Id = documentId then
  -                    projectInfoManager.RemoveSingleFileProject(projectId)
  -                    project.Disconnect()
  -                    workspace.DocumentClosed.RemoveHandler(onDocumentClosed)
  -            )
  -            workspace.DocumentClosed.AddHandler(onDocumentClosed)
  +            singleFileProjects.[projectId] <- project
   
       override this.ContentTypeName = FSharpCommonConstants.FSharpContentTypeName
       override this.LanguageName = FSharpCommonConstants.FSharpLanguageName
  
positive.code:           with ex -> 
              Assert.Exception(ex)
              return None
          else return this.TryGetOptionsForProject(projectId) 
       }
  
      /// Get the options for a document or project relevant for syntax processing.
      /// Quicker then TryGetOptionsForDocumentOrProject as it doesn't need to recompute the exact project options for a script.
      member this.TryGetOptionsForEditingDocumentOrProject(document: Document) = 
          let projectId = document.Project.Id
          if singleFileProjectTable.ContainsKey(projectId) then 
              let _loadTime, originalOptions = singleFileProjectTable.[projectId]
              Some originalOptions
          else 
              this.TryGetOptionsForProject(projectId) 
  
  // Used to expose FSharpChecker/ProjectInfo manager to diagnostic providers
  // Diagnostic providers can be executed in environment that does not use MEF so they can rely only
  
negative.code:     internal FSharpLanguageService(package : FSharpPackage) =
      inherit AbstractLanguageService<FSharpPackage, FSharpLanguageService>(package)
  
      let projectInfoManager = package.ComponentModel.DefaultExportProvider.GetExport<ProjectInfoManager>().Value
  
      let projectDisplayNameOf projectFileName = 
          if String.IsNullOrWhiteSpace projectFileName then projectFileName
          else Path.GetFileNameWithoutExtension projectFileName
  
      let singleFileProjects = ConcurrentDictionary<_, AbstractProject>()
  
      let tryRemoveSingleFileProject projectId =
          match singleFileProjects.TryRemove(projectId) with
          | true, project ->
              projectInfoManager.RemoveSingleFileProject(projectId)
              project.Disconnect()
          | _ -> ()
  
      override this.Initialize() =
          base.Initialize()
  
          this.Workspace.Options <- this.Workspace.Options.WithChangedOption(Completion.CompletionOptions.BlockForCompletionItems, FSharpCommonConstants.FSharpLanguageName, false)
          this.Workspace.Options <- this.Workspace.Options.WithChangedOption(Shared.Options.ServiceFeatureOnOffOptions.ClosedFileDiagnostic, FSharpCommonConstants.FSharpLanguageName, Nullable false)
  
          this.Workspace.DocumentClosed.Add <| fun args ->
              tryRemoveSingleFileProject args.Document.Project.Id 
              
          Events.SolutionEvents.OnAfterCloseSolution.Add <| fun _ ->
              singleFileProjects.Keys |> Seq.iter tryRemoveSingleFileProject
  
          let ctx = System.Threading.SynchronizationContext.Current
          
          let rec setupProjectsAfterSolutionOpen() =
              async {
                  use openedProjects = MailboxProcessor.Start <| fun inbox ->
                      async { 
                          // waits for AfterOpenSolution and then starts projects setup
                          do! Async.AwaitEvent Events.SolutionEvents.OnAfterOpenSolution |> Async.Ignore
                          while true do
                              let! siteProvider = inbox.Receive()
                              do! Async.SwitchToContext ctx
                              this.SetupProjectFile(siteProvider, this.Workspace) }
  
                  use _ = Events.SolutionEvents.OnAfterOpenProject |> Observable.subscribe ( fun args ->
                      match args.Hierarchy with
                      | :? IProvideProjectSite as siteProvider -> openedProjects.Post(siteProvider)
                      | _ -> () )
  
                  do! Async.AwaitEvent Events.SolutionEvents.OnAfterCloseSolution |> Async.Ignore
                  do! setupProjectsAfterSolutionOpen() 
              }
          setupProjectsAfterSolutionOpen() |> Async.StartImmediate
          
      /// Sync the information for the project 
      member this.SyncProject(project: AbstractProject, projectContext: IWorkspaceProjectContext, site: IProjectSite, forceUpdate) =
        async {
          let hashSetIgnoreCase x = new HashSet<string>(x, StringComparer.OrdinalIgnoreCase)
          let updatedFiles = site.SourceFilesOnDisk() |> hashSetIgnoreCase
          let workspaceFiles = project.GetCurrentDocuments() |> Seq.map(fun file -> file.FilePath) |> hashSetIgnoreCase
  