anchor.diff:              | _, _ -> loop dirInfo.Parent
           loop dirInfo :> _ seq
   
  +    override __.CanOpenDocuments = true
  +    override __.CanApplyChange _ = true
  +
  +
  +    member self.AddProject projectInfo =
  +        checkNullArg projectInfo "projectInfo"
  +        base.OnProjectAdded projectInfo
  +        base.UpdateReferencesAfterAdd ()
  +        self.CurrentSolution.GetProject projectInfo.Id
  +
  +//    /// Adds a project to the workspace. All previous projects remain intact.
  +//    member self.AddProject(name : string) =
  +//        ProjectInfo.Create(ProjectId.CreateNewId(), VersionStamp.Create(), name, name, "FSharp")
  +//        |> self.AddProject
  +
  +    /// Adds multiple projects to the workspace at once. All existing projects remain intact.
  +    member self.AddProjects (projectInfos: _ seq) =
  +        checkNullArg projectInfos "projectInfos"
  +        for info in projectInfos do
  +            self.OnProjectAdded info
  +        base.UpdateReferencesAfterAdd ()
  +
  +
  +    /// Adds an entire solution to the workspace, replacing any existing solution.
  +    member self.AddSolutionInfo (solutionInfo:SolutionInfo) =
  +        checkNullArg solutionInfo "solutionInfo"
  +        base.OnSolutionAdded solutionInfo
  +        base.UpdateReferencesAfterAdd()
  +        self.CurrentSolution
  +
  +
  +//    /// Adds an entire solution to the workspace, replacing any existing solution.
  +//    member self.AddSolution (solution:Solution) =
  +//        checkNullArg solution "solution"
  +//        let fn (arg:WorkspaceChangeEventArgs) =
  +//            arg.
  +//        base.OnSolutionAdded solution
  +//        base.UpdateReferencesAfterAdd()
  +//        self.CurrentSolution
  +
  +
  +
  +    member __.AddProjectReference (projectId, projectReference) =
  +        base.OnProjectReferenceAdded (projectId, projectReference)
  +
  +
  +    member __.AddMetadataReference (projectId, metadataReference) =
  +        base.OnMetadataReferenceAdded (projectId, metadataReference)
  +
  +
  +    member __.RemoveMetadataReference (projectId, metadataReference) =
  +        base.OnMetadataReferenceRemoved (projectId, metadataReference)
  +
  +
  +    member __.RemoveProject projectId = base.OnProjectRemoved projectId
  +
  +    member __.SetCompilationOptions (projectId, options) = base.OnCompilationOptionsChanged(projectId, options)
  +
  +    member __.SetParseOptions (projectId, parseOptions) = base.OnParseOptionsChanged(projectId, parseOptions)
  +
  +
  +    /// Adds a document to the workspace.
  +    member self.AddDocument (documentInfo:DocumentInfo) =
  +        checkNullArg documentInfo "documentInfo"
  +        base.OnDocumentAdded documentInfo
  +        self.CurrentSolution.GetDocument documentInfo.Id
  +
  +    /// Adds a document to a project in the workspace.
  +    member __.AddDocument (projectId:ProjectId, name:string, text:SourceText) =
  +        checkNullArg projectId "projectId"
  +        checkNullArg name "name"
  +        checkNullArg text "text"
  +        let docInfo = 
  +            DocumentInfo.Create(
  +                DocumentId.CreateNewId projectId, name,
  +                loader = TextLoader.From ^ TextAndVersion.Create (text, VersionStamp.Create ())
  +            )
  +        base.OnDocumentAdded docInfo
  +
  +
  +    member __.RemoveDocument documentId = base.OnDocumentRemoved documentId
  +
  +    /// Puts the specified document into the open state.
  +    override __.OpenDocument (docId, activate) =
  +        let doc = base.CurrentSolution.GetDocument docId
  +        if isNull doc then ()
  +        else
  +            let task = doc.GetTextAsync CancellationToken.None
  +            task.Wait CancellationToken.None
  +            let text = task.Result
  +            base.OnDocumentOpened (docId, text.Container, activate)
  +
  +
  +    
  +
  +    /// Puts the specified document into the closed state.
  +    override __.CloseDocument docId =
  +        let doc = base.CurrentSolution.GetDocument docId
  +        if isNull doc then ()
  +        else
  +            let task = doc.GetTextAsync CancellationToken.None
  +            task.Wait CancellationToken.None
  +            let text = task.Result
  +            let versionTask = doc.GetTextVersionAsync CancellationToken.None
  +            versionTask.Wait CancellationToken.None
  +            let version = versionTask.Result
  +            let loader = TextLoader.From ^ TextAndVersion.Create(text, version, doc.FilePath)
  +            base.OnDocumentClosed (docId, loader)
  +
  +
  +    override __.OnDocumentTextChanged (doc:Document) =
  +        let time = DateTime.UtcNow
  +        documentTimeStamps.AddOrUpdate(doc.Id,time,(fun _docId _lastTime -> time)) |> ignore
  +        base.OnDocumentTextChanged doc
  +        
  +
  +    member __.OnDocumentChanged (documentId, text) =
  +        base.OnDocumentTextChanged (documentId, text, PreservationMode.PreserveIdentity)
  +
  +
  +    member __.TryGetDocumentId filePath =
  +        let documentIds = base.CurrentSolution.GetDocumentIdsWithFilePath filePath
  +        match documentIds.FirstOrDefault () with
  +        | null -> None
  +        | docId -> Some docId
  +
  +
  +    member self.GetDocuments filePath =
  +        base.CurrentSolution.GetDocumentIdsWithFilePath(filePath)
  +            .Select(fun docId -> self.CurrentSolution.GetDocument docId)
  +
  +
  +    member self.TryGetDocument filePath =
  +        self.TryGetDocumentId filePath |> Option.map (fun docId -> self.CurrentSolution.GetDocument docId)
  +
  +
  +    member self.GetLastWriteTime docId =
  +        match documentTimeStamps.TryGetValue docId with
  +        | true, time -> Some time | _ -> None
  +
   
       interface IDisposable with
  -        member __.Dispose() =
  +        member __.Dispose () =
               subscriptions |> Seq.iter dispose
               subscriptions.Clear ()
   
  
positive.code:             let docIds = documents |> List.map ^ fun doc -> doc.Id
              transientDocuments.TryAdd (fileName, docIds) |> ignore
              transientDocumentIds.UnionWith docIds
          documents |> List.iter ^ fun doc -> workspace.AddDocument doc |> ignore
          true
  
      member __.ApplyTextChanges (docId:DocumentId) (textChanges:LinePositionSpanTextChange seq) = async {
          if Seq.isEmpty textChanges then return () else
          match workspace.CurrentSolution.TryGetDocument docId with
          | Some doc ->
              let! (sourceText:SourceText) = doc.GetTextAsync ()
              let sourceText =
  
negative.code:                     sourceText.WithChanges [| 
                          TextChange (TextSpan (startOffset, endOffset - startOffset), bufferChange.NewText) 
                      |]
                  self.OnDocumentChanged (docId, sourceText)
          else
              tryAddTransientDocument bufferChange.FileName bufferChange.NewText |> ignore
      }
  
      member self.OnWorkspaceChanged (args:WorkspaceChangeEventArgs) =
          let filename =
              match args.Kind with
              | WorkspaceChangeKind.DocumentAdded   -> (args.NewSolution.GetDocument args.DocumentId).FilePath
  