anchor.diff:  
           // returns `true` if both first and last spans are still here, which means
           // that new spans are not produced from partially valid source file.
  -        let areFirstAndLastSpansNotChanged() =
  +        let haveFirstAndLastSpansNotChanged() =
               let sameWordSpan x y =
                   x.SymbolKind = y.SymbolKind
                   && x.StartCol = y.StartCol
                   && x.EndCol = y.EndCol
               match newTcSpans, oldTcSpans with
  -            | [||], [||] -> false
  -            | _, [||] | [||], _ -> true
  +            | [||], [||] -> true
  +            | _, [||] | [||], _ -> false
               | x, y ->
                   sameWordSpan x.[0].ColumnSpan.WordSpan y.[0].ColumnSpan.WordSpan
                   && sameWordSpan x.[x.Length - 1].ColumnSpan.WordSpan y.[y.Length - 1].ColumnSpan.WordSpan
   
  -        if isNewRangeLarger || areFirstAndLastSpansNotChanged() then
  -            debug "[SyntaxConstructClassifier] Replace spans entirely."
  -            Logging.logInfo (fun _ -> "[SyntaxConstructClassifier] Replace spans entirely.")
  +        if isNewRangeLarger then
  +            debug "[SyntaxConstructClassifier] Replace spans entirely because new span range are wider than old one (old lines = %d..%d, new lines = %d..%d)" 
  +                  oldStartLine oldEndLine newStartLine newEndLine
  +            Logging.logInfo (fun _ -> 
  +                sprintf "[SyntaxConstructClassifier] Replace spans entirely because new span range are wider than old one (old lines = %d..%d, new lines = %d..%d)." 
  +                        oldStartLine oldEndLine newStartLine newEndLine)
  +            newSpans
  +        elif haveFirstAndLastSpansNotChanged() then
  +            debug "[SyntaxConstructClassifier] Replace spans entirely because first and last spans have not changed."
  +            Logging.logInfo (fun _ -> "[SyntaxConstructClassifier] Replace spans entirely because first and last spans have not changed.")
               newSpans
           else
               debug "[SyntaxConstructClassifier] Merging spans (new range %A < old range %A)."
  
positive.code: 
                  let! checkResults = pf.Time "parseFileInProject" <| fun _ ->
                      vsLanguageService.ParseAndCheckFileInProject(textDocument.FilePath, snapshot.GetText(), project) |> liftAsync
  
                  let! ast = checkResults.GetUntypedAst()
                  do! checkAst "Slow stage" ast
  
  
negative.code: 
  [<Sealed>]
  type private CategorizedSnapshotSpan (columnSpan: CategorizedColumnSpan<ITextSnapshot>, originalSnapshot: ITextSnapshot) =
      let snapshotSpan: SnapshotSpan option Atom = Atom None 
      member __.ColumnSpan = columnSpan
      member __.GetSnapshotSpan targetSnapshot =
          snapshotSpan.Swap (fun oldSpan ->
              oldSpan
              |> Option.orTry (fun _ -> fromRange originalSnapshot (columnSpan.WordSpan.ToRange()))
              |> Option.map (fun span ->
                  if span.Snapshot <> targetSnapshot then
                      span.TranslateTo(targetSnapshot, SpanTrackingMode.EdgeExclusive)
                  else span)) 
          |> ignore
          snapshotSpan.Value
  
  [<NoComparison>]
  type private FastStageData =
      { Snapshot: ITextSnapshot
        Spans: CategorizedSnapshotSpan[]
        SingleSymbolsProjects: CheckingProject list } 
  
  [<NoComparison>]
  type private FastStage =
  