if not modules then modules = { } end modules ['back-ini'] = {
    version   = 1.001,
    comment   = "companion to back-ini.mkiv",
    author    = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
    copyright = "PRAGMA ADE / ConTeXt Development Team",
    license   = "see context related readme files"
}

local next, type = next, type

backends                = backends or { }
local backends          = backends

local context           = context

local trace             = false  trackers.register("backend", function(v) trace = v end)
local report            = logs.reporter("backend")

local allocate          = utilities.storage.allocate
local setmetatableindex = table.setmetatableindex
----- setaction         = nodes.tasks.setaction

local implement         = interfaces.implement
local variables         = interfaces.variables

local texset            = tex.set

local nodeinjections    = { }
local codeinjections    = { }
local registrations     = { }
local tables            = allocate()

local function nothing()
    return nil
end

backends.nothing = nothing

local function donothing(t,k)
    t[k] = nothing
    return nothing
end

setmetatableindex(nodeinjections, donothing)
setmetatableindex(codeinjections, donothing)
setmetatableindex(registrations,  donothing)

local defaults = {
    nodeinjections = nodeinjections,
    codeinjections = codeinjections,
    registrations  = registrations,
    tables         = tables,
}

backends.defaults = defaults -- so, when not in the specific namespace we need to register here (to be checked)

backends.nodeinjections = { }  setmetatableindex(backends.nodeinjections, nodeinjections)
backends.codeinjections = { }  setmetatableindex(backends.codeinjections, codeinjections)
backends.registrations  = { }  setmetatableindex(backends.registrations,  registrations)
backends.tables         = { }  setmetatableindex(backends.tables,         tables)

backends.current = "unknown"

local registered = table.setmetatableindex(function(t,k)
    local v = {
        name           = k,
        nodeinjections = { },
        codeinjections = { },
        registrations  = { },
        tables         = { },
    }
    t[k] = v
    return v
end)

backends.registered = registered

-- The binding feature is mostly there to prevent side effects of overloading
-- not so much for performance because there are not that many calls.

function backends.initialize(what)
    if type(what) == "string" then
        local backend = registered[what]
        if backend then
            if trace then
                report("initializing backend %a",what)
            end
            for category, default in next, defaults do
                local target = backends[category]
                local plugin = backend [category]
                setmetatableindex(plugin, default)
                setmetatableindex(target, plugin)
            end
            --
            backends.current = what
            -- delayed / out-of-order locals: like lpdf.* (a few forward references)
            updaters.apply("backends." .. what .. ".latebindings")
            -- delayed / out-of-order locals: backends.[c|n]odeinjections.* (not all, only critical ones)
            updaters.apply("backends.injections.latebindings")
        elseif trace then
            report("no backend named %a",what)
        end
    end
end

statistics.register("used backend", function()
    local bc = backends.current
    return bc ~= "unknown" and bc or nil
end)

-- can best be here

interfaces.implement {
    name      = "setrealspaces",
    arguments = "string",
    actions   = function(v)
        directives.enable("backends.spaces", v == variables.yes)
     -- setaction("shipouts","nodes.handlers.accessibility",v == variables.yes)
    end
}

-- moved to here

local included = table.setmetatableindex( {
    context  = true,
    id       = true,
    metadata = true,
    date     = true,
    id       = true,
    pdf      = true,
}, function(t,k)
    return true
end)

backends.included = included

-- could also be codeinjections

function backends.getcallbackstate()
    return { count = status.late_callbacks or 0 }
end

--

function backends.setencryption(specification)
    codeinjections.setencryption(specification)
end
