anchor.diff:                                      and 't : struct> () =
   
                       let ec = mkClonerCached<'t> ctx
  -                    EQ(fun s c (t:Nullable<'t>) -> 
  -                        if t.HasValue then Nullable(ec s c t.Value)
  -                        else t) }
  +                    EQ { new Cloner<Nullable<'t>>() with
  +                        member _.Clone s c (t:Nullable<'t>) =
  +                            if t.HasValue then Nullable(ec.Clone s c t.Value)
  +                            else t } }
   
           | Shape.FSharpList s ->
               s.Element.Accept {
                   new ITypeVisitor<Cloner<'T>> with
                       member _.Visit<'t> () =
                           let ec = mkClonerCached<'t> ctx
  -                        EQ(fun s c ts -> List.map (ec s c) ts) }
  +                        EQ { new Cloner<'t list>() with member _.Clone s c ts = List.map (ec.Clone s c) ts } }
   
           | Shape.FSharpSet s ->
               s.Accept {
                   new IFSharpSetVisitor<Cloner<'T>> with
                       member _.Visit<'t when 't : comparison> () =
                           let tc = mkClonerCached<'t> ctx
  -                        EQ(fun s c ts -> Set.map (tc s c) ts) }
  +                        EQ { new Cloner<Set<'t>>() with member _.Clone s c ts = Set.map (tc.Clone s c) ts } }
   
           | Shape.FSharpMap s ->
               s.Accept {
  
positive.code:                     member _.Visit<'k, 'v when 'k : comparison> () =
                          let kc = mkClonerCached<'k> ctx
                          let vc = mkClonerCached<'v> ctx
                          EQ(fun s c (ts:Map<'k,'v>) -> ts |> Seq.map (fun kv -> kc s c kv.Key, vc s c kv.Value) |> Map.ofSeq) }
  
          | Shape.Tuple (:? ShapeTuple<'T> as shape) ->
              let memberCloners = shape.Elements |> Array.map mkMemberCloner
              fun s c source ->
                  let mutable target = shape.CreateUninitialized()
                  for mc in memberCloners do
                      target <- mc s c source target
                  target
  
          | Shape.FSharpRecord (:? ShapeFSharpRecord<'T> as shape) ->
              let memberCloners = shape.Fields |> Array.map mkMemberCloner
              fun s c source ->
                  let mutable target = shape.CreateUninitialized()
                  for mc in memberCloners do
                      target <- mc s c source target
                  target
  
          | Shape.FSharpUnion (:? ShapeFSharpUnion<'T> as shape) ->
              let caseMemberCloners = 
                  shape.UnionCases 
                  |> Array.map (fun c -> c.Fields |> Array.map mkMemberCloner)
  
              fun s c source ->
                  let tag = shape.GetTag source
                  let case = shape.UnionCases.[tag]
                  let memberCloners = caseMemberCloners.[tag]
                  let mutable target = case.CreateUninitialized()
                  for mc in memberCloners do
                      target <- mc s c source target
                  target
  
          | Shape.ISerializable s ->
              s.Accept { new ISerializableVisitor<Cloner<'T>> with
                  member _.Visit (shape : ShapeISerializable<'S>) =
                      fun s c (source : 'S) ->
                          let sc = new StreamingContext()
                          let si = new SerializationInfo(typeof<'S>, FormatterConverter())
                          let si' = new SerializationInfo(typeof<'S>, FormatterConverter())
  
                          source.GetObjectData(si, sc)
                          let e = si.GetEnumerator()
                          while e.MoveNext() do si'.AddValue(e.Name, cloneUntyped s c e.Value)
  
                          shape.Create(si, sc)
                      |> EQ }
  
          | Shape.CliMutable (:? ShapeCliMutable<'T> as shape) ->
              let memberCloners = shape.Properties |> Array.map mkMemberCloner
              fun s c source ->
                  let mutable target = shape.CreateUninitialized()
                  for mc in memberCloners do
                      target <- mc s c source target
                  target
  
          | Shape.Poco (:? ShapePoco<'T> as shape) ->
              let fieldCloners = shape.Fields |> Array.map mkMemberCloner
              fun s c source ->
                  let mutable target = shape.CreateUninitialized()
                  for fc in fieldCloners do
                      target <- fc s c source target
                  target
  
          | _ -> failwithf "Unsupported type %O" typeof<'T>
  
  
negative.code:         mkClonerCached<'T> ctx
  
      and cloneUntyped s c (o:obj) : obj =
          let t = o.GetType()
          let mutable res = Unchecked.defaultof<obj>
          let cloner =
              if cache.TryGetValue(t, &res) then res :?> Cloner
              else
                  let shape = TypeShape.Create t
                  shape.Accept { new ITypeVisitor<Cloner> with
                      member _.Visit<'T>() = mkCloner<'T>() :> Cloner }
  
          cloner.CloneUntyped s c o
  
      and mkRefEqCloner<'T> (cloner : Cloner<'T>) : Cloner<'T> =
          match shapeof<'T> with
  