anchor.diff:                  sprintf "Type '%O' is not an F# union" typeof<'Union>
                   |> invalidArg "Union"
   
  -        let mkFieldEncoders (field : IShapeMember<'Union>) (encoder : IEncoder<'Format>) =
  -            field.Accept {
  -                new IMemberVisitor<'Union, ('Union -> 'Format) * ('Union -> 'Format -> 'Union)> with
  -                    member _.Visit(sfield : ShapeMember<'Union, 'Field>) =
  -                        let enc u =
  -                            let f = sfield.Get u
  -                            encoder.Encode f
  -
  -                        let dec u f =
  -                            let v = encoder.Decode f
  -                            sfield.Set u v
  -
  -                        enc, dec
  -            }
  -
           let hasRecordPayload (scase : ShapeFSharpUnionCase<'Union>) =
               match scase.Fields with
               | [| |] -> true // support as trivial case
  
positive.code:                 |> Array.map (fun e -> e encoder)
                  |> Array.unzip
  
              { new UnionContractEncoder<'Union, 'Format>() with
                  member _.GetCaseName(u:'Union) =
                      let tag = shape.GetTag u
                      labels.[tag]
  
                  member _.Encode(u:'Union) =
                      let tag = shape.GetTag u
                      caseEncoders.[tag] u
  
                  member _.Decode e =
                      match labelIndex.TryFindIndex e.CaseName with
                      |  -1 ->
                          let msg = sprintf "Unrecognized case name '%O.%s'" typeof<'Union> e.CaseName
                          raise <| FormatException msg
                      | tag -> caseDecoders.[tag] e.Payload
  
                  member _.TryDecode e =
                      match labelIndex.TryFindIndex e.CaseName with
                      |  -1 -> None
                      | tag -> caseDecoders.[tag] e.Payload |> Some }
  
      type EncoderFactory<'Union, 'Format> private () =
          static let factory = lazy(mkUnionEncoder<'Union, 'Format>())
          static member Create requireRecordFields (e : IEncoder<_>) = factory.Value requireRecordFields e
  
  
  type UnionContractEncoder =
  
  
negative.code:     }
  
  /// Provides an encoder implementation for a union of events
  [<Sealed>]
  type UnionContractEncoder<'Union, 'Format> internal 
      (shape : ShapeFSharpUnion<'Union>,
       labelIndex : BinSearch,
       caseEncoders : Func<'Union, EncodedUnion<'Format>>[],
       caseDecoders : Func<'Format, 'Union>[]) =
  
      /// Gets the union case string identifier for given union instance
      member _.GetCaseName (value:'Union) : string =
          let tag = shape.GetTagByRef &value
          labelIndex.Values.[tag]
  
      /// Encodes a union instance into a decoded representation
      member _.Encode (value:'Union) : EncodedUnion<'Format> =
          let tag = shape.GetTagByRef &value
          caseEncoders.[tag].Invoke value
  
      /// Decodes a formatted representation into a union instance. Can potentially throw FormatException
      member _.Decode (encodedUnion:EncodedUnion<'Format>) : 'Union =
          let unrecognizedCaseName(caseName : string) =
              let msg = sprintf "Unrecognized case name '%O.%s'" typeof<'Union> caseName
              raise <| FormatException msg
  
          match labelIndex.TryFindIndex encodedUnion.CaseName with
          |  -1 -> unrecognizedCaseName encodedUnion.CaseName
          | tag -> caseDecoders.[tag].Invoke encodedUnion.Payload
  
      /// Decodes a formatted representation into a union instance. Does not throw exception on format mismatches
      member _.TryDecode (encodedUnion:EncodedUnion<'Format>) : 'Union option =
          match labelIndex.TryFindIndex encodedUnion.CaseName with
          |  -1 -> None
          | tag -> caseDecoders.[tag].Invoke encodedUnion.Payload |> Some
  
  [<AutoOpen>]
  module private Impl =
  