text:
abstract type AbstractRALF end

# RALF1
mutable struct RALF1{LC} <: AbstractRALF
    f::Function
    f0::Function
    cache::LC
end

get_cache_type(ral::RALF1{LC}) where {LC} = LC

function RALF1(f::Function, x1::C1, cache::AbstractArray{<: Number};
               chunksize::Int = ForwardDiff.pickchunksize(length(x1))) where {C1 <: AbstractArray{<: Number}, N}
    if applicable(f, cache, x1)
        fnew = function _f_ip(cache::LCN, x1::C1N) where {LCN <: DiffCache, C1N <: AbstractArray{<: Number}}
            target_cache = get_tmp(cache, x1)
            if size(target_cache) != size(cache.du)
                target_cache = reshape(target_cache, size(cache.du))
            end
            f(target_cache, x1)
            return target_cache
        end
    else
        fnew = function _f_oop(cache::LCN, x1::C1N) where {LCN <: DiffCache, C1N <: AbstractArray{<: Number}}
            target_cache = get_tmp(cache, x1)
            if size(target_cache) != size(cache.du)
                target_cache = reshape(target_cache, size(cache.du))
            end
            target_cache .= f(x1)
            return target_cache
        end
    end
    return RALF1(fnew, f, dualcache(cache, Val{chunksize}))
end

function RALF1(fin::LC) where {LC <: AbstractArray{<: Number}}
    f(cache::LCN, x1::C1N) where {LCN <: AbstractMatrix{ <: Number}, C1N <: AbstractArray{<: Number}} = cache
    return RALF1{LC}(f, x -> fin, fin)
end

function (ralf::RALF1)(x1::C1) where {C1 <: AbstractArray{<: Number}}
    return ralf.f(ralf.cache, x1)
end

# RALF2
mutable struct RALF2{LC} <: AbstractRALF
    f::Function
    f0::Function
    cache::LC
end

get_cache_type(ral::RALF2{LC}) where {LC} = LC

function RALF2(f::Function, x1::C1, x2::C2, cache::AbstractArray{<: Number}, chunksizes::NTuple{Nc, Int} =
               (ForwardDiff.pickchunksize(min(length(x1), length(x2))), )) where {C1 <: AbstractArray{<: Number}, C2 <: AbstractArray{<: Number}, N, Nc}
    if applicable(f, cache, x1, x2)
        if length(chunksizes) == 1 # Figure out which type of DiffCache is needed
            diffcache = dualcache(cache, Val{chunksizes[1]})
            fnew      = function _f_ip1(cache::LCN, x1::C1N, x2::C2N, select::Tuple{Int, Int}) where {LCN <: DiffCache,
                                                                                C1N <: AbstractArray{<: Number},
                                                                                C2N <: AbstractArray{<: Number}}
                target_cache = get_tmp(cache, x1, x2, select)
                if size(target_cache) != size(cache.du)
                    target_cache = reshape(target_cache, size(cache.du))
                end
                f(target_cache, x1, x2)
                return target_cache
            end
        elseif length(chunksizes) == 2
            diffcache = twodualcache(cache, Val{chunksizes[1]}, Val{chunksizes[2]})
            fnew      = function _f_ip2(cache::LCN, x1::C1N, x2::C2N, select::Tuple{Int, Int}) where {LCN <: TwoDiffCache,
                                                                                C1N <: AbstractArray{<: Number},
                                                                                C2N <: AbstractArray{<: Number}}
                target_cache = get_tmp(cache, x1, x2, select)
                if size(target_cache) != size(cache.du)
                    target_cache = reshape(target_cache, size(cache.du))
                end
                f(target_cache, x1, x2)
                return target_cache
            end
        elseif length(chunksizes) == 3
            diffcache = threedualcache(cache, Val{chunksizes[1]}, Val{chunksizes[2]}, Val{chunksizes[3]})
            fnew      = function _f_ip3(cache::LCN, x1::C1N, x2::C2N, select::Tuple{Int, Int}) where {LCN <: ThreeDiffCache,
                                                                                C1N <: AbstractArray{<: Number},
                                                                                C2N <: AbstractArray{<: Number}}
                target_cache = get_tmp(cache, x1, x2, select)
                if size(target_cache) != size(cache.du)
                    target_cache = reshape(target_cache, size(cache.du))
                end
                f(target_cache, x1, x2)
                return target_cache
            end
        else
            throw(MethodError("The length of the sixth input argument, chunksizes, must be 1, 2, or 3."))
        end
    else
        if length(chunksizes) == 1 # Figure out which type of DiffCache is needed
            diffcache = dualcache(cache, Val{chunksizes[1]})
            fnew      = function _f_oop1(cache::LCN, x1::C1N, x2::C2N, select::Tuple{Int, Int}) where {LCN <: DiffCache,
                                                                                C1N <: AbstractArray{<: Number},
                                                                                C2N <: AbstractArray{<: Number}}
                target_cache = get_tmp(cache, x1, x2, select)
                if size(target_cache) != size(cache.du)
                    target_cache = reshape(target_cache, size(cache.du))
                end
                target_cache .= f(x1, x2)
                return target_cache
            end
        elseif length(chunksizes) == 2
            diffcache = twodualcache(cache, Val{chunksizes[1]}, Val{chunksizes[2]})
            fnew      = function _f_oop2(cache::LCN, x1::C1N, x2::C2N, select::Tuple{Int, Int}) where {LCN <: TwoDiffCache,
                                                                                C1N <: AbstractArray{<: Number},
                                                                                C2N <: AbstractArray{<: Number}}
                target_cache = get_tmp(cache, x1, x2, select)
                if size(target_cache) != size(cache.du)
                    target_cache = reshape(target_cache, size(cache.du))
                end
                target_cache .= f(x1, x2)
                return target_cache
            end
        elseif length(chunksizes) == 3
            diffcache = threedualcache(cache, Val{chunksizes[1]}, Val{chunksizes[2]}, Val{chunksizes[3]})
            fnew      = function _f_oop3(cache::LCN, x1::C1N, x2::C2N, select::Tuple{Int, Int}) where {LCN <: ThreeDiffCache,
                                                                                C1N <: AbstractArray{<: Number},
                                                                                C2N <: AbstractArray{<: Number}}
                target_cache = get_tmp(cache, x1, x2, select)
                if size(target_cache) != size(cache.du)
                    target_cache = reshape(target_cache, size(cache.du))
                end
                target_cache .= f(x1, x2)
                return target_cache
            end
        else
            throw(MethodError("The length of the sixth input argument, chunksizes, must be 1, 2, or 3."))
        end
    end
    return RALF2(fnew, f, diffcache)
end

function RALF2(fin::LC) where {LC <: AbstractArray{<: Number}}
    f(cache::LCN, x1::C1N, x2::C2N, select::Tuple{Int, Int}) where {LCN <: AbstractArray{<: Number}, C1N <: AbstractArray{<: Number}, C2N <: AbstractArray{<: Number}} = cache
    return RALF2{LC}(f, x -> fin, fin)
end

# Using the default of (1, 1) for `select` is important. This way, we can use autodiff
# during the homotopy algorithm without requiring additional arguments when calling `update!`
# to ensure the correct cache is used.
function (ralf::RALF2)(x1::C1, x2::C2, select::Tuple{Int, Int} = (1, 1)) where {C1 <: AbstractArray{<: Number}, C2 <: AbstractArray{<: Number}}
    return ralf.f(ralf.cache, x1, x2, select)
end

# RALF3
mutable struct RALF3{LC} <: AbstractRALF
    f::Function
    f0::Function
    cache::LC
end

get_cache_type(ral::RALF3{LC}) where {LC} = LC

function RALF3(f::Function, x1::C1, x2::C2, x3::C3, cache::AbstractArray{<: Number},
               chunksizes::NTuple{Nc, Int} =
               (ForwardDiff.pickchunksize(min(length(x1),
                                              length(x2), length(x3))), )) where {C1 <: AbstractArray{<: Number}, C2 <: AbstractArray{<: Number},
                                                                                C3 <: AbstractArray{<: Number}, N, Nc}
    if applicable(f, cache, x1, x2, x3)
        if length(chunksizes) == 1 # Figure out which type of DiffCache is needed
            diffcache = dualcache(cache, Val{chunksizes[1]})
            fnew      = function _f_ip1(cache::LCN, x1::C1N, x2::C2N,
                                        x3::C3N, select::Tuple{Int, Int}) where {LCN <: DiffCache,
                                                                                C1N <: AbstractArray{<: Number},
                                                                                C2N <: AbstractArray{<: Number},
                                                                                C3N <: AbstractArray{<: Number}}
                target_cache = get_tmp(cache, x1, x2, x3, select)
                if size(target_cache) != size(cache.du)
                    target_cache = reshape(target_cache, size(cache.du))
                end
                f(target_cache, x1, x2, x3)
                return target_cache
            end
        elseif length(chunksizes) == 2
            diffcache = twodualcache(cache, Val{chunksizes[1]}, Val{chunksizes[2]})
            fnew      = function _f_ip2(cache::LCN, x1::C1N, x2::C2N,
                                        x3::C3N, select::Tuple{Int, Int}) where {LCN <: TwoDiffCache,
                                                                                C1N <: AbstractArray{<: Number},
                                                                                C2N <: AbstractArray{<: Number},
                                                                                C3N <: AbstractArray{<: Number}}
                target_cache = get_tmp(cache, x1, x2, x3, select)
                if size(target_cache) != size(cache.du)
                    target_cache = reshape(target_cache, size(cache.du))
                end
                f(target_cache, x1, x2, x3)
                return target_cache
            end
        elseif length(chunksizes) == 3
            diffcache = threedualcache(cache, Val{chunksizes[1]}, Val{chunksizes[2]}, Val{chunksizes[3]})
            fnew      = function _f_ip3(cache::LCN, x1::C1N, x2::C2N,
                                        x3::C3N, select::Tuple{Int, Int}) where {LCN <: ThreeDiffCache,
                                                                                C1N <: AbstractArray{<: Number},
                                                                                C2N <: AbstractArray{<: Number},
                                                                                C3N <: AbstractArray{<: Number}}
                target_cache = get_tmp(cache, x1, x2, x3, select)
                if size(target_cache) != size(cache.du)
                    target_cache = reshape(target_cache, size(cache.du))
                end
                f(target_cache, x1, x2, x3)
                return target_cache
            end
        else
            throw(MethodError("The length of the seventh input argument, chunksizes, must be 1, 2, or 3."))
        end
    else
        if length(chunksizes) == 1 # Figure out which type of DiffCache is needed
            diffcache = dualcache(cache, Val{chunksizes[1]})
            fnew      = function _f_oop1(cache::LCN, x1::C1N, x2::C2N,
                                         x3::C3N, select::Tuple{Int, Int}) where {LCN <: DiffCache,
                                                                                C1N <: AbstractArray{<: Number},
                                                                                C2N <: AbstractArray{<: Number},
                                                                                C3N <: AbstractArray{<: Number}}
                target_cache = get_tmp(cache, x1, x2, x3, select)
                if size(target_cache) != size(cache.du)
                    target_cache = reshape(target_cache, size(cache.du))
                end
                target_cache .= f(x1, x2, x3)
                return target_cache
            end
        elseif length(chunksizes) == 2
            diffcache = twodualcache(cache, Val{chunksizes[1]}, Val{chunksizes[2]})
            fnew      = function _f_oop2(cache::LCN, x1::C1N, x2::C2N,
                                         x3::C3N, select::Tuple{Int, Int}) where {LCN <: TwoDiffCache,
                                                                                C1N <: AbstractArray{<: Number},
                                                                                C2N <: AbstractArray{<: Number},
                                                                                C3N <: AbstractArray{<: Number}}
                target_cache = get_tmp(cache, x1, x2, x3, select)
                if size(target_cache) != size(cache.du)
                    target_cache = reshape(target_cache, size(cache.du))
                end
                target_cache .= f(x1, x2, x3)
                return target_cache
            end
        elseif length(chunksizes) == 3
            diffcache = threedualcache(cache, Val{chunksizes[1]}, Val{chunksizes[2]}, Val{chunksizes[3]})
            fnew      = function _f_oop3(cache::LCN, x1::C1N, x2::C2N,
                                         x3::C3N, select::Tuple{Int, Int}) where {LCN <: ThreeDiffCache,
                                                                                C1N <: AbstractArray{<: Number},
                                                                                C2N <: AbstractArray{<: Number},
                                                                                C3N <: AbstractArray{<: Number}}
                target_cache = get_tmp(cache, x1, x2, x3, select)
                if size(target_cache) != size(cache.du)
                    target_cache = reshape(target_cache, size(cache.du))
                end
                target_cache .= f(x1, x2, x3)
                return target_cache
            end
        else
            throw(MethodError("The length of the seventh input argument, chunksizes, must be 1, 2, or 3."))
        end
    end
    return RALF3(fnew, f, diffcache)
end

function RALF3(fin::LC) where {LC <: AbstractArray{<: Number}}
    f(cache::LCN, x1::C1N, x2::C2N, x3::C3N, select::Tuple{Int, Int}) where {LCN <: AbstractArray{<: Number}, C1N <: AbstractArray{<: Number}, C2N <: AbstractArray{<: Number}, C3N <: AbstractArray{<: Number}} = cache
    return RALF3{LC}(f, x -> fin, fin)
end

# Using the default of (1, 1) for `select` is important. This way, we can use autodiff
# during the homotopy algorithm without requiring additional arguments when calling `update!`
# to ensure the correct cache is used.
function (ralf::RALF3)(x1::C1, x2::C2, x3::C3,
                       select::Tuple{Int, Int} = (1, 1)) where {C1 <: AbstractArray{<: Number}, C2 <: AbstractArray{<: Number},
                                                                C3 <: AbstractArray{<: Number}}
    return ralf.f(ralf.cache, x1, x2, x3, select)
end

# RALF4
mutable struct RALF4{LC} <: AbstractRALF
    f::Function
    f0::Function
    cache::LC
end

get_cache_type(ral::RALF4{LC}) where {LC} = LC

function RALF4(f::Function, x1::C1, x2::C2, x3::C3, x4::C4, cache::AbstractArray{<: Number},
               chunksizes::NTuple{Nc, Int} =
               (ForwardDiff.pickchunksize(min(length(x1),
                                              length(x2), legnth(x3), length(x4))), )) where {C1 <: AbstractArray{<: Number}, C2 <: AbstractArray{<: Number},
                                                                                C3 <: AbstractArray{<: Number}, C4 <: AbstractArray{<: Number}, N, Nc}

    if applicable(f, cache, x1, x2, x3, x4)
        if length(chunksizes) == 1 # Figure out which type of DiffCache is needed
            diffcache = dualcache(cache, Val{chunksizes[1]})
            fnew      = function _f_ip1(cache::LCN, x1::C1N, x2::C2N,
                                        x3::C3N, x4::C4N, select::Tuple{Int, Int}) where {LCN <: DiffCache,
                                                                                C1N <: AbstractArray{<: Number},
                                                                                C2N <: AbstractArray{<: Number},
                                                                                C3N <: AbstractArray{<: Number},
                                                                                C4N <: AbstractArray{<: Number}}
                target_cache = get_tmp(cache, x1, x2, x3, x4, select)
                if size(target_cache) != size(cache.du)
                    target_cache = reshape(target_cache, size(cache.du))
                end
                f(target_cache, x1, x2, x3, x4)
                return target_cache
            end
        elseif length(chunksizes) == 2
            diffcache = twodualcache(cache, Val{chunksizes[1]}, Val{chunksizes[2]})
            fnew      = function _f_ip2(cache::LCN, x1::C1N, x2::C2N,
                                        x3::C3N, x4::C4N, select::Tuple{Int, Int}) where {LCN <: TwoDiffCache,
                                                                                C1N <: AbstractArray{<: Number},
                                                                                C2N <: AbstractArray{<: Number},
                                                                                C3N <: AbstractArray{<: Number},
                                                                                C4N <: AbstractArray{<: Number}}
                f(get_tmp(cache, x1, x2, x3, x4, select), x1, x2, x3, x4)
                return get_tmp(cache, x1, x2, x3, x4, select)
            end
        elseif length(chunksizes) == 3
            diffcache = threedualcache(cache, Val{chunksizes[1]}, Val{chunksizes[2]}, Val{chunksizes[3]})
            fnew      = function _f_ip3(cache::LCN, x1::C1N, x2::C2N,
                                        x3::C3N, x4::C4N, select::Tuple{Int, Int}) where {LCN <: ThreeDiffCache,
                                                                                C1N <: AbstractArray{<: Number},
                                                                                C2N <: AbstractArray{<: Number},
                                                                                C3N <: AbstractArray{<: Number},
                                                                                C4N <: AbstractArray{<: Number}}
                f(get_tmp(cache, x1, x2, x3, x4, select), x1, x2, x3, x4)
                return get_tmp(cache, x1, x2, x3, x4, select)
            end
        else
            throw(MethodError("The length of the eighth input argument, chunksizes, must be 1, 2, or 3."))
        end
    else
        if length(chunksizes) == 1 # Figure out which type of DiffCache is needed
            diffcache = dualcache(cache, Val{chunksizes[1]})
            fnew      = function _f_oop1(cache::LCN, x1::C1N, x2::C2N,
                                         x3::C3N, x4::C4N, select::Tuple{Int, Int}) where {LCN <: DiffCache,
                                                                                C1N <: AbstractArray{<: Number},
                                                                                C2N <: AbstractArray{<: Number},
                                                                                C3N <: AbstractArray{<: Number},
                                                                                C4N <: AbstractArray{<: Number}}
                target_cache = get_tmp(cache, x1, x2, x3, x4, select)
                if size(target_cache) != size(cache.du)
                    target_cache = reshape(target_cache, size(cache.du))
                end
                target_cache .= f(x1, x2, x3, x4)
                return target_cache
            end
        elseif length(chunksizes) == 2
            diffcache = twodualcache(cache, Val{chunksizes[1]}, Val{chunksizes[2]})
            fnew      = function _f_oop2(cache::LCN, x1::C1N, x2::C2N,
                                         x3::C3N, x4::C4N, select::Tuple{Int, Int}) where {LCN <: TwoDiffCache,
                                                                                C1N <: AbstractArray{<: Number},
                                                                                C2N <: AbstractArray{<: Number},
                                                                                C3N <: AbstractArray{<: Number},
                                                                                C4N <: AbstractArray{<: Number}}
                target_cache = get_tmp(cache, x1, x2, x3, x4, select)
                if size(target_cache) != size(cache.du)
                    target_cache = reshape(target_cache, size(cache.du))
                end
                target_cache .= f(x1, x2, x3, x4)
                return target_cache
            end
        elseif length(chunksizes) == 3
            diffcache = threedualcache(cache, Val{chunksizes[1]}, Val{chunksizes[2]}, Val{chunksizes[3]})
            fnew      = function _f_oop3(cache::LCN, x1::C1N, x2::C2N,
                                         x3::C3N, x4::C4N, select::Tuple{Int, Int}) where {LCN <: ThreeDiffCache,
                                                                                C1N <: AbstractArray{<: Number},
                                                                                C2N <: AbstractArray{<: Number},
                                                                                C3N <: AbstractArray{<: Number},
                                                                                C4N <: AbstractArray{<: Number}}
                target_cache = get_tmp(cache, x1, x2, x3, x4, select)
                if size(target_cache) != size(cache.du)
                    target_cache = reshape(target_cache, size(cache.du))
                end
                target_cache .= f(x1, x2, x3, x4)
                return target_cache
            end
        else
            throw(MethodError("The length of the eighth input argument, chunksizes, must be 1, 2, or 3."))
        end
    end
    return RALF4(fnew, f, diffcache)
end

function RALF4(fin::LC) where {LC <: AbstractArray{<: Number}}
    f(cache::LCN, x1::C1N, x2::C2N, x3::C3N, x4::C4N, select::Tuple{Int, Int}) where {LCN <: AbstractArray{<: Number}, C1N <: AbstractArray{<: Number}, C2N <: AbstractArray{<: Number}, C3N <: AbstractArray{<: Number}, C4N <: AbstractArray{<: Number}} = cache
    return RALF4{LC}(f, x -> fin, fin)
end

# Using the default of (1, 1) for `select` is important. This way, we can use autodiff
# during the homotopy algorithm without requiring additional arguments when calling `update!`
# to ensure the correct cache is used.
function (ralf::RALF4)(x1::C1, x2::C2, x3::C3,
                       x4::C4, select::Tuple{Int, Int} = (1, 1)) where {C1 <: AbstractArray{<: Number}, C2 <: AbstractArray{<: Number},
                                                                        C3 <: AbstractArray{<: Number}, C4 <: AbstractArray{<: Number}}
    return ralf.f(ralf.cache, x1, x2, x3, x4, select)
end


text:
# benchmark for tuple VS vector cache

using BenchmarkTools
using FrankWolfe

for n in (10, 100, 1000)
    @info "n = $n"
    direction = zeros(n)
    rhs = 10 * rand()
    lmo_unit = FrankWolfe.UnitSimplexOracle(rhs)
    lmo_veccached = FrankWolfe.VectorCacheLMO(lmo_unit)
    res_vec = @benchmark begin
        for idx in 1:$n
            $direction .= 0
            $direction[idx] = -1
            res_point_cached_vec =
                FrankWolfe.compute_extreme_point($lmo_veccached, $direction, threshold=0)
            _ = length($lmo_veccached)
        end
        empty!($lmo_veccached)
    end
    res_multi = map(1:10) do N
        lmo_multicached = FrankWolfe.MultiCacheLMO{N}(lmo_unit)
        @benchmark begin
            for idx in 1:$n
                $direction .= 0
                $direction[idx] = -1
                res_point_cached_vec =
                    FrankWolfe.compute_extreme_point($lmo_multicached, $direction, threshold=0)
                _ = length($lmo_multicached)
            end
            empty!($lmo_multicached)
        end
    end
    @info "Vec benchmark"
    display(res_vec)
    for N in 1:10
        @info "Tuple benchmark $N"
        display(res_multi[N])
    end
end

ext: jl


text:
# This file was generated by the Julia Swagger Code Generator
# Do not modify this file directly. Modify the swagger specification instead.

struct AdmissionregistrationV1beta1Api <: SwaggerApi
    client::Swagger.Client
end

"""

create a MutatingWebhookConfiguration
Param: body::IoK8sApiAdmissionregistrationV1beta1MutatingWebhookConfiguration (required)
Param: pretty::String
Param: dryRun::String
Param: fieldManager::String
Return: IoK8sApiAdmissionregistrationV1beta1MutatingWebhookConfiguration
"""
function createAdmissionregistrationV1beta1MutatingWebhookConfiguration(_api::AdmissionregistrationV1beta1Api, body; pretty=nothing, dryRun=nothing, fieldManager=nothing, _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "POST", IoK8sApiAdmissionregistrationV1beta1MutatingWebhookConfiguration, "/apis/admissionregistration.k8s.io/v1beta1/mutatingwebhookconfigurations", ["BearerToken"], body)
    Swagger.set_param(_ctx.query, "pretty", pretty)  # type String
    Swagger.set_param(_ctx.query, "dryRun", dryRun)  # type String
    Swagger.set_param(_ctx.query, "fieldManager", fieldManager)  # type String
    Swagger.set_header_accept(_ctx, ["application/json", "application/yaml", "application/vnd.kubernetes.protobuf"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["*/*"] : [_mediaType])
    Swagger.exec(_ctx)
end

"""

create a ValidatingWebhookConfiguration
Param: body::IoK8sApiAdmissionregistrationV1beta1ValidatingWebhookConfiguration (required)
Param: pretty::String
Param: dryRun::String
Param: fieldManager::String
Return: IoK8sApiAdmissionregistrationV1beta1ValidatingWebhookConfiguration
"""
function createAdmissionregistrationV1beta1ValidatingWebhookConfiguration(_api::AdmissionregistrationV1beta1Api, body; pretty=nothing, dryRun=nothing, fieldManager=nothing, _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "POST", IoK8sApiAdmissionregistrationV1beta1ValidatingWebhookConfiguration, "/apis/admissionregistration.k8s.io/v1beta1/validatingwebhookconfigurations", ["BearerToken"], body)
    Swagger.set_param(_ctx.query, "pretty", pretty)  # type String
    Swagger.set_param(_ctx.query, "dryRun", dryRun)  # type String
    Swagger.set_param(_ctx.query, "fieldManager", fieldManager)  # type String
    Swagger.set_header_accept(_ctx, ["application/json", "application/yaml", "application/vnd.kubernetes.protobuf"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["*/*"] : [_mediaType])
    Swagger.exec(_ctx)
end

"""

delete collection of MutatingWebhookConfiguration
Param: pretty::String
Param: __continue__::String
Param: fieldSelector::String
Param: labelSelector::String
Param: limit::Int32
Param: resourceVersion::String
Param: timeoutSeconds::Int32
Param: watch::Bool
Return: IoK8sApimachineryPkgApisMetaV1Status
"""
function deleteAdmissionregistrationV1beta1CollectionMutatingWebhookConfiguration(_api::AdmissionregistrationV1beta1Api; pretty=nothing, __continue__=nothing, fieldSelector=nothing, labelSelector=nothing, limit=nothing, resourceVersion=nothing, timeoutSeconds=nothing, watch=nothing, _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "DELETE", IoK8sApimachineryPkgApisMetaV1Status, "/apis/admissionregistration.k8s.io/v1beta1/mutatingwebhookconfigurations", ["BearerToken"])
    Swagger.set_param(_ctx.query, "pretty", pretty)  # type String
    Swagger.set_param(_ctx.query, "continue", __continue__)  # type String
    Swagger.set_param(_ctx.query, "fieldSelector", fieldSelector)  # type String
    Swagger.set_param(_ctx.query, "labelSelector", labelSelector)  # type String
    Swagger.set_param(_ctx.query, "limit", limit)  # type Int32
    Swagger.set_param(_ctx.query, "resourceVersion", resourceVersion)  # type String
    Swagger.set_param(_ctx.query, "timeoutSeconds", timeoutSeconds)  # type Int32
    Swagger.set_param(_ctx.query, "watch", watch)  # type Bool
    Swagger.set_header_accept(_ctx, ["application/json", "application/yaml", "application/vnd.kubernetes.protobuf"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["*/*"] : [_mediaType])
    Swagger.exec(_ctx)
end

"""

delete collection of ValidatingWebhookConfiguration
Param: pretty::String
Param: __continue__::String
Param: fieldSelector::String
Param: labelSelector::String
Param: limit::Int32
Param: resourceVersion::String
Param: timeoutSeconds::Int32
Param: watch::Bool
Return: IoK8sApimachineryPkgApisMetaV1Status
"""
function deleteAdmissionregistrationV1beta1CollectionValidatingWebhookConfiguration(_api::AdmissionregistrationV1beta1Api; pretty=nothing, __continue__=nothing, fieldSelector=nothing, labelSelector=nothing, limit=nothing, resourceVersion=nothing, timeoutSeconds=nothing, watch=nothing, _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "DELETE", IoK8sApimachineryPkgApisMetaV1Status, "/apis/admissionregistration.k8s.io/v1beta1/validatingwebhookconfigurations", ["BearerToken"])
    Swagger.set_param(_ctx.query, "pretty", pretty)  # type String
    Swagger.set_param(_ctx.query, "continue", __continue__)  # type String
    Swagger.set_param(_ctx.query, "fieldSelector", fieldSelector)  # type String
    Swagger.set_param(_ctx.query, "labelSelector", labelSelector)  # type String
    Swagger.set_param(_ctx.query, "limit", limit)  # type Int32
    Swagger.set_param(_ctx.query, "resourceVersion", resourceVersion)  # type String
    Swagger.set_param(_ctx.query, "timeoutSeconds", timeoutSeconds)  # type Int32
    Swagger.set_param(_ctx.query, "watch", watch)  # type Bool
    Swagger.set_header_accept(_ctx, ["application/json", "application/yaml", "application/vnd.kubernetes.protobuf"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["*/*"] : [_mediaType])
    Swagger.exec(_ctx)
end

"""

delete a MutatingWebhookConfiguration
Param: name::String (required)
Param: pretty::String
Param: body::IoK8sApimachineryPkgApisMetaV1DeleteOptions
Param: dryRun::String
Param: gracePeriodSeconds::Int32
Param: orphanDependents::Bool
Param: propagationPolicy::String
Return: IoK8sApimachineryPkgApisMetaV1Status
"""
function deleteAdmissionregistrationV1beta1MutatingWebhookConfiguration(_api::AdmissionregistrationV1beta1Api, name::String; pretty=nothing, body=nothing, dryRun=nothing, gracePeriodSeconds=nothing, orphanDependents=nothing, propagationPolicy=nothing, _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "DELETE", IoK8sApimachineryPkgApisMetaV1Status, "/apis/admissionregistration.k8s.io/v1beta1/mutatingwebhookconfigurations/{name}", ["BearerToken"], body)
    Swagger.set_param(_ctx.path, "name", name)  # type String
    Swagger.set_param(_ctx.query, "pretty", pretty)  # type String
    Swagger.set_param(_ctx.query, "dryRun", dryRun)  # type String
    Swagger.set_param(_ctx.query, "gracePeriodSeconds", gracePeriodSeconds)  # type Int32
    Swagger.set_param(_ctx.query, "orphanDependents", orphanDependents)  # type Bool
    Swagger.set_param(_ctx.query, "propagationPolicy", propagationPolicy)  # type String
    Swagger.set_header_accept(_ctx, ["application/json", "application/yaml", "application/vnd.kubernetes.protobuf"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["*/*"] : [_mediaType])
    Swagger.exec(_ctx)
end

"""

delete a ValidatingWebhookConfiguration
Param: name::String (required)
Param: pretty::String
Param: body::IoK8sApimachineryPkgApisMetaV1DeleteOptions
Param: dryRun::String
Param: gracePeriodSeconds::Int32
Param: orphanDependents::Bool
Param: propagationPolicy::String
Return: IoK8sApimachineryPkgApisMetaV1Status
"""
function deleteAdmissionregistrationV1beta1ValidatingWebhookConfiguration(_api::AdmissionregistrationV1beta1Api, name::String; pretty=nothing, body=nothing, dryRun=nothing, gracePeriodSeconds=nothing, orphanDependents=nothing, propagationPolicy=nothing, _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "DELETE", IoK8sApimachineryPkgApisMetaV1Status, "/apis/admissionregistration.k8s.io/v1beta1/validatingwebhookconfigurations/{name}", ["BearerToken"], body)
    Swagger.set_param(_ctx.path, "name", name)  # type String
    Swagger.set_param(_ctx.query, "pretty", pretty)  # type String
    Swagger.set_param(_ctx.query, "dryRun", dryRun)  # type String
    Swagger.set_param(_ctx.query, "gracePeriodSeconds", gracePeriodSeconds)  # type Int32
    Swagger.set_param(_ctx.query, "orphanDependents", orphanDependents)  # type Bool
    Swagger.set_param(_ctx.query, "propagationPolicy", propagationPolicy)  # type String
    Swagger.set_header_accept(_ctx, ["application/json", "application/yaml", "application/vnd.kubernetes.protobuf"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["*/*"] : [_mediaType])
    Swagger.exec(_ctx)
end

"""

get available resources
Return: IoK8sApimachineryPkgApisMetaV1APIResourceList
"""
function getAdmissionregistrationV1beta1APIResources(_api::AdmissionregistrationV1beta1Api; _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "GET", IoK8sApimachineryPkgApisMetaV1APIResourceList, "/apis/admissionregistration.k8s.io/v1beta1/", ["BearerToken"])
    Swagger.set_header_accept(_ctx, ["application/json", "application/yaml", "application/vnd.kubernetes.protobuf"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["application/json", "application/yaml", "application/vnd.kubernetes.protobuf"] : [_mediaType])
    Swagger.exec(_ctx)
end

"""

list or watch objects of kind MutatingWebhookConfiguration
Param: pretty::String
Param: __continue__::String
Param: fieldSelector::String
Param: labelSelector::String
Param: limit::Int32
Param: resourceVersion::String
Param: timeoutSeconds::Int32
Param: watch::Bool
Return: IoK8sApiAdmissionregistrationV1beta1MutatingWebhookConfigurationList
"""
function listAdmissionregistrationV1beta1MutatingWebhookConfiguration(_api::AdmissionregistrationV1beta1Api; pretty=nothing, __continue__=nothing, fieldSelector=nothing, labelSelector=nothing, limit=nothing, resourceVersion=nothing, timeoutSeconds=nothing, watch=nothing, _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "GET", IoK8sApiAdmissionregistrationV1beta1MutatingWebhookConfigurationList, "/apis/admissionregistration.k8s.io/v1beta1/mutatingwebhookconfigurations", ["BearerToken"])
    Swagger.set_param(_ctx.query, "pretty", pretty)  # type String
    Swagger.set_param(_ctx.query, "continue", __continue__)  # type String
    Swagger.set_param(_ctx.query, "fieldSelector", fieldSelector)  # type String
    Swagger.set_param(_ctx.query, "labelSelector", labelSelector)  # type String
    Swagger.set_param(_ctx.query, "limit", limit)  # type Int32
    Swagger.set_param(_ctx.query, "resourceVersion", resourceVersion)  # type String
    Swagger.set_param(_ctx.query, "timeoutSeconds", timeoutSeconds)  # type Int32
    Swagger.set_param(_ctx.query, "watch", watch)  # type Bool
    Swagger.set_header_accept(_ctx, ["application/json", "application/yaml", "application/vnd.kubernetes.protobuf", "application/json;stream=watch", "application/vnd.kubernetes.protobuf;stream=watch"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["*/*"] : [_mediaType])
    Swagger.exec(_ctx)
end

"""

list or watch objects of kind ValidatingWebhookConfiguration
Param: pretty::String
Param: __continue__::String
Param: fieldSelector::String
Param: labelSelector::String
Param: limit::Int32
Param: resourceVersion::String
Param: timeoutSeconds::Int32
Param: watch::Bool
Return: IoK8sApiAdmissionregistrationV1beta1ValidatingWebhookConfigurationList
"""
function listAdmissionregistrationV1beta1ValidatingWebhookConfiguration(_api::AdmissionregistrationV1beta1Api; pretty=nothing, __continue__=nothing, fieldSelector=nothing, labelSelector=nothing, limit=nothing, resourceVersion=nothing, timeoutSeconds=nothing, watch=nothing, _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "GET", IoK8sApiAdmissionregistrationV1beta1ValidatingWebhookConfigurationList, "/apis/admissionregistration.k8s.io/v1beta1/validatingwebhookconfigurations", ["BearerToken"])
    Swagger.set_param(_ctx.query, "pretty", pretty)  # type String
    Swagger.set_param(_ctx.query, "continue", __continue__)  # type String
    Swagger.set_param(_ctx.query, "fieldSelector", fieldSelector)  # type String
    Swagger.set_param(_ctx.query, "labelSelector", labelSelector)  # type String
    Swagger.set_param(_ctx.query, "limit", limit)  # type Int32
    Swagger.set_param(_ctx.query, "resourceVersion", resourceVersion)  # type String
    Swagger.set_param(_ctx.query, "timeoutSeconds", timeoutSeconds)  # type Int32
    Swagger.set_param(_ctx.query, "watch", watch)  # type Bool
    Swagger.set_header_accept(_ctx, ["application/json", "application/yaml", "application/vnd.kubernetes.protobuf", "application/json;stream=watch", "application/vnd.kubernetes.protobuf;stream=watch"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["*/*"] : [_mediaType])
    Swagger.exec(_ctx)
end

"""

partially update the specified MutatingWebhookConfiguration
Param: name::String (required)
Param: body::IoK8sApimachineryPkgApisMetaV1Patch (required)
Param: pretty::String
Param: dryRun::String
Param: fieldManager::String
Param: force::Bool
Return: IoK8sApiAdmissionregistrationV1beta1MutatingWebhookConfiguration
"""
function patchAdmissionregistrationV1beta1MutatingWebhookConfiguration(_api::AdmissionregistrationV1beta1Api, name::String, body; pretty=nothing, dryRun=nothing, fieldManager=nothing, force=nothing, _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "PATCH", IoK8sApiAdmissionregistrationV1beta1MutatingWebhookConfiguration, "/apis/admissionregistration.k8s.io/v1beta1/mutatingwebhookconfigurations/{name}", ["BearerToken"], body)
    Swagger.set_param(_ctx.path, "name", name)  # type String
    Swagger.set_param(_ctx.query, "pretty", pretty)  # type String
    Swagger.set_param(_ctx.query, "dryRun", dryRun)  # type String
    Swagger.set_param(_ctx.query, "fieldManager", fieldManager)  # type String
    Swagger.set_param(_ctx.query, "force", force)  # type Bool
    Swagger.set_header_accept(_ctx, ["application/json", "application/yaml", "application/vnd.kubernetes.protobuf"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["application/json-patch+json", "application/merge-patch+json", "application/strategic-merge-patch+json"] : [_mediaType])
    Swagger.exec(_ctx)
end

"""

partially update the specified ValidatingWebhookConfiguration
Param: name::String (required)
Param: body::IoK8sApimachineryPkgApisMetaV1Patch (required)
Param: pretty::String
Param: dryRun::String
Param: fieldManager::String
Param: force::Bool
Return: IoK8sApiAdmissionregistrationV1beta1ValidatingWebhookConfiguration
"""
function patchAdmissionregistrationV1beta1ValidatingWebhookConfiguration(_api::AdmissionregistrationV1beta1Api, name::String, body; pretty=nothing, dryRun=nothing, fieldManager=nothing, force=nothing, _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "PATCH", IoK8sApiAdmissionregistrationV1beta1ValidatingWebhookConfiguration, "/apis/admissionregistration.k8s.io/v1beta1/validatingwebhookconfigurations/{name}", ["BearerToken"], body)
    Swagger.set_param(_ctx.path, "name", name)  # type String
    Swagger.set_param(_ctx.query, "pretty", pretty)  # type String
    Swagger.set_param(_ctx.query, "dryRun", dryRun)  # type String
    Swagger.set_param(_ctx.query, "fieldManager", fieldManager)  # type String
    Swagger.set_param(_ctx.query, "force", force)  # type Bool
    Swagger.set_header_accept(_ctx, ["application/json", "application/yaml", "application/vnd.kubernetes.protobuf"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["application/json-patch+json", "application/merge-patch+json", "application/strategic-merge-patch+json"] : [_mediaType])
    Swagger.exec(_ctx)
end

"""

read the specified MutatingWebhookConfiguration
Param: name::String (required)
Param: pretty::String
Param: exact::Bool
Param: __export__::Bool
Return: IoK8sApiAdmissionregistrationV1beta1MutatingWebhookConfiguration
"""
function readAdmissionregistrationV1beta1MutatingWebhookConfiguration(_api::AdmissionregistrationV1beta1Api, name::String; pretty=nothing, exact=nothing, __export__=nothing, _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "GET", IoK8sApiAdmissionregistrationV1beta1MutatingWebhookConfiguration, "/apis/admissionregistration.k8s.io/v1beta1/mutatingwebhookconfigurations/{name}", ["BearerToken"])
    Swagger.set_param(_ctx.path, "name", name)  # type String
    Swagger.set_param(_ctx.query, "pretty", pretty)  # type String
    Swagger.set_param(_ctx.query, "exact", exact)  # type Bool
    Swagger.set_param(_ctx.query, "export", __export__)  # type Bool
    Swagger.set_header_accept(_ctx, ["application/json", "application/yaml", "application/vnd.kubernetes.protobuf"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["*/*"] : [_mediaType])
    Swagger.exec(_ctx)
end

"""

read the specified ValidatingWebhookConfiguration
Param: name::String (required)
Param: pretty::String
Param: exact::Bool
Param: __export__::Bool
Return: IoK8sApiAdmissionregistrationV1beta1ValidatingWebhookConfiguration
"""
function readAdmissionregistrationV1beta1ValidatingWebhookConfiguration(_api::AdmissionregistrationV1beta1Api, name::String; pretty=nothing, exact=nothing, __export__=nothing, _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "GET", IoK8sApiAdmissionregistrationV1beta1ValidatingWebhookConfiguration, "/apis/admissionregistration.k8s.io/v1beta1/validatingwebhookconfigurations/{name}", ["BearerToken"])
    Swagger.set_param(_ctx.path, "name", name)  # type String
    Swagger.set_param(_ctx.query, "pretty", pretty)  # type String
    Swagger.set_param(_ctx.query, "exact", exact)  # type Bool
    Swagger.set_param(_ctx.query, "export", __export__)  # type Bool
    Swagger.set_header_accept(_ctx, ["application/json", "application/yaml", "application/vnd.kubernetes.protobuf"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["*/*"] : [_mediaType])
    Swagger.exec(_ctx)
end

"""

replace the specified MutatingWebhookConfiguration
Param: name::String (required)
Param: body::IoK8sApiAdmissionregistrationV1beta1MutatingWebhookConfiguration (required)
Param: pretty::String
Param: dryRun::String
Param: fieldManager::String
Return: IoK8sApiAdmissionregistrationV1beta1MutatingWebhookConfiguration
"""
function replaceAdmissionregistrationV1beta1MutatingWebhookConfiguration(_api::AdmissionregistrationV1beta1Api, name::String, body; pretty=nothing, dryRun=nothing, fieldManager=nothing, _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "PUT", IoK8sApiAdmissionregistrationV1beta1MutatingWebhookConfiguration, "/apis/admissionregistration.k8s.io/v1beta1/mutatingwebhookconfigurations/{name}", ["BearerToken"], body)
    Swagger.set_param(_ctx.path, "name", name)  # type String
    Swagger.set_param(_ctx.query, "pretty", pretty)  # type String
    Swagger.set_param(_ctx.query, "dryRun", dryRun)  # type String
    Swagger.set_param(_ctx.query, "fieldManager", fieldManager)  # type String
    Swagger.set_header_accept(_ctx, ["application/json", "application/yaml", "application/vnd.kubernetes.protobuf"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["*/*"] : [_mediaType])
    Swagger.exec(_ctx)
end

"""

replace the specified ValidatingWebhookConfiguration
Param: name::String (required)
Param: body::IoK8sApiAdmissionregistrationV1beta1ValidatingWebhookConfiguration (required)
Param: pretty::String
Param: dryRun::String
Param: fieldManager::String
Return: IoK8sApiAdmissionregistrationV1beta1ValidatingWebhookConfiguration
"""
function replaceAdmissionregistrationV1beta1ValidatingWebhookConfiguration(_api::AdmissionregistrationV1beta1Api, name::String, body; pretty=nothing, dryRun=nothing, fieldManager=nothing, _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "PUT", IoK8sApiAdmissionregistrationV1beta1ValidatingWebhookConfiguration, "/apis/admissionregistration.k8s.io/v1beta1/validatingwebhookconfigurations/{name}", ["BearerToken"], body)
    Swagger.set_param(_ctx.path, "name", name)  # type String
    Swagger.set_param(_ctx.query, "pretty", pretty)  # type String
    Swagger.set_param(_ctx.query, "dryRun", dryRun)  # type String
    Swagger.set_param(_ctx.query, "fieldManager", fieldManager)  # type String
    Swagger.set_header_accept(_ctx, ["application/json", "application/yaml", "application/vnd.kubernetes.protobuf"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["*/*"] : [_mediaType])
    Swagger.exec(_ctx)
end

"""

watch changes to an object of kind MutatingWebhookConfiguration. deprecated: use the 'watch' parameter with a list operation instead, filtered to a single item with the 'fieldSelector' parameter.
Param: name::String (required)
Param: __continue__::String
Param: fieldSelector::String
Param: labelSelector::String
Param: limit::Int32
Param: pretty::String
Param: resourceVersion::String
Param: timeoutSeconds::Int32
Param: watch::Bool
Return: IoK8sApimachineryPkgApisMetaV1WatchEvent
"""
function watchAdmissionregistrationV1beta1MutatingWebhookConfiguration(_api::AdmissionregistrationV1beta1Api, name::String; __continue__=nothing, fieldSelector=nothing, labelSelector=nothing, limit=nothing, pretty=nothing, resourceVersion=nothing, timeoutSeconds=nothing, watch=nothing, _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "GET", IoK8sApimachineryPkgApisMetaV1WatchEvent, "/apis/admissionregistration.k8s.io/v1beta1/watch/mutatingwebhookconfigurations/{name}", ["BearerToken"])
    Swagger.set_param(_ctx.path, "name", name)  # type String
    Swagger.set_param(_ctx.query, "continue", __continue__)  # type String
    Swagger.set_param(_ctx.query, "fieldSelector", fieldSelector)  # type String
    Swagger.set_param(_ctx.query, "labelSelector", labelSelector)  # type String
    Swagger.set_param(_ctx.query, "limit", limit)  # type Int32
    Swagger.set_param(_ctx.query, "pretty", pretty)  # type String
    Swagger.set_param(_ctx.query, "resourceVersion", resourceVersion)  # type String
    Swagger.set_param(_ctx.query, "timeoutSeconds", timeoutSeconds)  # type Int32
    Swagger.set_param(_ctx.query, "watch", watch)  # type Bool
    Swagger.set_header_accept(_ctx, ["application/json", "application/yaml", "application/vnd.kubernetes.protobuf", "application/json;stream=watch", "application/vnd.kubernetes.protobuf;stream=watch"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["*/*"] : [_mediaType])
    Swagger.exec(_ctx)
end

"""

watch individual changes to a list of MutatingWebhookConfiguration. deprecated: use the 'watch' parameter with a list operation instead.
Param: __continue__::String
Param: fieldSelector::String
Param: labelSelector::String
Param: limit::Int32
Param: pretty::String
Param: resourceVersion::String
Param: timeoutSeconds::Int32
Param: watch::Bool
Return: IoK8sApimachineryPkgApisMetaV1WatchEvent
"""
function watchAdmissionregistrationV1beta1MutatingWebhookConfigurationList(_api::AdmissionregistrationV1beta1Api; __continue__=nothing, fieldSelector=nothing, labelSelector=nothing, limit=nothing, pretty=nothing, resourceVersion=nothing, timeoutSeconds=nothing, watch=nothing, _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "GET", IoK8sApimachineryPkgApisMetaV1WatchEvent, "/apis/admissionregistration.k8s.io/v1beta1/watch/mutatingwebhookconfigurations", ["BearerToken"])
    Swagger.set_param(_ctx.query, "continue", __continue__)  # type String
    Swagger.set_param(_ctx.query, "fieldSelector", fieldSelector)  # type String
    Swagger.set_param(_ctx.query, "labelSelector", labelSelector)  # type String
    Swagger.set_param(_ctx.query, "limit", limit)  # type Int32
    Swagger.set_param(_ctx.query, "pretty", pretty)  # type String
    Swagger.set_param(_ctx.query, "resourceVersion", resourceVersion)  # type String
    Swagger.set_param(_ctx.query, "timeoutSeconds", timeoutSeconds)  # type Int32
    Swagger.set_param(_ctx.query, "watch", watch)  # type Bool
    Swagger.set_header_accept(_ctx, ["application/json", "application/yaml", "application/vnd.kubernetes.protobuf", "application/json;stream=watch", "application/vnd.kubernetes.protobuf;stream=watch"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["*/*"] : [_mediaType])
    Swagger.exec(_ctx)
end

"""

watch changes to an object of kind ValidatingWebhookConfiguration. deprecated: use the 'watch' parameter with a list operation instead, filtered to a single item with the 'fieldSelector' parameter.
Param: name::String (required)
Param: __continue__::String
Param: fieldSelector::String
Param: labelSelector::String
Param: limit::Int32
Param: pretty::String
Param: resourceVersion::String
Param: timeoutSeconds::Int32
Param: watch::Bool
Return: IoK8sApimachineryPkgApisMetaV1WatchEvent
"""
function watchAdmissionregistrationV1beta1ValidatingWebhookConfiguration(_api::AdmissionregistrationV1beta1Api, name::String; __continue__=nothing, fieldSelector=nothing, labelSelector=nothing, limit=nothing, pretty=nothing, resourceVersion=nothing, timeoutSeconds=nothing, watch=nothing, _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "GET", IoK8sApimachineryPkgApisMetaV1WatchEvent, "/apis/admissionregistration.k8s.io/v1beta1/watch/validatingwebhookconfigurations/{name}", ["BearerToken"])
    Swagger.set_param(_ctx.path, "name", name)  # type String
    Swagger.set_param(_ctx.query, "continue", __continue__)  # type String
    Swagger.set_param(_ctx.query, "fieldSelector", fieldSelector)  # type String
    Swagger.set_param(_ctx.query, "labelSelector", labelSelector)  # type String
    Swagger.set_param(_ctx.query, "limit", limit)  # type Int32
    Swagger.set_param(_ctx.query, "pretty", pretty)  # type String
    Swagger.set_param(_ctx.query, "resourceVersion", resourceVersion)  # type String
    Swagger.set_param(_ctx.query, "timeoutSeconds", timeoutSeconds)  # type Int32
    Swagger.set_param(_ctx.query, "watch", watch)  # type Bool
    Swagger.set_header_accept(_ctx, ["application/json", "application/yaml", "application/vnd.kubernetes.protobuf", "application/json;stream=watch", "application/vnd.kubernetes.protobuf;stream=watch"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["*/*"] : [_mediaType])
    Swagger.exec(_ctx)
end

"""

watch individual changes to a list of ValidatingWebhookConfiguration. deprecated: use the 'watch' parameter with a list operation instead.
Param: __continue__::String
Param: fieldSelector::String
Param: labelSelector::String
Param: limit::Int32
Param: pretty::String
Param: resourceVersion::String
Param: timeoutSeconds::Int32
Param: watch::Bool
Return: IoK8sApimachineryPkgApisMetaV1WatchEvent
"""
function watchAdmissionregistrationV1beta1ValidatingWebhookConfigurationList(_api::AdmissionregistrationV1beta1Api; __continue__=nothing, fieldSelector=nothing, labelSelector=nothing, limit=nothing, pretty=nothing, resourceVersion=nothing, timeoutSeconds=nothing, watch=nothing, _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "GET", IoK8sApimachineryPkgApisMetaV1WatchEvent, "/apis/admissionregistration.k8s.io/v1beta1/watch/validatingwebhookconfigurations", ["BearerToken"])
    Swagger.set_param(_ctx.query, "continue", __continue__)  # type String
    Swagger.set_param(_ctx.query, "fieldSelector", fieldSelector)  # type String
    Swagger.set_param(_ctx.query, "labelSelector", labelSelector)  # type String
    Swagger.set_param(_ctx.query, "limit", limit)  # type Int32
    Swagger.set_param(_ctx.query, "pretty", pretty)  # type String
    Swagger.set_param(_ctx.query, "resourceVersion", resourceVersion)  # type String
    Swagger.set_param(_ctx.query, "timeoutSeconds", timeoutSeconds)  # type Int32
    Swagger.set_param(_ctx.query, "watch", watch)  # type Bool
    Swagger.set_header_accept(_ctx, ["application/json", "application/yaml", "application/vnd.kubernetes.protobuf", "application/json;stream=watch", "application/vnd.kubernetes.protobuf;stream=watch"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["*/*"] : [_mediaType])
    Swagger.exec(_ctx)
end

export createAdmissionregistrationV1beta1MutatingWebhookConfiguration, createAdmissionregistrationV1beta1ValidatingWebhookConfiguration, deleteAdmissionregistrationV1beta1CollectionMutatingWebhookConfiguration, deleteAdmissionregistrationV1beta1CollectionValidatingWebhookConfiguration, deleteAdmissionregistrationV1beta1MutatingWebhookConfiguration, deleteAdmissionregistrationV1beta1ValidatingWebhookConfiguration, getAdmissionregistrationV1beta1APIResources, listAdmissionregistrationV1beta1MutatingWebhookConfiguration, listAdmissionregistrationV1beta1ValidatingWebhookConfiguration, patchAdmissionregistrationV1beta1MutatingWebhookConfiguration, patchAdmissionregistrationV1beta1ValidatingWebhookConfiguration, readAdmissionregistrationV1beta1MutatingWebhookConfiguration, readAdmissionregistrationV1beta1ValidatingWebhookConfiguration, replaceAdmissionregistrationV1beta1MutatingWebhookConfiguration, replaceAdmissionregistrationV1beta1ValidatingWebhookConfiguration, watchAdmissionregistrationV1beta1MutatingWebhookConfiguration, watchAdmissionregistrationV1beta1MutatingWebhookConfigurationList, watchAdmissionregistrationV1beta1ValidatingWebhookConfiguration, watchAdmissionregistrationV1beta1ValidatingWebhookConfigurationList


text:
###############
# Branch Type #
###############

@ghdef mutable struct Branch
    name::Union{String, Nothing}
    label::Union{String, Nothing}
    ref::Union{String, Nothing}
    sha::Union{String, Nothing}
    commit::Union{Commit, Nothing}
    user::Union{Owner, Nothing}
    repo::Union{Repo, Nothing}
    _links::Union{Dict, Nothing}
    protection::Union{Dict, Nothing}
end

Branch(name::AbstractString) = Branch(Dict("name" => name))

namefield(branch::Branch) = (branch.name === nothing) ? branch.ref : branch.name

###############
# API Methods #
###############

@api_default function branches(api::GitHubAPI, repo; options...)
    results, page_data = gh_get_paged_json(api, "/repos/$(name(repo))/branches"; options...)
    return map(Branch, results), page_data
end

@api_default function branch(api::GitHubAPI, repo, branch_obj; options...)
    result = gh_get_json(api, "/repos/$(name(repo))/branches/$(name(branch_obj))"; options...)
    return Branch(result)
end


text:
using UncertaintyQuantification

x = RandomVariable.(Uniform(-π, π), [:x1, :x2, :x3])
a = Parameter(7, :a)
b = Parameter(0.05, :b)

inputs = [x; a; b]

ishigami = Model(
    df -> sin.(df.x1) .+ df.a .* sin.(df.x2) .^ 2 .+ df.b .* (df.x3 .^ 4) .* sin.(df.x1), :y
)

data = sample(inputs, SobolSampling(500))
evaluate!(ishigami, data)

phs = PolyharmonicSpline(data, 2, :y)

si, _ = sobolindices([ishigami], inputs, :y, MonteCarlo(10000))
si_phs, _ = sobolindices([phs], inputs, :y, SobolSampling(10000))

println("First order sobol indices of the ishigami function: $si")
println("First order sobol indices of the polyharmonic spline meta mode: $si_phs")

max_stars_repo_name: FriesischScott/julia-uq

max_issues_repo_name: FriesischScott/julia-uq

max_forks_repo_name: FriesischScott/julia-uq


text:
using DiffEqTutorials
DiffEqTutorials.weave_file(".","test.jmd")


text:
export correlationsum_fixedmass

using SpecialFunctions, Random

"""
    correlationsum_fixedmass(data, max_j; metric = Euclidean(), M = length(data)) → rs, ys
A fixed mass algorithm for the calculation of the fractal dimension ``\\Delta`` according
to [^Grassberger1988] with `max_j` the maximum number of neighbours that
should be considered for the calculation, `M` defines the number of points
considered for the calculation, default is the whole data set.

Implements
```math
\\Delta \\overline{\\log r^{(j)}} \\sim Ψ(j) - \\log N
```
where `` \\Psi(j) = \\frac{\\text{d} \\log Γ(j)}{\\text{d} j}
``, `rs` = ``\\overline{\\log r^{(j)}}`` and `ys` = ``\\Psi(j) - \\log N``.

``\\Delta`` can be computed by using `linear_region(rs, ys)`.

[^Grassberger1988]: Peter Grassberger (1988) [Finite sample Corrections to Entropy and Dimension Estimates, Physics Letters A 128(6-7)](https://doi.org/10.1016/0375-9601(88)90193-4)
"""
function correlationsum_fixedmass(data, max_j; metric = Euclidean(), M = length(data), w = 0)
    N = length(data)
    M > N && throw(ArgumentError("The number of points used for the calculation `M` should not exceed the number of points provided."))
    # Transform the data into a tree.
    tree = searchstructure(KDTree, data, metric)
    # Calculate all nearest neighbours up to max_j.
    _, distances =
        bulksearch(
            tree,
            N == M ? data.data : data[view(randperm(N), 1:M)],
            NeighborNumber(max_j),
            Theiler(w),
        )
    # The epsilons define the left side of the equation
    ys = [digamma(j) - log(N) for j in 1:max_j]
    # Holds the mean value of the logarithms of the distances.
    rs = zeros(max_j)
    for dists in distances
        for j in 1:max_j
            rs[j] += log(dists[j])
        end
    end
    return rs ./ M, ys
end


text:
type TruneExternalBurgerSS <: TruneOptions
  n_off :: Int64
  x :: BurgerData
end

type TruneExternalBurgerSSDynamicSV <: TruneOptions
  n_off :: Int64
  x :: BurgerData
end

type TruneExternalBurgerSV <: TruneOptions
  n_off :: Int64
  x :: BurgerData
end

type TruneExternalBurgerSVSS <: TruneOptions
  n_off :: Int64
  x :: BurgerData
end

export TruneExternalBurgerSS, TruneExternalBurgerSV, TruneExternalBurgerSVSS, TruneExternalBurgerSSDynamicSV


text:
using DynamicGrids, Test, BenchmarkTools

using DynamicGrids: SimData, radius, rules, _readkeys, _writekeys,
    applyrule, neighborhood, neighborhoodkey, Extent

@testset "CellRule chain" begin

    rule1 = Cell{:a,:b}() do a
        2a
    end

    rule2 = Cell{Tuple{:b,:d},:c}() do (b, d)
        b + d
    end

    rule3 = Cell{Tuple{:a,:c,:d},Tuple{:d,:e}}() do (a, c, d)
        a + c + d, 3a
    end

    rule4 = Cell{Tuple{:a,:b,:c,:d},Tuple{:a,:b,:c,:d}}() do (a, b, c, d)
        2a, 2b, 2c, 2d
    end

    # These aren't actually used yet, they just build SimData
    agrid = [1 0 0
             0 0 2]

    bgrid = [0 0 0
             0 0 0]

    cgrid = [0 0 0
             0 0 0]

    dgrid = [0 0 0
             0 0 0]

    egrid = [0 0 0
             0 0 0]

    chain = Chain(rule1, rule2, rule3, rule4)
    @test _readkeys(chain) == (:a, :b, :d, :c)
    @test _writekeys(chain) == (:b, :c, :d, :e, :a)

    ruleset = Ruleset(chain)
    init = (a=agrid, b=bgrid, c=cgrid, d=dgrid, e=egrid)
    data = SimData(Extent(init=init, tspan=1:1), ruleset)

    @test radius(ruleset) == (b=0, c=0, d=0, e=0, a=0)

    @test applyrule(data, chain, (b=1, c=1, d=1, a=1), (1, 1)) ==
        (4, 6, 10, 3, 2)

    # @inferred applyrule(data, chain, (b=1, c=1, d=1, a=1), (1, 1))

    state = (b=1, c=1, d=1, a=1)
    ind = (1, 1)

    # This breaks with --inline=no
    # b = @benchmark applyrule($data, $chain, $state, $ind)
    # @test b.allocs == 0

    output = ArrayOutput(init; tspan=1:3)
    sim!(output, ruleset)

    @test output[2][:a] == [2 0 0
                            0 0 4]
    @test output[3][:a] == [4 0 0
                            0 0 8]

    @test output[2][:b] == [4 0 0
                            0 0 8]
    @test output[3][:b] == [8 0  0
                            0 0 16]

    @test output[2][:c] == [4 0 0
                            0 0 8]
    @test output[3][:c] == [20 0 0
                            0 0 40]

    @test output[3][:d] == [36 0 0
                            0 0 72]
    @test output[3][:d] == [36 0 0
                            0 0 72]

    @test output[2][:e] == [3 0 0
                            0 0 6]
    @test output[3][:e] == [6 0  0
                            0 0 12]

    @test isinferred(output, ruleset)
end

@testset "NeighborhoodRule, CellRule chain" begin

    buf = reshape(1:9, 3, 3)
    hood = Moore{1}(buf)
    hoodrule = Neighbors{:a,:a}(hood) do neighborhodhood, cell
        sum(neighborhodhood)
    end

    rule = Cell{Tuple{:a,:c},:b}() do (b, c)
        b + c
    end

    init = (
        a = [0 0 0 0 0
             0 0 0 0 0
             0 0 1 0 0
             0 0 0 0 0
             0 0 0 0 0],
        b = [0 0 0 0 0
             0 0 0 0 0
             0 0 0 0 0
             0 0 0 0 0
             0 0 0 0 0],
        c = [1 1 1 1 1
             1 1 1 1 1
             1 1 1 1 1
             1 1 1 1 1
             1 1 1 1 1]
    )

    chain = Chain(hoodrule, rule)
    @test radius(chain) === 1
    @test neighborhood(chain) == hood
    @test Tuple(neighbors(chain)) === (1, 2, 3, 4, 6, 7, 8, 9)
    @test neighborhoodkey(chain) === :a
    @test rules(Base.tail(chain)) === (rule,)
    @test chain[1] === first(chain) === hoodrule
    @test chain[end] === last(chain) === rule
    @test length(chain) === 2
    @test iterate(chain) === (hoodrule, 2)
    @test firstindex(chain) === 1
    @test lastindex(chain) === 2

    ruleset = Ruleset(chain; opt=NoOpt())
    noopt_output = ArrayOutput(init; tspan=1:3)
    @btime sim!($noopt_output, $ruleset)
    @test isinferred(noopt_output, ruleset)

    ruleset = Ruleset(Chain(hoodrule, rule); opt=SparseOpt())
    sparseopt_output = ArrayOutput(init; tspan=1:3)
    @btime sim!($sparseopt_output, $ruleset; init=$init)
    @test isinferred(sparseopt_output, ruleset)

    noopt_output[2][:a] == sparseopt_output[2][:a] ==
        [0 0 0 0 0
         0 1 1 1 0
         0 1 0 1 0
         0 1 1 1 0
         0 0 0 0 0]
    noopt_output[2][:b] == sparseopt_output[2][:b] ==
        [1 1 1 1 1
         1 2 2 2 1
         1 2 1 2 1
         1 2 2 2 1
         1 1 1 1 1]
    noopt_output[3][:a] == sparseopt_output[3][:a] ==
        [1 2 3 2 1
         2 2 4 2 2
         3 4 8 4 3
         2 2 4 2 2
         1 2 3 2 1]
    noopt_output[3][:b] == sparseopt_output[3][:b] ==
        [2 3 4 3 2
         3 3 5 3 3
         4 5 9 5 4
         3 3 5 3 3
         2 3 4 3 2]
end


text:
function show_which_quadrule(op,X,Y)

    test_charts, test_ad = assemblydata(X)
    trial_charts, trial_ad = assemblydata(Y)

    x = refspace(X)
    y = refspace(Y)

    @show @which quaddata(op, x, y, test_charts, trial_charts)
    qd = quaddata(op, x, y, test_charts, trial_charts)
    @show @which quadrule(op, x, y, 1, first(test_charts), 1, first(trial_charts), qd)

    nothing
end


text:
#Create a true low-rank model
Xtrue = randn(100,10)
Ytrue = randn(10, 60)
A = Xtrue*Ytrue + 0.01*randn(100,60)
obs = [(i,j) for i in 1:100 for j in 1:60 if !(j in [3,59])]

#Test that the results from LowRankModels are approximately equal to GraphGLRM
glrm_quad = GLRM(A, QuadLoss(), QuadReg(1.), QuadReg(1.), 5)
gg = GGLRM(A, QuadLoss(), QuadReg(1.), QuadReg(1.), 5)
fit!(gg); fit!(glrm_quad)
ggobj = whole_objective(gg, gg.X'*gg.Y)
glrmobj = whole_objective(gg, glrm_quad.X'*glrm_quad.Y)
@test_approx_eq_eps(ggobj, glrmobj, 0.1*length(A))

#Try for a different loss function and regularizers
glrm_hquad = GLRM(A, HuberLoss(), OneReg(1.), OneReg(1.), 5)
ggh = GGLRM(A, HuberLoss(), OneReg(1.), OneReg(1.), 5)
fit!(ggh); fit!(glrm_hquad)
gghobj = whole_objective(ggh, ggh.X'*ggh.Y)
glrmhobj = whole_objective(ggh, glrm_hquad.X'*glrm_hquad.Y)
@test_approx_eq_eps(gghobj, glrmhobj, 0.1*length(A))

#Make sure that it works with missing data
glrm_missing = GLRM(A, L1Loss(), NonNegConstraint(), NonNegConstraint(), 5, obs=obs)
gg_missing = GGLRM(A, L1Loss(), NonNegConstraint(), NonNegConstraint(), 5, obs=obs)
fit!(gg_missing); fit!(glrm_missing);
ggmobj = whole_objective(gg_missing, gg_missing.X'gg_missing.Y)
glrmmobj = whole_objective(gg_missing, glrm_missing.X'glrm_missing.Y)
@test_approx_eq_eps(ggmobj, glrmmobj, 0.1*length(A))


text:
function solve(FDDE::FDDEProblem, h, ::DelayPECE)
    @unpack f, ϕ, α, τ, tspan = FDDE
    t = collect(0:h:tspan)
    maxn = length(t)
    yp = zeros(maxn)
    y = copy(t)
    y[1] = ϕ(0)

    for n in 1:maxn-1
        yp[n+1] = 0
        for j = 1:n
            yp[n+1] = yp[n+1]+b(j-1, n-1, α, h)*f(t[j], y[j], v(ϕ, j, τ, h, y, yp)...)
        end
        yp[n+1] = yp[n+1]/gamma(α)+ϕ(0)

        y[n+1] = 0

        for j=1:n
            y[n+1] = y[n+1]+a(j-1, n-1, α, h)*f(t[j], y[j], v(ϕ, j, τ, h, y, yp)...)
        end

        y[n+1] = y[n+1]/gamma(α)+h^α*f(t[n+1], yp[n+1], v(ϕ, n+1, τ, h, y, yp)...)/gamma(α+2) + ϕ(0)
    end

    V = []
    for n = 1:maxn
        push!(V, v(ϕ, n, τ, h, y, yp))
    end

    delayed = zeros(length(τ), length(V))
    for i=1:length(V)
        delayed[:, i] = V[i]
    end

    return delayed, y
end

function a(j, n, α, h)
    if j == n+1
        result = 1
    elseif j == 0
        result = n^(α+1)-(n-α)*(n+1)^α
    elseif j == n
        result = 2*(2^(α+1)-1)
    else
        result = (n-j+2)^(α+1) + (n-j)^(α+1) - 2*(n-j+1)^(α+1)
    end
    return result*h^α / (α*(α + 1))
end

function b(j, n, α, h)
    return h^α/α*((n-j+1)^α - (n-j)^α)
end

function v(ϕ, n, τ, h, y, yp)
    if maximum(τ) > n*h
        return ϕ.((n-1)*h.-τ)
    else
        m = floor.(Int, τ./h)
        δ = m.-τ./h

        function judge(m)
            temp1 = findall(x->x>1, m)
            temp2 = findall(x->x==1, m)#FIXME: Another case for x == 1

            result = zeros(length(m))
            if length(temp1) == length(m)
                for i=1:length(m)
                    result[i] = δ[i]*y[n-m[i]+2]+(1-δ[i])*y[n-m[i]+1]
                end
                return result
            end
        end
        return judge(m)
    end
end


text:
# This file is a part of RRRMC.jl. License is MIT: http://github.com/carlobaldassi/RRRMC.jl/LICENCE.md

const graphs_dir = joinpath(dirname(@__FILE__), "graphs")
const valid_graph_name = r"^([^/]+)\.jl$"

macro include_graph(filename)
    occursin(valid_graph_name, filename) || (warn("Unrecogniezd file $filename, skipping"); return :())
    modname = Symbol(replace(filename, valid_graph_name => s"\1"))
    quote
        include(joinpath(graphs_dir, $(esc(filename))))
        using .$modname
    end
end

@include_graph "QT.jl"
@include_graph "RE.jl"
@include_graph "LE.jl"
@include_graph "TLE.jl"

for filename in filter(f->endswith(f, ".jl") && f ∉ ["QT.jl", "RE.jl", "LE.jl", "TLE.jl"], readdir(graphs_dir))
    @eval @include_graph $filename
end


text:
using BDF, Compat.Test, HDF5
#using JLD

origFilePath = joinpath(dirname(@__FILE__), "Newtest17-256.bdf")
bdfHeader = readBDFHeader(origFilePath)
dats, evtTab, trigs, statusChan = readBDF(origFilePath)

## testData=load("test_data.jld")

## @test isequal(testData["bdfHeader"], bdfHeader)
## @test isequal(testData["EEG"], dats)
## @test isequal(testData["evtTab"], evtTab)
## @test isequal(testData["trigs"], trigs)

testData = h5read(joinpath(dirname(@__FILE__), "Newtest17-256_data.h5"), "data")
@test isequal(testData["EEG"], dats)
@test isequal(testData["trigs"], trigs)
@test isequal(testData["idx"], evtTab["idx"])
@test isequal(testData["dur"], evtTab["dur"])
@test isequal(testData["code"], evtTab["code"])

# Test transposed return
dats, evtTab, trigs, statusChan = readBDF(origFilePath, transposeData = true)
@test isequal(testData["EEG"]', dats)
@test isequal(testData["trigs"], trigs)
@test isequal(testData["idx"], evtTab["idx"])
@test isequal(testData["dur"], evtTab["dur"])
@test isequal(testData["code"], evtTab["code"])


text:
function SampledSignals.unsafe_read!(source::SndFileSource, buf::Array, frameoffset, framecount)
    total = min(framecount, nframes(source) - source.pos + 1)
    nread = 0
    readbuf = source.readbuf
    while nread < total
        n = min(size(readbuf, 2), total - nread)
        nr = sf_readf(source.filePtr, readbuf, n)
        # the data comes in interleaved, so we need to transpose
        transpose!(view(buf, (1:nr) .+ frameoffset .+ nread, :),
                   view(readbuf, :, 1:nr))
        source.pos += nr
        nread += nr
        nr == n || break
    end

    nread
end

# returns the number of samples written
function SampledSignals.unsafe_write(sink::SndFileSink, buf::Array, frameoffset, framecount)
    nwritten = 0
    writebuf = sink.writebuf
    while nwritten < framecount
        n = min(size(writebuf, 2), framecount - nwritten)
        # the data needs to be interleaved, so we need to transpose
        transpose!(view(writebuf, :, 1:n),
                   view(buf, (1:n) .+ frameoffset .+ nwritten, :))
        nw = sf_writef(sink.filePtr, writebuf, n)
        sink.nframes += nw
        nwritten += nw
        nw == n || break
    end

    nwritten
end


text:
module RelayISI

using SpkCore
using Statistics, Random, StatsBase, Optim, ImageFiltering

using LoopVectorization

using ..RelayUtils, ..GLMMetrics, ..GLMFit.Partitions
import ..PredictorSet, ..Predictor, ..GLM, ..cross_validate, ..NullPrior,
       ..Binomial, ..Logistic, ..wasrelayed

export isi_cross_validate

# ============================================================================ #
function spike_status(ret::Vector{Float64}, lgn::Vector{Float64})

    status = wasrelayed(ret, lgn)
    # first spike has no isi so we can't make a prediction...
    return diff(ret), status[2:end]
end
# ============================================================================ #
function smooth_ef(ef::AbstractVector{<:Real}, sigma::Real, bin_size::Real)
    return imfilter(ef, (KernelFactors.IIRGaussian(sigma/bin_size),))
end
# ============================================================================ #
function get_eff(isi::Vector{Float64}, status::AbstractVector{<:Real}, kuse::AbstractVector{<:Integer},
        sigma::Real, isibin::Real, isimax::Real)

        isi_use = isi[kuse]
        status_use = status[kuse]
        krel = findall(>(0), status_use)

        edges = 0.002:isibin:isimax

        all = fit(Histogram, isi_use, edges)
        rel = fit(Histogram, isi_use[krel], edges)

        eff = Vector{Float64}(undef, length(all.weights))
        @turbo thread=8 for k in eachindex(all.weights)
            eff[k] = all.weights[k] > 0 ? rel.weights[k] / all.weights[k] : 0.0
        end

        if sigma > 0.0
            out = smooth_ef(eff, sigma, isibin)
        else
            out = eff
        end

        # ensure [0,1]
        @turbo thread=8 for k in eachindex(out)
            out[k] = out[k] < 0.0 ? 0.0 : out[k]
        end

    return edges, out
end
# ============================================================================ #
@inline function predict(edges::AbstractVector{<:Real}, ef::AbstractVector{T}, isi::Vector{Float64}) where T
    return predict!(fill(T(0), length(isi)), edges, ef, isi)
end
# ---------------------------------------------------------------------------- #
function predict!(p::Vector{T}, edges::AbstractVector{<:Real}, ef::AbstractVector{T}, isi::Vector{Float64}) where T<:Real

    mu = mean(ef)

    Threads.@threads for k in eachindex(p)
        @inbounds begin
            x = isi[k]
            if x >= edges[end]
                # for all isi's beyond isimax (edges[end]) predict the mean
                # efficacy mu
                p[k] = mu
            elseif x < edges[1]
                p[k] = ef[1]
            else
                j = findfirst(>(x), edges)
                # subtract 1 as we used > above to locate the upper edge of the
                # bin that this isi belongs in
                p[k] = ef[j-1]
            end
        end
    end
    return p
end
# ============================================================================ #
roundn(x::Real, n::Integer) = round(x / 10.0^n) * 10.0^n
# ============================================================================ #
function isi_cross_validate(::Type{T}, ret::AbstractVector{<:Real}, lgn::AbstractVector{<:Real},
    isimax::Vector{Float64}, isibin::Real=0.001, nfold::Integer=10) where T <: PerformanceMetric

    sigma = roundn.(vcat(0.0, 10 .^ range(log10(0.002), log10(0.03), length=7)), -3)

    out = T(nfold)
    sig = 0.0
    isimx = 0.0
    best = worst_value(T)

    isi, status = spike_status(ret, lgn)

    for row in eachrow([repeat(sigma, inner=length(isimax)) repeat(isimax, outer=length(sigma))])
        res = isi_model(T, isi, status, row[1], isibin, row[2], nfold, true)
        tmp = mean(res)[1]
        if better_than(T, tmp, best)
            copy!(out, res)
            sig = row[1]
            isimx = row[2]
            best = tmp
        end
    end

    return out, sig, isimx
end
# ============================================================================ #
# NOTE: we are NOT using the turbo functions from RelayUtils as they do not work
# with ForwardDiff.Dual types [which we need to get the objective gradient from
# ForwardDiff (via Optim) in scale_ef()]; however, Dual numbers work just fine
# with Threads (obviously...)
function logistic!(x::AbstractVector{<:Real})
    Threads.@threads for k in eachindex(x)
        @inbounds x[k] = 1.0 / (1.0 + exp(-x[k]))
    end
    return x
end
# ============================================================================ #
# NOTE: this is combined logistic + NEGATIVE likelihood calculation specifically
# for scale_ef() below
function binomial_logistic_nlli!(x::Vector{<:Real}, status::Vector{<:Real})
    Threads.@threads for k in eachindex(status)
        @inbounds begin
            tmp = 1.0 / (1.0 + exp(-x[k]))
            x[k] = status[k] > 0 ? log(tmp + eps()) : log(1.0 - (tmp - eps()))
        end
    end
    return -sum(x)
end
# ============================================================================ #
function scale_ef(edges::AbstractVector{<:Real}, ef::Vector{Float64}, isi::Vector{Float64}, status::AbstractVector{<:Real}, isibin::Real)

    cache = Dict{DataType, Any}(Float64 => zeros(length(isi)))
    N = length(isi)

    objective(p::Vector{T}) where T =  begin

        yp = get!(cache, T) do
            Vector{T}(undef, N)
        end::Vector{T}

        return binomial_logistic_nlli!(predict!(yp, edges, p[1] .+ ef .* p[2], isi), status)
    end

    x0 = [0.0, 1.0]

    # mn = mean(ef)
    # mx = maximum(ef)
    # x0 = [-mn, 1.0/(mx - mn)]

    res = optimize(objective, x0, LBFGS(); autodiff=:forward)

    return res.minimizer[1] .+ ef .* res.minimizer[2]
end
# ============================================================================ #
function isi_model(::Type{T}, isi::AbstractVector{<:Real}, status::Vector{Bool},
    sigma::Real, isibin::Real, isimax::Real, nfold::Integer, shfl::Bool) where T <: PerformanceMetric

    res = T(nfold)

    k = 1
    for p in ballanced_partition(IndexPartitioner, isi, status, nfold, shfl)
        idxtrain = training_set(p)
        idxtest = testing_set(p)

        edges, ef = get_eff(isi, status, idxtrain, sigma, isibin, isimax)
        ef = scale_ef(edges, ef, isi[idxtrain], status[idxtrain], isibin)

        pred = logistic!(predict(edges, ef, isi[idxtest]))

        eval_and_store!(res, status[idxtest], pred, k)

        k += 1
    end

    return res
end
# ============================================================================ #
end


text:
@testset "detectors" begin
  Random.seed!(42)
  x = vcat(rand(8,2), 5*rand(1,2), 30*rand(1,2))
  x1 = vcat(rand(20,3), 5*rand(1,3), 30*rand(1,3))
  @test rxdetect(x, 0.9) == [false, false, false, false, false, false, false, false, false, true]
  @test hosvdc4detect(x, 4., 2; b=2) == [false, false, false, false, false, false, false, false, true, true]
  @test hosvdc4detect(x1, 3.9, 1; b=1) == vcat(fill(false, 20), [true, true])
  @test rxdetect(x1, 0.9) == vcat(fill(false, 20), [true, true])
  ls = fill(true, 10)
  ls1 = [true, true, true, true, true, true, true, true, false, false]
  c = cumulants(x, 4)
  @test hosvdstep(x, ls, 4., 2, c[4])[1] == ls1
  @test hosvdstep(x, ls, 3., 1, c[4])[2] ≈ 1.147775879385989
  @test hosvdstep(x, ls, 3., 2, c[4])[2] ≈ 1.2715241637233354
  c = cumulants(x[ls1,:], 4)
  @test hosvdstep(x, ls1, 4., 2, c[4])[1] == ls1
  @test hosvdstep(x, ls1, 4., 2, c[4])[2] ≈ 1.6105157709082383
  m = momentarray(x,4,2)
  m1, t1 = updatemoments(m, size(x,1), x, ls1, ls)
  @test t1 == 8
  @test Array(m1[4]) ≈ Array(moment(x[1:8,:], 4))
end


text:
export @mpirun, @master, @mpiman

minibatch(x, b) = [x[i:min(end, i + b - 1)] for i in 1:b:max(1, length(x) - b + 1)]

sample(lo, hi) = lo .+ rand(size(lo)) .* (hi .- lo)

function ptp(x)
    xmin, xmax = extrema(x)
    xmax - xmin
end

runall(f) = f
runall(fs::AbstractVector) = (xs...) -> last([f(xs...) for f in fs])

function throttle(f, timeout; leading = true)
    lasttime = time()
    leading && (lasttime -= timeout)
    function throttled(args...; kwargs...)
        barrier()
        result = nothing
        if time() >= lasttime + timeout
            result = f(args...; kwargs...)
            lasttime = time()
        end
        return result
    end
end

function getppid(pid = getpid())
    try
        @static if Sys.iswindows()
            cmd = `wmic process where processid=$pid get parentprocessid`
            str = read(pipeline(cmd, stderr = devnull), String)
            parse(Int, match(r"\d+", str).match)
        else
            cmd = `ps -o ppid= -p $pid`
            str = read(pipeline(cmd, stderr = devnull), String)
            parse(Int, strip(str))
        end
    catch
        nothing
    end
end

function getcpids(pid = getpid())
    try
        cmd = `ps -o pid= --ppid $pid`
        str = read(pipeline(cmd, stderr = devnull), String)
        parse.(Int, split(str, '\n', keepempty = false))
    catch
        nothing
    end
end

function processname(pid)
    @static if Sys.iswindows()
        split(read(`wmic process where processid=$pid get executablepath`, String))[end]
    else
        strip(read(`ps -p $pid -o comm=`, String))
    end
end

function pstreeids(pid = getpid())
    pids = Int[]
    while !isnothing(pid)
        push!(pids, pid)
        pid = getppid(pid)
    end
    pop!(pids)
    return pids[end:-1:1]
end

pstree(pid = getpid()) = join(processname.(pstreeids(pid)), "--")

function inmpi()
    try
        isfile("/usr/bin/yhrun") ?
        occursin(r"mpi|orte|hydra|slurm|srun|salloc", pstree()) :
        occursin(r"mpi|orte|hydra", pstree())
    catch
        false
    end
end

deigen(x) = eigen(Symmetric(x, :U))

worldsize() = nworkers()

myrank() = myid() - 1

bcast(x, root = 0) = x

allequal(x) = length(unique(x)) == 1

barrier() = nothing

macro barrier(ex) :(barrier(); res = $(esc(ex)); barrier(); res) end

macro mpirun(ex)
    !inmpi() && return esc(ex)
    quote
        @eval using MPI
        !MPI.Initialized() && MPI.Init()
        MPI.Barrier(worldcomm())
        res = $(esc(ex))
        MPI.Barrier(worldcomm())
        res
    end
end

macro mpiman(ex)
    !inmpi() && return esc(ex)
    man = gensym()
    quote
        @eval using MPIClusterManagers
        $man = MPIClusterManagers.start_main_loop(MPIClusterManagers.MPI_TRANSPORT_ALL)
        res = $ex
        MPIClusterManagers.stop_main_loop($man)
    end |> esc
end

macro master(ex)
    quote
        @barrier if myrank() == 0
            res = $(esc(ex))
            bcast(res, 0)
        else
            bcast(nothing, 0)
        end
    end
end

function part(x::AbstractArray{T, N}, rank, wsize, dims) where {T, N}
    dims = clamp(dims > 0 ? dims : N + dims + 1, 1, N)
    dsize = size(x, dims)
    wsize = something(wsize, dsize)
    if dsize >= wsize
        q, r = divrem(dsize, wsize)
        splits = cumsum([i <= r ? q + 1 : q for i in 1:wsize])
        pushfirst!(splits, 0)
        is = (splits[rank + 1] + 1):splits[rank + 2]
        view(x, ntuple(x -> x == dims ? is : (:), N)...)
    else
        @debug @warn "rank=$rank: dsize=$dsize < wsize=$wsize"
        is = (rank + 1):min(rank + 1, dsize)
        view(x, ntuple(x -> x == dims ? is : (:), N)...)
    end
end

function partjob(x; dims = -1)
    if haskey(ENV, "SLURM_ARRAY_TASK_ID")
        rank = parse(Int, ENV["SLURM_ARRAY_TASK_ID"])
        wsize = parse(Int, ENV["SLURM_ARRAY_TASK_COUNT"])
        part(x, rank, wsize, dims)
    elseif haskey(ENV, "PBS_ARRAYID")
        rank = parse(Int, ENV["PBS_ARRAYID"])
        part(x, rank, nothing, dims)
    else
        return x
    end
end

part(x, comm = nothing; dims = -1) = x

function limit_julia_procs(n)
    njulia = parse(Int, read(pipeline(`pgrep julia`, `wc -l`), String)) - 1
    if njulia > n
        println("njulia > $n, exiting...")
        return true
    end
    return false
end

function limit_mem_per_cpu(mem)
    mem = @eval let MB = 1024^2, M = MB, G = GB = 1024^3
        $(Meta.parse(mem))
    end
    n = floor(Int, Sys.total_memory() / mem)
    limit_julia_procs(n)
end

function make_virtual_jobarray(n)
    !inmpi() && return nothing
    if !haskey(ENV, "SLURM_ARRAY_TASK_ID")
        ENV["SLURM_ARRAY_TASK_ID"] = 0
        ENV["SLURM_ARRAY_TASK_COUNT"] = 1
    end
    taskid = parse(Int, ENV["SLURM_ARRAY_TASK_ID"])
    taskcount = parse(Int, ENV["SLURM_ARRAY_TASK_COUNT"])
    rank, wsize = myrank(), worldsize()
    q, r = divrem(wsize, n)
    splits = cumsum([i <= r ? q + 1 : q for i in 1:n])
    splits = [0; splits[1:end-1]]
    color = searchsortedlast(splits, rank) - 1
    comm = MPI.Comm_split(MPI.COMM_WORLD, color, rank)
    setglobalcomm!(comm)
    ENV["SLURM_ARRAY_TASK_ID"] = taskid * n + color
    ENV["SLURM_ARRAY_TASK_COUNT"] = taskcount * n
    return nothing
end