anchor.diff:      let rec isFree (onDeclarationFun : ScopeTree -> bool) targetName tree =
           match tree with
               | Usage(n,_) -> n <> targetName
  -            | Declaration(vs, ts) ->
  -                if List.exists (fun (n,_) -> n = targetName) vs
  -                then onDeclarationFun (Declaration(vs, ts))
  +            | 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)]))
  +   
  
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: 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)]
  