anchor.diff:          // Set comparison.  This can be expensive.
           //--------------------------------------------------------------------------
   
  -        let rec compareStacks (comparer: IComparer<'T>) l1 l2 =
  -            match l1,l2 with 
  -            | [],[] ->  0
  -            | [],_  -> -1
  -            | _ ,[] ->  1
  -            | (SetEmpty  _ :: t1),(SetEmpty    :: t2) -> compareStacks comparer t1 t2
  -#if ONE
  -            | (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 (empty :: 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)
  -#endif
  -            | (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)
  -#if ONE
  -            | (SetOne(n1k) :: t1),_ -> 
  -                compareStacks comparer (empty :: SetOne(n1k) :: t1) l2
  -#endif
  -            | (SetNode(n1k,n1l,n1r,_) :: t1),_ -> 
  -                compareStacks comparer (n1l :: SetNode(n1k,empty,n1r,0) :: t1) l2
  -#if ONE
  -            | _,(SetOne(n2k) :: t2) -> 
  -                compareStacks comparer l1 (empty :: SetOne(n2k) :: t2)
  -#endif
  -            | _,(SetNode(n2k,n2l,n2r,_) :: t2) -> 
  -                compareStacks comparer l1 (n2l :: SetNode(n2k,empty,n2r,0) :: t2)
  -                
  -        let compare comparer s1 s2 = 
  -            match s1,s2 with 
  -            | SetEmpty,SetEmpty -> 0
  -            | SetEmpty,_ -> -1
  -            | _,SetEmpty -> 1
  -            | _ -> compareStacks comparer [s1] [s2]
  +        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
  +            | (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 x = 
  -                match m with 
  -                | SetNode(k,l,r,_) -> loop l (k :: (loop r x))
  -#if ONE
  -                | SetOne(k) -> k :: x
  -#endif
  -                | SetEmpty -> x
  -            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:             let notStarted() = raise (new System.InvalidOperationException("Enumeration has not started. Call MoveNext."))
              let alreadyFinished() = raise (new System.InvalidOperationException("Enumeration already finished."))
  
              member i.Current =
                  if started then
                      match stack with
  #if ONE
                        | SetOne k :: _ -> k
  #else
                        | SetNode( k,_,_,_) :: _ -> k
  #endif
                        | []            -> alreadyFinished()
                        | _             -> failwith "Please report error: Set iterator, unexpected stack for current"
                  else
                      notStarted()
  
              member i.MoveNext() = 
                  if started then
                      match stack with
  #if ONE
                        | SetOne _ :: rest -> 
  #else
                        | SetNode _ :: rest -> 
  #endif
                              stack <- collapseLHS rest;
                              not stack.IsEmpty
                        | [] -> false
                        | _ -> failwith "Please report error: Set iterator, unexpected stack for moveNext"
                  else
                      started <- true;  // The first call to MoveNext "starts" the enumeration.
                      not stack.IsEmpty
  
          let toSeq s = 
              let mutable i = SetIterator s
  
negative.code:     open Microsoft.FSharp.Core.LanguagePrimitives.IntrinsicOperators
      open System.Collections.Generic
  
      [<NoEquality; NoComparison>]
      [<AllowNullLiteral>]
      type internal SetTree<'T>(k: 'T) =
          member _.Key = k
  
      [<NoEquality; NoComparison>]
      [<Sealed>]
      [<AllowNullLiteral>]
      type internal SetTreeNode<'T>(v:'T, left:SetTree<'T>, right: SetTree<'T>, h: int) =
          inherit SetTree<'T>(v)
  
          member _.Left = left
          member _.Right = right
          member _.Height = h
  
      [<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
      module SetTree = 
          let empty = null
  
          let inline isEmpty (t:SetTree<'T>) = isNull t
  
          let rec countAux (t:SetTree<'T>) acc = 
              if isEmpty t then
                  acc
              else
                  match t with 
                  | :? SetTreeNode<'T> as tn -> countAux tn.Left (countAux tn.Right (acc+1))
                  | _ -> acc+1
  
          let count s = countAux s 0
  
          let inline height (t:SetTree<'T>) = 
              if isEmpty t then 0
              else
                  match t with 
                  | :? SetTreeNode<'T> as tn -> tn.Height
                  | _ -> 1
  
  #if CHECKED
          let rec checkInvariant (t:SetTree<'T>) =
              // A good sanity check, loss of balance can hit perf
              if isEmpty t then true
              else
                  match t with 
                  | :? SetTreeNode<'T> as tn  ->
                      let h1 = height tn.Left 
                      let h2 = height tn.Right 
                      (-2 <= (h1 - h2) && (h1 - h2) <= 2) && checkInvariant tn.Left && checkInvariant tn.Right
                  | _ -> true
  #endif
  
          [<Literal>]
          let tolerance = 2
  
          let mk l k r : SetTree<'T> = 
              let hl = height l 
              let hr = height r 
              let m = if hl < hr then hr else hl
              if m = 0 then // m=0 ~ isEmpty l && isEmpty r
                  SetTree k
              else
                  SetTreeNode (k, l, r, m+1) :> SetTree<'T>
  
          let inline private asNode(value:SetTree<'T>) : SetTreeNode<'T> =
              value :?> SetTreeNode<'T>
  
          let rebalance t1 v t2 =
              let t1h = height t1 
              let t2h = height t2 
              if  t2h > t1h + tolerance then // right is heavier than left 
                  let t2' = asNode(t2)
                  // one of the nodes must have height > height t1 + 1 
                  if height t2'.Left > t1h + 1 then  // balance left: combination 
                      let t2l = asNode(t2'.Left)
                      mk (mk t1 v t2l.Left) t2l.Key (mk t2l.Right t2'.Key t2'.Right) 
                  else // rotate left
                      mk (mk t1 v t2'.Left) t2.Key t2'.Right
              else
                  if  t1h > t2h + tolerance then // left is heavier than right
                      let t1' = asNode(t1)
                      // one of the nodes must have height > height t2 + 1 
                      if height t1'.Right > t2h + 1 then 
                          // balance right: combination
                          let t1r = asNode(t1'.Right)
                          mk (mk t1'.Left t1.Key t1r.Left) t1r.Key (mk t1r.Right v t2)
                      else
                          mk t1'.Left t1'.Key (mk t1'.Right v t2)
                  else mk t1 v t2
  
          let rec add (comparer: IComparer<'T>) k (t:SetTree<'T>) : SetTree<'T> = 
              if isEmpty t then SetTree k
              else
                  let c = comparer.Compare(k, t.Key)
                  match t with
                  | :? SetTreeNode<'T> as tn ->
                      if   c < 0 then rebalance (add comparer k tn.Left) tn.Key tn.Right
                      elif c = 0 then t
                      else            rebalance tn.Left tn.Key (add comparer k tn.Right)
                  | _ -> 
                      // nb. no check for rebalance needed for small trees, also be sure to reuse node already allocated 
                      let c = comparer.Compare(k, t.Key) 
                      if c < 0   then SetTreeNode (k, empty, t, 2) :> SetTree<'T>
                      elif c = 0 then t
                      else            SetTreeNode (k, t, empty, 2) :> SetTree<'T>
  
          let rec balance comparer (t1:SetTree<'T>) k (t2:SetTree<'T>) =
              // Given t1 < k < t2 where t1 and t2 are "balanced", 
              // return a balanced tree for <t1, k, t2>.
              // Recall: balance means subtrees heights differ by at most "tolerance"
              if isEmpty t1 then add comparer k t2 // drop t1 = empty
              elif isEmpty t2 then add comparer k t1 // drop t2 = empty
              else
                  match t1 with
                  | :? SetTreeNode<'T> as t1n ->
                      match t2 with
                      | :? SetTreeNode<'T> as t2n ->
                          // Have:  (t1l < k1 < t1r) < k < (t2l < k2 < t2r)
                          // Either (a) h1, h2 differ by at most 2 - no rebalance needed.
                          //        (b) h1 too small, i.e. h1+2 < h2
                          //        (c) h2 too small, i.e. h2+2 < h1 
                          if t1n.Height + tolerance < t2n.Height then
                              // case: b, h1 too small 
                              // push t1 into low side of t2, may increase height by 1 so rebalance 
                              rebalance (balance comparer t1 k t2n.Left) t2n.Key t2n.Right
                          elif t2n.Height + tolerance < t1n.Height then
                              // case: c, h2 too small 
                              // push t2 into high side of t1, may increase height by 1 so rebalance 
                              rebalance t1n.Left t1n.Key (balance comparer t1n.Right k t2)
                          else
                              // case: a, h1 and h2 meet balance requirement 
                              mk t1 k t2
                      | _ -> add comparer k (add comparer t2.Key t1)
                  | _ -> add comparer k (add comparer t1.Key t2)
  
          let rec split (comparer: IComparer<'T>) pivot (t:SetTree<'T>) =
              // Given a pivot and a set t
              // Return { x in t s.t. x < pivot }, pivot in t?, { x in t s.t. x > pivot } 
              if isEmpty t then empty, false, empty
              else
                  match t with
                  | :? SetTreeNode<'T> as tn ->
                      let c = comparer.Compare(pivot, tn.Key)
                      if   c < 0 then // pivot t1 
                          let t11Lo, havePivot, t11Hi = split comparer pivot tn.Left
                          t11Lo, havePivot, balance comparer t11Hi tn.Key tn.Right
                      elif c = 0 then // pivot is k1 
                          tn.Left, true, tn.Right
                      else            // pivot t2 
                          let t12Lo, havePivot, t12Hi = split comparer pivot tn.Right
                          balance comparer tn.Left tn.Key t12Lo, havePivot, t12Hi
                  | _ ->
                      let c = comparer.Compare(t.Key, pivot)
                      if   c < 0 then t, false, empty // singleton under pivot 
                      elif c = 0 then empty, true, empty // singleton is    pivot 
                      else            empty, false, t        // singleton over  pivot 
          
          let rec spliceOutSuccessor (t:SetTree<'T>) = 
              if isEmpty t then failwith "internal error: Set.spliceOutSuccessor"
              else
                  match t with 
                  | :? SetTreeNode<'T> as tn ->
                      if isEmpty tn.Left then tn.Key, tn.Right
                      else let k3, l' = spliceOutSuccessor tn.Left in k3, mk l' tn.Key tn.Right
                  | _ -> t.Key, empty
  
          let rec remove (comparer: IComparer<'T>) k (t:SetTree<'T>) = 
              if isEmpty t then t
              else
                  let c = comparer.Compare(k, t.Key)
                  match t with 
                  | :? SetTreeNode<'T> as tn ->
                      if   c < 0 then rebalance (remove comparer k tn.Left) tn.Key tn.Right
                      elif c = 0 then
                          if isEmpty tn.Left then tn.Right
                          elif isEmpty tn.Right then tn.Left
                          else
                              let sk, r' = spliceOutSuccessor tn.Right 
                              mk tn.Left sk r'
                      else rebalance tn.Left tn.Key (remove comparer k tn.Right)
                  | _ ->  
                      if   c = 0 then empty
                      else t
  
          let rec contains (comparer: IComparer<'T>) k (t:SetTree<'T>) = 
              if isEmpty t then false
              else
                  let c = comparer.Compare(k, t.Key) 
                  match t with 
                  | :? SetTreeNode<'T> as tn ->
                      if   c < 0 then contains comparer k tn.Left
                      elif c = 0 then true
                      else contains comparer k tn.Right
                  | _ -> (c = 0)
  
          let rec iter f (t:SetTree<'T>) = 
              if isEmpty t then ()
              else
                  match t with 
                  | :? SetTreeNode<'T> as tn -> iter f tn.Left; f tn.Key; iter f tn.Right
                  | _ -> f t.Key           
  
          // Fold, left-to-right. 
          //
          // NOTE: This differs from the behaviour of Map.fold which folds right-to-left.
          let rec fold f (t:SetTree<'T>) x =
              if isEmpty t then x
              else
                match t with
                | :? SetTreeNode<'T> as tn -> fold f tn.Right (f tn.Key (fold f tn.Left x))
                | _ -> f t.Key x          
  
          let rec forall f (t:SetTree<'T>) = 
              if isEmpty t then true
              else
                  match t with 
                  | :? SetTreeNode<'T> as tn -> f tn.Key && forall f tn.Left && forall f tn.Right
                  | _ -> f t.Key          
  
          let rec exists f (t:SetTree<'T>) = 
              if isEmpty t then false
              else
                  match t with 
                  | :? SetTreeNode<'T> as tn -> f tn.Key || exists f tn.Left || exists f tn.Right
                  | _ -> f t.Key       
  
          let subset comparer a b  =
              forall (fun x -> contains comparer x b) a
  
          let rec filterAux comparer f (t:SetTree<'T>) acc = 
              if isEmpty t then acc
              else
                  match t with 
                  | :? SetTreeNode<'T> as tn ->
                      let acc = if f tn.Key then add comparer tn.Key acc else acc 
                      filterAux comparer f tn.Left (filterAux comparer f tn.Right acc)
                  | _ -> if f t.Key then add comparer t.Key acc else acc        
  
          let filter comparer f s = filterAux comparer f s empty
  
          let rec diffAux comparer (t:SetTree<'T>) acc = 
              if isEmpty acc then acc
              else
                  if isEmpty t then acc
                  else
                      match t with 
                      | :? SetTreeNode<'T> as tn -> diffAux comparer tn.Left (diffAux comparer tn.Right (remove comparer tn.Key acc))
                      | _ -> remove comparer t.Key acc     
  
          let diff comparer a b = diffAux comparer b a
  
          let rec union comparer (t1:SetTree<'T>) (t2:SetTree<'T>) =
              // Perf: tried bruteForce for low heights, but nothing significant 
              if isEmpty t1 then t2
              elif isEmpty t2 then t1
              else
                  match t1 with
                  | :? SetTreeNode<'T> as t1n ->
                      match t2 with
                      | :? SetTreeNode<'T> as t2n -> // (t1l < k < t1r) AND (t2l < k2 < t2r) 
                          // Divide and Conquer:
                          //   Suppose t1 is largest.
                          //   Split t2 using pivot k1 into lo and hi.
                          //   Union disjoint subproblems and then combine. 
                          if t1n.Height > t2n.Height then
                              let lo, _, hi = split comparer t1n.Key t2 in
                              balance comparer (union comparer t1n.Left lo) t1n.Key (union comparer t1n.Right hi)
                          else
                              let lo, _, hi = split comparer t2n.Key t1 in
                              balance comparer (union comparer t2n.Left lo) t2n.Key (union comparer t2n.Right hi)
                      | _ -> add comparer t2.Key t1
                  | _ -> add comparer t1.Key t2
  
          let rec intersectionAux comparer b (t:SetTree<'T>) acc = 
              if isEmpty t then acc
              else
                  match t with 
                  | :? SetTreeNode<'T> as tn -> 
                      let acc = intersectionAux comparer b tn.Right acc 
                      let acc = if contains comparer tn.Key b then add comparer tn.Key acc else acc 
                      intersectionAux comparer b tn.Left acc
                  | _ -> 
                      if contains comparer t.Key b then add comparer t.Key acc else acc
  
          let intersection comparer a b = intersectionAux comparer b a empty
  
          let partition1 comparer f k (acc1, acc2) = if f k then (add comparer k acc1, acc2) else (acc1, add comparer k acc2) 
  
          let rec partitionAux comparer f (t:SetTree<'T>) acc = 
              if isEmpty t then acc
              else
                  match t with 
                  | :? SetTreeNode<'T> as tn -> 
                      let acc = partitionAux comparer f tn.Right acc 
                      let acc = partition1 comparer f tn.Key acc
                      partitionAux comparer f tn.Left acc
                  | _ -> partition1 comparer f t.Key acc
  
          let partition comparer f s = partitionAux comparer f s (empty, empty)
          
          let rec minimumElementAux (t:SetTree<'T>) n = 
              if isEmpty t then n
              else
                  match t with 
                  | :? SetTreeNode<'T> as tn -> minimumElementAux tn.Left tn.Key
                  | _ -> t.Key
  
          and minimumElementOpt (t:SetTree<'T>) = 
              if isEmpty t then None
              else
                  match t with 
                  | :? SetTreeNode<'T> as tn -> Some(minimumElementAux tn.Left tn.Key)
                  | _ -> Some t.Key
  
          and maximumElementAux (t:SetTree<'T>) n = 
              if isEmpty t then n
              else
                  match t with 
                  | :? SetTreeNode<'T> as tn -> maximumElementAux tn.Right tn.Key
                  | _ -> t.Key
  
          and maximumElementOpt (t:SetTree<'T>) = 
              if isEmpty t then None
              else
                  match t with 
                  | :? SetTreeNode<'T> as tn -> Some(maximumElementAux tn.Right tn.Key)
                  | _ -> Some t.Key
  
          let minimumElement s = 
              match minimumElementOpt s with 
  