anchor.diff:                member __.Dispose() = () }
   
       /// Set comparison.  Note this can be expensive.
  -    let rec compareStacks (comparer: IComparer<'T>) l1 l2 =
  +    let rec compareStacks (comparer: IComparer<'T>) (l1:SetTree<'T> list) (l2:SetTree<'T> list) : int =
  +        let cont() =
  +            match l1, l2 with 
  +            | (x1 :: t1), _ when not (isEmpty x1) ->
  +                match x1 with
  +                | :? SetTreeNode<'T> as x1n ->
  +                    compareStacks comparer (x1n.Left :: (SetTreeNode (x1n.Key, empty, x1n.Right, 0) :> SetTree<'T>) :: t1) l2
  +                | _ -> compareStacks comparer (empty :: SetTree x1.Key :: t1) l2
  +            | _, (x2 :: t2) when not (isEmpty x2) ->
  +                match x2 with
  +                | :? SetTreeNode<'T> as x2n ->
  +                    compareStacks comparer l1 (x2n.Left :: (SetTreeNode (x2n.Key, empty, x2n.Right, 0) :> SetTree<'T>  ) :: t2)
  +                | _ -> compareStacks comparer l1 (empty :: SetTree x2.Key :: t2)
  +            | _ -> failwith "unexpected state in SetTree.compareStacks"
  +        
           match l1, l2 with 
           | [], [] ->  0
           | [], _  -> -1
           | _, [] ->  1
  -        | (SetEmpty  _ :: t1), (SetEmpty    :: t2) -> compareStacks comparer t1 t2
  -        | (SetOne n1k :: t1), (SetOne n2k :: t2) -> 
  -             let c = comparer.Compare(n1k, n2k) 
  -             if c <> 0 then c else compareStacks comparer t1 t2
  -        | (SetOne n1k :: t1), (SetNode (n2k, SetEmpty, n2r, _) :: t2) -> 
  -             let c = comparer.Compare(n1k, n2k) 
  -             if c <> 0 then c else compareStacks comparer (SetEmpty :: t1) (n2r :: t2)
  -        | (SetNode (n1k, (SetEmpty as emp), n1r, _) :: t1), (SetOne n2k :: t2) -> 
  -             let c = comparer.Compare(n1k, n2k) 
  -             if c <> 0 then c else compareStacks comparer (n1r :: t1) (emp :: t2)
  -        | (SetNode (n1k, SetEmpty, n1r, _) :: t1), (SetNode (n2k, SetEmpty, n2r, _) :: t2) -> 
  -             let c = comparer.Compare(n1k, n2k) 
  -             if c <> 0 then c else compareStacks comparer (n1r :: t1) (n2r :: t2)
  -        | (SetOne n1k :: t1), _ -> 
  -            compareStacks comparer (SetEmpty :: SetOne n1k :: t1) l2
  -        | (SetNode (n1k, n1l, n1r, _) :: t1), _ -> 
  -            compareStacks comparer (n1l :: SetNode (n1k, SetEmpty, n1r, 0) :: t1) l2
  -        | _, (SetOne n2k :: t2) -> 
  -            compareStacks comparer l1 (SetEmpty :: SetOne n2k :: t2)
  -        | _, (SetNode (n2k, n2l, n2r, _) :: t2) -> 
  -            compareStacks comparer l1 (n2l :: SetNode (n2k, SetEmpty, n2r, 0) :: t2)
  -
  -    let compare comparer s1 s2 = 
  -        match s1, s2 with 
  -        | SetEmpty, SetEmpty -> 0
  -        | SetEmpty, _ -> -1
  -        | _, SetEmpty -> 1
  -        | _ -> compareStacks comparer [s1] [s2]
  +        | (x1 :: t1), (x2 :: t2) ->
  +            if isEmpty x1 then
  +                if isEmpty x2 then compareStacks comparer t1 t2
  +                else cont()
  +            elif isEmpty x2 then cont()
  +            else
  +                match x1 with
  +                | :? SetTreeNode<'T> as x1n ->
  +                    if isEmpty x1n.Left then
  +                        match x2 with
  +                        | :? SetTreeNode<'T> as x2n ->
  +                            if isEmpty x2n.Left then
  +                                let c = comparer.Compare(x1n.Key, x2n.Key) 
  +                                if c <> 0 then c else compareStacks comparer (x1n.Right :: t1) (x2n.Right :: t2)
  +                            else cont()
  +                        | _ ->
  +                            let c = comparer.Compare(x1n.Key, x2.Key) 
  +                            if c <> 0 then c else compareStacks comparer (x1n.Right :: t1) (empty :: t2)
  +                    else cont()
  +                | _ ->
  +                    match x2 with
  +                    | :? SetTreeNode<'T> as x2n ->
  +                        if isEmpty x2n.Left then
  +                            let c = comparer.Compare(x1.Key, x2n.Key) 
  +                            if c <> 0 then c else compareStacks comparer (empty :: t1) (x2n.Right :: t2)
  +                        else cont()
  +                    | _ ->
  +                        let c = comparer.Compare(x1.Key, x2.Key) 
  +                        if c <> 0 then c else compareStacks comparer t1 t2
  +                                
  +    let compare comparer (t1:SetTree<'T>) (t2:SetTree<'T>) = 
  +        if isEmpty t1 then
  +            if isEmpty t2 then 0
  +            else -1
  +        else
  +            if isEmpty t2 then 1
  +            else compareStacks comparer [t1] [t2]
   
       let choose s =
           minimumElement s
   
  -    let toList s = 
  -        let rec loop m acc = 
  -            match m with 
  -            | SetNode (k, l, r, _) -> loop l (k :: loop r acc)
  -            | SetOne k ->  k :: acc
  -            | SetEmpty -> acc
  -        loop s []
  +    let toList (t:SetTree<'T>) = 
  +        let rec loop (t':SetTree<'T>) acc =
  +            if isEmpty t' then acc
  +            else
  +                match t' with 
  +                | :? SetTreeNode<'T> as tn -> loop tn.Left (tn.Key :: loop tn.Right acc)
  +                | _ ->  t'.Key :: acc
  +        loop t []
   
       let copyToArray s (arr: _[]) i =
           let mutable j = i 
  
positive.code: 
      [<System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2225:OperatorOverloadsHaveNamedAlternates")>]
      static member (-) (set1: Set<'T>, set2: Set<'T>) = 
          match set1.Tree with 
          | SetEmpty -> set1 (* 0 - B = 0 *)
          | _ -> 
          match set2.Tree with 
          | SetEmpty -> set1 (* A - 0 = A *)
          | _ -> Set(set1.Comparer, SetTree.diff set1.Comparer  set1.Tree set2.Tree)
  
      [<System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2225:OperatorOverloadsHaveNamedAlternates")>]
      static member (+) (set1: Set<'T>, set2: Set<'T>) = 
  
negative.code: 
      static let empty: Set<'T> = 
          let comparer = LanguagePrimitives.FastGenericComparer<'T> 
          Set<'T>(comparer, SetTree.empty)
  
      [<System.Runtime.Serialization.OnSerializingAttribute>]
      member __.OnSerializing(context: System.Runtime.Serialization.StreamingContext) =
  