anchor.diff:  open Microsoft.FSharp.Compiler.Ast
   open FSharpRefactor.Engine.Ast
   open FSharpRefactor.Engine.CodeAnalysis
  +open FSharpRefactor.Engine.CodeTransforms
   
   type ScopeTree =
       | Declaration of (string * range) list * ScopeTree list
       | Usage of string * range
   
  +let isDeclared (name : string) (identifiers : (string * range) list) =
  +    List.exists (fun (n,_) -> n = name) identifiers
  +
  +let rangeOfIdent (name : string) (identifiers : (string * range) list) =
  +    let identifier = List.tryFind (fun (n,_) -> n = name) identifiers
  +    if Option.isNone identifier then None else Some(snd identifier.Value)
  +    
   let rec getDeclarations p =
       match p with
           | CodeAnalysis.Declaration(text, range) -> [(text, range)]
  
positive.code:         match trees with
              | [] -> None
              | Usage(_,_)::ds -> findDeclarationInScopeTrees ds
              | Declaration(vs, ts)::ds ->
                  let isDeclaration = (fun (n,r) -> n = name && rangeContainsRange r declarationRange)
                  if List.exists isDeclaration vs then Some(Declaration(vs, ts))
                  else findDeclarationInScopeTrees ds
  
      // Check if targetName is free in tree
  
negative.code:     let rec isFree (onDeclarationFun : ScopeTree -> bool) targetName tree =
          match tree with
              | Usage(n,_) -> n <> targetName
              | Declaration(is, ts) ->
                  if isDeclared targetName is
                  then onDeclarationFun (Declaration(is, ts))
                  else List.fold (fun state t -> state && isFree onDeclarationFun targetName t) true ts
  
      let declarationScope = findDeclarationInScopeTrees (makeScopeTree tree)
      if Option.isSome declarationScope
      then isFree (isFree (fun _ -> true) name) newName declarationScope.Value else false
  
  //TODO: make some generic tree walking function which can be used for most of this
  let DoRename source (tree: Ast.AstNode) (name : string, declarationRange : range) (newName : string) =
      let isNestedDeclaration idents =
          List.exists (fun (n,r) -> n = name && not (rangeContainsRange r declarationRange)) idents
      let rec rangesToReplace tree =
          match tree with
              | Usage(n, r) -> if n = name then [r] else []
              | Declaration(is, ts) ->
                  if isNestedDeclaration is then []
                  else
                      let declarationRange = rangeOfIdent name is
                      let remainingRanges = List.concat (Seq.map rangesToReplace ts)
                      if Option.isSome declarationRange then declarationRange.Value::remainingRanges
                      else remainingRanges
  
      let ranges = List.concat (Seq.map rangesToReplace (makeScopeTree tree))
      CodeTransforms.ChangeTextOf source (List.zip ranges (List.map (fun _ -> newName) [1..(ranges.Length)]))
     
  