anchor.diff:  [<Theory>]
   [<MemberData("HtmlReturningAcceptHeaderCases")>]
   let ``Get "/auto" with Accept header of "text/html" returns a 406 response`` (config : NegotiationConfigWithExpectedResult) =
  -    let johnDoe =
  -        {
  -            FirstName = "John"
  -            LastName  = "Doe"
  -            BirthDate = DateTime(1990, 7, 12)
  -            Height    = 1.85
  -            Piercings = [| "ear"; "nose" |]
  -        }
  -
  -    let ctx = Substitute.For<HttpContext>()
  -    mockNegotiation ctx config.NegotiationConfig
  -    let app =
  -        GET >=> choose [
  -            route "/"     >=> text "Hello World"
  -            route "/foo"  >=> text "bar"
  -            route "/auto" >=> negotiate johnDoe
  -            setStatusCode 404 >=> text "Not found" ]
  -
  -    let headers = HeaderDictionary()
  -    headers.Add("Accept", StringValues("text/html"))
  -    ctx.Items.Returns (new Dictionary<obj,obj>() :> IDictionary<obj,obj>) |> ignore
  -    ctx.Request.Method.ReturnsForAnyArgs "GET" |> ignore
  -    ctx.Request.Path.ReturnsForAnyArgs (PathString("/auto")) |> ignore
  -    ctx.Request.Headers.ReturnsForAnyArgs(headers) |> ignore
  -    ctx.Response.Body <- new MemoryStream()
  -    ctx.Response.StatusCode <- 200
  -
  +    let ctx = getNegotiationTestHttpContext config.NegotiationConfig None false (StringValues("text/html"))
  +    
       let expected = "text/html is unacceptable by the server."
  -
  -    task {
  -        let! result = app next ctx
  -
  -        match result with
  -        | None -> assertFailf "Result was expected to be %s" expected
  -        | Some ctx ->
  -            Assert.Equal(config.StatusCode, ctx.Response.StatusCode)
  -            if ctx.Response.StatusCode = 406 then
  -                let body = getBody ctx
  -                Assert.Equal(expected, body)
  -                Assert.Equal("text/plain; charset=utf-8", ctx.Response |> getContentType)
  -    }
  +    let testChecks (context : HttpContext) =
  +        Assert.Equal(config.StatusCode, context.Response.StatusCode)
  +        if context.Response.StatusCode = 406 then
  +            let body = getBody context
  +            Assert.Equal(expected, body)
  +            Assert.Equal("text/plain; charset=utf-8", context.Response |> getContentType)
  +    runNegotiationTest ctx expected testChecks
   
   [<Theory>]
   [<MemberData("JsonReturningAcceptHeaderCases")>]
   let ``Get "/auto" without an Accept header returns a JSON object`` (config : NegotiationConfigWithExpectedResult) =
  -    let johnDoe =
  -        {
  -            FirstName = "John"
  -            LastName  = "Doe"
  -            BirthDate = DateTime(1990, 7, 12)
  -            Height    = 1.85
  -            Piercings = [| "ear"; "nose" |]
  -        }
  -
  -    let ctx = Substitute.For<HttpContext>()
  -    mockJson ctx (Newtonsoft None)
  -    mockNegotiation ctx config.NegotiationConfig
  -    let app =
  -        GET >=> choose [
  -            route "/"     >=> text "Hello World"
  -            route "/foo"  >=> text "bar"
  -            route "/auto" >=> negotiate johnDoe
  -            setStatusCode 404 >=> text "Not found" ]
  -
  -    let headers = HeaderDictionary()
  -    ctx.Items.Returns (new Dictionary<obj,obj>() :> IDictionary<obj,obj>) |> ignore
  -    ctx.Request.Method.ReturnsForAnyArgs "GET" |> ignore
  -    ctx.Request.Path.ReturnsForAnyArgs (PathString("/auto")) |> ignore
  -    ctx.Request.Headers.ReturnsForAnyArgs(headers) |> ignore
  -    ctx.Response.Body <- new MemoryStream()
  -    ctx.Response.StatusCode <- 200
  -
  -    let expected = "{\"firstName\":\"John\",\"lastName\":\"Doe\",\"birthDate\":\"1990-07-12T00:00:00\",\"height\":1.85,\"piercings\":[\"ear\",\"nose\"]}"
  -
  -    task {
  -        let! result = app next ctx
  -
  -        match result with
  -        | None -> assertFailf "Result was expected to be %s" expected
  -        | Some ctx ->
  -            Assert.Equal(config.StatusCode, ctx.Response.StatusCode)
  -            if ctx.Response.StatusCode = 200 then
  -                let body = getBody ctx
  -                Assert.Equal(expected, body)
  -                Assert.Equal("application/json; charset=utf-8", ctx.Response |> getContentType)
  -    }
  -
  -[<Fact>]
  -let ``Warbler function should execute inner function each time`` () =
  -    let ctx = Substitute.For<HttpContext>()
  -    let inner() = Guid.NewGuid().ToString()
  -    let app =
  -        GET >=> choose [
  -            route "/foo"  >=> text (inner())
  -            route "/foo2" >=> warbler (fun _ -> text (inner())) ]
  -        <| next
  -
  -    ctx.Request.Method.ReturnsForAnyArgs "GET" |> ignore
  -    ctx.Request.Path.ReturnsForAnyArgs (PathString("/foo")) |> ignore
  -    ctx.Response.Body <- new MemoryStream()
  -
  -    task {
  -        let! res1 = app ctx
  -        let result1 = getBody res1.Value
  -
  -        ctx.Response.Body <- new MemoryStream()
  -
  -        let! res2 = app ctx
  -        let result2 = getBody res2.Value
  -
  -        Assert.Equal(result1, result2)
  -
  -        ctx.Request.Path.ReturnsForAnyArgs (PathString("/foo2")) |> ignore
  -        ctx.Response.Body <- new MemoryStream()
  -
  -        let! res3 = app ctx
  -        let result3 = getBody res3.Value
  -
  -        ctx.Response.Body <- new MemoryStream()
  -
  -        let! res4 = app ctx
  -        let result4 = getBody res4.Value
  -
  -        Assert.False(result3.Equals result4)
  -    }
  -
  -[<Fact>]
  -let ``GET "/redirect" redirect to "/" `` () =
  -    let ctx = Substitute.For<HttpContext>()
  -    let app =
  -        GET >=> choose [
  -            route "/"         >=> text "Hello World"
  -            route "/redirect" >=> redirectTo false "/"
  -            setStatusCode 404 >=> text "Not found" ]
  -
  -    ctx.Request.Method.ReturnsForAnyArgs "GET" |> ignore
  -    ctx.Request.Path.ReturnsForAnyArgs (PathString("/redirect")) |> ignore
  -
  -    task {
  -        let! result = app next ctx
  -
  -        match result with
  -        | None     -> assertFail "It was expected that the request would be redirected"
  -        | Some ctx -> ctx.Response.Received().Redirect("/", false)
  -
  -    }
  -
  -[<Fact>]
  -let ``POST "/redirect" redirect to "/" `` () =
  -    let ctx = Substitute.For<HttpContext>()
  -    let app =
  -        POST >=> choose [
  -            route "/"         >=> text "Hello World"
  -            route "/redirect" >=> redirectTo true "/"
  -            setStatusCode 404 >=> text "Not found" ]
  -
  -    ctx.Request.Method.ReturnsForAnyArgs "POST" |> ignore
  -    ctx.Request.Path.ReturnsForAnyArgs (PathString("/redirect")) |> ignore
  -
  -    task {
  -        let! result = app next ctx
  -
  -        match result with
  -        | None     -> assertFail "It was expected that the request would be redirected"
  -        | Some ctx -> ctx.Response.Received().Redirect("/", true)
  -    }+    let ctx = getNegotiationTestHttpContext config.NegotiationConfig (Some (Newtonsoft None)) false StringValues.Empty
  +    let testChecks (ctx : HttpContext) =
  +        Assert.Equal(config.StatusCode, ctx.Response.StatusCode)
  +        if ctx.Response.StatusCode = 200 then
  +            let body = getBody ctx
  +            Assert.Equal(johnDoeAsJson, body)
  +            Assert.Equal("application/json; charset=utf-8", ctx.Response |> getContentType)
  +    runNegotiationTest ctx johnDoeAsJson testChecks
  
positive.code:             Assert.Equal(expected, body)
              Assert.Equal(404, ctx.Response.StatusCode)
      }
  
  let JsonReturningAcceptHeaderCases =
      [
          {NegotiationConfig = JsonOnlyNegotiationConfig() :> INegotiationConfig; StatusCode = 200; ReturnContentType = "application/json; charset=utf-8"}
          {NegotiationConfig = DefaultNegotiationConfig() :> INegotiationConfig; StatusCode = 200; ReturnContentType = "application/json; charset=utf-8"}
      ] |> toTheoryData
  
  [<Theory>]
  [<MemberData("JsonReturningAcceptHeaderCases")>]
  let ``Get "/auto" with Accept header of "application/json" returns JSON object`` (config : NegotiationConfigWithExpectedResult) =
      let johnDoe =
          {
              FirstName = "John"
              LastName  = "Doe"
              BirthDate = DateTime(1990, 7, 12)
              Height    = 1.85
              Piercings = [| "left ear"; "nose" |]
          }
  
      let ctx = Substitute.For<HttpContext>()
      mockJson ctx (Newtonsoft None)
      mockNegotiation ctx config.NegotiationConfig
      let app =
          GET >=> choose [
              route "/"     >=> text "Hello World"
              route "/foo"  >=> text "bar"
              route "/auto" >=> negotiate johnDoe
              setStatusCode 404 >=> text "Not found" ]
  
      let headers = HeaderDictionary()
      headers.Add("Accept", StringValues("application/json"))
      ctx.Items.Returns (new Dictionary<obj,obj>() :> IDictionary<obj,obj>) |> ignore
      ctx.Request.Method.ReturnsForAnyArgs "GET" |> ignore
      ctx.Request.Path.ReturnsForAnyArgs (PathString("/auto")) |> ignore
      ctx.Request.Headers.ReturnsForAnyArgs(headers) |> ignore
      ctx.Response.Body <- new MemoryStream()
      ctx.Response.StatusCode <- 200
  
      let expected = "{\"firstName\":\"John\",\"lastName\":\"Doe\",\"birthDate\":\"1990-07-12T00:00:00\",\"height\":1.85,\"piercings\":[\"left ear\",\"nose\"]}"
  
      task {
          let! result = app next ctx
  
          match result with
          | None -> assertFailf "Result was expected to be %s" expected
          | Some ctx ->
              let body = getBody ctx
              Assert.Equal(expected, body)
              Assert.Equal(config.StatusCode, ctx.Response.StatusCode)
              Assert.Equal(config.ReturnContentType, ctx.Response |> getContentType)
      }
  
  [<Theory>]
  [<MemberData("JsonReturningAcceptHeaderCases")>]
  let ``Get "/auto" with Accept header of "application/xml; q=0.9, application/json" returns JSON object`` (config : NegotiationConfigWithExpectedResult) =
      let johnDoe =
          {
              FirstName = "John"
              LastName  = "Doe"
              BirthDate = DateTime(1990, 7, 12)
              Height    = 1.85
              Piercings = [| "left ear"; "nose" |]
          }
  
      let ctx = Substitute.For<HttpContext>()
      mockJson ctx (Newtonsoft None)
      mockNegotiation ctx config.NegotiationConfig
      let app =
          GET >=> choose [
              route "/"     >=> text "Hello World"
              route "/foo"  >=> text "bar"
              route "/auto" >=> negotiate johnDoe
              setStatusCode 404 >=> text "Not found" ]
  
      let headers = HeaderDictionary()
      headers.Add("Accept", StringValues("application/xml; q=0.9, application/json"))
      ctx.Items.Returns (new Dictionary<obj,obj>() :> IDictionary<obj,obj>) |> ignore
      ctx.Request.Method.ReturnsForAnyArgs "GET" |> ignore
      ctx.Request.Path.ReturnsForAnyArgs (PathString("/auto")) |> ignore
      ctx.Request.Headers.ReturnsForAnyArgs(headers) |> ignore
      ctx.Response.Body <- new MemoryStream()
      ctx.Response.StatusCode <- 200
  
      let expected = "{\"firstName\":\"John\",\"lastName\":\"Doe\",\"birthDate\":\"1990-07-12T00:00:00\",\"height\":1.85,\"piercings\":[\"left ear\",\"nose\"]}"
  
      task {
          let! result = app next ctx
  
          match result with
          | None -> assertFailf "Result was expected to be %s" expected
          | Some ctx ->
              Assert.Equal(config.StatusCode, ctx.Response.StatusCode)
              if ctx.Response.StatusCode = 200 then
                  let body = getBody ctx
                  Assert.Equal(expected, body)
                  Assert.Equal(config.ReturnContentType, ctx.Response |> getContentType)
      }
  
  let XmlReturningAcceptHeaderCases =
      [
          {NegotiationConfig = JsonOnlyNegotiationConfig() :> INegotiationConfig; StatusCode = 406; ReturnContentType = ""}
          {NegotiationConfig = DefaultNegotiationConfig() :> INegotiationConfig; StatusCode = 200; ReturnContentType = "application/xml; charset=utf-8"}
      ] |> toTheoryData
  
  [<Theory>]
  [<MemberData("XmlReturningAcceptHeaderCases")>]
  let ``Get "/auto" with Accept header of "application/xml" returns XML object`` (config : NegotiationConfigWithExpectedResult) =
      let johnDoe =
          {
              FirstName = "John"
              LastName  = "Doe"
              BirthDate = DateTime(1990, 7, 12)
              Height    = 1.85
              Piercings = [| "ear"; "nose" |]
          }
  
      let ctx = Substitute.For<HttpContext>()
      mockXml ctx
      mockNegotiation ctx config.NegotiationConfig
      let app =
          GET >=> choose [
              route "/"     >=> text "Hello World"
              route "/foo"  >=> text "bar"
              route "/auto" >=> negotiate johnDoe
              setStatusCode 404 >=> text "Not found" ]
  
      let headers = HeaderDictionary()
      headers.Add("Accept", StringValues("application/xml"))
      ctx.Items.Returns (new Dictionary<obj,obj>() :> IDictionary<obj,obj>) |> ignore
      ctx.Request.Method.ReturnsForAnyArgs "GET" |> ignore
      ctx.Request.Path.ReturnsForAnyArgs (PathString("/auto")) |> ignore
      ctx.Request.Headers.ReturnsForAnyArgs(headers) |> ignore
      ctx.Response.Body <- new MemoryStream()
      ctx.Response.StatusCode <- 200
  
      let expected = @"<?xml version=""1.0"" encoding=""utf-8""?>
  <Person xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">
    <FirstName>John</FirstName>
    <LastName>Doe</LastName>
  
negative.code: [<Theory>]
  [<MemberData("TextReturningAcceptHeaderCases")>]
  let ``Get "/auto" with Accept header of "text/plain; q=0.7, application/xml; q=0.6" returns text object`` (config : NegotiationConfigWithExpectedResult) =
      let ctx = getNegotiationTestHttpContext config.NegotiationConfig None false (StringValues("text/plain; q=0.7, application/xml; q=0.6"))
      let testChecks (context : HttpContext) =
          Assert.Equal(config.StatusCode, context.Response.StatusCode)
          if context.Response.StatusCode = 200 then
              let body = getBody context
              Assert.Equal(johnDoeAsText, body)
              Assert.Equal(config.ReturnContentType, context.Response |> getContentType)
      runNegotiationTest ctx johnDoeAsText testChecks
  
  let HtmlReturningAcceptHeaderCases =
      [
  