local parse_token = token.create'__luakeyval_parse:n'
local parse_clist_token = token.create'__luakeyval_clist_parse:n'
local parse_clist_token_e = token.create'__luakeyval_clist_parse:e'
local put_next = token.put_next
local scan_token = token.scan_token
local scan_argument = token.scan_argument
local functions = lua.get_functions_table()

local current_clist_handler
local current_handlers, current_context

local func_single = luatexbase.new_luafunction'__luakeyval_pair:n'
token.set_lua('__luakeyval_pair:n', func_single)
functions[func_single] = function()
  local name = scan_argument()
  current_handlers[name](false, current_context, name)
end

local func_pair = luatexbase.new_luafunction'__luakeyval_pair:nn'
token.set_lua('__luakeyval_pair:nn', func_pair)
functions[func_pair] = function()
  local name = scan_argument()
  current_handlers[name](true, current_context, name)
end

local func_item = luatexbase.new_luafunction'__luakeyval_item:n'
token.set_lua('__luakeyval_item:n', func_item)
functions[func_item] = function()
  current_clist_handler(current_context)
end

return {
  clist = function(handler, context, expand)
    local saved_handler, saved_context = current_clist_handler, current_context
    current_clist_handler, current_context = handler, context
    put_next(expand and parse_clist_token_e or parse_clist_token)
    local scanned = scan_token()
    if scanned.csname ~= 'scan_stop:' then
      print(scanned, scanned.cmdname)
      error'???'
    end
    current_clist_handler, current_context = saved_handlers, saved_context
  end,
  keyval = function(handlers, context)
    local saved_handlers, saved_context = current_handlers, current_context
    current_handlers, current_context = handlers, context
    put_next(parse_token)
    local scanned = scan_token()
    if scanned.csname ~= 'scan_stop:' then
      print(scanned, scanned.cmdname)
      error'???'
    end
    current_handler, current_context = saved_handler, saved_context
  end,
}
