anchor.diff:  ﻿namespace FSharp.Data
  -
  -// TODO: document all of these
   
   open System
   open System.IO
  
positive.code: 
  module Html =
      module HtmlAttribute = 
          
          let name = function
              | HtmlAttribute(name = name) -> name
           
          let value = function
              | HtmlAttribute(value = value) -> value   
      
          let parseValue parseF attr = 
              value attr |> parseF
      
          let tryParseValue defaultValue parseF attr = 
              match value attr |> parseF with
              | true, v -> v
              | false, _ -> defaultValue
      
      type HtmlAttribute with
      
          member x.Name with get() = HtmlAttribute.name x
          member x.Value() = HtmlAttribute.value x
          member x.Value<'a>(parseF : string -> 'a)= 
              HtmlAttribute.parseValue parseF x
          member x.Value<'a>(defaultValue, parseF : string -> (bool * 'a))= 
              HtmlAttribute.tryParseValue defaultValue parseF x
      
      module HtmlNode = 
          
          let name = function
              | HtmlElement(_, name, _, _) -> name.ToLowerInvariant()
              | HtmlContent(_, HtmlContentType.Script, _ ) -> "script"
              | HtmlContent(_, HtmlContentType.Style, _) -> "style"
              | _ -> String.Empty
              
          let children = function 
              | HtmlElement(_, _, _, children) -> children
              | _ -> []
      
          let parent = function
              | HtmlElement(parent = parent) 
              | HtmlContent(parent = parent) -> !parent
          
          let descendantsAndSelf f x = 
              let rec descendantsBy f (x:HtmlNode) =
                      [   
  
negative.code:                     ]
              descendantsBy f x
      
          /// <summary>
          /// Finds all of the descendant nodes of this nodes that match the given set of names
          /// </summary>
          /// <param name="names">The set of names to match</param>
          /// <param name="x">The given node</param>
          let descendantsNamed names x = 
              let nameSet = Set.ofSeq (names |> Seq.map (fun (n:string) -> n.ToLowerInvariant()))
              descendants (fun x -> name x |> nameSet.Contains) x
          
          /// <summary>
          /// Returns true if any of the descendants of the current node exist in the 
          /// given set of names
          /// </summary>
          /// <param name="names">The set of names to match against</param>
          /// <param name="x">The given node</param>
          let hasDescendants names x = 
              let nameSet = Set.ofSeq (names |> Seq.map (fun (n:string) -> n.ToLowerInvariant()))
              descendants (fun x -> nameSet.Contains(name x)) x |> Seq.isEmpty |> not
          
          /// <summary>
          /// Trys to return an attribute that exists on the current node
          /// </summary>
          /// <param name="name">The name of the attribute to return.</param>
          let tryGetAttribute (name:string) = function
              | HtmlElement(_,_,attr,_) -> attr |> List.tryFind (fun a -> a.Name.ToLowerInvariant() = (name.ToLowerInvariant()))
              | _ -> None   
          
          /// <summary>
          /// Trys to return a parsed value of the named attribute.
          /// </summary>
          /// <param name="defaultValue">The default value to return if the attribute does not exist or the parsing fails</param>
          /// <param name="parseF">The function to parse the value</param>
          /// <param name="name">The name of the attribute to get the value from</param>
          /// <param name="x">The given node</param>
          let getAttributeValue defaultValue parseF name x = 
              match tryGetAttribute name x with
              | Some(v) -> v.Value(defaultValue, parseF)
              | None -> defaultValue
          
          /// <summary>
          /// Returns the attribute with the given name. If the attribute does not exist
          /// </summary>
          /// <param name="name"></param>
          /// <param name="x"></param>
          let attribute name x = 
              match tryGetAttribute name x with
              | Some(v) -> v
  