@testset "ThermalGen data misspecification" begin
    # See https://discourse.julialang.org/t/how-to-use-test-warn/15557/5 about testing for warning throwing
    warn_message = "The data doesn't include devices of type ThermalStandard, consider changing the device models"
    model = DeviceModel(ThermalStandard, PSI.ThermalStandardUnitCommitment)
    op_problem = OperationsProblem(TestOpProblem, DCPPowerModel, c_sys5_re_only)
    @test_logs (:warn, warn_message) construct_device!(op_problem, :Thermal, model)
end

################################### Unit Commitment tests ##################################
@testset "Thermal UC With DC - PF" begin
    bin_variable_names = [:ON_ThermalStandard,
                          :START_ThermalStandard,
                          :STOP_ThermalStandard]
    uc_constraint_names = [:ramp_up_ThermalStandard,
                           :ramp_dn_ThermalStandard,
                           :duration_up_ThermalStandard,
                           :duration_dn_ThermalStandard]
    model = DeviceModel(PSY.ThermalStandard, PSI.ThermalStandardUnitCommitment)

    @info "5-Bus testing"
    op_problem = OperationsProblem(TestOpProblem, DCPPowerModel, c_sys5_uc)
    construct_device!(op_problem, :Thermal, model)
    moi_tests(op_problem, false, 480, 0, 480, 120, 120, true)
    psi_constraint_test(op_problem, uc_constraint_names)
    psi_checkbinvar_test(op_problem, bin_variable_names)
    psi_checkobjfun_test(op_problem, GAEVF)

    op_problem = OperationsProblem(TestOpProblem, DCPPowerModel, c_sys5_uc; use_parameters = true)
    construct_device!(op_problem, :Thermal, model)
    moi_tests(op_problem, true, 480, 0, 480, 120, 120, true)
    psi_constraint_test(op_problem, uc_constraint_names)
    psi_checkbinvar_test(op_problem, bin_variable_names)
    psi_checkobjfun_test(op_problem, GAEVF)

    @info "14-Bus testing"
    for p in [true, false]
        op_problem = OperationsProblem(TestOpProblem, DCPPowerModel, c_sys14; use_parameters = p)
        construct_device!(op_problem, :Thermal, model)
        moi_tests(op_problem, p, 480, 0, 240, 120, 120, true)
        psi_checkbinvar_test(op_problem, bin_variable_names)
        psi_checkobjfun_test(op_problem, GQEVF)
    end
end

@testset "Thermal UC With AC - PF" begin
    bin_variable_names = [:ON_ThermalStandard,
                          :START_ThermalStandard,
                          :STOP_ThermalStandard]
    uc_constraint_names = [:ramp_up_ThermalStandard,
                           :ramp_dn_ThermalStandard,
                           :duration_up_ThermalStandard,
                           :duration_dn_ThermalStandard]
    model = DeviceModel(PSY.ThermalStandard, PSI.ThermalStandardUnitCommitment)

    @info "5-Bus testing"
    op_problem = OperationsProblem(TestOpProblem, ACPPowerModel, c_sys5_uc)
    construct_device!(op_problem, :Thermal, model)
    moi_tests(op_problem, false, 600, 0, 600, 240, 120, true)
    psi_constraint_test(op_problem, uc_constraint_names)
    psi_checkbinvar_test(op_problem, bin_variable_names)
    psi_checkobjfun_test(op_problem, GAEVF)

    op_problem = OperationsProblem(TestOpProblem, ACPPowerModel, c_sys5_uc; use_parameters = true)
    construct_device!(op_problem, :Thermal, model)
    moi_tests(op_problem, true, 600, 0, 600, 240, 120, true)
    psi_constraint_test(op_problem, uc_constraint_names)
    psi_checkbinvar_test(op_problem, bin_variable_names)
    psi_checkobjfun_test(op_problem, GAEVF)

    @info "14-Bus testing"
    for p in [true, false]
        op_problem = OperationsProblem(TestOpProblem, ACPPowerModel, c_sys14; use_parameters = p)
        construct_device!(op_problem, :Thermal, model)
        moi_tests(op_problem, p, 600, 0, 360, 240, 120, true)
        psi_checkbinvar_test(op_problem, bin_variable_names)
        psi_checkobjfun_test(op_problem, GQEVF)
    end
end

################################### Basic Unit Commitment tests ############################
@testset "Thermal Basic UC With DC - PF" begin
    bin_variable_names = [:ON_ThermalStandard,
                          :START_ThermalStandard,
                          :STOP_ThermalStandard]
    model = DeviceModel(PSY.ThermalStandard, PSI.ThermalBasicUnitCommitment)

    @info "5-Bus testing"
    op_problem = OperationsProblem(TestOpProblem, DCPPowerModel, c_sys5_uc)
    construct_device!(op_problem, :Thermal, model)
    moi_tests(op_problem, false, 480, 0, 240, 120, 120, true)
    psi_checkbinvar_test(op_problem, bin_variable_names)
    psi_checkobjfun_test(op_problem, GAEVF)

    op_problem = OperationsProblem(TestOpProblem, DCPPowerModel, c_sys5_uc; use_parameters = true)
    construct_device!(op_problem, :Thermal, model)
    moi_tests(op_problem, true, 480, 0, 240, 120, 120, true)
    psi_checkbinvar_test(op_problem, bin_variable_names)
    psi_checkobjfun_test(op_problem, GAEVF)

    @info "14-Bus testing"
    for p in [true, false]
        op_problem = OperationsProblem(TestOpProblem, DCPPowerModel, c_sys14; use_parameters = p)
        construct_device!(op_problem, :Thermal, model)
        moi_tests(op_problem, p, 480, 0, 240, 120, 120, true)
        psi_checkbinvar_test(op_problem, bin_variable_names)
        psi_checkobjfun_test(op_problem, GQEVF)
    end
end

@testset "Thermal Basic UC With AC - PF" begin
    bin_variable_names = [:ON_ThermalStandard,
                          :START_ThermalStandard,
                          :STOP_ThermalStandard]
     model = DeviceModel(PSY.ThermalStandard, PSI.ThermalBasicUnitCommitment)

    @info "5-Bus testing"
    op_problem = OperationsProblem(TestOpProblem, ACPPowerModel, c_sys5_uc)
    construct_device!(op_problem, :Thermal, model)
    moi_tests(op_problem, false, 600, 0, 360, 240, 120, true)
    psi_checkbinvar_test(op_problem, bin_variable_names)
    psi_checkobjfun_test(op_problem, GAEVF)

    op_problem = OperationsProblem(TestOpProblem, ACPPowerModel, c_sys5_uc; use_parameters = true)
    construct_device!(op_problem, :Thermal, model)
    moi_tests(op_problem, true, 600, 0, 360, 240, 120, true)
    psi_checkbinvar_test(op_problem, bin_variable_names)
    psi_checkobjfun_test(op_problem, GAEVF)

    @info "14-Bus testing"
    for p in [true, false]
        op_problem = OperationsProblem(TestOpProblem, ACPPowerModel, c_sys14; use_parameters = p)
        construct_device!(op_problem, :Thermal, model)
        moi_tests(op_problem, p, 600, 0, 360, 240, 120, true)
        psi_checkbinvar_test(op_problem, bin_variable_names)
        psi_checkobjfun_test(op_problem, GQEVF)
    end
end

################################### Basic Dispatch tests ###################################
@testset "Thermal Dispatch With DC - PF" begin
    model = DeviceModel(PSY.ThermalStandard, PSI.ThermalDispatch)
    @info "5-Bus testing"
    for p in [true, false]
        op_problem = OperationsProblem(TestOpProblem, DCPPowerModel, c_sys5; use_parameters = p)
        construct_device!(op_problem, :Thermal, model)
        moi_tests(op_problem, p, 120, 120, 0, 0, 0, false)
        psi_checkobjfun_test(op_problem, GAEVF)
    end

    @info "14-Bus testing"
    for p in [true, false]
        op_problem = OperationsProblem(TestOpProblem, DCPPowerModel, c_sys14; use_parameters = p)
        construct_device!(op_problem, :Thermal, model)
        moi_tests(op_problem, p, 120, 120, 0, 0, 0, false)
        psi_checkobjfun_test(op_problem, GQEVF)
    end
end

@testset "Thermal Dispatch With AC - PF" begin
    model = DeviceModel(PSY.ThermalStandard, PSI.ThermalDispatch)
    @info "5-Bus testing"
    for p in [true, false]
        op_problem = OperationsProblem(TestOpProblem, ACPPowerModel, c_sys5; use_parameters = p)
        construct_device!(op_problem, :Thermal, model)
        moi_tests(op_problem, p, 240, 240, 0, 0, 0, false)
        psi_checkobjfun_test(op_problem, GAEVF)
    end

    @info "14-Bus testing"
    for p in [true, false]
        op_problem = OperationsProblem(TestOpProblem, ACPPowerModel, c_sys14; use_parameters = p)
        construct_device!(op_problem, :Thermal, model)
        moi_tests(op_problem, p, 240, 240, 0, 0, 0, false)
        psi_checkobjfun_test(op_problem, GQEVF)
    end
end

################################### No Minimum Dispatch tests ##############################

@testset "Thermal Dispatch NoMin With DC - PF" begin
    model = DeviceModel(PSY.ThermalStandard, PSI.ThermalDispatchNoMin)
    @info "5-Bus testing"
    for p in [true, false]
        op_problem = OperationsProblem(TestOpProblem, DCPPowerModel, c_sys5; use_parameters = p)
        construct_device!(op_problem, :Thermal, model)
        moi_tests(op_problem, p, 120, 120, 0, 0, 0, false)
        moi_lbvalue_test(op_problem, :activerange_ThermalStandard, 0.0)
        psi_checkobjfun_test(op_problem, GAEVF)
    end

    @info "14-Bus testing"
    for p in [true, false]
        op_problem = OperationsProblem(TestOpProblem, DCPPowerModel, c_sys14; use_parameters = p)
        construct_device!(op_problem, :Thermal, model)
        moi_tests(op_problem, p, 120, 120, 0, 0, 0, false)
        moi_lbvalue_test(op_problem, :activerange_ThermalStandard, 0.0)
        psi_checkobjfun_test(op_problem, GQEVF)
    end
end

@testset "Thermal Dispatch NoMin With AC - PF" begin
    model = DeviceModel(PSY.ThermalStandard, PSI.ThermalDispatchNoMin)
    @info "5-Bus testing"
    for p in [true, false]
        op_problem = OperationsProblem(TestOpProblem, ACPPowerModel, c_sys5; use_parameters = p)
        construct_device!(op_problem, :Thermal, model)
        moi_tests(op_problem, p, 240, 240, 0, 0, 0, false)
        moi_lbvalue_test(op_problem, :activerange_ThermalStandard, 0.0)
        psi_checkobjfun_test(op_problem, GAEVF)
    end

    @info "14-Bus testing"
    for p in [true, false]
        op_problem = OperationsProblem(TestOpProblem, ACPPowerModel, c_sys14; use_parameters = p)
        construct_device!(op_problem, :Thermal, model)
        moi_tests(op_problem, p, 240, 240, 0, 0, 0, false)
        moi_lbvalue_test(op_problem, :activerange_ThermalStandard, 0.0)
        psi_checkobjfun_test(op_problem, GQEVF)
    end
end

################################### Ramp Limited Testing ##################################
@testset "Thermal Ramp Limited Dispatch With DC - PF" begin
    constraint_names = [:ramp_up_ThermalStandard, :ramp_dn_ThermalStandard]
    model = DeviceModel(PSY.ThermalStandard, PSI.ThermalRampLimited)
    @info "5-Bus testing"
    for p in [true, false]
        op_problem = OperationsProblem(TestOpProblem, DCPPowerModel, c_sys5_uc; use_parameters = p)
        construct_device!(op_problem, :Thermal, model)
        moi_tests(op_problem, p, 120, 120, 96, 0, 0, false)
        psi_constraint_test(op_problem, constraint_names)
        psi_checkobjfun_test(op_problem, GAEVF)
    end

    @info "14-Bus testing"
    for p in [true, false]
        op_problem = OperationsProblem(TestOpProblem, DCPPowerModel, c_sys14; use_parameters = p)
        construct_device!(op_problem, :Thermal, model)
        moi_tests(op_problem, p, 120, 120, 0, 0, 0, false)
        psi_checkobjfun_test(op_problem, GQEVF)
    end
end

@testset "Thermal Ramp Limited Dispatch With AC - PF" begin
    constraint_names = [:ramp_up_ThermalStandard, :ramp_dn_ThermalStandard]
    model = DeviceModel(PSY.ThermalStandard, PSI.ThermalRampLimited)
    @info "5-Bus testing"
    for p in [true, false]
        op_problem = OperationsProblem(TestOpProblem, ACPPowerModel, c_sys5_uc; use_parameters = p)
        construct_device!(op_problem, :Thermal, model)
        moi_tests(op_problem, p, 240, 240, 96, 0, 0, false)
        psi_constraint_test(op_problem, constraint_names)
        psi_checkobjfun_test(op_problem, GAEVF)
    end

    @info "14-Bus testing"
    for p in [true, false]
        op_problem = OperationsProblem(TestOpProblem, ACPPowerModel, c_sys14; use_parameters = p)
        construct_device!(op_problem, :Thermal, model)
        moi_tests(op_problem, p, 240, 240, 0, 0, 0, false)
        psi_checkobjfun_test(op_problem, GQEVF)
    end
end

############################# UC validation tests ##########################################
branches = Dict{Symbol, PSI.DeviceModel}()
services = Dict{Symbol, PSI.ServiceModel}()
ED_devices = Dict{Symbol, DeviceModel}(:Generators => PSI.DeviceModel(PSY.ThermalStandard, PSI.ThermalRampLimited),
                                        :Loads =>  PSI.DeviceModel(PSY.PowerLoad, PSI.StaticPowerLoad))
UC_devices = Dict{Symbol, DeviceModel}(:Generators => DeviceModel(PSY.ThermalStandard, PSI.ThermalStandardUnitCommitment),
                                        :Loads =>  DeviceModel(PSY.PowerLoad, PSI.StaticPowerLoad))
# Testing Ramping Constraint
@testset "Solving UC with CopperPlate for testing Ramping Constraints" begin
node = Bus(1,"nodeA", "PV", 0, 1.0, (min = 0.9, max=1.05), 230)
load = PowerLoad("Bus1", true, node,nothing, 0.4, 0.9861, 1.0, 2.0)
    DA_ramp = collect(DateTime("1/1/2024  0:00:00", "d/m/y  H:M:S"):
                        Hour(1):
                        DateTime("1/1/2024  4:00:00", "d/m/y  H:M:S"))
    gen_ramp = [ThermalStandard("Alta", true, node,0.20, 0.010,
            TechThermal(0.5,PSY.PrimeMovers(6),PSY.ThermalFuels(6),
                            (min=0.0, max=0.40), nothing,
                            nothing, nothing),
            ThreePartCost((0.0, 1400.0), 0.0, 4.0, 2.0)
            ),
            ThermalStandard("Park City", true, node,0.70,0.20,
                TechThermal(2.0,PSY.PrimeMovers(6),PSY.ThermalFuels(6),
                            (min=0.7, max=2.20), nothing,
                            (up = 0.010625, down= 0.010625),nothing),
                ThreePartCost((0.0, 1500.0), 0.0, 1.5, 0.75)
            )];
    ramp_load = [ 0.9, 1.1, 2.485, 2.175, 0.9];
    load_forecast_ramp = Deterministic("get_maxactivepower", TimeArray(DA_ramp, ramp_load))
    ramp_test_sys = PSY.System(100.0)
    add_component!(ramp_test_sys, node)
    add_component!(ramp_test_sys, load)
    add_component!(ramp_test_sys, gen_ramp[1])
    add_component!(ramp_test_sys, gen_ramp[2])
    add_forecast!(ramp_test_sys, load, load_forecast_ramp)

    template = OperationsTemplate(CopperPlatePowerModel, ED_devices, branches, services)
    ED = OperationsProblem(TestOpProblem, template,
                        ramp_test_sys; optimizer = Cbc_optimizer,
                        use_parameters = true)
    psi_checksolve_test(ED, [MOI.OPTIMAL], 11191.00)
    moi_tests(ED, true, 10, 10, 10, 0, 5, false)
end

# Testing Duration Constraints
@testset "Solving UC with CopperPlate for testing Duration Constraints" begin
node = Bus(1,"nodeA", "PV", 0, 1.0, (min = 0.9, max=1.05), 230)
load = PowerLoad("Bus1", true, node,nothing, 0.4, 0.9861, 1.0, 2.0)
    DA_dur  = collect(DateTime("1/1/2024  0:00:00", "d/m/y  H:M:S"):
                        Hour(1):
                        DateTime("1/1/2024  6:00:00", "d/m/y  H:M:S"))
    gens_dur = [ThermalStandard("Alta", true, node,0.40, 0.010,
            TechThermal(0.5,PSY.PrimeMovers(6),PSY.ThermalFuels(6),
                            (min=0.3, max=0.9), nothing,
                            nothing, (up=4, down=2)),
            ThreePartCost((0.0, 1400.0), 0.0, 4.0, 2.0)
            ),
            ThermalStandard("Park City", true, node,1.70,0.20,
                TechThermal(2.2125,PSY.PrimeMovers(6),PSY.ThermalFuels(6),
                                (min=0.7, max=2.2), nothing,
                                nothing, (up=6, down=4)),
                ThreePartCost((0.0, 1500.0), 0.0, 1.5, 0.75)
            )];

    duration_load = [0.3, 0.6, 0.8, 0.7, 1.7, 0.9, 0.7]
    load_forecast_dur = Deterministic("get_maxactivepower", TimeArray(DA_dur, duration_load))
    duration_test_sys = PSY.System(100.0)
    add_component!(duration_test_sys, node)
    add_component!(duration_test_sys, load)
    add_component!(duration_test_sys, gens_dur[1])
    add_component!(duration_test_sys, gens_dur[2])
    add_forecast!(duration_test_sys, load, load_forecast_dur)

    status = [1.0,0.0]
    up_time = [2.0,0.0]
    down_time = [0.0,3.0]

    alta = gens_dur[1]
    init_cond = PSI.DICKDA()
    init_cond[PSI.ICKey(PSI.DeviceStatus,typeof(alta))] = build_init(gens_dur, status)
    init_cond[PSI.ICKey(PSI.TimeDurationON,typeof(alta))] = build_init(gens_dur, up_time)
    init_cond[PSI.ICKey(PSI.TimeDurationOFF,typeof(alta))] = build_init(gens_dur, down_time)

    template = OperationsTemplate(CopperPlatePowerModel, UC_devices, branches, services)
    UC = OperationsProblem(TestOpProblem, template,
                        duration_test_sys; optimizer = Cbc_optimizer,
                        use_parameters = true, initial_conditions = init_cond)
    psi_checksolve_test(UC, [MOI.OPTIMAL], 8223.50)
    moi_tests(UC, true, 56, 0, 56, 14, 21, true)
end

## PWL linear Cost implementation test
@testset "Solving UC with CopperPlate testing Linear PWL" begin
node = Bus(1,"nodeA", "PV", 0, 1.0, (min = 0.9, max=1.05), 230)
load = PowerLoad("Bus1", true, node,nothing, 0.4, 0.9861, 1.0, 2.0)
    gens_cost = [ThermalStandard("Alta", true, node,0.52, 0.010,
            TechThermal(0.5,PSY.PrimeMovers(6),PSY.ThermalFuels(6),
                            (min = 0.22, max = 0.55), nothing,
                            nothing, nothing),
            ThreePartCost([ (589.99, 0.220),(884.99, 0.33)
                    ,(1210.04, 0.44),(1543.44, 0.55)],532.44, 5665.23, 0.0)
            ),
            ThermalStandard("Park City", true, node,0.62,0.20,
                TechThermal(2.2125,PSY.PrimeMovers(6),PSY.ThermalFuels(6),
                            (min = 0.62, max = 1.55), nothing,
                            nothing, nothing),
                ThreePartCost([   (1264.80, 0.62),(1897.20, 0.93),
                    (2594.4787, 1.24),(3433.04, 1.55)   ], 235.397, 5665.23, 0.0)
            )];
    DA_cost  = collect(DateTime("1/1/2024  0:00:00", "d/m/y  H:M:S"):
                        Hour(1):
                        DateTime("1/1/2024  1:00:00", "d/m/y  H:M:S"))
    cost_load = [1.3,2.1];
    load_forecast_cost = Deterministic("get_maxactivepower", TimeArray(DA_cost, cost_load))
    cost_test_sys = PSY.System(100.0)
    add_component!(cost_test_sys, node)
    add_component!(cost_test_sys, load)
    add_component!(cost_test_sys, gens_cost[1])
    add_component!(cost_test_sys, gens_cost[2])
    add_forecast!(cost_test_sys, load, load_forecast_cost)

    template = OperationsTemplate(CopperPlatePowerModel, UC_devices, branches, services)
    UC = OperationsProblem(TestOpProblem, template,
                        cost_test_sys; optimizer = Cbc_optimizer,
                        use_parameters = true)
    psi_checksolve_test(UC, [MOI.OPTIMAL], 9336.736919354838)
    moi_tests(UC, true, 32, 0, 8, 4, 10, true)
end

## PWL SOS-2 Cost implementation test
@testset "Solving UC with CopperPlate testing SOS2 implementation" begin
    node = Bus(1,"nodeA", "PV", 0, 1.0, (min = 0.9, max=1.05), 230)
    load = PowerLoad("Bus1", true, node,nothing, 0.4, 0.9861, 1.0, 2.0)
    gens_cost_sos = [ThermalStandard("Alta", true, node,0.52, 0.010,
            TechThermal(0.5,PSY.PrimeMovers(6),PSY.ThermalFuels(6),
                            (min = 0.22, max = 0.55), nothing,
                            nothing, nothing),
            ThreePartCost([ (1122.43, 0.22),(1417.43, 0.33),
                    (1742.48, 0.44),(2075.88, 0.55) ],0.0, 5665.23, 0.0)
            ),
            ThermalStandard("Park City", true, node,0.62,0.20,
                TechThermal(2.2125,PSY.PrimeMovers(6),PSY.ThermalFuels(6),
                            (min = 0.62, max = 1.55), nothing,
                            nothing, nothing),
                ThreePartCost([ (1500.19, 0.62),(2132.59, 0.929),
                    (2829.875, 1.24),(3668.444, 1.55)], 0.0, 5665.23, 0.0)
            )];
    DA_cost_sos   = collect(DateTime("1/1/2024  0:00:00", "d/m/y  H:M:S"):
                        Hour(1):
                        DateTime("1/1/2024  1:00:00", "d/m/y  H:M:S"))
    cost_sos_load = [1.3,2.1];
    load_forecast_cost_sos  = Deterministic("get_maxactivepower", TimeArray(DA_cost_sos, cost_sos_load))
    cost_test_sos_sys = PSY.System(100.0)
    add_component!(cost_test_sos_sys, node)
    add_component!(cost_test_sos_sys, load)
    add_component!(cost_test_sos_sys, gens_cost_sos[1])
    add_component!(cost_test_sos_sys, gens_cost_sos[2])
    add_forecast!(cost_test_sos_sys, load, load_forecast_cost_sos)

    template = OperationsTemplate(CopperPlatePowerModel, UC_devices, branches, services)
    UC = OperationsProblem(TestOpProblem, template,
                        cost_test_sos_sys; optimizer = Cbc_optimizer,
                        use_parameters = true)
    psi_checksolve_test(UC, [MOI.OPTIMAL], 9336.736919,10.0)
    moi_tests(UC, true, 32, 0, 8, 4, 14, true)
end


@test first(evaluate5(A♣, A♡, A♢, K♠, Q♢)) == 1610 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, K♠, J♢)) == 1611 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, K♠, T♢)) == 1612 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, K♠, 9♢)) == 1613 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, K♠, 8♢)) == 1614 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, K♠, 7♢)) == 1615 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, K♠, 6♢)) == 1616 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, K♠, 5♢)) == 1617 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, K♠, 4♢)) == 1618 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, K♠, 3♢)) == 1619 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, K♠, 2♢)) == 1620 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, Q♠, J♢)) == 1621 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, Q♠, T♢)) == 1622 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, Q♠, 9♢)) == 1623 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, Q♠, 8♢)) == 1624 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, Q♠, 7♢)) == 1625 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, Q♠, 6♢)) == 1626 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, Q♠, 5♢)) == 1627 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, Q♠, 4♢)) == 1628 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, Q♠, 3♢)) == 1629 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, Q♠, 2♢)) == 1630 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, J♠, T♢)) == 1631 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, J♠, 9♢)) == 1632 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, J♠, 8♢)) == 1633 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, J♠, 7♢)) == 1634 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, J♠, 6♢)) == 1635 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, J♠, 5♢)) == 1636 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, J♠, 4♢)) == 1637 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, J♠, 3♢)) == 1638 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, J♠, 2♢)) == 1639 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, T♠, 9♢)) == 1640 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, T♠, 8♢)) == 1641 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, T♠, 7♢)) == 1642 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, T♠, 6♢)) == 1643 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, T♠, 5♢)) == 1644 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, T♠, 4♢)) == 1645 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, T♠, 3♢)) == 1646 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, T♠, 2♢)) == 1647 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, 9♠, 8♢)) == 1648 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, 9♠, 7♢)) == 1649 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, 9♠, 6♢)) == 1650 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, 9♠, 5♢)) == 1651 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, 9♠, 4♢)) == 1652 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, 9♠, 3♢)) == 1653 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, 9♠, 2♢)) == 1654 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, 8♠, 7♢)) == 1655 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, 8♠, 6♢)) == 1656 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, 8♠, 5♢)) == 1657 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, 8♠, 4♢)) == 1658 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, 8♠, 3♢)) == 1659 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, 8♠, 2♢)) == 1660 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, 7♠, 6♢)) == 1661 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, 7♠, 5♢)) == 1662 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, 7♠, 4♢)) == 1663 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, 7♠, 3♢)) == 1664 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, 7♠, 2♢)) == 1665 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, 6♠, 5♢)) == 1666 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, 6♠, 4♢)) == 1667 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, 6♠, 3♢)) == 1668 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, 6♠, 2♢)) == 1669 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, 5♠, 4♢)) == 1670 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, 5♠, 3♢)) == 1671 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, 5♠, 2♢)) == 1672 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, 4♠, 3♢)) == 1673 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, 4♠, 2♢)) == 1674 # Three Aces
@test first(evaluate5(A♣, A♡, A♢, 3♠, 2♢)) == 1675 # Three Aces
@test first(evaluate5(K♣, K♡, K♢, A♠, Q♢)) == 1676 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, A♠, J♢)) == 1677 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, A♠, T♢)) == 1678 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, A♠, 9♢)) == 1679 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, A♠, 8♢)) == 1680 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, A♠, 7♢)) == 1681 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, A♠, 6♢)) == 1682 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, A♠, 5♢)) == 1683 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, A♠, 4♢)) == 1684 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, A♠, 3♢)) == 1685 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, A♠, 2♢)) == 1686 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, Q♠, J♢)) == 1687 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, Q♠, T♢)) == 1688 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, Q♠, 9♢)) == 1689 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, Q♠, 8♢)) == 1690 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, Q♠, 7♢)) == 1691 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, Q♠, 6♢)) == 1692 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, Q♠, 5♢)) == 1693 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, Q♠, 4♢)) == 1694 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, Q♠, 3♢)) == 1695 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, Q♠, 2♢)) == 1696 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, J♠, T♢)) == 1697 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, J♠, 9♢)) == 1698 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, J♠, 8♢)) == 1699 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, J♠, 7♢)) == 1700 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, J♠, 6♢)) == 1701 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, J♠, 5♢)) == 1702 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, J♠, 4♢)) == 1703 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, J♠, 3♢)) == 1704 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, J♠, 2♢)) == 1705 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, T♠, 9♢)) == 1706 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, T♠, 8♢)) == 1707 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, T♠, 7♢)) == 1708 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, T♠, 6♢)) == 1709 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, T♠, 5♢)) == 1710 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, T♠, 4♢)) == 1711 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, T♠, 3♢)) == 1712 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, T♠, 2♢)) == 1713 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, 9♠, 8♢)) == 1714 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, 9♠, 7♢)) == 1715 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, 9♠, 6♢)) == 1716 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, 9♠, 5♢)) == 1717 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, 9♠, 4♢)) == 1718 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, 9♠, 3♢)) == 1719 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, 9♠, 2♢)) == 1720 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, 8♠, 7♢)) == 1721 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, 8♠, 6♢)) == 1722 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, 8♠, 5♢)) == 1723 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, 8♠, 4♢)) == 1724 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, 8♠, 3♢)) == 1725 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, 8♠, 2♢)) == 1726 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, 7♠, 6♢)) == 1727 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, 7♠, 5♢)) == 1728 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, 7♠, 4♢)) == 1729 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, 7♠, 3♢)) == 1730 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, 7♠, 2♢)) == 1731 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, 6♠, 5♢)) == 1732 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, 6♠, 4♢)) == 1733 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, 6♠, 3♢)) == 1734 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, 6♠, 2♢)) == 1735 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, 5♠, 4♢)) == 1736 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, 5♠, 3♢)) == 1737 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, 5♠, 2♢)) == 1738 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, 4♠, 3♢)) == 1739 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, 4♠, 2♢)) == 1740 # Three Kings
@test first(evaluate5(K♣, K♡, K♢, 3♠, 2♢)) == 1741 # Three Kings
@test first(evaluate5(Q♣, Q♡, Q♢, A♠, K♢)) == 1742 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, A♠, J♢)) == 1743 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, A♠, T♢)) == 1744 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, A♠, 9♢)) == 1745 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, A♠, 8♢)) == 1746 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, A♠, 7♢)) == 1747 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, A♠, 6♢)) == 1748 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, A♠, 5♢)) == 1749 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, A♠, 4♢)) == 1750 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, A♠, 3♢)) == 1751 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, A♠, 2♢)) == 1752 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, K♠, J♢)) == 1753 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, K♠, T♢)) == 1754 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, K♠, 9♢)) == 1755 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, K♠, 8♢)) == 1756 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, K♠, 7♢)) == 1757 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, K♠, 6♢)) == 1758 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, K♠, 5♢)) == 1759 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, K♠, 4♢)) == 1760 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, K♠, 3♢)) == 1761 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, K♠, 2♢)) == 1762 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, J♠, T♢)) == 1763 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, J♠, 9♢)) == 1764 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, J♠, 8♢)) == 1765 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, J♠, 7♢)) == 1766 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, J♠, 6♢)) == 1767 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, J♠, 5♢)) == 1768 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, J♠, 4♢)) == 1769 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, J♠, 3♢)) == 1770 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, J♠, 2♢)) == 1771 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, T♠, 9♢)) == 1772 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, T♠, 8♢)) == 1773 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, T♠, 7♢)) == 1774 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, T♠, 6♢)) == 1775 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, T♠, 5♢)) == 1776 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, T♠, 4♢)) == 1777 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, T♠, 3♢)) == 1778 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, T♠, 2♢)) == 1779 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, 9♠, 8♢)) == 1780 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, 9♠, 7♢)) == 1781 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, 9♠, 6♢)) == 1782 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, 9♠, 5♢)) == 1783 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, 9♠, 4♢)) == 1784 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, 9♠, 3♢)) == 1785 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, 9♠, 2♢)) == 1786 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, 8♠, 7♢)) == 1787 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, 8♠, 6♢)) == 1788 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, 8♠, 5♢)) == 1789 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, 8♠, 4♢)) == 1790 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, 8♠, 3♢)) == 1791 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, 8♠, 2♢)) == 1792 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, 7♠, 6♢)) == 1793 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, 7♠, 5♢)) == 1794 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, 7♠, 4♢)) == 1795 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, 7♠, 3♢)) == 1796 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, 7♠, 2♢)) == 1797 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, 6♠, 5♢)) == 1798 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, 6♠, 4♢)) == 1799 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, 6♠, 3♢)) == 1800 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, 6♠, 2♢)) == 1801 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, 5♠, 4♢)) == 1802 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, 5♠, 3♢)) == 1803 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, 5♠, 2♢)) == 1804 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, 4♠, 3♢)) == 1805 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, 4♠, 2♢)) == 1806 # Three Queens
@test first(evaluate5(Q♣, Q♡, Q♢, 3♠, 2♢)) == 1807 # Three Queens
@test first(evaluate5(J♣, J♡, J♢, A♠, K♢)) == 1808 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, A♠, Q♢)) == 1809 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, A♠, T♢)) == 1810 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, A♠, 9♢)) == 1811 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, A♠, 8♢)) == 1812 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, A♠, 7♢)) == 1813 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, A♠, 6♢)) == 1814 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, A♠, 5♢)) == 1815 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, A♠, 4♢)) == 1816 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, A♠, 3♢)) == 1817 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, A♠, 2♢)) == 1818 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, K♠, Q♢)) == 1819 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, K♠, T♢)) == 1820 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, K♠, 9♢)) == 1821 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, K♠, 8♢)) == 1822 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, K♠, 7♢)) == 1823 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, K♠, 6♢)) == 1824 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, K♠, 5♢)) == 1825 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, K♠, 4♢)) == 1826 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, K♠, 3♢)) == 1827 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, K♠, 2♢)) == 1828 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, Q♠, T♢)) == 1829 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, Q♠, 9♢)) == 1830 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, Q♠, 8♢)) == 1831 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, Q♠, 7♢)) == 1832 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, Q♠, 6♢)) == 1833 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, Q♠, 5♢)) == 1834 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, Q♠, 4♢)) == 1835 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, Q♠, 3♢)) == 1836 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, Q♠, 2♢)) == 1837 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, T♠, 9♢)) == 1838 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, T♠, 8♢)) == 1839 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, T♠, 7♢)) == 1840 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, T♠, 6♢)) == 1841 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, T♠, 5♢)) == 1842 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, T♠, 4♢)) == 1843 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, T♠, 3♢)) == 1844 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, T♠, 2♢)) == 1845 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, 9♠, 8♢)) == 1846 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, 9♠, 7♢)) == 1847 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, 9♠, 6♢)) == 1848 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, 9♠, 5♢)) == 1849 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, 9♠, 4♢)) == 1850 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, 9♠, 3♢)) == 1851 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, 9♠, 2♢)) == 1852 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, 8♠, 7♢)) == 1853 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, 8♠, 6♢)) == 1854 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, 8♠, 5♢)) == 1855 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, 8♠, 4♢)) == 1856 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, 8♠, 3♢)) == 1857 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, 8♠, 2♢)) == 1858 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, 7♠, 6♢)) == 1859 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, 7♠, 5♢)) == 1860 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, 7♠, 4♢)) == 1861 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, 7♠, 3♢)) == 1862 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, 7♠, 2♢)) == 1863 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, 6♠, 5♢)) == 1864 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, 6♠, 4♢)) == 1865 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, 6♠, 3♢)) == 1866 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, 6♠, 2♢)) == 1867 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, 5♠, 4♢)) == 1868 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, 5♠, 3♢)) == 1869 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, 5♠, 2♢)) == 1870 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, 4♠, 3♢)) == 1871 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, 4♠, 2♢)) == 1872 # Three Jacks
@test first(evaluate5(J♣, J♡, J♢, 3♠, 2♢)) == 1873 # Three Jacks
@test first(evaluate5(T♣, T♡, T♢, A♠, K♢)) == 1874 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, A♠, Q♢)) == 1875 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, A♠, J♢)) == 1876 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, A♠, 9♢)) == 1877 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, A♠, 8♢)) == 1878 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, A♠, 7♢)) == 1879 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, A♠, 6♢)) == 1880 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, A♠, 5♢)) == 1881 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, A♠, 4♢)) == 1882 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, A♠, 3♢)) == 1883 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, A♠, 2♢)) == 1884 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, K♠, Q♢)) == 1885 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, K♠, J♢)) == 1886 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, K♠, 9♢)) == 1887 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, K♠, 8♢)) == 1888 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, K♠, 7♢)) == 1889 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, K♠, 6♢)) == 1890 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, K♠, 5♢)) == 1891 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, K♠, 4♢)) == 1892 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, K♠, 3♢)) == 1893 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, K♠, 2♢)) == 1894 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, Q♠, J♢)) == 1895 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, Q♠, 9♢)) == 1896 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, Q♠, 8♢)) == 1897 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, Q♠, 7♢)) == 1898 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, Q♠, 6♢)) == 1899 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, Q♠, 5♢)) == 1900 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, Q♠, 4♢)) == 1901 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, Q♠, 3♢)) == 1902 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, Q♠, 2♢)) == 1903 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, J♠, 9♢)) == 1904 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, J♠, 8♢)) == 1905 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, J♠, 7♢)) == 1906 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, J♠, 6♢)) == 1907 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, J♠, 5♢)) == 1908 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, J♠, 4♢)) == 1909 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, J♠, 3♢)) == 1910 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, J♠, 2♢)) == 1911 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, 9♠, 8♢)) == 1912 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, 9♠, 7♢)) == 1913 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, 9♠, 6♢)) == 1914 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, 9♠, 5♢)) == 1915 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, 9♠, 4♢)) == 1916 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, 9♠, 3♢)) == 1917 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, 9♠, 2♢)) == 1918 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, 8♠, 7♢)) == 1919 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, 8♠, 6♢)) == 1920 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, 8♠, 5♢)) == 1921 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, 8♠, 4♢)) == 1922 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, 8♠, 3♢)) == 1923 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, 8♠, 2♢)) == 1924 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, 7♠, 6♢)) == 1925 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, 7♠, 5♢)) == 1926 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, 7♠, 4♢)) == 1927 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, 7♠, 3♢)) == 1928 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, 7♠, 2♢)) == 1929 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, 6♠, 5♢)) == 1930 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, 6♠, 4♢)) == 1931 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, 6♠, 3♢)) == 1932 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, 6♠, 2♢)) == 1933 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, 5♠, 4♢)) == 1934 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, 5♠, 3♢)) == 1935 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, 5♠, 2♢)) == 1936 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, 4♠, 3♢)) == 1937 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, 4♠, 2♢)) == 1938 # Three Tens
@test first(evaluate5(T♣, T♡, T♢, 3♠, 2♢)) == 1939 # Three Tens
@test first(evaluate5(9♣, 9♡, 9♢, A♠, K♢)) == 1940 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, A♠, Q♢)) == 1941 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, A♠, J♢)) == 1942 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, A♠, T♢)) == 1943 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, A♠, 8♢)) == 1944 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, A♠, 7♢)) == 1945 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, A♠, 6♢)) == 1946 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, A♠, 5♢)) == 1947 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, A♠, 4♢)) == 1948 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, A♠, 3♢)) == 1949 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, A♠, 2♢)) == 1950 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, K♠, Q♢)) == 1951 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, K♠, J♢)) == 1952 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, K♠, T♢)) == 1953 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, K♠, 8♢)) == 1954 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, K♠, 7♢)) == 1955 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, K♠, 6♢)) == 1956 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, K♠, 5♢)) == 1957 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, K♠, 4♢)) == 1958 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, K♠, 3♢)) == 1959 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, K♠, 2♢)) == 1960 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, Q♠, J♢)) == 1961 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, Q♠, T♢)) == 1962 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, Q♠, 8♢)) == 1963 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, Q♠, 7♢)) == 1964 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, Q♠, 6♢)) == 1965 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, Q♠, 5♢)) == 1966 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, Q♠, 4♢)) == 1967 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, Q♠, 3♢)) == 1968 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, Q♠, 2♢)) == 1969 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, J♠, T♢)) == 1970 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, J♠, 8♢)) == 1971 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, J♠, 7♢)) == 1972 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, J♠, 6♢)) == 1973 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, J♠, 5♢)) == 1974 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, J♠, 4♢)) == 1975 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, J♠, 3♢)) == 1976 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, J♠, 2♢)) == 1977 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, T♠, 8♢)) == 1978 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, T♠, 7♢)) == 1979 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, T♠, 6♢)) == 1980 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, T♠, 5♢)) == 1981 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, T♠, 4♢)) == 1982 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, T♠, 3♢)) == 1983 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, T♠, 2♢)) == 1984 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, 8♠, 7♢)) == 1985 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, 8♠, 6♢)) == 1986 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, 8♠, 5♢)) == 1987 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, 8♠, 4♢)) == 1988 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, 8♠, 3♢)) == 1989 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, 8♠, 2♢)) == 1990 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, 7♠, 6♢)) == 1991 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, 7♠, 5♢)) == 1992 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, 7♠, 4♢)) == 1993 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, 7♠, 3♢)) == 1994 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, 7♠, 2♢)) == 1995 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, 6♠, 5♢)) == 1996 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, 6♠, 4♢)) == 1997 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, 6♠, 3♢)) == 1998 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, 6♠, 2♢)) == 1999 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, 5♠, 4♢)) == 2000 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, 5♠, 3♢)) == 2001 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, 5♠, 2♢)) == 2002 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, 4♠, 3♢)) == 2003 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, 4♠, 2♢)) == 2004 # Three Nines
@test first(evaluate5(9♣, 9♡, 9♢, 3♠, 2♢)) == 2005 # Three Nines
@test first(evaluate5(8♣, 8♡, 8♢, A♠, K♢)) == 2006 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, A♠, Q♢)) == 2007 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, A♠, J♢)) == 2008 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, A♠, T♢)) == 2009 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, A♠, 9♢)) == 2010 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, A♠, 7♢)) == 2011 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, A♠, 6♢)) == 2012 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, A♠, 5♢)) == 2013 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, A♠, 4♢)) == 2014 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, A♠, 3♢)) == 2015 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, A♠, 2♢)) == 2016 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, K♠, Q♢)) == 2017 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, K♠, J♢)) == 2018 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, K♠, T♢)) == 2019 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, K♠, 9♢)) == 2020 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, K♠, 7♢)) == 2021 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, K♠, 6♢)) == 2022 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, K♠, 5♢)) == 2023 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, K♠, 4♢)) == 2024 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, K♠, 3♢)) == 2025 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, K♠, 2♢)) == 2026 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, Q♠, J♢)) == 2027 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, Q♠, T♢)) == 2028 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, Q♠, 9♢)) == 2029 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, Q♠, 7♢)) == 2030 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, Q♠, 6♢)) == 2031 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, Q♠, 5♢)) == 2032 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, Q♠, 4♢)) == 2033 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, Q♠, 3♢)) == 2034 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, Q♠, 2♢)) == 2035 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, J♠, T♢)) == 2036 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, J♠, 9♢)) == 2037 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, J♠, 7♢)) == 2038 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, J♠, 6♢)) == 2039 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, J♠, 5♢)) == 2040 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, J♠, 4♢)) == 2041 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, J♠, 3♢)) == 2042 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, J♠, 2♢)) == 2043 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, T♠, 9♢)) == 2044 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, T♠, 7♢)) == 2045 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, T♠, 6♢)) == 2046 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, T♠, 5♢)) == 2047 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, T♠, 4♢)) == 2048 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, T♠, 3♢)) == 2049 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, T♠, 2♢)) == 2050 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, 9♠, 7♢)) == 2051 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, 9♠, 6♢)) == 2052 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, 9♠, 5♢)) == 2053 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, 9♠, 4♢)) == 2054 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, 9♠, 3♢)) == 2055 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, 9♠, 2♢)) == 2056 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, 7♠, 6♢)) == 2057 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, 7♠, 5♢)) == 2058 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, 7♠, 4♢)) == 2059 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, 7♠, 3♢)) == 2060 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, 7♠, 2♢)) == 2061 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, 6♠, 5♢)) == 2062 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, 6♠, 4♢)) == 2063 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, 6♠, 3♢)) == 2064 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, 6♠, 2♢)) == 2065 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, 5♠, 4♢)) == 2066 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, 5♠, 3♢)) == 2067 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, 5♠, 2♢)) == 2068 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, 4♠, 3♢)) == 2069 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, 4♠, 2♢)) == 2070 # Three Eights
@test first(evaluate5(8♣, 8♡, 8♢, 3♠, 2♢)) == 2071 # Three Eights
@test first(evaluate5(7♣, 7♡, 7♢, A♠, K♢)) == 2072 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, A♠, Q♢)) == 2073 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, A♠, J♢)) == 2074 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, A♠, T♢)) == 2075 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, A♠, 9♢)) == 2076 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, A♠, 8♢)) == 2077 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, A♠, 6♢)) == 2078 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, A♠, 5♢)) == 2079 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, A♠, 4♢)) == 2080 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, A♠, 3♢)) == 2081 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, A♠, 2♢)) == 2082 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, K♠, Q♢)) == 2083 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, K♠, J♢)) == 2084 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, K♠, T♢)) == 2085 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, K♠, 9♢)) == 2086 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, K♠, 8♢)) == 2087 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, K♠, 6♢)) == 2088 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, K♠, 5♢)) == 2089 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, K♠, 4♢)) == 2090 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, K♠, 3♢)) == 2091 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, K♠, 2♢)) == 2092 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, Q♠, J♢)) == 2093 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, Q♠, T♢)) == 2094 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, Q♠, 9♢)) == 2095 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, Q♠, 8♢)) == 2096 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, Q♠, 6♢)) == 2097 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, Q♠, 5♢)) == 2098 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, Q♠, 4♢)) == 2099 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, Q♠, 3♢)) == 2100 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, Q♠, 2♢)) == 2101 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, J♠, T♢)) == 2102 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, J♠, 9♢)) == 2103 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, J♠, 8♢)) == 2104 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, J♠, 6♢)) == 2105 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, J♠, 5♢)) == 2106 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, J♠, 4♢)) == 2107 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, J♠, 3♢)) == 2108 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, J♠, 2♢)) == 2109 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, T♠, 9♢)) == 2110 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, T♠, 8♢)) == 2111 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, T♠, 6♢)) == 2112 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, T♠, 5♢)) == 2113 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, T♠, 4♢)) == 2114 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, T♠, 3♢)) == 2115 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, T♠, 2♢)) == 2116 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, 9♠, 8♢)) == 2117 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, 9♠, 6♢)) == 2118 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, 9♠, 5♢)) == 2119 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, 9♠, 4♢)) == 2120 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, 9♠, 3♢)) == 2121 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, 9♠, 2♢)) == 2122 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, 8♠, 6♢)) == 2123 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, 8♠, 5♢)) == 2124 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, 8♠, 4♢)) == 2125 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, 8♠, 3♢)) == 2126 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, 8♠, 2♢)) == 2127 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, 6♠, 5♢)) == 2128 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, 6♠, 4♢)) == 2129 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, 6♠, 3♢)) == 2130 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, 6♠, 2♢)) == 2131 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, 5♠, 4♢)) == 2132 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, 5♠, 3♢)) == 2133 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, 5♠, 2♢)) == 2134 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, 4♠, 3♢)) == 2135 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, 4♠, 2♢)) == 2136 # Three Sevens
@test first(evaluate5(7♣, 7♡, 7♢, 3♠, 2♢)) == 2137 # Three Sevens
@test first(evaluate5(6♣, 6♡, 6♢, A♠, K♢)) == 2138 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, A♠, Q♢)) == 2139 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, A♠, J♢)) == 2140 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, A♠, T♢)) == 2141 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, A♠, 9♢)) == 2142 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, A♠, 8♢)) == 2143 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, A♠, 7♢)) == 2144 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, A♠, 5♢)) == 2145 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, A♠, 4♢)) == 2146 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, A♠, 3♢)) == 2147 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, A♠, 2♢)) == 2148 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, K♠, Q♢)) == 2149 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, K♠, J♢)) == 2150 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, K♠, T♢)) == 2151 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, K♠, 9♢)) == 2152 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, K♠, 8♢)) == 2153 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, K♠, 7♢)) == 2154 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, K♠, 5♢)) == 2155 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, K♠, 4♢)) == 2156 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, K♠, 3♢)) == 2157 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, K♠, 2♢)) == 2158 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, Q♠, J♢)) == 2159 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, Q♠, T♢)) == 2160 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, Q♠, 9♢)) == 2161 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, Q♠, 8♢)) == 2162 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, Q♠, 7♢)) == 2163 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, Q♠, 5♢)) == 2164 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, Q♠, 4♢)) == 2165 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, Q♠, 3♢)) == 2166 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, Q♠, 2♢)) == 2167 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, J♠, T♢)) == 2168 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, J♠, 9♢)) == 2169 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, J♠, 8♢)) == 2170 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, J♠, 7♢)) == 2171 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, J♠, 5♢)) == 2172 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, J♠, 4♢)) == 2173 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, J♠, 3♢)) == 2174 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, J♠, 2♢)) == 2175 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, T♠, 9♢)) == 2176 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, T♠, 8♢)) == 2177 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, T♠, 7♢)) == 2178 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, T♠, 5♢)) == 2179 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, T♠, 4♢)) == 2180 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, T♠, 3♢)) == 2181 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, T♠, 2♢)) == 2182 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, 9♠, 8♢)) == 2183 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, 9♠, 7♢)) == 2184 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, 9♠, 5♢)) == 2185 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, 9♠, 4♢)) == 2186 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, 9♠, 3♢)) == 2187 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, 9♠, 2♢)) == 2188 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, 8♠, 7♢)) == 2189 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, 8♠, 5♢)) == 2190 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, 8♠, 4♢)) == 2191 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, 8♠, 3♢)) == 2192 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, 8♠, 2♢)) == 2193 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, 7♠, 5♢)) == 2194 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, 7♠, 4♢)) == 2195 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, 7♠, 3♢)) == 2196 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, 7♠, 2♢)) == 2197 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, 5♠, 4♢)) == 2198 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, 5♠, 3♢)) == 2199 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, 5♠, 2♢)) == 2200 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, 4♠, 3♢)) == 2201 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, 4♠, 2♢)) == 2202 # Three Sixes
@test first(evaluate5(6♣, 6♡, 6♢, 3♠, 2♢)) == 2203 # Three Sixes
@test first(evaluate5(5♣, 5♡, 5♢, A♠, K♢)) == 2204 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, A♠, Q♢)) == 2205 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, A♠, J♢)) == 2206 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, A♠, T♢)) == 2207 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, A♠, 9♢)) == 2208 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, A♠, 8♢)) == 2209 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, A♠, 7♢)) == 2210 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, A♠, 6♢)) == 2211 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, A♠, 4♢)) == 2212 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, A♠, 3♢)) == 2213 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, A♠, 2♢)) == 2214 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, K♠, Q♢)) == 2215 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, K♠, J♢)) == 2216 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, K♠, T♢)) == 2217 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, K♠, 9♢)) == 2218 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, K♠, 8♢)) == 2219 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, K♠, 7♢)) == 2220 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, K♠, 6♢)) == 2221 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, K♠, 4♢)) == 2222 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, K♠, 3♢)) == 2223 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, K♠, 2♢)) == 2224 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, Q♠, J♢)) == 2225 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, Q♠, T♢)) == 2226 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, Q♠, 9♢)) == 2227 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, Q♠, 8♢)) == 2228 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, Q♠, 7♢)) == 2229 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, Q♠, 6♢)) == 2230 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, Q♠, 4♢)) == 2231 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, Q♠, 3♢)) == 2232 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, Q♠, 2♢)) == 2233 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, J♠, T♢)) == 2234 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, J♠, 9♢)) == 2235 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, J♠, 8♢)) == 2236 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, J♠, 7♢)) == 2237 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, J♠, 6♢)) == 2238 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, J♠, 4♢)) == 2239 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, J♠, 3♢)) == 2240 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, J♠, 2♢)) == 2241 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, T♠, 9♢)) == 2242 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, T♠, 8♢)) == 2243 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, T♠, 7♢)) == 2244 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, T♠, 6♢)) == 2245 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, T♠, 4♢)) == 2246 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, T♠, 3♢)) == 2247 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, T♠, 2♢)) == 2248 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, 9♠, 8♢)) == 2249 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, 9♠, 7♢)) == 2250 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, 9♠, 6♢)) == 2251 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, 9♠, 4♢)) == 2252 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, 9♠, 3♢)) == 2253 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, 9♠, 2♢)) == 2254 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, 8♠, 7♢)) == 2255 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, 8♠, 6♢)) == 2256 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, 8♠, 4♢)) == 2257 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, 8♠, 3♢)) == 2258 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, 8♠, 2♢)) == 2259 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, 7♠, 6♢)) == 2260 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, 7♠, 4♢)) == 2261 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, 7♠, 3♢)) == 2262 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, 7♠, 2♢)) == 2263 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, 6♠, 4♢)) == 2264 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, 6♠, 3♢)) == 2265 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, 6♠, 2♢)) == 2266 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, 4♠, 3♢)) == 2267 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, 4♠, 2♢)) == 2268 # Three Fives
@test first(evaluate5(5♣, 5♡, 5♢, 3♠, 2♢)) == 2269 # Three Fives
@test first(evaluate5(4♣, 4♡, 4♢, A♠, K♢)) == 2270 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, A♠, Q♢)) == 2271 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, A♠, J♢)) == 2272 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, A♠, T♢)) == 2273 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, A♠, 9♢)) == 2274 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, A♠, 8♢)) == 2275 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, A♠, 7♢)) == 2276 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, A♠, 6♢)) == 2277 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, A♠, 5♢)) == 2278 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, A♠, 3♢)) == 2279 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, A♠, 2♢)) == 2280 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, K♠, Q♢)) == 2281 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, K♠, J♢)) == 2282 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, K♠, T♢)) == 2283 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, K♠, 9♢)) == 2284 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, K♠, 8♢)) == 2285 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, K♠, 7♢)) == 2286 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, K♠, 6♢)) == 2287 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, K♠, 5♢)) == 2288 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, K♠, 3♢)) == 2289 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, K♠, 2♢)) == 2290 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, Q♠, J♢)) == 2291 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, Q♠, T♢)) == 2292 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, Q♠, 9♢)) == 2293 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, Q♠, 8♢)) == 2294 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, Q♠, 7♢)) == 2295 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, Q♠, 6♢)) == 2296 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, Q♠, 5♢)) == 2297 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, Q♠, 3♢)) == 2298 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, Q♠, 2♢)) == 2299 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, J♠, T♢)) == 2300 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, J♠, 9♢)) == 2301 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, J♠, 8♢)) == 2302 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, J♠, 7♢)) == 2303 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, J♠, 6♢)) == 2304 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, J♠, 5♢)) == 2305 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, J♠, 3♢)) == 2306 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, J♠, 2♢)) == 2307 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, T♠, 9♢)) == 2308 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, T♠, 8♢)) == 2309 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, T♠, 7♢)) == 2310 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, T♠, 6♢)) == 2311 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, T♠, 5♢)) == 2312 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, T♠, 3♢)) == 2313 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, T♠, 2♢)) == 2314 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, 9♠, 8♢)) == 2315 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, 9♠, 7♢)) == 2316 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, 9♠, 6♢)) == 2317 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, 9♠, 5♢)) == 2318 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, 9♠, 3♢)) == 2319 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, 9♠, 2♢)) == 2320 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, 8♠, 7♢)) == 2321 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, 8♠, 6♢)) == 2322 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, 8♠, 5♢)) == 2323 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, 8♠, 3♢)) == 2324 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, 8♠, 2♢)) == 2325 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, 7♠, 6♢)) == 2326 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, 7♠, 5♢)) == 2327 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, 7♠, 3♢)) == 2328 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, 7♠, 2♢)) == 2329 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, 6♠, 5♢)) == 2330 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, 6♠, 3♢)) == 2331 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, 6♠, 2♢)) == 2332 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, 5♠, 3♢)) == 2333 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, 5♠, 2♢)) == 2334 # Three Fours
@test first(evaluate5(4♣, 4♡, 4♢, 3♠, 2♢)) == 2335 # Three Fours
@test first(evaluate5(3♣, 3♡, 3♢, A♠, K♢)) == 2336 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, A♠, Q♢)) == 2337 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, A♠, J♢)) == 2338 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, A♠, T♢)) == 2339 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, A♠, 9♢)) == 2340 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, A♠, 8♢)) == 2341 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, A♠, 7♢)) == 2342 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, A♠, 6♢)) == 2343 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, A♠, 5♢)) == 2344 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, A♠, 4♢)) == 2345 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, A♠, 2♢)) == 2346 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, K♠, Q♢)) == 2347 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, K♠, J♢)) == 2348 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, K♠, T♢)) == 2349 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, K♠, 9♢)) == 2350 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, K♠, 8♢)) == 2351 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, K♠, 7♢)) == 2352 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, K♠, 6♢)) == 2353 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, K♠, 5♢)) == 2354 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, K♠, 4♢)) == 2355 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, K♠, 2♢)) == 2356 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, Q♠, J♢)) == 2357 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, Q♠, T♢)) == 2358 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, Q♠, 9♢)) == 2359 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, Q♠, 8♢)) == 2360 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, Q♠, 7♢)) == 2361 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, Q♠, 6♢)) == 2362 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, Q♠, 5♢)) == 2363 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, Q♠, 4♢)) == 2364 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, Q♠, 2♢)) == 2365 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, J♠, T♢)) == 2366 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, J♠, 9♢)) == 2367 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, J♠, 8♢)) == 2368 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, J♠, 7♢)) == 2369 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, J♠, 6♢)) == 2370 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, J♠, 5♢)) == 2371 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, J♠, 4♢)) == 2372 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, J♠, 2♢)) == 2373 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, T♠, 9♢)) == 2374 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, T♠, 8♢)) == 2375 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, T♠, 7♢)) == 2376 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, T♠, 6♢)) == 2377 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, T♠, 5♢)) == 2378 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, T♠, 4♢)) == 2379 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, T♠, 2♢)) == 2380 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, 9♠, 8♢)) == 2381 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, 9♠, 7♢)) == 2382 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, 9♠, 6♢)) == 2383 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, 9♠, 5♢)) == 2384 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, 9♠, 4♢)) == 2385 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, 9♠, 2♢)) == 2386 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, 8♠, 7♢)) == 2387 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, 8♠, 6♢)) == 2388 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, 8♠, 5♢)) == 2389 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, 8♠, 4♢)) == 2390 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, 8♠, 2♢)) == 2391 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, 7♠, 6♢)) == 2392 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, 7♠, 5♢)) == 2393 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, 7♠, 4♢)) == 2394 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, 7♠, 2♢)) == 2395 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, 6♠, 5♢)) == 2396 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, 6♠, 4♢)) == 2397 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, 6♠, 2♢)) == 2398 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, 5♠, 4♢)) == 2399 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, 5♠, 2♢)) == 2400 # Three Treys
@test first(evaluate5(3♣, 3♡, 3♢, 4♠, 2♢)) == 2401 # Three Treys
@test first(evaluate5(2♣, 2♡, 2♢, A♠, K♢)) == 2402 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, A♠, Q♢)) == 2403 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, A♠, J♢)) == 2404 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, A♠, T♢)) == 2405 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, A♠, 9♢)) == 2406 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, A♠, 8♢)) == 2407 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, A♠, 7♢)) == 2408 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, A♠, 6♢)) == 2409 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, A♠, 5♢)) == 2410 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, A♠, 4♢)) == 2411 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, A♠, 3♢)) == 2412 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, K♠, Q♢)) == 2413 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, K♠, J♢)) == 2414 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, K♠, T♢)) == 2415 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, K♠, 9♢)) == 2416 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, K♠, 8♢)) == 2417 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, K♠, 7♢)) == 2418 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, K♠, 6♢)) == 2419 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, K♠, 5♢)) == 2420 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, K♠, 4♢)) == 2421 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, K♠, 3♢)) == 2422 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, Q♠, J♢)) == 2423 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, Q♠, T♢)) == 2424 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, Q♠, 9♢)) == 2425 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, Q♠, 8♢)) == 2426 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, Q♠, 7♢)) == 2427 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, Q♠, 6♢)) == 2428 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, Q♠, 5♢)) == 2429 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, Q♠, 4♢)) == 2430 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, Q♠, 3♢)) == 2431 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, J♠, T♢)) == 2432 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, J♠, 9♢)) == 2433 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, J♠, 8♢)) == 2434 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, J♠, 7♢)) == 2435 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, J♠, 6♢)) == 2436 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, J♠, 5♢)) == 2437 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, J♠, 4♢)) == 2438 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, J♠, 3♢)) == 2439 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, T♠, 9♢)) == 2440 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, T♠, 8♢)) == 2441 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, T♠, 7♢)) == 2442 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, T♠, 6♢)) == 2443 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, T♠, 5♢)) == 2444 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, T♠, 4♢)) == 2445 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, T♠, 3♢)) == 2446 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, 9♠, 8♢)) == 2447 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, 9♠, 7♢)) == 2448 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, 9♠, 6♢)) == 2449 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, 9♠, 5♢)) == 2450 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, 9♠, 4♢)) == 2451 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, 9♠, 3♢)) == 2452 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, 8♠, 7♢)) == 2453 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, 8♠, 6♢)) == 2454 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, 8♠, 5♢)) == 2455 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, 8♠, 4♢)) == 2456 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, 8♠, 3♢)) == 2457 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, 7♠, 6♢)) == 2458 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, 7♠, 5♢)) == 2459 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, 7♠, 4♢)) == 2460 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, 7♠, 3♢)) == 2461 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, 6♠, 5♢)) == 2462 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, 6♠, 4♢)) == 2463 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, 6♠, 3♢)) == 2464 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, 5♠, 4♢)) == 2465 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, 5♠, 3♢)) == 2466 # Three Deuces
@test first(evaluate5(2♣, 2♡, 2♢, 4♠, 3♢)) == 2467 # Three Deuces


# `apply_memory_noise!()`: helper function called from `fciqmc_step!()`
# dispatches on `MemoryStrategy` and `StochasticStyle`
# `purge_negative_walkers!()`: helper function called from `apply_memory_noise!()`

"""
    r = apply_memory_noise!(w, v, shift, dτ, pnorm, m_strat::MemoryStrategy)
Apply memory noise to `w`, i.e. `w .+= r.*v`, computing the noise `r` according
to `m_strat`. Note that `m_strat`
needs to be compatible with `StochasticStyle(w)`. Otherwise, an
error exception is thrown. See [`MemoryStrategy`](@ref).

`w` is the walker array after fciqmc step, `v` the previous one, `pnorm` the
norm of `v`, and `r` the instantaneously applied noise.
"""
function apply_memory_noise!(w::Union{AbstractArray{T},AbstractDVec{K,T}},
         v, shift, dτ, pnorm, m
    ) where  {K,T<:Real}
    apply_memory_noise!(StochasticStyle(w), w, v, real(shift), dτ, real(pnorm), m)
end
# only use real part of the shift and norm if the coefficients are real

# otherwise, pass on complex shift in generic method
function apply_memory_noise!(w::Union{AbstractArray,AbstractDVec}, args...)
    apply_memory_noise!(StochasticStyle(w), w, args...)
end

function apply_memory_noise!(ws::NTuple, args...)
    apply_memory_noise!(StochasticStyle(first(ws)), ws, args...)
end

function apply_memory_noise!(s::StochasticStyle, w, v, shift, dτ, pnorm, m::NoMemory)
    return 0.0 # does nothing
end

function apply_memory_noise!(s::StochasticStyle, w, v, shift, dτ, pnorm, m::MemoryStrategy)
    throw(ErrorException("MemoryStrategy `$(typeof(m))` does not work with StochasticStyle `$(typeof(s))`. Ignoring memory noise for now."))
    # @error "MemoryStrategy `$(typeof(m))` does not work with StochasticStyle `$(typeof(s))`. Ignoring memory noise for now." maxlog=2
    return 0.0 # default prints an error message
end

function apply_memory_noise!(s::IsStochasticWithThreshold,
                           w, v, shift, dτ, pnorm, m::DeltaMemory)
    tnorm = norm(w, 1) # MPIsync
    # current norm of `w` after FCIQMC step
    # compute memory noise
    r̃ = (pnorm - tnorm)/(dτ*pnorm) + shift
    push!(m.noiseBuffer, r̃) # add current value to buffer
    # Buffer only remembers up to `Δ` values. Average over whole buffer.
    r = r̃ - sum(m.noiseBuffer)/length(m.noiseBuffer)

    # apply `r` noise to current state vector
    axpy!(dτ*r, v, w) # w .+= dτ*r .* v
    # nnorm = norm(w, 1) # new norm after applying noise

    return dτ*r
end

function apply_memory_noise!(s::IsStochasticWithThreshold,
                           w, v, shift, dτ, pnorm, m::DeltaMemory2)
    tnorm = norm(w, 1) # MPIsync
    # current norm of `w` after FCIQMC step
    # compute memory noise
    r̃ = pnorm - tnorm + shift*dτ*pnorm
    push!(m.noiseBuffer, r̃) # add current value to buffer
    # Buffer only remembers up to `Δ` values. Average over whole buffer.
    r = (r̃ - sum(m.noiseBuffer)/length(m.noiseBuffer))/(dτ*pnorm)

    # apply `r` noise to current state vector
    axpy!(dτ*r, v, w) # w .+= dτ*r .* v
    # nnorm = norm(w, 1) # new norm after applying noise

    return dτ*r
end

function apply_memory_noise!(s::IsStochasticWithThreshold,
    w, v, shift, dτ, pnorm, m::DeltaMemory3)
tnorm = norm(w, 1) # MPIsync
# current norm of `w` after FCIQMC step
# compute memory noise
r̃ = (pnorm - tnorm)/pnorm + dτ*shift
push!(m.noiseBuffer, r̃) # add current value to buffer
# Buffer only remembers up to `Δ` values. Average over whole buffer.
r = r̃ - sum(m.noiseBuffer)/length(m.noiseBuffer)

# apply `r` noise to current state vector
rmul!(w, 1 + m.level * r) # w = w * (1 + level*r)

return r
end

function apply_memory_noise!(s::IsStochasticWithThreshold,
                           w, v, shift, dτ, pnorm, m::ShiftMemory)
    push!(m.noiseBuffer, shift) # add current value of `shift` to buffer
    # Buffer only remembers up to `Δ` values. Average over whole buffer.
    r = - shift + sum(m.noiseBuffer)/length(m.noiseBuffer)

    # apply `r` noise to current state vector
    axpy!(dτ*r, v, w) # w .+= dτ*r .* v
    # nnorm = norm(w, 1) # new norm after applying noise

    return dτ*r
end

function apply_memory_noise!(s::IsStochasticWithThreshold,
                           w, v, shift, dτ, pnorm, m::ProjectedMemory)
    tp = m.projector⋅w # w  may be a tuple for multithreading
    # TODO: make this work with multithreading and MPI

    # current projection of `w` after FCIQMC step
    pp  = m.pp
    # projection of `v`, i.e. before FCIQMC step
    # compute memory noise
    r̃ = (pp - tp)/pp + shift*dτ
    push!(m.noiseBuffer, r̃) # add current value to buffer
    # Buffer only remembers up to `Δ` values. Average over whole buffer.
    r = r̃ - sum(m.noiseBuffer)/length(m.noiseBuffer)

    # apply `r` noise to current state vector
    axpy!(r, v, w) # w .+= r .* v
    # TODO: make this work with multithreading
    m.pp = tp + r*pp # update previous projection
    return r
end

# This one works to remove the bias when projection is done with exact
# eigenvector
function apply_memory_noise!(s::IsStochasticWithThreshold,
                           w, v, shift, dτ, pnorm, m::ProjectedMemory2)
    tp = m.projector⋅w # w  may be a tuple for multithreading
    # TODO: make this work with multithreading and MPI
    # current projection of `w` after FCIQMC step

    pp  = m.projector⋅v
    # projection of `v`, i.e. before FCIQMC step
    # compute memory noise
    r̃ = (pp - tp)/pp + shift*dτ
    push!(m.noiseBuffer, r̃) # add current value to buffer
    # Buffer only remembers up to `Δ` values. Average over whole buffer.
    r = r̃ - sum(m.noiseBuffer)/length(m.noiseBuffer)

    # apply `r` noise to current state vector
    axpy!(r, v, w) # w .+= r .* v
    # TODO: make this work with multithreading
    m.pp = tp + r*pp # update previous projection
    return r
end

# seems to not be effective
function apply_memory_noise!(s::IsStochasticWithThreshold,
                           w, v, shift, dτ, pnorm, m::ProjectedMemory3)
    tp = m.projector⋅w # w  may be a tuple for multithreading
    # TODO: make this work with multithreading and MPI
    # current projection of `w` after FCIQMC step

    pp  = m.projector⋅v
    # projection of `v`, i.e. before FCIQMC step
    # compute memory noise
    r̃ = (pp - tp) + shift*dτ*pp
    push!(m.noiseBuffer, r̃) # add current value to buffer
    # Buffer only remembers up to `Δ` values. Average over whole buffer.
    r = r̃ - sum(m.noiseBuffer)/length(m.noiseBuffer)
    if true # abs(pp) > 0.01
        r = r/pp
        # apply `r` noise to current state vector
        axpy!(r, v, w) # w .+= r .* v
        # TODO: make this work with multithreading
        m.pp = tp + r*pp # update previous projection
    else
        r = 0.0
        m.pp = tp
    end
    return r
end

# this one does not work well - no bias correction achieved
function apply_memory_noise!(s::IsStochasticWithThreshold,
                           w, v, shift, dτ, pnorm, m::ProjectedMemory4)
    tp = m.projector⋅w # w  may be a tuple for multithreading
    # TODO: make this work with multithreading and MPI
    # current projection of `w` after FCIQMC step

    pp  = m.projector⋅v
    # projection of `v`, i.e. before FCIQMC step
    # compute memory noise
    r̃ = (pp - tp) + shift*dτ*pp
    push!(m.noiseBuffer, r̃) # add current value to buffer
    # Buffer only remembers up to `Δ` values. Average over whole buffer.
    r = r̃ - sum(m.noiseBuffer)/length(m.noiseBuffer)
    sf = 0.2
    r = sf*tanh(r/pp/sf)
    # apply `r` noise to current state vector
    axpy!(r, v, w) # w .+= r .* v
    # TODO: make this work with multithreading
    m.pp = tp + r*pp # update previous projection
    return r
end

function apply_memory_noise!(s::StochasticStyle, w, v, shift, dτ, pnorm, m::PurgeNegatives)
    purge_negative_walkers!(w)
    return 0.0
end

function purge_negative_walkers!(w::AbstractDVec{K,V}) where {K,V <:Real}
    for (k,v) in pairs(w)
        if v < 0
            delete!(w,k)
        end
    end
    return w
end
function purge_negative_walkers!(w::AbstractDVec{K,V}) where {K,V <:Complex}
    for (k,v) in pairs(w)
        if real(v) < 0
            v = 0 + im*imag(v)
        end
        if imag(v) < 0
            v = real(v)
        end
        w[k] = convert(V,v)
    end
    return w
end


@kernel function sor_car_gpu!(
    potential::AbstractArray{T, 4},
    imp_scale::AbstractArray{T, 4},
    @Const(point_types::AbstractArray{PointType, 4}),
    @Const(volume_weights::AbstractArray{T, 4}),
    @Const(q_eff_imp::AbstractArray{T, 4}),
    @Const(q_eff_fix::AbstractArray{T, 4}),
    @Const(ϵ_r::AbstractArray{T, 3}),
    @Const(geom_weights::NTuple{3, AbstractArray{T, 2}}),
    @Const(sor_const::AbstractArray{T, 1}),
    @Const(update_even_points::Bool),
    @Const(depletion_handling_enabled::Bool),
    @Const(is_weighting_potential::Bool),
    @Const(only2d::Bool)
) where {T}
    gpu_inds = @index(Global, NTuple)
    sor_kernel(
        potential,
        imp_scale,
        point_types,
        volume_weights,
        q_eff_imp,
        q_eff_fix,
        ϵ_r,
        geom_weights,
        sor_const,
        update_even_points,
        depletion_handling_enabled,
        is_weighting_potential,
        only2d,
        Cartesian,
        gpu_inds
    )
end


# Read files and set up simulation
# See http://manual.gromacs.org/documentation/2016/user-guide/file-formats.html

export
    readinputs,
    Simulation

"Gromacs atom type."
struct Atomtype
    mass::Float64
    charge::Float64
    σ::Float64
    ϵ::Float64
end

"Gromacs bond type."
struct Bondtype
    b0::Float64
    kb::Float64
end

"Gromacs angle type."
struct Angletype
    th0::Float64
    cth::Float64
end

"Gromacs dihedral type."
struct Dihedraltype
    f1::Float64
    f2::Float64
    f3::Float64
    f4::Float64
end

"Gromacs forcefield information."
struct Forcefield
    name::String
    atomtypes::Dict{String, Atomtype}
    bondtypes::Dict{String, Bondtype}
    angletypes::Dict{String, Angletype}
    dihedraltypes::Dict{String, Dihedraltype}
    atomnames::Dict{String, String}
end

"An atom and its associated information."
struct Atom
    attype::String
    name::String
    resnum::Int
    resname::String
    charge::Float64
    mass::Float64
    σ::Float64
    ϵ::Float64
end

"A bond between two atoms."
struct Bond
    atom_i::Int
    atom_j::Int
end

"A bond angle between three atoms."
struct Angle
    atom_i::Int
    atom_j::Int
    atom_k::Int
end

"A dihedral torsion angle between four atoms."
struct Dihedral
    atom_i::Int
    atom_j::Int
    atom_k::Int
    atom_l::Int
end

"A molecule."
struct Molecule
    name::String
    atoms::Vector{Atom}
    bonds::Vector{Bond}
    angles::Vector{Angle}
    dihedrals::Vector{Dihedral}
    nb_matrix::BitArray{2}
    nb_pairs::BitArray{2}
end

"3D coordinates, e.g. for an atom, in nm."
mutable struct Coordinates <: FieldVector{3, Float64}
    x::Float64
    y::Float64
    z::Float64
end

"3D velocity values, e.g. for an atom, in nm/ps."
mutable struct Velocity <: FieldVector{3, Float64}
    x::Float64
    y::Float64
    z::Float64
end

"A universe of a molecule, its instantaneous data and the surrounding box."
struct Universe
    molecule::Molecule
    coords::Vector{Coordinates}
    velocities::Vector{Velocity}
    temperature::Float64
    box_size::Float64
    neighbour_list::Vector{Tuple{Int, Int, Bool}} # i, j and whether they are 1-4 pairs (halved force)
end

"A simulation of a `Universe`, a `Forcefield` and timing information."
mutable struct Simulation
    forcefield::Forcefield
    universe::Universe
    timestep::Float64
    n_steps::Int
    steps_made::Int
    temperatures::Vector{Float64}
end

function Base.show(io::IO, s::Simulation)
    print("MD simulation with $(s.forcefield.name) forcefield, ",
            "molecule $(s.universe.molecule.name), ",
            "$(length(s.universe.coords)) atoms, ",
            "$(s.steps_made) steps made")
end

# Placeholder if we want to introduce logging later on
report(msg) = println(msg)

"Read a Gromacs topology flat file, i.e. all includes collapsed into one file."
function readinputs(top_file::AbstractString, coord_file::AbstractString)
    # Read forcefield and topology file
    atomtypes = Dict{String, Atomtype}()
    bondtypes = Dict{String, Bondtype}()
    angletypes = Dict{String, Angletype}()
    dihedraltypes = Dict{String, Dihedraltype}()
    atomnames = Dict{String, String}()
    name = "?"
    atoms = Atom[]
    bonds = Bond[]
    pairs = Tuple{Int, Int}[]
    angles = Angle[]
    dihedrals = Dihedral[]
    current_field = ""
    for l in eachline(top_file)
        sl = strip(l)
        if length(sl) == 0 || startswith(sl, ';')
            continue
        end
        if startswith(sl, '[') && endswith(sl, ']')
            current_field = strip(sl[2:end-1])
            continue
        end
        c = split(rstrip(first(split(sl, ";", limit=2))), r"\s+")
        if current_field == "bondtypes"
            bondtypes["$(c[1])/$(c[2])"] = Bondtype(parse(Float64, c[4]), parse(Float64, c[5]))
        elseif current_field == "angletypes"
            # Convert th0 to radians
            angletypes["$(c[1])/$(c[2])/$(c[3])"] = Angletype(deg2rad(
                                parse(Float64, c[5])), parse(Float64, c[6]))
        elseif current_field == "dihedraltypes" && c[1] != "#define"
            # Convert back to OPLS types
            f4 = parse(Float64, c[10]) / -4
            f3 = parse(Float64, c[9]) / -2
            f2 = 4*f4 - parse(Float64, c[8])
            f1 = 3*f3 - 2*parse(Float64, c[7])
            dihedraltypes["$(c[1])/$(c[2])/$(c[3])/$(c[4])"] = Dihedraltype(f1, f2, f3, f4)
        elseif current_field == "atomtypes" && length(c) >= 8
            atomname = uppercase(c[2])
            atomnames[c[1]] = atomname
            # Take the first version of each atom type only
            if !haskey(atomtypes, atomname)
                atomtypes[atomname] = Atomtype(parse(Float64, c[4]), parse(Float64, c[5]),
                        parse(Float64, c[7]), parse(Float64, c[8]))
            end
        elseif current_field == "atoms"
            attype = atomnames[c[2]]
            push!(atoms, Atom(attype, c[5], parse(Int, c[3]), c[4], parse(Float64, c[7]),
                parse(Float64, c[8]), atomtypes[attype].σ, atomtypes[attype].ϵ))
        elseif current_field == "bonds"
            push!(bonds, Bond(parse(Int, c[1]), parse(Int, c[2])))
        elseif current_field == "pairs"
            push!(pairs, (parse(Int, c[1]), parse(Int, c[2])))
        elseif current_field == "angles"
            push!(angles, Angle(parse(Int, c[1]), parse(Int, c[2]), parse(Int, c[3])))
        elseif current_field == "dihedrals"
            push!(dihedrals, Dihedral(parse(Int, c[1]), parse(Int, c[2]),
                parse(Int, c[3]), parse(Int, c[4])))
        elseif current_field == "system"
            name = rstrip(first(split(sl, ";", limit=2)))
        end
    end

    # Add new dihedral types to match wildcards
    retained_dihedrals = Dihedral[]
    for d in dihedrals
        at_types = [atoms[x].attype for x in [d.atom_i, d.atom_j, d.atom_k, d.atom_l]]
        desired_key = join(at_types, "/")
        if haskey(dihedraltypes, desired_key)
            push!(retained_dihedrals, d)
        else
            best_score = 0
            best_key = ""
            for k in keys(dihedraltypes)
                c = split(k, "/")
                for a in (c, reverse(c))
                    valid = true
                    score = 0
                    for (i, v) in enumerate(a)
                        if v == at_types[i]
                            score += 1
                        elseif v != "X"
                            valid = false
                            break
                        end
                    end
                    if valid && (score > best_score)
                        best_score = score
                        best_key = k
                    end
                end
            end
            # If a wildcard match is found, add a new specific dihedral type
            if best_key != ""
                dihedraltypes[desired_key] = dihedraltypes[best_key]
                push!(retained_dihedrals, d)
            end
        end
    end

    # Read coordinate file and add solvent atoms
    lines = readlines(coord_file)
    coords = Coordinates[]
    for (i, l) in enumerate(lines[3:end-1])
        push!(coords, Coordinates(
            parse(Float64, l[21:28]),
            parse(Float64, l[29:36]),
            parse(Float64, l[37:44])
        ))

        # This atom was not specified explicitly in the topology and is added here
        if i > length(atoms)
            atname = strip(l[11:15])
            attype = replace(atname, r"\d+" => "")
            temp_charge = atomtypes[attype].charge
            if attype == "CL" # Temp hack to fix charges
                temp_charge = -1.0
            end
            push!(atoms, Atom(attype, atname, parse(Int, l[1:5]), strip(l[6:10]),
                temp_charge, atomtypes[attype].mass,
                atomtypes[attype].σ, atomtypes[attype].ϵ))

            # Add O-H bonds and H-O-H angle in water
            if atname == "OW"
                push!(bonds, Bond(i, i+1))
                push!(bonds, Bond(i, i+2))
                push!(angles, Angle(i+1, i, i+2))
            end
        end
    end

    # Calculate matrix of pairs eligible for non-bonded interactions
    n_atoms = length(coords)
    nb_matrix = trues(n_atoms, n_atoms)
    for i in 1:n_atoms
        nb_matrix[i, i] = false
    end
    for b in bonds
        nb_matrix[b.atom_i, b.atom_j] = false
        nb_matrix[b.atom_j, b.atom_i] = false
    end
    for a in angles
        # Assume bonding is already specified
        nb_matrix[a.atom_i, a.atom_k] = false
        nb_matrix[a.atom_k, a.atom_i] = false
    end

    # Calculate matrix of pairs eligible for halved non-bonded interactions
    # This applies to specified pairs in the topology file, usually 1-4 bonded
    nb_pairs = falses(n_atoms, n_atoms)
    for (i, j) in pairs
        nb_pairs[i, j] = true
        nb_pairs[j, i] = true
    end

    # Bounding box for PBCs - box goes 0 to this value in 3 dimensions
    box_size = parse(Float64, first(split(strip(lines[end]), r"\s+")))

    return Forcefield("OPLS", atomtypes, bondtypes, angletypes, dihedraltypes, atomnames),
        Molecule(name, atoms, bonds, angles, retained_dihedrals, nb_matrix, nb_pairs),
        coords,
        box_size
end

# Generate a random velocity from the Maxwell-Boltzmann distribution
function maxwellboltzmann(mass::Real, T::Real)
    return rand(Normal(0.0, sqrt(8.3144598*T/mass)))
end

# Generate a random 3D velocity from the Maxwell-Boltzmann distribution
function Velocity(mass::Real, T::Real)
    return Velocity([maxwellboltzmann(mass, T) for _ in 1:3])
end

function Simulation(forcefield::Forcefield,
                molecule::Molecule,
                coords::Vector{Coordinates},
                box_size::Real,
                temperature::Real,
                timestep::Real,
                n_steps::Real)
    n_atoms = length(coords)
    v = [Velocity(molecule.atoms[i].mass, temperature) for i in 1:n_atoms]
    u = Universe(molecule, coords, v, temperature, box_size, [])
    return Simulation(forcefield, u, timestep, n_steps, 0, [])
end