anchor.diff:              | SynExpr.DotGet (e,_,_,_)
               | SynExpr.Do (e,_)
               | SynExpr.DotSet (e,_,_,_)
  -            | SynExpr.New (_,_,e,_)
               | SynExpr.Typed (e,_,_)
               | SynExpr.DotIndexedGet (e,_,_,_)
               | SynExpr.DotIndexedSet (e,_,_,_,_,_) -> yield! parseExpr e
  +            | SynExpr.New (_,_,expr,r) ->
  +                let collapse = Range.endToEnd expr.Range r
  +                yield! rcheck Scope.New Collapse.Below r collapse
  +                yield! parseExpr expr
               | SynExpr.YieldOrReturn (_,e,r) ->
  -                yield! rcheck Scope.YieldOrReturn Collapse.Below r
  +                yield! rcheck Scope.YieldOrReturn Collapse.Below r r
                   yield! parseExpr e
               | SynExpr.YieldOrReturnFrom (_,e,r) ->
  -                yield! rcheck Scope.YieldOrReturnBang Collapse.Below r
  +                yield! rcheck Scope.YieldOrReturnBang Collapse.Below r r
                   yield! parseExpr e
               | SynExpr.DoBang (e,r) ->
  -                yield! rcheck Scope.Do Collapse.Below <| Range.modStart r 3
  +                yield! rcheck Scope.Do Collapse.Below r <| Range.modStart 3 r
                   yield! parseExpr e
               | SynExpr.LetOrUseBang (_,_,_,pat,e1,e2,_) ->
                   // for `let!` or `use!` the pattern begins at the end of the keyword so that
                   // this scope can be used without adjustment if there is no `=` on the same line
                   // if there is an `=` the range will be adjusted during the tooltip creation
  -                yield! rcheck Scope.LetOrUseBang Collapse.Below <| Range.endToEnd pat.Range e1.Range
  +                let r = Range.endToEnd pat.Range e1.Range
  +                yield! rcheck Scope.LetOrUseBang Collapse.Below r r
                   yield! parseExpr e1
                   yield! parseExpr e2
               | SynExpr.For (_,_,_,_,_,e,r)
               | SynExpr.ForEach (_,_,_,_,_,e,r) ->
  -                yield! rcheck Scope.For Collapse.Below r
  +                yield! rcheck Scope.For Collapse.Below r r
                   yield! parseExpr e
  -            | SynExpr.LetOrUse (_,_,bindings, body,_) ->
  +            | SynExpr.LetOrUse (_,_,bindings, body, _) ->
                   yield! parseBindings bindings
                   yield! parseExpr body
  -            | SynExpr.Match (seqPointAtBinding,_,clauses,_,r) ->
  +            | SynExpr.Match (seqPointAtBinding,_expr,clauses,_,r) ->
                   match seqPointAtBinding with
  -                | SequencePointAtBinding pr ->
  -                    yield! rcheck Scope.Match Collapse.Below <| Range.endToEnd pr r
  +                | SequencePointAtBinding sr ->
  +                    let collapse = Range.endToEnd sr r
  +                    yield! rcheck Scope.Match Collapse.Same r collapse
                   | _ -> ()
                   yield! parseMatchClauses clauses
  -            | SynExpr.MatchLambda (_,_,clauses,_,r) ->
  -                yield! rcheck Scope.MatchLambda Collapse.Below <| Range.modStart r 8
  +            | SynExpr.MatchLambda (_,caseRange,clauses,matchSeqPoint,r) ->
  +                let caseRange =
  +                    match matchSeqPoint with
  +                    | SequencePointAtBinding r -> r
  +                    | _ -> caseRange
  +                let collapse = Range.endToEnd caseRange r
  +                yield! rcheck Scope.MatchLambda Collapse.Same r collapse
                   yield! parseMatchClauses clauses
               | SynExpr.App (atomicFlag,isInfix,funcExpr,argExpr,r) ->
                   // seq exprs, custom operators, etc
                   if ExprAtomicFlag.NonAtomic=atomicFlag && (not isInfix)
  -                   && (function | SynExpr.Ident _ -> true | _ -> false) funcExpr
  +                   && (function | SynExpr.Ident _    -> true  | _ -> false) funcExpr
  +                   && (function | SynExpr.CompExpr _ -> false | _ -> true ) argExpr then
                      // if the argExrp is a computation expression another match will handle the outlining
                      // these cases must be removed to prevent creating unnecessary tags for the same scope
  -                   && (function | SynExpr.CompExpr _ -> false | _ -> true) argExpr then
  -                        yield! rcheck Scope.SpecialFunc Collapse.Below <| Range.endToEnd funcExpr.Range r
  +                    let collapse = Range.endToEnd funcExpr.Range r
  +                    yield! rcheck Scope.SpecialFunc Collapse.Below r collapse
  +                elif ExprAtomicFlag.NonAtomic=atomicFlag && (not isInfix)
  +                   && (function | SynExpr.CompExpr _ -> true | _ -> false) argExpr then
  +                        let collapse = Range.startToEnd argExpr.Range r
  +                        yield! rcheck Scope.CompExpr Collapse.Same r <| Range.modBoth 1 1 collapse
                   yield! parseExpr argExpr
                   yield! parseExpr funcExpr
               | SynExpr.Sequential (_,_,e1,e2,_) ->
                   yield! parseExpr e1
                   yield! parseExpr e2
               | SynExpr.ArrayOrListOfSeqExpr (isArray,e,r) ->
  -                yield! rcheck  Scope.ArrayOrList Collapse.Same <| Range.modBoth r (if isArray then 2 else 1) (if isArray then 2 else 1)
  +                yield! rcheck  Scope.ArrayOrList Collapse.Same r <| Range.modBoth (if isArray then 2 else 1) (if isArray then 2 else 1) r
                   yield! parseExpr e
  -            | SynExpr.CompExpr (arrayOrList,_,e,r) ->
  -                if arrayOrList then
  -                    yield! parseExpr e
  -                else  // exclude the opening { and closing } on the cexpr from collapsing
  -                    yield! rcheck Scope.CompExpr Collapse.Same <| Range.modBoth r 1 1
  +            | SynExpr.CompExpr (_arrayOrList,_,e,_r) as _c ->
                   yield! parseExpr e
  -            | SynExpr.ObjExpr (_,_,bindings,_,newRange,wholeRange) ->
  -                let r = mkFileIndexRange newRange.FileIndex newRange.End (Range.mkPos wholeRange.EndLine (wholeRange.EndColumn - 1))
  -                yield! rcheck Scope.ObjExpr Collapse.Below r
  +            | SynExpr.ObjExpr (_,argOpt,bindings,extraImpls,newRange,wholeRange) as _objExpr ->
  +                match argOpt with
  +                | Some (args,_) ->
  +                    let collapse = Range.endToEnd args.Range wholeRange
  +                    yield! rcheck Scope.ObjExpr Collapse.Below wholeRange collapse
  +                | None ->
  +                    let collapse = Range.endToEnd newRange wholeRange
  +                    yield! rcheck Scope.ObjExpr Collapse.Below wholeRange collapse
                   yield! parseBindings bindings
  -            | SynExpr.TryWith (e,_,matchClauses,tryRange,withRange,tryPoint,withPoint) ->
  -                match tryPoint with
  -                | SequencePointAtTry r ->
  -                    yield! rcheck Scope.TryWith Collapse.Below <| Range.endToEnd r tryRange
  -                | _ -> ()
  -                match withPoint with
  -                | SequencePointAtWith r ->
  -                    yield! rcheck Scope.WithInTryWith Collapse.Below <| Range.endToEnd r withRange
  +                yield! parseExprInterfaces extraImpls
  +            | SynExpr.TryWith (e,_tryRange,matchClauses,_withRange,wholeRange,tryPoint,withPoint) ->
  +                match tryPoint, withPoint with
  +                | SequencePointAtTry tryRange,  SequencePointAtWith withRange ->
  +                    let fullrange = Range.startToEnd tryRange wholeRange
  +                    let collapse = Range.endToEnd tryRange wholeRange
  +                    let collapseTry = Range.endToStart tryRange withRange
  +                    let fullrangeTry = Range.startToStart tryRange withRange
  +                    let collapseWith = Range.endToEnd withRange wholeRange
  +                    let fullrangeWith = Range.startToEnd withRange wholeRange
  +                    yield! rcheck Scope.TryWith Collapse.Below fullrange collapse
  +                    yield! rcheck Scope.TryInTryWith Collapse.Below fullrangeTry collapseTry
  +                    yield! rcheck Scope.WithInTryWith Collapse.Below fullrangeWith collapseWith
                   | _ -> ()
                   yield! parseExpr e
                   yield! parseMatchClauses matchClauses
  -            | SynExpr.TryFinally (tryExpr,finallyExpr,r,tryPoint,finallyPoint) ->
  -                match tryPoint with
  -                | SequencePointAtTry tryRange ->
  -                    yield! rcheck Scope.TryFinally Collapse.Below <| Range.endToEnd tryRange r
  -                | _ -> ()
  -                match finallyPoint with
  -                | SequencePointAtFinally finallyRange ->
  -                    yield! rcheck  Scope.FinallyInTryFinally Collapse.Below <| Range.endToEnd finallyRange r
  +            | SynExpr.TryFinally (tryExpr,finallyExpr,r,tryPoint,finallyPoint) as _tryFinally ->
  +                match tryPoint, finallyPoint with
  +                | SequencePointAtTry tryRange, SequencePointAtFinally finallyRange ->
  +                    let collapse = Range.endToEnd tryRange finallyExpr.Range
  +                    let fullrange = Range.startToEnd tryRange finallyExpr.Range
  +                    let collapseFinally = Range.endToEnd finallyRange r
  +                    let fullrangeFinally = Range.startToEnd finallyRange r
  +                    yield! rcheck Scope.TryFinally Collapse.Below fullrange collapse
  +                    yield! rcheck  Scope.FinallyInTryFinally Collapse.Below fullrangeFinally collapseFinally
                   | _ -> ()
                   yield! parseExpr tryExpr
                   yield! parseExpr finallyExpr
  -            | SynExpr.IfThenElse (e1,e2,e3,seqPointInfo,_,_,r) ->
  -                // Outline the entire IfThenElse
  -                yield! rcheck Scope.IfThenElse Collapse.Below r
  -                // Outline the `then` scope
  -                match seqPointInfo with
  +            | SynExpr.IfThenElse (ifExpr,thenExpr,elseExprOpt,spIfToThen,_,ifToThenRange,r) as _ifThenElse->
  +                match spIfToThen with
                   | SequencePointInfoForBinding.SequencePointAtBinding rt ->
  -                    yield! rcheck  Scope.ThenInIfThenElse Collapse.Below <| Range.endToEnd rt e2.Range
  +                    // Outline the entire IfThenElse
  +                    let fullrange = Range.startToEnd rt r
  +                    let collapse = Range.endToEnd  ifExpr.Range r
  +                    yield! rcheck Scope.IfThenElse Collapse.Below fullrange collapse
  +                    // Outline the `then` scope
  +                    let thenRange = Range.endToEnd (Range.modEnd -4  ifToThenRange)   thenExpr.Range
  +                    let thenCollapse = Range.endToEnd ifToThenRange thenExpr.Range
  +                    yield! rcheck Scope.ThenInIfThenElse Collapse.Below thenRange thenCollapse
                   | _ -> ()
  -                yield! parseExpr e1
  -                yield! parseExpr e2
  -                match e3 with
  -                | Some e ->
  -                    match e with // prevent double collapsing on elifs
  -                    | SynExpr.IfThenElse (_,_,_,_,_,_,_) ->
  -                        yield! parseExpr e
  +                yield! parseExpr ifExpr
  +                yield! parseExpr thenExpr
  +                match elseExprOpt with
  +                | Some elseExpr ->
  +                    match elseExpr with // prevent double collapsing on elifs
  +                    | SynExpr. IfThenElse (_,_,_,_,_,_,_) ->
  +                        yield! parseExpr elseExpr
                       | _ ->
  -                        yield! rcheck Scope.ElseInIfThenElse Collapse.Same e.Range
  -                        yield! parseExpr e
  +                        // This is not the best way to establish the position of `else`
  +                        // the AST doesn't provide an easy way to find the position of the keyword
  +                        // as such `else` will be left out of block structuring and outlining until a
  +                        // a suitable approach is determined
  +                        yield! parseExpr elseExpr
                   | None -> ()
               | SynExpr.While (_,_,e,r) ->
  -                yield! rcheck Scope.While Collapse.Below  r
  +                yield! rcheck Scope.While Collapse.Below r r
                   yield! parseExpr e
               | SynExpr.Lambda (_,_,pats,e,r) ->
                   match pats with
                   | SynSimplePats.SimplePats (_,pr)
                   | SynSimplePats.Typed (_,_,pr) ->
  -                    yield! rcheck Scope.Lambda Collapse.Below <| Range.endToEnd pr r
  +                    yield! rcheck Scope.Lambda Collapse.Below r <| Range.endToEnd pr r
                   yield! parseExpr e
               | SynExpr.Lazy (e,r) ->
  -                yield! rcheck Scope.SpecialFunc Collapse.Below r
  +                yield! rcheck Scope.SpecialFunc Collapse.Below r r
                   yield! parseExpr e
               | SynExpr.Quote (_,isRaw,e,_,r) ->
                   // subtract columns so the @@> or @> is not collapsed
  -                yield! rcheck Scope.Quote Collapse.Same <| Range.modBoth r (if isRaw then 3 else 2) (if isRaw then 3 else 2)
  +                yield! rcheck Scope.Quote Collapse.Same r <| Range.modBoth (if isRaw then 3 else 2) (if isRaw then 3 else 2) r
                   yield! parseExpr e
  -            | SynExpr.Tuple (es,_,r) ->
  -                yield! rcheck Scope.Tuple Collapse.Same r
  +            | SynExpr.Tuple (es,_,r)
  +            | SynExpr.StructTuple(es,_,r) ->
  +                yield! rcheck Scope.Tuple Collapse.Same r r
                   yield! Seq.collect parseExpr es
               | SynExpr.Paren (e,_,_,_) ->
                   yield! parseExpr e
  
positive.code:                     yield! parseExpr e
                  yield! recordFields |> (Seq.choose (fun (_,e,_) -> e) >> Seq.collect parseExpr)
                  // exclude the opening `{` and closing `}` of the record from collapsing
                  yield! rcheck Scope.Record Collapse.Same <| Range.modBoth r 1 1
              | _ -> ()
          }
  
      and private parseMatchClause (SynMatchClause.Clause (synPat,_,e,_,_)) =
          seq { yield! rcheck Scope.MatchClause Collapse.Same <| Range.startToEnd synPat.Range e.Range  // Collapse the scope after `->`
                yield! parseExpr e }
  
      and private parseMatchClauses = Seq.collect parseMatchClause
  
  
negative.code:             let endCol = endStr.TrimEnd().Length
  
              let scopeType =
                  match comment.Type with
                  | SingleLine -> Scope.Comment
                  | XmlDoc -> Scope.XmlDocComment
  
              let range = Range.mkRange "" (Range.mkPos (startLine + 1) startCol) (Range.mkPos (endLine + 1) endCol)
  
              { Scope = scopeType
                Collapse = Collapse.Same
                Range = range
                CollapseRange = range })
  
  
        //=======================================//
       //     Signature File AST Traversal      //
      //=======================================//
  
      (*
          The following helper functions are necessary due to a bug in the Parsed UAST within a 
          signature file that causes the scopes to extend past the end of the construct and overlap
          with the following construct. This necessitates inspecting the children of the construct and
          finding the end of the last child's range to use instead.
  
          Detailed further in - https://github.com/Microsoft/visualfsharp/issues/2094
      *)
  
      let lastMemberSigRangeElse r memberSigs =
          match memberSigs with
          | [] -> r
          | ls ->
              match List.last ls with
              | SynMemberSig.Inherit (range=r)
              | SynMemberSig.Interface (range=r)
              | SynMemberSig.Member (range=r)
              | SynMemberSig.NestedType (range=r)
              | SynMemberSig.ValField (range=r) -> r
  
      let lastTypeDefnSigRangeElse range (typeSigs:SynTypeDefnSig list) =
          match typeSigs with
          | [] -> range
          | ls ->
              let (SynTypeDefnSig.TypeDefnSig(_,_,memberSigs,r)) = List.last ls
              lastMemberSigRangeElse r memberSigs
  
      let lastModuleSigDeclRangeElse range (sigDecls:SynModuleSigDecls) =
          match sigDecls with
          | [] -> range
          | ls -> match List.last ls with
                  | SynModuleSigDecl.Types (typeSigs,r) -> lastTypeDefnSigRangeElse r typeSigs
                  | SynModuleSigDecl.Val (ValSpfn(range=r),_) -> r
                  | SynModuleSigDecl.Exception(_,r) -> r
                  | SynModuleSigDecl.Open(_,r)-> r
                  | SynModuleSigDecl.ModuleAbbrev(_,_,r)-> r
                  | _ -> range
  
  
      let rec private parseSynMemberDefnSig (dsig:SynMemberSig) =
          seq {
              match dsig with
              | SynMemberSig.Member(valSigs,_flags,r) ->
                  let collapse = Range.endToEnd valSigs.RangeOfId r
                  yield! rcheck Scope.Member Collapse.Below r collapse
              | SynMemberSig.ValField(Field(attrs,_a,_b,_c,_d,_e,_,fr),fullrange) ->
                  let collapse = Range.endToEnd fr fullrange
                  yield! rcheck Scope.Val Collapse.Below fullrange collapse
                  yield! parseAttributes attrs
              | SynMemberSig.Interface(tp,r) ->
                  yield! rcheck Scope.Interface Collapse.Below r <| Range.endToEnd tp.Range r
              | SynMemberSig.NestedType (typeDefSig, _r) ->
                  yield! parseTypeDefnSig typeDefSig
              | _ -> ()
          }
  
  
      and private parseTypeDefnSig
        (TypeDefnSig (SynComponentInfo.ComponentInfo(attribs,typeArgs,_constraints,longId,_doc,_b,_access,r)
                  as _componentInfo, objectModel,  memberSigs, _)) = seq {
              yield! parseAttributes attribs
  
              let makeRanges memberSigs =
                  let typeArgsRange = rangeOfTypeArgsElse r typeArgs
                  let rangeEnd = lastMemberSigRangeElse r memberSigs
                  let collapse = Range.endToEnd (Range.modEnd 1 typeArgsRange) rangeEnd
                  let fullrange = Range.startToEnd (longIdentRange longId) rangeEnd
                  fullrange, collapse
  
              yield! Seq.collect parseSynMemberDefnSig memberSigs
              match objectModel with
              // matches against a type declaration with <'T,...> and (args,...)
              | SynTypeDefnSigRepr.ObjectModel
                  (SynTypeDefnKind.TyconUnspecified,objMembers,_r) ->
                      yield! Seq.collect parseSynMemberDefnSig objMembers
                      let fullrange,collapse = makeRanges objMembers
                      yield! rcheck Scope.Type Collapse.Below fullrange collapse
              | SynTypeDefnSigRepr.ObjectModel
                  (SynTypeDefnKind.TyconAugmentation , objMembers, _) ->
                      let fullrange,collapse = makeRanges objMembers
                      yield! rcheck Scope.TypeExtension Collapse.Below fullrange collapse
                      yield! Seq.collect parseSynMemberDefnSig objMembers
              | SynTypeDefnSigRepr.ObjectModel
                  (_ , objMembers, _) ->
                      let fullrange,collapse = makeRanges objMembers
                      yield! rcheck Scope.Type Collapse.Below fullrange collapse
                      yield! Seq.collect parseSynMemberDefnSig objMembers
                  // visit the members of a type extension
              | SynTypeDefnSigRepr.Simple (simpleRepr,_r) ->
                  let fullrange,collapse = makeRanges memberSigs
                  yield! rcheck Scope.Type Collapse.Below fullrange collapse
                  yield! parseSimpleRepr simpleRepr
              | SynTypeDefnSigRepr.Exception _ -> ()
          }
  
  
      let private getConsecutiveSigModuleDecls (predicate: SynModuleSigDecl -> range option) (scope:Scope) (decls: SynModuleSigDecls) =
          let groupConsecutiveSigDecls input =
              let rec loop (input: range list) (res: range list list) currentBulk =
                  match input, currentBulk with
                  | [], [] -> List.rev res
                  | [], _ -> List.rev (currentBulk::res)
                  | r :: rest, [] -> loop rest res [r]
                  | r :: rest, last :: _ when r.StartLine = last.EndLine + 1 ->
                      loop rest res (r::currentBulk)
                  | r :: rest, _ -> loop rest (currentBulk::res) [r]
              loop input [] []
  
  
          let selectSigRanges (ranges: range list) =
              match ranges with
              | [] -> None
              | [r] when r.StartLine = r.EndLine -> None
              | [r] ->
                  let range = Range.mkRange "" r.Start r.End
                  Some { Scope = scope; Collapse = Collapse.Same; Range = range ; CollapseRange = range }
              | lastRange :: rest ->
                  let firstRange = Seq.last rest
                  let range = Range.mkRange "" firstRange.Start lastRange.End
                  Some { Scope = scope; Collapse = Collapse.Same; Range = range; CollapseRange = range }
  
          decls |> (List.choose predicate >> groupConsecutiveSigDecls >> List.choose selectSigRanges)
  
  
      let collectSigHashDirectives (decls: SynModuleSigDecls) =
          decls
          |> getConsecutiveSigModuleDecls(
              function
              | SynModuleSigDecl.HashDirective (ParsedHashDirective (directive, _, _),r) ->
                  let prefixLength = "#".Length + directive.Length + " ".Length
                  Some (Range.mkRange "" (Range.mkPos r.StartLine prefixLength) r.End)
              | _ -> None) Scope.HashDirective
  
  
      let collectSigOpens = getConsecutiveSigModuleDecls (function SynModuleSigDecl.Open (_,r) -> Some r | _ -> None) Scope.Open
  
      let rec private parseModuleSigDeclaration (decl: SynModuleSigDecl) =
          seq {
              match decl with
              | SynModuleSigDecl.Val ((ValSpfn(attrs,ident,_valdecls,_,_,_,_,_,_,_,valrange)),_r) ->
                  let collapse = Range.endToEnd  ident.idRange valrange
                  yield! rcheck Scope.Val Collapse.Below _r collapse
                  yield! parseAttributes attrs
              | SynModuleSigDecl.Types (typeSigs,_r) ->
                  yield! Seq.collect parseTypeDefnSig typeSigs
              // Fold the attributes above a module
              | SynModuleSigDecl.NestedModule (SynComponentInfo.ComponentInfo (attrs,_,_,_,_,_,_,cmpRange),_, decls,moduleRange) ->
                  let rangeEnd = lastModuleSigDeclRangeElse moduleRange decls
                  // Outline the full scope of the module
                  let collapse = Range.endToEnd cmpRange rangeEnd
                  let fullrange = Range.startToEnd moduleRange rangeEnd
                  yield! rcheck Scope.Module Collapse.Below fullrange collapse
                  // A module's component info stores the ranges of its attributes
                  yield! parseAttributes attrs
                  yield! collectSigOpens decls
                  yield! Seq.collect parseModuleSigDeclaration decls
              | _ -> ()
          }
  
      let private parseModuleOrNamespaceSigs moduleOrNamespaceSig =
          seq {
              let (SynModuleOrNamespaceSig.SynModuleOrNamespaceSig(longId,_,isModule,decls,_,attribs,_,r)) =  moduleOrNamespaceSig
              yield! parseAttributes attribs
              let rangeEnd = lastModuleSigDeclRangeElse r decls
              let idrange = longIdentRange longId
              let fullrange = Range.startToEnd idrange rangeEnd
              let collapse = Range.endToEnd idrange rangeEnd
              if isModule then
                  yield! rcheck Scope.Module Collapse.Below fullrange collapse
  
              yield! collectSigHashDirectives decls
              yield! collectSigOpens decls
              yield! Seq.collect parseModuleSigDeclaration decls
          }
  
      let getOutliningRanges (sourceLines: string []) (parsedInput: ParsedInput) =
          match parsedInput with
          | ParsedInput.ImplFile (ParsedImplFileInput (_,_,_,_,_,modules,_)) ->
              let astBasedRanges = Seq.collect parseModuleOrNamespace modules
              let commentRanges = getCommentRanges sourceLines
              Seq.append astBasedRanges commentRanges
          | ParsedInput.SigFile (ParsedSigFileInput (_,_,_,_,moduleSigs)) ->
              let astBasedRanges = Seq.collect parseModuleOrNamespaceSigs moduleSigs
              let commentRanges = getCommentRanges sourceLines
              Seq.append astBasedRanges commentRanges
  
  module Printf =
      [<NoComparison>]
  