\RequirePackage{xparse,l3keys2e,leftindex,semtex}
\ProvidesExplPackage{semantex}{2022/06/22}{0.520}{}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%															%
%		SemanTeX -- semantic, keyval-based mathematics		%
%		https://ctan.org/pkg/semantex						%
%		(C) 2021 Sebastian Ørsted							%
%       sorsted@gmail.com									%
%															%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\tl_set:Nn\SemantexVersion{0.520}

\cs_set_eq:NN \semantex_keyval_parse:NNn \keyval_parse:NNn
\cs_set:Npn \semantex_singlekey_parse:Nn#1#2 { \clist_map_function:nN { #2 } #1 }


\keys_define:nn { semantex }
{
	keyval~parser .code:n = \cs_set_eq:NN \semantex_keyval_parse:NNn #1,
	keyval~parser .value_required:n = true,
	single~key~parser .code:n = \cs_set_eq:NN \semantex_singlekey_parse:Nn #1,
	single~key~parser .value_required:n = true,
	semtex~file .choice:,
	semtex~file / true .code:n = \semantex_turn_semtex_file_on:,
	semtex~file / false .code:n = \semantex_turn_semtex_file_off:,
	semtex~file / .code:n = \semantex_turn_semtex_file_on:,
	semtex~file / unknown .code:n = \msg_error:nnnn { semantex } { semantex_setup_key_value_not_found } { semtexfile } { #1 },
	unknown .code:n =  \msg_error:nnx { semantex } { semantex_setup_key_not_found } { \l_keys_key_str }
}

\DeclareDocumentCommand\SemantexSetup { m }
{
	\keys_set:nn { semantex } { #1 }
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%	THE .semtex FILE
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\bool_new:N \g__semantex_semtex_file_was_opened_bool

\iow_new:N \g__semantex_semtex_file_stream_temp_iow

\cs_new_protected:Npn \semantex_turn_semtex_file_on:
{
	\bool_if:NF \g__semantex_semtex_file_was_opened_bool
	{
		\iow_open:Nn \g__semantex_semtex_file_stream_temp_iow { \jobname.semtex }
		\iow_now:Nn \g__semantex_semtex_file_stream_temp_iow { \RegisterClass {\SemantexBaseObject } }
		\iow_now:Nn \g__semantex_semtex_file_stream_temp_iow { \RegisterObject {\SemantexDelimiterSize } }
	}
	
	\cs_set:Npn\semantex_write_to_semtex_file:n##1
	{
		\iow_now:Nn \g__semantex_semtex_file_stream_temp_iow { ##1 }
	}
	
	\cs_set:Npn\semantex_write_to_semtex_file_V:N ##1
	{
		% We use this command instead of a :V variant
		% in order to save time; when semtexfile=false,
		% there is no reason to V-expand the argument.
		\semantex_write_to_semtex_file:V ##1
	}
	
	\bool_set_true:N \g__semantex_semtex_file_was_opened_bool
}

\cs_new_protected:Npn \semantex_turn_semtex_file_off:
{
	\bool_if:NT \g__semantex_semtex_file_was_opened_bool
	{
		\iow_close:N \g__semantex_semtex_file_stream_temp_iow
	}
	
	\cs_set:Npn\semantex_write_to_semtex_file:n##1 {}

	\cs_set:Npn\semantex_write_to_semtex_file_V:N ##1 {}
		% We use this command instead of a :V variant
		% in order to save time; when semtexfile=false,
		% there is no reason to V-expand the argument.

	\bool_set_false:N \g__semantex_semtex_file_was_opened_bool
}

\semantex_turn_semtex_file_off:

\cs_generate_variant:Nn \semantex_write_to_semtex_file:n { V }

\cs_new_protected:Npn\semantex_write_original_source_to_semtex_file:n#1
{
	\semantex_write_to_semtex_file:n { \BeginSource }
	\semantex_write_to_semtex_file:n { #1 }
}

\cs_set_eq:NN\SemantexRecordSource\semantex_write_original_source_to_semtex_file:n

\cs_new_protected:Npn\semantex_add_to_existing_original_source_in_semtex_file:n#1
{
	\semantex_write_to_semtex_file:n { #1 }
}

\cs_set_eq:NN\SemantexAddToRecordedSource\semantex_add_to_existing_original_source_in_semtex_file:n

\cs_new_protected:Npn\semantex_write_output_to_semtex_file:n#1
{
	\semantex_write_to_semtex_file:n { \EndSource }
	\semantex_write_to_semtex_file:n { \BeginOutput }
	\semantex_write_to_semtex_file:n { #1 }
	\semantex_write_to_semtex_file:n { \EndOutput }
}

\cs_set_eq:NN\SemantexRecordOutput\semantex_write_output_to_semtex_file:n

\cs_new_protected:Npn\semantex_write_output_to_semtex_file_V:N#1
{
	\semantex_write_to_semtex_file:n { \EndSource }
	\semantex_write_to_semtex_file:n { \BeginOutput }
	\semantex_write_to_semtex_file_V:N #1
	\semantex_write_to_semtex_file:n { \EndOutput }
}

\cs_new_protected:Npn\semantex_write_class_declaration_to_semtex_file:n#1
{
	\semantex_write_to_semtex_file:n { \RegisterClass{#1} }
}

\cs_new_protected:Npn\semantex_write_object_declaration_to_semtex_file:n#1
{
	\semantex_write_to_semtex_file:n { \RegisterObject{#1} }
}

\cs_new_protected:Npn\SemantexID#1
{
	\semantex_write_to_semtex_file:n { \RegisterID{#1} }
}

\cs_set_eq:NN\SemantexRecordObject\semantex_write_object_declaration_to_semtex_file:n


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%    USER COMMANDS FOR CREATING NEW CLASSES
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\cs_new_protected:Npn\semantex_declare_simple_class:N#1 % new simple-type class
{
	% #1 = class name
	\DeclareDocumentCommand{#1}{m}
	{
		% the actual \#1 command
		\semantex_write_original_source_to_semtex_file:n { #1 { ##1 } }
		\semantex_render_object_associated_to_class:Nn #1 {
			\semantex_object_associated_to_class_set_symbol:Nn #1 { ##1 }
		}
	}
	\exp_args:Nc\DeclareDocumentCommand{__semantex_make_object_of_\semantex_class_to_register:N #1_with_options:nnw}{mm}
	{
		%\semantex_add_to_existing_original_source_in_semtex_file:n { } % add nothing to file
		\semantex_render_object_associated_to_class:Nn #1 {
			\semantex_object_associated_to_class_set_symbol:Nn #1 { ##2 }
			##1
		}
	}
	\exp_args:Nc\DeclareDocumentCommand{__semantex_declare_object_of_\semantex_class_to_register:N #1:Nw}{mgO{}}
	{
		% the command for creating a new object of class #1
		% ##1 = command name, with backslash
		% ##2 = symbol
		% ##3 = options
		\IfValueTF{##2}
		{
			\semantex_declare_object:NNn #1 ##1 {
				\semantex_object_set_symbol:Nn ##1 { ##2 }
				\semantex_object_set_keys:Nn ##1 { ##3 }
			}
		}
		{
			\semantex_declare_object:NNn #1 ##1 {
				\semantex_object_set_keys:Nn ##1 { ##3 }
			}
		}
		% create the object with name ##1
		\DeclareDocumentCommand{##1}{}
		{
		% the actual \##1 command
			\semantex_write_original_source_to_semtex_file:n { ##1 }
			\semantex_render_object:Nn ##1 { }
		}
	}
}

\NewDocumentCommand\DeclareSimpleClass{ m O{} }
{
	\semantex_declare_class:Nn { #1 } { \semantex_class_set_keys:Nn #1 { #2 } }
	\semantex_declare_simple_class:N #1
}

\NewDocumentCommand\NewSimpleClass { m O{} }
{
	\semantex_new_class_and_do:NNnn #1 \DeclareSimpleClass { \semantex_class_set_keys:Nn #1 { #2 } }
	{
		\semantex_declare_simple_class:N #1
	}
}

\cs_new_protected:Npn\semantex_declare_symbol_class:N #1 % new symbol-type class
{
	% #1 = class name
	\DeclareDocumentCommand{#1}{mo}
	{
		% the actual \#1 command
		\IfValueTF{##2}
		{
			\semantex_write_original_source_to_semtex_file:n { #1 { ##1 } { ##2 } }
			\semantex_render_object_associated_to_class:Nn #1 {
				\semantex_object_associated_to_class_do_output:N #1
				\semantex_object_associated_to_class_set_symbol:Nn #1 { ##1 }
				\semantex_object_associated_to_class_set_keys:Nn #1 { ##2 }
			}
		}
		{
			\semantex_write_original_source_to_semtex_file:n { #1 { ##1 } }
			\semantex_render_object_associated_to_class:Nn #1 {
				\semantex_object_associated_to_class_set_symbol:Nn #1 { ##1 }
			}
		}
	}
	\exp_args:Nc\DeclareDocumentCommand{__semantex_make_object_of_\semantex_class_to_register:N #1_with_options:nnw}{mmo}
	{
		\IfValueTF{##3}
		{
			\semantex_add_to_existing_original_source_in_semtex_file:n { [##3] }
			\semantex_render_object_associated_to_class:Nn #1 {
				\semantex_object_associated_to_class_do_output:N #1
				\semantex_object_associated_to_class_set_symbol:Nn #1 { ##2 }
				##1
				\semantex_object_associated_to_class_set_keys:Nn #1 { ##3 }
			}
		}
		{
			%\semantex_add_to_existing_original_source_in_semtex_file:n { } % write nothing to file
			\semantex_render_object_associated_to_class:Nn #1 {
				\semantex_object_associated_to_class_set_symbol:Nn #1 { ##2 }
				##1
			}
		}
	}
	\exp_args:Nc\DeclareDocumentCommand{__semantex_declare_object_of_\semantex_class_to_register:N #1:Nw}{mgO{}}
	{
		% the command for creating a new object of class #1
		% ##1 = command name, with backslash
		% ##2 = symbol
		% ##3 = options
		\IfValueTF{##2}
		{
			\semantex_declare_object:NNn #1 ##1 {
				\semantex_object_set_symbol:Nn ##1 { ##2 }
				\semantex_object_set_keys:Nn ##1 { ##3 }
			}
		}
		{
			\semantex_declare_object:NNn #1 ##1 {
				\semantex_object_set_keys:Nn ##1 { ##3 }
			}
		}
		% create the object with name ##1
		\DeclareDocumentCommand{##1}{o}
		{
		% the actual \##1 command
			\IfValueTF { ####1 }
			{
				\semantex_write_original_source_to_semtex_file:n { ##1 [ ####1 ] }
				\semantex_render_object:Nn ##1 {
					\semantex_object_do_output:N ##1
					\semantex_object_set_keys:Nn ##1 { ####1 }
				}
			}
			{
				\semantex_write_original_source_to_semtex_file:n { ##1 }
				\semantex_render_object:Nn ##1 { }
			}
		}
	}
}

\NewDocumentCommand\DeclareSymbolClass{ m O{} }
{
	\semantex_declare_class:Nn { #1 } { \semantex_class_set_keys:Nn #1 { #2 } }
	\semantex_declare_symbol_class:N #1
}

\NewDocumentCommand\NewSymbolClass { m O{} }
{
	\semantex_new_class_and_do:NNnn #1 \DeclareSymbolClass { \semantex_class_set_keys:Nn #1 { #2 } }
	{
		\semantex_declare_symbol_class:N #1
	}
}

\cs_new_protected:Npn\semantex_declare_variable_class:N#1 % new variable-type class
{
	% #1 = class name
	\DeclareDocumentCommand{#1}{mog}
	{
		% the actual \#1 command
			\IfValueTF { ##2 }
			{
				\IfValueTF { ##3 }
				{
					\semantex_write_original_source_to_semtex_file:n { #1 { ##1 } [ ##2 ] { ##3 } }
					\semantex_render_object_associated_to_class:Nn #1 {
						\semantex_object_associated_to_class_do_output:N #1
						\semantex_object_associated_to_class_set_symbol:Nn #1 { ##1 }
						\semantex_object_associated_to_class_set_keys:Nn #1 { ##2 }
						\semantex_object_associated_to_class_set_arg:Nn #1 { ##3 }
					}
				}
				{
					\semantex_write_original_source_to_semtex_file:n { #1 { ##1 } [ ##2 ] }
					\semantex_render_object_associated_to_class:Nn #1 { 
						\semantex_object_associated_to_class_do_output:N #1
						\semantex_object_associated_to_class_set_symbol:Nn #1 { ##1 }
						\semantex_object_associated_to_class_set_keys:Nn #1 { ##2 }
					}
				}
			}
			{
				\IfValueTF { ##3 }
				{
					\semantex_write_original_source_to_semtex_file:n { #1 { ##1 } { ##3 } }
					\semantex_render_object_associated_to_class:Nn #1 {
						\semantex_object_associated_to_class_do_output:N #1
						\semantex_object_associated_to_class_set_symbol:Nn #1 { ##1 }
						\semantex_object_associated_to_class_set_arg:Nn #1 { ##3 }
					}
				}
				{
					\semantex_write_original_source_to_semtex_file:n { #1 { ##1 } }
					\semantex_render_object_associated_to_class:Nn #1 {
						\semantex_object_associated_to_class_set_symbol:Nn #1 { ##1 }
					}
				}
			}
	}
	\exp_args:Nc\DeclareDocumentCommand{__semantex_make_object_of_\semantex_class_to_register:N #1_with_options:nnw}{mmog}
	{
		\IfValueTF { ##3 }
		{
			\IfValueTF { ##4 }{
				\semantex_add_to_existing_original_source_in_semtex_file:n { [ ##3 ] { ##4 } }
				\semantex_render_object_associated_to_class:Nn #1 {
					\semantex_object_associated_to_class_do_output:N #1
					\semantex_object_associated_to_class_set_symbol:Nn #1 { ##2 }
					##1
					\semantex_object_associated_to_class_set_keys:Nn #1 { ##3 }
					\semantex_object_associated_to_class_set_arg:Nn #1 { ##4 }
				}
			}
			{
				\semantex_add_to_existing_original_source_in_semtex_file:n { [ ##3 ] }
				\semantex_render_object_associated_to_class:Nn #1 {
					\semantex_object_associated_to_class_do_output:N #1
					\semantex_object_associated_to_class_set_symbol:Nn #1 { ##2 }
					##1
					\semantex_object_associated_to_class_set_keys:Nn #1 { ##3 }
				}
			}
		}
		{
			\IfValueTF { ##4 }
			{
				\semantex_add_to_existing_original_source_in_semtex_file:n { { ##4 } }
				\semantex_render_object_associated_to_class:Nn #1 {
					\semantex_object_associated_to_class_do_output:N #1
					\semantex_object_associated_to_class_set_symbol:Nn #1 { ##2 }
					##1
					\semantex_object_associated_to_class_set_arg:Nn #1 { ##4 }
				}
			}
			{
				% \semantex_add_to_existing_original_source_in_semtex_file:n { } % write nothing to file
				\semantex_render_object_associated_to_class:Nn #1 {
					\semantex_object_associated_to_class_set_symbol:Nn #1 { ##2 }
					##1
				}
			}
		}
	}
	\exp_args:Nc\DeclareDocumentCommand{__semantex_declare_object_of_\semantex_class_to_register:N #1:Nw}{mgO{}}
	{
		% the command for creating a new object of class #1
		% ##1 = command name, with backslash
		% ##2 = symbol
		% ##3 = options
		\IfValueTF{##2}
		{
			\semantex_declare_object:NNn #1 ##1 {
				\semantex_object_set_symbol:Nn ##1 { ##2 }
				\semantex_object_set_keys:Nn ##1 { ##3 }
			}
		}
		{
			\semantex_declare_object:NNn #1 ##1 {
				\semantex_object_set_keys:Nn ##1 { ##3 }
			}
		}
		% creates the object with name ##1
		\DeclareDocumentCommand{##1}{og}{
		% the actual \##1 command
			\IfValueTF{####1}{
				\IfValueTF{####2}
				{
					\semantex_write_original_source_to_semtex_file:n
					{
						##1 [ ####1 ] { ####2 }
					}
					\semantex_render_object:Nn ##1 {
						\semantex_object_do_output:N ##1
						\semantex_object_set_keys:Nn ##1 { ####1 }
						\semantex_object_set_arg:Nn ##1 { ####2 }
					}
				}
				{
					\semantex_write_original_source_to_semtex_file:n
					{
						##1 [ ####1 ]
					}
					\semantex_render_object:Nn ##1 {
						\semantex_object_do_output:N ##1
						\semantex_object_set_keys:Nn ##1 { ####1 }
					}
				}
			}
			{
				\IfValueTF{####2}
				{
					\semantex_write_original_source_to_semtex_file:n
					{
						##1 {####2}
					}
					\semantex_render_object:Nn ##1 {
						\semantex_object_do_output:N ##1
						\semantex_object_set_arg:Nn ##1 { ####2 }
					}
				}
				{
					\semantex_write_original_source_to_semtex_file:n
					{
						##1
					}
					\semantex_render_object:Nn ##1 {}
				}
			}
		}
	}
}

\NewDocumentCommand\DeclareVariableClass{ m O{} }
{
	\semantex_declare_class:Nn { #1 } { \semantex_class_set_keys:Nn #1 { #2 } }
	\semantex_declare_variable_class:N #1
}

\NewDocumentCommand\NewVariableClass { m O{} }
{
	\semantex_new_class_and_do:NNnn #1 \DeclareVariableClass { \semantex_class_set_keys:Nn #1 { #2 } }
	{
		\semantex_declare_variable_class:N #1
	}
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%    COMMANDS FOR CREATING AND HANDLING CLASSES AND OJBECTS
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Internally, objects and classes are both special cases of what we call "registers".
% A register is a collection of data and key definitions, and different registers can
% inherit from each other. Each register has a name which is a token list, with no
% backslash. The class \<MyClass> corresponds to the register "class_<MyClass>",
% and the object \<MyObject> corresponds to the register "object_<MyObject>".
% Firstly, we need a couple of commands to convert class and object names into
% register names.

\cs_new:Npn\semantex_class_to_register:N#1
{
	% #1 = name of class
	class_\token_to_str:N #1
}

\cs_new:Npn\semantex_class_to_associated_object_register:N#1
{
	% #1 = name of class
	object_associated_to_class_\token_to_str:N #1
}

\cs_new:Npn\semantex_object_to_register:N#1
{
	% #1 = name of object
	object_\token_to_str:N #1
}

\tl_new:N \g_semantex_class_SemantexBaseObject_register_tl

\tl_set:Nx \g_semantex_class_SemantexBaseObject_register_tl { \semantex_class_to_register:N \SemantexBaseObject }

\DeclareDocumentCommand\DeclareObject { m m }
{
	% #1 = name of object
	\semantex_class_if_exist:NTF #1
	{
		\use:c { __semantex_declare_object_of_\semantex_class_to_register:N #1:Nw } #2
	}
	{
		\msg_error:nnn { semantex } { created_object_of_unknown_class } { #1 }
	}
}

\DeclareDocumentCommand\NewObject { m m }
{
	\cs_if_exist:NTF #2
	{
		\msg_error:nnn { semantex } { created_object_with_already_defined_name } { #2 }
	}
	{
		\DeclareObject #1 #2
	}
}

\DeclareDocumentCommand\UseClassInCommand { mo }
{
	\semantex_class_if_exist:NTF #1
	{
		\IfValueTF { #2 }
		{
			\use:c { __semantex_make_object_of_\semantex_class_to_register:N #1_with_options:nnw }
			{
				\semantex_keys_set:nn { \semantex_class_to_associated_object_register:N #1 } { #2 }
			}
		}
		{
			\use:c { __semantex_make_object_of_\semantex_class_to_register:N #1_with_options:nnw } {}
		}
	}
	{
		\msg_error:nnn { semantex } { used_unknown_class } { #1 }
	}
}

\cs_new_protected:Npn \semantex_new_register:nn#1#2
{
	% create new register
	% #1 = name of register
	% #2 = standard keyval setup

	\semantex_data_tl_provide:nn { #1 } { parent }

	\semantex_data_tl_set:nno { #1 } { parent } { \g_semantex_class_SemantexBaseObject_register_tl }
	% The parent class by default is \SemantexBaseObject

	\cs_set:cpn { __semantex_data_cs_#1_valuekey:nn } ##1##2 % command controlling valuekeys
		{ \semantex_valuekey:nnn { #1 } { ##1 } { ##2 } }

	\cs_set:cpn { __semantex_data_cs_#1_singlekey:n } ##1 % command controlling singlekeys
		{ \semantex_singlekey:nn { #1 } { ##1 } }

	\cs_generate_variant:cn { __semantex_data_cs_#1_valuekey:nn } { nx }
	
	\cs_set:cpn { __semantex_data_cs_#1_singlekey_x:n } ##1 % command controlling executed singlekeys
		{ \semantex_singlekey_x:nn { #1 } { ##1 } }

	% Now a similar collection of keyval commands for the *argument*
	
	\cs_set:cpn { __semantex_data_cs_#1_arg_valuekey:nn } ##1##2
		{ \semantex_arg_valuekey:nnn { #1 } { ##1 } { ##2 } }
	
	\cs_set:cpn { __semantex_data_cs_#1_arg_singlekey:n } ##1
		{ \semantex_arg_singlekey:nn { #1 } { ##1 } }
	
	\cs_generate_variant:cn { __semantex_data_cs_#1_arg_valuekey:nn } { nx }
	
	\cs_set:cpn { __semantex_data_cs_#1_arg_singlekey_x:n } ##1
		{ \semantex_arg_singlekey_x:nn { #1 } { ##1 } }
	
	% This is used to set up the register when creating it
	#2
}

\cs_generate_variant:Nn \semantex_new_register:nn { xn }

\cs_new_protected:Npn \semantex_declare_class:Nn#1#2
{
	% create a new class
	% #1 = name of class
	% #2 = standard keyval setup
	\semantex_class_if_exist:NTF #1
	{
		\msg_error:nnn { semantex } { class_already_defined } { #1 }
	}
	{
		\semantex_add_to_list_of_classes:N #1
		\semantex_new_register:xn { \semantex_class_to_register:N #1 } { #2 }
		\semantex_new_register:xn { \semantex_class_to_associated_object_register:N #1 } {
			\semantex_object_associated_to_class_set_class:Nn #1 { #1 }
		}
	}
}

\cs_new_protected:Npn \semantex_new_class_and_do:NNnn#1#2#3#4
{
	% create a new class
	% #1 = name of class
	% #2 = name of \Declare...Class variant of command, for error messages
	% #3 = standard keyval setup
	% #4 = code to execute if successful
	\cs_if_exist:NTF #1
	{
		\msg_error:nnnn { semantex } { created_class_with_already_defined_name } { #1 } { #2 }
	}
	{
		\semantex_declare_class:Nn #1 { #3 }
		#4
	}
}

\cs_set_protected:Npn \semantex_declare_object:NNn#1#2#3
{
	% create a new object
	% #1 = name of class
	% #2 = name of object
	% #3 = standard keyval setup
	\semantex_object_if_exist:NTF #2
	{
		\msg_error:nnn { semantex } { object_already_defined } { #2 }
	}
	{
		\semantex_add_to_list_of_objects:N #2
		\semantex_new_register:xn { \semantex_object_to_register:N #2 }
		{
			\semantex_object_set_class:Nn #2 { #1 }
			#3
		}
	}
}

% The following commands are used in the code for creating class types:
% Writing the actual content of the commands is not that much more
% complicated, but I've decided to use them anyway to make it more
% user-friendly to create your own class type.

\cs_new_protected:Npn\semantex_class_set_keys:Nn#1#2
{
	\semantex_keys_set:nn { \semantex_class_to_register:N #1 } { #2 }
}

\cs_new_protected:Npn\semantex_object_associated_to_class_set_symbol:Nn#1#2
{
	\semantex_valuekey:nnn { \semantex_class_to_associated_object_register:N #1 } { symbol } { #2 }
}

\cs_new_protected:Npn\semantex_object_set_symbol:Nn#1#2
{
	\semantex_valuekey:nnn { \semantex_object_to_register:N #1 } { symbol } { #2 }
}

\cs_new_protected:Npn\semantex_object_associated_to_class_do_output:N#1
{
	\semantex_data_bool_set_true:nn { \semantex_class_to_associated_object_register:N #1 } { output }
}

\cs_new_protected:Npn\semantex_object_do_output:N#1
{
	\semantex_data_bool_set_true:nn { \semantex_object_to_register:N #1 } { output }
}

\cs_new_protected:Npn\semantex_object_associated_to_class_set_keys:Nn#1#2
{
	\semantex_keys_set:nn { \semantex_class_to_associated_object_register:N #1 } { #2 }
}

\cs_new_protected:Npn\semantex_object_set_keys:Nn#1#2
{
	\semantex_keys_set:nn { \semantex_object_to_register:N #1 } { #2 }
}

\cs_new_protected:Npn\semantex_object_associated_to_class_set_arg:Nn#1#2
{
	\semantex_valuekey:nnn { \semantex_class_to_associated_object_register:N #1 } { arg } { #2 }
}

\cs_new_protected:Npn\semantex_object_set_arg:Nn#1#2
{
	\semantex_valuekey:nnn { \semantex_object_to_register:N #1 } { arg } { #2 }
}

\cs_new_protected:Npn\semantex_object_associated_to_class_set_class:Nn#1#2
{
	\semantex_data_class_set:nn { \semantex_class_to_associated_object_register:N #1 } { #2 }
}

\cs_new_protected:Npn\semantex_object_set_class:Nn#1#2
{
	\semantex_data_class_set:nn { \semantex_object_to_register:N #1 } { #2 }
}

\seq_new:N \g__semantex_all_classes_seq % a list of all objects created

\cs_new_protected:Npn\semantex_add_to_list_of_classes:N#1
{
	\seq_put_right:Nx\g__semantex_all_classes_seq { \semantex_class_to_register:N #1 }
	\semantex_write_class_declaration_to_semtex_file:n { #1 }
}

\cs_new_protected:Npn\semantex_class_if_exist:NTF#1#2#3
{
	\seq_if_in:NxTF\g__semantex_all_classes_seq { \semantex_class_to_register:N #1 } { #2 } { #3 }
}

\seq_new:N \g__semantex_all_objects_seq % a list of all objects created

\cs_new_protected:Npn\semantex_add_to_list_of_objects:N#1
{
	\seq_put_right:Nx\g__semantex_all_objects_seq { \semantex_object_to_register:N #1 }
	\semantex_write_object_declaration_to_semtex_file:n { #1 }
}

\cs_new_protected:Npn\semantex_object_if_exist:NTF#1#2#3
{
	\seq_if_in:NxTF\g__semantex_all_objects_seq { \semantex_object_to_register:N #1 } { #2 } { #3 }
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%    COMMANDS FOR RENDERING REGISTERS
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\cs_generate_variant:Nn\tl_if_blank:nTF { xTF }

\cs_new_protected:Npn \semantex_render_register:nn#1#2
{
	% the main command for rendering a register
	% #1 = name of register
	% #2 = options
	\group_begin:
		\cs_set:Nn\semantex_this: { #1 }
		#2 % This is where keys can be set up
		\semantex_singlekey:nn { #1 } { parse } % Run the "parse" routine, i.e. run the collection of code that the user has added via the key "parse options"
		\semantex_data_bool_get:nnTF { #1 } { output } % Checks if the register is supposed to output
		{
			\semantex_inner_pre_return:n { #1 }
			\tl_set:Nx \l__semantex_render_output_class_temp_tl { \semantex_data_tl_get:nn { #1 } { output } } % The output class
			\tl_set:Nx \l__semantex_render_object_associated_to_output_class_tempt_tl {
				object_associated_to_\l__semantex_render_output_class_temp_tl
			}
			\exp_args:NNx\cs_set:Nn\l__semantex_render_output_options_temp_cs:n
				{ \semantex_data_tl_get_exp_not:nn { #1 } { output~options } }
				% \cs_set:Nx did not work here, as it changes ##1 to #1, which we don't want.
			\tl_set:Nn\l__semantex_render_output_options_temp_tl
			{
				\l__semantex_render_output_options_temp_cs:n
			}
			\tl_put_right:Nx \l__semantex_render_output_options_temp_tl
			{
				{ \l__semantex_render_output_class_temp_tl }
			}
			\exp_args:NNo\tl_set:No \l__semantex_render_output_options_temp_tl
			{
				\l__semantex_render_output_options_temp_tl
			} % This was necessary, trust me.
			\semantex_data_int_if_positive:nnTF { #1 } { number~of~arguments } % Checks if more than one argument has been received, i.e. whether we want to render any argument
			{
				\semantex_data_bool_get:nnTF { #1 } { left~argument } % Checks if left or right argument
				{
					\semantex_left_indices_pre_return:n { #1 }
					\semantex_left_arg_pre_return:n { #1 }
					\tl_set:Nx\l__semantex_render_symbol_temp_tl { \semantex_data_tl_get_exp_not:nn { #1 } { symbol } } % Stores the symbol in a temporary command
					\tl_set:Nx \l__semantex_render_temp_tl
					{
						\exp_not:c {
							__semantex_make_object_of_\l__semantex_render_output_class_temp_tl _with_options:nnw
						}
						% This is for outputting -- the command
						% \__semantex_make_object_of_class_???_with_options:nnw
						% makes a one-time object of class ??? and allows us to
						% immediately pass options to it
						{
							\exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_object_associated_to_output_class_tempt_tl }
								{ upper~put~left } { \semantex_data_tl_get_exp_not:nn { #1 } { upper } }
							\exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_object_associated_to_output_class_tempt_tl }
								{ lower~put~left } { \semantex_data_tl_get_exp_not:nn { #1 } { lower } }
							\exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_object_associated_to_output_class_tempt_tl }
								{ pre~upper~put~left } { \semantex_data_tl_get_exp_not:nn { #1 } { pre~upper } }
							\exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_object_associated_to_output_class_tempt_tl }
								{ post~upper~put~right } { \semantex_data_tl_get_exp_not:nn { #1 } { post~upper } }
							\exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_object_associated_to_output_class_tempt_tl }
								{ pre~lower~put~left } { \semantex_data_tl_get_exp_not:nn { #1 } { pre~lower } }
							\exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_object_associated_to_output_class_tempt_tl }
								{ post~lower~put~right } { \semantex_data_tl_get_exp_not:nn { #1 } { post~lower } }
							\exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_object_associated_to_output_class_tempt_tl }
								{ slanting~phantom } { } % reset slanting phantom
							\exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_object_associated_to_output_class_tempt_tl }
								{ math~class } { \semantex_data_tl_get_exp_not:nn { #1 } { math~class } }
							\exp_not:V \l__semantex_render_output_options_temp_tl
							% These are the options we pass to the output class so that it
							% can eventually render it
						}
						{ \exp_not:V \l__semantex_render_symbol_temp_tl }
					}
				}
				{
					\semantex_right_indices_pre_return:n { #1 }
					\semantex_right_arg_pre_return:n { #1 }
					\tl_set:Nx\l__semantex_render_symbol_temp_tl { \semantex_data_tl_get_exp_not:nn { #1 } { symbol } } % Stores the symbol in a temporary command
					\tl_set:Nx \l__semantex_render_temp_tl
					{
						\exp_not:c {
							__semantex_make_object_of_\l__semantex_render_output_class_temp_tl _with_options:nnw
						}
						% This is for outputting -- the command
						% \__semantex_make_object_of_class_???_with_options:nnw
						% makes a one-time object of class ??? and allows us to
						% immediately pass options to it
						{
							\exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_object_associated_to_output_class_tempt_tl }
								{ upper~left~put~right } { \semantex_data_tl_get_exp_not:nn { #1 } { upper~left } }
							\exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_object_associated_to_output_class_tempt_tl }
								{ lower~left~put~right } { \semantex_data_tl_get_exp_not:nn { #1 } { lower~left } }
							\exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_object_associated_to_output_class_tempt_tl }
								{ pre~upper~left~put~left } { \semantex_data_tl_get_exp_not:nn { #1 } { pre~upper~left } }
							\exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_object_associated_to_output_class_tempt_tl }
								{ post~upper~left~put~right } { \semantex_data_tl_get_exp_not:nn { #1 } { post~upper~left } }
							\exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_object_associated_to_output_class_tempt_tl }
								{ pre~lower~left~put~left } { \semantex_data_tl_get_exp_not:nn { #1 } { pre~lower~left } }
							\exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_object_associated_to_output_class_tempt_tl }
								{ post~lower~left~put~right } { \semantex_data_tl_get_exp_not:nn { #1 } { post~lower~left } }
							\exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_object_associated_to_output_class_tempt_tl }
								{ height~phantom } { \semantex_data_tl_get_exp_not:nn { #1 } { height~phantom } }
							\exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_object_associated_to_output_class_tempt_tl }
								{ slanting~phantom } { \semantex_data_tl_get_exp_not:nn { #1 } { slanting~phantom } }
							\exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_object_associated_to_output_class_tempt_tl }
								{ math~class } { \semantex_data_tl_get_exp_not:nn { #1 } { math~class } }
							\exp_not:V \l__semantex_render_output_options_temp_tl
							% These are the options we pass to the output class so that it
							% can eventually render it
						}
						{ \exp_not:V \l__semantex_render_symbol_temp_tl }
					}
				}
			}
			{
				\tl_set:Nx\l__semantex_render_symbol_temp_tl { \semantex_data_tl_get_exp_not:nn { #1 } { symbol } } % Stores the symbol in a temporary command
				\tl_set:Nx \l__semantex_render_temp_tl
				{
					\exp_not:c {
						__semantex_make_object_of_\l__semantex_render_output_class_temp_tl _with_options:nnw
					}
					% This is for outputting -- the command
					% \__semantex_make_object_of_class_???_with_options:nnw
					% makes a one-time object of class ??? and allows us to
					% immediately pass options to it
					{
						\exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_object_associated_to_output_class_tempt_tl }
							{ upper~put~left } { \semantex_data_tl_get_exp_not:nn { #1 } { upper } }
						\exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_object_associated_to_output_class_tempt_tl }
							{ lower~put~left } { \semantex_data_tl_get_exp_not:nn { #1 } { lower } }
						\exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_object_associated_to_output_class_tempt_tl }
							{ upper~left~put~right } { \semantex_data_tl_get_exp_not:nn { #1 } { upper~left } }
						\exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_object_associated_to_output_class_tempt_tl }
							{ lower~left~put~right } { \semantex_data_tl_get_exp_not:nn { #1 } { lower~left } }
						\exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_object_associated_to_output_class_tempt_tl }
							{ pre~upper~put~left } { \semantex_data_tl_get_exp_not:nn { #1 } { pre~upper } }
						\exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_object_associated_to_output_class_tempt_tl }
							{ post~upper~put~right } { \semantex_data_tl_get_exp_not:nn { #1 } { post~upper } }
						\exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_object_associated_to_output_class_tempt_tl }
							{ pre~lower~put~left } { \semantex_data_tl_get_exp_not:nn { #1 } { pre~lower } }
						\exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_object_associated_to_output_class_tempt_tl }
							{ post~lower~put~right } { \semantex_data_tl_get_exp_not:nn { #1 } { post~lower } }
						\exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_object_associated_to_output_class_tempt_tl }
							{ pre~upper~left~put~left } { \semantex_data_tl_get_exp_not:nn { #1 } { pre~upper~left } }
						\exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_object_associated_to_output_class_tempt_tl }
							{ post~upper~left~put~right } { \semantex_data_tl_get_exp_not:nn { #1 } { post~upper~left } }
						\exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_object_associated_to_output_class_tempt_tl }
							{ pre~lower~left~put~left } { \semantex_data_tl_get_exp_not:nn { #1 } { pre~lower~left } }
						\exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_object_associated_to_output_class_tempt_tl }
							{ post~lower~left~put~right } { \semantex_data_tl_get_exp_not:nn { #1 } { post~lower~left } }
						\exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_object_associated_to_output_class_tempt_tl }
							{ height~phantom } { \semantex_data_tl_get_exp_not:nn { #1 } { height~phantom } }
						\exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_object_associated_to_output_class_tempt_tl }
							{ slanting~phantom } { \semantex_data_tl_get_exp_not:nn { #1 } { slanting~phantom } }
						\exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_object_associated_to_output_class_tempt_tl }
							{ math~class } { \semantex_data_tl_get_exp_not:nn { #1 } { math~class } }
						\exp_not:V \l__semantex_render_output_options_temp_tl
						% These are the options we pass to the output class so that it
						% can eventually render it
					}
					{ \exp_not:V \l__semantex_render_symbol_temp_tl }
				}
			}
		}
		{
			\semantex_pre_return:n { #1 } % Performs the pre_return routine, i.e. adds all remaining indices and arguments to the symbol
			\tl_if_blank:xTF { \semantex_data_tl_get_exp_not:nn { #1 } { math~class } }
			% Checks whether the math~class register has been declared -- this is
			% where you store \mathord, \mathbin, \mathrel, etc., if you want
			% the object to be eventually wrapped in this.
			{
				\tl_set:Nx\l__semantex_render_temp_tl
				{
					\semantex_data_tl_get_exp_not:nn { #1 } { symbol }
				}
			}
			{
				\tl_set:Nx\l__semantex_render_temp_tl
				{
					\semantex_data_tl_get_exp_not:nn { #1 } { math~class }
						{ \semantex_data_tl_get_exp_not:nn { #1 } { symbol } }
				}
			}
			\group_begin:
				\semantex_write_output_to_semtex_file_V:N \l__semantex_render_temp_tl
				% Adds the output to the .semtex file, if this has been turned on,
				% which it is not by default.
			\group_end:
		}
	\exp_last_unbraced:NV
	\group_end:
	\l__semantex_render_temp_tl
	% This neat trick allows outputting to different classes to work as expected
}

\cs_generate_variant:Nn \semantex_render_register:nn { xn }

\cs_new_protected:Npn\semantex_render_object_associated_to_class:Nn#1#2 % a front-end command
{
	\semantex_render_register:xn { \semantex_class_to_associated_object_register:N #1 } { #2 }
}

\cs_new_protected:Npn\semantex_render_object:Nn#1#2
{
	\semantex_render_register:xn { \semantex_object_to_register:N #1 } { #2 }
	% Actually, it seems to all still work out fine with n-type
	% instead of x-type, but better be sure
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%    COMMANDS FOR HANDLING PARENTHESES
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\DeclareDocumentCommand\SemantexDelimiterSize { }
{
	\semantex_write_original_source_to_semtex_file:n { \SemantexDelimiterSize }
	\semantex_write_output_to_semtex_file_V:N \l_semantex_delimiter_size_temp_tl
	\l_semantex_delimiter_size_temp_tl
}

\DeclareDocumentCommand\RecordSemantexDelimiterSize { }
{
	\semantex_write_output_to_semtex_file_V:N \l_semantex_delimiter_size_temp_tl
}

\DeclareDocumentCommand\SemantexDelimiterSizeNoRecord { }
{
	\l_semantex_delimiter_size_temp_tl
}

\DeclareDocumentCommand\SemantexMathOpen { mm }
{
	\group_begin:
	\tl_set:Nn\l_semantex_delimiter_size_temp_tl { #1 }
	\str_if_eq:nnF { #2 } { . } { \mathopen #1 #2 }
}

\DeclareDocumentCommand\SemantexMathClose { mm }
{
	\str_if_eq:nnF { #2 } { . } { \mathclose #1 #2 }
	\group_end:
}

\DeclareDocumentCommand\SemantexMathOpenAuto { m }
{
	\group_begin:
	\tl_set:Nn\l_semantex_delimiter_size_temp_tl { \middle }
	\SemantexLeft #1
}

\DeclareDocumentCommand\SemantexMathCloseAuto { m }
{
	\SemantexRight #1
	\group_end:
}

\DeclareDocumentCommand\SemantexMathOpenNoPar { }
{
	\group_begin:
	\tl_clear:N\l_semantex_delimiter_size_temp_tl
}

\DeclareDocumentCommand\SemantexMathCloseNoPar { }
{
	\group_end:
}

\cs_new_protected:Npn \semantex_parentheses_store:nN#1#2
{
	\semantex_data_tl_get_store:nnN { #1 } { par~size } \l__semantex_parentheses_store_temp_tl
	\str_case:VnF { \l__semantex_parentheses_store_temp_tl } % This is where \big,\Big, etc. go.
	{
		{ normal } {
			\tl_set:Nx #2
			{
				\exp_not:N \SemantexMathOpen { }
				\semantex_data_tl_get_exp_not:nn { #1 } { left~par }
				\semantex_data_tl_get_exp_not:nn { #1 } { pre~arg }
				\semantex_data_tl_get_exp_not:nn { #1 } { arg }
				\semantex_data_tl_get_exp_not:nn { #1 } { post~arg }
				\exp_not:N \SemantexMathClose { }
				\semantex_data_tl_get_exp_not:nn { #1 } { right~par }
			}
		}
		{ auto } {
			\tl_set:Nx #2
			{
				\exp_not:N \SemantexMathOpenAuto
				\semantex_data_tl_get_exp_not:nn { #1 } { left~par }
				\semantex_data_tl_get_exp_not:nn { #1 } { pre~arg }
				\semantex_data_tl_get_exp_not:nn { #1 } { arg }
				\semantex_data_tl_get_exp_not:nn { #1 } { post~arg }
				\exp_not:N \SemantexMathCloseAuto
				\semantex_data_tl_get_exp_not:nn { #1 } { right~par }
			}
		}
		{ * } {
			\tl_set:Nx #2
			{
				\exp_not:N \SemantexMathOpenAuto
				\semantex_data_tl_get_exp_not:nn { #1 } { left~par }
				\semantex_data_tl_get_exp_not:nn { #1 } { pre~arg }
				\semantex_data_tl_get_exp_not:nn { #1 } { arg }
				\semantex_data_tl_get_exp_not:nn { #1 } { post~arg }
				\exp_not:N \SemantexMathCloseAuto
				\semantex_data_tl_get_exp_not:nn { #1 } { right~par }
			}
		}
	}
	{
		\tl_set:Nx #2
		{
			\exp_not:N \SemantexMathOpen
			\exp_not:V \l__semantex_parentheses_store_temp_tl
			\semantex_data_tl_get_exp_not:nn { #1 } { left~par }
			\semantex_data_tl_get_exp_not:nn { #1 } { pre~arg }
			\semantex_data_tl_get_exp_not:nn { #1 } { arg }
			\semantex_data_tl_get_exp_not:nn { #1 } { post~arg }
			\exp_not:N \SemantexMathClose
			\exp_not:V \l__semantex_parentheses_store_temp_tl
			\semantex_data_tl_get_exp_not:nn { #1 } { right~par }
		}
	}
}

\cs_generate_variant:Nn \str_case:nnF { VnF }

\cs_generate_variant:Nn \str_if_eq:nnF { xnF }

\cs_new_protected:Npn \semantex_no_parentheses_store:nN#1#2
% The central command for handling the rendering of arguments with no parentheses around
{
	\tl_set:Nx#2
	{
		\exp_not:N\SemantexMathOpenNoPar
		\semantex_data_tl_get_exp_not:nn { #1 } { pre~arg }
		\semantex_data_tl_get_exp_not:nn { #1 } { arg }
		\semantex_data_tl_get_exp_not:nn { #1 } { post~arg }
		\exp_not:N\SemantexMathCloseNoPar
	}
}

\cs_new_protected:Npn \__semantex_symbol_parentheses_store:nnnnN#1#2#3#4#5
% The central command handling the rendering of symbol parentheses
{
	\str_case:nnF { #1 } % This is where \big,\Big, etc. go.
	{
		{ normal } {
			\tl_set:Nn#5
			{
				#4
			}
			\str_if_eq:nnF { #2 } { . }
			{
				\tl_put_left:Nn#5
				{
					\mathopen #2
				}
			}
			\str_if_eq:nnF { #3 } { . }
			{
				\tl_put_right:Nn#5
				{
					\mathclose #3
				}
			}
		}
		{ auto } {
			\tl_set:Nn#5
			{
				\SemantexLeft #2
				#4
				\SemantexRight #3
			}
		}
		{ * } {
			\tl_set:Nn#5
			{
				\SemantexLeft #2
				#4
				\SemantexRight #3
			}
		}
	}
	{
		\tl_set:Nn#5
		{
			\mathopen #1 #2
			#4
			\mathclose #1 #3
		}
	}
}

\cs_generate_variant:Nn \__semantex_symbol_parentheses_store:nnnnN { xxxxN }

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%		COMMANDS FOR THE RETURN ROUTINES
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\cs_new_protected:Npn\semantex_return:n#1
{
	% This is an umbrella key that runs all of the three
	% return routines, innerreturn, rightreturn, and leftreturn
	\semantex_inner_return:n { #1 }
	\semantex_left_index_return:n { #1 }
	\semantex_left_arg_return:n { #1 }
	\semantex_right_index_return:n { #1 }
	\semantex_right_arg_return:n { #1 }
}

\cs_new_protected:Npn\semantex_pre_return:n#1
{
	% The pre-return routines are like the return routines, except
	% they do not reset all the parameters we need. This is only
	% intended for use when rendering and not outputting, as
	% resetting parameters in this case would just waste
	% time.
	\semantex_inner_pre_return:n { #1 }
	\semantex_left_indices_pre_return:n { #1 }
	\semantex_left_arg_pre_return:n { #1 }
	\semantex_right_indices_pre_return:n { #1 }
	\semantex_right_arg_pre_return:n { #1 }
}

\cs_new_protected:Npn\semantex_inner_return:n#1
{
	\semantex_inner_pre_return:n { #1 }
	\semantex_data_seq_clear:nn { #1 } { commands~sequence }
}

\cs_new_protected:Npn\semantex_inner_pre_return:n#1
{
	% This adds all of the commands added via the command key
	% to the symbol
	\semantex_data_seq_get_store:nnN { #1 } { commands~sequence }
		\l__semantex_data_seq_commands_sequence_temp
	\seq_map_inline:Nn \l__semantex_data_seq_commands_sequence_temp
	{
		\semantex_data_tl_set:nnx { #1 } { symbol }
		{
			\exp_not:N ##1
			{
				\semantex_data_tl_get_exp_not:nn { #1 } { symbol }
			}
		}
	}
	\semantex_data_seq_clear:nn { #1 } { commands~sequence }
}

\cs_new_protected:Npn\semantex_right_return:n#1
{
	\semantex_inner_return:n { #1 }
	\semantex_right_index_return:n { #1 }
	\semantex_right_arg_return:n { #1 }
}

\cs_new_protected:Npn\semantex_right_index_return:n#1
{
	\semantex_right_indices_pre_return:n { #1 }
	\semantex_data_tl_clear:nn { #1 } { upper }
	\semantex_data_tl_clear:nn { #1 } { pre~upper }
	\semantex_data_tl_clear:nn { #1 } { post~upper }
	\semantex_data_bool_set_false:nn { #1 } { next~upper~with~sep }
	\semantex_data_int_clear:nn { #1 } { number~of~upper~indices }
	\semantex_data_tl_clear:nn { #1 } { lower }
	\semantex_data_tl_clear:nn { #1 } { pre~lower }
	\semantex_data_tl_clear:nn { #1 } { post~lower }
	\semantex_data_bool_set_false:nn { #1 } { next~lower~with~sep }
	\semantex_data_int_clear:nn { #1 } { number~of~lower~indices }
}

\cs_new_protected:Npn\semantex_right_indices_pre_return:n#1
{
	\_semantex_right_index_return_store:nN { #1 }
		\l__semantex_rightreturn_right_indices_temp
	\semantex_data_tl_put_right:nnx { #1 } { symbol }
	{
		\exp_not:V \l__semantex_rightreturn_right_indices_temp
	}
}

\cs_new_protected:Npn \_semantex_right_index_return_store:nN#1#2
{
	\tl_set:Nn#2{}
	\semantex_data_int_if_positive:nnTF { #1 } { number~of~lower~indices }
	{
		\tl_put_right:Nx#2
		{
			\sb{
				\semantex_data_tl_get_exp_not:nn { #1 } { pre~lower }
				\semantex_data_tl_get_exp_not:nn { #1 } { lower }
				\semantex_data_tl_get_exp_not:nn { #1 } { post~lower }
			}
		}
	}
	{
		% do nothing
	}
	\semantex_data_int_if_positive:nnTF { #1 } { number~of~upper~indices }
	{
		\tl_put_right:Nx#2
		{
			\sp{
				\semantex_data_tl_get_exp_not:nn { #1 } { pre~upper }
				\semantex_data_tl_get_exp_not:nn { #1 } { upper }
				\semantex_data_tl_get_exp_not:nn { #1 } { post~upper }
			}
		}
	}
	{
		% do nothing
	}
}

\cs_new_protected:Npn\semantex_left_return:n#1
{
	\semantex_inner_return:n { #1 }
	\semantex_left_index_return:n { #1 }
	\semantex_left_arg_return:n { #1 }
}

\cs_new_protected:Npn\semantex_left_index_return:n#1
{
	\semantex_left_indices_pre_return:n { #1 }
	\semantex_data_tl_clear:nn { #1 } { upper~left }
	\semantex_data_tl_clear:nn { #1 } { pre~upper~left }
	\semantex_data_tl_clear:nn { #1 } { post~upper~left }
	\semantex_data_bool_set_false:nn { #1 } { next~upper~left~with~sep }
	\semantex_data_int_clear:nn { #1 } { number~of~upper~left~indices }
	\semantex_data_tl_clear:nn { #1 } { lower~left }
	\semantex_data_tl_clear:nn { #1 } { pre~lower~left }
	\semantex_data_tl_clear:nn { #1 } { post~lower~left }
	\semantex_data_bool_set_false:nn { #1 } { next~lower~left~with~sep }
	\semantex_data_int_clear:nn { #1 } { number~of~lower~left~indices }
	\semantex_data_tl_set:nnx { #1 } { height~phantom }
	{
		\semantex_data_tl_get_exp_not:nn { #1 } { symbol }
	}
	\semantex_data_tl_clear:nn { #1 } { slanting~phantom }
}

\cs_new_protected:Npn\semantex_left_indices_pre_return:n#1
{
	\_semantex_left_index_return_store:nN { #1 }
		\l__semantex_leftreturn_left_indices_temp
	\semantex_data_tl_put_left:nnx { #1 } { symbol }
	{
		\exp_not:V \l__semantex_leftreturn_left_indices_temp
	}
}

\cs_new_protected:Npn \_semantex_left_index_return_store:nN#1#2
{
	\tl_set:Nn#2{}
	\semantex_data_int_if_positive:nnTF { #1 } { number~of~upper~left~indices }
	{
		\tl_put_right:Nn #2 { \manualleftindex }
		\tl_put_right:Nx #2
		{
			{ \semantex_data_tl_get_exp_not:nn { #1 } { height~phantom } }
			{ \semantex_data_tl_get_exp_not:nn { #1 } { slanting~phantom} }
			{
				\semantex_data_tl_get_exp_not:nn { #1 } { pre~upper~left }
				\semantex_data_tl_get_exp_not:nn { #1 } { upper~left }
				\semantex_data_tl_get_exp_not:nn { #1 } { post~upper~left }
			}
		}
		\semantex_data_int_if_positive:nnTF { #1 } { number~of~lower~left~indices }
		{
			\tl_put_right:Nx#2
			{
				{
					\semantex_data_tl_get_exp_not:nn { #1 } { pre~lower~left }
					\semantex_data_tl_get_exp_not:nn { #1 } { lower~left }
					\semantex_data_tl_get_exp_not:nn { #1 } { post~lower~left }
				}
			}
		}
		{
			\tl_put_right:Nn#2
			{
				{ }
			}
		}
	}
	{
		\semantex_data_int_if_positive:nnTF { #1 } { number~of~lower~left~indices }
		{
			\tl_put_right:Nn #2 { \manualleftindex }
			\tl_put_right:Nx #2
			{
				{ \semantex_data_tl_get_exp_not:nn { #1 } { height~phantom } }
				{ \semantex_data_tl_get_exp_not:nn { #1 } { slanting~phantom } }
				{ }
				{
					\semantex_data_tl_get_exp_not:nn { #1 } { pre~lower~left }
					\semantex_data_tl_get_exp_not:nn { #1 } { lower~left }
					\semantex_data_tl_get_exp_not:nn { #1 } { post~lower~left }
				}
			}
		}
		{
			% do nothing
		}
	}
}

\cs_new_protected:Npn\semantex_right_arg_return:n#1
{
	\semantex_data_bool_get:nnTF { #1 } { left~argument }
	{
		% do nothing
	}
	{
		\_semantex_arg_return_store:nN { #1 } \l__semantex_rightreturn_arg_temp
		\semantex_data_tl_put_right:nnx { #1 } { symbol }
		{
			\exp_not:V
			\l__semantex_rightreturn_arg_temp
		}
		\semantex_data_tl_clear:nn { #1 } { arg }
		\semantex_data_tl_clear:nn { #1 } { pre~arg }
		\semantex_data_tl_clear:nn { #1 } { post~arg }
		\semantex_data_int_clear:nn { #1 } { number~of~arguments }
		\semantex_data_bool_set_false:nn { #1 } { next~arg~with~sep }
	}
}

\cs_new_protected:Npn\semantex_right_arg_pre_return:n#1
{
	\semantex_data_bool_get:nnTF { #1 } { left~argument }
	{
		% do nothing
	}
	{
		\_semantex_arg_return_store:nN { #1 } \l__semantex_rightreturn_arg_temp
		\semantex_data_tl_put_right:nnx { #1 } { symbol }
		{
			\exp_not:V
			\l__semantex_rightreturn_arg_temp
		}
	}
}

\cs_new_protected:Npn\semantex_left_arg_return:n#1
{
	\semantex_data_bool_get:nnTF { #1 } { left~argument }
	{
		\_semantex_arg_return_store:nN { #1 } \l__semantex_leftreturn_arg_temp
		\semantex_data_tl_put_left:nnx { #1 } { symbol }
		{
			\exp_not:V \l__semantex_leftreturn_arg_temp
		}
		\semantex_data_tl_clear:nn { #1 } { arg }
		\semantex_data_tl_clear:nn { #1 } { pre~arg }
		\semantex_data_tl_clear:nn { #1 } { post~arg }
		\semantex_data_int_clear:nn { #1 } { number~of~arguments }
		\semantex_data_bool_set_false:nn { #1 } { next~arg~with~sep }
	}
	{
		% do nothing
	}
}

\cs_new_protected:Npn\semantex_left_arg_pre_return:n#1
{
	\semantex_data_bool_get:nnTF { #1 } { left~argument }
	{
		\_semantex_arg_return_store:nN { #1 } \l__semantex_leftreturn_arg_temp
		\semantex_data_tl_put_left:nnx { #1 } { symbol }
		{
			\exp_not:V \l__semantex_leftreturn_arg_temp
		}
	}
	{
		% do nothing
	}
}

\cs_new_protected:Npn\semantex_arg_return:n#1
{
	\semantex_arg_pre_return:n { #1 }
	\semantex_data_tl_clear:nn { #1 } { arg }
	\semantex_data_tl_clear:nn { #1 } { pre~arg }
	\semantex_data_tl_clear:nn { #1 } { post~arg }
	\semantex_data_int_clear:nn { #1 } { number~of~arguments }
	\semantex_data_bool_set_false:nn { #1 } { next~arg~with~sep }
}

\cs_new_protected:Npn\semantex_arg_pre_return:n#1
{
	\semantex_data_bool_get:nnTF { #1 } { left~argument }
	{
		\_semantex_arg_return_store:nN { #1 } \l__semantex_leftreturn_arg_temp
		\semantex_data_tl_put_left:nnx { #1 } { symbol }
		{
			\exp_not:V \l__semantex_leftreturn_arg_temp
		}
	}
	{
		\_semantex_arg_return_store:nN { #1 } \l__semantex_rightreturn_arg_temp
		\semantex_data_tl_put_right:nnx { #1 } { symbol }
		{
			\exp_not:V
			\l__semantex_rightreturn_arg_temp
		}
	}
}

\cs_new_protected:Npn \_semantex_arg_return_store:nN#1#2
{
	\semantex_data_bool_get:nnTF { #1 } { par }
	{
		\semantex_data_int_if_positive:nnTF { #1 } { number~of~arguments }
		{
			\semantex_parentheses_store:nN { #1 } #2
		}
		{
			\tl_set:Nn#2{}
		}
	}
	{
		\semantex_data_bool_get:nnTF { #1 } { flex~par }
		{
			\semantex_data_int_if_greater_than_one:nnTF { #1 } { number~of~arguments }
			{
				\semantex_parentheses_store:nN { #1 } #2
			}
			{
				\semantex_data_int_if_positive:nnTF { #1 } { number~of~arguments }
				{
					\semantex_no_parentheses_store:nN { #1 } #2
				}
				{
					\tl_set:Nn#2{}
				}
			}
		}
		{
			\semantex_data_int_if_positive:nnTF { #1 } { number~of~arguments }
			{	
				\semantex_no_parentheses_store:nN { #1 } #2
			}
			{
				\tl_set:Nn#2{}
			}
		}
	}
}

\cs_generate_variant:Nn \__semantex_parentheses_store:nnnnN { xxxxN , ooooN }

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%		COMMANDS HADNLING "spar" -- SYMBOL PARENTHESES
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\cs_new_protected:Npn\semantex_spar:nn#1#2
{
	% Abbreviation for "symbol parentheses"
	% Adds parentheses around the current symbol
	\semantex_return:n { #1 }
	\tl_if_blank:nTF { #2 }
	{
		\semantex_data_tl_get_store:nnN { #1 } { spar~size } 
			\l__semantex_spar_spar_size_temp_tl
	}
	{
		\tl_set:Nn \l__semantex_spar_spar_size_temp_tl { #2 }
	}
	\__semantex_symbol_parentheses_store:xxxxN
		{ \exp_not:V\l__semantex_spar_spar_size_temp_tl }
		{ \semantex_data_tl_get_exp_not:nn { #1 } { left~spar } }
		{ \semantex_data_tl_get_exp_not:nn { #1 } { right~spar } }
		{ \semantex_data_tl_get_exp_not:nn { #1 } { symbol } }
		\l__semantex_spar_temp_tl
	\semantex_data_tl_set:nnx { #1 } { symbol }
	{
		\exp_not:V \l__semantex_spar_temp_tl
	}
	\semantex_spar_set_height_phantom_to_parentheses_size:nx { #1 }
		{ \exp_not:V \l__semantex_spar_spar_size_temp_tl }
}

\cs_new_protected:Npn\semantex_other_spar:nnn#1#2#3
{
	\semantex_return:n { #1 }
	\semantex_data_tl_get_store:nnN { #1 } { spar~size }
		\l__semantex_other_spar_spar_size_temp_tl
	\__semantex_symbol_parentheses_store:xxxxN
		{ \exp_not:V \l__semantex_other_spar_spar_size_temp_tl }
		{ \exp_not:n { #2 } }
		{ \exp_not:n { #3 } }
		{ \semantex_data_tl_get_exp_not:nn { #1 } { symbol } }
		\l__semantex_other_spar_temp_tl
	\semantex_data_tl_set:nnx { #1 } { symbol }
	{
		\exp_not:V \l__semantex_other_spar_temp_tl
	}
	\semantex_spar_set_height_phantom_to_parentheses_size:nx { #1 }
		{ \exp_not:V \l__semantex_other_spar_spar_size_temp_tl }
}

\cs_new_protected:Npn\semantex_other_spar_with_size:nnnn#1#2#3#4
{
	\semantex_return:n { #1 }
	\__semantex_symbol_parentheses_store:xxxxN
		{ \exp_not:n { #4 } }
		{ \exp_not:n { #2 } }
		{ \exp_not:n { #3 } }
		{ \semantex_data_tl_get_exp_not:nn { #1 } { symbol } }
		\l__semantex_other_spar_with_size_temp_tl
	\semantex_data_tl_set:nnx { #1 } { symbol }
	{
		\exp_not:V \l__semantex_other_spar_with_size_temp_tl
	}
	\semantex_spar_set_height_phantom_to_parentheses_size:nn { #1 }
		{ #4 }
}

\cs_new_protected:Npn\semantex_spar_set_height_phantom_to_parentheses_size:nn#1#2
{
	% #1 = register
	% #2 = parentheses size
	\str_case:nnF { #2 }
	{
		{ normal } {
			\semantex_data_tl_set:nnn { #1 } { height~phantom } { \vert }
		}
		{ auto } {
			\semantex_data_tl_set:nnx { #1 } { height~phantom }
			{
				\semantex_data_tl_get_exp_not:nn { #1 } { symbol }
			}
		}
		{ * } {
			\semantex_data_tl_set:nnx { #1 } { height~phantom }
			{
				\semantex_data_tl_get_exp_not:nn { #1 } { symbol }
			}
		}
	}
	{
		\semantex_data_tl_set:nnx { #1 } { height~phantom }
		{
			\exp_not:n { #2 \vert }
		}
	}
}

\cs_generate_variant:Nn \semantex_spar_set_height_phantom_to_parentheses_size:nn { nx }

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%    COMMANDS FOR MODIFYING AND OBTAINING DATA
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% COMMANDS FOR HANDLING THE PARENT OF A CLASS/OBJECT:

\cs_new:Npn \semantex_data_parent_get:n#1
{
	% #1 = register
	% A command to get the parent of an object
	\use:c { g__semantex_data_tl_#1_parent }
}

\cs_new_protected:Npn \semantex_data_parent_set:nn#1#2
{
	% #1 = reigster
	% Sets the parent
	\semantex_class_if_exist:NTF { #2 }
	{
		\tl_set:cx { g__semantex_data_tl_#1_parent } { \semantex_class_to_register:N #2 }
	}
	{
		\semantex_msg_error:nnnn { #1 } { class_not_found } { parent } { #2 }
	}
}

\cs_new_protected:Npn \semantex_data_class_set:nn#1#2 
{
	% #1 = register
	% Sets the parent to be a class
	\semantex_class_if_exist:NTF { #2 }
	{
		\tl_set:cx { g__semantex_data_tl_#1_parent } { \semantex_class_to_register:N #2 }
	}
	{
		\semantex_msg_error:nnnn { #1 } { class_not_found } { class } { #2 }
	}
}

\cs_generate_variant:Nn \semantex_data_class_set:nn { xn }

\cs_new_protected:Npn \semantex_data_copy_object:nn#1#2 
{
	\semantex_object_if_exist:NTF { #2 }
	{
		\tl_set:cx { g__semantex_data_tl_#1_parent } { \semantex_object_to_register:N #2 }
	}
	{
		\semantex_msg_error:nnnn { #1 } { object_not_found } { copy } { #2 }
	}
}

% COMMANDS FOR HANDLING DATA CONSISTING OF TOKEN LISTS

\cs_new:Npn \semantex_data_tl_get:nn#1#2
{
	% #1 = name of object
	% #2 = the data to get
	\__semantex_data_tl_get_auxiliary:nnn { #1 } { #2 } { #1 }
}

\cs_new:Npn \__semantex_data_tl_get_auxiliary:nnn#1#2#3
{
	% #1 = name of register
	% #2 = the data to get
	% #3 = the original register, used for error messaging
	\tl_if_exist:cTF { g__semantex_data_tl_#1_#2 }
	{
		\use:c { g__semantex_data_tl_#1_#2 }
	}
	{
		\str_if_eq:nVTF { #1 } \g_semantex_class_SemantexBaseObject_register_tl
		{
			\semantex_msg_error:nnx { #3 } { data_tl_not_found } { #2 }
		}
		{
			\__semantex_data_tl_get_auxiliary:fnn { \semantex_data_parent_get:n { #1 } } { #2 } { #3 }
		}
	}
}

\cs_generate_variant:Nn \__semantex_data_tl_get_auxiliary:nnn { fnn }

\cs_new:Npn \semantex_data_tl_get_exp_not:nn#1#2
{
	% #1 = name of register
	% #2 = the data to get
	\__semantex_data_tl_get_exp_not_auxiliary:nnn { #1 } { #2 } { #1 }
}

\cs_new:Npn \__semantex_data_tl_get_exp_not_auxiliary:nnn#1#2#3
{
	% #1 = name of register
	% #2 = the data to get
	% #3 = the original register, used for error messaging
	\tl_if_exist:cTF { g__semantex_data_tl_#1_#2 }
	{
		\exp_not:v { g__semantex_data_tl_#1_#2 }
	}
	{
		\str_if_eq:nVTF { #1 } \g_semantex_class_SemantexBaseObject_register_tl
		{
			\semantex_msg_error:nnx { #3 } { data_tl_not_found } { #2 }
		}
		{
			\__semantex_data_tl_get_exp_not_auxiliary:fnn { \semantex_data_parent_get:n { #1 } } { #2 } { #3 }
		}
	}
}

\cs_generate_variant:Nn \__semantex_data_tl_get_exp_not_auxiliary:nnn { fnn }

\cs_new_protected:Npn \semantex_data_tl_get_store:nnN#1#2#3
{
	% #1 = name of object
	% #2 = the data to get
	% #3 = where to store it
	\__semantex_data_tl_get_store_auxiliary:nnNn { #1 } { #2 } #3 { #1 }
}

\cs_new_protected:Npn \__semantex_data_tl_get_store_auxiliary:nnNn#1#2#3#4
{
	% #1 = name of register
	% #2 = the data to get
	% #3 = where to store it
	% #4 = name of original register, for error message purposes
	\tl_if_exist:cTF { g__semantex_data_tl_#1_#2 }
	{
		\tl_set_eq:Nc #3 { g__semantex_data_tl_#1_#2 }
	}
	{
		\str_if_eq:nVTF { #1 } \g_semantex_class_SemantexBaseObject_register_tl
		{
			\semantex_msg_error:nnx { #4 } { data_tl_not_found } { #2 }
		}
		{
			\__semantex_data_tl_get_store_auxiliary:fnNn { \semantex_data_parent_get:n { #1 } } { #2 } #3 { #4 }
		}
	}
}

\cs_generate_variant:Nn \__semantex_data_tl_get_store_auxiliary:nnNn { fnNn }

\cs_generate_variant:Nn \semantex_data_tl_get_store:nnN { nnc }

\cs_new_protected:Npn\semantex_data_tl_provide:nn#1#2
{
	% #1 = name of register
	% #2 = the data to provide
	\tl_if_exist:cF { g__semantex_data_tl_#1_#2 }
	{
		\tl_set:cn { g__semantex_data_tl_#1_#2 } {}
	}
}

\cs_new_protected:Npn\semantex_data_tl_inherit:nn#1#2
{
	% #1 = register
	% #2 = piece of token list data
	% Takes the data #2 from the parent of #1 and saves it locally
	% to the object #1. After this, no more inheritance is taking place
	% from the parent, and the data can be changed locally on the level
	% of #1.
	\tl_if_exist:cF { g__semantex_data_tl_#1_#2 }
	{
		\semantex_data_tl_get_store:nnc { \semantex_data_parent_get:n { #1 } } { #2 } { g__semantex_data_tl_#1_#2 }
	}
}


\cs_new_protected:Npn \semantex_data_tl_set:nnn#1#2#3
{
	\tl_set:cn { g__semantex_data_tl_#1_#2 } { #3 }
}

\cs_generate_variant:Nn \semantex_data_tl_set:nnn { nno, nnx }

\cs_new_protected:Npn \semantex_data_tl_put_right:nnn#1#2#3
{
	\semantex_data_tl_inherit:nn { #1 } { #2 }
	\tl_put_right:cn { g__semantex_data_tl_#1_#2 } { #3 }
}

\cs_generate_variant:Nn \semantex_data_tl_put_right:nnn { nnx }

\cs_new_protected:Npn \semantex_data_tl_put_left:nnn#1#2#3
{
	\semantex_data_tl_inherit:nn { #1 } { #2 }
	\tl_put_left:cn { g__semantex_data_tl_#1_#2 } { #3 }
}

\cs_generate_variant:Nn \semantex_data_tl_put_left:nnn { nnx }

\cs_new_protected:Npn \semantex_data_tl_clear:nn#1#2
{
	\semantex_data_tl_provide:nn { #1 } { #2 }
	\tl_clear:c { g__semantex_data_tl_#1_#2 }
}

% DATA OF TYPE INTEGER:

\cs_new_protected:Npn\semantex_data_int_provide:nn#1#2
{
	\bool_if_exist:cTF { g__semantex_data_int_#1_#2_bool_if_provided }
	{
		\bool_if:cF { g__semantex_data_int_#1_#2_bool_if_provided }
		{
			\bool_set_true:c { g__semantex_data_int_#1_#2_bool_if_provided }
		}
	}
	{
		\bool_new:c { g__semantex_data_int_#1_#2_bool_if_provided }
		\bool_set_true:c { g__semantex_data_int_#1_#2_bool_if_provided }
		\int_new:c { g__semantex_data_int_#1_#2 }
	}
}

\cs_new_protected:Npn\semantex_data_int_inherit:nn#1#2
{
	\bool_if_exist:cTF { g__semantex_data_int_#1_#2_bool_if_provided }
	{
		\bool_if:cF { g__semantex_data_int_#1_#2_bool_if_provided }
		{
			\semantex_data_int_get_store:nnc { \semantex_data_parent_get:n { #1 } } { #2 }
				{ g__semantex_data_int_#1_#2 }
			\bool_set_true:c { g__semantex_data_int_#1_#2_bool_if_provided }
		}
	}
	{
		\bool_new:c { g__semantex_data_int_#1_#2_bool_if_provided }
		\bool_set_true:c { g__semantex_data_int_#1_#2_bool_if_provided }
		\int_new:c { g__semantex_data_int_#1_#2 }
		\semantex_data_int_get_store:nnc { \semantex_data_parent_get:n { #1 } } { #2 }
			{ g__semantex_data_int_#1_#2 }
	}
}

\cs_new:Npn \semantex_data_int_get:nn#1#2{
	% #1 = name of object
	% #2 = the integer to get
	\__semantex_data_int_get_auxiliary:nnn { #1 } { #2 } { #1 }
}

\cs_new:Npn \__semantex_data_int_get_auxiliary:nnn#1#2#3{
	% #1 = name of object
	% #2 = the integer to get
	% #3 = stores the original register, for error message purposes
	\bool_if_exist:cTF { g__semantex_data_int_#1_#2_bool_if_provided }
	{
		\bool_if:cTF { g__semantex_data_int_#1_#2_bool_if_provided }
		{
			\int_use:c { g__semantex_data_int_#1_#2 }
		}
		{
			\str_if_eq:nVTF { #1 } \g_semantex_class_SemantexBaseObject_register_tl
			{
				\semantex_msg_error:nnx { #3 } { data_int_not_found } { #2 }
			}
			{
				\__semantex_data_int_get_auxiliary:fnn { \semantex_data_parent_get:n { #1 } } { #2 } { #3 }
			}
		}
	}
	{
		\str_if_eq:nVTF { #1 } \g_semantex_class_SemantexBaseObject_register_tl
		{
			\semantex_msg_error:nnx { #3 } { data_int_not_found } { #2 }
		}
		{
			\__semantex_data_int_get_auxiliary:fnn { \semantex_data_parent_get:n { #1 } } { #2 } { #3 }
		}
	}
}

\cs_generate_variant:Nn \__semantex_data_int_get_auxiliary:nnn { fnn }


\cs_new_protected:Npn \semantex_data_int_get_store:nnN#1#2#3{
	% #1 = name of object
	% #2 = the integer to get
	% #3 = the command to store it in
	\__semantex_data_int_get_store_auxiliary:nnNn { #1 } { #2 } #3 { #1 }
}

\cs_new_protected:Npn\__semantex_data_int_get_store_auxiliary:nnNn#1#2#3#4{
	% #1 = name of object
	% #2 = the integer to get
	% #3 = the command to store it in
	\bool_if_exist:cTF { g__semantex_data_int_#1_#2_bool_if_provided }
	{
		\bool_if:cTF { g__semantex_data_int_#1_#2_bool_if_provided }
		{
			\int_set_eq:Nc#3 { g__semantex_data_int_#1_#2 }
		}
		{
			\str_if_eq:nVTF { #1 } \g_semantex_class_SemantexBaseObject_register_tl
			{
				\semantex_msg_error:nnx { #4 } { data_int_not_found } { #2 }
			}
			{
				\__semantex_data_int_get_store_auxiliary:fnNn { \semantex_data_parent_get:n { #1 } } { #2 } #3 { #4 }
			}
		}
	}
	{
		\str_if_eq:nVTF { #1 } \g_semantex_class_SemantexBaseObject_register_tl
		{
			\semantex_msg_error:nnx { #4 } { data_int_not_found } { #2 }
		}
		{
			\__semantex_data_int_get_store_auxiliary:fnNn { \semantex_data_parent_get:n { #1 } } { #2 } #3 { #4 }
		}
	}
}

\cs_generate_variant:Nn \__semantex_data_int_get_store_auxiliary:nnNn { fnNn }

\cs_generate_variant:Nn \semantex_data_int_get_store:nnN { nnc }

\cs_new_protected:Npn\semantex_data_int_incr:nn#1#2
{
	\semantex_data_int_inherit:nn { #1 } { #2 }
	\int_incr:c { g__semantex_data_int_#1_#2 }
}

\cs_new_protected:Npn\semantex_data_int_set:nnn#1#2#3
{
	\semantex_data_int_provide:nn { #1 } { #2 }
	\int_set:cn { g__semantex_data_int_#1_#2 } { #3 }
}

\cs_new_protected:Npn\semantex_data_int_if_positive:nnTF#1#2#3#4
{
	\int_compare:nNnTF { \semantex_data_int_get:nn { #1 } { #2 } } > { 0 } { #3 } { #4 }
}

\cs_new_protected:Npn\semantex_data_int_if_greater_than_one:nnTF#1#2#3#4
{
	\int_compare:nNnTF { \semantex_data_int_get:nn { #1 } { #2 } } > { 1 } { #3 } { #4 }
}

\cs_new_protected:Npn\semantex_data_int_clear:nn#1#2
{
	\semantex_data_int_provide:nn { #1 } { #2 }
	\int_zero:c { g__semantex_data_int_#1_#2 }
}

% COMMANDS FOR HANDLING DATA OF SEQUENCE TYPE

\cs_new_protected:Npn \semantex_data_seq_get_store:nnN#1#2#3{
	% #1 = name of object
	% #2 = the sequence to get
	% #3 = the command to store it in
	\bool_if_exist:cTF { g__semantex_data_seq_#1_#2_bool_if_provided }
	{
		\bool_if:cTF { g__semantex_data_seq_#1_#2_bool_if_provided }
		{
			\seq_set_eq:Nc#3 { g__semantex_data_seq_#1_#2 }
		}
		{
			\semantex_data_seq_get_store:nnN { \semantex_data_parent_get:n { #1 } } { #2 } #3
		}
	}
	{
		\semantex_data_seq_get_store:nnN { \semantex_data_parent_get:n { #1 } } { #2 } #3
	}
}

\cs_generate_variant:Nn \semantex_data_seq_get_store:nnN { nnc }

\cs_new_protected:Npn\semantex_data_seq_provide:nn#1#2
{
	\bool_if_exist:cTF { g__semantex_data_seq_#1_#2_bool_if_provided }
	{
		\bool_if:cF { g__semantex_data_seq_#1_#2_bool_if_provided }
		{
			\bool_set_true:c { g__semantex_data_seq_#1_#2_bool_if_provided }
		}
	}
	{
		\seq_new:c { g__semantex_data_seq_#1_#2 }
		\bool_new:c { g__semantex_data_seq_#1_#2_bool_if_provided }
		\bool_set_true:c { g__semantex_data_seq_#1_#2_bool_if_provided }
	}
}

\cs_new_protected:Npn\semantex_data_seq_inherit:nn#1#2
{
	\bool_if_exist:cTF { g__semantex_data_seq_#1_#2_bool_if_provided }
	{
		\bool_if:cF { g__semantex_data_seq_#1_#2_bool_if_provided }
		{
			\semantex_data_seq_get_store:nnc { \semantex_data_parent_get:n { #1 } } { #2 } { g__semantex_data_seq_#1_#2 }
			\bool_set_true:c { g__semantex_data_seq_#1_#2_bool_if_provided }
		}
	}
	{
		\bool_new:c { g__semantex_data_seq_#1_#2_bool_if_provided }
		\bool_set_true:c { g__semantex_data_seq_#1_#2_bool_if_provided }
		\seq_if_exist:cF { g__semantex_data_seq_#1_#2 } { \seq_new:c { g__semantex_data_seq_#1_#2 } }
		\semantex_data_seq_get_store:nnc { \semantex_data_parent_get:n { #1 } } { #2 } { g__semantex_data_seq_#1_#2 }
	}
}

\cs_new_protected:Npn\semantex_data_seq_put_right:nnn#1#2#3
{
	\semantex_data_seq_inherit:nn { #1 } { #2 }
	\seq_put_right:cn { g__semantex_data_seq_#1_#2 } { #3 }
}

\cs_new_protected:Npn\semantex_data_seq_clear:nn#1#2
{
	\semantex_data_seq_provide:nn { #1 } { #2 }
	\seq_clear:c { g__semantex_data_seq_#1_#2 }
}

% COMMANDS FOR HANDLING DATA OF TYPE BOOLEAN:

\cs_new:Npn\semantex_data_bool_get:nnTF#1#2#3#4
{
	% #1 = name of the register
	% #2 = boolean to get
	% #3 = if true
	% #4 = if false
	\__semantex_data_bool_get_auxiliary:nnTFn { #1 } { #2 } { #3 } { #4 } { #1 }
}

\cs_new:Npn\__semantex_data_bool_get_auxiliary:nnTFn#1#2#3#4#5
{
	% We keep the somewhat unusual order of the arguments
	% to be consistent with how these commands look elsewhere.
	% #1 = name of the register
	% #2 = boolean to get
	% #3 = if true
	% #4 = if false
	% #5 = name of the original register, to be used for error messaging
	\bool_if_exist:cTF { g__semantex_data_bool_#1_if_#2_bool_if_provided }
	{
		\bool_if:cTF { g__semantex_data_bool_#1_if_#2_bool_if_provided }
		{
			\bool_if:cTF { g__semantex_data_bool_#1_if_#2 } { #3 } { #4 }
		}
		{
			\str_if_eq:nVTF { #1 } \g_semantex_class_SemantexBaseObject_register_tl
			{
				#4
			}
			{
				\__semantex_data_bool_get_auxiliary:fnTFn { \semantex_data_parent_get:n { #1 } } { #2 } { #3 } { #4 } { #5 }
			}
		}
	}
	{
		\str_if_eq:nVTF { #1 } \g_semantex_class_SemantexBaseObject_register_tl
		{
			\semantex_msg_error:nnx { #5 } { data_bool_not_found } { #2 }
		}
		{
			\__semantex_data_bool_get_auxiliary:fnTFn { \semantex_data_parent_get:n { #1 } } { #2 } { #3 } { #4 } { #5 }
		}
	}
}

\cs_generate_variant:Nn \__semantex_data_bool_get_auxiliary:nnTFn { fnTFn }

\cs_generate_variant:Nn \semantex_data_bool_get:nnTF { nnT }

\cs_new:Npn\semantex_data_bool_get:nnF#1#2#3
{
	\semantex_data_bool_get:nnTF { #1 } { #2 } { } { #3 }
}

\cs_new_protected:Npn\semantex_data_bool_provide:nn#1#2
{
	% #1 = name of the register
	% #2 = boolean to provide
	\bool_if_exist:cTF { g__semantex_data_bool_#1_if_#2_bool_if_provided }
	{
		\bool_if:cF { g__semantex_data_bool_#1_if_#2_bool_if_provided }
		{
			\bool_set_true:c { g__semantex_data_bool_#1_if_#2_bool_if_provided }
		}
	}
	{
		\bool_new:c { g__semantex_data_bool_#1_if_#2 }
		\bool_new:c { g__semantex_data_bool_#1_if_#2_bool_if_provided }
		\bool_set_true:c { g__semantex_data_bool_#1_if_#2_bool_if_provided }
	}
}

\cs_new_protected:Npn\semantex_data_bool_set_true:nn#1#2
{
	% #1 = name of the register
	% #2 = boolean to set true
	\semantex_data_bool_provide:nn { #1 } { #2 }
	\bool_set_true:c { g__semantex_data_bool_#1_if_#2 }
}

\cs_new_protected:Npn\semantex_data_bool_set_false:nn#1#2
{
	% #1 = name of the register
	% #2 = boolean to set false
	\semantex_data_bool_provide:nn { #1 } { #2 }
	\bool_set_false:c { g__semantex_data_bool_#1_if_#2 }
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%		COMMANDS FOR HANDLING KEYVAL INTERFACES
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\cs_generate_variant:Nn \semantex_keyval_parse:NNn { ccn }

\cs_new_protected:Npn \semantex_keys_set:nn#1#2
{
	\cs_set_eq:NN\l__semantex_keys_set_old_this_temp_cs:\semantex_this:
	\cs_set:Nn\semantex_this:{#1}
	% The central command for doing keyval setup
	% #1 = object
	% #2 = keys
	\semantex_keyval_parse:ccn % Used to use o-type expansions, but no longer seems necessary
		{ __semantex_data_cs_#1_singlekey:n }
		{ __semantex_data_cs_#1_valuekey:nn }
		{ #2 }
	\cs_set_eq:NN\semantex_this:\l__semantex_keys_set_old_this_temp_cs:
}

\cs_new_protected:Npn \semantex_keys_set_x:nn#1#2
{
	% This key should no longer be used.
	\cs_set_eq:NN\l__semantex_keys_set_old_this_temp_cs:\semantex_this:
	\cs_set:Nn\semantex_this:{#1}
	% The central command for doing expanded keyval setup
	% #1 = object
	% #2 = keys
	\semantex_keyval_parse:ccn % Used to use o-type expansions, but no longer seems necessary
		{ __semantex_data_cs_#1_singlekey_x:n }
		{ __semantex_data_cs_#1_valuekey:nx }
		{ #2 }
	\cs_set_eq:NN\semantex_this:\l__semantex_keys_set_old_this_temp_cs:
}

\cs_new_protected:Npn \semantex_arg_keys_set:nn#1#2
{
	% The central command for doing keyval setup for the argument
	% #1 = object
	% #2 = keys
	\semantex_keyval_parse:ccn % See last command
		{ __semantex_data_cs_#1_arg_singlekey:n }
		{ __semantex_data_cs_#1_arg_valuekey:nn }
		{ #2 }
}

\cs_new_protected:Npn \semantex_arg_keys_set_x:nn#1#2
{
	% This key should no longer be used.
	% The central command for doing expanded keyval setup for the argument
	% #1 = object
	% #2 = keys
	\semantex_keyval_parse:ccn % See last command
		{ __semantex_data_cs_#1_arg_singlekey_x:n }
		{ __semantex_data_cs_#1_arg_valuekey:nx }
		{ #2 }
}

\cs_generate_variant:Nn \semantex_singlekey_parse:Nn { cn }

\cs_new_protected:Npn \semantex_arg_singlekeys_set:nn#1#2
{
	% This command is necessary because you sometimes want to only allow singlekeys
	% and not valuekeys in arguments (for instance, if you allow valuekeys, anything
	% containing an equality sign will die horribly in the argument of any object)
	\semantex_singlekey_parse:cn { __semantex_data_cs_#1_arg_singlekey:n } { #2 }
}

\cs_new_protected:Npn \semantex_arg_singlekeys_set_x:nn#1#2
{
	% This command is necessary because you sometimes want to only allow singlekeys
	% and not valuekeys in arguments (for instance, if you allow valuekeys, anything
	% containing an equality sign will die horribly in the argument of any object)
	\semantex_singlekey_parse:cn { __semantex_data_cs_#1_arg_singlekey_x:n } {#2}
}

\DeclareDocumentCommand\SetupClass{mm}{ % a user-level command for setting up the object
	% #1 = class
	% #2 = setup
	\semantex_class_if_exist:NTF #1
	{
		\semantex_keys_set:nn { \semantex_class_to_register:N #1 }{ #2 }
	}
	{
		\semantex_msg_error:nn { \semantex_class_to_register:N #1 } { setup_unknown_class }
	}
}

\DeclareDocumentCommand\SetupObject{mm}{%
	% #1 = object
	% #2 = setup
	\semantex_object_if_exist:NTF #1
	{
		\semantex_keys_set:nn { \semantex_object_to_register:N #1 }{ #2 }
	}
	{
		\semantex_msg_error:nn { \semantex_object_to_register:N #1 } { setup_unknown_object }
	}
}

\cs_new_protected:Npn\semantex_valuekey:nnn#1#2#3
{
	% The central command for executing valuekeys,
	% i.e. keys taking a value
	% #1 = register
	% #2 = name of the key
	% #3 = value
	\__semantex_valuekey:nnnn { #1 } { #2 } { #3 } { #1 }
}

\cs_new_protected:Npn \__semantex_valuekey:nnnn#1#2#3#4
{
	\cs_if_exist:cTF { __semantex_data_cs_custom_valuekey_#1_#2:nn }
	{
		\use:c { __semantex_data_cs_custom_valuekey_#1_#2:nn } { #4 } { #3 }
	}
	{
		\str_if_eq:nVTF { #1 } \g_semantex_class_SemantexBaseObject_register_tl
		{
			\semantex_msg_error:nnn { #4 } { valuekey_not_found } { #2 }
		}
		{
			\__semantex_valuekey:fnnn { \semantex_data_parent_get:n { #1 } } { #2 } { #3 } { #4 }
		}
	}
}

\cs_generate_variant:Nn \__semantex_valuekey:nnnn { fnnn }

\cs_generate_variant:Nn \semantex_valuekey:nnn { nnx }

\cs_new_protected:Npn\semantex_base_object_valuekey:nnn#1#2#3
{
	% Skips through the steps above to go directly to the
	% valuekey as defined by \SemantexBaseObject.
	% This is only being used in the rendering routine,
	% so so far, an corresponding command for singlekeys
	% has not been needed.
	% #1 = register
	% #2 = key
	% #3 = value
	\use:c { __semantex_data_cs_custom_valuekey_\g_semantex_class_SemantexBaseObject_register_tl _#2:nn } { #1 } { #3 }
}

\cs_new_protected:Npn\semantex_singlekey:nn#1#2
{
	% The central command for executing singlekeys,
	% i.e. keys taking no
	% #1 = register
	% #2 = name of the key
	\__semantex_singlekey:nnn { #1 } { #2 } { #1 }
}

\cs_new_protected:Npn\__semantex_singlekey:nnn#1#2#3
{
	\cs_if_exist:cTF { __semantex_data_cs_custom_singlekey_#1_\tl_to_str:n{ #2 }:n }
		% This is necessary in order to allow the case where something nasty
		% and unexpandable gets passed as singlekey -- this often happens
		% because of the convention that \<Object>[<something not a key>]
		% just prints <something not a key>
	{
		\use:c { __semantex_data_cs_custom_singlekey_#1_#2:n } { #3 }
	}
	{
		\str_if_eq:nVTF { #1 } \g_semantex_class_SemantexBaseObject_register_tl
		{
			\semantex_valuekey:nnn { #3 } { default } { #2 }
		}
		{
			\__semantex_singlekey:fnn { \semantex_data_parent_get:n { #1 } } { #2 } { #3 }
		}
	}
}

\cs_generate_variant:Nn \__semantex_singlekey:nnn { fnn }

\cs_new_protected:Npn\semantex_singlekey_x:nn#1#2
{
	% The central command for executing expanded singlekeys,
	% i.e. keys taking no
	% #1 = register
	% #2 = name of the key
	\__semantex_singlekey_x:nnn { #1 } { #2 } { #1 }
}

\cs_new_protected:Npn\__semantex_singlekey_x:nnn#1#2#3
{
	\cs_if_exist:cTF { __semantex_data_cs_custom_singlekey_#1_\tl_to_str:n{ #2 }:n }
	{
		\use:c { __semantex_data_cs_custom_singlekey_#1_#2:n } { #3 }
		% and no, we don't want :x here; we don't need to expand
		% the name of the register
	}
	{
		\str_if_eq:nVTF { #1 } \g_semantex_class_SemantexBaseObject_register_tl
		{
			\semantex_valuekey:nnx { #3 } { default } { #2 }
		}
		{
			\__semantex_singlekey_x:fnn { \semantex_data_parent_get:n { #1 } } { #2 } { #3 }
		}
	}
}

\cs_generate_variant:Nn \__semantex_singlekey_x:nnn { fnn }

\cs_new_protected:Npn\semantex_valuekey_store:nnN#1#2#3
{
	% Stores the content of the valuekey
	% i.e. keys taking a value
	% #1 = register
	% #2 = name of the key
	% #3 = command to store the content in
	\cs_if_exist:cTF { __semantex_data_cs_custom_valuekey_#1_\tl_trim_spaces:n{#2}:nn }
	{
		\exp_args:NNNo \exp_args:NNo\tl_set:No#3 { \use:c { __semantex_data_cs_custom_valuekey_#1_\tl_trim_spaces:n{#2}:nn } { ##1 } { ##2 } }
	}
	{
		\str_if_eq:nVTF { #1 } \g_semantex_class_SemantexBaseObject_register_tl
		{
			\tl_set:Nn #3 {}
		}
		{
			\semantex_valuekey_store:fnN { \semantex_data_parent_get:n { #1 } } { #2 } #3
		}
	}
}

\cs_generate_variant:Nn \semantex_valuekey_store:nnN { fnN }

\cs_new_protected:Npn\semantex_singlekey_store:nnN#1#2#3
{
	% Stores the content of the singlekey
	% #1 = register
	% #2 = name of the key
	% #3 = command to store the content in
	\cs_if_exist:cTF { __semantex_data_cs_custom_singlekey_#1_\tl_trim_spaces:n{#2}:n }
	{
		\exp_args:NNNo \exp_args:NNo\tl_set:No#3 { \use:c { __semantex_data_cs_custom_singlekey_#1_\tl_trim_spaces:n{#2}:n } { ##1 } }
	}
	{
		\str_if_eq:nVTF { #1 } \g_semantex_class_SemantexBaseObject_register_tl
		{
			\tl_set:Nn #3 {}
		}
		{
			\semantex_singlekey_store:fnN { \semantex_data_parent_get:n { #1 } } { #2 } #3
		}
	}
}

\cs_generate_variant:Nn \semantex_singlekey_store:nnN { fnN }

\cs_new_protected:Npn\semantex_two_valuekey_store:nnN#1#2#3
{
	% Stores the content of the valuekey
	% i.e. keys taking a value
	% #1 = register
	% #2 = name of the key
	% #3 = command to store the content in
	\cs_if_exist:cTF { __semantex_data_cs_custom_two_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnn }
	{
		\exp_args:NNNo \exp_args:NNo\tl_set:No#3 { \use:c { __semantex_data_cs_custom_two_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnn } { ##1 } { ##2 } { ##3 } }
	}
	{
		\str_if_eq:nVTF { #1 } \g_semantex_class_SemantexBaseObject_register_tl
		{
			\tl_set:Nn #3 {}
		}
		{
			\semantex_two_valuekey_store:fnN { \semantex_data_parent_get:n { #1 } } { #2 } #3
		}
	}
}

\cs_generate_variant:Nn \semantex_two_valuekey_store:nnN { fnN }

\cs_new_protected:Npn\semantex_three_valuekey_store:nnN#1#2#3
{
	% Stores the content of the valuekey
	% i.e. keys taking a value
	% #1 = register
	% #2 = name of the key
	% #3 = command to store the content in
	\cs_if_exist:cTF { __semantex_data_cs_custom_three_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnn }
	{
		\exp_args:NNNo \exp_args:NNo\tl_set:No#3 { \use:c { __semantex_data_cs_custom_three_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnn } { ##1 } { ##2 } { ##3 } { ##4 } }
	}
	{
		\str_if_eq:nVTF { #1 } \g_semantex_class_SemantexBaseObject_register_tl
		{
			\tl_set:Nn #3 {}
		}
		{
			\semantex_three_valuekey_store:fnN { \semantex_data_parent_get:n { #1 } } { #2 } #3
		}
	}
}

\cs_generate_variant:Nn \semantex_three_valuekey_store:nnN { fnN }

\cs_new_protected:Npn\semantex_four_valuekey_store:nnN#1#2#3
{
	% Stores the content of the valuekey
	% i.e. keys taking a value
	% #1 = register
	% #2 = name of the key
	% #3 = command to store the content in
	\cs_if_exist:cTF { __semantex_data_cs_custom_four_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnn }
	{
		\exp_args:NNNo \exp_args:NNo\tl_set:No#3 { \use:c { __semantex_data_cs_custom_four_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnn } { ##1 } { ##2 } { ##3 } { ##4 } { ##5 } }
	}
	{
		\str_if_eq:nVTF { #1 } \g_semantex_class_SemantexBaseObject_register_tl
		{
			\tl_set:Nn #3 {}
		}
		{
			\semantex_four_valuekey_store:fnN { \semantex_data_parent_get:n { #1 } } { #2 } #3
		}
	}
}

\cs_generate_variant:Nn \semantex_four_valuekey_store:nnN { fnN }

\cs_new_protected:Npn\semantex_five_valuekey_store:nnN#1#2#3
{
	% Stores the content of the valuekey
	% i.e. keys taking a value
	% #1 = register
	% #2 = name of the key
	% #3 = command to store the content in
	\cs_if_exist:cTF { __semantex_data_cs_custom_five_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnn }
	{
		\exp_args:NNNo \exp_args:NNo\tl_set:No#3 { \use:c { __semantex_data_cs_custom_five_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnn } { ##1 } { ##2 } { ##3 } { ##4 } { ##5 } { ##6 } }
	}
	{
		\str_if_eq:nVTF { #1 } \g_semantex_class_SemantexBaseObject_register_tl
		{
			\tl_set:Nn #3 {}
		}
		{
			\semantex_five_valuekey_store:fnN { \semantex_data_parent_get:n { #1 } } { #2 } #3
		}
	}
}

\cs_generate_variant:Nn \semantex_five_valuekey_store:nnN { fnN }

\cs_new_protected:Npn\semantex_six_valuekey_store:nnN#1#2#3
{
	% Stores the content of the valuekey
	% i.e. keys taking a value
	% #1 = register
	% #2 = name of the key
	% #3 = command to store the content in
	\cs_if_exist:cTF { __semantex_data_cs_custom_six_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnn }
	{
		\exp_args:NNNo \exp_args:NNo\tl_set:No#3 { \use:c { __semantex_data_cs_custom_six_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnn } { ##1 } { ##2 } { ##3 } { ##4 } { ##5 } { ##6 } { ##7 } }
	}
	{
		\str_if_eq:nVTF { #1 } \g_semantex_class_SemantexBaseObject_register_tl
		{
			\tl_set:Nn #3 {}
		}
		{
			\semantex_six_valuekey_store:fnN { \semantex_data_parent_get:n { #1 } } { #2 } #3
		}
	}
}

\cs_generate_variant:Nn \semantex_six_valuekey_store:nnN { fnN }

\cs_new_protected:Npn\semantex_seven_valuekey_store:nnN#1#2#3
{
	% Stores the content of the valuekey
	% i.e. keys taking a value
	% #1 = register
	% #2 = name of the key
	% #3 = command to store the content in
	\cs_if_exist:cTF { __semantex_data_cs_custom_seven_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnnn }
	{
		\exp_args:NNNo \exp_args:NNo\tl_set:No#3 { \use:c { __semantex_data_cs_custom_seven_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnnn } { ##1 } { ##2 } { ##3 } { ##4 } { ##5 } { ##6 } { ##7 } { ##8 } }
	}
	{
		\str_if_eq:nVTF { #1 } \g_semantex_class_SemantexBaseObject_register_tl
		{
			\tl_set:Nn #3 {}
		}
		{
			\semantex_seven_valuekey_store:fnN { \semantex_data_parent_get:n { #1 } } { #2 } #3
		}
	}
}

\cs_generate_variant:Nn \semantex_seven_valuekey_store:nnN { fnN }

\cs_new_protected:Npn\semantex_eight_valuekey_store:nnN#1#2#3
{
	% Stores the content of the valuekey
	% i.e. keys taking a value
	% #1 = register
	% #2 = name of the key
	% #3 = command to store the content in
	\cs_if_exist:cTF { __semantex_data_cs_custom_eight_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnnnn }
	{
		\exp_args:NNNo \exp_args:NNo\tl_set:No#3 { \use:c { __semantex_data_cs_custom_eight_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnnnn } { ##1 } { ##2 } { ##3 } { ##4 } { ##5 } { ##6 } { ##7 } { ##8 } { ##9 } }
	}
	{
		\str_if_eq:nVTF { #1 } \g_semantex_class_SemantexBaseObject_register_tl
		{
			\tl_set:Nn #3 {}
		}
		{
			\semantex_eight_valuekey_store:fnN { \semantex_data_parent_get:n { #1 } } { #2 } #3
		}
	}
}

\cs_generate_variant:Nn \semantex_eight_valuekey_store:nnN { fnN }

\cs_new_protected:Npn\semantex_nine_valuekey_store:nnN#1#2#3
{
	% Stores the content of the valuekey
	% i.e. keys taking a value
	% #1 = register
	% #2 = name of the key
	% #3 = command to store the content in
	\cs_if_exist:cTF { __semantex_data_cs_custom_nine_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnnnn }
	{
		\exp_args:NNNo \exp_args:NNo\tl_set:No#3 { \use:c { __semantex_data_cs_custom_nine_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnnnn } { ##1 } { ##2 } { ##3 } { ##4 } { ##5 } { ##6 } { ##7 } { ##8 } { ##9 } }
	}
	{
		\str_if_eq:nVTF { #1 } \g_semantex_class_SemantexBaseObject_register_tl
		{
			\tl_set:Nn #3 {}
		}
		{
			\semantex_nine_valuekey_store:fnN { \semantex_data_parent_get:n { #1 } } { #2 } #3
		}
	}
}

\cs_generate_variant:Nn \semantex_nine_valuekey_store:nnN { fnN }


\cs_new_protected:Npn\semantex_arg_valuekey:nnn#1#2#3
{
	% Takes care of argument valuekeys, 
	% i.e. argument keys with a value
	% #1 = register
	% #2 = name of the key
	% #3 = value of the key
	\__semantex_arg_valuekey:nnnn { #1 } { #2 } { #3 } { #1 }
}

\cs_new_protected:Npn \__semantex_arg_valuekey:nnnn#1#2#3#4
{
	\cs_if_exist:cTF { __semantex_data_cs_custom_arg_valuekey_#1_#2:nn }
	{
		\use:c { __semantex_data_cs_custom_arg_valuekey_#1_#2:nn } { #4 } { #3 }
	}
	{
		\str_if_eq:nVTF { #1 } \g_semantex_class_SemantexBaseObject_register_tl
		{
			\semantex_msg_error:nnn { #1 } { arg_valuekey_not_found } { #2 }
		}
		{
			\__semantex_arg_valuekey:fnnn { \semantex_data_parent_get:n { #1 } } { #2 } { #3 } { #4 }
		}
	}
}

\cs_generate_variant:Nn \__semantex_arg_valuekey:nnnn { fnnn }

\cs_generate_variant:Nn \semantex_arg_valuekey:nnn { nnx }

\cs_new_protected:Npn \semantex_arg_singlekey:nn#1#2
{
	% The central command for executing argument singlekeys,
	% i.e. keys taking no
	% #1 = register
	% #2 = name of the key
	\__semantex_arg_singlekey:nnn { #1 } { #2 } { #1 }
}

\cs_new_protected:Npn \__semantex_arg_singlekey:nnn#1#2#3
{
	\cs_if_exist:cTF { __semantex_data_cs_custom_arg_singlekey_#1_\tl_to_str:n{ #2 }:n }
	{
		\use:c { __semantex_data_cs_custom_arg_singlekey_#1_#2:n } { #3 }
	}
	{
		\str_if_eq:nVTF { #1 } \g_semantex_class_SemantexBaseObject_register_tl
		{
			\semantex_arg_valuekey:nnn { #3 } { default } { #2 }
		}
		{
			\__semantex_arg_singlekey:fnn { \semantex_data_parent_get:n { #1 } } { #2 } { #3 }
		}
	}
}

\cs_generate_variant:Nn \__semantex_arg_singlekey:nnn { fnn }

\cs_new_protected:Npn \semantex_arg_singlekey_x:nn#1#2
{
	% The central command for executing expanded argument singlekeys,
	% i.e. keys taking no
	% #1 = register
	% #2 = name of the key
	\__semantex_arg_singlekey_x:nnn { #1 } { #2 } { #1 }
}

\cs_new_protected:Npn \__semantex_arg_singlekey_x:nnn#1#2#3
{
	\cs_if_exist:cTF { \tl_to_str:n{__semantex_data_cs_custom_arg_singlekey_#1_#2:n } }
	{
		\use:c { __semantex_data_cs_custom_arg_singlekey_#1_#2:n } { #3 }
		% and no, we don't want :x here; we don't need to expand
		% the name of the register
	}
	{
		\str_if_eq:nVTF { #1 } \g_semantex_class_SemantexBaseObject_register_tl
		{
			\semantex_arg_valuekey:nnx { #3 } { default } { #2 }
		}
		{
			\__semantex_arg_singlekey:fnn { \semantex_data_parent_get:n { #1 } } { #2 } { #3 }
		}
	}
}

\cs_generate_variant:Nn \__semantex_arg_singlekey_x:nnn { fnn }

\cs_new_protected:Npn\semantex_arg_without_keyval:nn#1#2
{
	% Sets the argument (no keyval interface allowed)
	\semantex_data_tl_put_right:nnn { #1 } { arg } { #2 }
	\semantex_data_int_incr:nn { #1 } { number~of~arguments }
	\semantex_data_bool_set_true:nn { #1 } { next~arg~with~sep }
}

\cs_generate_variant:Nn \semantex_arg_without_keyval:nn { nx }

\cs_new_protected:Npn\semantex_arg_valuekey_store:nnN#1#2#3
{
	% Stores the content of the argument valuekey
	% i.e. keys taking a value
	% #1 = register
	% #2 = name of the key
	% #3 = command to store the content in
	\cs_if_exist:cTF { __semantex_data_cs_custom_arg_valuekey_#1_\tl_trim_spaces:n{#2}:nn }
	{
		\exp_args:NNNo \exp_args:NNo\tl_set:No#3 { \use:c { __semantex_data_cs_custom_arg_valuekey_#1_\tl_trim_spaces:n{#2}:nn } { ##1 } { ##2 } }
	}
	{
		\str_if_eq:nVTF { #1 } \g_semantex_class_SemantexBaseObject_register_tl
		{
			\tl_set:Nn #3 {}
		}
		{
			\semantex_arg_valuekey_store:fnN { \semantex_data_parent_get:n { #1 } } { #2 } #3
		}
	}
}

\cs_generate_variant:Nn \semantex_arg_valuekey_store:nnN { fnN }

\cs_new_protected:Npn\semantex_arg_singlekey_store:nnN#1#2#3
{
	% Stores the content of the argument singlekey
	% #1 = register
	% #2 = name of the key
	% #3 = command to store the content in
	\cs_if_exist:cTF { __semantex_data_cs_custom_arg_singlekey_#1_\tl_trim_spaces:n{#2}:n }
	{
		\exp_args:NNNo \exp_args:NNo\tl_set:No#3 { \use:c { __semantex_data_cs_custom_arg_singlekey_#1_\tl_trim_spaces:n{#2}:n } { ##1 } }
	}
	{
		\str_if_eq:nVTF { #1 } \g_semantex_class_SemantexBaseObject_register_tl
		{
			\tl_set:Nn #3 {}
		}
		{
			\semantex_arg_singlekey_store:fnN { \semantex_data_parent_get:n { #1 } } { #2 } #3
		}
	}
}

\cs_generate_variant:Nn \semantex_arg_singlekey_store:nnN { fnN }

\cs_new_protected:Npn\semantex_arg_two_valuekey_store:nnN#1#2#3
{
	% Stores the content of the argument valuekey
	% i.e. keys taking a value
	% #1 = register
	% #2 = name of the key
	% #3 = command to store the content in
	\cs_if_exist:cTF { __semantex_data_cs_custom_arg_two_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnn }
	{
		\exp_args:NNNo \exp_args:NNo\tl_set:No#3 { \use:c { __semantex_data_cs_custom_arg_two_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnn } { ##1 } { ##2 } { ##3 } }
	}
	{
		\str_if_eq:nVTF { #1 } \g_semantex_class_SemantexBaseObject_register_tl
		{
			\tl_set:Nn #3 {}
		}
		{
			\semantex_arg_two_valuekey_store:fnN { \semantex_data_parent_get:n { #1 } } { #2 } #3
		}
	}
}

\cs_generate_variant:Nn \semantex_arg_two_valuekey_store:nnN { fnN }

\cs_new_protected:Npn\semantex_arg_three_valuekey_store:nnN#1#2#3
{
	% Stores the content of the argument valuekey
	% i.e. keys taking a value
	% #1 = register
	% #2 = name of the key
	% #3 = command to store the content in
	\cs_if_exist:cTF { __semantex_data_cs_custom_arg_three_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnn }
	{
		\exp_args:NNNo \exp_args:NNo\tl_set:No#3 { \use:c { __semantex_data_cs_custom_arg_three_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnn } { ##1 } { ##2 } { ##3 } { ##4 } }
	}
	{
		\str_if_eq:nVTF { #1 } \g_semantex_class_SemantexBaseObject_register_tl
		{
			\tl_set:Nn #3 {}
		}
		{
			\semantex_arg_three_valuekey_store:fnN { \semantex_data_parent_get:n { #1 } } { #2 } #3
		}
	}
}

\cs_generate_variant:Nn \semantex_arg_three_valuekey_store:nnN { fnN }

\cs_new_protected:Npn\semantex_arg_four_valuekey_store:nnN#1#2#3
{
	% Stores the content of the argument valuekey
	% i.e. keys taking a value
	% #1 = register
	% #2 = name of the key
	% #3 = command to store the content in
	\cs_if_exist:cTF { __semantex_data_cs_custom_arg_four_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnn }
	{
		\exp_args:NNNo \exp_args:NNo\tl_set:No#3 { \use:c { __semantex_data_cs_custom_arg_four_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnn } { ##1 } { ##2 } { ##3 } { ##4 } { ##5 } }
	}
	{
		\str_if_eq:nVTF { #1 } \g_semantex_class_SemantexBaseObject_register_tl
		{
			\tl_set:Nn #3 {}
		}
		{
			\semantex_arg_four_valuekey_store:fnN { \semantex_data_parent_get:n { #1 } } { #2 } #3
		}
	}
}

\cs_generate_variant:Nn \semantex_arg_four_valuekey_store:nnN { fnN }

\cs_new_protected:Npn\semantex_arg_five_valuekey_store:nnN#1#2#3
{
	% Stores the content of the argument valuekey
	% i.e. keys taking a value
	% #1 = register
	% #2 = name of the key
	% #3 = command to store the content in
	\cs_if_exist:cTF { __semantex_data_cs_custom_arg_five_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnn }
	{
		\exp_args:NNNo \exp_args:NNo\tl_set:No#3 { \use:c { __semantex_data_cs_custom_arg_five_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnn } { ##1 } { ##2 } { ##3 } { ##4 } { ##5 } { ##6 } }
	}
	{
		\str_if_eq:nVTF { #1 } \g_semantex_class_SemantexBaseObject_register_tl
		{
			\tl_set:Nn #3 {}
		}
		{
			\semantex_arg_five_valuekey_store:fnN { \semantex_data_parent_get:n { #1 } } { #2 } #3
		}
	}
}

\cs_generate_variant:Nn \semantex_arg_five_valuekey_store:nnN { fnN }

\cs_new_protected:Npn\semantex_arg_six_valuekey_store:nnN#1#2#3
{
	% Stores the content of the argument valuekey
	% i.e. keys taking a value
	% #1 = register
	% #2 = name of the key
	% #3 = command to store the content in
	\cs_if_exist:cTF { __semantex_data_cs_custom_arg_six_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnn }
	{
		\exp_args:NNNo \exp_args:NNo\tl_set:No#3 { \use:c { __semantex_data_cs_custom_arg_six_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnn } { ##1 } { ##2 } { ##3 } { ##4 } { ##5 } { ##6 } { ##7 } }
	}
	{
		\str_if_eq:nVTF { #1 } \g_semantex_class_SemantexBaseObject_register_tl
		{
			\tl_set:Nn #3 {}
		}
		{
			\semantex_arg_six_valuekey_store:fnN { \semantex_data_parent_get:n { #1 } } { #2 } #3
		}
	}
}

\cs_generate_variant:Nn \semantex_arg_six_valuekey_store:nnN { fnN }

\cs_new_protected:Npn\semantex_arg_seven_valuekey_store:nnN#1#2#3
{
	% Stores the content of the argument valuekey
	% i.e. keys taking a value
	% #1 = register
	% #2 = name of the key
	% #3 = command to store the content in
	\cs_if_exist:cTF { __semantex_data_cs_custom_arg_seven_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnnn }
	{
		\exp_args:NNNo \exp_args:NNo\tl_set:No#3 { \use:c { __semantex_data_cs_custom_arg_seven_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnnn } { ##1 } { ##2 } { ##3 } { ##4 } { ##5 } { ##6 } { ##7 } { ##8 } }
	}
	{
		\str_if_eq:nVTF { #1 } \g_semantex_class_SemantexBaseObject_register_tl
		{
			\tl_set:Nn #3 {}
		}
		{
			\semantex_arg_seven_valuekey_store:fnN { \semantex_data_parent_get:n { #1 } } { #2 } #3
		}
	}
}

\cs_generate_variant:Nn \semantex_arg_seven_valuekey_store:nnN { fnN }

\cs_new_protected:Npn\semantex_arg_eight_valuekey_store:nnN#1#2#3
{
	% Stores the content of the argument valuekey
	% i.e. keys taking a value
	% #1 = register
	% #2 = name of the key
	% #3 = command to store the content in
	\cs_if_exist:cTF { __semantex_data_cs_custom_arg_eight_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnnnn }
	{
		\exp_args:NNNo \exp_args:NNo\tl_set:No#3 { \use:c { __semantex_data_cs_custom_arg_eight_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnnnn } { ##1 } { ##2 } { ##3 } { ##4 } { ##5 } { ##6 } { ##7 } { ##8 } { ##9 } }
	}
	{
		\str_if_eq:nVTF { #1 } \g_semantex_class_SemantexBaseObject_register_tl
		{
			\tl_set:Nn #3 {}
		}
		{
			\semantex_arg_eight_valuekey_store:fnN { \semantex_data_parent_get:n { #1 } } { #2 } #3
		}
	}
}

\cs_generate_variant:Nn \semantex_arg_eight_valuekey_store:nnN { fnN }

\cs_new_protected:Npn\semantex_arg_nine_valuekey_store:nnN#1#2#3
{
	% Stores the content of the argument valuekey
	% i.e. keys taking a value
	% #1 = register
	% #2 = name of the key
	% #3 = command to store the content in
	\cs_if_exist:cTF { __semantex_data_cs_custom_arg_nine_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnnnn }
	{
		\exp_args:NNNo \exp_args:NNo\tl_set:No#3 { \use:c { __semantex_data_cs_custom_arg_nine_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnnnn } { ##1 } { ##2 } { ##3 } { ##4 } { ##5 } { ##6 } { ##7 } { ##8 } { ##9 } }
	}
	{
		\str_if_eq:nVTF { #1 } \g_semantex_class_SemantexBaseObject_register_tl
		{
			\tl_set:Nn #3 {}
		}
		{
			\semantex_arg_nine_valuekey_store:fnN { \semantex_data_parent_get:n { #1 } } { #2 } #3
		}
	}
}

\cs_generate_variant:Nn \semantex_arg_nine_valuekey_store:nnN { fnN }

% NOW SOME KEYS FOR DEFINING NEW KEYS:

% First, we define the central commands for preprocessing keys

\cs_generate_variant:Nn \semantex_keyval_parse:NNn { NNo }

\cs_new_protected:Npn\semantex_preprocess_keys:nN#1#2
{
	\cs_set:Npn\l__semantex_preprocess_singlekey_temp_cs:n##1
	{
		\__semantex_preprocess_singlekey:nnN { ####1 } { ##1 } #2
	}
	\cs_set:Npn\l__semantex_preprocess_valuekey_temp_cs:nn##1##2
	{
		\__semantex_preprocess_valuekey:nnnN { ####1 } { ##1 } { ##2 } #2
	}
	\semantex_keyval_parse:NNn
		\l__semantex_preprocess_singlekey_temp_cs:n
		\l__semantex_preprocess_valuekey_temp_cs:nn
		{ #1 }
}

\cs_generate_variant:Nn \semantex_preprocess_keys:nN { oN }

\cs_new_protected:Npn\__semantex_preprocess_singlekey:nnN#1#2#3
{
	\tl_put_right:Nn#3
	{
		\semantex_singlekey:nn { #1 } { #2 }
	}
}

\cs_new_protected:Npn\__semantex_preprocess_valuekey:nnnN#1#2#3#4
{
	\str_case:nnF { #2 }
	{
		{ execute }{
			\tl_put_right:Nn #4 { #3 }
		}
		{ set~keys }{
			\semantex_preprocess_keys:nN { #3 } #4
		}
		{ keys~set }{
			\semantex_preprocess_keys:nN { #3 } #4
		}
		{ set~keys~x }{
			\semantex_preprocess_keys_x:nN { #3 } #4
		}
		{ keys~set~x }{
			\semantex_preprocess_keys_x:nN { #3 } #4
		}
		{ set~arg~keys }{
			\semantex_preprocess_arg_keys:nN { #3 } #4
		}
		{ arg~keys~set }{
			\semantex_preprocess_arg_keys:nN { #3 } #4
		}
		{ set~arg~keys~x }{
			\semantex_preprocess_arg_keys_x:nN { #3 } #4
		}
		{ arg~keys~set~x }{
			\semantex_preprocess_arg_keys_x:nN { #3 } #4
		}
		{ set~arg~single~keys }{
			\semantex_preprocess_arg_singlekeys:nN { #3 } #4
		}
		{ arg~single~keys~set }{
			\semantex_preprocess_arg_singlekeys:nN { #3 } #4
		}
		{ set~arg~single~keys~x }{
			\semantex_preprocess_arg_singlekeys_x:nN { #3 } #4
		}
		{ arg~single~keys~set~x }{
			\semantex_preprocess_arg_singlekeys_x:nN { #3 } #4
		}
		{ parse~options }{
			\tl_put_right:Nn#4
			{
				\semantex_append_singlekey_with_raw_code:nnn { #1 } { parse~code }
			}
			\group_begin:
				\tl_set:Nn\l__semantex_preprocess_valuekey_keys_pre_temp_tl {}
				\semantex_preprocess_keys:nN { #3 } \l__semantex_preprocess_valuekey_keys_pre_temp_tl
				\cs_set:Npo\l__semantex_preprocess_valuekey_keys_temp_cs:nnnnnnnnn##1##2##3##4##5##6##7##8##9
				{
					\l__semantex_preprocess_valuekey_keys_pre_temp_tl
				}
				\tl_set:No\l__semantex_preprocess_valuekey_keys_temp_tl
				{
					\l__semantex_preprocess_valuekey_keys_temp_cs:nnnnnnnnn { ###1 } { ##2 } { ##3 } { ##4 } { ##5 } { ##6 } { ##7 } { ##8 } { ##9 }
				}
			\exp_args:NNNx
			\group_end:
			\tl_put_right:Nn#4
			{
				{ \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl }
			}
		}
		{ pre~parse~options }{
			\tl_put_right:Nn#4
			{
				\semantex_prepend_singlekey_with_raw_code:nnn { #1 } { parse~code }
			}
			\group_begin:
				\tl_set:Nn\l__semantex_preprocess_valuekey_keys_pre_temp_tl {}
				\semantex_preprocess_keys:nN { #3 } \l__semantex_preprocess_valuekey_keys_pre_temp_tl
				\cs_set:Npo\l__semantex_preprocess_valuekey_keys_temp_cs:nnnnnnnnn##1##2##3##4##5##6##7##8##9
				{
					\l__semantex_preprocess_valuekey_keys_pre_temp_tl
				}
				\tl_set:No\l__semantex_preprocess_valuekey_keys_temp_tl
				{
					\l__semantex_preprocess_valuekey_keys_temp_cs:nnnnnnnnn { ###1 } { ##2 } { ##3 } { ##4 } { ##5 } { ##6 } { ##7 } { ##8 } { ##9 }
				}
			\exp_args:NNNx
			\group_end:
			\tl_put_right:Nn#4
			{
				{ \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl }
			}
		}
		{ output~options }{
			\tl_put_right:Nn#4
			{
				\semantex_add_raw_code_to_output_options:nn { #1 }
			}
			\group_begin:
				\tl_set:Nn\l__semantex_preprocess_valuekey_keys_pre_temp_tl {}
				\semantex_preprocess_keys:nN { #3 } \l__semantex_preprocess_valuekey_keys_pre_temp_tl
				\cs_set:Npo\l__semantex_preprocess_valuekey_keys_temp_cs:nnnnnnnnn##1##2##3##4##5##6##7##8##9
				{
					\l__semantex_preprocess_valuekey_keys_pre_temp_tl
				}
				\tl_set:No\l__semantex_preprocess_valuekey_keys_temp_tl
				{
					\l__semantex_preprocess_valuekey_keys_temp_cs:nnnnnnnnn { ###1 } { ##2 } { ##3 } { ##4 } { ##5 } { ##6 } { ##7 } { ##8 } { ##9 }
				}
			\exp_args:NNNx
			\group_end:
			\tl_put_right:Nn#4
			{
				{ \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl }
			}
		}
		{ pre~output~options }{
			\tl_put_right:Nn#4
			{
				\semantex_add_raw_code_to_the_left_of_output_options:nn { #1 }
			}
			\group_begin:
				\tl_set:Nn\l__semantex_preprocess_valuekey_keys_pre_temp_tl {}
				\semantex_preprocess_keys:nN { #3 } \l__semantex_preprocess_valuekey_keys_pre_temp_tl
				\cs_set:Npo\l__semantex_preprocess_valuekey_keys_temp_cs:nnnnnnnnn##1##2##3##4##5##6##7##8##9
				{
					\l__semantex_preprocess_valuekey_keys_pre_temp_tl
				}
				\tl_set:No\l__semantex_preprocess_valuekey_keys_temp_tl
				{
					\l__semantex_preprocess_valuekey_keys_temp_cs:nnnnnnnnn { ###1 } { ##2 } { ##3 } { ##4 } { ##5 } { ##6 } { ##7 } { ##8 } { ##9 }
				}
			\exp_args:NNNx
			\group_end:
			\tl_put_right:Nn#4
			{
				{ \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl }
			}
		}
		{ bool~if~TF }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_bool_if_TF_temp_cs:nTF##1##2##3
			{
				\tl_put_right:Nn#4
				{
					\semantex_data_bool_get:nnTF { ####1 } { \tl_trim_spaces:n { ##1 } }
				}
				\group_begin:
					\tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {}
					\semantex_preprocess_keys:nN { ##2 } \l__semantex_preprocess_valuekey_keys_temp_tl
				\exp_args:NNNx
				\group_end:
				\tl_put_right:Nn#4
				{
					{ \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl }
				}
				\group_begin:
					\tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {}
					\semantex_preprocess_keys:nN { ##3 } \l__semantex_preprocess_valuekey_keys_temp_tl
				\exp_args:NNNx
				\group_end:
				\tl_put_right:Nn#4
				{
					{ \exp_not:V \l__semantex_preprocess_valuekey_keys_temp_tl }
				}
			}
			\l__semantex_preprocess_valuekey_bool_if_TF_temp_cs:nTF #3
		}
		{ bool~if~T }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_bool_if_T_temp_cs:nT##1##2
			{
				\tl_put_right:Nn#4
				{
					\semantex_data_bool_get:nnTF { ####1 } { \tl_trim_spaces:n { ##1 } }
				}
				\group_begin:
					\tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {}
					\semantex_preprocess_keys:nN { ##2 } \l__semantex_preprocess_valuekey_keys_temp_tl
				\exp_args:NNNx
				\group_end:
				\tl_put_right:Nn#4
				{
					{ \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl }
					{ }
				}
			}
			\l__semantex_preprocess_valuekey_bool_if_T_temp_cs:nT #3
		}
		{ bool~if~F }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_bool_if_F_temp_cs:nF##1##2
			{
				\tl_put_right:Nn#4
				{
					\semantex_data_bool_get:nnTF { ####1 } { \tl_trim_spaces:n { ##1 } }
				}
				\group_begin:
					\tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {}
					\semantex_preprocess_keys:nN { ##2 } \l__semantex_preprocess_valuekey_keys_temp_tl
				\exp_args:NNNx
				\group_end:
				\tl_put_right:Nn#4
				{
					{ }
					{ \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl }
				}
			}
			\l__semantex_preprocess_valuekey_bool_if_F_temp_cs:nF #3
		}
		{ if~blank~TF }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_if_blank_TF_temp_cs:nTF##1##2##3
			{
				\tl_put_right:Nn#4
				{
					\tl_if_blank:xTF { ##1 }
				}
				\group_begin:
					\tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {}
					\semantex_preprocess_keys:nN { ##2 } \l__semantex_preprocess_valuekey_keys_temp_tl
				\exp_args:NNNx
				\group_end:
				\tl_put_right:Nn#4
				{
					{ \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl }
				}
				\group_begin:
					\tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {}
					\semantex_preprocess_keys:nN { ##3 } \l__semantex_preprocess_valuekey_keys_temp_tl
				\exp_args:NNNx
				\group_end:
				\tl_put_right:Nn#4
				{
					{ \exp_not:V \l__semantex_preprocess_valuekey_keys_temp_tl }
				}
			}
			\l__semantex_preprocess_valuekey_if_blank_TF_temp_cs:nTF #3
		}
		{ if~blank~T }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_if_blank_T_temp_cs:nT##1##2
			{
				\tl_put_right:Nn#4
				{
					\tl_if_blank:xTF { ##1 }
				}
				\group_begin:
					\tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {}
					\semantex_preprocess_keys:nN { ##2 } \l__semantex_preprocess_valuekey_keys_temp_tl
				\exp_args:NNNx
				\group_end:
				\tl_put_right:Nn#4
				{
					{ \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl }
					{ }
				}
			}
			\l__semantex_preprocess_valuekey_if_blank_T_temp_cs:nT #3
		}
		{ if~blank~F }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_if_blank_F_temp_cs:nF##1##2
			{
				\tl_put_right:Nn#4
				{
					\tl_if_blank:xTF { ##1 }
				}
				\group_begin:
					\tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {}
					\semantex_preprocess_keys:nN { ##2 } \l__semantex_preprocess_valuekey_keys_temp_tl
				\exp_args:NNNx
				\group_end:
				\tl_put_right:Nn#4
				{
					{ }
					{ \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl }
				}
			}
			\l__semantex_preprocess_valuekey_if_blank_F_temp_cs:nF #3
		}
		{ str~if~eq~TF }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_str_if_eq_TF_temp_cs:nnTF##1##2##3##4
			{
				\tl_put_right:Nn#4
				{
					\str_if_eq:xxTF { ##1 } { ##2 }
				}
				\group_begin:
					\tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {}
					\semantex_preprocess_keys:nN { ##3 } \l__semantex_preprocess_valuekey_keys_temp_tl
				\exp_args:NNNx
				\group_end:
				\tl_put_right:Nn#4
				{
					{ \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl }
				}
				\group_begin:
					\tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {}
					\semantex_preprocess_keys:nN { ##4 } \l__semantex_preprocess_valuekey_keys_temp_tl
				\exp_args:NNNx
				\group_end:
				\tl_put_right:Nn#4
				{
					{ \exp_not:V \l__semantex_preprocess_valuekey_keys_temp_tl }
				}
			}
			\l__semantex_preprocess_valuekey_str_if_eq_TF_temp_cs:nnTF #3
		}
		{ str~if~eq~T }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_str_if_eq_T_temp_cs:nnT##1##2##3
			{
				\tl_put_right:Nn#4
				{
					\str_if_eq:xxTF { ##1 } { ##2 }
				}
				\group_begin:
					\tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {}
					\semantex_preprocess_keys:nN { ##3 } \l__semantex_preprocess_valuekey_keys_temp_tl
				\exp_args:NNNx
				\group_end:
				\tl_put_right:Nn#4
				{
					{ \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl }
					{ }
				}
			}
			\l__semantex_preprocess_valuekey_str_if_eq_T_temp_cs:nnT #3
		}
		{ str~if~eq~F }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_str_if_eq_F_temp_cs:nnF##1##2##3
			{
				\tl_put_right:Nn#4
				{
					\str_if_eq:xxTF { ##1 } { ##2 }
				}
				\group_begin:
					\tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {}
					\semantex_preprocess_keys:nN { ##3 } \l__semantex_preprocess_valuekey_keys_temp_tl
				\exp_args:NNNx
				\group_end:
				\tl_put_right:Nn#4
				{
					{ }
					{ \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl }
				}
			}
			\l__semantex_preprocess_valuekey_str_if_eq_F_temp_cs:nnF #3
		}
		{ int~if~greater~TF }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_int_if_greater_TF_temp_cs:nnTF##1##2##3##4
			{
				\tl_put_right:Nn#4
				{
					\int_compare:nNnTF { ##1 } > { ##2 }
				}
				\group_begin:
					\tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {}
					\semantex_preprocess_keys:nN { ##3 } \l__semantex_preprocess_valuekey_keys_temp_tl
				\exp_args:NNNx
				\group_end:
				\tl_put_right:Nn#4
				{
					{ \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl }
				}
				\group_begin:
					\tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {}
					\semantex_preprocess_keys:nN { ##4 } \l__semantex_preprocess_valuekey_keys_temp_tl
				\exp_args:NNNx
				\group_end:
				\tl_put_right:Nn#4
				{
					{ \exp_not:V \l__semantex_preprocess_valuekey_keys_temp_tl }
				}
			}
			\l__semantex_preprocess_valuekey_int_if_greater_TF_temp_cs:nnTF #3
		}
		{ int~if~greater~T }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_int_if_greater_T_temp_cs:nnT##1##2##3
			{
				\tl_put_right:Nn#4
				{
					\int_compare:nNnTF { ##1 } > { ##2 }
				}
				\group_begin:
					\tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {}
					\semantex_preprocess_keys:nN { ##3 } \l__semantex_preprocess_valuekey_keys_temp_tl
				\exp_args:NNNx
				\group_end:
				\tl_put_right:Nn#4
				{
					{ \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl }
					{ }
				}
			}
			\l__semantex_preprocess_valuekey_int_if_greater_T_temp_cs:nnT #3
		}
		{ int~if~greater~F }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_int_if_greater_F_temp_cs:nnF##1##2##3
			{
				\tl_put_right:Nn#4
				{
					\int_compare:nNnTF { ##1 } > { ##2 }
				}
				\group_begin:
					\tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {}
					\semantex_preprocess_keys:nN { ##3 } \l__semantex_preprocess_valuekey_keys_temp_tl
				\exp_args:NNNx
				\group_end:
				\tl_put_right:Nn#4
				{
					{ }
					{ \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl }
				}
			}
			\l__semantex_preprocess_valuekey_int_if_greater_F_temp_cs:nnF #3
		}
		{ int~if~eq~TF }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_int_if_eq_TF_temp_cs:nnTF##1##2##3##4
			{
				\tl_put_right:Nn#4
				{
					\int_compare:nNnTF { ##1 } = { ##2 }
				}
				\group_begin:
					\tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {}
					\semantex_preprocess_keys:nN { ##3 } \l__semantex_preprocess_valuekey_keys_temp_tl
				\exp_args:NNNx
				\group_end:
				\tl_put_right:Nn#4
				{
					{ \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl }
				}
				\group_begin:
					\tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {}
					\semantex_preprocess_keys:nN { ##4 } \l__semantex_preprocess_valuekey_keys_temp_tl
				\exp_args:NNNx
				\group_end:
				\tl_put_right:Nn#4
				{
					{ \exp_not:V \l__semantex_preprocess_valuekey_keys_temp_tl }
				}
			}
			\l__semantex_preprocess_valuekey_int_if_eq_TF_temp_cs:nnTF #3
		}
		{ int~if~eq~T }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_int_if_eq_T_temp_cs:nnT##1##2##3
			{
				\tl_put_right:Nn#4
				{
					\int_compare:nNnTF { ##1 } = { ##2 }
				}
				\group_begin:
					\tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {}
					\semantex_preprocess_keys:nN { ##3 } \l__semantex_preprocess_valuekey_keys_temp_tl
				\exp_args:NNNx
				\group_end:
				\tl_put_right:Nn#4
				{
					{ \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl }
					{ }
				}
			}
			\l__semantex_preprocess_valuekey_int_if_eq_T_temp_cs:nnT #3
		}
		{ int~if~eq~F }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_int_if_eq_F_temp_cs:nnF##1##2##3
			{
				\tl_put_right:Nn#4
				{
					\int_compare:nNnTF { ##1 } = { ##2 }
				}
				\group_begin:
					\tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {}
					\semantex_preprocess_keys:nN { ##3 } \l__semantex_preprocess_valuekey_keys_temp_tl
				\exp_args:NNNx
				\group_end:
				\tl_put_right:Nn#4
				{
					{ }
					{ \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl }
				}
			}
			\l__semantex_preprocess_valuekey_int_if_eq_F_temp_cs:nnF #3
		}
		{ int~if~less~TF }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_int_if_less_TF_temp_cs:nnTF##1##2##3##4
			{
				\tl_put_right:Nn#4
				{
					\int_compare:nNnTF { ##1 } < { ##2 }
				}
				\group_begin:
					\tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {}
					\semantex_preprocess_keys:nN { ##3 } \l__semantex_preprocess_valuekey_keys_temp_tl
				\exp_args:NNNx
				\group_end:
				\tl_put_right:Nn#4
				{
					{ \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl }
				}
				\group_begin:
					\tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {}
					\semantex_preprocess_keys:nN { ##4 } \l__semantex_preprocess_valuekey_keys_temp_tl
				\exp_args:NNNx
				\group_end:
				\tl_put_right:Nn#4
				{
					{ \exp_not:V \l__semantex_preprocess_valuekey_keys_temp_tl }
				}
			}
			\l__semantex_preprocess_valuekey_int_if_less_TF_temp_cs:nnTF #3
		}
		{ int~if~less~T }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_int_if_less_T_temp_cs:nnT##1##2##3
			{
				\tl_put_right:Nn#4
				{
					\int_compare:nNnTF { ##1 } < { ##2 }
				}
				\group_begin:
					\tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {}
					\semantex_preprocess_keys:nN { ##3 } \l__semantex_preprocess_valuekey_keys_temp_tl
				\exp_args:NNNx
				\group_end:
				\tl_put_right:Nn#4
				{
					{ \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl }
					{ }
				}
			}
			\l__semantex_preprocess_valuekey_int_if_less_T_temp_cs:nnT #3
		}
		{ int~if~less~F }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_int_if_less_F_temp_cs:nnF##1##2##3
			{
				\tl_put_right:Nn#4
				{
					\int_compare:nNnTF { ##1 } < { ##2 }
				}
				\group_begin:
					\tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {}
					\semantex_preprocess_keys:nN { ##3 } \l__semantex_preprocess_valuekey_keys_temp_tl
				\exp_args:NNNx
				\group_end:
				\tl_put_right:Nn#4
				{
					{ }
					{ \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl }
				}
			}
			\l__semantex_preprocess_valuekey_int_if_less_F_temp_cs:nnF #3
		}
	}
	{
		\tl_put_right:Nn#4
		{
			\semantex_valuekey:nnn { #1 } { #2 } { #3 }
		}
	}
}

% The x version:

\cs_new_protected:Npn\semantex_preprocess_keys_x:nN#1#2
{
	\cs_set:Npn\l__semantex_preprocess_singlekey_x_temp_cs:n##1
	{
		\__semantex_preprocess_singlekey_x:nnN { ####1 } { ##1 } #2
	}
	\cs_set:Npn\l__semantex_preprocess_valuekey_x_temp_cs:nn##1##2
	{
		\__semantex_preprocess_valuekey_x:nnnN { ####1 } { ##1 } { ##2 } #2
	}
	\semantex_keyval_parse:NNn
		\l__semantex_preprocess_singlekey_x_temp_cs:n
		\l__semantex_preprocess_valuekey_x_temp_cs:nn
		{ #1 }
}

\cs_new_protected:Npn\__semantex_preprocess_singlekey_x:nnN#1#2#3
{
	\tl_put_right:Nn#3
	{
		\semantex_singlekey_x:nn { #1 } { #2 }
	}
}

\cs_new_protected:Npn\__semantex_preprocess_valuekey_x:nnnN#1#2#3#4
{
	\str_case:nnF { #2 }
	{
		{ execute } {
			\tl_put_right:Nn#4
			{
				#3
			}
		}
		{ set~keys }{
			\semantex_preprocess_keys:nN { #3 } #4
		}
		{ keys~set }{
			\semantex_preprocess_keys:nN { #3 } #4
		}
		{ set~keys~x }{
			\semantex_preprocess_keys_x:nN { #3 } #4
		}
		{ keys~set~x }{
			\semantex_preprocess_keys_x:nN { #3 } #4
		}
		{ set~arg~keys }{
			\semantex_preprocess_arg_keys:nN { #3 } #4
		}
		{ arg~keys~set }{
			\semantex_preprocess_arg_keys:nN { #3 } #4
		}
		{ set~arg~keys~x }{
			\semantex_preprocess_arg_keys_x:nN { #3 } #4
		}
		{ arg~keys~set~x }{
			\semantex_preprocess_arg_keys_x:nN { #3 } #4
		}
		{ set~arg~single~keys }{
			\semantex_preprocess_arg_singlekeys:nN { #3 } #4
		}
		{ arg~single~keys~set }{
			\semantex_preprocess_arg_singlekeys:nN { #3 } #4
		}
		{ set~arg~single~keys~x }{
			\semantex_preprocess_arg_singlekeys_x:nN { #3 } #4
		}
		{ arg~single~keys~set~x }{
			\semantex_preprocess_arg_singlekeys_x:nN { #3 } #4
		}
		{ parse~options }{
			\tl_put_right:Nn#4
			{
				\semantex_append_singlekey_with_raw_code:nnn { #1 } { parse~code }
			}
			\group_begin:
				\tl_set:Nn\l__semantex_preprocess_valuekey_keys_pre_temp_tl {}
				\semantex_preprocess_keys:nN { #3 } \l__semantex_preprocess_valuekey_keys_pre_temp_tl
				\cs_set:Npo\l__semantex_preprocess_valuekey_keys_temp_cs:nnnnnnnnn##1##2##3##4##5##6##7##8##9
				{
					\l__semantex_preprocess_valuekey_keys_pre_temp_tl
				}
				\tl_set:No\l__semantex_preprocess_valuekey_keys_temp_tl
				{
					\l__semantex_preprocess_valuekey_keys_temp_cs:nnnnnnnnn { ###1 } { ##2 } { ##3 } { ##4 } { ##5 } { ##6 } { ##7 } { ##8 } { ##9 }
				}
			\exp_args:NNNx
			\group_end:
			\tl_put_right:Nn#4
			{
				{ \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl }
			}
		}
		{ pre~parse~options }{
			\tl_put_right:Nn#4
			{
				\semantex_prepend_singlekey_with_raw_code:nnn { #1 } { parse~code }
			}
			\group_begin:
				\tl_set:Nn\l__semantex_preprocess_valuekey_keys_pre_temp_tl {}
				\semantex_preprocess_keys:nN { #3 } \l__semantex_preprocess_valuekey_keys_pre_temp_tl
				\cs_set:Npo\l__semantex_preprocess_valuekey_keys_temp_cs:nnnnnnnnn##1##2##3##4##5##6##7##8##9
				{
					\l__semantex_preprocess_valuekey_keys_pre_temp_tl
				}
				\tl_set:No\l__semantex_preprocess_valuekey_keys_temp_tl
				{
					\l__semantex_preprocess_valuekey_keys_temp_cs:nnnnnnnnn { ###1 } { ##2 } { ##3 } { ##4 } { ##5 } { ##6 } { ##7 } { ##8 } { ##9 }
				}
			\exp_args:NNNx
			\group_end:
			\tl_put_right:Nn#4
			{
				{ \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl }
			}
		}
		{ output~options }{
			\tl_put_right:Nn#4
			{
				\semantex_add_raw_code_to_output_options:nn { #1 }
			}
			\group_begin:
				\tl_set:Nn\l__semantex_preprocess_valuekey_keys_pre_temp_tl {}
				\semantex_preprocess_keys_x:nN { #3 } \l__semantex_preprocess_valuekey_keys_pre_temp_tl
				\cs_set:Npo\l__semantex_preprocess_valuekey_keys_temp_cs:nnnnnnnnn##1##2##3##4##5##6##7##8##9
				{
					\l__semantex_preprocess_valuekey_keys_pre_temp_tl
				}
				\tl_set:No\l__semantex_preprocess_valuekey_keys_temp_tl
				{
					\l__semantex_preprocess_valuekey_keys_temp_cs:nnnnnnnnn { ###1 } { ##2 } { ##3 } { ##4 } { ##5 } { ##6 } { ##7 } { ##8 } { ##9 }
				}
			\exp_args:NNNx
			\group_end:
			\tl_put_right:Nn#4
			{
				{ \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl }
			}
		}
		{ pre~output~options }{
			\tl_put_right:Nn#4
			{
				\semantex_add_raw_code_to_the_left_of_output_options:nn { #1 }
			}
			\group_begin:
				\tl_set:Nn\l__semantex_preprocess_valuekey_keys_pre_temp_tl {}
				\semantex_preprocess_keys_x:nN { #3 } \l__semantex_preprocess_valuekey_keys_pre_temp_tl
				\cs_set:Npo\l__semantex_preprocess_valuekey_keys_temp_cs:nnnnnnnnn##1##2##3##4##5##6##7##8##9
				{
					\l__semantex_preprocess_valuekey_keys_pre_temp_tl
				}
				\tl_set:No\l__semantex_preprocess_valuekey_keys_temp_tl
				{
					\l__semantex_preprocess_valuekey_keys_temp_cs:nnnnnnnnn { ###1 } { ##2 } { ##3 } { ##4 } { ##5 } { ##6 } { ##7 } { ##8 } { ##9 }
				}
			\exp_args:NNNx
			\group_end:
			\tl_put_right:Nn#4
			{
				{ \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl }
			}
		}
		{ bool~if~TF }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_bool_if_TF_temp_cs:nTF##1##2##3
			{
				\tl_put_right:Nn#4
				{
					\semantex_data_bool_get:nnTF { ####1 } { \tl_trim_spaces:n { ##1 } }
				}
				\group_begin:
					\tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {}
					\semantex_preprocess_keys_x:nN { ##2 } \l__semantex_preprocess_valuekey_keys_temp_tl
				\exp_args:NNNx
				\group_end:
				\tl_put_right:Nn#4
				{
					{ \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl }
				}
				\group_begin:
					\tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {}
					\semantex_preprocess_keys_x:nN { ##3 } \l__semantex_preprocess_valuekey_keys_temp_tl
				\exp_args:NNNx
				\group_end:
				\tl_put_right:Nn#4
				{
					{ \exp_not:V \l__semantex_preprocess_valuekey_keys_temp_tl }
				}
			}
			\l__semantex_preprocess_valuekey_bool_if_TF_temp_cs:nTF #3
		}
		{ bool~if~T }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_bool_if_T_temp_cs:nT##1##2
			{
				\tl_put_right:Nn#4
				{
					\semantex_data_bool_get:nnTF { ####1 } { \tl_trim_spaces:n { ##1 } }
				}
				\group_begin:
					\tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {}
					\semantex_preprocess_keys_x:nN { ##2 } \l__semantex_preprocess_valuekey_keys_temp_tl
				\exp_args:NNNx
				\group_end:
				\tl_put_right:Nn#4
				{
					{ \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl }
					{ }
				}
			}
			\l__semantex_preprocess_valuekey_bool_if_T_temp_cs:nT #3
		}
		{ bool~if~F }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_bool_if_F_temp_cs:nF##1##2
			{
				\tl_put_right:Nn#4
				{
					\semantex_data_bool_get:nnTF { ####1 } { \tl_trim_spaces:n { ##1 } }
				}
				\group_begin:
					\tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {}
					\semantex_preprocess_keys_x:nN { ##2 } \l__semantex_preprocess_valuekey_keys_temp_tl
				\exp_args:NNNx
				\group_end:
				\tl_put_right:Nn#4
				{
					{ }
					{ \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl }
				}
			}
			\l__semantex_preprocess_valuekey_bool_if_F_temp_cs:nF #3
		}
		{ if~blank~TF }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_if_blank_TF_temp_cs:nTF##1##2##3
			{
				\tl_put_right:Nn#4
				{
					\tl_if_blank:xTF { ##1 }
				}
				\group_begin:
					\tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {}
					\semantex_preprocess_keys_x:nN { ##2 } \l__semantex_preprocess_valuekey_keys_temp_tl
				\exp_args:NNNx
				\group_end:
				\tl_put_right:Nn#4
				{
					{ \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl }
				}
				\group_begin:
					\tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {}
					\semantex_preprocess_keys_x:nN { ##3 } \l__semantex_preprocess_valuekey_keys_temp_tl
				\exp_args:NNNx
				\group_end:
				\tl_put_right:Nn#4
				{
					{ \exp_not:V \l__semantex_preprocess_valuekey_keys_temp_tl }
				}
			}
			\l__semantex_preprocess_valuekey_if_blank_TF_temp_cs:nTF #3
		}
		{ if~blank~T }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_if_blank_T_temp_cs:nT##1##2
			{
				\tl_put_right:Nn#4
				{
					\tl_if_blank:xTF { ##1 }
				}
				\group_begin:
					\tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {}
					\semantex_preprocess_keys_x:nN { ##2 } \l__semantex_preprocess_valuekey_keys_temp_tl
				\exp_args:NNNx
				\group_end:
				\tl_put_right:Nn#4
				{
					{ \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl }
					{ }
				}
			}
			\l__semantex_preprocess_valuekey_if_blank_T_temp_cs:nT #3
		}
		{ if~blank~F }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_if_blank_F_temp_cs:nF##1##2
			{
				\tl_put_right:Nn#4
				{
					\tl_if_blank:xTF { ##1 }
				}
				\group_begin:
					\tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {}
					\semantex_preprocess_keys_x:nN { ##2 } \l__semantex_preprocess_valuekey_keys_temp_tl
				\exp_args:NNNx
				\group_end:
				\tl_put_right:Nn#4
				{
					{ }
					{ \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl }
				}
			}
			\l__semantex_preprocess_valuekey_if_blank_F_temp_cs:nF #3
		}
		{ str~if~eq~TF }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_str_if_eq_TF_temp_cs:nnTF##1##2##3##4
			{
				\tl_put_right:Nn#4
				{
					\str_if_eq:xxTF { ##1 } { ##2 }
				}
				\group_begin:
					\tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {}
					\semantex_preprocess_keys_x:nN { ##3 } \l__semantex_preprocess_valuekey_keys_temp_tl
				\exp_args:NNNx
				\group_end:
				\tl_put_right:Nn#4
				{
					{ \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl }
				}
				\group_begin:
					\tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {}
					\semantex_preprocess_keys_x:nN { ##4 } \l__semantex_preprocess_valuekey_keys_temp_tl
				\exp_args:NNNx
				\group_end:
				\tl_put_right:Nn#4
				{
					{ \exp_not:V \l__semantex_preprocess_valuekey_keys_temp_tl }
				}
			}
			\l__semantex_preprocess_valuekey_str_if_eq_TF_temp_cs:nnTF #3
		}
		{ str~if~eq~T }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_str_if_eq_T_temp_cs:nnT##1##2##3
			{
				\tl_put_right:Nn#4
				{
					\str_if_eq:xxTF { ##1 } { ##2 }
				}
				\group_begin:
					\tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {}
					\semantex_preprocess_keys_x:nN { ##3 } \l__semantex_preprocess_valuekey_keys_temp_tl
				\exp_args:NNNx
				\group_end:
				\tl_put_right:Nn#4
				{
					{ \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl }
					{ }
				}
			}
			\l__semantex_preprocess_valuekey_str_if_eq_T_temp_cs:nnT #3
		}
		{ str~if~eq~F }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_str_if_eq_F_temp_cs:nnF##1##2##3
			{
				\tl_put_right:Nn#4
				{
					\str_if_eq:xxTF { ##1 } { ##2 }
				}
				\group_begin:
					\tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {}
					\semantex_preprocess_keys_x:nN { ##3 } \l__semantex_preprocess_valuekey_keys_temp_tl
				\exp_args:NNNx
				\group_end:
				\tl_put_right:Nn#4
				{
					{ }
					{ \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl }
				}
			}
			\l__semantex_preprocess_valuekey_str_if_eq_F_temp_cs:nnF #3
		}
		{ int~if~greater~TF }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_int_if_greater_TF_temp_cs:nnTF##1##2##3##4
			{
				\tl_put_right:Nn#4
				{
					\int_compare:nNnTF { ##1 } > { ##2 }
				}
				\group_begin:
					\tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {}
					\semantex_preprocess_keys_x:nN { ##3 } \l__semantex_preprocess_valuekey_keys_temp_tl
				\exp_args:NNNx
				\group_end:
				\tl_put_right:Nn#4
				{
					{ \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl }
				}
				\group_begin:
					\tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {}
					\semantex_preprocess_keys_x:nN { ##4 } \l__semantex_preprocess_valuekey_keys_temp_tl
				\exp_args:NNNx
				\group_end:
				\tl_put_right:Nn#4
				{
					{ \exp_not:V \l__semantex_preprocess_valuekey_keys_temp_tl }
				}
			}
			\l__semantex_preprocess_valuekey_int_if_greater_TF_temp_cs:nnTF #3
		}
		{ int~if~greater~T }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_int_if_greater_T_temp_cs:nnT##1##2##3
			{
				\tl_put_right:Nn#4
				{
					\int_compare:nNnTF { ##1 } > { ##2 }
				}
				\group_begin:
					\tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {}
					\semantex_preprocess_keys_x:nN { ##3 } \l__semantex_preprocess_valuekey_keys_temp_tl
				\exp_args:NNNx
				\group_end:
				\tl_put_right:Nn#4
				{
					{ \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl }
					{ }
				}
			}
			\l__semantex_preprocess_valuekey_int_if_greater_T_temp_cs:nnT #3
		}
		{ int~if~greater~F }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_int_if_greater_F_temp_cs:nnF##1##2##3
			{
				\tl_put_right:Nn#4
				{
					\int_compare:nNnTF { ##1 } > { ##2 }
				}
				\group_begin:
					\tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {}
					\semantex_preprocess_keys_x:nN { ##3 } \l__semantex_preprocess_valuekey_keys_temp_tl
				\exp_args:NNNx
				\group_end:
				\tl_put_right:Nn#4
				{
					{ }
					{ \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl }
				}
			}
			\l__semantex_preprocess_valuekey_int_if_greater_F_temp_cs:nnF #3
		}
		{ int~if~eq~TF }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_int_if_eq_TF_temp_cs:nnTF##1##2##3##4
			{
				\tl_put_right:Nn#4
				{
					\int_compare:nNnTF { ##1 } = { ##2 }
				}
				\group_begin:
					\tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {}
					\semantex_preprocess_keys_x:nN { ##3 } \l__semantex_preprocess_valuekey_keys_temp_tl
				\exp_args:NNNx
				\group_end:
				\tl_put_right:Nn#4
				{
					{ \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl }
				}
				\group_begin:
					\tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {}
					\semantex_preprocess_keys_x:nN { ##4 } \l__semantex_preprocess_valuekey_keys_temp_tl
				\exp_args:NNNx
				\group_end:
				\tl_put_right:Nn#4
				{
					{ \exp_not:V \l__semantex_preprocess_valuekey_keys_temp_tl }
				}
			}
			\l__semantex_preprocess_valuekey_int_if_eq_TF_temp_cs:nnTF #3
		}
		{ int~if~eq~T }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_int_if_eq_T_temp_cs:nnT##1##2##3
			{
				\tl_put_right:Nn#4
				{
					\int_compare:nNnTF { ##1 } = { ##2 }
				}
				\group_begin:
					\tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {}
					\semantex_preprocess_keys_x:nN { ##3 } \l__semantex_preprocess_valuekey_keys_temp_tl
				\exp_args:NNNx
				\group_end:
				\tl_put_right:Nn#4
				{
					{ \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl }
					{ }
				}
			}
			\l__semantex_preprocess_valuekey_int_if_eq_T_temp_cs:nnT #3
		}
		{ int~if~eq~F }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_int_if_eq_F_temp_cs:nnF##1##2##3
			{
				\tl_put_right:Nn#4
				{
					\int_compare:nNnTF { ##1 } = { ##2 }
				}
				\group_begin:
					\tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {}
					\semantex_preprocess_keys_x:nN { ##3 } \l__semantex_preprocess_valuekey_keys_temp_tl
				\exp_args:NNNx
				\group_end:
				\tl_put_right:Nn#4
				{
					{ }
					{ \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl }
				}
			}
			\l__semantex_preprocess_valuekey_int_if_eq_F_temp_cs:nnF #3
		}
		{ int~if~less~TF }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_int_if_less_TF_temp_cs:nnTF##1##2##3##4
			{
				\tl_put_right:Nn#4
				{
					\int_compare:nNnTF { ##1 } < { ##2 }
				}
				\group_begin:
					\tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {}
					\semantex_preprocess_keys_x:nN { ##3 } \l__semantex_preprocess_valuekey_keys_temp_tl
				\exp_args:NNNx
				\group_end:
				\tl_put_right:Nn#4
				{
					{ \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl }
				}
				\group_begin:
					\tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {}
					\semantex_preprocess_keys_x:nN { ##4 } \l__semantex_preprocess_valuekey_keys_temp_tl
				\exp_args:NNNx
				\group_end:
				\tl_put_right:Nn#4
				{
					{ \exp_not:V \l__semantex_preprocess_valuekey_keys_temp_tl }
				}
			}
			\l__semantex_preprocess_valuekey_int_if_less_TF_temp_cs:nnTF #3
		}
		{ int~if~less~T }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_int_if_less_T_temp_cs:nnT##1##2##3
			{
				\tl_put_right:Nn#4
				{
					\int_compare:nNnTF { ##1 } < { ##2 }
				}
				\group_begin:
					\tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {}
					\semantex_preprocess_keys_x:nN { ##3 } \l__semantex_preprocess_valuekey_keys_temp_tl
				\exp_args:NNNx
				\group_end:
				\tl_put_right:Nn#4
				{
					{ \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl }
					{ }
				}
			}
			\l__semantex_preprocess_valuekey_int_if_less_T_temp_cs:nnT #3
		}
		{ int~if~less~F }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_int_if_less_F_temp_cs:nnF##1##2##3
			{
				\tl_put_right:Nn#4
				{
					\int_compare:nNnTF { ##1 } < { ##2 }
				}
				\group_begin:
					\tl_set:Nn\l__semantex_preprocess_valuekey_keys_temp_tl {}
					\semantex_preprocess_keys_x:nN { ##3 } \l__semantex_preprocess_valuekey_keys_temp_tl
				\exp_args:NNNx
				\group_end:
				\tl_put_right:Nn#4
				{
					{ }
					{ \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl }
				}
			}
			\l__semantex_preprocess_valuekey_int_if_less_F_temp_cs:nnF #3
		}
	}
	{
		\tl_put_right:Nn#4
		{
			\semantex_valuekey:nnx { #1 } { #2 } { #3 }
		}
	}
}

\cs_new_protected:Npn\semantex_define_valuekeys:nn#1#2
{
	% Add new valuekeys
	\clist_map_inline:nn { #2 }{
		\__semantex_valuekey_format_auxiliary:nnn { #1 } ##1
	}
}

\cs_new_protected:Npn\__semantex_valuekey_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_valuekey_auxiliary_temp_cs:n##1 { #3 }
	\tl_set:Nn \l__semantex_valuekey_auxiliary_temp_tl {}
	\semantex_preprocess_keys:oN
	{
		\l__semantex_valuekey_auxiliary_temp_cs:n { ##2 }
	} \l__semantex_valuekey_auxiliary_temp_tl
	\cs_set_protected:cpo { __semantex_data_cs_custom_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2
	{
		\l__semantex_valuekey_auxiliary_temp_tl
	}
}

\cs_generate_variant:Nn \cs_set:Npn { Npo }

\cs_generate_variant:Nn \cs_set_protected:Npn { cpo , Npo }

\cs_new_protected:Npn\semantex_remove_valuekey:nn#1#2
{
	\cs_undefine:c { __semantex_data_cs_custom_valuekey_#1_\tl_trim_spaces:n{#2}:nn }
}

\cs_new_protected:Npn\semantex_define_singlekeys:nn#1#2
{
	% Add keys taking no values
	\clist_map_inline:nn { #2 }{
		\__semantex_singlekeys_format_auxiliary:nnn { #1 } ##1
	}
}

\cs_new_protected:Npn \__semantex_singlekeys_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_singlekey_auxiliary_temp_cs: { #3 }
	\tl_set:Nn \l__semantex_singlekey_auxiliary_temp_tl {}
	\semantex_preprocess_keys:oN
	{
		\l__semantex_singlekey_auxiliary_temp_cs:
	} \l__semantex_singlekey_auxiliary_temp_tl
	\cs_set_protected:cpo { __semantex_data_cs_custom_singlekey_#1_\tl_trim_spaces:n{#2}:n } ##1
	{
		\l__semantex_singlekey_auxiliary_temp_tl
	}
}

\cs_new_protected:Npn \semantex_clear_singlekey:nn#1#2
{
	% Note that this is strictly different from undefining the key.
	\cs_set_protected:cpo { __semantex_data_cs_custom_singlekey_#1_\tl_trim_spaces:n{#2}:n } ##1
	{
		% do nothing
	}
}

\cs_new_protected:Npn\semantex_remove_singlekey:nn#1#2
{
	\cs_undefine:c { __semantex_data_cs_custom_singlekey_#1_#2:n }
}

\cs_new_protected:Npn\semantex_define_two_valuekeys:nn#1#2
{
	% Add new valuekeys with 2 values
	\clist_map_inline:nn { #2 }{
		\__semantex_two_valuekey_format_auxiliary:nnn { #1 } ##1
	}
}

\cs_new_protected:Npn\__semantex_two_valuekey_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_two_valuekey_auxiliary_temp_cs:nn##1##2 { #3 }
	\tl_set:Nn\l__semantex_two_valuekey_auxiliary_temp_tl{}
	\semantex_preprocess_keys:oN
	{
		\l__semantex_two_valuekey_auxiliary_temp_cs:nn { ##2 } { ##3 }
	} \l__semantex_two_valuekey_auxiliary_temp_tl
	\cs_set_protected:cpo { __semantex_data_cs_custom_two_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnn } ##1##2##3
	{
		\l__semantex_two_valuekey_auxiliary_temp_tl
	}
	\cs_set_protected:cpn { __semantex_data_cs_custom_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2
	{
		\use:c { __semantex_data_cs_custom_two_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnn } { ##1 } ##2
	}
}

\cs_new_protected:Npn\semantex_define_three_valuekeys:nn#1#2
{
	% Add new valuekeys with 3 values
	\clist_map_inline:nn { #2 }{
		\__semantex_three_valuekey_format_auxiliary:nnn {#1} ##1
	}
}

\cs_new_protected:Npn\__semantex_three_valuekey_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_three_valuekey_auxiliary_temp_cs:nnn##1##2##3 { #3 }
	\tl_set:Nn\l__semantex_three_valuekey_auxiliary_temp_tl{}
	\semantex_preprocess_keys:oN
	{
		\l__semantex_three_valuekey_auxiliary_temp_cs:nnn { ##2 } { ##3 } { ##4 }
	} \l__semantex_three_valuekey_auxiliary_temp_tl
	\cs_set_protected:cpo { __semantex_data_cs_custom_three_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnn } ##1##2##3##4
	{
		\l__semantex_three_valuekey_auxiliary_temp_tl
	}
	\cs_set_protected:cpn { __semantex_data_cs_custom_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2
	{
		\use:c { __semantex_data_cs_custom_three_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnn } { ##1 } ##2
	}
}

\cs_new_protected:Npn\semantex_define_four_valuekeys:nn#1#2
{
	% Add new valuekeys with 4 values
	\clist_map_inline:nn { #2 }{
		\__semantex_four_valuekey_format_auxiliary:nnn{#1}##1
	}
}

\cs_new_protected:Npn\__semantex_four_valuekey_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_four_valuekey_auxiliary_temp_cs:nnnn##1##2##3##4 { #3 }
	\tl_set:Nn\l__semantex_four_valuekey_auxiliary_temp_tl{}
	\semantex_preprocess_keys:oN
	{
		\l__semantex_four_valuekey_auxiliary_temp_cs:nnnn { ##2 } { ##3 } { ##4 } { ##5 }
	} \l__semantex_four_valuekey_auxiliary_temp_tl
	\cs_set_protected:cpo { __semantex_data_cs_custom_four_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnn } ##1##2##3##4##5
	{
		\l__semantex_four_valuekey_auxiliary_temp_tl
	}
	\cs_set_protected:cpn { __semantex_data_cs_custom_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2
	{
		\use:c { __semantex_data_cs_custom_four_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnn } { ##1 } ##2
	}
}

\cs_new_protected:Npn\semantex_define_five_valuekeys:nn#1#2
{
	% Add new valuekeys with 5 values
	\clist_map_inline:nn { #2 }{
		\__semantex_five_valuekey_format_auxiliary:nnn{#1}##1
	}
}

\cs_new_protected:Npn\__semantex_five_valuekey_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_five_valuekey_auxiliary_temp_cs:nnnnn##1##2##3##4##5 { #3 }
	\tl_set:Nn\l__semantex_five_valuekey_auxiliary_temp_tl{}
	\semantex_preprocess_keys:oN
	{
		\l__semantex_five_valuekey_auxiliary_temp_cs:nnnnn { ##2 } { ##3 } { ##4 } { ##5 } { ##6 }
	} \l__semantex_five_valuekey_auxiliary_temp_tl
	\cs_set_protected:cpo { __semantex_data_cs_custom_five_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnn } ##1##2##3##4##5##6
	{
		\l__semantex_five_valuekey_auxiliary_temp_tl
	}
	\cs_set_protected:cpn { __semantex_data_cs_custom_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2
	{
		\use:c { __semantex_data_cs_custom_five_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnn } { ##1 } ##2
	}
}

\cs_new_protected:Npn\semantex_define_six_valuekeys:nn#1#2
{
	% Add new valuekeys with 6 values
	\clist_map_inline:nn { #2 }{
		\__semantex_six_valuekey_format_auxiliary:nnn{#1}##1
	}
}

\cs_new_protected:Npn\__semantex_six_valuekey_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_six_valuekey_auxiliary_temp_cs:nnnnnn##1##2##3##4##5##6 { #3 }
	\tl_set:Nn\l__semantex_six_valuekey_auxiliary_temp_tl{}
	\semantex_preprocess_keys:oN
	{
		\l__semantex_six_valuekey_auxiliary_temp_cs:nnnnnn { ##2 } { ##3 } { ##4 } { ##5 } { ##6 } { ##7 }
	} \l__semantex_six_valuekey_auxiliary_temp_tl
	\cs_set_protected:cpo { __semantex_data_cs_custom_six_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnn } ##1##2##3##4##5##6##7
	{
		\l__semantex_six_valuekey_auxiliary_temp_tl
	}
	\cs_set_protected:cpn { __semantex_data_cs_custom_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2
	{
		\use:c { __semantex_data_cs_custom_six_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnn } { ##1 } ##2
	}
}

\cs_new_protected:Npn\semantex_define_seven_valuekeys:nn#1#2
{
	% Add new valuekeys with 7 values
	\clist_map_inline:nn { #2 }{
		\__semantex_seven_valuekey_format_auxiliary:nnn{#1}##1
	}
}

\cs_new_protected:Npn\__semantex_seven_valuekey_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_seven_valuekey_auxiliary_temp_cs:nnnnnnn##1##2##3##4##5##6##7 { #3 }
	\tl_set:Nn\l__semantex_seven_valuekey_auxiliary_temp_tl{}
	\semantex_preprocess_keys:oN
	{
		\l__semantex_seven_valuekey_auxiliary_temp_cs:nnnnnnn { ##2 } { ##3 } { ##4 } { ##5 } { ##6 } { ##7 } { ##8 }
	} \l__semantex_seven_valuekey_auxiliary_temp_tl
	\cs_set_protected:cpo { __semantex_data_cs_custom_seven_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnnn } ##1##2##3##4##5##6##7##8
	{
		\l__semantex_seven_valuekey_auxiliary_temp_tl
	}
	\cs_set_protected:cpn { __semantex_data_cs_custom_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2
	{
		\use:c { __semantex_data_cs_custom_seven_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnnn } { ##1 } ##2
	}
}

\cs_new_protected:Npn\semantex_define_eight_valuekeys:nn#1#2
{
	% Add new valuekeys with 8 values
	\clist_map_inline:nn { #2 }{
		\__semantex_eight_valuekey_format_auxiliary:nnn{#1}##1
	}
}

\cs_new_protected:Npn\__semantex_eight_valuekey_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_eight_valuekey_auxiliary_temp_cs:nnnnnnnn##1##2##3##4##5##6##7##8 { #3 }
	\tl_set:Nn\l__semantex_eight_valuekey_auxiliary_temp_tl{}
	\semantex_preprocess_keys:oN
	{
		\l__semantex_eight_valuekey_auxiliary_temp_cs:nnnnnnnn { ##2 } { ##3 } { ##4 } { ##5 } { ##6 } { ##7 } { ##8 } { ##9 }
	} \l__semantex_eight_valuekey_auxiliary_temp_tl
	\cs_set_protected:cpo { __semantex_data_cs_custom_eight_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnnnn } ##1##2##3##4##5##6##7##8##9
	{
		\l__semantex_eight_valuekey_auxiliary_temp_tl
	}
	\cs_set_protected:cpn { __semantex_data_cs_custom_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2
	{
		\use:c { __semantex_data_cs_custom_eight_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnnnn } { ##1 } ##2
	}
}

%\cs_new_protected:Npn\semantex_define_nine_valuekeys:nn#1#2
%{
%	% Add new valuekeys with 9 values
%	\clist_map_inline:nn { #2 }{
%		\__semantex_nine_valuekey_format_auxiliary:nnn{#1}##1
%	}
%}
%
%\cs_new_protected:Npn\__semantex_nine_valuekey_format_auxiliary:nnn#1#2#3
%{
%	\cs_set:Npn\l__semantex_nine_valuekey_auxiliary_temp_cs:nnnnnnnnn##1##2##3##4##5##6##7##8##9 { #3 }
%	\tl_set:Nn\l__semantex_nine_valuekey_auxiliary_temp_tl{}
%	\cs_set:Npn\l__semantex_nine_valuekey_auxiliary_singlekey_temp_cs:n##1
%	{
%		\__semantex_preprocess_singlekey:nnN { \__semantex_nine_valuekey_format_auxiliary_name_of_register_temp_tl } { ##1 } \l__semantex_nine_valuekey_auxiliary_temp_tl
%	}
%	\cs_set:Npn\l__semantex_nine_valuekey_auxiliary_valuekey_temp_cs:nn##1##2
%	{
%		\__semantex_preprocess_valuekey:nnnN { \__semantex_nine_valuekey_format_auxiliary_name_of_register_temp_tl } { ##1 } { ##2 } \l__semantex_nine_valuekey_auxiliary_temp_tl
%	}
%	\semantex_keyval_parse:NNo
%		\l__semantex_nine_valuekey_auxiliary_singlekey_temp_cs:n
%		\l__semantex_nine_valuekey_auxiliary_valuekey_temp_cs:nn
%		{
%			\l__semantex_nine_valuekey_auxiliary_temp_cs:nnnnnnnnn { ##1 } { ##2 } { ##3 } { ##4 } { ##5 } { ##6 } { ##7 } { ##8 } { ##9 }
%		}
%	\cs_set_protected:cpo { __semantex_data_cs_custom_nine_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnnnn } ##1##2##3##4##5##6##7##8##9
%	{
%		\l__semantex_nine_valuekey_auxiliary_temp_tl
%	}
%	\cs_set_protected:cpn { __semantex_data_cs_custom_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2
%	{
%		\tl_set:Nn \__semantex_nine_valuekey_format_auxiliary_name_of_register_temp_tl { ##1 }
%		\use:c { __semantex_data_cs_custom_nine_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnnnn } ##2
%	}
%}



\cs_new_protected:Npn\semantex_append_valuekeys:nn#1#2
{
	% Appends keys taking one value
	\clist_map_inline:nn { #2 }{
		\__semantex_append_valuekeys_format_auxiliary:nnn { #1 } ##1
	}
}

\cs_new_protected:Npn\__semantex_append_valuekeys_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_append_valuekeys_auxiliary_temp_cs:n##1 { #3 }
	\tl_set:Nn \l__semantex_append_valuekeys_auxiliary_temp_tl {}
	\semantex_preprocess_keys:oN
	{
		\l__semantex_append_valuekeys_auxiliary_temp_cs:n { ##2 }
	} \l__semantex_append_valuekeys_auxiliary_temp_tl
	\semantex_valuekey_store:nnN { #1 } { #2 } \l__semantex_append_valuekeys_auxiliary_original_temp_tl
	\exp_args:Nnx\cs_set_protected:cn
		% \cs_set_protected:cx gave us ##1 where we wanted #1
	{ __semantex_data_cs_custom_valuekey_#1_\tl_trim_spaces:n{#2}:nn }
	{
		\exp_not:V\l__semantex_append_valuekeys_auxiliary_original_temp_tl
		\exp_not:V\l__semantex_append_valuekeys_auxiliary_temp_tl
	}
}

\cs_new_protected:Npn\semantex_prepend_valuekeys:nn#1#2
{
	% Prepends keys taking one value
	\clist_map_inline:nn { #2 }{
		\__semantex_prepend_valuekeys_format_auxiliary:nnn { #1 } ##1
	}
}

\cs_new_protected:Npn\__semantex_prepend_valuekeys_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_prepend_valuekeys_auxiliary_temp_cs:n##1 { #3 }
	\tl_set:Nn \l__semantex_prepend_valuekeys_auxiliary_temp_tl {}
	\semantex_preprocess_keys:oN
	{
		\l__semantex_prepend_valuekeys_auxiliary_temp_cs:n { ##2 }
	} \l__semantex_prepend_valuekeys_auxiliary_temp_tl
	\semantex_valuekey_store:nnN { #1 } { #2 } \l__semantex_prepend_valuekeys_auxiliary_original_temp_tl
	\exp_args:Nnx\cs_set_protected:cn
		% \cs_set_protected:cx gave us ##1 where we wanted #1
	{ __semantex_data_cs_custom_valuekey_#1_\tl_trim_spaces:n{#2}:nn }
	{
		\exp_not:V\l__semantex_prepend_valuekeys_auxiliary_temp_tl
		\exp_not:V\l__semantex_prepend_valuekeys_auxiliary_original_temp_tl
	}
}

\cs_new_protected:Npn\semantex_append_singlekeys:nn#1#2
{
	% Appends keys taking no values
	\clist_map_inline:nn { #2 }{
		\__semantex_append_singlekeys_format_auxiliary:nnn { #1 } ##1
	}
}

\cs_new_protected:Npn \__semantex_append_singlekeys_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_append_singlekeys_auxiliary_temp_cs: { #3 }
	\tl_set:Nn \l__semantex_append_singlekeys_auxiliary_temp_tl {}
	\semantex_preprocess_keys:oN
	{
		\l__semantex_append_singlekeys_auxiliary_temp_cs:
	} \l__semantex_append_singlekeys_auxiliary_temp_tl
	\semantex_singlekey_store:nnN { #1 } { #2 } \l__semantex_append_singlekeys_auxiliary_original_temp_tl
	\exp_args:Nnx\cs_set_protected:cn
		% \cs_set_protected:cx gave us ##1 where we wanted #1
	{ __semantex_data_cs_custom_singlekey_#1_\tl_trim_spaces:n{#2}:n }
	{
		\exp_not:V\l__semantex_append_singlekeys_auxiliary_original_temp_tl
		\exp_not:V\l__semantex_append_singlekeys_auxiliary_temp_tl
	}
}

\cs_new_protected:Npn \semantex_append_singlekey_with_raw_code:nnn#1#2#3
{
	% Appends the key #2 with the raw code #3
	% #1 = register
	% #2 = key
	% #3 = raw code
	\tl_set:Nn \l__semantex_append_singlekey_with_raw_code_auxiliary_temp_tl { #3 }
	\semantex_singlekey_store:nnN { #1 } { #2 } \l__semantex_append_singlekey_with_raw_code_auxiliary_original_temp_tl
	\exp_args:Nnx\cs_set_protected:cn
		% \cs_set_protected:cx gave us ##1 where we wanted #1
	{ __semantex_data_cs_custom_singlekey_#1_\tl_trim_spaces:n{#2}:n }
	{
		\exp_not:V\l__semantex_append_singlekey_with_raw_code_auxiliary_original_temp_tl
		\exp_not:V\l__semantex_append_singlekey_with_raw_code_auxiliary_temp_tl
	}
}

\cs_new_protected:Npn \semantex_prepend_singlekey_with_raw_code:nnn#1#2#3
{
	% Appends the key #2 with the raw code #3
	% #1 = register
	% #2 = key
	% #3 = raw code
	\tl_set:Nn \l__semantex_prepend_singlekey_with_raw_code_auxiliary_temp_tl { #3 }
	\semantex_singlekey_store:nnN { #1 } { #2 } \l__semantex_prepend_singlekey_with_raw_code_auxiliary_original_temp_tl
	\exp_args:Nnx\cs_set_protected:cn
		% \cs_set_protected:cx gave us ##1 where we wanted #1
	{ __semantex_data_cs_custom_singlekey_#1_\tl_trim_spaces:n{#2}:n }
	{
		\exp_not:V\l__semantex_prepend_singlekey_with_raw_code_auxiliary_temp_tl
		\exp_not:V\l__semantex_prepend_singlekey_with_raw_code_auxiliary_original_temp_tl
	}
}

\cs_new_protected:Npn\semantex_prepend_singlekeys:nn#1#2
{
	% Prepends keys taking no values
	\clist_map_inline:nn { #2 }{
		\__semantex_prepend_singlekeys_format_auxiliary:nnn { #1 } ##1
	}
}

\cs_new_protected:Npn \__semantex_prepend_singlekeys_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_prepend_singlekeys_auxiliary_temp_cs: { #3 }
	\tl_set:Nn \l__semantex_prepend_singlekeys_auxiliary_temp_tl {}
	\semantex_preprocess_keys:oN
	{
		\l__semantex_prepend_singlekeys_auxiliary_temp_cs:
	} \l__semantex_prepend_singlekeys_auxiliary_temp_tl
	\semantex_singlekey_store:nnN { #1 } { #2 } \l__semantex_prepend_singlekeys_auxiliary_original_temp_tl
	\exp_args:Nnx\cs_set_protected:cn
		% \cs_set_protected:cx gave us ##1 where we wanted #1
	{ __semantex_data_cs_custom_singlekey_#1_\tl_trim_spaces:n{#2}:n }
	{
		\exp_not:V\l__semantex_prepend_singlekeys_auxiliary_temp_tl
		\exp_not:V\l__semantex_prepend_singlekeys_auxiliary_original_temp_tl
	}
}

\cs_new_protected:Npn\semantex_append_two_valuekeys:nn#1#2
{
	% Appends valuekeys with 2 values
	\clist_map_inline:nn { #2 }{
		\__semantex_append_two_valuekey_format_auxiliary:nnn { #1 } ##1
	}
}

\cs_new_protected:Npn\__semantex_append_two_valuekey_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_append_two_valuekey_auxiliary_temp_cs:nn##1##2 { #3 }
	\tl_set:Nn\l__semantex_append_two_valuekey_auxiliary_temp_tl{}
	\semantex_preprocess_keys:oN
	{
		\l__semantex_append_two_valuekey_auxiliary_temp_cs:nn { ##2 } { ##3 }
	} \l__semantex_append_two_valuekey_auxiliary_temp_tl
	\semantex_two_valuekey_store:nnN { #1 } { #2 } \l__semantex_append_two_valuekey_auxiliary_original_temp_tl
	\exp_args:Nnx\cs_set_protected:cn { __semantex_data_cs_custom_two_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnn }
	{
		\exp_not:V\l__semantex_append_two_valuekey_auxiliary_original_temp_tl
		\exp_not:V\l__semantex_append_two_valuekey_auxiliary_temp_tl
	}
	\cs_set_protected:cpn { __semantex_data_cs_custom_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2
	{
		\use:c { __semantex_data_cs_custom_two_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnn } { ##1 } ##2
	}
}

\cs_new_protected:Npn\semantex_prepend_two_valuekeys:nn#1#2
{
	% Prepends valuekeys with 2 values
	\clist_map_inline:nn { #2 }{
		\__semantex_prepend_two_valuekey_format_auxiliary:nnn { #1 } ##1
	}
}

\cs_new_protected:Npn\__semantex_prepend_two_valuekey_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_prepend_two_valuekey_auxiliary_temp_cs:nn##1##2 { #3 }
	\tl_set:Nn\l__semantex_prepend_two_valuekey_auxiliary_temp_tl{}
	\semantex_preprocess_keys:oN
	{
		\l__semantex_prepend_two_valuekey_auxiliary_temp_cs:nn { ##2 } { ##3 }
	} \l__semantex_prepend_two_valuekey_auxiliary_temp_tl
	\semantex_two_valuekey_store:nnN { #1 } { #2 } \l__semantex_prepend_two_valuekey_auxiliary_original_temp_tl
	\exp_args:Nnx\cs_set_protected:cn { __semantex_data_cs_custom_two_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnn }
	{
		\exp_not:V\l__semantex_prepend_two_valuekey_auxiliary_original_temp_tl
		\exp_not:V\l__semantex_prepend_two_valuekey_auxiliary_temp_tl
	}
	\cs_set_protected:cpn { __semantex_data_cs_custom_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2
	{
		\use:c { __semantex_data_cs_custom_two_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnn } { ##1 } ##2
	}
}

\cs_new_protected:Npn\semantex_append_three_valuekeys:nn#1#2
{
	% Appends valuekeys with 3 values
	\clist_map_inline:nn { #2 }{
		\__semantex_append_three_valuekey_format_auxiliary:nnn {#1} ##1
	}
}

\cs_new_protected:Npn\__semantex_append_three_valuekey_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_append_three_valuekey_auxiliary_temp_cs:nnn##1##2##3 { #3 }
	\tl_set:Nn\l__semantex_append_three_valuekey_auxiliary_temp_tl{}
	\semantex_preprocess_keys:oN
	{
		\l__semantex_append_three_valuekey_auxiliary_temp_cs:nnn { ##2 } { ##3 } { ##4 }
	} \l__semantex_append_three_valuekey_auxiliary_temp_tl
	\semantex_three_valuekey_store:nnN { #1 } { #2 } \l__semantex_append_three_valuekey_auxiliary_original_temp_tl
	\exp_args:Nnx\cs_set_protected:cn { __semantex_data_cs_custom_three_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnn }
	{
		\exp_not:V\l__semantex_append_three_valuekey_auxiliary_original_temp_tl
		\exp_not:V\l__semantex_append_three_valuekey_auxiliary_temp_tl
	}
	\cs_set_protected:cpn { __semantex_data_cs_custom_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2
	{
		\use:c { __semantex_data_cs_custom_three_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnn } { ##1 } ##2
	}
}

\cs_new_protected:Npn\semantex_prepend_three_valuekeys:nn#1#2
{
	% Prepends valuekeys with 3 values
	\clist_map_inline:nn { #2 }{
		\__semantex_prepend_three_valuekey_format_auxiliary:nnn {#1} ##1
	}
}

\cs_new_protected:Npn\__semantex_prepend_three_valuekey_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_prepend_three_valuekey_auxiliary_temp_cs:nnn##1##2##3 { #3 }
	\tl_set:Nn\l__semantex_prepend_three_valuekey_auxiliary_temp_tl{}
	\semantex_preprocess_keys:oN
	{
		\l__semantex_prepend_three_valuekey_auxiliary_temp_cs:nnn { ##2 } { ##3 } { ##4 }
	} \l__semantex_prepend_three_valuekey_auxiliary_temp_tl
	\semantex_three_valuekey_store:nnN { #1 } { #2 } \l__semantex_prepend_three_valuekey_auxiliary_original_temp_tl
	\exp_args:Nnx\cs_set_protected:cn { __semantex_data_cs_custom_three_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnn }
	{
		\exp_not:V\l__semantex_prepend_three_valuekey_auxiliary_temp_tl
		\exp_not:V\l__semantex_prepend_three_valuekey_auxiliary_original_temp_tl
	}
	\cs_set_protected:cpn { __semantex_data_cs_custom_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2
	{
		\use:c { __semantex_data_cs_custom_three_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnn } { ##1 } ##2
	}
}

\cs_new_protected:Npn\semantex_append_four_valuekeys:nn#1#2
{
	% Appends valuekeys with 4 values
	\clist_map_inline:nn { #2 }{
		\__semantex_append_four_valuekey_format_auxiliary:nnn{#1}##1
	}
}

\cs_new_protected:Npn\__semantex_append_four_valuekey_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_append_four_valuekey_auxiliary_temp_cs:nnnn##1##2##3##4 { #3 }
	\tl_set:Nn\l__semantex_append_four_valuekey_auxiliary_temp_tl{}
	\semantex_preprocess_keys:oN
	{
		\l__semantex_append_four_valuekey_auxiliary_temp_cs:nnnn { ##2 } { ##3 } { ##4 } { ##5 }
	} \l__semantex_append_four_valuekey_auxiliary_temp_tl
	\semantex_four_valuekey_store:nnN { #1 } { #2 } \l__semantex_append_four_valuekey_auxiliary_original_temp_tl
	\exp_args:Nnx\cs_set_protected:cn { __semantex_data_cs_custom_four_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnn }
	{
		\exp_not:V\l__semantex_append_four_valuekey_auxiliary_original_temp_tl
		\exp_not:V\l__semantex_append_four_valuekey_auxiliary_temp_tl
	}
	\cs_set_protected:cpn { __semantex_data_cs_custom_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2
	{
		\use:c { __semantex_data_cs_custom_four_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnn } { ##1 } ##2
	}
}

\cs_new_protected:Npn\semantex_prepend_four_valuekeys:nn#1#2
{
	% Prepends valuekeys with 4 values
	\clist_map_inline:nn { #2 }{
		\__semantex_prepend_four_valuekey_format_auxiliary:nnn{#1}##1
	}
}

\cs_new_protected:Npn\__semantex_prepend_four_valuekey_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_prepend_four_valuekey_auxiliary_temp_cs:nnnn##1##2##3##4 { #3 }
	\tl_set:Nn\l__semantex_prepend_four_valuekey_auxiliary_temp_tl{}
	\semantex_preprocess_keys:oN
	{
		\l__semantex_prepend_four_valuekey_auxiliary_temp_cs:nnnn { ##2 } { ##3 } { ##4 } { ##5 }
	} \l__semantex_prepend_four_valuekey_auxiliary_temp_tl
	\semantex_four_valuekey_store:nnN { #1 } { #2 } \l__semantex_prepend_four_valuekey_auxiliary_original_temp_tl
	\exp_args:Nnx\cs_set_protected:cn { __semantex_data_cs_custom_four_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnn }
	{
		\exp_not:V\l__semantex_prepend_four_valuekey_auxiliary_temp_tl
		\exp_not:V\l__semantex_prepend_four_valuekey_auxiliary_original_temp_tl
	}
	\cs_set_protected:cpn { __semantex_data_cs_custom_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2
	{
		\use:c { __semantex_data_cs_custom_four_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnn } { ##1 } ##2
	}
}

\cs_new_protected:Npn\semantex_append_five_valuekeys:nn#1#2
{
	% Appends valuekeys with 5 values
	\clist_map_inline:nn { #2 }{
		\__semantex_append_five_valuekey_format_auxiliary:nnn{#1}##1
	}
}

\cs_new_protected:Npn\__semantex_append_five_valuekey_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_append_five_valuekey_auxiliary_temp_cs:nnnnn##1##2##3##4##5 { #3 }
	\tl_set:Nn\l__semantex_append_five_valuekey_auxiliary_temp_tl{}
	\semantex_preprocess_keys:oN
	{
		\l__semantex_append_five_valuekey_auxiliary_temp_cs:nnnnn { ##2 } { ##3 } { ##4 } { ##5 } { ##6 }
	} \l__semantex_append_five_valuekey_auxiliary_temp_tl
	\semantex_five_valuekey_store:nnN { #1 } { #2 } \l__semantex_append_five_valuekey_auxiliary_original_temp_tl
	\exp_args:Nnx\cs_set_protected:cn { __semantex_data_cs_custom_five_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnn }
	{
		\exp_not:V\l__semantex_append_five_valuekey_auxiliary_original_temp_tl
		\exp_not:V\l__semantex_append_five_valuekey_auxiliary_temp_tl
	}
	\cs_set_protected:cpn { __semantex_data_cs_custom_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2
	{
		\use:c { __semantex_data_cs_custom_five_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnn } { ##1 } ##2
	}
}

\cs_new_protected:Npn\semantex_prepend_five_valuekeys:nn#1#2
{
	% Prepends valuekeys with 5 values
	\clist_map_inline:nn { #2 }{
		\__semantex_prepend_five_valuekey_format_auxiliary:nnn{#1}##1
	}
}

\cs_new_protected:Npn\__semantex_prepend_five_valuekey_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_prepend_five_valuekey_auxiliary_temp_cs:nnnnn##1##2##3##4##5 { #3 }
	\tl_set:Nn\l__semantex_prepend_five_valuekey_auxiliary_temp_tl{}
	\semantex_preprocess_keys:oN
	{
		\l__semantex_prepend_five_valuekey_auxiliary_temp_cs:nnnnn { ##2 } { ##3 } { ##4 } { ##5 } { ##6 }
	} \l__semantex_prepend_five_valuekey_auxiliary_temp_tl
	\semantex_five_valuekey_store:nnN { #1 } { #2 } \l__semantex_prepend_five_valuekey_auxiliary_original_temp_tl
	\exp_args:Nnx\cs_set_protected:cn { __semantex_data_cs_custom_five_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnn }
	{
		\exp_not:V\l__semantex_prepend_five_valuekey_auxiliary_temp_tl
		\exp_not:V\l__semantex_prepend_five_valuekey_auxiliary_original_temp_tl
	}
	\cs_set_protected:cpn { __semantex_data_cs_custom_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2
	{
		\use:c { __semantex_data_cs_custom_five_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnn } { ##1 } ##2
	}
}

\cs_new_protected:Npn\semantex_append_six_valuekeys:nn#1#2
{
	% Appends valuekeys with 6 values
	\clist_map_inline:nn { #2 }{
		\__semantex_append_six_valuekey_format_auxiliary:nnn{#1}##1
	}
}

\cs_new_protected:Npn\__semantex_append_six_valuekey_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_append_six_valuekey_auxiliary_temp_cs:nnnnnn##1##2##3##4##5##6 { #3 }
	\tl_set:Nn\l__semantex_append_six_valuekey_auxiliary_temp_tl{}
	\semantex_preprocess_keys:oN
	{
		\l__semantex_append_six_valuekey_auxiliary_temp_cs:nnnnnn { ##2 } { ##3 } { ##4 } { ##5 } { ##6 } { ##7 }
	} \l__semantex_append_six_valuekey_auxiliary_temp_tl
	\semantex_six_valuekey_store:nnN { #1 } { #2 } \l__semantex_append_six_valuekey_auxiliary_original_temp_tl
	\exp_args:Nnx\cs_set_protected:cn { __semantex_data_cs_custom_six_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnn }
	{
		\exp_not:V\l__semantex_append_six_valuekey_auxiliary_original_temp_tl
		\exp_not:V\l__semantex_append_six_valuekey_auxiliary_temp_tl
	}
	\cs_set_protected:cpn { __semantex_data_cs_custom_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2
	{
		\use:c { __semantex_data_cs_custom_six_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnn } { ##1 } ##2
	}
}

\cs_new_protected:Npn\semantex_prepend_six_valuekeys:nn#1#2
{
	% Prepends valuekeys with 6 values
	\clist_map_inline:nn { #2 }{
		\__semantex_prepend_six_valuekey_format_auxiliary:nnn{#1}##1
	}
}

\cs_new_protected:Npn\__semantex_prepend_six_valuekey_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_prepend_six_valuekey_auxiliary_temp_cs:nnnnnn##1##2##3##4##5##6 { #3 }
	\tl_set:Nn\l__semantex_prepend_six_valuekey_auxiliary_temp_tl{}
	\semantex_preprocess_keys:oN
	{
		\l__semantex_prepend_six_valuekey_auxiliary_temp_cs:nnnnnn { ##2 } { ##3 } { ##4 } { ##5 } { ##6 } { ##7 }
	} \l__semantex_prepend_six_valuekey_auxiliary_temp_tl
	\semantex_six_valuekey_store:nnN { #1 } { #2 } \l__semantex_prepend_six_valuekey_auxiliary_original_temp_tl
	\exp_args:Nnx\cs_set_protected:cn { __semantex_data_cs_custom_six_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnn }
	{
		\exp_not:V\l__semantex_prepend_six_valuekey_auxiliary_original_temp_tl
		\exp_not:V\l__semantex_prepend_six_valuekey_auxiliary_temp_tl
	}
	\cs_set_protected:cpn { __semantex_data_cs_custom_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2
	{
		\use:c { __semantex_data_cs_custom_six_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnn } { ##1 } ##2
	}
}

\cs_new_protected:Npn\semantex_append_seven_valuekeys:nn#1#2
{
	% Appends valuekeys with 7 values
	\clist_map_inline:nn { #2 }{
		\__semantex_append_seven_valuekey_format_auxiliary:nnn{#1}##1
	}
}

\cs_new_protected:Npn\__semantex_append_seven_valuekey_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_append_seven_valuekey_auxiliary_temp_cs:nnnnnnn##1##2##3##4##5##6##7 { #3 }
	\tl_set:Nn\l__semantex_append_seven_valuekey_auxiliary_temp_tl{}
	\semantex_preprocess_keys:oN
	{
		\l__semantex_append_seven_valuekey_auxiliary_temp_cs:nnnnnnn { ##2 } { ##3 } { ##4 } { ##5 } { ##6 } { ##7 } { ##8 }
	} \l__semantex_append_seven_valuekey_auxiliary_temp_tl
	\semantex_seven_valuekey_store:nnN { #1 } { #2 } \l__semantex_append_seven_valuekey_auxiliary_original_temp_tl
	\exp_args:Nnx\cs_set_protected:cn { __semantex_data_cs_custom_seven_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnnn }
	{
		\exp_not:V\l__semantex_append_seven_valuekey_auxiliary_original_temp_tl
		\exp_not:V\l__semantex_append_seven_valuekey_auxiliary_temp_tl
	}
	\cs_set_protected:cpn { __semantex_data_cs_custom_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2
	{
		\use:c { __semantex_data_cs_custom_seven_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnnn } { ##1 } ##2
	}
}

\cs_new_protected:Npn\semantex_prepend_seven_valuekeys:nn#1#2
{
	% Prepends valuekeys with 7 values
	\clist_map_inline:nn { #2 }{
		\__semantex_prepend_seven_valuekey_format_auxiliary:nnn{#1}##1
	}
}

\cs_new_protected:Npn\__semantex_prepend_seven_valuekey_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_prepend_seven_valuekey_auxiliary_temp_cs:nnnnnnn##1##2##3##4##5##6##7 { #3 }
	\tl_set:Nn\l__semantex_prepend_seven_valuekey_auxiliary_temp_tl{}
	\semantex_preprocess_keys:oN
	{
		\l__semantex_prepend_seven_valuekey_auxiliary_temp_cs:nnnnnnn { ##2 } { ##3 } { ##4 } { ##5 } { ##6 } { ##7 } { ##8 }
	} \l__semantex_prepend_seven_valuekey_auxiliary_temp_tl
	\semantex_seven_valuekey_store:nnN { #1 } { #2 } \l__semantex_prepend_seven_valuekey_auxiliary_original_temp_tl
	\exp_args:Nnx\cs_set_protected:cn { __semantex_data_cs_custom_seven_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnnn }
	{
		\exp_not:V\l__semantex_prepend_seven_valuekey_auxiliary_original_temp_tl
		\exp_not:V\l__semantex_prepend_seven_valuekey_auxiliary_temp_tl
	}
	\cs_set_protected:cpn { __semantex_data_cs_custom_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2
	{
		\use:c { __semantex_data_cs_custom_seven_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnnn } { ##1 } ##2
	}
}

\cs_new_protected:Npn\semantex_append_eight_valuekeys:nn#1#2
{
	% Appends valuekeys with 8 values
	\clist_map_inline:nn { #2 }{
		\__semantex_append_eight_valuekey_format_auxiliary:nnn{#1}##1
	}
}

\cs_new_protected:Npn\__semantex_append_eight_valuekey_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_append_eight_valuekey_auxiliary_temp_cs:nnnnnnnn##1##2##3##4##5##6##7##8 { #3 }
	\tl_set:Nn\l__semantex_append_eight_valuekey_auxiliary_temp_tl{}
	\semantex_preprocess_keys:oN
	{
		\l__semantex_append_eight_valuekey_auxiliary_temp_cs:nnnnnnnn { ##2 } { ##3 } { ##4 } { ##5 } { ##6 } { ##7 } { ##8 } { ##9 }
	} \l__semantex_append_eight_valuekey_auxiliary_temp_tl
	\semantex_eight_valuekey_store:nnN { #1 } { #2 } \l__semantex_append_eight_valuekey_auxiliary_original_temp_tl
	\exp_args:Nnx\cs_set_protected:cn { __semantex_data_cs_custom_eight_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnnnn }
	{
		\exp_not:V\l__semantex_append_eight_valuekey_auxiliary_original_temp_tl
		\exp_not:V\l__semantex_append_eight_valuekey_auxiliary_temp_tl
	}
	\cs_set_protected:cpn { __semantex_data_cs_custom_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2
	{
		\use:c { __semantex_data_cs_custom_eight_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnnnn } { ##1 } ##2
	}
}

\cs_new_protected:Npn\semantex_prepend_eight_valuekeys:nn#1#2
{
	% Prepends valuekeys with 8 values
	\clist_map_inline:nn { #2 }{
		\__semantex_prepend_eight_valuekey_format_auxiliary:nnn{#1}##1
	}
}

\cs_new_protected:Npn\__semantex_prepend_eight_valuekey_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_prepend_eight_valuekey_auxiliary_temp_cs:nnnnnnnn##1##2##3##4##5##6##7##8 { #3 }
	\tl_set:Nn\l__semantex_prepend_eight_valuekey_auxiliary_temp_tl{}
	\semantex_preprocess_keys:oN
	{
		\l__semantex_prepend_eight_valuekey_auxiliary_temp_cs:nnnnnnnn { ##2 } { ##3 } { ##4 } { ##5 } { ##6 } { ##7 } { ##8 } { ##9 }
	} \l__semantex_prepend_eight_valuekey_auxiliary_temp_tl
	\semantex_eight_valuekey_store:nnN { #1 } { #2 } \l__semantex_prepend_eight_valuekey_auxiliary_original_temp_tl
	\exp_args:Nnx\cs_set_protected:cn { __semantex_data_cs_custom_eight_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnnnn }
	{
		\exp_not:V\l__semantex_prepend_eight_valuekey_auxiliary_temp_tl
		\exp_not:V\l__semantex_prepend_eight_valuekey_auxiliary_original_temp_tl
	}
	\cs_set_protected:cpn { __semantex_data_cs_custom_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2
	{
		\use:c { __semantex_data_cs_custom_eight_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnnnn } { ##1 } ##2
	}
}

%\cs_new_protected:Npn\semantex_append_nine_valuekeys:nn#1#2
%{
%	% Appends valuekeys with 9 values
%	\clist_map_inline:nn { #2 }{
%		\__semantex_append_nine_valuekey_format_auxiliary:nnn{#1}##1
%	}
%}
%
%\cs_new_protected:Npn\__semantex_append_nine_valuekey_format_auxiliary:nnn#1#2#3
%{
%	\cs_set:Npn\l__semantex_append_nine_valuekey_auxiliary_temp_cs:nnnnnnnnn##1##2##3##4##5##6##7##8##9 { #3 }
%	\tl_set:Nn\l__semantex_append_nine_valuekey_auxiliary_temp_tl{}
%	\cs_set:Npn\l__semantex_append_nine_valuekey_auxiliary_singlekey_temp_cs:n##1
%	{
%		\__semantex_preprocess_singlekey:nnN { \__semantex_nine_valuekey_format_auxiliary_name_of_register_temp_tl } { ##1 } \l__semantex_append_nine_valuekey_auxiliary_temp_tl
%	}
%	\cs_set:Npn\l__semantex_append_nine_valuekey_auxiliary_valuekey_temp_cs:nn##1##2
%	{
%		\__semantex_preprocess_valuekey:nnnN { \__semantex_nine_valuekey_format_auxiliary_name_of_register_temp_tl } { ##1 } { ##2 } \l__semantex_append_nine_valuekey_auxiliary_temp_tl
%	}
%	\semantex_keyval_parse:NNo
%		\l__semantex_append_nine_valuekey_auxiliary_singlekey_temp_cs:n
%		\l__semantex_append_nine_valuekey_auxiliary_valuekey_temp_cs:nn
%		{
%			\l__semantex_append_nine_valuekey_auxiliary_temp_cs:nnnnnnnnn { ##1 } { ##2 } { ##3 } { ##4 } { ##5 } { ##6 } { ##7 } { ##8 } { ##9 }
%		}
%	\semantex_nine_valuekey_store:nnN { #1 } { #2 } \l__semantex_append_nine_valuekey_auxiliary_original_temp_tl
%	\exp_args:Nnx\cs_set_protected:cn { __semantex_data_cs_custom_nine_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnnnn }
%	{
%		\exp_not:V\l__semantex_append_nine_valuekey_auxiliary_original_temp_tl
%		\exp_not:V\l__semantex_append_nine_valuekey_auxiliary_temp_tl
%	}
%	\cs_set_protected:cpn { __semantex_data_cs_custom_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2
%	{
%		\tl_set:Nn \__semantex_nine_valuekey_format_auxiliary_name_of_register_temp_tl { ##1 }
%		\use:c { __semantex_data_cs_custom_nine_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnnnn } ##2
%	}
%}
%
%\cs_new_protected:Npn\semantex_prepend_nine_valuekeys:nn#1#2
%{
%	% Prepends valuekeys with 9 values
%	\clist_map_inline:nn { #2 }{
%		\__semantex_prepend_nine_valuekey_format_auxiliary:nnn{#1}##1
%	}
%}
%
%\cs_new_protected:Npn\__semantex_prepend_nine_valuekey_format_auxiliary:nnn#1#2#3
%{
%	\cs_set:Npn\l__semantex_prepend_nine_valuekey_auxiliary_temp_cs:nnnnnnnnn##1##2##3##4##5##6##7##8##9 { #3 }
%	\tl_set:Nn\l__semantex_prepend_nine_valuekey_auxiliary_temp_tl{}
%	\cs_set:Npn\l__semantex_prepend_nine_valuekey_auxiliary_singlekey_temp_cs:n##1
%	{
%		\__semantex_preprocess_singlekey:nnN { \__semantex_nine_valuekey_format_auxiliary_name_of_register_temp_tl } { ##1 } \l__semantex_prepend_nine_valuekey_auxiliary_temp_tl
%	}
%	\cs_set:Npn\l__semantex_prepend_nine_valuekey_auxiliary_valuekey_temp_cs:nn##1##2
%	{
%		\__semantex_preprocess_valuekey:nnnN { \__semantex_nine_valuekey_format_auxiliary_name_of_register_temp_tl } { ##1 } { ##2 } \l__semantex_prepend_nine_valuekey_auxiliary_temp_tl
%	}
%	\semantex_keyval_parse:NNo
%		\l__semantex_prepend_nine_valuekey_auxiliary_singlekey_temp_cs:n
%		\l__semantex_prepend_nine_valuekey_auxiliary_valuekey_temp_cs:nn
%		{
%			\l__semantex_prepend_nine_valuekey_auxiliary_temp_cs:nnnnnnnnn { ##1 } { ##2 } { ##3 } { ##4 } { ##5 } { ##6 } { ##7 } { ##8 } { ##9 }
%		}
%	\semantex_nine_valuekey_store:nnN { #1 } { #2 } \l__semantex_prepend_nine_valuekey_auxiliary_original_temp_tl
%	\exp_args:Nnx\cs_set_protected:cn { __semantex_data_cs_custom_nine_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnnnn }
%	{
%		\exp_not:V\l__semantex_prepend_nine_valuekey_auxiliary_temp_tl
%		\exp_not:V\l__semantex_prepend_nine_valuekey_auxiliary_original_temp_tl
%	}
%	\cs_set_protected:cpn { __semantex_data_cs_custom_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2
%	{
%		\tl_set:Nn \__semantex_nine_valuekey_format_auxiliary_name_of_register_temp_tl { ##1 }
%		\use:c { __semantex_data_cs_custom_nine_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnnnn } ##2
%	}
%}


% SETTING UP THE ARGUMENT KEYVAL INTERFACE

\cs_new_protected:Npn\semantex_preprocess_arg_keys:nN#1#2
{
	\cs_set:Npn\l__semantex_preprocess_arg_singlekey_temp_cs:n##1
	{
		\__semantex_preprocess_arg_singlekey:nnN { ####1 } { ##1 } #2
	}
	\cs_set:Npn\l__semantex_preprocess_arg_valuekey_temp_cs:nn##1##2
	{
		\__semantex_preprocess_arg_valuekey:nnnN { ####1 } { ##1 } { ##2 } #2
	}
	\semantex_keyval_parse:NNn
		\l__semantex_preprocess_arg_singlekey_temp_cs:n
		\l__semantex_preprocess_arg_valuekey_temp_cs:nn
		{ #1 }
}

\cs_generate_variant:Nn \semantex_preprocess_arg_keys:nN { oN }

\cs_new_protected:Npn\semantex_preprocess_arg_singlekeys:nN#1#2
{
	\cs_set:Npn\l__semantex_preprocess_arg_singlekey_temp_cs:n##1
	{
		\__semantex_preprocess_arg_singlekey:nnN { ####1 } { ##1 } #2
	}
	\semantex_singlekey_parse:Nn \l__semantex_preprocess_arg_singlekey_temp_cs:n { #1 }
}


\cs_new_protected:Npn\__semantex_preprocess_arg_singlekey:nnN#1#2#3
{
	\tl_put_right:Nn#3
	{
		\semantex_arg_singlekey:nn { #1 } { #2 }
	}
}


\cs_new_protected:Npn\__semantex_preprocess_arg_valuekey:nnnN#1#2#3#4
{
	\str_case:nnF { #2 }
	{
		{ execute }{
			\tl_put_right:Nn#4
			{
				#3
			}
		}
		{ set~keys }{
			\semantex_preprocess_keys:nN { #3 } #4
		}
		{ keys~set }{
			\semantex_preprocess_keys:nN { #3 } #4
		}
		{ set~keys~x }{
			\semantex_preprocess_keys_x:nN { #3 } #4
		}
		{ keys~set~x }{
			\semantex_preprocess_keys_x:nN { #3 } #4
		}
		{ set~arg~keys }{
			\semantex_preprocess_arg_keys:nN { #3 } #4
		}
		{ arg~keys~set }{
			\semantex_preprocess_arg_keys:nN { #3 } #4
		}
		{ set~arg~keys~x }{
			\semantex_preprocess_arg_keys_x:nN { #3 } #4
		}
		{ arg~keys~set~x }{
			\semantex_preprocess_arg_keys_x:nN { #3 } #4
		}
		{ set~arg~single~keys }{
			\semantex_preprocess_arg_singlekeys:nN { #3 } #4
		}
		{ arg~single~keys~set }{
			\semantex_preprocess_arg_singlekeys:nN { #3 } #4
		}
		{ set~arg~single~keys~x }{
			\semantex_preprocess_arg_singlekeys_x:nN { #3 } #4
		}
		{ arg~single~keys~set~x }{
			\semantex_preprocess_arg_singlekeys_x:nN { #3 } #4
		}
	}
	{
		\tl_put_right:Nn#4
		{
			\semantex_arg_valuekey:nnn { #1 } { #2 } { #3 }
		}
	}
}

% The x version:

\cs_new_protected:Npn\semantex_preprocess_arg_keys_x:nN#1#2
{
	\cs_set:Npn\l__semantex_preprocess_arg_singlekey_x_temp_cs:n##1
	{
		\__semantex_preprocess_arg_singlekey_x:nnN { ####1 } { ##1 } #2
	}
	\cs_set:Npn\l__semantex_preprocess_arg_valuekey_x_temp_cs:nn##1##2
	{
		\__semantex_preprocess_arg_valuekey_x:nnnN { ####1 } { ##1 } { ##2 } #2
	}
	\semantex_keyval_parse:NNn
		\l__semantex_preprocess_arg_singlekey_x_temp_cs:n
		\l__semantex_preprocess_arg_valuekey_x_temp_cs:nn
		{ #1 }
}

\cs_new_protected:Npn\semantex_preprocess_arg_singlekeys_x:nN#1#2
{
	\cs_set:Npn\l__semantex_preprocess_arg_singlekey_x_temp_cs:n##1
	{
		\__semantex_preprocess_arg_singlekey_x:nnN { ####1 } { ##1 } #2
	}
	\semantex_singlekey_parse:Nn \l__semantex_preprocess_arg_singlekey_x_temp_cs:n { #1 }
}


\cs_new_protected:Npn\__semantex_preprocess_arg_singlekey_x:nnN#1#2#3
{
	\tl_put_right:Nn#3
	{
		\semantex_arg_singlekey_x:nn { #1 } { #2 }
	}
}

\cs_new_protected:Npn\__semantex_preprocess_arg_valuekey_x:nnnN#1#2#3#4
{
	\str_case:nnF { #2 }
	{
		{ execute } {
			\tl_put_right:Nn#4
			{
				#3
			}
		}
		{ set~keys }{
			\semantex_preprocess_keys:nN { #3 } #4
		}
		{ keys~set }{
			\semantex_preprocess_keys:nN { #3 } #4
		}
		{ set~keys~x }{
			\semantex_preprocess_keys_x:nN { #3 } #4
		}
		{ keys~set~x }{
			\semantex_preprocess_keys_x:nN { #3 } #4
		}
		{ set~arg~keys }{
			\semantex_preprocess_arg_keys:nN { #3 } #4
		}
		{ arg~keys~set }{
			\semantex_preprocess_arg_keys:nN { #3 } #4
		}
		{ set~arg~keys~x }{
			\semantex_preprocess_arg_keys_x:nN { #3 } #4
		}
		{ arg~keys~set~x }{
			\semantex_preprocess_arg_keys_x:nN { #3 } #4
		}
		{ set~arg~single~keys }{
			\semantex_preprocess_arg_singlekeys:nN { #3 } #4
		}
		{ arg~single~keys~set }{
			\semantex_preprocess_arg_singlekeys:nN { #3 } #4
		}
		{ set~arg~single~keys~x }{
			\semantex_preprocess_arg_singlekeys_x:nN { #3 } #4
		}
		{ arg~single~keys~set~x }{
			\semantex_preprocess_arg_singlekeys_x:nN { #3 } #4
		}
	}
	{
		\tl_put_right:Nn#4
		{
			\semantex_arg_valuekey:nnx { #1 } { #2 } { #3 }
		}
	}
}

\cs_new_protected:Npn\semantex_define_arg_valuekeys:nn#1#2
{
	% Add new valuekeys
	\clist_map_inline:nn { #2 }{
		\__semantex_arg_valuekey_format_auxiliary:nnn{#1}##1
	}
}

\cs_generate_variant:Nn \l__semantex_auxiliary_preprocess_arg_keys_temp:n { o }

\cs_new_protected:Npn\__semantex_arg_valuekey_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_arg_valuekey_auxiliary_temp_cs:n##1 { #3 }
	\tl_set:Nn \l__semantex_arg_valuekey_auxiliary_temp_tl {}
	\semantex_preprocess_arg_keys:oN
	{
		\l__semantex_arg_valuekey_auxiliary_temp_cs:n { ##2 }
	} \l__semantex_arg_valuekey_auxiliary_temp_tl
	\cs_set_protected:cpo { __semantex_data_cs_custom_arg_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2
	{
		\l__semantex_arg_valuekey_auxiliary_temp_tl
	}
}

\cs_new_protected:Npn\semantex_remove_arg_valuekey:nn#1#2
{
	\cs_undefine:c { __semantex_data_cs_custom_arg_valuekey_#1_\tl_trim_spaces:n{#2}:nn }
}

\cs_new_protected:Npn\semantex_define_arg_singlekeys:nn#1#2
{
	% Add keys taking no values
	\clist_map_inline:nn { #2 }{
		\__semantex_arg_singlekey_format_auxiliary:nnn{#1}##1
	}
}

\cs_new_protected:Npn \__semantex_arg_singlekey_format_auxiliary:nnn#1#2#3{
	\cs_set:Npn\l__semantex_arg_singlekey_auxiliary_temp_cs: { #3 }
	\tl_set:Nn \l__semantex_arg_singlekey_auxiliary_temp_tl {}
	\semantex_preprocess_arg_keys:oN
	{
		\l__semantex_arg_singlekey_auxiliary_temp_cs:
	} \l__semantex_arg_singlekey_auxiliary_temp_tl
	\cs_set_protected:cpo { __semantex_data_cs_custom_arg_singlekey_#1_\tl_trim_spaces:n{#2}:n } ##1
	{
		\l__semantex_arg_singlekey_auxiliary_temp_tl
	}
}


\cs_new_protected:Npn\semantex_remove_arg_singlekey:nn#1#2
{
	\cs_undefine:c { __semantex_data_cs_custom_arg_singlekey_#1_#2:n }
}

\cs_new_protected:Npn\semantex_define_arg_two_valuekeys:nn#1#2
{
	% Add new argument valuekeys with 2 values
	\clist_map_inline:nn { #2 }{
		\__semantex_arg_two_valuekey_format_auxiliary:nnn{#1}##1
	}
}

\cs_new_protected:Npn\__semantex_arg_two_valuekey_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_arg_two_valuekey_auxiliary_temp_cs:nn##1##2 { #3 }
	\tl_set:Nn\l__semantex_arg_two_valuekey_auxiliary_temp_tl{}
	\semantex_preprocess_arg_keys:oN
	{
		\l__semantex_arg_two_valuekey_auxiliary_temp_cs:nn { ##2 } { ##3 }
	} \l__semantex_arg_two_valuekey_auxiliary_temp_tl
	\cs_set_protected:cpo { __semantex_data_cs_custom_arg_two_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnn } ##1##2##3
	{
		\l__semantex_arg_two_valuekey_auxiliary_temp_tl
	}
	\cs_set_protected:cpn { __semantex_data_cs_custom_arg_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2
	{
		\use:c { __semantex_data_cs_custom_arg_two_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnn } { ##1 } ##2
	}
}

\cs_new_protected:Npn\semantex_define_arg_three_valuekeys:nn#1#2
{
	% Add new argument valuekeys with 3 values
	\clist_map_inline:nn { #2 }{
		\__semantex_arg_three_valuekey_format_auxiliary:nnn{#1}##1
	}
}

\cs_new_protected:Npn\__semantex_arg_three_valuekey_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_arg_three_valuekey_auxiliary_temp_cs:nnn##1##2##3 { #3 }
	\tl_set:Nn\l__semantex_arg_three_valuekey_auxiliary_temp_tl{}
	\semantex_preprocess_arg_keys:oN
	{
		\l__semantex_arg_three_valuekey_auxiliary_temp_cs:nnn { ##2 } { ##3 } { ##4 }
	} \l__semantex_arg_three_valuekey_auxiliary_temp_tl
	\cs_set_protected:cpo { __semantex_data_cs_custom_arg_three_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnn } ##1##2##3##4
	{
		\l__semantex_arg_three_valuekey_auxiliary_temp_tl
	}
	\cs_set_protected:cpn { __semantex_data_cs_custom_arg_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2
	{
		\use:c { __semantex_data_cs_custom_arg_three_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnn } { ##1 } ##2
	}
}

\cs_new:Npn\semantex_define_arg_four_valuekeys:nn#1#2
{
	% Add new argument valuekeys with 4 values
	\clist_map_inline:nn { #2 }{
		\__semantex_arg_four_valuekey_format_auxiliary:nnn{#1}##1
	}
}

\cs_new_protected:Npn\__semantex_arg_four_valuekey_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_arg_four_valuekey_auxiliary_temp_cs:nnnn##1##2##3##4 { #3 }
	\tl_set:Nn\l__semantex_arg_four_valuekey_auxiliary_temp_tl{}
	\semantex_preprocess_arg_keys:oN
	{
		\l__semantex_arg_four_valuekey_auxiliary_temp_cs:nnnn { ##2 } { ##3 } { ##4 } { ##5 }
	} \l__semantex_arg_four_valuekey_auxiliary_temp_tl
	\cs_set_protected:cpo { __semantex_data_cs_custom_arg_four_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnn } ##1##2##3##4##5
	{
		\l__semantex_arg_four_valuekey_auxiliary_temp_tl
	}
	\cs_set_protected:cpn { __semantex_data_cs_custom_arg_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2
	{
		\use:c { __semantex_data_cs_custom_arg_four_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnn } { ##1 } ##2
	}
}

\cs_new_protected:Npn\semantex_define_arg_five_valuekeys:nn#1#2
{
	% Add new argument valuekeys with 5 values
	\clist_map_inline:nn { #2 }{
		\__semantex_arg_five_valuekey_format_auxiliary:nnn{#1}##1
	}
}

\cs_new_protected:Npn\__semantex_arg_five_valuekey_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_arg_five_valuekey_auxiliary_temp_cs:nnnnn##1##2##3##4##5 { #3 }
	\tl_set:Nn\l__semantex_arg_five_valuekey_auxiliary_temp_tl{}
	\semantex_preprocess_arg_keys:oN
	{
		\l__semantex_arg_five_valuekey_auxiliary_temp_cs:nnnnn { ##2 } { ##3 } { ##4 } { ##5 } { ##6 }
	} \l__semantex_arg_five_valuekey_auxiliary_temp_tl
	\cs_set_protected:cpo { __semantex_data_cs_custom_arg_five_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnn } ##1##2##3##4##5##6
	{
		\l__semantex_arg_five_valuekey_auxiliary_temp_tl
	}
	\cs_set_protected:cpn { __semantex_data_cs_custom_arg_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2
	{
		\use:c { __semantex_data_cs_custom_arg_five_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnn } { ##1 } ##2
	}
}

\cs_new_protected:Npn\semantex_define_arg_six_valuekeys:nn#1#2
{
	% Add new argument valuekeys with 6 values
	\clist_map_inline:nn { #2 }{
		\__semantex_arg_six_valuekey_format_auxiliary:nnn{#1}##1
	}
}

\cs_new_protected:Npn\__semantex_arg_six_valuekey_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_arg_six_valuekey_auxiliary_temp_cs:nnnnnn##1##2##3##4##5##6 { #3 }
	\tl_set:Nn\l__semantex_arg_six_valuekey_auxiliary_temp_tl{}
	\semantex_preprocess_arg_keys:oN
	{
		\l__semantex_arg_six_valuekey_auxiliary_temp_cs:nnnnnn { ##2 } { ##3 } { ##4 } { ##5 } { ##6 } { ##7 }
	} \l__semantex_arg_six_valuekey_auxiliary_temp_tl
	\cs_set_protected:cpo { __semantex_data_cs_custom_arg_six_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnn } ##1##2##3##4##5##6##7
	{
		\l__semantex_arg_six_valuekey_auxiliary_temp_tl
	}
	\cs_set_protected:cpn { __semantex_data_cs_custom_arg_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2
	{
		\use:c { __semantex_data_cs_custom_arg_six_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnn } { ##1 } ##2
	}
}

\cs_new_protected:Npn\semantex_define_arg_seven_valuekeys:nn#1#2
{
	% Add new argument valuekeys with 7 values
	\clist_map_inline:nn { #2 }{
		\__semantex_arg_seven_valuekey_format_auxiliary:nnn{#1}##1
	}
}

\cs_new_protected:Npn\__semantex_arg_seven_valuekey_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_arg_seven_valuekey_auxiliary_temp_cs:nnnnnnn##1##2##3##4##5##6##7 { #3 }
	\tl_set:Nn\l__semantex_arg_seven_valuekey_auxiliary_temp_tl{}
	\semantex_preprocess_arg_keys:oN
	{
		\l__semantex_arg_seven_valuekey_auxiliary_temp_cs:nnnnnnn { ##2 } { ##3 } { ##4 } { ##5 } { ##6 } { ##7 } { ##8 }
	} \l__semantex_arg_seven_valuekey_auxiliary_temp_tl
	\cs_set_protected:cpo { __semantex_data_cs_custom_arg_seven_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnnn } ##1##2##3##4##5##6##7##8
	{
		\l__semantex_arg_seven_valuekey_auxiliary_temp_tl
	}
	\cs_set_protected:cpn { __semantex_data_cs_custom_arg_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2
	{
		\use:c { __semantex_data_cs_custom_arg_seven_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnnn } { ##1 } ##2
	}
}

\cs_new_protected:Npn\semantex_define_arg_eight_valuekeys:nn#1#2
{
	% Add new argument valuekeys with 8 values
	\clist_map_inline:nn { #2 }{
		\__semantex_arg_eight_valuekey_format_auxiliary:nnn{#1}##1
	}
}

\cs_new_protected:Npn\__semantex_arg_eight_valuekey_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_arg_eight_valuekey_auxiliary_temp_cs:nnnnnnnn##1##2##3##4##5##6##7##8 { #3 }
	\tl_set:Nn\l__semantex_arg_eight_valuekey_auxiliary_temp_tl{}
	\semantex_preprocess_arg_keys:oN
	{
		\l__semantex_arg_eight_valuekey_auxiliary_temp_cs:nnnnnnnn { ##2 } { ##3 } { ##4 } { ##5 } { ##6 } { ##7 } { ##8 } { ##9 }
	} \l__semantex_arg_eight_valuekey_auxiliary_temp_tl
	\cs_set_protected:cpo { __semantex_data_cs_custom_arg_eight_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnnnn } ##1##2##3##4##5##6##7##8##9
	{
		\l__semantex_arg_eight_valuekey_auxiliary_temp_tl
	}
	\cs_set_protected:cpn { __semantex_data_cs_custom_arg_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2
	{
		\use:c { __semantex_data_cs_custom_arg_eight_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnnnn } { ##1 } ##2
	}
}

%\cs_new_protected:Npn\semantex_define_arg_nine_valuekeys:nn#1#2
%{
%	% Add new argument valuekeys with 9 values
%	\clist_map_inline:nn { #2 }{
%		\__semantex_arg_nine_valuekey_format_auxiliary:nnn{#1}##1
%	}
%}
%
%\cs_new_protected:Npn\__semantex_arg_nine_valuekey_format_auxiliary:nnn#1#2#3
%{
%	\cs_set:Npn\l__semantex_arg_nine_valuekey_auxiliary_temp_cs:nnnnnnnnn##1##2##3##4##5##6##7##8##9 { #3 }
%	\tl_set:Nn\l__semantex_arg_nine_valuekey_auxiliary_temp_tl{}
%	\cs_set:Npn\l__semantex_arg_nine_valuekey_auxiliary_singlekey_temp_cs:n##1
%	{
%		\__semantex_preprocess_arg_singlekey:nnN { \__semantex_arg_nine_valuekey_format_auxiliary_name_of_register_temp_tl } { ##1 } \l__semantex_arg_nine_valuekey_auxiliary_temp_tl
%	}
%	\cs_set:Npn\l__semantex_arg_nine_valuekey_auxiliary_valuekey_temp_cs:nn##1##2
%	{
%		\__semantex_preprocess_arg_valuekey:nnnN { \__semantex_arg_nine_valuekey_format_auxiliary_name_of_register_temp_tl  } { ##1 } { ##2 } \l__semantex_arg_nine_valuekey_auxiliary_temp_tl
%	}
%	\semantex_keyval_parse:NNo
%		\l__semantex_arg_nine_valuekey_auxiliary_singlekey_temp_cs:n
%		\l__semantex_arg_nine_valuekey_auxiliary_valuekey_temp_cs:nn
%		{
%			\l__semantex_arg_nine_valuekey_auxiliary_temp_cs:nnnnnnnnn { ##1 } { ##2 } { ##3 } { ##4 } { ##5 } { ##6 } { ##7 } { ##8 } { ##9 }
%		}
%	\cs_set_protected:cpo { __semantex_data_cs_custom_arg_nine_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnnnn } ##1##2##3##4##5##6##7##8##9
%	{
%		\l__semantex_arg_nine_valuekey_auxiliary_temp_tl
%	}
%	\cs_set_protected:cpn { __semantex_data_cs_custom_arg_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2
%	{
%		\tl_set:Nn \__semantex_arg_nine_valuekey_format_auxiliary_name_of_register_temp_tl  { ##1 }
%		\use:c { __semantex_data_cs_custom_arg_nine_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnnnn } ##2
%	}
%}


\cs_new_protected:Npn\semantex_append_arg_valuekeys:nn#1#2
{
	% Appends keys taking one value
	\clist_map_inline:nn { #2 }{
		\__semantex_append_arg_valuekeys_format_auxiliary:nnn { #1 } ##1
	}
}

\cs_new_protected:Npn\__semantex_append_arg_valuekeys_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_append_arg_valuekeys_auxiliary_temp_cs:n##1 { #3 }
	\tl_set:Nn \l__semantex_append_arg_valuekeys_auxiliary_temp_tl {}
	\semantex_preprocess_arg_keys:oN
	{
		\l__semantex_append_arg_valuekeys_auxiliary_temp_cs:n { ##2 }
	} \l__semantex_append_arg_valuekeys_auxiliary_temp_tl
	\semantex_arg_valuekey_store:nnN { #1 } { #2 } \l__semantex_append_arg_valuekeys_auxiliary_original_temp_tl
	\exp_args:Nnx\cs_set_protected:cn
		% \cs_set_protected:cx gave us ##1 where we wanted #1
	{ __semantex_data_cs_custom_arg_valuekey_#1_\tl_trim_spaces:n{#2}:nn }
	{
		\exp_not:V\l__semantex_append_arg_valuekeys_auxiliary_original_temp_tl
		\exp_not:V\l__semantex_append_arg_valuekeys_auxiliary_temp_tl
	}
}

\cs_new_protected:Npn\semantex_prepend_arg_valuekeys:nn#1#2
{
	% Prepends keys taking one value
	\clist_map_inline:nn { #2 }{
		\__semantex_prepend_arg_valuekeys_format_auxiliary:nnn { #1 } ##1
	}
}

\cs_new_protected:Npn\__semantex_prepend_arg_valuekeys_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_prepend_arg_valuekeys_auxiliary_temp_cs:n##1 { #3 }
	\tl_set:Nn \l__semantex_prepend_arg_valuekeys_auxiliary_temp_tl {}
	\semantex_preprocess_arg_keys:oN
	{
		\l__semantex_prepend_arg_valuekeys_auxiliary_temp_cs:n { ##2 }
	} \l__semantex_prepend_arg_valuekeys_auxiliary_temp_tl
	\semantex_arg_valuekey_store:nnN { #1 } { #2 } \l__semantex_prepend_arg_valuekeys_auxiliary_original_temp_tl
	\exp_args:Nnx\cs_set_protected:cn
		% \cs_set_protected:cx gave us ##1 where we wanted #1
	{ __semantex_data_cs_custom_arg_valuekey_#1_\tl_trim_spaces:n{#2}:nn }
	{
		\exp_not:V\l__semantex_prepend_arg_valuekeys_auxiliary_temp_tl
		\exp_not:V\l__semantex_prepend_arg_valuekeys_auxiliary_original_temp_tl
	}
}

\cs_new_protected:Npn\semantex_append_arg_singlekeys:nn#1#2
{
	% Appends keys taking no values
	\clist_map_inline:nn { #2 }{
		\__semantex_append_arg_singlekeys_format_auxiliary:nnn { #1 } ##1
	}
}

\cs_new_protected:Npn \__semantex_append_arg_singlekeys_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_append_arg_singlekeys_auxiliary_temp_cs: { #3 }
	\tl_set:Nn \l__semantex_append_arg_singlekeys_auxiliary_temp_tl {}
	\semantex_preprocess_arg_keys:oN
	{
		\l__semantex_append_arg_singlekeys_auxiliary_temp_cs:
	} \l__semantex_append_arg_singlekeys_auxiliary_temp_tl
	\semantex_arg_singlekey_store:nnN { #1 } { #2 } \l__semantex_append_arg_singlekeys_auxiliary_original_temp_tl
	\exp_args:Nnx\cs_set_protected:cn
		% \cs_set_protected:cx gave us ##1 where we wanted #1
	{ __semantex_data_cs_custom_arg_singlekey_#1_\tl_trim_spaces:n{#2}:n }
	{
		\exp_not:V\l__semantex_append_arg_singlekeys_auxiliary_original_temp_tl
		\exp_not:V\l__semantex_append_arg_singlekeys_auxiliary_temp_tl
	}
}

\cs_new_protected:Npn\semantex_prepend_arg_singlekeys:nn#1#2
{
	% Prepend_args keys taking no values
	\clist_map_inline:nn { #2 }{
		\__semantex_prepend_arg_singlekeys_format_auxiliary:nnn { #1 } ##1
	}
}

\cs_new_protected:Npn \__semantex_prepend_arg_singlekeys_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_prepend_arg_singlekeys_auxiliary_temp_cs: { #3 }
	\tl_set:Nn \l__semantex_prepend_arg_singlekeys_auxiliary_temp_tl {}
	\semantex_preprocess_arg_keys:oN
	{
		\l__semantex_prepend_arg_singlekeys_auxiliary_temp_cs:
	} \l__semantex_prepend_arg_singlekeys_auxiliary_temp_tl
	\semantex_arg_singlekey_store:nnN { #1 } { #2 } \l__semantex_prepend_arg_singlekeys_auxiliary_original_temp_tl
	\exp_args:Nnx\cs_set_protected:cn
		% \cs_set_protected:cx gave us ##1 where we wanted #1
	{ __semantex_data_cs_custom_arg_singlekey_#1_\tl_trim_spaces:n{#2}:n }
	{
		\exp_not:V\l__semantex_prepend_arg_singlekeys_auxiliary_temp_tl
		\exp_not:V\l__semantex_prepend_arg_singlekeys_auxiliary_original_temp_tl
	}
}

\cs_new_protected:Npn\semantex_append_arg_two_valuekeys:nn#1#2
{
	% Appends valuekeys with 2 values
	\clist_map_inline:nn { #2 }{
		\__semantex_append_arg_two_valuekey_format_auxiliary:nnn { #1 } ##1
	}
}

\cs_new_protected:Npn\__semantex_append_arg_two_valuekey_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_append_arg_two_valuekey_auxiliary_temp_cs:nn##1##2 { #3 }
	\tl_set:Nn\l__semantex_append_arg_two_valuekey_auxiliary_temp_tl{}
	\semantex_preprocess_arg_keys:oN
	{
		\l__semantex_append_arg_two_valuekey_auxiliary_temp_cs:nn { ##2 } { ##3 }
	} \l__semantex_append_arg_two_valuekey_auxiliary_temp_tl
	\semantex_arg_two_valuekey_store:nnN { #1 } { #2 } \l__semantex_append_arg_two_valuekey_auxiliary_original_temp_tl
	\exp_args:Nnx\cs_set_protected:cn { __semantex_data_cs_custom_arg_two_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnn }
	{
		\exp_not:V\l__semantex_append_arg_two_valuekey_auxiliary_original_temp_tl
		\exp_not:V\l__semantex_append_arg_two_valuekey_auxiliary_temp_tl
	}
	\cs_set_protected:cpn { __semantex_data_cs_custom_arg_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2
	{
		\use:c { __semantex_data_cs_custom_arg_two_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnn } { ##1 } ##2
	}
}

\cs_new_protected:Npn\semantex_prepend_arg_two_valuekeys:nn#1#2
{
	% Prepends valuekeys with 2 values
	\clist_map_inline:nn { #2 }{
		\__semantex_prepend_arg_two_valuekey_format_auxiliary:nnn { #1 } ##1
	}
}

\cs_new_protected:Npn\__semantex_prepend_arg_two_valuekey_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_prepend_arg_two_valuekey_auxiliary_temp_cs:nn##1##2 { #3 }
	\tl_set:Nn\l__semantex_prepend_arg_two_valuekey_auxiliary_temp_tl{}
	\semantex_preprocess_arg_keys:oN
	{
		\l__semantex_prepend_arg_two_valuekey_auxiliary_temp_cs:nn { ##2 } { ##3 }
	} \l__semantex_prepend_arg_two_valuekey_auxiliary_temp_tl
	\semantex_arg_two_valuekey_store:nnN { #1 } { #2 } \l__semantex_prepend_arg_two_valuekey_auxiliary_original_temp_tl
	\exp_args:Nnx\cs_set_protected:cn { __semantex_data_cs_custom_arg_two_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnn }
	{
		\exp_not:V\l__semantex_prepend_arg_two_valuekey_auxiliary_original_temp_tl
		\exp_not:V\l__semantex_prepend_arg_two_valuekey_auxiliary_temp_tl
	}
	\cs_set_protected:cpn { __semantex_data_cs_custom_arg_arg_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2
	{
		\use:c { __semantex_data_cs_custom_arg_two_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnn } { ##1 } ##2
	}
}

\cs_new_protected:Npn\semantex_append_arg_three_valuekeys:nn#1#2
{
	% Appends valuekeys with 3 values
	\clist_map_inline:nn { #2 }{
		\__semantex_append_arg_three_valuekey_format_auxiliary:nnn {#1} ##1
	}
}

\cs_new_protected:Npn\__semantex_append_arg_three_valuekey_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_append_arg_three_valuekey_auxiliary_temp_cs:nnn##1##2##3 { #3 }
	\tl_set:Nn\l__semantex_append_arg_three_valuekey_auxiliary_temp_tl{}
	\semantex_preprocess_arg_keys:oN
	{
		\l__semantex_append_arg_three_valuekey_auxiliary_temp_cs:nnn { ##2 } { ##3 } { ##4 }
	} \l__semantex_append_arg_three_valuekey_auxiliary_temp_tl
	\semantex_arg_three_valuekey_store:nnN { #1 } { #2 } \l__semantex_append_arg_three_valuekey_auxiliary_original_temp_tl
	\exp_args:Nnx\cs_set_protected:cn { __semantex_data_cs_custom_arg_three_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnn }
	{
		\exp_not:V\l__semantex_append_arg_three_valuekey_auxiliary_original_temp_tl
		\exp_not:V\l__semantex_append_arg_three_valuekey_auxiliary_temp_tl
	}
	\cs_set_protected:cpn { __semantex_data_cs_custom_arg_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2
	{
		\use:c { __semantex_data_cs_custom_arg_three_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnn } { ##1 } ##2
	}
}

\cs_new_protected:Npn\semantex_prepend_arg_three_valuekeys:nn#1#2
{
	% Prepends valuekeys with 3 values
	\clist_map_inline:nn { #2 }{
		\__semantex_prepend_arg_three_valuekey_format_auxiliary:nnn {#1} ##1
	}
}

\cs_new_protected:Npn\__semantex_prepend_arg_three_valuekey_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_prepend_arg_three_valuekey_auxiliary_temp_cs:nnn##1##2##3 { #3 }
	\tl_set:Nn\l__semantex_prepend_arg_three_valuekey_auxiliary_temp_tl{}
	\semantex_preprocess_arg_keys:oN
	{
		\l__semantex_prepend_arg_three_valuekey_auxiliary_temp_cs:nnn { ##2 } { ##3 } { ##4 }
	} \l__semantex_prepend_arg_three_valuekey_auxiliary_temp_tl
	\semantex_arg_three_valuekey_store:nnN { #1 } { #2 } \l__semantex_prepend_arg_three_valuekey_auxiliary_original_temp_tl
	\exp_args:Nnx\cs_set_protected:cn { __semantex_data_cs_custom_arg_three_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnn }
	{
		\exp_not:V\l__semantex_prepend_arg_three_valuekey_auxiliary_temp_tl
		\exp_not:V\l__semantex_prepend_arg_three_valuekey_auxiliary_original_temp_tl
	}
	\cs_set_protected:cpn { __semantex_data_cs_custom_arg_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2
	{
		\use:c { __semantex_data_cs_custom_arg_three_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnn } { ##1 } ##2
	}
}

\cs_new_protected:Npn\semantex_append_arg_four_valuekeys:nn#1#2
{
	% Appends valuekeys with 4 values
	\clist_map_inline:nn { #2 }{
		\__semantex_append_arg_four_valuekey_format_auxiliary:nnn{#1}##1
	}
}

\cs_new_protected:Npn\__semantex_append_arg_four_valuekey_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_append_arg_four_valuekey_auxiliary_temp_cs:nnnn##1##2##3##4 { #3 }
	\tl_set:Nn\l__semantex_append_arg_four_valuekey_auxiliary_temp_tl{}
	\semantex_preprocess_arg_keys:oN
	{
		\l__semantex_append_arg_four_valuekey_auxiliary_temp_cs:nnnn { ##2 } { ##3 } { ##4 } { ##5 }
	} \l__semantex_append_arg_four_valuekey_auxiliary_temp_tl
	\semantex_arg_four_valuekey_store:nnN { #1 } { #2 } \l__semantex_append_arg_four_valuekey_auxiliary_original_temp_tl
	\exp_args:Nnx\cs_set_protected:cn { __semantex_data_cs_custom_arg_four_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnn }
	{
		\exp_not:V\l__semantex_append_arg_four_valuekey_auxiliary_original_temp_tl
		\exp_not:V\l__semantex_append_arg_four_valuekey_auxiliary_temp_tl
	}
	\cs_set_protected:cpn { __semantex_data_cs_custom_arg_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2
	{
		\use:c { __semantex_data_cs_custom_arg_four_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnn } { ##1 } ##2
	}
}

\cs_new_protected:Npn\semantex_prepend_arg_four_valuekeys:nn#1#2
{
	% Prepends valuekeys with 4 values
	\clist_map_inline:nn { #2 }{
		\__semantex_prepend_arg_four_valuekey_format_auxiliary:nnn{#1}##1
	}
}

\cs_new_protected:Npn\__semantex_prepend_arg_four_valuekey_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_prepend_arg_four_valuekey_auxiliary_temp_cs:nnnn##1##2##3##4 { #3 }
	\tl_set:Nn\l__semantex_prepend_arg_four_valuekey_auxiliary_temp_tl{}
	\semantex_preprocess_arg_keys:oN
	{
		\l__semantex_prepend_arg_four_valuekey_auxiliary_temp_cs:nnnn { ##2 } { ##3 } { ##4 } { ##5 }
	} \l__semantex_prepend_arg_four_valuekey_auxiliary_temp_tl
	\semantex_arg_four_valuekey_store:nnN { #1 } { #2 } \l__semantex_prepend_arg_four_valuekey_auxiliary_original_temp_tl
	\exp_args:Nnx\cs_set_protected:cn { __semantex_data_cs_custom_arg_four_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnn }
	{
		\exp_not:V\l__semantex_prepend_arg_four_valuekey_auxiliary_temp_tl
		\exp_not:V\l__semantex_prepend_arg_four_valuekey_auxiliary_original_temp_tl
	}
	\cs_set_protected:cpn { __semantex_data_cs_custom_arg_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2
	{
		\use:c { __semantex_data_cs_custom_arg_four_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnn } { ##1 } ##2
	}
}

\cs_new_protected:Npn\semantex_append_arg_five_valuekeys:nn#1#2
{
	% Appends valuekeys with 5 values
	\clist_map_inline:nn { #2 }{
		\__semantex_append_arg_five_valuekey_format_auxiliary:nnn{#1}##1
	}
}

\cs_new_protected:Npn\__semantex_append_arg_five_valuekey_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_append_arg_five_valuekey_auxiliary_temp_cs:nnnnn##1##2##3##4##5 { #3 }
	\tl_set:Nn\l__semantex_append_arg_five_valuekey_auxiliary_temp_tl{}
	\semantex_preprocess_arg_keys:oN
	{
		\l__semantex_append_arg_five_valuekey_auxiliary_temp_cs:nnnnn { ##2 } { ##3 } { ##4 } { ##5 } { ##6 }
	} \l__semantex_append_arg_five_valuekey_auxiliary_temp_tl
	\semantex_arg_five_valuekey_store:nnN { #1 } { #2 } \l__semantex_append_arg_five_valuekey_auxiliary_original_temp_tl
	\exp_args:Nnx\cs_set_protected:cn { __semantex_data_cs_custom_arg_five_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnn }
	{
		\exp_not:V\l__semantex_append_arg_five_valuekey_auxiliary_original_temp_tl
		\exp_not:V\l__semantex_append_arg_five_valuekey_auxiliary_temp_tl
	}
	\cs_set_protected:cpn { __semantex_data_cs_custom_arg_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2
	{
		\use:c { __semantex_data_cs_custom_arg_five_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnn } { ##1 } ##2
	}
}

\cs_new_protected:Npn\semantex_prepend_arg_five_valuekeys:nn#1#2
{
	% Prepends valuekeys with 5 values
	\clist_map_inline:nn { #2 }{
		\__semantex_prepend_arg_five_valuekey_format_auxiliary:nnn{#1}##1
	}
}

\cs_new_protected:Npn\__semantex_prepend_arg_five_valuekey_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_prepend_arg_five_valuekey_auxiliary_temp_cs:nnnnn##1##2##3##4##5 { #3 }
	\tl_set:Nn\l__semantex_prepend_arg_five_valuekey_auxiliary_temp_tl{}
	\semantex_preprocess_arg_keys:oN
	{
		\l__semantex_prepend_arg_five_valuekey_auxiliary_temp_cs:nnnnn { ##2 } { ##3 } { ##4 } { ##5 } { ##6 }
	} \l__semantex_prepend_arg_five_valuekey_auxiliary_temp_tl
	\semantex_arg_five_valuekey_store:nnN { #1 } { #2 } \l__semantex_prepend_arg_five_valuekey_auxiliary_original_temp_tl
	\exp_args:Nnx\cs_set_protected:cn { __semantex_data_cs_custom_arg_five_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnn }
	{
		\exp_not:V\l__semantex_prepend_arg_five_valuekey_auxiliary_temp_tl
		\exp_not:V\l__semantex_prepend_arg_five_valuekey_auxiliary_original_temp_tl
	}
	\cs_set_protected:cpn { __semantex_data_cs_custom_arg_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2
	{
		\use:c { __semantex_data_cs_custom_arg_five_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnn } { ##1 } ##2
	}
}

\cs_new_protected:Npn\semantex_append_arg_six_valuekeys:nn#1#2
{
	% Appends valuekeys with 6 values
	\clist_map_inline:nn { #2 }{
		\__semantex_append_arg_six_valuekey_format_auxiliary:nnn{#1}##1
	}
}

\cs_new_protected:Npn\__semantex_append_arg_six_valuekey_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_append_arg_six_valuekey_auxiliary_temp_cs:nnnnnn##1##2##3##4##5##6 { #3 }
	\tl_set:Nn\l__semantex_append_arg_six_valuekey_auxiliary_temp_tl{}
	\semantex_preprocess_arg_keys:oN
	{
		\l__semantex_append_arg_six_valuekey_auxiliary_temp_cs:nnnnnn { ##2 } { ##3 } { ##4 } { ##5 } { ##6 } { ##7 }
	} \l__semantex_append_arg_six_valuekey_auxiliary_temp_tl
	\semantex_arg_six_valuekey_store:nnN { #1 } { #2 } \l__semantex_append_arg_six_valuekey_auxiliary_original_temp_tl
	\exp_args:Nnx\cs_set_protected:cn { __semantex_data_cs_custom_arg_six_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnn }
	{
		\exp_not:V\l__semantex_append_arg_six_valuekey_auxiliary_original_temp_tl
		\exp_not:V\l__semantex_append_arg_six_valuekey_auxiliary_temp_tl
	}
	\cs_set_protected:cpn { __semantex_data_cs_custom_arg_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2
	{
		\use:c { __semantex_data_cs_custom_arg_six_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnn } { ##1 } ##2
	}
}

\cs_new_protected:Npn\semantex_prepend_arg_six_valuekeys:nn#1#2
{
	% Prepends valuekeys with 6 values
	\clist_map_inline:nn { #2 }{
		\__semantex_prepend_arg_six_valuekey_format_auxiliary:nnn{#1}##1
	}
}

\cs_new_protected:Npn\__semantex_prepend_arg_six_valuekey_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_prepend_arg_six_valuekey_auxiliary_temp_cs:nnnnnn##1##2##3##4##5##6 { #3 }
	\tl_set:Nn\l__semantex_prepend_arg_six_valuekey_auxiliary_temp_tl{}
	\semantex_preprocess_arg_keys:oN
	{
		\l__semantex_prepend_arg_six_valuekey_auxiliary_temp_cs:nnnnnn { ##2 } { ##3 } { ##4 } { ##5 } { ##6 } { ##7 }
	} \l__semantex_prepend_arg_six_valuekey_auxiliary_temp_tl
	\semantex_arg_six_valuekey_store:nnN { #1 } { #2 } \l__semantex_prepend_arg_six_valuekey_auxiliary_original_temp_tl
	\exp_args:Nnx\cs_set_protected:cn { __semantex_data_cs_custom_arg_six_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnn }
	{
		\exp_not:V\l__semantex_prepend_arg_six_valuekey_auxiliary_original_temp_tl
		\exp_not:V\l__semantex_prepend_arg_six_valuekey_auxiliary_temp_tl
	}
	\cs_set_protected:cpn { __semantex_data_cs_custom_arg_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2
	{
		\use:c { __semantex_data_cs_custom_arg_six_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnn } { ##1 } ##2
	}
}

\cs_new_protected:Npn\semantex_append_arg_seven_valuekeys:nn#1#2
{
	% Appends valuekeys with 7 values
	\clist_map_inline:nn { #2 }{
		\__semantex_append_arg_seven_valuekey_format_auxiliary:nnn{#1}##1
	}
}

\cs_new_protected:Npn\__semantex_append_arg_seven_valuekey_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_append_arg_seven_valuekey_auxiliary_temp_cs:nnnnnnn##1##2##3##4##5##6##7 { #3 }
	\tl_set:Nn\l__semantex_append_arg_seven_valuekey_auxiliary_temp_tl{}
	\semantex_preprocess_arg_keys:oN
	{
		\l__semantex_append_arg_seven_valuekey_auxiliary_temp_cs:nnnnnnn { ##2 } { ##3 } { ##4 } { ##5 } { ##6 } { ##7 } { ##8 }
	} \l__semantex_append_arg_seven_valuekey_auxiliary_temp_tl
	\semantex_arg_seven_valuekey_store:nnN { #1 } { #2 } \l__semantex_append_arg_seven_valuekey_auxiliary_original_temp_tl
	\exp_args:Nnx\cs_set_protected:cn { __semantex_data_cs_custom_arg_seven_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnnn }
	{
		\exp_not:V\l__semantex_append_arg_seven_valuekey_auxiliary_original_temp_tl
		\exp_not:V\l__semantex_append_arg_seven_valuekey_auxiliary_temp_tl
	}
	\cs_set_protected:cpn { __semantex_data_cs_custom_arg_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2
	{
		\use:c { __semantex_data_cs_custom_arg_seven_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnnn } { ##1 } ##2
	}
}

\cs_new_protected:Npn\semantex_prepend_arg_seven_valuekeys:nn#1#2
{
	% Prepends valuekeys with 7 values
	\clist_map_inline:nn { #2 }{
		\__semantex_prepend_arg_seven_valuekey_format_auxiliary:nnn{#1}##1
	}
}

\cs_new_protected:Npn\__semantex_prepend_arg_seven_valuekey_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_prepend_arg_seven_valuekey_auxiliary_temp_cs:nnnnnnn##1##2##3##4##5##6##7 { #3 }
	\tl_set:Nn\l__semantex_prepend_arg_seven_valuekey_auxiliary_temp_tl{}
	\semantex_preprocess_arg_keys:oN
	{
		\l__semantex_prepend_arg_seven_valuekey_auxiliary_temp_cs:nnnnnnn { ##2 } { ##3 } { ##4 } { ##5 } { ##6 } { ##7 } { ##8 }
	} \l__semantex_prepend_arg_seven_valuekey_auxiliary_temp_tl
	\semantex_arg_seven_valuekey_store:nnN { #1 } { #2 } \l__semantex_prepend_arg_seven_valuekey_auxiliary_original_temp_tl
	\exp_args:Nnx\cs_set_protected:cn { __semantex_data_cs_custom_arg_seven_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnnn }
	{
		\exp_not:V\l__semantex_prepend_arg_seven_valuekey_auxiliary_original_temp_tl
		\exp_not:V\l__semantex_prepend_arg_seven_valuekey_auxiliary_temp_tl
	}
	\cs_set_protected:cpn { __semantex_data_cs_custom_arg_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2
	{
		\use:c { __semantex_data_cs_custom_arg_seven_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnnn } { ##1 } ##2
	}
}

\cs_new_protected:Npn\semantex_append_arg_eight_valuekeys:nn#1#2
{
	% Appends valuekeys with 8 values
	\clist_map_inline:nn { #2 }{
		\__semantex_append_arg_eight_valuekey_format_auxiliary:nnn{#1}##1
	}
}

\cs_new_protected:Npn\__semantex_append_arg_eight_valuekey_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_append_arg_eight_valuekey_auxiliary_temp_cs:nnnnnnnn##1##2##3##4##5##6##7##8 { #3 }
	\tl_set:Nn\l__semantex_append_arg_eight_valuekey_auxiliary_temp_tl{}
	\semantex_preprocess_arg_keys:oN
	{
		\l__semantex_append_arg_eight_valuekey_auxiliary_temp_cs:nnnnnnnn { ##2 } { ##3 } { ##4 } { ##5 } { ##6 } { ##7 } { ##8 } { ##9 }
	} \l__semantex_append_arg_eight_valuekey_auxiliary_temp_tl
	\semantex_arg_eight_valuekey_store:nnN { #1 } { #2 } \l__semantex_append_arg_eight_valuekey_auxiliary_original_temp_tl
	\exp_args:Nnx\cs_set_protected:cn { __semantex_data_cs_custom_arg_eight_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnnnn }
	{
		\exp_not:V\l__semantex_append_arg_eight_valuekey_auxiliary_original_temp_tl
		\exp_not:V\l__semantex_append_arg_eight_valuekey_auxiliary_temp_tl
	}
	\cs_set_protected:cpn { __semantex_data_cs_custom_arg_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2
	{
		\use:c { __semantex_data_cs_custom_arg_eight_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnnnn } { ##1 } ##2
	}
}

\cs_new_protected:Npn\semantex_prepend_arg_eight_valuekeys:nn#1#2
{
	% Prepends valuekeys with 8 values
	\clist_map_inline:nn { #2 }{
		\__semantex_prepend_arg_eight_valuekey_format_auxiliary:nnn{#1}##1
	}
}

\cs_new_protected:Npn\__semantex_prepend_arg_eight_valuekey_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_prepend_arg_eight_valuekey_auxiliary_temp_cs:nnnnnnnn##1##2##3##4##5##6##7##8 { #3 }
	\tl_set:Nn\l__semantex_prepend_arg_eight_valuekey_auxiliary_temp_tl{}
	\semantex_preprocess_arg_keys:oN
	{
		\l__semantex_prepend_arg_eight_valuekey_auxiliary_temp_cs:nnnnnnnn { ##2 } { ##3 } { ##4 } { ##5 } { ##6 } { ##7 } { ##8 } { ##9 }
	} \l__semantex_prepend_arg_eight_valuekey_auxiliary_temp_tl
	\semantex_arg_eight_valuekey_store:nnN { #1 } { #2 } \l__semantex_prepend_arg_eight_valuekey_auxiliary_original_temp_tl
	\exp_args:Nnx\cs_set_protected:cn { __semantex_data_cs_custom_arg_eight_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnnnn }
	{
		\exp_not:V\l__semantex_prepend_arg_eight_valuekey_auxiliary_temp_tl
		\exp_not:V\l__semantex_prepend_arg_eight_valuekey_auxiliary_original_temp_tl
	}
	\cs_set_protected:cpn { __semantex_data_cs_custom_arg_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2
	{
		\use:c { __semantex_data_cs_custom_arg_eight_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnnnn } { ##1 } ##2
	}
}

%\cs_new_protected:Npn\semantex_append_arg_nine_valuekeys:nn#1#2
%{
%	% Appends valuekeys with 9 values
%	\clist_map_inline:nn { #2 }{
%		\__semantex_append_arg_nine_valuekey_format_auxiliary:nnn{#1}##1
%	}
%}
%
%\cs_new_protected:Npn\__semantex_append_arg_nine_valuekey_format_auxiliary:nnn#1#2#3
%{
%	\cs_set:Npn\l__semantex_append_arg_nine_valuekey_auxiliary_temp_cs:nnnnnnnnn##1##2##3##4##5##6##7##8##9 { #3 }
%	\tl_set:Nn\l__semantex_append_arg_nine_valuekey_auxiliary_temp_tl{}
%	\cs_set:Npn\l__semantex_append_arg_nine_valuekey_auxiliary_singlekey_temp_cs:n##1
%	{
%		\__semantex_preprocess_arg_singlekey:nnN { \__semantex_arg_nine_valuekey_format_auxiliary_name_of_register_temp_tl } { ##1 } \l__semantex_append_arg_nine_valuekey_auxiliary_temp_tl
%	}
%	\cs_set:Npn\l__semantex_append_arg_nine_valuekey_auxiliary_valuekey_temp_cs:nn##1##2
%	{
%		\__semantex_preprocess_arg_valuekey:nnnN { \__semantex_arg_nine_valuekey_format_auxiliary_name_of_register_temp_tl } { ##1 } { ##2 } \l__semantex_append_arg_nine_valuekey_auxiliary_temp_tl
%	}
%	\semantex_keyval_parse:NNo
%		\l__semantex_append_arg_nine_valuekey_auxiliary_singlekey_temp_cs:n
%		\l__semantex_append_arg_nine_valuekey_auxiliary_valuekey_temp_cs:nn
%		{
%			\l__semantex_append_arg_nine_valuekey_auxiliary_temp_cs:nnnnnnnnn { ##1 } { ##2 } { ##3 } { ##4 } { ##5 } { ##6 } { ##7 } { ##8 } { ##9 }
%		}
%	\semantex_arg_nine_valuekey_store:nnN { #1 } { #2 } \l__semantex_append_arg_nine_valuekey_auxiliary_original_temp_tl
%	\exp_args:Nnx\cs_set_protected:cn { __semantex_data_cs_custom_arg_nine_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnnnn }
%	{
%		\exp_not:V\l__semantex_append_arg_nine_valuekey_auxiliary_original_temp_tl
%		\exp_not:V\l__semantex_append_arg_nine_valuekey_auxiliary_temp_tl
%	}
%	\cs_set_protected:cpn { __semantex_data_cs_custom_arg_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2
%	{
%		\tl_set:Nn \__semantex_arg_nine_valuekey_format_auxiliary_name_of_register_temp_tl { ##1 }
%		\use:c { __semantex_data_cs_custom_arg_nine_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnnnn } ##2
%	}
%}
%
%\cs_new_protected:Npn\semantex_prepend_arg_nine_valuekeys:nn#1#2
%{
%	% Prepends valuekeys with 9 values
%	\clist_map_inline:nn { #2 }{
%		\__semantex_prepend_arg_nine_valuekey_format_auxiliary:nnn{#1}##1
%	}
%}
%
%\cs_new_protected:Npn\__semantex_prepend_arg_nine_valuekey_format_auxiliary:nnn#1#2#3
%{
%	\cs_set:Npn\l__semantex_prepend_arg_nine_valuekey_auxiliary_temp_cs:nnnnnnnnn##1##2##3##4##5##6##7##8##9 { #3 }
%	\tl_set:Nn\l__semantex_prepend_arg_nine_valuekey_auxiliary_temp_tl{}
%	\cs_set:Npn\l__semantex_prepend_arg_nine_valuekey_auxiliary_singlekey_temp_cs:n##1
%	{
%		\__semantex_preprocess_arg_singlekey:nnN { \__semantex_arg_nine_valuekey_format_auxiliary_name_of_register_temp_tl } { ##1 } \l__semantex_prepend_arg_nine_valuekey_auxiliary_temp_tl
%	}
%	\cs_set:Npn\l__semantex_prepend_arg_nine_valuekey_auxiliary_valuekey_temp_cs:nn##1##2
%	{
%		\__semantex_preprocess_arg_valuekey:nnnN { \__semantex_arg_nine_valuekey_format_auxiliary_name_of_register_temp_tl } { ##1 } { ##2 } \l__semantex_prepend_arg_nine_valuekey_auxiliary_temp_tl
%	}
%	\semantex_keyval_parse:NNo
%		\l__semantex_prepend_arg_nine_valuekey_auxiliary_singlekey_temp_cs:n
%		\l__semantex_prepend_arg_nine_valuekey_auxiliary_valuekey_temp_cs:nn
%		{
%			\l__semantex_prepend_arg_nine_valuekey_auxiliary_temp_cs:nnnnnnnnn { ##1 } { ##2 } { ##3 } { ##4 } { ##5 } { ##6 } { ##7 } { ##8 } { ##9 }
%		}
%	\semantex_arg_nine_valuekey_store:nnN { #1 } { #2 } \l__semantex_prepend_arg_nine_valuekey_auxiliary_original_temp_tl
%	\exp_args:Nnx\cs_set_protected:cn { __semantex_data_cs_custom_arg_nine_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnnnn }
%	{
%		\exp_not:V\l__semantex_prepend_arg_nine_valuekey_auxiliary_temp_tl
%		\exp_not:V\l__semantex_prepend_arg_nine_valuekey_auxiliary_original_temp_tl
%	}
%	\cs_set_protected:cpn { __semantex_data_cs_custom_arg_valuekey_#1_\tl_trim_spaces:n{#2}:nn } ##1##2
%	{
%		\tl_set:Nn \__semantex_arg_nine_valuekey_format_auxiliary_name_of_register_temp_tl { ##1 }
%		\use:c { __semantex_data_cs_custom_arg_nine_valuekey_#1_\tl_trim_spaces:n{#2}_auxiliary:nnnnnnnnn } ##2
%	}
%}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%		COMMANDS HANDLING OUTPUT OPTIONS
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\cs_new_protected:Npn\semantex_set_output:nn#1#2
{
	% Tells what class the register is supposed to output
	\semantex_class_if_exist:NTF #2
	{
		\semantex_data_tl_set:nnx { #1 } { output } { \semantex_class_to_register:N #2 }
	}
	{
		\semantex_msg_error:nnnn { #1 } { class_not_found } { output } { #2 }
	}
}

\cs_new_protected:Npn\semantex_add_to_output_options:nn#1#2
{
	\tl_set:Nn\l__semantex_output_options_auxiliary_temp_tl{}
	\semantex_preprocess_keys:nN { #2 } \l__semantex_output_options_auxiliary_temp_tl
	\semantex_add_raw_code_to_output_options:no { #1 } { \l__semantex_output_options_auxiliary_temp_tl }
}

\cs_new_protected:Npn\semantex_add_raw_code_to_output_options:nn#1#2
{
	\semantex_data_tl_put_right:nnn { #1 } { output~options } { #2 }
}

\cs_generate_variant:Nn \semantex_add_raw_code_to_output_options:nn { no }

\cs_new_protected:Npn\semantex_add_to_the_left_of_output_options:nn#1#2
{
	\tl_set:Nn\l__semantex_left_of_output_options_auxiliary_temp_tl{}
	\semantex_preprocess_keys:nN { #2 } \l__semantex_left_of_output_options_auxiliary_temp_tl
	\semantex_add_raw_code_to_the_left_of_output_options:no { #1 } { \l__semantex_left_of_output_options_auxiliary_temp_tl }
}

\cs_new_protected:Npn\semantex_add_raw_code_to_the_left_of_output_options:nn#1#2
{
	\semantex_data_tl_put_left:nnn { #1 } { output~options } { #2 }
}

\cs_generate_variant:Nn \semantex_add_raw_code_to_the_left_of_output_options:nn { no }

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%    USER-LEVEL PROGRAMMING KEYS
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\cs_generate_variant:Nn\str_if_eq:nnTF { xxTF }

\cs_generate_variant:Nn\str_if_eq:nnT { xxT }


\cs_generate_variant:Nn\str_if_eq:nnF { xxF }


\cs_generate_variant:Nn\tl_if_blank:nTF { xTF, xT }

\cs_generate_variant:Nn \tl_if_blank:nF { xF }

\cs_generate_variant:Nn \semantex_keys_set:nn { on }

\cs_generate_variant:Nn \semantex_keys_set_x:nn { on }

\cs_new:Npn\semantex_this:{
	\msg_error:nn { semantex } { SemantexThis_in_input_stream }
}
\cs_new:Npn\SemantexThis{\semantex_this:}
\cs_new_protected:Npn\SemantexDataProvide#1{\semantex_data_tl_provide:nn{\semantex_this:}{\tl_trim_spaces:n{#1}}}
\cs_new_protected:Npn\SemantexDataSet#1#2{\semantex_data_tl_set:nnn{\semantex_this:}{\tl_trim_spaces:n{#1}}{#2}}
\cs_new_protected:Npn\SemantexDataSetx#1#2{\semantex_data_tl_set:nnx{\semantex_this:}{\tl_trim_spaces:n{#1}}{#2}}
\cs_new_protected:Npn\SemantexDataPutRight#1#2{\semantex_data_tl_put_right:nnn{\semantex_this:}{\tl_trim_spaces:n{#1}}{#2}}
\cs_new_protected:Npn\SemantexDataPutRightx#1#2{\semantex_data_tl_put_right:nnx{\semantex_this:}{\tl_trim_spaces:n{#1}}{#2}}
\cs_new_protected:Npn\SemantexDataPutLeft#1#2{\semantex_data_tl_put_left:nnn{\semantex_this:}{\tl_trim_spaces:n{#1}}{#2}}
\cs_new_protected:Npn\SemantexDataPutLeftx#1#2{\semantex_data_tl_put_left:nnx{\semantex_this:}{\tl_trim_spaces:n{#1}}{#2}}
\cs_new:Npn\SemantexDataGet#1{\semantex_data_tl_get:nn{\semantex_this:}{\tl_trim_spaces:n{#1}}}
\cs_new:Npn\SemantexDataGetExpNot#1{\semantex_data_tl_get_exp_not:nn{\semantex_this:}{\tl_trim_spaces:n{#1}}}
\cs_new_protected:Npn\SemantexDataClear#1{\semantex_data_tl_clear:nn{\semantex_this:}{\tl_trim_spaces:n{#1}}}
\cs_new_protected:Npn\SemantexSetKeys#1{
	\tl_set:Nn\l__semantex_keys_set_temp_tl{}
	\semantex_preprocess_keys:nN { #1 } \l__semantex_keys_set_temp_tl
	\exp_args:NNo\cs_set:Nn\l__semantex_keys_set_temp_cs:n{\l__semantex_keys_set_temp_tl}
	\l__semantex_keys_set_temp_cs:n { \semantex_this: }
}
\cs_new_protected:Npn\SemantexKeysSet#1{
	\tl_set:Nn\l__semantex_keys_set_temp_tl{}
	\semantex_preprocess_keys:nN { #1 } \l__semantex_keys_set_temp_tl
	\exp_args:NNo\cs_set:Nn\l__semantex_keys_set_temp_cs:n{\l__semantex_keys_set_temp_tl}
	\l__semantex_keys_set_temp_cs:n { \semantex_this: }
}
\cs_new_protected:Npn\SemantexSetKeysx#1{
	\tl_set:Nn\l__semantex_keys_set_x_temp_tl{}
	\semantex_preprocess_keys_x:nN { #1 } \l__semantex_keys_set_x_temp_tl
	\exp_args:NNo\cs_set:Nn\l__semantex_keys_set_x_temp_cs:n{\l__semantex_keys_set_x_temp_tl}
	\l__semantex_keys_set_x_temp_cs:n { \semantex_this: }
}
\cs_new_protected:Npn\SemantexKeysSetx#1{
	\tl_set:Nn\l__semantex_keys_set_x_temp_tl{}
	\semantex_preprocess_keys_x:nN { #1 } \l__semantex_keys_set_x_temp_tl
	\exp_args:NNo\cs_set:Nn\l__semantex_keys_set_x_temp_cs:n{\l__semantex_keys_set_x_temp_tl}
	\l__semantex_keys_set_x_temp_cs:n { \semantex_this: }
}
\cs_new_protected:Npn\SemantexSetArgKeys#1{
	\tl_set:Nn\l__semantex_arg_keys_set_temp_tl{}
	\semantex_preprocess_arg_keys:nN { #1 } \l__semantex_arg_keys_set_temp_tl
	\exp_args:NNo\cs_set:Nn\l__semantex_arg_keys_set_temp_cs:n{\l__semantex_arg_keys_set_temp_tl}
	\l__semantex_arg_keys_set_temp_cs:n { \semantex_this: }
}
\cs_new_protected:Npn\SemantexArgKeysSet#1{
	\tl_set:Nn\l__semantex_arg_keys_set_temp_tl{}
	\semantex_preprocess_arg_keys:nN { #1 } \l__semantex_arg_keys_set_temp_tl
	\exp_args:NNo\cs_set:Nn\l__semantex_arg_keys_set_temp_cs:n{\l__semantex_arg_keys_set_temp_tl}
	\l__semantex_arg_keys_set_temp_cs:n { \semantex_this: }
}
\cs_new_protected:Npn\SemantexSetArgKeysx#1{
	\tl_set:Nn\l__semantex_arg_keys_set_x_temp_tl{}
	\semantex_preprocess_arg_keys_x:nN { #1 } \l__semantex_arg_keys_set_x_temp_tl
	\exp_args:NNo\cs_set:Nn\l__semantex_arg_keys_set_x_temp_cs:n{\l__semantex_arg_keys_set_x_temp_tl}
	\l__semantex_arg_keys_set_x_temp_cs:n { \semantex_this: }
}
\cs_new_protected:Npn\SemantexArgKeysSetx#1{
	\tl_set:Nn\l__semantex_arg_keys_set_x_temp_tl{}
	\semantex_preprocess_arg_keys_x:nN { #1 } \l__semantex_arg_keys_set_x_temp_tl
	\exp_args:NNo\cs_set:Nn\l__semantex_arg_keys_set_x_temp_cs:n{\l__semantex_arg_keys_set_x_temp_tl}
	\l__semantex_arg_keys_set_x_temp_cs:n { \semantex_this: }
}
\cs_new_protected:Npn\SemantexSetArgSingleKeys#1{
	\tl_set:Nn\l__semantex_arg_singlekeys_set_temp_tl{}
	\semantex_preprocess_arg_singlekeys:nN { #1 } \l__semantex_arg_singlekeys_set_temp_tl
	\exp_args:NNo\cs_set:Nn\l__semantex_arg_singlekeys_set_temp_cs:n{\l__semantex_arg_singlekeys_set_temp_tl}
	\l__semantex_arg_singlekeys_set_temp_cs:n { \semantex_this: }
}
\cs_new_protected:Npn\SemantexArgSingleKeysSet#1{
	\tl_set:Nn\l__semantex_arg_singlekeys_set_temp_tl{}
	\semantex_preprocess_arg_singlekeys:nN { #1 } \l__semantex_arg_singlekeys_set_temp_tl
	\exp_args:NNo\cs_set:Nn\l__semantex_arg_singlekeys_set_temp_cs:n{\l__semantex_arg_singlekeys_set_temp_tl}
	\l__semantex_arg_singlekeys_set_temp_cs:n { \semantex_this: }
}
\cs_new_protected:Npn\SemantexSetArgSingleKeysx#1{
	\tl_set:Nn\l__semantex_arg_singlekeys_set_x_temp_tl{}
	\semantex_preprocess_arg_singlekeys_x:nN { #1 } \l__semantex_arg_singlekeys_set_x_temp_tl
	\exp_args:NNo\cs_set:Nn\l__semantex_arg_singlekeys_set_x_temp_cs:n{\l__semantex_arg_singlekeys_set_x_temp_tl}
	\l__semantex_arg_singlekeys_set_x_temp_cs:n { \semantex_this: }
}
\cs_new_protected:Npn\SemantexArgSingleKeysSetx#1{
	\tl_set:Nn\l__semantex_arg_singlekeys_set_x_temp_tl{}
	\semantex_preprocess_arg_singlekeys_x:nN { #1 } \l__semantex_arg_singlekeys_set_x_temp_tl
	\exp_args:NNo\cs_set:Nn\l__semantex_arg_singlekeys_set_x_temp_cs:n{\l__semantex_arg_singlekeys_set_x_temp_tl}
	\l__semantex_arg_singlekeys_set_x_temp_cs:n { \semantex_this: }
}
\cs_new_protected:Npn\SemantexSetOneArgSingleKey#1{\semantex_arg_singlekey:nn { \semantex_this: } { #1 } }
\cs_new_protected:Npn\SemantexOneSingleArgKeySet#1{\semantex_arg_singlekey:nn { \semantex_this: } { #1 } }
\cs_new_protected:Npn\SemantexSetOneArgSingleKeyx#1{\semantex_arg_singlekey_x:nn { \semantex_this: } { #1 } }
\cs_new_protected:Npn\SemantexOneSingleArgKeySetx#1{\semantex_arg_singlekey_x:nn { \semantex_this: } { #1 } }
\cs_new_protected:Npn\SemantexSetArgWithoutKeyval#1{\semantex_arg_without_keyval:nn { \semantex_this: } { #1 } }
\cs_new_protected:Npn\SemantexArgWithoutKeyvalSet#1{\semantex_arg_without_keyval:nn { \semantex_this: } { #1 } }
\cs_new_protected:Npn\SemantexSetArgWithoutKeyvalx#1{\semantex_arg_without_keyval:nx { \semantex_this: } { #1 } }
\cs_new_protected:Npn\SemantexArgWithoutKeyvalSetx#1{\semantex_arg_without_keyval:nx { \semantex_this: } { #1 } }
\cs_new_protected:Npn\SemantexStrIfEqTF#1#2#3#4{\str_if_eq:xxTF{#1}{#2}{#3}{#4}}
\cs_new_protected:Npn\SemantexStrIfEqT#1#2#3{\str_if_eq:xxT{#1}{#2}{#3}}
\cs_new_protected:Npn\SemantexStrIfEqF#1#2#3{\str_if_eq:xxF{#1}{#2}{#3}}
\cs_new_protected:Npn\SemantexIfBlankTF#1#2#3{\tl_if_blank:xTF{#1}{#2}{#3}}
\cs_new_protected:Npn\SemantexIfBlankT#1#2{\tl_if_blank:xT{#1}{#2}}
\cs_new_protected:Npn\SemantexIfBlankF#1#2{\tl_if_blank:xF{#1}{#2}}
\cs_new_protected:Npn\SemantexBoolProvide#1{\semantex_data_bool_provide:nn{\semantex_this:}{\tl_trim_spaces:n{#1}}}
\cs_new_protected:Npn\SemantexBoolSetTrue#1{\semantex_data_bool_set_true:nn{\semantex_this:}{\tl_trim_spaces:n{#1}}}
\cs_new_protected:Npn\SemantexBoolSetFalse#1{\semantex_data_bool_set_false:nn{\semantex_this:}{\tl_trim_spaces:n{#1}}}
\cs_new:Npn\SemantexBoolIfTF#1#2#3{\semantex_data_bool_get:nnTF{\semantex_this:}{\tl_trim_spaces:n{#1}}{#2}{#3}}
\cs_new:Npn\SemantexBoolIfT#1#2{\semantex_data_bool_get:nnTF{\semantex_this:}{\tl_trim_spaces:n{#1}}{#2}{}}
\cs_new:Npn\SemantexBoolIfF#1#2{\semantex_data_bool_get:nnTF{\semantex_this:}{\tl_trim_spaces:n{#1}}{}{#2}}
\cs_new_protected:Npn\SemantexIntProvide#1{\semantex_data_int_provide:nn{\semantex_this:}{\tl_trim_spaces:n{#1}}}
\cs_new:Npn\SemantexIntGet#1{\semantex_data_int_get:nn{\semantex_this:}{\tl_trim_spaces:n{#1}}}
\cs_new_protected:Npn\SemantexIntClear#1{\semantex_data_int_clear:nn{\semantex_this:}{\tl_trim_spaces:n{#1}}}
\cs_new_protected:Npn\SemantexIntIncr#1{\semantex_data_int_incr:nn{\semantex_this:}{\tl_trim_spaces:n{#1}}}
\cs_new_protected:Npn\SemantexIntSet#1#2{\semantex_data_int_set:nnn{\semantex_this:}{\tl_trim_spaces:n{#1}}{#2}}
\cs_new:Npn\SemantexIntIfGreaterTF#1#2#3#4
{
	\int_compare:nNnTF
		{ #1 }
		>
		{ #2 }
		{ #3 }
		{ #4 }
}
\cs_new:Npn\SemantexIntIfGreaterT#1#2#3
{
	\int_compare:nNnTF
		{ #1 }
		>
		{ #2 }
		{ #3 }
		{ }
}
\cs_new:Npn\SemantexIntIfGreaterF#1#2#3
{
	\int_compare:nNnTF
		{ #1 }
		>
		{ #2 }
		{ }
		{ #3 }
}
\cs_new:Npn\SemantexIntIfEqTF#1#2#3#4
{
	\int_compare:nNnTF
		{ #1 }
		=
		{ #2 }
		{ #3 }
		{ #4 }
}
\cs_new:Npn\SemantexIntIfEqT#1#2#3
{
	\int_compare:nNnTF
		{ #1 }
		=
		{ #2 }
		{ #3 }
		{ }
}
\cs_new:Npn\SemantexIntIfEqF#1#2#3
{
	\int_compare:nNnTF
		{ #1 }
		=
		{ #2 }
		{ }
		{ #3 }
}
\cs_new:Npn\SemantexIntIfLessTF#1#2#3#4
{
	\int_compare:nNnTF
		{ #1 }
		<
		{ #2 }
		{ #3 }
		{ #4 }
}
\cs_new:Npn\SemantexIntIfLessT#1#2#3
{
	\int_compare:nNnTF
		{ #1 }
		<
		{ #2 }
		{ #3 }
		{ }
}
\cs_new:Npn\SemantexIntIfLessF#1#2#3
{
	\int_compare:nNnTF
		{ #1 }
		<
		{ #2 }
		{ }
		{ #3 }
}
\cs_new:Npn\SemantexExpNot#1{\exp_not:n{#1}}
\cs_new:Npn\SemantexERRORKeyValueNotFound#1#2
{
	\semantex_error_key_value_not_found:nnn { \semantex_this: } { #1 } { #2 }
}

\cs_new:Npn\SemantexERRORArgKeyValueNotFound#1#2
{
	\semantex_error_arg_key_value_not_found:nnn { \semantex_this: } { #1 } { #2 }
}

\cs_new:Npn\SemantexERROR#1
{
	\semantex_error_generic:nn { \semantex_this: } { #1 }
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%    ERROR MESSAGES
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


\msg_new:nnnn { semantex } { semantex_setup_key_not_found } { Unknown~key~#1~passed~to~\token_to_str:N\SemantexSetup~on~line~\msg_line_number: } {}

\msg_new:nnnn { semantex } { semantex_setup_key_value_not_found } {  Unknown~value~#2~passed~to~key~#1~in~\token_to_str:N\SemantexSetup~on~line~\msg_line_number: } {}

\msg_new:nnnn { semantex } { valuekey_not_found } {  Unknown~key~#2~passed~to~#1~on~line~\msg_line_number: } {}

\msg_new:nnnn { semantex } { arg_valuekey_not_found } { Unknown~argument~key~#2~passed~to~#1~on~line~\msg_line_number: } {}

\msg_new:nnnn { semantex } { data_tl_not_found } { Unknown~data~#2~requested~from~#1~on~line~\msg_line_number: } {}

\msg_new:nnnn { semantex } { data_int_not_found } { Unknown~integer~#2~requested~from~#1~on~line~\msg_line_number: } {}

\msg_new:nnnn { semantex } { data_bool_not_found } { Unknown~boolean~#2~requested~from~#1~on~line~\msg_line_number: } {}

\msg_new:nnnn { semantex } { data_cs_not_found } { Unknown~command~sequence~#2~requested~from~#1~on~line~\msg_line_number: } {}

\msg_new:nnnn { semantex } { data_prop_not_found } { Unknown~property~list~#2~requested~from~#1~on~line~\msg_line_number: } {}

\msg_new:nnnn { semantex } { key_value_not_found } { Unknown~value~#3~passed~to~key~#2~in~#1~on~line~\msg_line_number: } {}

\msg_new:nnnn { semantex } { arg_key_value_not_found } { Unknown~value~#3~passed~to~argument~key~#2~in~#1~on~line~\msg_line_number: } {}

\msg_new:nnnn { semantex } { class_already_defined } { Class~#1~already~defined;~you~tried~defining~it~again~on~line~\msg_line_number: } {}

\msg_new:nnnn { semantex } { object_already_defined } { Object~#1~already~defined;~you~tried~defining~it~again~on~line~\msg_line_number: } {}

\msg_new:nnnn { semantex } { class_not_found } { Unknown~class~#3~declared~as~#2~of~#1~on~line~\msg_line_number: } {}

\msg_new:nnnn { semantex } { object_not_found } { You~set~#1~as~#2~of~unknown~object~#3~on~line~\msg_line_number: } {}

\msg_new:nnnn { semantex } { created_object_of_unknown_class } { Unknown~class~#1~declared~as~class~of~#2~on~line~\msg_line_number: } {}

\msg_new:nnnn { semantex } { created_object_with_already_defined_name } { Command~#1~already~defined;~you~can~use~\token_to_str:N\DeclareObject~to~override~existing~commands. } {}

\msg_new:nnnn { semantex } { created_class_with_already_defined_name } { Command~#1~already~defined;~you~can~use~\token_to_str:N #2~to~override~existing~commands. } {}

\msg_new:nnnn { semantex } { used_unknown_class } { Unknown~class~#1~received~by~\token_to_str:N\UseClassInCommand~on~line~\msg_line_number: } {}

\msg_new:nnnn { semantex } { setup_unknown_class } { You~tried~setting~up~an~unknown~#1~on~line~\msg_line_number: } {}

\msg_new:nnnn { semantex } { setup_unknown_object } { You~tried~setting~up~an~unknown~#1~on~line~\msg_line_number: } {}

\msg_new:nnnn { semantex } { created_a_SemantexBaseObject } { Never~create~objects~of~class~\token_to_str:N\SemantexBaseObject;~create~a~new~class~yourself~instead.~You~created~the~object~#1 on~line~\msg_line_number: } {}

\msg_new:nnnn { semantex } { SemantexThis_in_input_stream } { The~command~\token_to_str:N\SemantexThis~was~found~outside~a~class~or~object~on~line~\msg_line_number:;~did~you~forget~to~use~set~keys~x={...}? } {}

\msg_new:nnnn { semantex } { generic_error } { #2~#1~on~line~\msg_line_number: } {}

\cs_generate_variant:Nn \msg_error:nnnn { nnnx }

\tl_new:N\l__semantex_error_output_format_temp

\cs_new_protected:Npn\semantex_error_output_format:nN#1#2
{
	\tl_set:Nn \l__semantex_error_output_format_temp { #1 }
	\tl_replace_all:Nnn \l__semantex_error_output_format_temp { object_associated_to_class_ } { object~of~class~ }
	\tl_replace_all:Nnn \l__semantex_error_output_format_temp { object_ } { object~ }
	\tl_replace_all:Nnn \l__semantex_error_output_format_temp { class_ } { class~ }
	\tl_trim_spaces:N \l__semantex_error_output_format_temp
	\tl_set_eq:NN #2 \l__semantex_error_output_format_temp
}

\cs_generate_variant:Nn \semantex_error_output_format:nN { xN }

\cs_generate_variant:Nn \msg_error:nnn { nnx }

\cs_generate_variant:Nn \msg_error:nnnn { nnxn }

\cs_generate_variant:Nn \msg_error:nnnnn { nnxnn }

\cs_new_protected:Npn \semantex_msg_error:nn#1#2
{
	\semantex_error_output_format:xN { #1 } \l__semantex_msg_error_nnn_temp_tl
	\msg_error:nnx { semantex } { #2 }
	{
		\l__semantex_msg_error_nnn_temp_tl
	}
}

\cs_new_protected:Npn \semantex_msg_error:nnn#1#2#3
{
	\semantex_error_output_format:xN { #1 } \l__semantex_msg_error_nnnn_temp_tl
	\msg_error:nnxn { semantex } { #2 }
	{
		\l__semantex_msg_error_nnnn_temp_tl
	} { #3 }
}

\cs_generate_variant:Nn \semantex_msg_error:nnn { nnx }

\cs_new_protected:Npn \semantex_msg_error:nnnn#1#2#3#4
{
	\semantex_error_output_format:xN { #1 } \l__semantex_msg_error_nnnnn_temp_tl
	\msg_error:nnxnn { semantex } { #2 }
	{
		\l__semantex_msg_error_nnnnn_temp_tl
	} { #3 } { #4 }
}

\cs_new_protected:Npn\semantex_error_key_value_not_found:nnn#1#2#3
{
	\semantex_msg_error:nnnn { #1 } { key_value_not_found } { #2 } { #3 }
}

\cs_new_protected:Npn\semantex_error_arg_key_value_not_found:nnn#1#2#3
{
	\semantex_msg_error:nnnn { #1 } { arg_key_value_not_found } { #2 } { #3 }
}

\cs_new_protected:Npn\semantex_error_generic:nn#1#2
{
	\semantex_msg_error:nnn { #1 } { generic_error } { #2 }
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%    SETTING UP THE BASE CLASS \SemantexBaseObject
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\semantex_define_valuekeys:nn { \semantex_class_to_register:N \SemantexBaseObject }
{
	{define~keys[1]}{execute={ \semantex_define_valuekeys:nn { ##1 } { #1 } }},
}

\NewSimpleClass \SemantexBaseObject [
	define~keys[1]={
		%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		%
		%		THE MOST BASIC KEYS, INCLUDING PROGRAMMING KEYS
		%
		%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
		{execute}{ execute={#1} },
		% Yes, this really does make sense
		% -- check how \semantex_define_valuekeys:nn was defined
		% Keys for setting up the keyval interface
		{define~keys}{ execute={ \semantex_define_singlekeys:nn { ##1 } { #1 } } },
		{define~keys[0]}{ execute={ \semantex_define_singlekeys:nn { ##1 } { #1 } } },
		{define~keys[{0}]}{ execute={ \semantex_define_singlekeys:nn { ##1 } { #1 } } },
		{define~keys[{1}]}{ execute={ \semantex_define_valuekeys:nn { ##1 } { #1 } } },
		{define~keys[2]}{ execute={ \semantex_define_two_valuekeys:nn { ##1 } { #1 } } },
		{define~keys[{2}]}{ execute={ \semantex_define_two_valuekeys:nn { ##1 } { #1 } } },
		{define~keys[3]}{ execute={ \semantex_define_three_valuekeys:nn { ##1 } { #1 } } },
		{define~keys[{3}]}{ execute={ \semantex_define_three_valuekeys:nn { ##1 } { #1 } } },
		{define~keys[4]}{ execute={ \semantex_define_four_valuekeys:nn { ##1 } { #1 } } },
		{define~keys[{4}]}{ execute={ \semantex_define_four_valuekeys:nn { ##1 } { #1 } } },
		{define~keys[5]}{ execute={ \semantex_define_five_valuekeys:nn { ##1 } { #1 } } },
		{define~keys[{5}]}{ execute={ \semantex_define_five_valuekeys:nn { ##1 } { #1 } } },
		{define~keys[6]}{ execute={ \semantex_define_six_valuekeys:nn { ##1 } { #1 } } },
		{define~keys[{6}]}{ execute={ \semantex_define_six_valuekeys:nn { ##1 } { #1 } } },
		{define~keys[7]}{ execute={ \semantex_define_seven_valuekeys:nn { ##1 } { #1 } } },
		{define~keys[{7}]}{ execute={ \semantex_define_seven_valuekeys:nn { ##1 } { #1 } } },
		{define~keys[8]}{ execute={ \semantex_define_eight_valuekeys:nn { ##1 } { #1 } } },
		{define~keys[{8}]}{ execute={ \semantex_define_eight_valuekeys:nn { ##1 } { #1 } } },
%		{define~keys[9]}{ execute={ \semantex_define_nine_valuekeys:nn { ##1 } { #1 } } },
%		{define~keys[{9}]}{ execute={ \semantex_define_nine_valuekeys:nn { ##1 } { #1 } } },
		{append~keys}{ execute={ \semantex_append_singlekeys:nn { ##1 } { #1 } } },
		{append~keys[0]}{ execute={ \semantex_append_singlekeys:nn { ##1 } { #1 } } },
		{append~keys[{0}]}{ execute={ \semantex_append_singlekeys:nn { ##1 } { #1 } } },
		{append~keys[1]}{ execute={ \semantex_append_valuekeys:nn { ##1 } { #1 } } },
		{append~keys[{1}]}{ execute={ \semantex_append_valuekeys:nn { ##1 } { #1 } } },
		{append~keys[2]}{ execute={ \semantex_append_two_valuekeys:nn { ##1 } { #1 } } },
		{append~keys[{2}]}{ execute={ \semantex_append_two_valuekeys:nn { ##1 } { #1 } } },
		{append~keys[3]}{ execute={ \semantex_append_three_valuekeys:nn { ##1 } { #1 } } },
		{append~keys[{3}]}{ execute={ \semantex_append_three_valuekeys:nn { ##1 } { #1 } } },
		{append~keys[4]}{ execute={ \semantex_append_four_valuekeys:nn { ##1 } { #1 } } },
		{append~keys[{4}]}{ execute={ \semantex_append_four_valuekeys:nn { ##1 } { #1 } } },
		{append~keys[5]}{ execute={ \semantex_append_five_valuekeys:nn { ##1 } { #1 } } },
		{append~keys[{5}]}{ execute={ \semantex_append_five_valuekeys:nn { ##1 } { #1 } } },
		{append~keys[6]}{ execute={ \semantex_append_six_valuekeys:nn { ##1 } { #1 } } },
		{append~keys[{6}]}{ execute={ \semantex_append_six_valuekeys:nn { ##1 } { #1 } } },
		{append~keys[7]}{ execute={ \semantex_append_seven_valuekeys:nn { ##1 } { #1 } } },
		{append~keys[{7}]}{ execute={ \semantex_append_seven_valuekeys:nn { ##1 } { #1 } } },
		{append~keys[8]}{ execute={ \semantex_append_eight_valuekeys:nn { ##1 } { #1 } } },
		{append~keys[{8}]}{ execute={ \semantex_append_eight_valuekeys:nn { ##1 } { #1 } } },
%		{append~keys[9]}{ execute={ \semantex_append_nine_valuekeys:nn { ##1 } { #1 } } },
%		{append~keys[{9}]}{ execute={ \semantex_append_nine_valuekeys:nn { ##1 } { #1 } } },
		{prepend~keys}{ execute={ \semantex_prepend_singlekeys:nn { ##1 } { #1 } } },
		{prepend~keys[0]}{ execute={ \semantex_prepend_singlekeys:nn { ##1 } { #1 } } },
		{prepend~keys[{0}]}{ execute={ \semantex_prepend_singlekeys:nn { ##1 } { #1 } } },
		{prepend~keys[1]}{ execute={ \semantex_prepend_valuekeys:nn { ##1 } { #1 } } },
		{prepend~keys[{1}]}{ execute={ \semantex_prepend_valuekeys:nn { ##1 } { #1 } } },
		{prepend~keys[2]}{ execute={ \semantex_prepend_two_valuekeys:nn { ##1 } { #1 } } },
		{prepend~keys[{2}]}{ execute={ \semantex_prepend_two_valuekeys:nn { ##1 } { #1 } } },
		{prepend~keys[3]}{ execute={ \semantex_prepend_three_valuekeys:nn { ##1 } { #1 } } },
		{prepend~keys[{3}]}{ execute={ \semantex_prepend_three_valuekeys:nn { ##1 } { #1 } } },
		{prepend~keys[4]}{ execute={ \semantex_prepend_four_valuekeys:nn { ##1 } { #1 } } },
		{prepend~keys[{4}]}{ execute={ \semantex_prepend_four_valuekeys:nn { ##1 } { #1 } } },
		{prepend~keys[5]}{ execute={ \semantex_prepend_five_valuekeys:nn { ##1 } { #1 } } },
		{prepend~keys[{5}]}{ execute={ \semantex_prepend_five_valuekeys:nn { ##1 } { #1 } } },
		{prepend~keys[6]}{ execute={ \semantex_prepend_six_valuekeys:nn { ##1 } { #1 } } },
		{prepend~keys[{6}]}{ execute={ \semantex_prepend_six_valuekeys:nn { ##1 } { #1 } } },
		{prepend~keys[7]}{ execute={ \semantex_prepend_seven_valuekeys:nn { ##1 } { #1 } } },
		{prepend~keys[{7}]}{ execute={ \semantex_prepend_seven_valuekeys:nn { ##1 } { #1 } } },
		{prepend~keys[8]}{ execute={ \semantex_prepend_eight_valuekeys:nn { ##1 } { #1 } } },
		{prepend~keys[{8}]}{ execute={ \semantex_prepend_eight_valuekeys:nn { ##1 } { #1 } } },
%		{prepend~keys[9]}{ execute={ \semantex_prepend_nine_valuekeys:nn { ##1 } { #1 } } },
%		{prepend~keys[{9}]}{ execute={ \semantex_prepend_nine_valuekeys:nn { ##1 } { #1 } } },
		{remove~key}{ execute={ \semantex_remove_singlekey:nn { ##1 } { #1 } } },
		{remove~key[0]}{ execute={ \semantex_remove_singlekey:nn { ##1 } { #1 } } },
		{remove~key[{0}]}{ execute={ \semantex_remove_singlekey:nn { ##1 } { #1 } } },
		{remove~key[1]}{ execute={ \semantex_remove_valuekey:nn { ##1 } { #1 } } },
		{remove~key[{1}]}{ execute={ \semantex_remove_valuekey:nn { ##1 } { #1 } } },
		{remove~key[2]}{ execute={ \semantex_remove_valuekey:nn { ##1 } { #1 } } },
		{remove~key[{2}]}{ execute={ \semantex_remove_valuekey:nn { ##1 } { #1 } } },
		{remove~key[3]}{ execute={ \semantex_remove_valuekey:nn { ##1 } { #1 } } },
		{remove~key[{3}]}{ execute={ \semantex_remove_valuekey:nn { ##1 } { #1 } } },
		{remove~key[4]}{ execute={ \semantex_remove_valuekey:nn { ##1 } { #1 } } },
		{remove~key[{5}]}{ execute={ \semantex_remove_valuekey:nn { ##1 } { #1 } } },
		{remove~key[6]}{ execute={ \semantex_remove_valuekey:nn { ##1 } { #1 } } },
		{remove~key[{6}]}{ execute={ \semantex_remove_valuekey:nn { ##1 } { #1 } } },
		{remove~key[7]}{ execute={ \semantex_remove_valuekey:nn { ##1 } { #1 } } },
		{remove~key[{7}]}{ execute={ \semantex_remove_valuekey:nn { ##1 } { #1 } } },
		{remove~key[8]}{ execute={ \semantex_remove_valuekey:nn { ##1 } { #1 } } },
		{remove~key[{8}]}{ execute={ \semantex_remove_valuekey:nn { ##1 } { #1 } } },
%		{remove~key[9]}{ execute={ \semantex_remove_valuekey:nn { ##1 } { #1 } } },
%		{remove~key[{9}]}{ execute={ \semantex_remove_valuekey:nn { ##1 } { #1 } } },
		% Keys for setting up the argument keyval interface:
		{define~arg~keys}{ execute={ \semantex_define_arg_singlekeys:nn { ##1 } { #1 } } },
		{define~arg~keys[0]}{ execute={ \semantex_define_arg_singlekeys:nn { ##1 } { #1 } } },
		{define~arg~keys[{0}]}{ execute={ \semantex_define_arg_singlekeys:nn { ##1 } { #1 } } },
		{define~arg~keys[1]}{ execute={ \semantex_define_arg_valuekeys:nn { ##1 } { #1 } } },
		{define~arg~keys[{1}]}{ execute={ \semantex_define_arg_valuekeys:nn { ##1 } { #1 } } },
		{define~arg~keys[2]}{ execute={ \semantex_define_arg_two_valuekeys:nn { ##1 } { #1 } } },
		{define~arg~keys[{2}]}{ execute={ \semantex_define_arg_two_valuekeys:nn { ##1 } { #1 } } },
		{define~arg~keys[3]}{ execute={ \semantex_define_arg_three_valuekeys:nn { ##1 } { #1 } } },
		{define~arg~keys[{3}]}{ execute={ \semantex_define_arg_three_valuekeys:nn { ##1 } { #1 } } },
		{define~arg~keys[4]}{ execute={ \semantex_define_arg_four_valuekeys:nn { ##1 } { #1 } } },
		{define~arg~keys[{4}]}{ execute={ \semantex_define_arg_four_valuekeys:nn { ##1 } { #1 } } },
		{define~arg~keys[5]}{ execute={ \semantex_define_arg_five_valuekeys:nn { ##1 } { #1 } } },
		{define~arg~keys[{5}]}{ execute={ \semantex_define_arg_five_valuekeys:nn { ##1 } { #1 } } },
		{define~arg~keys[6]}{ execute={ \semantex_define_arg_six_valuekeys:nn { ##1 } { #1 } } },
		{define~arg~keys[{6}]}{ execute={ \semantex_define_arg_six_valuekeys:nn { ##1 } { #1 } } },
		{define~arg~keys[7]}{ execute={ \semantex_define_arg_seven_valuekeys:nn { ##1 } { #1 } } },
		{define~arg~keys[{7}]}{ execute={ \semantex_define_arg_seven_valuekeys:nn { ##1 } { #1 } } },
		{define~arg~keys[8]}{ execute={ \semantex_define_arg_eight_valuekeys:nn { ##1 } { #1 } } },
		{define~arg~keys[{8}]}{ execute={ \semantex_define_arg_eight_valuekeys:nn { ##1 } { #1 } } },
%		{define~arg~keys[9]}{ execute={ \semantex_define_arg_nine_valuekeys:nn { ##1 } { #1 } } },
%		{define~arg~keys[{9}]}{ execute={ \semantex_define_arg_nine_valuekeys:nn { ##1 } { #1 } } },
		{append~arg~keys}{ execute={ \semantex_append_arg_singlekeys:nn { ##1 } { #1 } } },
		{append~arg~keys[0]}{ execute={ \semantex_append_arg_singlekeys:nn { ##1 } { #1 } } },
		{append~arg~keys[{0}]}{ execute={ \semantex_append_arg_singlekeys:nn { ##1 } { #1 } } },
		{append~arg~keys[1]}{ execute={ \semantex_append_arg_valuekeys:nn { ##1 } { #1 } } },
		{append~arg~keys[{1}]}{ execute={ \semantex_append_arg_valuekeys:nn { ##1 } { #1 } } },
		{append~arg~keys[2]}{ execute={ \semantex_append_arg_two_valuekeys:nn { ##1 } { #1 } } },
		{append~arg~keys[{2}]}{ execute={ \semantex_append_arg_two_valuekeys:nn { ##1 } { #1 } } },
		{append~arg~keys[3]}{ execute={ \semantex_append_arg_three_valuekeys:nn { ##1 } { #1 } } },
		{append~arg~keys[{3}]}{ execute={ \semantex_append_arg_three_valuekeys:nn { ##1 } { #1 } } },
		{append~arg~keys[4]}{ execute={ \semantex_append_arg_four_valuekeys:nn { ##1 } { #1 } } },
		{append~arg~keys[{4}]}{ execute={ \semantex_append_arg_four_valuekeys:nn { ##1 } { #1 } } },
		{append~arg~keys[5]}{ execute={ \semantex_append_arg_five_valuekeys:nn { ##1 } { #1 } } },
		{append~arg~keys[{5}]}{ execute={ \semantex_append_arg_five_valuekeys:nn { ##1 } { #1 } } },
		{append~arg~keys[6]}{ execute={ \semantex_append_arg_six_valuekeys:nn { ##1 } { #1 } } },
		{append~arg~keys[{6}]}{ execute={ \semantex_append_arg_six_valuekeys:nn { ##1 } { #1 } } },
		{append~arg~keys[7]}{ execute={ \semantex_append_arg_seven_valuekeys:nn { ##1 } { #1 } } },
		{append~arg~keys[{7}]}{ execute={ \semantex_append_arg_seven_valuekeys:nn { ##1 } { #1 } } },
		{append~arg~keys[8]}{ execute={ \semantex_append_arg_eight_valuekeys:nn { ##1 } { #1 } } },
		{append~arg~keys[{8}]}{ execute={ \semantex_append_arg_eight_valuekeys:nn { ##1 } { #1 } } },
%		{append~arg~keys[9]}{ execute={ \semantex_append_arg_nine_valuekeys:nn { ##1 } { #1 } } },
%		{append~arg~keys[{9}]}{ execute={ \semantex_append_arg_nine_valuekeys:nn { ##1 } { #1 } } },%
		{prepend~arg~keys}{ execute={ \semantex_prepend_arg_singlekeys:nn { ##1 } { #1 } } },
		{prepend~arg~keys[0]}{ execute={ \semantex_prepend_arg_singlekeys:nn { ##1 } { #1 } } },
		{prepend~arg~keys[{0}]}{ execute={ \semantex_prepend_arg_singlekeys:nn { ##1 } { #1 } } },
		{prepend~arg~keys[1]}{ execute={ \semantex_prepend_arg_valuekeys:nn { ##1 } { #1 } } },
		{prepend~arg~keys[{1}]}{ execute={ \semantex_prepend_arg_valuekeys:nn { ##1 } { #1 } } },
		{prepend~arg~keys[2]}{ execute={ \semantex_prepend_arg_two_valuekeys:nn { ##1 } { #1 } } },
		{prepend~arg~keys[{2}]}{ execute={ \semantex_prepend_arg_two_valuekeys:nn { ##1 } { #1 } } },
		{prepend~arg~keys[3]}{ execute={ \semantex_prepend_arg_three_valuekeys:nn { ##1 } { #1 } } },
		{prepend~arg~keys[{3}]}{ execute={ \semantex_prepend_arg_three_valuekeys:nn { ##1 } { #1 } } },
		{prepend~arg~keys[4]}{ execute={ \semantex_prepend_arg_four_valuekeys:nn { ##1 } { #1 } } },
		{prepend~arg~keys[{4}]}{ execute={ \semantex_prepend_arg_four_valuekeys:nn { ##1 } { #1 } } },
		{prepend~arg~keys[5]}{ execute={ \semantex_prepend_arg_five_valuekeys:nn { ##1 } { #1 } } },
		{prepend~arg~keys[{5}]}{ execute={ \semantex_prepend_arg_five_valuekeys:nn { ##1 } { #1 } } },
		{prepend~arg~keys[6]}{ execute={ \semantex_prepend_arg_six_valuekeys:nn { ##1 } { #1 } } },
		{prepend~arg~keys[{6}]}{ execute={ \semantex_prepend_arg_six_valuekeys:nn { ##1 } { #1 } } },
		{prepend~arg~keys[7]}{ execute={ \semantex_prepend_arg_seven_valuekeys:nn { ##1 } { #1 } } },
		{prepend~arg~keys[{7}]}{ execute={ \semantex_prepend_arg_seven_valuekeys:nn { ##1 } { #1 } } },
		{prepend~arg~keys[8]}{ execute={ \semantex_prepend_arg_eight_valuekeys:nn { ##1 } { #1 } } },
		{prepend~arg~keys[{8}]}{ execute={ \semantex_prepend_arg_eight_valuekeys:nn { ##1 } { #1 } } },
%		{prepend~arg~keys[9]}{ execute={ \semantex_prepend_arg_nine_valuekeys:nn { ##1 } { #1 } } },
%		{prepend~arg~keys[{9}]}{ execute={ \semantex_prepend_arg_nine_valuekeys:nn { ##1 } { #1 } } },
		{remove~arg~key}{ execute={ \semantex_remove_arg_singlekey:nn { ##1 } { #1 } } },
		{remove~arg~key[0]}{ execute={ \semantex_remove_arg_singlekey:nn { ##1 } { #1 } } },
		{remove~arg~key[{0}]}{ execute={ \semantex_remove_arg_singlekey:nn { ##1 } { #1 } } },
		{remove~arg~key[1]}{ execute={ \semantex_remove_arg_valuekey:nn { ##1 } { #1 } } },
		{remove~arg~key[{1}]}{ execute={ \semantex_remove_arg_valuekey:nn { ##1 } { #1 } } },
		{remove~arg~key[2]}{ execute={ \semantex_remove_arg_valuekey:nn { ##1 } { #1 } } },
		{remove~arg~key[{2}]}{ execute={ \semantex_remove_arg_valuekey:nn { ##1 } { #1 } } },
		{remove~arg~key[3]}{ execute={ \semantex_remove_arg_valuekey:nn { ##1 } { #1 } } },
		{remove~arg~key[{3}]}{ execute={ \semantex_remove_arg_valuekey:nn { ##1 } { #1 } } },
		{remove~arg~key[4]}{ execute={ \semantex_remove_arg_valuekey:nn { ##1 } { #1 } } },
		{remove~arg~key[{5}]}{ execute={ \semantex_remove_arg_valuekey:nn { ##1 } { #1 } } },
		{remove~arg~key[6]}{ execute={ \semantex_remove_arg_valuekey:nn { ##1 } { #1 } } },
		{remove~arg~key[{6}]}{ execute={ \semantex_remove_arg_valuekey:nn { ##1 } { #1 } } },
		{remove~arg~key[7]}{ execute={ \semantex_remove_arg_valuekey:nn { ##1 } { #1 } } },
		{remove~arg~key[{7}]}{ execute={ \semantex_remove_arg_valuekey:nn { ##1 } { #1 } } },
		{remove~arg~key[8]}{ execute={ \semantex_remove_arg_valuekey:nn { ##1 } { #1 } } },
		{remove~arg~key[{8}]}{ execute={ \semantex_remove_arg_valuekey:nn { ##1 } { #1 } } },
%		{remove~arg~key[9]}{ execute={ \semantex_remove_arg_valuekey:nn { ##1 } { #1 } } },
%		{remove~arg~key[{9}]}{ execute={ \semantex_remove_arg_valuekey:nn { ##1 } { #1 } } },
		% Keys for programming:
		{data~provide}{ execute={ \semantex_data_tl_provide:nn { ##1 } { \tl_trim_spaces:n { #1 } } } },
		{data~clear}{
			execute={ \semantex_data_tl_clear:nn { ##1 } { \tl_trim_spaces:n { #1 } } },
		},
		{keys~set}{
			execute={
				\tl_set:Nn\l__semantex_keys_set_temp_tl{}
				\semantex_preprocess_keys:nN { #1 } \l__semantex_keys_set_temp_tl
				\exp_args:NNo\cs_set:Nn\l__semantex_keys_set_temp_cs:n{\l__semantex_keys_set_temp_tl}
				\l__semantex_keys_set_temp_cs:n { ##1 }
			},
		},
		{set~keys}{
			execute={
				\tl_set:Nn\l__semantex_keys_set_temp_tl{}
				\semantex_preprocess_keys:nN { #1 } \l__semantex_keys_set_temp_tl
				\exp_args:NNo\cs_set:Nn\l__semantex_keys_set_temp_cs:n{\l__semantex_keys_set_temp_tl}
				\l__semantex_keys_set_temp_cs:n { ##1 }
			},
		},
		{keys~set~x}{
			execute={
				\tl_set:Nn\l__semantex_keys_set_x_temp_tl{}
				\semantex_preprocess_keys_x:nN { #1 } \l__semantex_keys_set_x_temp_tl
				\exp_args:NNo\cs_set:Nn\l__semantex_keys_set_x_temp_cs:n{\l__semantex_keys_set_x_temp_tl}
				\l__semantex_keys_set_x_temp_cs:n { ##1 }
			},
		},
		{set~keys~x}{
			execute={
				\tl_set:Nn\l__semantex_keys_set_x_temp_tl{}
				\semantex_preprocess_keys_x:nN { #1 } \l__semantex_keys_set_x_temp_tl
				\exp_args:NNo\cs_set:Nn\l__semantex_keys_set_x_temp_cs:n{\l__semantex_keys_set_x_temp_tl}
				\l__semantex_keys_set_x_temp_cs:n { ##1 }
			},
		},
		{bool~provide}{
			execute={
				\semantex_data_bool_provide:nn { ##1 } { \tl_trim_spaces:n { #1 } }
			},
		},
		{bool~set~true}{
			execute={
				\semantex_data_bool_set_true:nn { ##1 } { \tl_trim_spaces:n { #1 } }
			},
		},
		{bool~set~false}{
			execute={
				\semantex_data_bool_set_false:nn { ##1 } { \tl_trim_spaces:n { #1 } }
			},
		},
		{int~provide}{
			execute={
				\semantex_data_int_provide:nn { ##1 } { \tl_trim_spaces:n { #1 } }
			},
		},
		{int~clear}{
			execute={
				\semantex_data_int_clear:nn { ##1 } { \tl_trim_spaces:n { #1 } }
			},
		},
		{int~incr}{
			execute={
				\semantex_data_int_incr:nn { ##1 } { \tl_trim_spaces:n { #1 } }
			},
		},
		{ERROR}{
			execute={
				\semantex_error_generic:nn { ##1 } { #1 }
			},
		},
	},
	define~keys[2]={
		{data~set}{
			execute={
				\semantex_data_tl_set:nnn { ##1 } { \tl_trim_spaces:n { #1 } } { #2 }
			},
		},
		{data~set~x}{
			execute={
				\semantex_data_tl_set:nnx { ##1 } { \tl_trim_spaces:n { #1 } } { #2 }
			},
		},
		{data~put~right}{
			execute={
				\semantex_data_tl_put_right:nnn { ##1 } { \tl_trim_spaces:n { #1 } } { #2 }
			},
		},
		{data~put~right~x}{
			execute={
				\semantex_data_tl_put_right:nnx { ##1 } { \tl_trim_spaces:n { #1 } } { #2 }
			},
		},
		{data~put~left}{
			execute={
				\semantex_data_tl_put_left:nnn { ##1 } { \tl_trim_spaces:n { #1 } } { #2 }
			},
		},
		{data~put~left~x}{
			execute={
				\semantex_data_tl_put_left:nnx { ##1 } { \tl_trim_spaces:n { #1 } } { #2 }
			},
		},
		{if~blank~T}{
			execute={
				\tl_if_blank:xTF { #1 }
				{ \semantex_keys_set:nn { ##1 } { #2 } }
				{ }
			},
		},
		{if~blank~F}{
			execute={
				\tl_if_blank:xTF { #1 }
				{ }
				{ \semantex_keys_set:nn { ##1 } { #2 } }
			},
		},
		{bool~if~T}{
			execute={
				\semantex_data_bool_get:nnTF { ##1 }
					{ \tl_trim_spaces:n { #1 } }
					{ \semantex_keys_set:nn { ##1 } { #2 } }
					{ }
			},
		},
		{bool~if~F}{
			execute={
				\semantex_data_bool_get:nnTF { ##1 }
					{ \tl_trim_spaces:n { #1 } }
					{ }
					{ \semantex_keys_set:nn { ##1 } { #2 } }
			},
		},
		{int~set}{
			execute={
				\semantex_data_int_set:nnn { ##1 } { \tl_trim_spaces:n { #1 } } { #2 }
			},
		},
		{ERROR~key~value~not~found}{
			execute={
				\semantex_error_key_value_not_found:nnn { ##1 } { #1 } { #2 }
			},
		},
		{ERROR~arg~key~value~not~found}{
			execute={
				\semantex_error_arg_key_value_not_found:nnn { ##1 } { #1 } { #2 }
			},
		},
	},
	define~keys[3]={
		{str~if~eq~T}{
			execute={
				\str_if_eq:xxTF { #1 } { #2 }
				{ \semantex_keys_set:nn { ##1 } { #3 } }
				{ }
			},
		},
		{str~if~eq~F}{
			execute={
				\str_if_eq:xxTF { #1 } { #2 }
				{ }
				{ \semantex_keys_set:nn { ##1 } { #3 } }
			},
		},
		{if~blank~TF}{
			execute={
				\tl_if_blank:xTF { #1 }
				{ \semantex_keys_set:nn { ##1 } { #2 } }
				{ \semantex_keys_set:nn { ##1 } { #3 } }
			},
		},
		{bool~if~TF}{
			execute={
				\semantex_data_bool_get:nnTF { ##1 }
					{ \tl_trim_spaces:n { #1 } }
					{ \semantex_keys_set:nn { ##1 } { #2 } }
					{ \semantex_keys_set:nn { ##1 } { #3 } }
			},
		},
		{int~if~greater~T}{
			execute={
				\int_compare:nNnTF { #1 } > { #2 }
				{ \semantex_keys_set:nn { ##1 } { #3 } }
				{ }
			},
		},
		{int~if~greater~F}{
			execute={
				\int_compare:nNnTF { #1 } > { #2 }
				{ }
				{ \semantex_keys_set:nn { ##1 } { #3 } }
			},
		},
		{int~if~eq~T}{
			execute={
				\int_compare:nNnTF { #1 } = { #2 }
				{ \semantex_keys_set:nn { ##1 } { #3 } }
				{ }
			},
		},
		{int~if~eq~F}{
			execute={
				\int_compare:nNnTF { #1 } = { #2 }
				{ }
				{ \semantex_keys_set:nn { ##1 } { #3 } }
			},
		},
		{int~if~less~T}{
			execute={
				\int_compare:nNnTF { #1 } < { #2 }
				{ \semantex_keys_set:nn { ##1 } { #3 } }
				{ }
			},
		},
		{int~if~less~F}{
			execute={
				\int_compare:nNnTF { #1 } < { #2 }
				{ }
				{ \semantex_keys_set:nn { ##1 } { #3 } }
			},
		},
	},
	define~keys[4]={
		{str~if~eq~TF}{
			execute={
				\str_if_eq:xxTF { #1 } { #2 }
				{ \semantex_keys_set:nn { ##1 } { #3 } }
				{ \semantex_keys_set:nn { ##1 } { #4 } }
			},
		},
		{int~if~greater~TF}{
			execute={
				\int_compare:nNnTF { #1 } > { #2 }
				{ \semantex_keys_set:nn { ##1 } { #3 } }
				{ \semantex_keys_set:nn { ##1 } { #4 } }
			},
		},
		{int~if~eq~TF}{
			execute={
				\int_compare:nNnTF { #1 } = { #2 }
				{ \semantex_keys_set:nn { ##1 } { #3 } }
				{ \semantex_keys_set:nn { ##1 } { #4 } }
			},
		},
		{int~if~less~TF}{
			execute={
				\int_compare:nNnTF { #1 } < { #2 }
				{ \semantex_keys_set:nn { ##1 } { #3 } }
				{ \semantex_keys_set:nn { ##1 } { #4 } }
			},
		},
	},
	%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
	%
	%		THE COLLECTION OF SLIGHTLY LESS FUNDAMENTAL KEYS
	%
	%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
	data~provide=symbol,
	bool~provide=upper~grading,
	bool~set~true=upper~grading,
	bool~provide=output,
	data~provide=output~options,
	bool~provide=par,
	bool~set~true=par,
	bool~provide=flex~par,
	data~provide=math~class,
	bool~provide=left~argument,
	data~provide=height~phantom,
	data~provide=slanting~phantom,
	execute={ \semantex_data_seq_provide:nn { \semantex_this: } { commands~sequence } },
	define~keys[1]={
		{parent}{ execute={ \semantex_data_parent_set:nn { ##1 } { #1 } } },
		{class}{ execute={ \semantex_data_class_set:nn { ##1 } { #1 } } },
		{copy}{ execute={ \semantex_data_copy_object:nn { ##1 } { #1 } } },
		{math~class}{ execute={ \semantex_data_tl_set:nnn { ##1 } { math~class } { #1 } } },
		{symbol}{
			execute={
				\semantex_data_tl_set:nnn { ##1 } { symbol } { #1 }
				\semantex_data_tl_set:nnn { ##1 } { height~phantom } { #1 }
				\semantex_data_tl_set:nnn { ##1 } { slanting~phantom } { #1 }
			}
		},
		{symbol~put~right}{ execute={ \semantex_data_tl_put_right:nnn { ##1 } { symbol } { #1 } } },
		{symbol~put~left}{ execute={ \semantex_data_tl_put_left:nnn { ##1 } { symbol } { #1 } } },
		{height~phantom}{ execute={ \semantex_data_tl_set:nnn { ##1 } { height~phantom } { #1 } } },
		{slanting~phantom}{ execute={ \semantex_data_tl_set:nnn { ##1 } { slanting~phantom } { #1 } } },
		{parse~options}{ append~keys={ {parse~code}{#1} } },
		{pre~parse~options}{ prepend~keys={ {parse~code}{#1} } },
		{command}{ execute={ \semantex_data_seq_put_right:nnn { ##1 } { commands~sequence } { #1 } } },
		{output}{ execute={ \semantex_set_output:nn { ##1 } { #1 } } },
		{output~options}{ execute={ \semantex_add_to_output_options:nn { ##1 } { #1 } } },
		{pre~output~options}{ execute={ \semantex_add_to_the_left_of_output_options:nn { ##1 } { #1 } } },
		{do~output}{
			str~if~eq~TF={#1}{true}
			{
				bool~set~true={output},
			}
			{
				str~if~eq~TF={#1}{false}
				{
					bool~set~false={output},
				}
				{
					ERROR~key~value~not~found={do~output}{#1},
				}
			},
		},
		{grading~position}{
			str~if~eq~TF={#1}{upper}
			{
				bool~set~true={upper~grading},
			}
			{
				str~if~eq~TF={#1}{lower}
				{
					bool~set~false={upper~grading},
				}
				{
					ERROR~key~value~not~found={grading~position}{#1},
				},
			},
		},
		{grading~pos}{
			str~if~eq~TF={#1}{upper}
			{
				bool~set~true={upper~grading},
			}
			{
				str~if~eq~TF={#1}{lower}
				{
					bool~set~false={upper~grading},
				}
				{
					ERROR~key~value~not~found={grading~pos}{#1},
				},
			},
		},
		{default}{sep~i={#1}},
		{arg}{ execute={ \semantex_arg_singlekeys_set:nn { ##1 } { #1 } } },
		{*~with~other~sep}{
			d~*~with~other~sep={#1},
		},
		{**~with~other~sep}{
			d~**~with~other~sep={#1},
		},
	},
	output=\SemantexBaseObject,
	define~keys={
		{return}{ execute={ \semantex_return:n { ##1 } } },
		{inner~return}{ execute={ \semantex_inner_return:n { ##1 } } },
		{right~return}{ execute={ \semantex_right_return:n { ##1 } } },
		{left~return}{ execute={ \semantex_left_return:n { ##1 } } },
		{right~index~return}{ execute={ \semantex_right_index_return:n { ##1 } } },
		{left~index~return}{ execute={ \semantex_left_index_return:n { ##1 } } },
		{index~return}{ left~index~return, right~index~return },
		{right~arg~return}{ execute={ \semantex_right_arg_return:n { ##1 } } },
		{left~arg~return}{ execute={ \semantex_left_arg_return:n { ##1 } } },
		{arg~return}{ execute={ \semantex_arg_return:n { ##1 } } },
		{parse}{ parse~code, execute={ \semantex_clear_singlekey:nn { ##1 } { parse~code } } },
		{parse~code}{ },
		{clear~command}{ execute={ \semantex_data_seq_clear:nn { ##1 } { commands~sequence } } },
		{dots}{sep~i~dots},
		{...}{dots},
		{slot}{sep~i~slot},
		{*}{sep~d~*},
		{**}{sep~d~**},
	},
	% The "spar" routine:
	define~keys={
		{spar}{spar=},
	},
	define~keys[1]={
		{spar}{ execute={ \semantex_spar:nn { ##1 } { #1 } } },
		{spar~size}{ execute={ \semantex_data_tl_set:nnn { ##1 } { spar~size } { #1 } } },
		{left~spar}{ execute={ \semantex_data_tl_set:nnn { ##1 } { left~spar } { #1 } } },
		{right~spar}{ execute={ \semantex_data_tl_set:nnn { ##1 } { right~spar } { #1 } } },
	},
	define~keys[2]={
		{other~spar}{ execute={ \semantex_other_spar:nnn { ##1 } { #1 } { #2 } } },
	},
	define~keys[3]={
		{Other~spar}{ execute={ \semantex_other_spar_with_size:nnnn { ##1 } { #1 } { #2 } { #3 } } },
	},
	left~spar=(,
	right~spar=),
	spar~size=normal,
	% The argument:
	data~provide=arg,
	bool~provide=next~arg~with~sep,
	int~provide=number~of~arguments,
	data~provide=pre~arg,
	data~provide=post~arg,
	define~keys={
		{arg~dots}{set~arg~keys={...}},
		{arg~...}{set~arg~keys={dots}},
		{comma~arg~dots}{set~arg~keys={comma~dots}},
		{comma~arg~...}{set~arg~keys={comma~...}},
		{arg~slot}{set~arg~keys={slot}},
		{comma~arg~slot}{set~arg~keys={comma~slot}},
		{clear~arg}{ execute={
				\semantex_data_tl_clear:nn { ##1 } { arg }
				\semantex_data_int_clear:nn { ##1 } { number~of~arguments }
				\semantex_data_bool_set_false:nn { ##1 } { next~arg~with~sep }
			}
		},
		{clear~pre~arg}{ execute={ \semantex_data_tl_clear:nn { ##1 } { pre~arg } } },
		{clear~post~arg}{ execute={ \semantex_data_tl_clear:nn { ##1 } { post~arg } } },
	},
	define~keys[1]={
		{set~arg~keys}{
			execute={
				\tl_set:Nn\l__semantex_arg_keys_set_temp_tl{}
				\semantex_preprocess_arg_keys:nN { #1 } \l__semantex_arg_keys_set_temp_tl
				\exp_args:NNo\cs_set:Nn\l__semantex_arg_keys_set_temp_cs:n{\l__semantex_arg_keys_set_temp_tl}
				\l__semantex_arg_keys_set_temp_cs:n { ##1 }
			},
		},
		{arg~keys~set}{
			execute={
				\tl_set:Nn\l__semantex_arg_keys_set_temp_tl{}
				\semantex_preprocess_arg_keys:nN { #1 } \l__semantex_arg_keys_set_temp_tl
				\exp_args:NNo\cs_set:Nn\l__semantex_arg_keys_set_temp_cs:n{\l__semantex_arg_keys_set_temp_tl}
				\l__semantex_arg_keys_set_temp_cs:n { ##1 }
			},
		},
		{set~arg~keys~x}{
			execute={
				\tl_set:Nn\l__semantex_arg_keys_set_x_temp_tl{}
				\semantex_preprocess_arg_keys_x:nN { #1 } \l__semantex_arg_keys_set_x_temp_tl
				\exp_args:NNo\cs_set:Nn\l__semantex_arg_keys_set_x_temp_cs:n{\l__semantex_arg_keys_set_x_temp_tl}
				\l__semantex_arg_keys_set_x_temp_cs:n { ##1 }
			},
		},
		{arg~keys~set~x}{
			execute={
				\tl_set:Nn\l__semantex_arg_keys_set_x_temp_tl{}
				\semantex_preprocess_arg_keys_x:nN { #1 } \l__semantex_arg_keys_set_x_temp_tl
				\exp_args:NNo\cs_set:Nn\l__semantex_arg_keys_set_x_temp_cs:n{\l__semantex_arg_keys_set_x_temp_tl}
				\l__semantex_arg_keys_set_x_temp_cs:n { ##1 }
			},
		},
		{set~arg~single~keys}{
			execute={
				\tl_set:Nn\l__semantex_arg_singlekeys_set_temp_tl{}
				\semantex_preprocess_arg_singlekeys:nN { #1 } \l__semantex_arg_singlekeys_set_temp_tl
				\exp_args:NNo\cs_set:Nn\l__semantex_arg_singlekeys_set_temp_cs:n{\l__semantex_arg_singlekeys_set_temp_tl}
				\l__semantex_arg_singlekeys_set_temp_cs:n { ##1 }
			},
		},
		{arg~single~keys~set}{
			execute={
				\tl_set:Nn\l__semantex_arg_singlekeys_set_temp_tl{}
				\semantex_preprocess_arg_singlekeys:nN { #1 } \l__semantex_arg_singlekeys_set_temp_tl
				\exp_args:NNo\cs_set:Nn\l__semantex_arg_singlekeys_set_temp_cs:n{\l__semantex_arg_singlekeys_set_temp_tl}
				\l__semantex_arg_singlekeys_set_temp_cs:n { ##1 }
			},
		},
		{set~arg~single~keys~x}{
			execute={
				\tl_set:Nn\l__semantex_arg_singlekeys_set_x_temp_tl{}
				\semantex_preprocess_arg_singlekeys_x:nN { #1 } \l__semantex_arg_singlekeys_set_x_temp_tl
				\exp_args:NNo\cs_set:Nn\l__semantex_arg_singlekeys_set_x_temp_cs:n{\l__semantex_arg_singlekeys_set_x_temp_tl}
				\l__semantex_arg_singlekeys_set_x_temp_cs:n { ##1 }
			},
		},
		{arg~single~keys~set~x}{
			execute={
				\tl_set:Nn\l__semantex_arg_singlekeys_set_x_temp_tl{}
				\semantex_preprocess_arg_singlekeys_x:nN { #1 } \l__semantex_arg_singlekeys_set_x_temp_tl
				\exp_args:NNo\cs_set:Nn\l__semantex_arg_singlekeys_set_x_temp_cs:n{\l__semantex_arg_singlekeys_set_x_temp_tl}
				\l__semantex_arg_singlekeys_set_x_temp_cs:n { ##1 }
			},
		},
		{set~one~arg~single~key}{ execute={ \semantex_arg_singlekey:nn { ##1 } { #1 } } },
		{one~arg~single~key~set}{ execute={ \semantex_arg_singlekey:nn { ##1 } { #1 } } },
		{set~one~arg~single~key~x}{ execute={ \semantex_arg_singlekey_x:nn { ##1 } { #1 } } },
		{one~arg~single~key~set~x}{ execute={ \semantex_arg_singlekey_x:nn { ##1 } { #1 } } },
		{set~arg~without~keyval}{ execute={ \semantex_arg_without_keyval:nn { ##1 } { #1 } } },
		{arg~without~keyval~set}{ execute={ \semantex_arg_without_keyval:nn { ##1 } { #1 } } },
		{set~arg~without~keyval~x}{ execute={ \semantex_arg_without_keyval:nx { ##1 } { #1 } } },
		{arg~without~keyval~set~x}{ execute={ \semantex_arg_without_keyval:nx { ##1 } { #1 } } },
		{pre~arg}{
			execute={
				\tl_if_blank:nF{#1}{
					\semantex_data_tl_put_right:nnn { ##1 } { pre~arg } { #1 }
				}
			},
		},
		{pre~arg~put~left}{
			execute={
				\tl_if_blank:nF{#1}{
					\semantex_data_tl_put_left:nnn { ##1 } { pre~arg } { #1 }
				}
			},
		},
		{post~arg}{
			execute={
				\tl_if_blank:nF{#1}{
					\semantex_data_tl_put_left:nnn { ##1 } { post~arg } { #1 }
				}
			},
		},
		{post~arg~put~right}{
			execute={
				\tl_if_blank:nF{#1}{
					\semantex_data_tl_put_right:nnn { ##1 } { post~arg } { #1 }
				}
			},
		},
		{set~arg~sep}{ execute={ \semantex_data_tl_set:nnn { ##1 } { arg~sep } { #1 } } },
		{set~arg~slot}{ execute={ \semantex_data_tl_set:nnn { ##1 } { arg~slot } { #1 } } },
		{set~arg~dots}{ execute={ \semantex_data_tl_set:nnn { ##1 } { arg~dots } { #1 } } },
		{arg~keyval}{
			str~if~eq~TF={#1}{true}
			{
				define~keys[1]={
					{arg}{execute={ \semantex_arg_keys_set:nn { ########1 } { ####1 } }},
				},
			}
			{
				str~if~eq~TF={#1}{false}
				{
					define~keys[1]={
						{arg}{ execute={ \semantex_arg_without_keyval:nn { ########1 } { ####1 } } },
					},
				}
				{
					str~if~eq~TF={#1}{single~keys}
					{
						define~keys[1]={
							{arg}{ execute={ \semantex_arg_singlekeys_set:nn { ########1 } { ####1 } } },
						},
					}
					{
						str~if~eq~TF={#1}{one~single~key}
						{
							define~keys[1]={
								{arg}{ execute={ \semantex_arg_singlekey:nn { ########1 } { ####1 } } },
							},
						}
						{
							ERROR~key~value~not~found={arg~keyval}{#1},
						},
					},
				},
			},
		},
		{arg~position}{
			str~if~eq~TF={#1}{left}
			{
				bool~set~true=left~argument,
			}
			{
				str~if~eq~TF={#1}{right}
				{
					bool~set~false=left~argument,
				}
				{
					ERROR~key~value~not~found={arg~position}{#1},
				},
			},
		},
		{arg~pos}{
			str~if~eq~TF={#1}{left}
			{
				bool~set~true=left~argument,
			}
			{
				str~if~eq~TF={#1}{right}
				{
					bool~set~false=left~argument,
				}
				{
					ERROR~key~value~not~found={arg~pos}{#1},
				},
			},
		},
		{next~arg~with~sep}{
			str~if~eq~TF={#1}{true}
			{
				bool~set~true=next~arg~with~sep,
			}
			{
				str~if~eq~TF={#1}{false}
				{
					bool~set~false=next~arg~with~sep,
				}
				{
					ERROR~key~value~not~found={next~arg~with~sep}{#1},
				},
			},
		},
		{sep~arg}{set~arg~keys={sep={#1}}},
		{comma~arg}{set~arg~keys={comma={#1}}},
		{arg~dots~with~other~sep}{set~arg~keys={dots~with~other~sep={#1}}},
		{arg~...~with~other~sep}{set~arg~keys={dots~with~other~sep={#1}}},
		{arg~slot~with~other~sep}{set~arg~keys={slot~with~other~sep={#1}}},
	},
	define~keys[2]={
		{arg~with~other~sep}{set~arg~keys={other~sep={#1}{#2}}},
	},
	set~arg~sep={,},
	set~arg~slot={ {-} },
	set~arg~dots={ \dots },
	% Parentheses:
	define~keys={
		{par}{use~par=true},
		{never~par}{use~par=never},
		{no~par}{use~par=false},
	},
	define~keys[1]={
		{par}{
			execute={
				\semantex_data_tl_set:nnn { ##1 } { par~size } { #1 }
				\semantex_data_bool_set_true:nn { ##1 } { par }
			},
		},
		{par~size}{
			execute={
				\semantex_data_tl_set:nnn { ##1 } { par~size } { #1 }
			},
		},
		{left~par}{
			execute={ \semantex_data_tl_set:nnn { ##1 } { left~par } { #1 } },
		},
		{right~par}{
			execute={ \semantex_data_tl_set:nnn { ##1 } { right~par } { #1 } },
		},
		{use~par}{
			str~if~eq~TF={#1}{true}
			{
				bool~set~true=par,
				bool~set~false=flex~par,
			}
			{
				str~if~eq~TF={#1}{false}
				{
					bool~set~false=par,
					bool~set~true=flex~par,
				}
				{
					str~if~eq~TF={#1}{never}
					{
						bool~set~false=par,
						bool~set~false=flex~par,
					}
					{
						ERROR~key~value~not~found={use~par}{#1},
					},
				},
			},
		},
	},
	left~par=(,
	right~par=),
	par=normal,
	% Accents, primes, bullets, etc.:
	define~keys={
		{smash}{return,command=\smash},
		{prime}{upper={\prime},next~upper~with~sep=false},
		{'}{prime},
		{''}{prime,prime},
		{'''}{prime,prime,prime},
	},
	% Upper indices:
	data~provide=upper,
	bool~provide=next~upper~with~sep,
	int~provide=number~of~upper~indices,
	data~provide=pre~upper,
	data~provide=post~upper,
	define~keys={
		{upper~slot}{ set~keys~x={ upper=\semantex_data_tl_get_exp_not:nn { ##1 } { upper~slot } } },
		{sep~upper~slot}{ set~keys~x={ sep~upper=\semantex_data_tl_get_exp_not:nn { ##1 } { upper~slot } } },
		{comma~upper~slot}{ set~keys~x={ comma~upper=\semantex_data_tl_get_exp_not:nn { ##1 } { upper~slot } } },
		{upper~dots}{ set~keys~x={ upper=\semantex_data_tl_get_exp_not:nn { ##1 } { upper~dots } } },
		{upper~...}{upper~dots},
		{sep~upper~dots}{ set~keys~x={ sep~upper=\semantex_data_tl_get_exp_not:nn { ##1 } { upper~dots } } },
		{sep~upper~...}{sep~upper~dots},
		{comma~upper~dots}{ set~keys~x={ comma~upper=\semantex_data_tl_get_exp_not:nn { ##1 } { upper~dots } } },
		{comma~upper~...}{comma~upper~dots},
		{clear~upper}{
			execute={
				\semantex_data_tl_clear:nn { ##1 } { upper }
				\semantex_data_bool_set_false:nn { ##1 } { next~upper~with~sep }
				\semantex_data_int_clear:nn { ##1 } { number~of~upper~indices }
			},
		},
		{clear~pre~upper}{
			execute={ \semantex_data_tl_clear:nn { ##1 } { pre~upper } },
		},
		{clear~post~upper}{
			execute={ \semantex_data_tl_clear:nn { ##1 } { post~upper } },
		},
		{upper~*}{upper=\SemantexBullet},
		{upper~**}{upper=\SemantexDoubleBullet},
		{sep~upper~*}{sep~upper=\SemantexBullet},
		{sep~upper~**}{sep~upper=\SemantexDoubleBullet},
		{comma~upper~*}{comma~upper=\SemantexBullet},
		{comma~upper~**}{comma~upper=\SemantexDoubleBullet},
	},
	define~keys[1]={
		{upper}{
			execute={
				\tl_if_blank:nF { #1 }
				{
					\semantex_data_tl_put_right:nnn { ##1 } { upper } { #1 }
					\semantex_data_bool_set_true:nn { ##1 } { next~upper~with~sep }
					\semantex_data_int_incr:nn { ##1 } { number~of~upper~indices }
				}
			},
		},
		{sep~upper}{
			execute={
				\tl_if_blank:nF { #1 }
				{
					\semantex_data_bool_get:nnTF { ##1 } { next~upper~with~sep }
					{
						\semantex_data_tl_put_right:nnx { ##1 } { upper }
						{ \semantex_data_tl_get_exp_not:nn { ##1 } { upper~sep } }
						\semantex_data_tl_put_right:nnn { ##1 } { upper } { #1 }
					}
					{
						\semantex_data_tl_put_right:nnn { ##1 } { upper } { #1 }
					}
					\semantex_data_bool_set_true:nn { ##1 } { next~upper~with~sep }
					\semantex_data_int_incr:nn { ##1 } { number~of~upper~indices }
				}
			},
		},
		{comma~upper}{
			execute={
				\tl_if_blank:nF{#1}
				{
					\semantex_data_bool_get:nnTF { ##1 } { next~upper~with~sep }
					{
						\semantex_data_tl_put_right:nnn { ##1 } { upper } { , #1 }
					}
					{
						\semantex_data_tl_put_right:nnn { ##1 } { upper } { #1 }
					}
					\semantex_data_bool_set_true:nn { ##1 } { next~upper~with~sep }
					\semantex_data_int_incr:nn { ##1 } { number~of~upper~indices }
				}
			}
		},
		{pre~upper}{
			execute={
				\tl_if_blank:nF{#1}{
					\semantex_data_tl_put_right:nnn { ##1 } { pre~upper } { #1 }
				}
			},
		},
		{pre~upper~put~left}{
			execute={
				\tl_if_blank:nF{#1}{
					\semantex_data_tl_put_left:nnn { ##1 } { pre~upper } { #1 }
				}
			},
		},
		{post~upper}{
			execute={
				\tl_if_blank:nF{#1}{
					\semantex_data_tl_put_left:nnn { ##1 } { post~upper } { #1 }
				}
			},
		},
		{post~upper~put~right}{
			execute={
				\tl_if_blank:nF{#1}{
					\semantex_data_tl_put_right:nnn { ##1 } { post~upper } { #1 }
				}
			},
		},
		{upper~put~left}{
			execute={
				\tl_if_blank:nF { #1 }
				{
					\semantex_data_tl_put_left:nnn { ##1 } { upper } { #1 }
					\semantex_data_bool_set_true:nn { ##1 } { next~upper~with~sep }
					\semantex_data_int_incr:nn { ##1 } { number~of~upper~indices }
				}			
			},
		},
		{set~upper~slot}{
			execute={ \semantex_data_tl_set:nnn { ##1 } { upper~slot } { #1 } },
		},
		{upper~slot~with~other~sep}{
			execute={
				\semantex_valuekey:nnx { ##1 } { upper~with~other~sep }
				{
					{ \exp_not:n { #1 } }
					{ \semantex_data_tl_get_exp_not:nn { ##1 } { upper~slot } }
				}
			},
		},
		{set~upper~dots}{
			execute={ \semantex_data_tl_set:nnn { ##1 } { upper~dots } { #1 } },
		},
		{upper~dots~with~other~sep}{
			execute={
				\semantex_valuekey:nnx { ##1 } { upper~with~other~sep }
				{
					{ \exp_not:n { #1 } }
					{ \semantex_data_tl_get_exp_not:nn { ##1 } { upper~dots } }
				}
			},
		},
		{upper~...~with~other~sep}{
			execute={
				\semantex_valuekey:nnx { ##1 } { upper~with~other~sep }
				{
					{ \exp_not:n { #1 } }
					{ \semantex_data_tl_get_exp_not:nn { ##1 } { upper~dots } }
				}
			},
		},
		{upper~*~with~other~sep}{upper~with~other~sep={#1}{\SemantexBullet}},
		{upper~**~with~other~sep}{upper~with~other~sep={#1}{\SemantexDoubleBullet}},
		{set~upper~sep}{
			execute={ \semantex_data_tl_set:nnn { ##1 } { upper~sep } { #1 } },
		},
		{next~upper~with~sep}{
			str~if~eq~TF={#1}{false}
			{
				bool~set~false={next~upper~with~sep},
			}
			{
				str~if~eq~TF={#1}{true}
				{
					bool~set~true={next~upper~with~sep},
				}
				{
					ERROR~key~value~not~found={next~upper~with~sep}{#1},
				},
			},
		},
	},
	define~keys[2]={
		{upper~with~other~sep}{
			execute={
				\semantex_data_bool_get:nnTF { ##1 } { next~upper~with~sep }
					{ \semantex_data_tl_put_right:nnn { ##1 } { upper } { #1 #2 } }
					{ \semantex_data_tl_put_right:nnn { ##1 } { upper } { #2 } }
				\semantex_data_bool_set_true:nn { ##1 } { next~upper~with~sep }
				\semantex_data_int_incr:nn { ##1 } { number~of~upper~indices }
			},
		},
	},
	set~upper~sep={ , },
	set~upper~dots={ \dots },
	set~upper~slot={ {-} },
	% Lower indices:
	data~provide=lower,
	bool~provide=next~lower~with~sep,
	int~provide=number~of~lower~indices,
	data~provide=pre~lower,
	data~provide=post~lower,
	define~keys={
		{lower~slot}{ set~keys~x={ lower=\semantex_data_tl_get_exp_not:nn { ##1 } { lower~slot } } },
		{sep~lower~slot}{ set~keys~x={ sep~lower=\semantex_data_tl_get_exp_not:nn { ##1 } { lower~slot } } },
		{comma~lower~slot}{ set~keys~x={ comma~lower=\semantex_data_tl_get_exp_not:nn { ##1 } { lower~slot } } },
		{lower~dots}{ set~keys~x={ lower=\semantex_data_tl_get_exp_not:nn { ##1 } { lower~dots } } },
		{lower~...}{lower~dots},
		{sep~lower~dots}{ set~keys~x={ sep~lower=\semantex_data_tl_get_exp_not:nn { ##1 } { lower~dots } } },
		{sep~lower~...}{sep~lower~dots},
		{comma~lower~dots}{ set~keys~x={ comma~lower=\semantex_data_tl_get_exp_not:nn { ##1 } { lower~dots } } },
		{comma~lower~...}{comma~lower~dots},
		{clear~lower}{
			execute={
				\semantex_data_tl_clear:nn { ##1 } { lower }
				\semantex_data_bool_set_false:nn { ##1 } { next~lower~with~sep }
				\semantex_data_int_clear:nn { ##1 } { number~of~lower~indices }
			},
		},
		{clear~pre~lower}{
			execute={ \semantex_data_tl_clear:nn { ##1 } { pre~lower } },
		},
		{clear~post~lower}{
			execute={ \semantex_data_tl_clear:nn { ##1 } { post~lower } },
		},
		{lower~*}{lower=\SemantexBullet},
		{lower~**}{lower=\SemantexDoubleBullet},
		{sep~lower~*}{sep~lower=\SemantexBullet},
		{sep~lower~**}{sep~lower=\SemantexDoubleBullet},
		{comma~lower~*}{comma~lower=\SemantexBullet},
		{comma~lower~**}{comma~lower=\SemantexDoubleBullet},
	},
	define~keys[1]={
		{lower}{
			execute={
				\tl_if_blank:nF{#1}{
					\semantex_data_tl_put_right:nnn { ##1 } { lower } { #1 }
					\semantex_data_bool_set_true:nn { ##1 } { next~lower~with~sep }
					\semantex_data_int_incr:nn { ##1 } { number~of~lower~indices }
				}
			},
		},
		{sep~lower}{
			execute={
				\tl_if_blank:nF { #1 }
				{
					\semantex_data_bool_get:nnTF { ##1 } { next~lower~with~sep }
					{
						\semantex_data_tl_put_right:nnx { ##1 } { lower }
						{ \semantex_data_tl_get_exp_not:nn { ##1 } { lower~sep } }
						\semantex_data_tl_put_right:nnn { ##1 } { lower } { #1 }
					}
					{
						\semantex_data_tl_put_right:nnn { ##1 } { lower } { #1 }
					}
					\semantex_data_bool_set_true:nn { ##1 } { next~lower~with~sep }
					\semantex_data_int_incr:nn { ##1 } { number~of~lower~indices }
				}
			},
		},
		{comma~lower}{
			execute={
				\tl_if_blank:nF{#1}
				{
					\semantex_data_bool_get:nnTF { ##1 } { next~lower~with~sep }
					{
						\semantex_data_tl_put_right:nnn { ##1 } { lower } { , #1 }
					}
					{
						\semantex_data_tl_put_right:nnn { ##1 } { lower } { #1 }
					}
					\semantex_data_bool_set_true:nn { ##1 } { next~lower~with~sep }
					\semantex_data_int_incr:nn { ##1 } { number~of~lower~indices }
				}
			}
		},
		{pre~lower}{
			execute={
				\tl_if_blank:nF{#1}{
					\semantex_data_tl_put_right:nnn { ##1 } { pre~lower } { #1 }
				}
			},
		},
		{pre~lower~put~left}{
			execute={
				\tl_if_blank:nF{#1}{
					\semantex_data_tl_put_left:nnn { ##1 } { pre~lower } { #1 }
				}
			},
		},
		{post~lower}{
			execute={
				\tl_if_blank:nF{#1}{
					\semantex_data_tl_put_left:nnn { ##1 } { post~lower } { #1 }
				}
			},
		},
		{post~lower~put~right}{
			execute={
				\tl_if_blank:nF{#1}{
					\semantex_data_tl_put_right:nnn { ##1 } { post~lower } { #1 }
				}
			},
		},
		{lower~put~left}{
			execute={
				\tl_if_blank:nF { #1 }
				{
					\semantex_data_tl_put_left:nnn { ##1 } { lower } { #1 }
					\semantex_data_bool_set_true:nn { ##1 } { next~lower~with~sep }
					\semantex_data_int_incr:nn { ##1 } { number~of~lower~indices }
				}			
			},
		},
		{set~lower~slot}{
			execute={ \semantex_data_tl_set:nnn { ##1 } { lower~slot } { #1 } },
		},
		{lower~slot~with~other~sep}{
			execute={
				\semantex_valuekey:nnx { ##1 } { lower~with~other~sep }
				{
					{ \exp_not:n { #1 } }
					{ \semantex_data_tl_get_exp_not:nn { ##1 } { lower~slot } }
				}
			},
		},
		{set~lower~dots}{
			execute={ \semantex_data_tl_set:nnn { ##1 } { lower~dots } { #1 } },
		},
		{lower~dots~with~other~sep}{
			execute={
				\semantex_valuekey:nnx { ##1 } { lower~with~other~sep }
				{
					{ \exp_not:n { #1 } }
					{ \semantex_data_tl_get_exp_not:nn { ##1 } { lower~dots } }
				}
			},
		},
		{lower~...~with~other~sep}{
			execute={
				\semantex_valuekey:nnx { ##1 } { lower~with~other~sep }
				{
					{ \exp_not:n { #1 } }
					{ \semantex_data_tl_get_exp_not:nn { ##1 } { lower~dots } }
				}
			},
		},
		{lower~*~with~other~sep}{lower~with~other~sep={#1}{\SemantexBullet}},
		{lower~**~with~other~sep}{lower~with~other~sep={#1}{\SemantexDoubleBullet}},
		{set~lower~sep}{
			execute={ \semantex_data_tl_set:nnn { ##1 } { lower~sep } { #1 } },
		},
		{next~lower~with~sep}{
			str~if~eq~TF={#1}{false}
			{
				bool~set~false={next~lower~with~sep},
			}
			{
				str~if~eq~TF={#1}{true}
				{
					bool~set~true={next~lower~with~sep},
				}
				{
					ERROR~key~value~not~found={next~lower~with~sep}{#1},
				},
			},
		},
	},
	define~keys[2]={
		{lower~with~other~sep}{
			execute={
				\semantex_data_bool_get:nnTF { ##1 } { next~lower~with~sep }
					{ \semantex_data_tl_put_right:nnn { ##1 } { lower } { #1 #2 } }
					{ \semantex_data_tl_put_right:nnn { ##1 } { lower } { #2 } }
				\semantex_data_bool_set_true:nn { ##1 } { next~lower~with~sep }
				\semantex_data_int_incr:nn { ##1 } { number~of~lower~indices }
			},
		},
	},
	set~lower~sep={ , },
	set~lower~dots={ \dots },
	set~lower~slot={ {-} },
	% Upper left indices:	
	data~provide=upper~left,
	bool~provide=next~upper~left~with~sep,
	int~provide=number~of~upper~left~indices,
	data~provide=pre~upper~left,
	data~provide=post~upper~left,
	define~keys={
		{upper~left~slot}{ set~keys~x={ upper~left=\semantex_data_tl_get_exp_not:nn { ##1 } { upper~left~slot } } },
		{sep~upper~left~slot}{ set~keys~x={ sep~upper~left=\semantex_data_tl_get_exp_not:nn { ##1 } { upper~left~slot } } },
		{comma~upper~left~slot}{ set~keys~x={ comma~upper~left=\semantex_data_tl_get_exp_not:nn { ##1 } { upper~left~slot } } },
		{upper~left~dots}{ set~keys~x={ upper~left=\semantex_data_tl_get_exp_not:nn { ##1 } { upper~left~dots } } },
		{upper~left~...}{upper~left~dots},
		{sep~upper~left~dots}{ set~keys~x={ sep~upper~left=\semantex_data_tl_get_exp_not:nn { ##1 } { upper~left~dots } } },
		{sep~upper~left~...}{sep~upper~left~dots},
		{comma~upper~left~dots}{ set~keys~x={ comma~upper~left=\semantex_data_tl_get_exp_not:nn { ##1 } { upper~left~dots } } },
		{comma~upper~left~...}{comma~upper~left~dots},
		{clear~upper~left}{
			execute={
				\semantex_data_tl_clear:nn { ##1 } { upper~left }
				\semantex_data_bool_set_false:nn { ##1 } { next~upper~left~with~sep }
				\semantex_data_int_clear:nn { ##1 } { number~of~upper~left~indices }
			},
		},
		{clear~pre~upper~left}{
			execute={ \semantex_data_tl_clear:nn { ##1 } { pre~upper~left } },
		},
		{clear~post~upper~left}{
			execute={ \semantex_data_tl_clear:nn { ##1 } { post~upper~left } },
		},
		{upper~left~*}{upper~left=\SemantexBullet},
		{upper~left~**}{upper~left=\SemantexDoubleBullet},
		{sep~upper~left~*}{sep~upper~left=\SemantexBullet},
		{sep~upper~left~**}{sep~upper~left=\SemantexDoubleBullet},
		{comma~upper~left~*}{comma~upper~left=\SemantexBullet},
		{comma~upper~left~**}{comma~upper~left=\SemantexDoubleBullet},
	},
	define~keys[1]={
		{upper~left}{
			execute={
				\tl_if_blank:nF{#1}{
					\semantex_data_tl_put_left:nnn { ##1 } { upper~left } { #1 }
					\semantex_data_bool_set_true:nn { ##1 } { next~upper~left~with~sep }
					\semantex_data_int_incr:nn { ##1 } { number~of~upper~left~indices }
				}
			},
		},
		{sep~upper~left}{
			execute={
				\tl_if_blank:nF { #1 }
				{
					\semantex_data_bool_get:nnTF { ##1 } { next~upper~left~with~sep }
					{
						\semantex_data_tl_put_left:nnx { ##1 } { upper~left }
						{ \semantex_data_tl_get_exp_not:nn { ##1 } { upper~left~sep } }
						\semantex_data_tl_put_left:nnn { ##1 } { upper~left } { #1 }
					}
					{
						\semantex_data_tl_put_left:nnn { ##1 } { upper~left } { #1 }
					}
					\semantex_data_bool_set_true:nn { ##1 } { next~upper~left~with~sep }
					\semantex_data_int_incr:nn { ##1 } { number~of~upper~left~indices }
				}
			},
		},
		{comma~upper~left}{
			execute={
				\tl_if_blank:nF{#1}
				{
					\semantex_data_bool_get:nnTF { ##1 } { next~upper~left~with~sep }
					{
						\semantex_data_tl_put_left:nnn { ##1 } { upper~left } { , #1 }
					}
					{
						\semantex_data_tl_put_left:nnn { ##1 } { upper~left } { #1 }
					}
					\semantex_data_bool_set_true:nn { ##1 } { next~upper~left~with~sep }
					\semantex_data_int_incr:nn { ##1 } { number~of~upper~left~indices }
				}
			}
		},
		{pre~upper~left}{
			execute={
				\tl_if_blank:nF{#1}{
					\semantex_data_tl_put_right:nnn { ##1 } { pre~upper~left } { #1 }
				}
			},
		},
		{pre~upper~left~put~left}{
			execute={
				\tl_if_blank:nF{#1}{
					\semantex_data_tl_put_left:nnn { ##1 } { pre~upper~left } { #1 }
				}
			},
		},
		{post~upper~left}{
			execute={
				\tl_if_blank:nF{#1}{
					\semantex_data_tl_put_left:nnn { ##1 } { post~upper~left } { #1 }
				}
			},
		},
		{post~upper~left~put~right}{
			execute={
				\tl_if_blank:nF{#1}{
					\semantex_data_tl_put_right:nnn { ##1 } { post~upper~left } { #1 }
				}
			},
		},
		{upper~left~put~right}{
			execute={
				\tl_if_blank:nF { #1 }
				{
					\semantex_data_tl_put_right:nnn { ##1 } { upper~left } { #1 }
					\semantex_data_bool_set_true:nn { ##1 } { next~upper~left~with~sep }
					\semantex_data_int_incr:nn { ##1 } { number~of~upper~left~indices }
				}			
			},
		},
		{set~upper~left~slot}{
			execute={ \semantex_data_tl_set:nnn { ##1 } { upper~left~slot } { #1 } },
		},
		{upper~left~slot~with~other~sep}{
			execute={
				\semantex_valuekey:nnx { ##1 } { upper~left~with~other~sep }
				{
					{ \exp_not:n { #1 } }
					{ \semantex_data_tl_get_exp_not:nn { ##1 } { upper~left~slot } }
				}
			},
		},
		{set~upper~left~dots}{
			execute={ \semantex_data_tl_set:nnn { ##1 } { upper~left~dots } { #1 } },
		},
		{upper~left~dots~with~other~sep}{
			execute={			
				\semantex_valuekey:nnx { upper~left~with~other~sep }
				{
					{ \exp_not:n { #1 } }
					{ \semantex_data_tl_get_exp_not:nn { ##1 } { upper~left~dots } }
				}
			},
		},
		{upper~left~...~with~other~sep}{
			execute={			
				\semantex_valuekey:nnx { upper~left~with~other~sep }
				{
					{ \exp_not:n { #1 } }
					{ \semantex_data_tl_get_exp_not:nn { ##1 } { upper~left~dots } }
				}
			},
		},
		{upper~left~*~with~other~sep}{upper~left~with~other~sep={#1}{\SemantexBullet}},
		{upper~left~**~with~other~sep}{upper~left~with~other~sep={#1}{\SemantexDoubleBullet}},
		{set~upper~left~sep}{
			execute={ \semantex_data_tl_set:nnn { ##1 } { upper~left~sep } { #1 } },
		},
		{next~upper~left~with~sep}{
			str~if~eq~TF={#1}{false}
			{
				bool~set~false=next~upper~left~with~sep,
			}
			{
				str~if~eq~TF={#1}{true}
				{
					bool~set~true=next~upper~left~with~sep,
				}
				{
					ERROR~key~value~not~found={next~upper~left~with~sep}{#1},
				},
			},
		},
	},
	define~keys[2]={
		{upper~left~with~other~sep}{
			execute={
				\semantex_data_bool_get:nnTF { ##1 } { next~upper~left~with~sep }
					{ \semantex_data_tl_put_left:nnn { ##1 } { upper~left } { #2 #1 } }
					{ \semantex_data_tl_put_left:nnn { ##1 } { upper~left } { #2 } }
				\semantex_data_bool_set_true:nn { ##1 } { next~upper~left~with~sep }
				\semantex_data_int_incr:nn { ##1 } { number~of~upper~left~indices }
			},
		},
	},
	set~upper~left~sep={ , },
	set~upper~left~dots={ \dots },
	set~upper~left~slot={ {-} },
	% Lower left indices:
	data~provide=lower~left,
	bool~provide=next~lower~left~with~sep,
	int~provide=number~of~lower~left~indices,
	data~provide=pre~lower~left,
	data~provide=post~lower~left,
	define~keys={
		{lower~left~slot}{ set~keys~x={ lower~left=\semantex_data_tl_get_exp_not:nn { ##1 } { lower~left~slot } } },
		{sep~lower~left~slot}{ set~keys~x={ sep~lower~left=\semantex_data_tl_get_exp_not:nn { ##1 } { lower~left~slot } } },
		{comma~lower~left~slot}{ set~keys~x={ comma~lower~left=\semantex_data_tl_get_exp_not:nn { ##1 } { lower~left~slot } } },
		{lower~left~dots}{ set~keys~x={ lower~left=\semantex_data_tl_get_exp_not:nn { ##1 } { lower~left~dots } } },
		{lower~left~...}{lower~left~dots},
		{sep~lower~left~dots}{ set~keys~x={ sep~lower~left=\semantex_data_tl_get_exp_not:nn { ##1 } { lower~left~dots } } },
		{sep~lower~left~...}{sep~lower~left~dots},
		{comma~lower~left~dots}{ set~keys~x={ comma~lower~left=\semantex_data_tl_get_exp_not:nn { ##1 } { lower~left~dots } } },
		{comma~lower~left~...}{comma~lower~left~dots},
		{clear~lower~left}{
			execute={
				\semantex_data_tl_clear:nn { ##1 } { lower~left }
				\semantex_data_bool_set_false:nn { ##1 } { next~lower~left~with~sep }
				\semantex_data_int_clear:nn { ##1 } { number~of~lower~left~indices }
			},
		},
		{clear~pre~lower~left}{
			execute={ \semantex_data_tl_clear:nn { ##1 } { pre~lower~left } },
		},
		{clear~post~lower~left}{
			execute={ \semantex_data_tl_clear:nn { ##1 } { post~lower~left } },
		},
		{lower~left~*}{lower~left=\SemantexBullet},
		{lower~left~**}{lower~left=\SemantexDoubleBullet},
		{sep~lower~left~*}{sep~lower~left=\SemantexBullet},
		{sep~lower~left~**}{sep~lower~left=\SemantexDoubleBullet},
		{comma~lower~left~*}{comma~lower~left=\SemantexBullet},
		{comma~lower~left~**}{comma~lower~left=\SemantexDoubleBullet},
	},
	define~keys[1]={
		{lower~left}{
			execute={
				\tl_if_blank:nF{#1}{
					\semantex_data_tl_put_left:nnn { ##1 } { lower~left } { #1 }
					\semantex_data_bool_set_true:nn { ##1 } { next~lower~left~with~sep }
					\semantex_data_int_incr:nn { ##1 } { number~of~lower~left~indices }
				}
			},
		},
		{sep~lower~left}{
			execute={
				\tl_if_blank:nF { #1 }
				{
					\semantex_data_bool_get:nnTF { ##1 } { next~lower~left~with~sep }
					{
						\semantex_data_tl_put_left:nnx { ##1 } { lower~left }
						{ \semantex_data_tl_get_exp_not:nn { ##1 } { lower~left~sep } }
						\semantex_data_tl_put_left:nnn { ##1 } { lower~left } { #1 }
					}
					{
						\semantex_data_tl_put_left:nnn { ##1 } { lower~left } { #1 }
					}
					\semantex_data_bool_set_true:nn { ##1 } { next~lower~left~with~sep }
					\semantex_data_int_incr:nn { ##1 } { number~of~lower~left~indices }
				}
			},
		},
		{comma~lower~left}{
			execute={
				\tl_if_blank:nF{#1}
				{
					\semantex_data_bool_get:nnTF { ##1 } { next~lower~left~with~sep }
					{
						\semantex_data_tl_put_left:nnn { ##1 } { lower~left } { , #1 }
					}
					{
						\semantex_data_tl_put_left:nnn { ##1 } { lower~left } { #1 }
					}
					\semantex_data_bool_set_true:nn { ##1 } { next~lower~left~with~sep }
					\semantex_data_int_incr:nn { ##1 } { number~of~lower~left~indices }
				}
			}
		},
		{pre~lower~left}{
			execute={
				\tl_if_blank:nF{#1}{
					\semantex_data_tl_put_right:nnn { ##1 } { pre~lower~left } { #1 }
				}
			},
		},
		{pre~lower~left~put~left}{
			execute={
				\tl_if_blank:nF{#1}{
					\semantex_data_tl_put_left:nnn { ##1 } { pre~lower~left } { #1 }
				}
			},
		},
		{post~lower~left}{
			execute={
				\tl_if_blank:nF{#1}{
					\semantex_data_tl_put_left:nnn { ##1 } { post~lower~left } { #1 }
				}
			},
		},
		{post~lower~left~put~right}{
			execute={
				\tl_if_blank:nF{#1}{
					\semantex_data_tl_put_right:nnn { ##1 } { post~lower~left } { #1 }
				}
			},
		},
		{lower~left~put~right}{
			execute={
				\tl_if_blank:nF { #1 }
				{
					\semantex_data_tl_put_right:nnn { ##1 } { lower~left } { #1 }
					\semantex_data_bool_set_true:nn { ##1 } { next~lower~left~with~sep }
					\semantex_data_int_incr:nn { ##1 } { number~of~lower~left~indices }
				}			
			},
		},
		{set~lower~left~slot}{
			execute={ \semantex_data_tl_set:nnn { ##1 } { lower~left~slot } { #1 } },
		},
		{lower~left~slot~with~other~sep}{
			execute={
				\semantex_valuekey:nnx { ##1 } { lower~left~with~other~sep }
				{
					{ \exp_not:n { #1 } }
					{ \semantex_data_tl_get_exp_not:nn { ##1 } { lower~left~slot } },
				}
			},
		},
		{set~lower~left~dots}{
			execute={ \semantex_data_tl_set:nnn { ##1 } { lower~left~dots } { #1 } },
		},
		{lower~left~dots~with~other~sep}{
			execute={
				\semantex_valuekey:nnx { ##1 } { lower~left~with~other~sep }
				{
					{ \exp_not:n { #1 } }
					{ \semantex_data_tl_get_exp_not:nn { ##1 } { lower~left~dots } }
				}
			},
		},
		{lower~left~...~with~other~sep}{
			execute={
				\semantex_valuekey:nnx { ##1 } { lower~left~with~other~sep }
				{
					{ \exp_not:n { #1 } }
					{ \semantex_data_tl_get_exp_not:nn { ##1 } { lower~left~dots } }
				}
			},
		},
		{lower~left~*~with~other~sep}{lower~left~with~other~sep={#1}{\SemantexBullet}},
		{lower~left~**~with~other~sep}{lower~left~with~other~sep={#1}{\SemantexDoubleBullet}},
		{set~lower~left~sep}{
			execute={ \semantex_data_tl_set:nnn { ##1 } { lower~left~sep } { #1 } },
		},
		{next~lower~left~with~sep}{
			str~if~eq~TF={#1}{false}
			{
				bool~set~false=next~lower~left~with~sep,
			}
			{
				str~if~eq~TF={#1}{true}
				{
					bool~set~true=next~lower~left~with~sep,
				}
				{
					ERROR~key~value~not~found={next~lower~left~with~sep}{#1},
				},
			},
		},
	},
	define~keys[2]={
		{lower~left~with~other~sep}{
			execute={
				\semantex_data_bool_get:nnTF { ##1 } { next~lower~left~with~sep }
					{ \semantex_data_tl_put_left:nnn { ##1 } { lower~left } { #2 #1 } }
					{ \semantex_data_tl_put_left:nnn { ##1 } { lower~left } { #2 } }
				\semantex_data_bool_set_true:nn { ##1 } { next~lower~left~with~sep }
				\semantex_data_int_incr:nn { ##1 } { number~of~lower~left~indices }
			},
		},
	},
	set~lower~left~sep={ , },
	set~lower~left~dots={ \dots },
	set~lower~left~slot={ {-} },
	% The "d" index:
	define~keys={
		{d~slot}{
			bool~if~TF={upper~grading}
				{ upper~slot }
				{ lower~slot },
		},
		{sep~d~slot}{
			bool~if~TF={upper~grading}
				{ sep~upper~slot }
				{ sep~lower~slot },
		},
		{comma~d~slot}{
			bool~if~TF={upper~grading}
				{ comma~upper~slot }
				{ comma~lower~slot },
		},
		{d~dots}{
			bool~if~TF={upper~grading}
				{ upper~dots }
				{ lower~dots },
		},
		{d~...}{d~dots},
		{sep~d~dots}{
			bool~if~TF={upper~grading}
				{ sep~upper~dots }
				{ sep~lower~dots },
		},
		{sep~d~...}{sep~d~dots},
		{comma~d~dots}{
			bool~if~TF={upper~grading}
				{ comma~upper~dots }
				{ comma~lower~dots },
		},
		{comma~d~...}{comma~d~dots},
		{clear~d}{
			bool~if~TF={upper~grading}
				{ clear~upper }
				{ clear~lower },
		},
		{clear~pre~d}{
			bool~if~TF={upper~grading}
				{ clear~pre~upper }
				{ clear~pre~lower },
		},
		{clear~post~d}{
			bool~if~TF={upper~grading}
				{ clear~post~upper }
				{ clear~post~lower },
		},
		{d~*}{
			bool~if~TF={upper~grading}
				{ upper~* }
				{ lower~* },
		},
		{d~**}{
			bool~if~TF={upper~grading}
				{ upper~** }
				{ lower~** },
		},
		{sep~d~*}{
			bool~if~TF={upper~grading}
				{ sep~upper~* }
				{ sep~lower~* },
		},
		{sep~d~**}{
			bool~if~TF={upper~grading}
				{ sep~upper~** }
				{ sep~lower~** },
		},
		{comma~d~*}{
			bool~if~TF={upper~grading}
				{ comma~upper~* }
				{ comma~lower~* },
		},
		{comma~d~**}{
			bool~if~TF={upper~grading}
				{ comma~upper~** }
				{ comma~lower~** },
		},
	},
	define~keys[1]={
		{d}{
			execute={
				\semantex_data_bool_get:nnTF { ##1 } { upper~grading }
					{ \semantex_valuekey:nnn { ##1 } { upper } { #1 } }
					{ \semantex_valuekey:nnn { ##1 } { lower } { #1 } }
			},
		},
		{sep~d}{
			execute={
				\semantex_data_bool_get:nnTF { ##1 } { upper~grading }
					{ \semantex_valuekey:nnn { ##1 } { sep~upper } { #1 } }
					{ \semantex_valuekey:nnn { ##1 } { sep~lower } { #1 } }
			},
		},
		{comma~d}{
			execute={
				\semantex_data_bool_get:nnTF { ##1 } { upper~grading }
					{ \semantex_valuekey:nnn { ##1 } { comma~upper } { #1 } }
					{ \semantex_valuekey:nnn { ##1 } { comma~lower } { #1 } }
			},
		},
		{pre~d}{
			bool~if~TF={upper~grading}
			{
				pre~upper={#1},
			}
			{
				pre~lower={#1},
			},
		},
		{pre~d~put~left}{
			bool~if~TF={upper~grading}
			{
				pre~upper~put~left={#1},
			}
			{
				pre~lower~put~left={#1},
			},
		},
		{post~d}{
			bool~if~TF={upper~grading}
			{
				post~upper={#1},
			}
			{
				post~lower={#1},
			},
		},
		{post~d~put~right}{
			bool~if~TF={upper~grading}
			{
				post~upper~put~right={#1},
			}
			{
				post~lower~put~right={#1},
			},
		},
		{d~put~left}{
			bool~if~TF={upper~grading}
			{
				upper~put~left={#1},
			}
			{
				lower~put~left={#1},
			},
		},
		{set~d~slot}{
			bool~if~TF={upper~grading}
			{
				set~upper~slot={#1},
			}
			{
				set~lower~slot={#1},
			}
		},
		{d~slot~with~other~sep}{
			bool~if~TF={upper~grading}
			{
				upper~slot~with~other~sep={#1},
			}
			{
				lower~slot~with~other~sep={#1},
			},
		},
		{set~d~dots}{
			bool~if~TF={upper~grading}
			{
				set~upper~dots={#1},
			}
			{
				set~lower~dots={#1},
			}
		},
		{d~dots~with~other~sep}{
			bool~if~TF={upper~grading}
			{
				upper~dots~with~other~sep={#1},
			}
			{
				lower~dots~with~other~sep={#1},
			},
		},
		{d~...~with~other~sep}{
			d~dots~with~other~sep={#1},
		},
		{d~*~with~other~sep}{
			bool~if~TF={upper~grading}
				{ upper~*~with~other~sep={#1} }
				{ lower~*~with~other~sep={#1} },
		},
		{d~**~with~other~sep}{
			bool~if~TF={upper~grading}
				{ upper~**~with~other~sep={#1} }
				{ lower~**~with~other~sep={#1} },
		},
		{set~d~sep}{
			bool~if~TF={upper~grading}
			{
				set~upper~sep={#1},
			}
			{
				set~lower~sep={#1},
			},
		},
		{next~d~with~sep}{
			str~if~eq~TF={#1}{true}
			{
				bool~if~TF={upper~grading}
				{
					next~upper~with~sep=true,
				}
				{
					next~lower~with~sep=true,
				},
			}
			{
				str~if~eq~TF={#1}{false}
				{
					bool~if~TF={upper~grading}
					{
						next~upper~with~sep=false,
					}
					{
						next~lower~with~sep=false,
					},
				}
				{
					ERROR~key~value~not~found={next~d~with~other~sep}{#1},
				},
			},
		},
	},
	define~keys[2]={
		{d~with~other~sep}{
			bool~if~TF={upper~grading}
			{
				upper~with~other~sep={#1}{#2},
			}
			{
				lower~with~other~sep={#1}{#2},
			},
		},
	},
	% The "i" index:
	define~keys={
		{i~slot}{
			bool~if~TF={upper~grading}
				{ lower~slot }
				{ upper~slot },
		},
		{sep~i~slot}{
			bool~if~TF={upper~grading}
				{ sep~lower~slot }
				{ sep~upper~slot },
		},
		{comma~i~slot}{
			bool~if~TF={upper~grading}
				{ comma~lower~slot }
				{ comma~upper~slot },
		},
		{i~dots}{
			bool~if~TF={upper~grading}
				{ lower~dots }
				{ upper~dots },
		},
		{i~...}{i~dots},
		{sep~i~dots}{
			bool~if~TF={upper~grading}
				{ sep~lower~dots }
				{ sep~upper~dots },
		},
		{sep~i~...}{sep~i~dots},
		{comma~i~dots}{
			bool~if~TF={upper~grading}
				{ comma~lower~dots }
				{ comma~upper~dots },
		},
		{comma~i~...}{comma~i~dots},
		{clear~i}{
			bool~if~TF={upper~grading}
				{ clear~lower }
				{ clear~upper },
		},
		{clear~pre~i}{
			bool~if~TF={upper~grading}
				{ clear~pre~lower }
				{ clear~pre~upper },
		},
		{clear~post~i}{
			bool~if~TF={upper~grading}
				{ clear~post~lower }
				{ clear~post~upper },
		},
		{i~*}{
			bool~if~TF={upper~grading}
				{ lower~* }
				{ upper~* },
		},
		{i~**}{
			bool~if~TF={upper~grading}
				{ lower~** }
				{ upper~** },
		},
		{sep~i~*}{
			bool~if~TF={upper~grading}
				{ sep~lower~* }
				{ sep~upper~* },
		},
		{sep~i~**}{
			bool~if~TF={upper~grading}
				{ sep~lower~** }
				{ sep~upper~** },
		},
		{comma~i~*}{
			bool~if~TF={upper~grading}
				{ comma~lower~* }
				{ comma~upper~* },
		},
		{comma~i~**}{
			bool~if~TF={upper~grading}
				{ comma~lower~** }
				{ comma~upper~** },
		},
	},
	define~keys[1]={
		{i}{
			execute={
				\semantex_data_bool_get:nnTF { ##1 } { upper~grading }
					{ \semantex_valuekey:nnn { ##1 } { lower } { #1 } }
					{ \semantex_valuekey:nnn { ##1 } { upper } { #1 } }
			},
		},
		{sep~i}{
			execute={
				\semantex_data_bool_get:nnTF { ##1 } { upper~grading }
					{ \semantex_valuekey:nnn { ##1 } { sep~lower } { #1 } }
					{ \semantex_valuekey:nnn { ##1 } { sep~upper } { #1 } }
			},
		},
		{comma~i}{
			execute={
				\semantex_data_bool_get:nnTF { ##1 } { upper~grading }
					{ \semantex_valuekey:nnn { ##1 } { comma~lower } { #1 } }
					{ \semantex_valuekey:nnn { ##1 } { comma~upper } { #1 } }
			},
		},
		{pre~i}{
			bool~if~TF={upper~grading}
			{
				pre~lower={#1},
			}
			{
				pre~upper={#1},
			},
		},
		{pre~i~put~left}{
			bool~if~TF={upper~grading}
			{
				pre~lower~put~left={#1},
			}
			{
				pre~upper~put~left={#1},
			},
		},
		{post~i}{
			bool~if~TF={upper~grading}
			{
				post~lower={#1},
			}
			{
				post~upper={#1},
			},
		},
		{post~i~put~right}{
			bool~if~TF={upper~grading}
			{
				post~lower~put~right={#1},
			}
			{
				post~upper~put~right={#1},
			},
		},
		{i~put~left}{
			bool~if~TF={upper~grading}
			{
				lower~put~left={#1},
			}{
				upper~put~left={#1},
			},
		},
		{set~i~slot}{
			bool~if~TF={upper~grading}
			{
				set~lower~slot={#1},
			}
			{
				set~upper~slot={#1},
			}
		},
		{i~slot~with~other~sep}{
			bool~if~TF={upper~grading}
			{
				lower~slot~with~other~sep={#1},
			}
			{
				upper~slot~with~other~sep={#1},
			},
		},
		{set~i~dots}{
			bool~if~TF={upper~grading}
			{
				set~lower~dots={#1},
			}
			{
				set~upper~dots={#1},
			}
		},
		{i~dots~with~other~sep}{
			bool~if~TF={upper~grading}
			{
				lower~dots~with~other~sep={#1},
			}
			{
				upper~dots~with~other~sep={#1},
			},
		},
		{i~...~with~other~sep}{
			i~dots~with~other~sep={#1},
		},
		{i~*~with~other~sep}{
			bool~if~TF={upper~grading}
				{ lower~*~with~other~sep={#1} }
				{ upper~*~with~other~sep={#1} },
		},
		{i~**~with~other~sep}{
			bool~if~TF={upper~grading}
				{ lower~**~with~other~sep={#1} }
				{ upper~**~with~other~sep={#1} },
		},
		{set~i~sep}{
			bool~if~TF={upper~grading}
			{
				set~lower~sep={#1},
			}
			{
				set~upper~sep={#1},
			},
		},
		{next~i~with~sep}{
			str~if~eq~TF={#1}{true}
			{
				bool~if~TF={upper~grading}
				{
					next~lower~with~sep={#1},
				}
				{
					next~upper~with~sep={#1},
				},
			}
			{
				str~if~eq~TF={#1}{false}
				{
					bool~if~TF={upper~grading}
					{
						next~upper~with~sep={#1},
					}
					{
						next~lower~with~sep={#1},
					},
				}
				{
					ERROR~key~value~not~found={next~i~with~other~sep}{#1},
				},
			},
		},
	},
	define~keys[2]={
		{i~with~other~sep}{
			execute={
				\semantex_data_bool_get:nnTF { ##1 } { upper~grading }
					{ \semantex_valuekey:nnn { ##1 } { lower~with~other~sep } { { #1 } { #2 } } }
					{ \semantex_valuekey:nnn { ##1 } { upper~with~other~sep } { { #1 } { #2 } } }
			},
		},
	},
	% Argument keyval interface
	define~arg~keys[1]={
		{execute}{execute={#1}},
		{keys~set}{
			execute={
				\tl_set:Nn\l__semantex_keys_set_temp_tl{}
				\semantex_preprocess_keys:nN { #1 } \l__semantex_keys_set_temp_tl
				\exp_args:NNo\cs_set:Nn\l__semantex_keys_set_temp_cs:n{\l__semantex_keys_set_temp_tl}
				\l__semantex_keys_set_temp_cs:n { ##1 }
			},
		},
		{set~keys}{
			execute={
				\tl_set:Nn\l__semantex_keys_set_temp_tl{}
				\semantex_preprocess_keys:nN { #1 } \l__semantex_keys_set_temp_tl
				\exp_args:NNo\cs_set:Nn\l__semantex_keys_set_temp_cs:n{\l__semantex_keys_set_temp_tl}
				\l__semantex_keys_set_temp_cs:n { ##1 }
			},
		},
		{keys~set~x}{
			execute={
				\tl_set:Nn\l__semantex_keys_set_x_temp_tl{}
				\semantex_preprocess_keys_x:nN { #1 } \l__semantex_keys_set_x_temp_tl
				\exp_args:NNo\cs_set:Nn\l__semantex_keys_set_x_temp_cs:n{\l__semantex_keys_set_x_temp_tl}
				\l__semantex_keys_set_x_temp_cs:n { ##1 }
			},
		},
		{set~keys~x}{
			execute={
				\tl_set:Nn\l__semantex_keys_set_x_temp_tl{}
				\semantex_preprocess_keys_x:nN { #1 } \l__semantex_keys_set_x_temp_tl
				\exp_args:NNo\cs_set:Nn\l__semantex_keys_set_x_temp_cs:n{\l__semantex_keys_set_x_temp_tl}
				\l__semantex_keys_set_x_temp_cs:n { ##1 }
			},
		},
		{set~arg~keys}{
			execute={
				\tl_set:Nn\l__semantex_arg_keys_set_temp_tl{}
				\semantex_preprocess_arg_keys:nN { #1 } \l__semantex_arg_keys_set_temp_tl
				\exp_args:NNo\cs_set:Nn\l__semantex_arg_keys_set_temp_cs:n{\l__semantex_arg_keys_set_temp_tl}
				\l__semantex_arg_keys_set_temp_cs:n { ##1 }
			},
		},
		{arg~keys~set}{
			execute={
				\tl_set:Nn\l__semantex_arg_keys_set_temp_tl{}
				\semantex_preprocess_arg_keys:nN { #1 } \l__semantex_arg_keys_set_temp_tl
				\exp_args:NNo\cs_set:Nn\l__semantex_arg_keys_set_temp_cs:n{\l__semantex_arg_keys_set_temp_tl}
				\l__semantex_arg_keys_set_temp_cs:n { ##1 }
			},
		},
		{set~arg~keys~x}{
			execute={
				\tl_set:Nn\l__semantex_arg_keys_set_x_temp_tl{}
				\semantex_preprocess_arg_keys_x:nN { #1 } \l__semantex_arg_keys_set_x_temp_tl
				\exp_args:NNo\cs_set:Nn\l__semantex_arg_keys_set_x_temp_cs:n{\l__semantex_arg_keys_set_x_temp_tl}
				\l__semantex_arg_keys_set_x_temp_cs:n { ##1 }
			},
		},
		{arg~keys~set~x}{
			execute={
				\tl_set:Nn\l__semantex_arg_keys_set_x_temp_tl{}
				\semantex_preprocess_arg_keys_x:nN { #1 } \l__semantex_arg_keys_set_x_temp_tl
				\exp_args:NNo\cs_set:Nn\l__semantex_arg_keys_set_x_temp_cs:n{\l__semantex_arg_keys_set_x_temp_tl}
				\l__semantex_arg_keys_set_x_temp_cs:n { ##1 }
			},
		},
		{set~arg~single~keys}{
			execute={
				\tl_set:Nn\l__semantex_arg_singlekeys_set_temp_tl{}
				\semantex_preprocess_arg_singlekeys:nN { #1 } \l__semantex_arg_singlekeys_set_temp_tl
				\exp_args:NNo\cs_set:Nn\l__semantex_arg_singlekeys_set_temp_cs:n{\l__semantex_arg_singlekeys_set_temp_tl}
				\l__semantex_arg_singlekeys_set_temp_cs:n { ##1 }
			},
		},
		{arg~single~keys~set}{
			execute={
				\tl_set:Nn\l__semantex_arg_singlekeys_set_temp_tl{}
				\semantex_preprocess_arg_singlekeys:nN { #1 } \l__semantex_arg_singlekeys_set_temp_tl
				\exp_args:NNo\cs_set:Nn\l__semantex_arg_singlekeys_set_temp_cs:n{\l__semantex_arg_singlekeys_set_temp_tl}
				\l__semantex_arg_singlekeys_set_temp_cs:n { ##1 }
			},
		},
		{set~arg~single~keys~x}{
			execute={
				\tl_set:Nn\l__semantex_arg_singlekeys_set_x_temp_tl{}
				\semantex_preprocess_arg_singlekeys_x:nN { #1 } \l__semantex_arg_singlekeys_set_x_temp_tl
				\exp_args:NNo\cs_set:Nn\l__semantex_arg_singlekeys_set_x_temp_cs:n{\l__semantex_arg_singlekeys_set_x_temp_tl}
				\l__semantex_arg_singlekeys_set_x_temp_cs:n { ##1 }
			},
		},
		{arg~single~keys~set~x}{
			execute={
				\tl_set:Nn\l__semantex_arg_singlekeys_set_x_temp_tl{}
				\semantex_preprocess_arg_singlekeys_x:nN { #1 } \l__semantex_arg_singlekeys_set_x_temp_tl
				\exp_args:NNo\cs_set:Nn\l__semantex_arg_singlekeys_set_x_temp_cs:n{\l__semantex_arg_singlekeys_set_x_temp_tl}
				\l__semantex_arg_singlekeys_set_x_temp_cs:n { ##1 }
			},
		},
		{set~one~arg~single~key}{ execute={ \semantex_arg_singlekey:nn { ##1 } { #1 } } },
		{one~arg~single~key~set}{ execute={ \semantex_arg_singlekey:nn { ##1 } { #1 } } },
		{set~one~arg~single~key~x}{ execute={ \semantex_arg_singlekey_x:nn { ##1 } { #1 } } },
		{one~arg~single~key~set~x}{ execute={ \semantex_arg_singlekey_x:nn { ##1 } { #1 } } },
		{set~arg~without~keyval}{ execute={ \semantex_arg_without_keyval:nn { ##1 } { #1 } } },
		{arg~without~keyval~set}{ execute={ \semantex_arg_without_keyval:nn { ##1 } { #1 } } },
		{set~arg~without~keyval~x}{ execute={ \semantex_arg_without_keyval:nx { ##1 } { #1 } } },
		{arg~without~keyval~set~x}{ execute={ \semantex_arg_without_keyval:nx { ##1 } { #1 } } },
		{default}{sep={#1}},
		{...~with~other~sep}{dots~with~other~sep={#1}},
		{sep}{
			execute={
				\semantex_data_bool_get:nnTF { ##1 } { next~arg~with~sep }
				{
					\semantex_data_tl_put_right:nnx { ##1 } { arg }
					{
						\semantex_data_tl_get_exp_not:nn { ##1 } { arg~sep }
					}
				}
				{
					% do nothing
				}
				\semantex_data_tl_put_right:nnn { ##1 } { arg } { #1 }
				\semantex_data_int_incr:nn { ##1 } { number~of~arguments }
				\semantex_data_bool_set_true:nn { ##1 } { next~arg~with~sep }
			}
		},
		{comma}{
			execute={
				\semantex_data_bool_get:nnTF { ##1 } { next~arg~with~sep }
				{
					\semantex_data_tl_put_right:nnn { ##1 } { arg } { , #1 }
				}
				{
					\semantex_data_tl_put_right:nnn { ##1 } { arg } { #1 }
				}
				\semantex_data_int_incr:nn { ##1 } { number~of~arguments }
				\semantex_data_bool_set_true:nn { ##1 } { next~arg~with~sep }
			}
		},
		{dots~with~other~sep}{
			execute={
				\semantex_arg_valuekey:nnx { ##1 } { other~sep }
				{
					{ \exp_not:n { #1 } }
					{ \semantex_data_tl_get_exp_not:nn { ##1 } { arg~dots } }
				}
			},
		},
		{slot~with~other~sep}{
			execute={
				\semantex_arg_valuekey:nnx { ##1 } { other~sep }
				{
					{ \exp_not:n { #1 } }
					{ \semantex_data_tl_get_exp_not:nn { ##1 } { arg~slot } }
				}
			},
		},
	},
	define~arg~keys={
		{dots}{
			execute={
				\semantex_arg_valuekey:nnx { ##1 } { sep }
				{
					\semantex_data_tl_get_exp_not:nn { ##1 } { arg~dots }
				}
			},
		},
		{...}{dots},
		{comma~dots}{
			execute={
				\semantex_arg_valuekey:nnx { ##1 } { comma }
				{
					\semantex_data_tl_get_exp_not:nn { ##1 } { arg~dots }
				}
			},
		},
		{comma~...}{comma~dots},
		{slot}{
			execute={
				\semantex_arg_valuekey:nnx { ##1 } { sep }
				{
					\semantex_data_tl_get_exp_not:nn { ##1 } { arg~slot }
				}
			},
		},
		{comma~slot}{
			execute={
				\semantex_arg_valuekey:nnx { ##1 } { comma }
				{
					\semantex_data_tl_get_exp_not:nn { ##1 } { arg~slot }
				}
			},
		},
	},
	define~arg~keys[2]={
		{other~sep}{
			execute={
				\semantex_data_bool_get:nnTF { ##1 } { next~arg~with~sep }
				{
					\semantex_data_tl_put_right:nnn { ##1 } { arg } { #1 #2 }
				}
				{
					\semantex_data_tl_put_right:nnn { ##1 } { arg } { #2 }
				}
				\semantex_data_int_incr:nn { ##1 } { number~of~arguments }
				\semantex_data_bool_set_true:nn { ##1 } { next~arg~with~sep }
			},
		},
	},
]

\cs_set_eq:cc { __semantex_old_version_of_semantex_declare_object_of_\g_semantex_class_SemantexBaseObject_register_tl :Nw } { __semantex_declare_object_of_\g_semantex_class_SemantexBaseObject_register_tl :Nw }

\cs_set_protected:Npn \__semantex_declare_object_of_class_SemantexBaseObject:Nw#1
{
	\msg_error:nnn { semantex } { created_a_SemantexBaseObject } { #1 }
	\use:c { __semantex_old_version_of_semantex_declare_object_of_\g_semantex_class_SemantexBaseObject_register_tl :Nw } #1
}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%    PROCESSING PACKAGE KEYVAL SETUP
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\ProcessKeysOptions { semantex }

% ... and they lived happily ever after.