anchor.diff:  
               search <| DirectoryInfo folder
   
  -        FindAllFiles(folder, "*.*proj")
  +        findAllFiles(folder, "*.*proj")
           |> Array.filter (fun f -> f.Extension = ".csproj" || f.Extension = ".fsproj" || f.Extension = ".vbproj" || f.Extension = ".wixproj" || f.Extension = ".nproj")
  -        |> Array.choose (fun fi -> ProjectFile.TryLoad fi.FullName)
  -
  -    static member FindCorrespondingFile (projectFile : FileInfo, correspondingFile:string) =
  -        let specificFile = FileInfo(Path.Combine(projectFile.Directory.FullName, projectFile.Name + "." + correspondingFile))
  -        if specificFile.Exists then Some specificFile.FullName
  -        else
  -            let rec findInDir (currentDir:DirectoryInfo) = 
  -                let generalFile = FileInfo(Path.Combine(currentDir.FullName, correspondingFile))
  -                if generalFile.Exists then Some generalFile.FullName
  -                elif (FileInfo(Path.Combine(currentDir.FullName, Constants.DependenciesFileName))).Exists then None
  -                elif currentDir.Parent = null then None
  -                else findInDir currentDir.Parent 
  +        |> Array.choose (fun fi -> tryLoad fi.FullName)
  +
  +
  +    let createNode name (project:ProjectFile) = 
  +        project.Document.CreateElement (name, Constants.ProjectDefaultNameSpace)
  +
  +    let createNodeSet name text (project:ProjectFile) = 
  +        let node = createNode name project
  +        node.InnerText <- text
  +        node
  +
  +
  +
  +//    let createChildNode name text project =
  +//        project |> addChild (createNodeSet name text project)
  +
  +    open System.Text
  +
  +    let getPropertyWithDefaults propertyName defaultProperties (projectFile:ProjectFile) =
  +
  +        let processPlaceholders (data : Map<string, string>) text =
  +            
  +            let getPlaceholderValue (name:string) =
  +                // Change "$(Configuration)" to "Configuration",
  +                // then find in the data map
  +                let name = name.Substring(2, name.Length - 3)
  +                match data.TryFind(name) with
  +                | None -> ""
  +                | Some s -> s
  +
  +            let replacePlaceholder (s:string) (m:RegularExpressions.Match) =
  +                let front = s.Substring(0, m.Index)
  +                let value = getPlaceholderValue m.Value
  +                let back = s.Substring(m.Index + m.Length)
  +                front + value + back
  +
  +            // The placeholder name must be a valid XML node name,
  +            // else where would its value be defined?
  +            let regex = @"\$\([a-zA-Z_\-\:][a-zA-Z0-9_\.\-\:]*\)"
  +
  +            RegularExpressions.Regex.Matches(text, regex)
  +            |> fun x -> Seq.cast<RegularExpressions.Match>(x)
  +            |> Seq.toArray
  +            |> Array.rev
  +            |> Array.fold replacePlaceholder text
  +
  +
  +        let rec parseWord (data:StringBuilder) (input:string) index inQuotes =
  +            if input.Length <= index
  +            then
  +                if data.Length > 0 && not inQuotes then Some(data.ToString(), index)
  +                else None
  +            else
  +                let c = input.[index]
  +                let gtz = data.Length > 0
  +                match gtz, inQuotes, c with
  +                | false, false, ' '  -> parseWord data input (index + 1) false
  +                | false, false, '\'' -> parseWord data input (index + 1) true
  +                |     _,  true, '\'' -> Some (string data, index + 1)
  +                |  true, false, ' '  -> Some (string data, index + 1)
  +                |     _,  true, c    -> parseWord (data.Append c) input (index + 1) true
  +                |     _, false, c    -> parseWord (data.Append c) input (index + 1) false
  +
  +
  +        let rec parseComparison (data:StringBuilder) (input:string) index =
  +            let isCompChar c = c = '<' || c = '>' || c = '!' || c = '='
  +                       
  +            if input.Length <= index then None else
  +            let c = input.[index]
  +            if data.Length = 0 && c = ' 'then 
  +                parseComparison data input (index + 1)
  +            elif data.Length = 2 && isCompChar c then 
  +                None
  +            elif isCompChar c then 
  +                parseComparison (data.Append c) input (index + 1)
  +            else
  +                let s = string data
  +                let valid = [ "=="; "!="; "<"; ">"; "<="; ">=" ]
  +                match (valid |> List.tryFind ((=) s)) with
  +                | None -> None
  +                | Some _ -> Some(s, index)
  +
  +
  +        let parseCondition (data:System.Text.StringBuilder) (input:string) index =
  +            maybe{
  +                if input.Length <= index then return! None else 
  +                data.Clear () |> ignore
  +                let! left, index = parseWord data input index false
  +                data.Clear () |> ignore
  +                let! comp, index = parseComparison data input index
  +                data.Clear () |> ignore
  +                let! right, index = parseWord data input index false 
  +                return (left, comp, right, index)
  +            }
  +
  +        let rec parseAndOr (data:System.Text.StringBuilder) (input:string) index =
  +            if input.Length <= index then None else
  +
  +            let c = input.[index]
  +            if   data.Length = 0 && c = ' '
  +            then parseAndOr data input (index + 1)
  +            elif c <> ' ' then parseAndOr (data.Append c) input (index + 1) else
  +            let  s = string data
  +            if   s.Equals ("and", StringComparison.OrdinalIgnoreCase) then Some("and", index)
  +            elif s.Equals ("or", StringComparison.OrdinalIgnoreCase)  then Some("or", index)
  +            else None
  +
  +        let rec containsMoreText (input:string) index =
  +            if input.Length <= index then false else
  +            match input.[index] with
  +            | ' ' -> containsMoreText input (index + 1)
  +            | _ -> true
  +
  +
  +        let rec parseFullCondition data (sb:System.Text.StringBuilder) (input:string) index =
  +            if input.Length <= index
  +            then data
  +            else
  +                match data with
  +                | None -> None
  +                | Some data ->
  +                    sb.Clear() |> ignore
  +                    let andOr, index =
  +                        match data with
  +                        | [] -> None, index
  +                        | _ ->
  +                            let moreText = containsMoreText input index
  +                            match (parseAndOr sb input index), moreText with
  +                            | None, false -> None, index
  +                            | Some(andOr, index), _ -> Some andOr, index
  +                            | None, true -> failwith "Could not parse condition; multiple conditions found with no \"AND\" or \"OR\" between them."
  +                    sb.Clear() |> ignore
  +                    let nextCondition = parseCondition sb input index
  +                    let moreText = containsMoreText input index
  +                    match nextCondition, moreText with
  +                    | None, true -> None
  +                    | None, false -> Some(data)
  +                    | Some(left, comp, right, index), _ ->
  +                        let data = Some <| data @[(andOr, left, comp, right)]
  +                        parseFullCondition data sb input index
  +
  +        let rec handleConditions data xs lastCondition =
  +            match xs with
  +            | [] -> lastCondition
  +            | (cond, left, comp, right)::xs ->
  +                let left  = processPlaceholders data left
  +                let right = processPlaceholders data right
  +                let inline doComp l r =
  +                    match comp with
  +                    | "==" -> l =  r
  +                    | "!=" -> l <> r
  +                    | ">"  -> l >  r
  +                    | "<"  -> l <  r
  +                    | "<=" -> l <= r
  +                    | ">=" -> l >= r
  +                    | _ -> failwithf "%s is not a valid comparison operator" comp
  +
  +                let result =
  +                    match comp with
  +                    | "==" | "!=" -> doComp left right
  +                    | _ ->
  +                        match System.Int64.TryParse left, System.Int64.TryParse right with
  +                        | (true, l), (true, r) -> doComp l r
  +                        | _ -> false
  +
  +                match lastCondition, cond with
  +                |    _, None       -> handleConditions data xs result
  +                | true, Some "and" -> handleConditions data xs result
  +                |    _, Some "or"  -> handleConditions data xs (lastCondition || result)
  +                | _ -> false
  +
  +
  +        let conditionMatches data condition =
  +            let allConditions = 
  +                parseFullCondition (Some []) (StringBuilder()) condition 0
  +            match allConditions with
  +            | None -> false
  +            | Some conditions -> handleConditions data conditions true
  +
  +
  +        let addData data (node:XmlNode) =
  +            let text = processPlaceholders data node.InnerText
  +            // Note that using Map.add overrides the value assigned
  +            // to this key if it already exists in the map; so long
  +            // as we process nodes top-to-bottom, this matches the
  +            // behavior of MSBuild.
  +            Map.add node.Name text data
  +
  +
  +        let rec handleElement (data : Map<string, string>) (node : XmlNode) =
  +
  +            let handleConditionalElement data node =
  +                match getAttribute "Condition" node with
  +                | None ->
  +                    node |> getChildNodes
  +                    |> Seq.fold handleElement data
  +                | Some s ->
  +                    if not (conditionMatches data s)
  +                    then data
  +                    elif node.ChildNodes.Count > 0 then
  +                        node |> getChildNodes
  +                        |> Seq.fold handleElement data
  +                    else data
  +
  +            match node.Name with
  +            | "PropertyGroup" -> handleConditionalElement data node
  +            // Don't handle these yet
  +            | "Choose" | "Import" | "ItemGroup" | "ProjectExtensions" | "Target" | "UsingTask" -> data
  +            // Any other node types are intended to be values being defined
  +            | _ ->
  +                match getAttribute "Condition" node with
  +                | None -> addData data node
  +                | Some s ->
  +                    if not (conditionMatches data s)
  +                    then data
  +                    else addData data node
  +
  +        let map =
  +            projectFile.Document
  +            |> getDescendants "PropertyGroup"
  +            |> Seq.fold handleElement defaultProperties
  +        
  +        Map.tryFind propertyName map
  +
  +    let getProperty propertyName (projectFile:ProjectFile) =
  +        getPropertyWithDefaults propertyName Map.empty<string, string> projectFile
  +
  +    let findCorrespondingFile (projectFile:FileInfo) (correspondingFile:string) =
  +        let specificFile = FileInfo (Path.Combine(projectFile.Directory.FullName, projectFile.Name + "." + correspondingFile))
  +        if specificFile.Exists then Some specificFile.FullName else
  +        
  +        let rec findInDir (currentDir:DirectoryInfo) = 
  +            let generalFile = FileInfo(Path.Combine(currentDir.FullName, correspondingFile))
  +            if generalFile.Exists then Some generalFile.FullName
  +            elif (FileInfo (Path.Combine(currentDir.FullName, Constants.DependenciesFileName))).Exists then None
  +            elif currentDir.Parent = null then None
  +            else findInDir currentDir.Parent 
                       
  -            findInDir projectFile.Directory
  -
  -    static member FindReferencesFile (projectFile : FileInfo) = ProjectFile.FindCorrespondingFile(projectFile, Constants.ReferencesFile)
  -
  -    static member FindTemplatesFile (projectFile : FileInfo) = ProjectFile.FindCorrespondingFile(projectFile, Constants.TemplateFile)
  -
  -    static member FindOrCreateReferencesFile (projectFile : FileInfo) =
  -        match ProjectFile.FindReferencesFile projectFile with
  +        findInDir projectFile.Directory
  +
  +    let findReferencesFile (projectFile:FileInfo) = findCorrespondingFile projectFile Constants.ReferencesFile
  +
  +    let findTemplatesFile (projectFile:FileInfo) = findCorrespondingFile projectFile Constants.TemplateFile
  +
  +    let findOrCreateReferencesFile (projectFile : FileInfo) =
  +        match findReferencesFile projectFile with
           | None ->
               let newFileName =
                   let fi = FileInfo(Path.Combine(projectFile.Directory.FullName,Constants.ReferencesFile))
  
positive.code:                     |> FrameworkDetection.Extract
                  match detectedFramework with
                  | None -> defaultResult
                  | Some x -> SinglePlatform(x)
      
      member this.AddImportForPaketTargets(relativeTargetsPath) =
          match this.Document 
                |> getDescendants "Import" 
                |> List.tryFind (withAttributeValue "Project" relativeTargetsPath) with
          | Some _ -> ()
          | None -> 
              let node = this.CreateNode("Import") |> addAttribute "Project" relativeTargetsPath
              this.ProjectNode.AppendChild(node) |> ignore
  
      member this.RemoveImportForPaketTargets(relativeTargetsPath) =
          this.Document
          |> getDescendants "Import"
          |> List.tryFind (withAttributeValue "Project" relativeTargetsPath)
          |> Option.iter (fun n -> n.ParentNode.RemoveChild(n) |> ignore)
  
      member this.DetermineBuildAction fileName =
          if Path.GetExtension(this.FileName) = Path.GetExtension(fileName) + "proj" 
          then BuildAction.Compile
          else BuildAction.Content
  
      member this.DetermineBuildActionForRemoteItems fileName =
          if Path.GetExtension(fileName) = ".dll"
          then BuildAction.Reference
          else this.DetermineBuildAction fileName 
  
      member this.GetOutputDirectory buildConfiguration buildPlatform =
          let platforms =
              if not <| String.IsNullOrWhiteSpace(buildPlatform)
              then [buildPlatform]
              else
                  [
  
negative.code:                     match fileItem.BuildAction with
                      | BuildAction.Reference -> 
                          let n = FileInfo(fileItem.Include).Name.TrimEnd('\\').Split('\\') |> Array.last
                          n.Replace(Path.GetExtension n,"")
                      | _ -> fileItem.Include
  
                  createNode (string fileItem.BuildAction) project
                  |> addAttribute "Include" name
                  |> fun node -> 
                      match fileItem.BuildAction with
                      | BuildAction.Reference -> 
                          node
                          |> addChild (createNodeSet "HintPath" fileItem.Include project)
                          |> addChild (createNodeSet "Private" "True" project)
                      | _ -> node
                  |> addChild (createNodeSet "Paket" "True" project)
                  |> fun n -> match fileItem.Link with
                              | Some link -> addChild (createNodeSet "Link" (link.Replace("\\","/")) project) n
                              | _ -> n
  
              let fileItemsInSameDir =
                  project.Document 
                  |> getDescendants (string fileItem.BuildAction)
                  |> List.filter (fun node -> 
                      match node |> getAttribute "Include" with
                      | Some path when path.StartsWith (Path.GetDirectoryName fileItem.Include) -> true
                      | _ -> false)
              
  
              if Seq.isEmpty fileItemsInSameDir then 
                  newItemGroups.[fileItem.BuildAction].PrependChild libReferenceNode |> ignore
              else
                  let existingNode = 
                      fileItemsInSameDir 
  