\RequirePackage{xparse,l3keys2e,leftindex}
\ProvidesExplPackage{semantex}{2020/09/27}{0.44}{}

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


\cs_set_eq:NN \semantex_keyval_parse:NNn \keyval_parse:NNn

\keys_define:nn { semantex }
{
	keyvalparser .code:n = \cs_set_eq:NN \semantex_keyval_parse:NNn #1,
	keyvalparser .value_required:n = true,
	semtexfile .choice:,
	semtexfile / true .code:n = \semantex_turn_semtex_file_on:,
	semtexfile / false .code:n = \semantex_turn_semtex_file_off:,
	semtexfile / .code:n = \semantex_turn_semtex_file_on:,
	semtexfile / 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 { \DeclareClass {\SemantexBaseObject } }
		\iow_now:Nn \g__semantex_semtex_file_stream_temp_iow { \DeclareObject {\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 { \DeclareClass{#1} }
}

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

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

\cs_set_eq:NN\SemantexRecordObject\semantex_write_object_declaration_to_semtex_file:n

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%	THE FOLLOWING SECTION IS IDENTICAL TO THE semtex PACKAGE
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% These are some essential commands that are needed for bullets and parentheses,
% and they are the only ones that will not be stripped by running the
% stripsemantex algorithm. Therefore, they are also available as a standalone
% package, called "semtex". This name is meant to suggest "stripped SemanTeX",
% and at the same time, semtex is the name of a plastic explosive, suggesting
% "blown-up SemanTeX".
% (Mathematicians are not famous for the quality of their humour.)

% Bullets:

\box_if_exist:NF \g__semantex_bullet_box
{
	\box_new:N \g__semantex_bullet_box
	\hbox_set:Nn \g__semantex_bullet_box { $\cdot$ }
	\box_scale:Nnn \g__semantex_bullet_box {1.2} {1.2}
	\tl_set:Nn\g_semantex_bullet
	{
		\box_move_up:nn{-0.25ex}{\box_use:N \g__semantex_bullet_box}
	}

	\tl_set:Nn\g_semantex_double_bullet{\g_semantex_bullet \g_semantex_bullet}
	
	\tl_set_eq:NN\SemantexBullet \g_semantex_bullet
	
	\tl_set_eq:NN \SemantexDoubleBullet \g_semantex_double_bullet
}

% Parentheses:

\cs_set:Npn\SemantexLeft { \mathopen{}\mathclose\bgroup\left }

\cs_set:Npn\SemantexRight { \aftergroup\egroup\right }

\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:
}

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

\DeclareDocumentCommand\semantex_new_simple_class:Nw{mO{}} % new simple-type class
{
	% #1 = class name
	% #2 = options
	\semantex_new_class:Nn { #1 } { \semantex_class_set_keys:Nn #1 { #2 } }
	\DeclareDocumentCommand{#1}{m}
	{
		% the actual \#1 command
		\semantex_write_original_source_to_semtex_file:n { #1 { ##1 } }
		\semantex_render_class:Nn #1 {
			\semantex_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_class:Nn #1 {
			\semantex_class_set_symbol:Nn #1 { ##2 }
			##1
		}
	}
	\exp_args:Nc\DeclareDocumentCommand{__semantex_new_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_new_object:NNn #1 ##1 {
				\semantex_object_set_symbol:Nn ##1 { ##2 }
				\semantex_object_set_keys:Nn ##1 { ##3 }
			}
		}
		{
			\semantex_new_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 { }
		}
	}
}

\tl_set_eq:NN\NewSimpleClass\semantex_new_simple_class:Nw

\DeclareDocumentCommand\semantex_new_symbol_class:Nw{mO{}} % new symbol-type class
{
	% #1 = class name
	% #2 = options
	\semantex_new_class:Nn { #1 } { \semantex_class_set_keys:Nn #1 { #2 } }
	\DeclareDocumentCommand{#1}{mo}
	{
		% the actual \#1 command
		\IfValueTF{##2}
		{
			\semantex_write_original_source_to_semtex_file:n { #1 { ##1 } { ##2 } }
			\semantex_render_class:Nn #1 {
				\semantex_class_do_output:N #1
				\semantex_class_set_symbol:Nn #1 { ##1 }
				\semantex_class_set_keys:Nn #1 { ##2 }
			}
		}
		{
			\semantex_write_original_source_to_semtex_file:n { #1 { ##1 } }
			\semantex_render_class:Nn #1 {
				\semantex_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_class:Nn #1 {
				\semantex_class_do_output:N #1
				\semantex_class_set_symbol:Nn #1 { ##2 }
				##1
				\semantex_class_set_keys:Nn #1 { ##3 }
			}
		}
		{
			%\semantex_add_to_existing_original_source_in_semtex_file:n { } % write nothing to file
			\semantex_render_class:Nn #1 {
				\semantex_class_set_symbol:Nn #1 { ##2 }
				##1
			}
		}
	}
	\exp_args:Nc\DeclareDocumentCommand{__semantex_new_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_new_object:NNn #1 ##1 {
				\semantex_object_set_symbol:Nn ##1 { ##2 }
				\semantex_object_set_keys:Nn ##1 { ##3 }
			}
		}
		{
			\semantex_new_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 { }
			}
		}
	}
}

\tl_set_eq:NN\NewSymbolClass\semantex_new_symbol_class:Nw

\DeclareDocumentCommand\semantex_new_variable_class:Nw{mO{}} % new variable-type class
{
	% #1 = class name
	% #2 = options
	\semantex_new_class:Nn { #1 } { \semantex_class_set_keys:Nn #1 { #2 } }
	%\semantex_new_class:Nn #1 { #2 }
	\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_class:Nn #1 {
						\semantex_class_do_output:N #1
						\semantex_class_set_symbol:Nn #1 { ##1 }
						\semantex_class_set_keys:Nn #1 { ##2 }
						\semantex_class_set_arg:Nn #1 { ##3 }
					}
				}
				{
					\semantex_write_original_source_to_semtex_file:n { #1 { ##1 } [ ##2 ] }
					\semantex_render_class:Nn #1 { 
						\semantex_class_do_output:N #1
						\semantex_class_set_symbol:Nn #1 { ##1 }
						\semantex_class_set_keys:Nn #1 { ##2 }
					}
				}
			}
			{
				\IfValueTF { ##3 }
				{
					\semantex_write_original_source_to_semtex_file:n { #1 { ##1 } { ##3 } }
					\semantex_render_class:Nn #1 {
						\semantex_class_do_output:N #1
						\semantex_class_set_symbol:Nn #1 { ##1 }
						\semantex_class_set_arg:Nn #1 { ##3 }
					}
				}
				{
					\semantex_write_original_source_to_semtex_file:n { #1 { ##1 } }
					\semantex_render_class:Nn #1 {
						\semantex_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_class:Nn #1 {
					\semantex_class_do_output:N #1
					\semantex_class_set_symbol:Nn #1 { ##2 }
					##1
					\semantex_class_set_keys:Nn #1 { ##3 }
					\semantex_class_set_arg:Nn #1 { ##4 }
				}
			}
			{
				\semantex_add_to_existing_original_source_in_semtex_file:n { [ ##3 ] }
				\semantex_render_class:Nn #1 {
					\semantex_class_do_output:N #1
					\semantex_class_set_symbol:Nn #1 { ##2 }
					##1
					\semantex_class_set_keys:Nn #1 { ##3 }
				}
			}
		}
		{
			\IfValueTF { ##4 }
			{
				\semantex_add_to_existing_original_source_in_semtex_file:n { { ##4 } }
				\semantex_render_class:Nn #1 {
					\semantex_class_do_output:N #1
					\semantex_class_set_symbol:Nn #1 { ##2 }
					##1
					\semantex_class_set_arg:Nn #1 { ##4 }
				}
			}
			{
				% \semantex_add_to_existing_original_source_in_semtex_file:n { } % write nothing to file
				\semantex_render_class:Nn #1 {
					\semantex_class_set_symbol:Nn #1 { ##2 }
					##1
				}
			}
		}
	}
	\exp_args:Nc\DeclareDocumentCommand{__semantex_new_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_new_object:NNn #1 ##1 {
				\semantex_object_set_symbol:Nn ##1 { ##2 }
				\semantex_object_set_keys:Nn ##1 { ##3 }
			}
		}
		{
			\semantex_new_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 {}
				}
			}
		}
	}
}

\cs_set_eq:NN\NewVariableClass\semantex_new_variable_class:Nw

\DeclareDocumentCommand\semantex_new_cohomology_class:Nw{mO{}} % new cohomology-type class
{
	% #1 = class name
	% #2 = options
	\semantex_new_class:Nn { #1 } { \semantex_class_set_keys:Nn #1 { #2 } }
	\DeclareDocumentCommand{#1}{mogg}{
		% the actual \#1 command
		\IfValueTF{##2}
		{
			\IfValueTF { ##3 }
			{
				\str_if_eq:nnTF { ##3 }{ * }
				{
					\IfValueTF { ##4 }
					{
						\semantex_write_original_source_to_semtex_file:n
							{ #1 { ##1 } [ ##2 ] { * } { ##4 } }
						\semantex_render_class:Nn #1 {
							\semantex_class_do_output:N #1
							\semantex_class_set_symbol:Nn #1 { ##1 }
							\semantex_class_set_keys:Nn #1 { ##2 }
							\semantex_class_use_bullet:N #1
							\semantex_class_set_arg:Nn #1 { ##4 }
						}
					}
					{
						\semantex_write_original_source_to_semtex_file:n
							{ #1 { ##1 } [ ##2 ] { * } }
						\semantex_render_class:Nn #1 {
							\semantex_class_do_output:N #1
							\semantex_class_set_symbol:Nn #1 { ##1 }
							\semantex_class_set_keys:Nn #1 { ##2 }
							\semantex_class_use_bullet:N #1
						}
					}	
				}
				{
					\str_if_eq:nnTF { ##3 }{ ** }
					{
						\IfValueTF { ##4 }
						{
							\semantex_write_original_source_to_semtex_file:n
								{ #1 { ##1 } [ ##2 ] { ** } { ##4 } }
							\semantex_render_class:Nn #1 {
								\semantex_class_do_output:N #1
								\semantex_class_set_symbol:Nn #1 { ##1 }
								\semantex_class_set_keys:Nn #1 { ##2 }
								\semantex_class_use_double_bullet:N #1
								\semantex_class_set_arg:Nn #1 { ##4 }
							}
						}
						{
							\semantex_write_original_source_to_semtex_file:n
								{ #1 { ##1 } [ ##2 ] { ** } }
							\semantex_render_class:Nn #1 {
								\semantex_class_do_output:N #1
								\semantex_class_set_symbol:Nn #1 { ##1 }
								\semantex_class_set_keys:Nn #1 { ##2 }
								\semantex_class_use_double_bullet:N #1
							}
						}
					}
					{
						\IfValueTF { ##4 }
						{
							\semantex_write_original_source_to_semtex_file:n
								{ #1 { ##1 } [ ##2 ] { ##3 } { ##4 } }
							\semantex_render_class:Nn #1 {
								\semantex_class_do_output:N #1
								\semantex_class_set_symbol:Nn #1 { ##1 }
								\semantex_class_set_keys:Nn #1 { ##2 }
								\semantex_class_set_degreedefault:Nn #1 { ##3 }
								\semantex_class_set_arg:Nn #1 { ##4 }
							}
						}
						{
							\semantex_write_original_source_to_semtex_file:n
								{ #1 { ##1 } [ ##2 ] { ##3 } }
							\semantex_render_class:Nn #1 {
								\semantex_class_do_output:N #1
								\semantex_class_set_symbol:Nn #1 { ##1 }
								\semantex_class_set_keys:Nn #1 { ##2 }
								\semantex_class_set_degreedefault:Nn #1 { ##3 }
							}
						}
					}
				}
			}
			{
				\IfValueTF { ##4 }
				{
					\semantex_write_original_source_to_semtex_file:n
						{ #1 { ##1 } [ ##2 ] { ##4 } }
					\semantex_render_class:Nn #1 {
						\semantex_class_do_output:N #1
						\semantex_class_set_symbol:Nn #1 { ##1 }
						\semantex_class_set_keys:Nn #1 { ##2 }
						\semantex_class_set_arg:Nn #1 { ##4 }
					}
				}
				{
					\semantex_write_original_source_to_semtex_file:n
						{ #1 { ##1 } [ ##2 ] }
					\semantex_render_class:Nn #1 {
						\semantex_class_do_output:N #1
						\semantex_class_set_symbol:Nn #1 { ##1 }
						\semantex_class_set_keys:Nn #1 { ##2 }
					}
				}
			}
		}
		{
			\IfValueTF { ##3 }
			{
				\str_if_eq:nnTF { ##3 }{ * }
				{
					\IfValueTF { ##4 }
					{
						\semantex_write_original_source_to_semtex_file:n
							{ #1 { ##1 } { * } { ##4 } }
						\semantex_render_class:Nn #1 {
							\semantex_class_do_output:N #1
							\semantex_class_set_symbol:Nn #1 { ##1 }
							\semantex_class_use_bullet:N #1
							\semantex_class_set_arg:Nn #1 { ##4 }
						}
					}
					{
						\semantex_write_original_source_to_semtex_file:n
							{ #1 { ##1 } { * } }
						\semantex_render_class:Nn #1 {
							\semantex_class_do_output:N #1
							\semantex_class_set_symbol:Nn #1 { ##1 }
							\semantex_class_use_bullet:N #1
						}
					}
				}
				{
					\str_if_eq:nnTF { ##3 }{ ** }
					{
						\IfValueTF { ##4 }
						{
							\semantex_write_original_source_to_semtex_file:n
								{ #1 { ##1 } { ** } { ##4 } }
							\semantex_render_class:Nn #1 {
								\semantex_class_do_output:N #1
								\semantex_class_set_symbol:Nn #1 { ##1 }
								\semantex_class_use_double_bullet:N #1
								\semantex_class_set_arg:Nn #1 { ##4 }
							}
						}
						{
							\semantex_write_original_source_to_semtex_file:n
								{ #1 { ##1 } { ** } }
							\semantex_render_class:Nn #1 {
								\semantex_class_do_output:N #1
								\semantex_class_set_symbol:Nn #1 { ##1 }
								\semantex_class_use_double_bullet:N #1
							}
						}
					}
					{
						\IfValueTF { ##4 }
						{
							\semantex_write_original_source_to_semtex_file:n
								{ #1 { ##1 } { ##3 } { ##4 } }
							\semantex_render_class:Nn #1 {
								\semantex_class_do_output:N #1
								\semantex_class_set_symbol:Nn #1 { ##1 }
								\semantex_class_set_degreedefault:Nn #1 { ##3 }
								\semantex_class_set_arg:Nn #1 { ##4 }
							}
						}
						{
							\semantex_write_original_source_to_semtex_file:n
								{ #1 { ##1 } { ##3 } }
							\semantex_render_class:Nn #1 {
								\semantex_class_do_output:N #1
								\semantex_class_set_symbol:Nn #1 { ##1 }
								\semantex_class_set_degreedefault:Nn #1 { ##3 }
							}
						}
					}
				}
			}
			{
				\IfValueTF { ##4 }
				{
					\semantex_write_original_source_to_semtex_file:n
						{ #1 { ##1 } { ##4 } }
					\semantex_render_class:Nn #1 {
						\semantex_class_do_output:N #1
						\semantex_class_set_symbol:Nn #1 { ##1 }
						\semantex_class_set_arg:Nn #1 { ##4 }
					}
				}
				{
					\semantex_write_original_source_to_semtex_file:n
						{ #1 { ##1 } }
					\semantex_render_class:Nn #1 {
						\semantex_class_set_symbol:Nn #1 { ##1 }
					}
				}
			}
		}
	}
	\exp_args:Nc\DeclareDocumentCommand{__semantex_make_object_of_\semantex_class_to_register:N #1_with_options:nnw}{mmogg}
	{
		\IfValueTF{##3}
		{
			\IfValueTF { ##4 }
			{
				\str_if_eq:nnTF { ##4 }{ * }
				{
					\IfValueTF { ##5 }
					{
						\semantex_add_to_existing_original_source_in_semtex_file:n
							{ [ ##3 ] { * } { ##5 } }
						\semantex_render_class:Nn #1 {
							\semantex_class_do_output:N #1
							\semantex_class_set_symbol:Nn #1 { ##2 }
							##1
							\semantex_class_set_keys:Nn #1 { ##3 }
							\semantex_class_use_bullet:N #1
							\semantex_class_set_arg:Nn #1 { ##5 }
						}
					}
					{
						\semantex_add_to_existing_original_source_in_semtex_file:n
							{ [ ##3 ] { * } }
						\semantex_render_class:Nn #1 {
							\semantex_class_do_output:N #1
							\semantex_class_set_symbol:Nn #1 { ##2 }
							##1
							\semantex_class_set_keys:Nn #1 { ##3 }
							\semantex_class_use_bullet:N #1
						}
					}
				}
				{
					\str_if_eq:nnTF { ##4 }{ ** }
					{
						\IfValueTF { ##5 }
						{
							\semantex_add_to_existing_original_source_in_semtex_file:n
								{ [ ##3 ] { ** } { ##5 } }
							\semantex_render_class:Nn #1 {
								\semantex_class_do_output:N #1
								\semantex_class_set_symbol:Nn #1 { ##2 }
								##1
								\semantex_class_set_keys:Nn #1 { ##3 }
								\semantex_class_use_double_bullet:N #1
								\semantex_class_set_arg:Nn #1 { ##5 }
							}
						}
						{
							\semantex_add_to_existing_original_source_in_semtex_file:n
								{ [ ##3 ] { ** } }
							\semantex_render_class:Nn #1 {
								\semantex_class_do_output:N #1
								\semantex_class_set_symbol:Nn #1 { ##2 }
								##1
								\semantex_class_set_keys:Nn #1 { ##3 }
								\semantex_class_use_double_bullet:N #1
							}
						}
					}
					{
						\IfValueTF { ##5 }
						{
							\semantex_add_to_existing_original_source_in_semtex_file:n
								{ [ ##3 ] { ##4 } { ##5 } }
							\semantex_render_class:Nn #1 {
								\semantex_class_do_output:N #1
								\semantex_class_set_symbol:Nn #1 { ##2 }
								##1
								\semantex_class_set_keys:Nn #1 { ##3 }
								\semantex_class_set_degreedefault:Nn #1 { ##4 }
								\semantex_class_set_arg:Nn #1 { ##5 }
							}
						}
						{
							\semantex_add_to_existing_original_source_in_semtex_file:n
								{ [ ##3 ] { ##4 } }
							\semantex_render_class:Nn #1 {
								\semantex_class_do_output:N #1
								\semantex_class_set_symbol:Nn #1 { ##2 }
								##1
								\semantex_class_set_keys:Nn #1 { ##3 }
								\semantex_class_set_degreedefault:Nn #1 { ##4 }
							}
						}
					}
				}
			}
			{
				\IfValueTF { ##5 }
				{
					\semantex_add_to_existing_original_source_in_semtex_file:n
						{ [ ##3 ] { ##5 } }
					\semantex_render_class:Nn #1 {
						\semantex_class_do_output:N #1
						\semantex_class_set_symbol:Nn #1 { ##2 }
						##1
						\semantex_class_set_keys:Nn #1 { ##3 }
						\semantex_class_set_arg:Nn #1 { ##5 }
					}
				}
				{
					\semantex_add_to_existing_original_source_in_semtex_file:n
						{ [ ##3 ] }
					\semantex_render_class:Nn #1 {
						\semantex_class_do_output:N #1
						\semantex_class_set_symbol:Nn #1 { ##2 }
						##1
						\semantex_class_set_keys:Nn #1 { ##3 }
					}
				}
			}
		}
		{
			\IfValueTF { ##4 }
			{
				\str_if_eq:nnTF { ##4 }{ * }
				{
					\IfValueTF { ##5 }
					{
						\semantex_add_to_existing_original_source_in_semtex_file:n
							{ { * } { ##5 } }
						\semantex_render_class:Nn #1 {
							\semantex_class_do_output:N #1
							\semantex_class_set_symbol:Nn #1 { ##2 }
							##1
							\semantex_class_use_bullet:N #1
							\semantex_class_set_arg:Nn #1 { ##5 }
						}
					}
					{
						\semantex_add_to_existing_original_source_in_semtex_file:n
							{ { * } }
						\semantex_render_class:Nn #1 {
							\semantex_class_do_output:N #1
							\semantex_class_set_symbol:Nn #1 { ##2 }
							##1
							\semantex_class_use_bullet:N #1
						}
					}
				}
				{
					\str_if_eq:nnTF { ##4 }{ ** }
					{
						\IfValueTF { ##5 }
						{
							\semantex_add_to_existing_original_source_in_semtex_file:n
								{ { ** } { ##5 } }
							\semantex_render_class:Nn #1 {
								\semantex_class_do_output:N #1
								\semantex_class_set_symbol:Nn #1 { ##2 }
								##1
								\semantex_class_use_double_bullet:N #1
								\semantex_class_set_arg:Nn #1 { ##5 }
							}
						}
						{
							\semantex_add_to_existing_original_source_in_semtex_file:n
								{ { ** } }
							\semantex_render_class:Nn #1 {
								\semantex_class_do_output:N #1
								\semantex_class_set_symbol:Nn #1 { ##2 }
								##1
								\semantex_class_use_double_bullet:N #1
							}
						}
					}
					{
						\IfValueTF { ##5 }
						{
							\semantex_add_to_existing_original_source_in_semtex_file:n
								{ { ##4 } { ##5 } }
							\semantex_render_class:Nn #1 {
								\semantex_class_do_output:N #1
								\semantex_class_set_symbol:Nn #1 { ##2 }
								##1
								\semantex_class_set_degreedefault:Nn #1 { ##4 }
								\semantex_class_set_arg:Nn #1 { ##5 }
							}
						}
						{
							\semantex_add_to_existing_original_source_in_semtex_file:n
								{ { ##4 } }
							\semantex_render_class:Nn #1 {
								\semantex_class_do_output:N #1
								\semantex_class_set_symbol:Nn #1 { ##2 }
								##1
								\semantex_class_set_degreedefault:Nn #1 { ##4 }
							}
						}
					}
				}
			}
			{
				\IfValueTF { ##5 }
				{
					\semantex_add_to_existing_original_source_in_semtex_file:n
						{ { ##5 } }
					\semantex_render_class:Nn #1 {
						\semantex_class_do_output:N #1
						\semantex_class_set_symbol:Nn #1 { ##2 }
						##1
						\semantex_class_set_arg:Nn #1 { ##5 }
					}
				}
				{
					% \semantex_add_to_existing_original_source_in_semtex_file:n { } % write nothing to file
					\semantex_render_class:Nn #1 {
						\semantex_class_set_symbol:Nn #1 { ##2 }
						##1
					}
				}
			}
		}
	}
	\exp_args:Nc\DeclareDocumentCommand{__semantex_new_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_new_object:NNn #1 { ##1 }{
				\semantex_object_set_symbol:Nn ##1 { ##2 }
				\semantex_object_set_keys:Nn ##1 { ##3 }
			}
		}
		{
			\semantex_new_object:NNn #1 { ##1 }{
				\semantex_object_set_keys:Nn ##1 { ##3 }
			}
		}
		% creates the object with name ##1
		\DeclareDocumentCommand{##1}{ogg}
		{
			% the actual \##1 command
			\IfValueTF{####1}
			{
				\IfValueTF{####2}
				{
					\str_if_eq:nnTF { ####2 } { * }
					{
						\IfValueTF{####3}
						{
							\semantex_write_original_source_to_semtex_file:n
								{ ##1 [ ####1 ] { * } { ####3 } }
							\semantex_render_object:Nn ##1 {
								\semantex_object_do_output:N ##1
								\semantex_object_set_keys:Nn ##1 { ####1 }
								\semantex_object_use_bullet:N ##1
								\semantex_object_set_arg:Nn ##1 { ####3 }
							}
						}
						{
							\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_object_use_bullet:N ##1
							}
						}
					}
					{
						\str_if_eq:nnTF { ####2 } { ** }
						{
							\IfValueTF{####3}
							{
								\semantex_write_original_source_to_semtex_file:n
									{ ##1 [ ####1 ] { ** } { ####3 } }
								\semantex_render_object:Nn ##1 {
									\semantex_object_do_output:N ##1
									\semantex_object_set_keys:Nn ##1 { ####1 }
									\semantex_object_use_double_bullet:N ##1
									\semantex_object_set_arg:Nn ##1 { ####3 }
								}
							}
							{
								\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_object_use_double_bullet:N ##1
								}
							}
						}
						{
							\IfValueTF{####3}
							{
								\semantex_write_original_source_to_semtex_file:n
									{ ##1 [ ####1 ] { ####2 } { ####3 } }
								\semantex_render_object:Nn ##1 {
									\semantex_object_do_output:N ##1
									\semantex_object_set_keys:Nn ##1 { ####1 }
									\semantex_object_set_degreedefault:Nn ##1 { ####2 }
									\semantex_object_set_arg:Nn ##1 { ####3 }
								}
							}
							{
								\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_degreedefault:Nn ##1 { ####2 }
								}
							}
						}
					}
				}
				{
					\IfValueTF{####3}
					{
						\semantex_write_original_source_to_semtex_file:n
							{ ##1 [ ####1 ] { ####3 } }
						\semantex_render_object:Nn ##1 {
							\semantex_object_do_output:N ##1
							\semantex_object_set_keys:Nn ##1 { ####1 }
							\semantex_object_set_arg:Nn ##1 { ####3 }
						}
					}
					{
						\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}
				{
					\str_if_eq:nnTF { ####2 } { * }
					{
						\IfValueTF{####3}
						{
							\semantex_write_original_source_to_semtex_file:n
								{ ##1 { * } { ####3 } }
							\semantex_render_object:Nn ##1 {
								\semantex_object_do_output:N ##1
								\semantex_object_use_bullet:N ##1
								\semantex_object_set_arg:Nn ##1 { ####3 }
							}
						}
						{
							\semantex_write_original_source_to_semtex_file:n
								{ ##1 { * } }
							\semantex_render_object:Nn ##1 {
								\semantex_object_do_output:N ##1
								\semantex_object_use_bullet:N ##1
							}
						}
					}
					{
						\str_if_eq:nnTF { ####2 } { ** }
						{
							\IfValueTF{####3}
							{
								\semantex_write_original_source_to_semtex_file:n
									{ ##1 { ** } { ####3 } }
								\semantex_render_object:Nn ##1 {
									\semantex_object_do_output:N ##1
									\semantex_object_use_double_bullet:N ##1
									\semantex_object_set_arg:Nn ##1 { ####3 }
								}
							}
							{
								\semantex_write_original_source_to_semtex_file:n
									{ ##1 { ** } }
								\semantex_render_object:Nn ##1 {
									\semantex_object_do_output:N ##1
									\semantex_object_use_double_bullet:N ##1
								}
							}
						}
						{
							\IfValueTF{####3}
							{
								\semantex_write_original_source_to_semtex_file:n
									{ ##1 { ####2 } { ####3 } }
								\semantex_render_object:Nn ##1 {
									\semantex_object_do_output:N ##1
									\semantex_object_set_degreedefault:Nn ##1 { ####2 }
									\semantex_object_set_arg:Nn ##1 { ####3 }
								}
							}
							{
								\semantex_write_original_source_to_semtex_file:n
									{ ##1 { ####2 } }
								\semantex_render_object:Nn ##1 {
									\semantex_object_do_output:N ##1
									\semantex_object_set_degreedefault:Nn ##1 { ####2 }
								}
							}
						}
					}
				}
				{
					\IfValueTF{####3}
					{
						\semantex_write_original_source_to_semtex_file:n
							{ ##1 { ####3 } }
						\semantex_render_object:Nn ##1 {
							\semantex_object_do_output:N ##1
							\semantex_object_set_arg:Nn ##1 { ####3 }
						}
					}
					{
						\semantex_write_original_source_to_semtex_file:n
							{ ##1 }
						\semantex_render_object:Nn ##1 { }
					}
				}
			}
		}
	}
}

\cs_set_eq:NN\NewCohomologyClass\semantex_new_cohomology_class:Nw

\DeclareDocumentCommand\semantex_new_delimiter_class:Nw{mO{}} % new delimiter-type class
{
	% #1 = class name
	% #2 = options
	\semantex_new_class:Nn { #1 } { \semantex_class_set_keys:Nn #1 { #2 } }
	\DeclareDocumentCommand{#1}{mog} % maybe this does not even make sense for delimiters
	{
		\IfValueTF { ##2 }
		{
			\IfValueTF { ##3 }
			{
				\semantex_write_original_source_to_semtex_file:n
					{ #1 { ##1 } [ ##2 ] { ##3 } }
				\semantex_render_class:Nn #1 {
					\semantex_class_do_output:N #1
					\semantex_class_set_symbol:Nn #1 { ##1 }
					\semantex_class_set_keys:Nn #1 { ##2 }
					\semantex_class_set_arg:Nn #1 { ##3 }
				}
			}
			{
				\semantex_write_original_source_to_semtex_file:n
					{ #1 { ##1 } [ ##2 ] }
				\semantex_render_class:Nn #1 {
					\semantex_class_do_output:N #1
					\semantex_class_set_symbol:Nn #1 { ##1 }
					\semantex_class_set_keys:Nn #1 { ##2 }
				}
			}
		}
		{
			\IfValueTF { ##3 }
			{
				\semantex_write_original_source_to_semtex_file:n
					{ #1 { ##1 } { ##3 } }
				\semantex_render_class:Nn #1 {
					\semantex_class_do_output:N #1
					\semantex_class_set_symbol:Nn #1 { ##1 }
					\semantex_class_set_arg:Nn #1 { ##3 }
				}
			}
			{
				\semantex_write_original_source_to_semtex_file:n
					{ #1 { ##1 } }
				\semantex_render_class:Nn #1 {
					\semantex_class_set_symbol:Nn #1 { ##1 }
				}
			}
		}
	}
	% the actual \#1 command
	\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_class:Nn #1 {
					\semantex_class_do_output:N #1
					\semantex_class_set_symbol:Nn #1 { ##2 }
					##1
					\semantex_class_set_keys:Nn #1 { ##3 }
					\semantex_class_set_arg:Nn #1 { ##4 }
				}
			}
			{
				\semantex_add_to_existing_original_source_in_semtex_file:n
					{ [ ##3 ] }
				\semantex_render_class:Nn #1 {
					\semantex_class_do_output:N #1
					\semantex_class_set_symbol:Nn #1 { ##2 }
					##1
					\semantex_class_set_keys:Nn #1 { ##3 }
				}
			}
		}
		{
			\IfValueTF { ##4 }
			{
				\semantex_render_class:Nn #1 {
					\semantex_add_to_existing_original_source_in_semtex_file:n
						{ { ##4 } }
					\semantex_class_do_output:N #1
					\semantex_class_set_symbol:Nn #1 { ##2 }
					##1
					\semantex_class_set_arg:Nn #1 { ##4 }
				}
			}
			{
				% \semantex_add_to_existing_original_source_in_semtex_file:n { } % write nothing to file
				\semantex_render_class:Nn #1 {
					\semantex_class_set_symbol:Nn #1 { ##2 }
					##1
				}
			}
		}
	}
	\exp_args:Nc\DeclareDocumentCommand{__semantex_new_object_of_\semantex_class_to_register:N #1:Nw}{mmmO{}}
	{
		% the command for creating a new object of class #1
		% ##1 = command name, with backslash
		% ##2 = symbol
		% ##3 = options
		\semantex_new_object:NNn #1 { ##1 }{
			\semantex_object_set_leftpar:Nn ##1 { ##2 }
			\semantex_object_set_rightpar:Nn ##1 { ##3 }
			\semantex_object_set_keys:Nn ##1 { ##4 }
		}
		% 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 { }
				}
			}
		}
	}
}

\cs_set_eq:NN\NewDelimiterClass\semantex_new_delimiter_class:Nw

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%    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_\cs_to_str:N #1
}

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

\DeclareDocumentCommand\NewObject { m }
{
	% #1 = name of object
	\semantex_class_if_exist:NTF #1
	{
		\use:c { __semantex_new_object_of_\semantex_class_to_register:N #1:Nw }
	}
	{
		\msg_error:nnnn { semantex } { created_object_of_unknown_class } { #1 }
	}
}

\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_register:N #1 } { #2 }
			}
		}
		{
			\use:c { __semantex_make_object_of_\semantex_class_to_register:N #1_with_options:nnw } {}
		}
	}
	{
		\msg_error:nnnn { 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:nnn { #1 } { parent } { class_SemantexBaseObject }
	% 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_new_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 }
	}
}

\cs_set_protected:Npn \semantex_new_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_symbol:Nn#1#2
{
	\semantex_valuekey:nnn { \semantex_class_to_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_class_do_output:N#1
{
	\semantex_data_bool_set_true:nn { \semantex_class_to_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_class_set_keys:Nn#1#2
{
	\semantex_keys_set:nn { \semantex_class_to_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_class_set_arg:Nn#1#2
{
	\semantex_valuekey:nnn { \semantex_class_to_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_class_set_degreedefault:Nn#1#2
{
	\semantex_valuekey:nnn { \semantex_class_to_register:N #1 } { degreedefault } { #2 }
}

\cs_new_protected:Npn\semantex_object_set_degreedefault:Nn#1#2
{
	\semantex_valuekey:nnn { \semantex_object_to_register:N #1 } { degreedefault } { #2 }
}

\cs_new_protected:Npn\semantex_class_use_bullet:N#1
{
	\semantex_singlekey:nn { \semantex_class_to_register:N #1 } { * }
}

\cs_new_protected:Npn\semantex_object_use_bullet:N#1
{
	\semantex_singlekey:nn { \semantex_object_to_register:N #1 } { * }
}

\cs_new_protected:Npn\semantex_class_use_double_bullet:N#1
{
	\semantex_singlekey:nn { \semantex_class_to_register:N #1 } { * }
}

\cs_new_protected:Npn\semantex_object_use_double_bullet:N#1
{
	\semantex_singlekey:nn { \semantex_object_to_register:N #1 } { * }
}

\cs_new_protected:Npn\semantex_class_set_leftpar:Nn#1#2
{
	\semantex_data_tl_set:nnn { \semantex_class_to_register:N #1 } { leftpar } { #2 }
}

\cs_new_protected:Npn\semantex_object_set_leftpar:Nn#1#2
{
	\semantex_data_tl_set:nnn { \semantex_object_to_register:N #1 } { leftpar } { #2 }
}

\cs_new_protected:Npn\semantex_class_set_rightpar:Nn#1#2
{
	\semantex_data_tl_set:nnn { \semantex_class_to_register:N #1 } { rightpar } { #2 }
}

\cs_new_protected:Npn\semantex_object_set_rightpar:Nn#1#2
{
	\semantex_data_tl_set:nnn { \semantex_object_to_register:N #1 } { rightpar } { #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 }
		\semantex_data_tl_inherit:nn { #1 } { symbol } % Inherit the symbol from parent if not done already
		#2 % This is where keys can be set up
		\semantex_parse:n { #1 } % Run the "parse" routine, i.e. run the collection of code that the user has added via the key "parseoptions"
		\semantex_data_bool_get:nnTF { #1 } { output } % Checks if the register is supposed to output
		{
			\semantex_inner_return:n { #1 }
			\tl_set:Nx \l__semantex_render_output_class_temp_tl { \semantex_data_tl_get:nn { #1 } { output } } % The output class
			\exp_args:NNx\cs_set:Nn\l__semantex_render_outputoptions_temp_cs:n
				{ \semantex_data_tl_get_exp_not:nn { #1 } { outputoptions } }
				% \cs_set:Nx did not work here, as it changes ##1 to #1, which we don't want.
			\tl_set:Nn\l__semantex_render_outputoptions_temp_tl
			{
				\l__semantex_render_outputoptions_temp_cs:n
			}
			\tl_put_right:Nx \l__semantex_render_outputoptions_temp_tl
			{
				{ \l__semantex_render_output_class_temp_tl }
			}
			\exp_args:NNo\tl_set:No \l__semantex_render_outputoptions_temp_tl
			{
				\l__semantex_render_outputoptions_temp_tl
			} % This was necessary, trust me.
			\semantex_data_int_if_positive:nnTF { #1 } { numberofarguments } % Checks if more than one argument has been received, i.e. whether we want to render any argument
			{
				\semantex_data_bool_get:nnTF { #1 } { leftargument } % Checks if left or right argument
				{
					\semantex_left_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_output_class_temp_tl }
								{ upperputleft } { \semantex_data_tl_get_exp_not:nn { #1 } { upper } }
							\exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
								{ lowerputleft } { \semantex_data_tl_get_exp_not:nn { #1 } { lower } }
							\exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
								{ preupper } { \semantex_data_tl_get_exp_not:nn { #1 } { preupper } }
							\exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
								{ postupper } { \semantex_data_tl_get_exp_not:nn { #1 } { postupper } }
							\exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
								{ prelower } { \semantex_data_tl_get_exp_not:nn { #1 } { prelower } }
							\exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
								{ postlower } { \semantex_data_tl_get_exp_not:nn { #1 } { postlower } }
							\exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
								{ texclass } { \semantex_data_tl_get_exp_not:nn { #1 } { texclass } }
							\exp_not:V \l__semantex_render_outputoptions_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_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_output_class_temp_tl }
								{ upperleftputright } { \semantex_data_tl_get_exp_not:nn { #1 } { upperleft } }
							\exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
								{ lowerleftputright } { \semantex_data_tl_get_exp_not:nn { #1 } { lowerleft } }
							\exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
								{ preupperleft } { \semantex_data_tl_get_exp_not:nn { #1 } { preupperleft } }
							\exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
								{ postupperleft } { \semantex_data_tl_get_exp_not:nn { #1 } { postupperleft } }
							\exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
								{ prelowerleft } { \semantex_data_tl_get_exp_not:nn { #1 } { prelowerleft } }
							\exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
								{ postlowerleft } { \semantex_data_tl_get_exp_not:nn { #1 } { postlowerleft } }
							\exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
								{ heightphantom } { \semantex_data_tl_get_exp_not:nn { #1 } { heightphantom } }
							\exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
								{ slantingphantom } { \semantex_data_tl_get_exp_not:nn { #1 } { slantingphantom } }
							\exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
								{ texclass } { \semantex_data_tl_get_exp_not:nn { #1 } { texclass } }
							\exp_not:V \l__semantex_render_outputoptions_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_output_class_temp_tl }
							{ upperputleft } { \semantex_data_tl_get_exp_not:nn { #1 } { upper } }
						\exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
							{ lowerputleft } { \semantex_data_tl_get_exp_not:nn { #1 } { lower } }
						\exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
							{ upperleftputright } { \semantex_data_tl_get_exp_not:nn { #1 } { upperleft } }
						\exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
							{ lowerleftputright } { \semantex_data_tl_get_exp_not:nn { #1 } { lowerleft } }
						\exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
							{ preupper } { \semantex_data_tl_get_exp_not:nn { #1 } { preupper } }
						\exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
							{ postupper } { \semantex_data_tl_get_exp_not:nn { #1 } { postupper } }
						\exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
							{ prelower } { \semantex_data_tl_get_exp_not:nn { #1 } { prelower } }
						\exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
							{ postlower } { \semantex_data_tl_get_exp_not:nn { #1 } { postlower } }
						\exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
							{ preupperleft } { \semantex_data_tl_get_exp_not:nn { #1 } { preupperleft } }
						\exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
							{ postupperleft } { \semantex_data_tl_get_exp_not:nn { #1 } { postupperleft } }
						\exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
							{ prelowerleft } { \semantex_data_tl_get_exp_not:nn { #1 } { prelowerleft } }
						\exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
							{ postlowerleft } { \semantex_data_tl_get_exp_not:nn { #1 } { postlowerleft } }
						\exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
							{ heightphantom } { \semantex_data_tl_get_exp_not:nn { #1 } { heightphantom } }
						\exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
							{ slantingphantom } { \semantex_data_tl_get_exp_not:nn { #1 } { slantingphantom } }
						\exp_not:N\semantex_base_object_valuekey:nnn { \l__semantex_render_output_class_temp_tl }
							{ texclass } { \semantex_data_tl_get_exp_not:nn { #1 } { texclass } }
						\exp_not:V \l__semantex_render_outputoptions_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 } { texclass } }
			% Checks whether the texclass 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 } { texclass }
						{ \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_class:Nn#1#2 % a front-end command
{
	\semantex_render_register:xn { \semantex_class_to_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
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\cs_new_protected:Npn \semantex_parentheses_store:nN#1#2
{
	\semantex_data_tl_get_store:nnN { #1 } { parsize } \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 } { leftpar }
				\semantex_data_tl_get_exp_not:nn { #1 } { prearg }
				\semantex_data_tl_get_exp_not:nn { #1 } { arg }
				\semantex_data_tl_get_exp_not:nn { #1 } { postarg }
				\exp_not:N \SemantexMathClose { }
				\semantex_data_tl_get_exp_not:nn { #1 } { rightpar }
			}
		}
		{ auto } {
			\tl_set:Nx #2
			{
				\exp_not:N \SemantexMathOpenAuto
				\semantex_data_tl_get_exp_not:nn { #1 } { leftpar }
				\semantex_data_tl_get_exp_not:nn { #1 } { prearg }
				\semantex_data_tl_get_exp_not:nn { #1 } { arg }
				\semantex_data_tl_get_exp_not:nn { #1 } { postarg }
				\exp_not:N \SemantexMathCloseAuto
				\semantex_data_tl_get_exp_not:nn { #1 } { rightpar }
			}
		}
		{ * } {
			\tl_set:Nx #2
			{
				\exp_not:N \SemantexMathOpenAuto
				\semantex_data_tl_get_exp_not:nn { #1 } { leftpar }
				\semantex_data_tl_get_exp_not:nn { #1 } { prearg }
				\semantex_data_tl_get_exp_not:nn { #1 } { arg }
				\semantex_data_tl_get_exp_not:nn { #1 } { postarg }
				\exp_not:N \SemantexMathCloseAuto
				\semantex_data_tl_get_exp_not:nn { #1 } { rightpar }
			}
		}
	}
	{
		\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 } { leftpar }
			\semantex_data_tl_get_exp_not:nn { #1 } { prearg }
			\semantex_data_tl_get_exp_not:nn { #1 } { arg }
			\semantex_data_tl_get_exp_not:nn { #1 } { postarg }
			\exp_not:N \SemantexMathClose
			\exp_not:V \l__semantex_parentheses_store_temp_tl
			\semantex_data_tl_get_exp_not:nn { #1 } { rightpar }
		}
	}
}

\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 } { prearg }
		\semantex_data_tl_get_exp_not:nn { #1 } { arg }
		\semantex_data_tl_get_exp_not:nn { #1 } { postarg }
		\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_return:n { #1 }
	\semantex_right_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_pre_return:n { #1 }
	\semantex_right_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_right_index_return:n { #1 }
	\semantex_right_arg_return:n { #1 }
}

\cs_new_protected:Npn\semantex_right_pre_return:n#1
{
	\semantex_right_indices_pre_return:n { #1 }
	\semantex_right_arg_pre_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 } { preupper }
	\semantex_data_tl_clear:nn { #1 } { postupper }
	\semantex_data_bool_set_false:nn { #1 } { nextupperwithsep }
	\semantex_data_int_clear:nn { #1 } { numberofupperindices }
	\semantex_data_tl_clear:nn { #1 } { lower }
	\semantex_data_tl_clear:nn { #1 } { prelower }
	\semantex_data_tl_clear:nn { #1 } { postlower }
	\semantex_data_bool_set_false:nn { #1 } { nextlowerwithsep }
	\semantex_data_int_clear:nn { #1 } { numberoflowerindices }
}

\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 } { numberoflowerindices }
	{
		\tl_put_right:Nx#2
		{
			\sb{
				\semantex_data_tl_get_exp_not:nn { #1 } { prelower }
				\semantex_data_tl_get_exp_not:nn { #1 } { lower }
				\semantex_data_tl_get_exp_not:nn { #1 } { postlower }
			}
		}
	}
	{
		% do nothing
	}
	\semantex_data_int_if_positive:nnTF { #1 } { numberofupperindices }
	{
		\tl_put_right:Nx#2
		{
			\sp{
				\semantex_data_tl_get_exp_not:nn { #1 } { preupper }
				\semantex_data_tl_get_exp_not:nn { #1 } { upper }
				\semantex_data_tl_get_exp_not:nn { #1 } { postupper }
			}
		}
	}
	{
		% do nothing
	}
}

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

\cs_new_protected:Npn\semantex_left_pre_return:n#1
{
	\semantex_left_indices_pre_return:n { #1 }
	\semantex_left_arg_pre_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 } { upperleft }
	\semantex_data_tl_clear:nn { #1 } { preupperleft }
	\semantex_data_tl_clear:nn { #1 } { postupperleft }
	\semantex_data_bool_set_false:nn { #1 } { nextupperleftwithsep }
	\semantex_data_int_clear:nn { #1 } { numberofupperleftindices }
	\semantex_data_tl_clear:nn { #1 } { lowerleft }
	\semantex_data_tl_clear:nn { #1 } { prelowerleft }
	\semantex_data_tl_clear:nn { #1 } { postlowerleft }
	\semantex_data_bool_set_false:nn { #1 } { nextlowerleftwithsep }
	\semantex_data_int_clear:nn { #1 } { numberoflowerleftindices }
	\semantex_data_tl_set:nnx { #1 } { heightphantom }
	{
		\semantex_data_tl_get_exp_not:nn { #1 } { symbol }
	}
	\semantex_data_tl_clear:nn { #1 } { slantingphantom }
}

\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 } { numberofupperleftindices }
	{
		\tl_put_right:Nn #2 { \manualleftindex }
		\tl_put_right:Nx #2
		{
			{ \semantex_data_tl_get_exp_not:nn { #1 } { heightphantom } }
			{ \semantex_data_tl_get_exp_not:nn { #1 } { slantingphantom} }
			{
				\semantex_data_tl_get_exp_not:nn { #1 } { preupperleft }
				\semantex_data_tl_get_exp_not:nn { #1 } { upperleft }
				\semantex_data_tl_get_exp_not:nn { #1 } { postupperleft }
			}
		}
		\semantex_data_int_if_positive:nnTF { #1 } { numberoflowerleftindices }
		{
			\tl_put_right:Nx#2
			{
				{
					\semantex_data_tl_get_exp_not:nn { #1 } { prelowerleft }
					\semantex_data_tl_get_exp_not:nn { #1 } { lowerleft }
					\semantex_data_tl_get_exp_not:nn { #1 } { postlowerleft }
				}
			}
		}
		{
			\tl_put_right:Nn#2
			{
				{ }
			}
		}
	}
	{
		\semantex_data_int_if_positive:nnTF { #1 } { numberoflowerleftindices }
		{
			\tl_put_right:Nn #2 { \manualleftindex }
			\tl_put_right:Nx #2
			{
				{ \semantex_data_tl_get_exp_not:nn { #1 } { heightphantom } }
				{ \semantex_data_tl_get_exp_not:nn { #1 } { slantingphantom} }
				{ }
				{
					\semantex_data_tl_get_exp_not:nn { #1 } { prelowerleft }
					\semantex_data_tl_get_exp_not:nn { #1 } { lowerleft }
					\semantex_data_tl_get_exp_not:nn { #1 } { postlowerleft }
				}
			}
		}
		{
			% do nothing
		}
	}
}

\cs_new_protected:Npn\semantex_right_arg_return:n#1
{
	\semantex_data_bool_get:nnTF { #1 } { leftargument }
	{
		% 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 } { prearg }
		\semantex_data_tl_clear:nn { #1 } { postarg }
		\semantex_data_int_clear:nn { #1 } { numberofarguments }
		\semantex_data_bool_set_false:nn { #1 } { nextargwithsep }
	}
}

\cs_new_protected:Npn\semantex_right_arg_pre_return:n#1
{
	\semantex_data_bool_get:nnTF { #1 } { leftargument }
	{
		% 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 } { leftargument }
	{
		\_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 } { prearg }
		\semantex_data_tl_clear:nn { #1 } { postarg }
		\semantex_data_int_clear:nn { #1 } { numberofarguments }
		\semantex_data_bool_set_false:nn { #1 } { nextargwithsep }
	}
	{
		% do nothing
	}
}

\cs_new_protected:Npn\semantex_left_arg_pre_return:n#1
{
	\semantex_data_bool_get:nnTF { #1 } { leftargument }
	{
		\_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 } { prearg }
	\semantex_data_tl_clear:nn { #1 } { postarg }
	\semantex_data_int_clear:nn { #1 } { numberofarguments }
	\semantex_data_bool_set_false:nn { #1 } { nextargwithsep }
}

\cs_new_protected:Npn\semantex_arg_pre_return:n#1
{
	\semantex_data_bool_get:nnTF { #1 } { leftargument }
	{
		\_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 } { numberofarguments }
		{
			\semantex_parentheses_store:nN { #1 } #2
		}
		{
			\tl_set:Nn#2{}
		}
	}
	{
		\semantex_data_bool_get:nnTF { #1 } { flexpar }
		{
			\semantex_data_int_if_greater_than_one:nnTF { #1 } { numberofarguments }
			{
				\semantex_parentheses_store:nN { #1 } #2
			}
			{
				\semantex_data_int_if_positive:nnTF { #1 } { numberofarguments }
				{
					\semantex_no_parentheses_store:nN { #1 } #2
				}
				{
					\tl_set:Nn#2{}
				}
			}
		}
		{
			\semantex_data_int_if_positive:nnTF { #1 } { numberofarguments }
			{	
				\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 } { sparsize } 
			\l__semantex_spar_sparsize_temp_tl
	}
	{
		\tl_set:Nn \l__semantex_spar_sparsize_temp_tl { #2 }
	}
	\__semantex_symbol_parentheses_store:xxxxN
		{ \exp_not:V\l__semantex_spar_sparsize_temp_tl }
		{ \semantex_data_tl_get_exp_not:nn { #1 } { leftspar } }
		{ \semantex_data_tl_get_exp_not:nn { #1 } { rightspar } }
		{ \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_sparsize_temp_tl }
}

\cs_new_protected:Npn\semantex_other_spar:nnn#1#2#3
{
	\semantex_return:n { #1 }
	\semantex_data_tl_get_store:nnN { #1 } { sparsize }
		\l__semantex_other_spar_sparsize_temp_tl
	\__semantex_symbol_parentheses_store:xxxxN
		{ \exp_not:V \l__semantex_other_spar_sparsize_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_sparsize_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 } { heightphantom } { \vert }
		}
		{ auto } {
			\semantex_data_tl_set:nnx { #1 } { heightphantom }
			{
				\semantex_data_tl_get_exp_not:nn { #1 } { symbol }
			}
		}
		{ * } {
			\semantex_data_tl_set:nnx { #1 } { heightphantom }
			{
				\semantex_data_tl_get_exp_not:nn { #1 } { symbol }
			}
		}
	}
	{
		\semantex_data_tl_set:nnx { #1 } { heightphantom }
		{
			\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 }
	}
}

\cs_new_protected:Npn \semantex_data_clone_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 } { clone } { #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:nnTF { #1 } { class_SemantexBaseObject }
		{
			\semantex_msg_error:nnn { #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:nnTF { #1 } { class_SemantexBaseObject }
		{
			\semantex_msg_error:nnn { #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:nnTF { #1 } { class_SemantexBaseObject }
		{
			\msg_error:nnn { #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 { 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 intuence 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 intuence 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:nnTF { #1 } { class_SemantexBaseObject }
			{
				\semantex_msg_error:nnn { #3 } { data_int_not_found } { #2 }
			}
			{
				\__semantex_data_int_get_auxiliary:fnn { \semantex_data_parent_get:n { #1 } } { #2 } { #3 }
			}
		}
	}
	{
		\str_if_eq:nnTF { #1 } { class_SemantexBaseObject }
		{
			\semantex_msg_error:nnn { #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 intuence 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 intuence 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:nnTF { #1 } { class_SemantexBaseObject }
			{
				\semantex_msg_error:nnn { #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:nnTF { #1 } { class_SemantexBaseObject }
		{
			\semantex_msg_error:nnn { #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 object
	% #2 = boolean to get
	% #3 = if true
	% #4 = if false
	\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:nnTF { #1 } { class_SemantexBaseObject }
			{
				#4
			}
			{
				\semantex_data_bool_get:fnTF { \semantex_data_parent_get:n { #1 } } { #2 } { #3 } { #4 }
			}
		}
	}
	{
		\str_if_eq:nnTF { #1 } { class_SemantexBaseObject }
		{
			#4
		}
		{
			\semantex_data_bool_get:fnTF { \semantex_data_parent_get:n { #1 } } { #2 } { #3 } { #4 }
		}
	}
}

\cs_generate_variant:Nn \semantex_data_bool_get:nnTF { fnTF, 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
{
	\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
{
	% 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 \clist_map_function:nN { nc }

\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)
	\clist_map_function:nc {#2} { __semantex_data_cs_#1_arg_singlekey:n }
}

\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:nnTF { #1 } { class_SemantexBaseObject }
		{
			\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_class_SemantexBaseObject_#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:nnTF { #1 } { class_SemantexBaseObject }
		{
			\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:nnTF { #1 } { class_SemantexBaseObject }
		{
			\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_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:nnTF { #1 } { class_SemantexBaseObject }
		{
			\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:nnTF { #1 } { class_SemantexBaseObject }
		{
			\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:nnTF { #1 } { class_SemantexBaseObject }
		{
			\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 } { numberofarguments }
	\semantex_data_bool_set_true:nn { #1 } { nextargwithsep }
}

\cs_generate_variant:Nn \semantex_arg_without_keyval:nn { nx }

% 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 }
		}
		{ setkeys }{
			\semantex_preprocess_keys:nN { #3 } #4
		}
		{ keysset }{
			\semantex_preprocess_keys:nN { #3 } #4
		}
		{ setkeysx }{
			\semantex_preprocess_keys_x:nN { #3 } #4
		}
		{ keyssetx }{
			\semantex_preprocess_keys_x:nN { #3 } #4
		}
		{ setargkeys }{
			\semantex_preprocess_arg_keys:nN { #3 } #4
		}
		{ argkeysset }{
			\semantex_preprocess_arg_keys:nN { #3 } #4
		}
		{ setargkeysx }{
			\semantex_preprocess_arg_keys_x:nN { #3 } #4
		}
		{ argkeyssetx }{
			\semantex_preprocess_arg_keys_x:nN { #3 } #4
		}
		{ setargsinglekeys }{
			\semantex_preprocess_arg_singlekeys:nN { #3 } #4
		}
		{ argsinglekeysset }{
			\semantex_preprocess_arg_singlekeys:nN { #3 } #4
		}
		{ setargsinglekeysx }{
			\semantex_preprocess_arg_singlekeys_x:nN { #3 } #4
		}
		{ argsinglekeyssetx }{
			\semantex_preprocess_arg_singlekeys_x:nN { #3 } #4
		}
		{ parseoptions }{
			\tl_put_right:Nn#4
			{
				\semantex_add_raw_commands_to_parse_options:nn { #1 }
			}
			\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 }
			}
		}
		{ outputoptions }{
			\tl_put_right:Nn#4
			{
				\semantex_add_raw_commands_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:nn##1##2
				{
					\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:nn { ###1 } { ##2 }
				}
			\exp_args:NNNx
			\group_end:
			\tl_put_right:Nn#4
			{
				{ \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl }
			}
		}
		{ boolifTF }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_boolifTF_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_boolifTF_temp_cs:nTF #3
		}
		{ boolifT }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_boolifT_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_boolifT_temp_cs:nT #3
		}
		{ boolifF }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_boolifF_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_boolifF_temp_cs:nF #3
		}
		{ ifblankTF }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_ifblankTF_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_ifblankTF_temp_cs:nTF #3
		}
		{ ifblankT }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_ifblankT_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_ifblankT_temp_cs:nT #3
		}
		{ ifblankF }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_ifblankF_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_ifblankF_temp_cs:nF #3
		}
		{ strifeqTF }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_strifeqTF_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_strifeqTF_temp_cs:nnTF #3
		}
		{ strifeqT }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_strifeqT_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_strifeqT_temp_cs:nnT #3
		}
		{ strifeqF }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_strifeqF_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_strifeqF_temp_cs:nnF #3
		}
		{ intifgreaterTF }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_intifgreaterTF_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_intifgreaterTF_temp_cs:nnTF #3
		}
		{ intifgreaterT }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_intifgreaterT_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_intifgreaterT_temp_cs:nnT #3
		}
		{ intifgreaterF }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_intifgreaterF_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_intifgreaterF_temp_cs:nnF #3
		}
		{ intifeqTF }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_intifeqTF_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_intifeqTF_temp_cs:nnTF #3
		}
		{ intifeqT }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_intifeqT_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_intifeqT_temp_cs:nnT #3
		}
		{ intifeqF }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_intifeqF_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_intifeqF_temp_cs:nnF #3
		}
		{ intiflessTF }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_intiflessTF_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_intiflessTF_temp_cs:nnTF #3
		}
		{ intiflessT }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_intiflessT_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_intiflessT_temp_cs:nnT #3
		}
		{ intiflessF }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_intiflessF_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_intiflessF_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
			}
		}
		{ setkeys }{
			\semantex_preprocess_keys:nN { #3 } #4
		}
		{ keysset }{
			\semantex_preprocess_keys:nN { #3 } #4
		}
		{ setkeysx }{
			\semantex_preprocess_keys_x:nN { #3 } #4
		}
		{ keyssetx }{
			\semantex_preprocess_keys_x:nN { #3 } #4
		}
		{ setargkeys }{
			\semantex_preprocess_arg_keys:nN { #3 } #4
		}
		{ argkeysset }{
			\semantex_preprocess_arg_keys:nN { #3 } #4
		}
		{ setargkeysx }{
			\semantex_preprocess_arg_keys_x:nN { #3 } #4
		}
		{ argkeyssetx }{
			\semantex_preprocess_arg_keys_x:nN { #3 } #4
		}
		{ setargsinglekeys }{
			\semantex_preprocess_arg_singlekeys:nN { #3 } #4
		}
		{ argsinglekeysset }{
			\semantex_preprocess_arg_singlekeys:nN { #3 } #4
		}
		{ setargsinglekeysx }{
			\semantex_preprocess_arg_singlekeys_x:nN { #3 } #4
		}
		{ argsinglekeyssetx }{
			\semantex_preprocess_arg_singlekeys_x:nN { #3 } #4
		}
		{ parseoptions }{
			\tl_put_right:Nn#4
			{
				\semantex_add_raw_commands_to_parse_options:nn { #1 }
			}
			\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 }
			}
		}
		{ outputoptions }{
			\tl_put_right:Nn#4
			{
				\semantex_add_raw_commands_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:nn##1##2
				{
					\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:nn { ###1 } { ##2 }
				}
			\exp_args:NNNx
			\group_end:
			\tl_put_right:Nn#4
			{
				{ \exp_not:V\l__semantex_preprocess_valuekey_keys_temp_tl }
			}
		}
		{ boolifTF }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_boolifTF_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_boolifTF_temp_cs:nTF #3
		}
		{ boolifT }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_boolifT_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_boolifT_temp_cs:nT #3
		}
		{ boolifF }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_boolifF_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_boolifF_temp_cs:nF #3
		}
		{ ifblankTF }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_ifblankTF_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_ifblankTF_temp_cs:nTF #3
		}
		{ ifblankT }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_ifblankT_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_ifblankT_temp_cs:nT #3
		}
		{ ifblankF }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_ifblankF_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_ifblankF_temp_cs:nF #3
		}
		{ strifeqTF }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_strifeqTF_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_strifeqTF_temp_cs:nnTF #3
		}
		{ strifeqT }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_strifeqT_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_strifeqT_temp_cs:nnT #3
		}
		{ strifeqF }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_strifeqF_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_strifeqF_temp_cs:nnF #3
		}
		{ intifgreaterTF }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_intifgreaterTF_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_intifgreaterTF_temp_cs:nnTF #3
		}
		{ intifgreaterT }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_intifgreaterT_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_intifgreaterT_temp_cs:nnT #3
		}
		{ intifgreaterF }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_intifgreaterF_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_intifgreaterF_temp_cs:nnF #3
		}
		{ intifeqTF }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_intifeqTF_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_intifeqTF_temp_cs:nnTF #3
		}
		{ intifeqT }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_intifeqT_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_intifeqT_temp_cs:nnT #3
		}
		{ intifeqF }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_intifeqF_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_intifeqF_temp_cs:nnF #3
		}
		{ intiflessTF }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_intiflessTF_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_intiflessTF_temp_cs:nnTF #3
		}
		{ intiflessT }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_intiflessT_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_intiflessT_temp_cs:nnT #3
		}
		{ intiflessF }{
			\cs_set:Npn \l__semantex_preprocess_valuekey_intiflessF_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_intiflessF_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_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
	}
}


% 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
	}
	\clist_map_function:nN { #1 } \l__semantex_preprocess_arg_singlekey_temp_cs:n
}


\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
			}
		}
		{ setkeys }{
			\semantex_preprocess_keys:nN { #3 } #4
		}
		{ keysset }{
			\semantex_preprocess_keys:nN { #3 } #4
		}
		{ setkeysx }{
			\semantex_preprocess_keys_x:nN { #3 } #4
		}
		{ keyssetx }{
			\semantex_preprocess_keys_x:nN { #3 } #4
		}
		{ setargkeys }{
			\semantex_preprocess_arg_keys:nN { #3 } #4
		}
		{ argkeysset }{
			\semantex_preprocess_arg_keys:nN { #3 } #4
		}
		{ setargkeysx }{
			\semantex_preprocess_arg_keys_x:nN { #3 } #4
		}
		{ argkeyssetx }{
			\semantex_preprocess_arg_keys_x:nN { #3 } #4
		}
		{ setargsinglekeys }{
			\semantex_preprocess_arg_singlekeys:nN { #3 } #4
		}
		{ argsinglekeysset }{
			\semantex_preprocess_arg_singlekeys:nN { #3 } #4
		}
		{ setargsinglekeysx }{
			\semantex_preprocess_arg_singlekeys_x:nN { #3 } #4
		}
		{ argsinglekeyssetx }{
			\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
	}
	\clist_map_function:nN { #1 } \l__semantex_preprocess_arg_singlekey_x_temp_cs:n
}


\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
			}
		}
		{ setkeys }{
			\semantex_preprocess_keys:nN { #3 } #4
		}
		{ keysset }{
			\semantex_preprocess_keys:nN { #3 } #4
		}
		{ setkeysx }{
			\semantex_preprocess_keys_x:nN { #3 } #4
		}
		{ keyssetx }{
			\semantex_preprocess_keys_x:nN { #3 } #4
		}
		{ setargkeys }{
			\semantex_preprocess_arg_keys:nN { #3 } #4
		}
		{ argkeysset }{
			\semantex_preprocess_arg_keys:nN { #3 } #4
		}
		{ setargkeysx }{
			\semantex_preprocess_arg_keys_x:nN { #3 } #4
		}
		{ argkeyssetx }{
			\semantex_preprocess_arg_keys_x:nN { #3 } #4
		}
		{ setargsinglekeys }{
			\semantex_preprocess_arg_singlekeys:nN { #3 } #4
		}
		{ argsinglekeysset }{
			\semantex_preprocess_arg_singlekeys:nN { #3 } #4
		}
		{ setargsinglekeysx }{
			\semantex_preprocess_arg_singlekeys_x:nN { #3 } #4
		}
		{ argsinglekeyssetx }{
			\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_three_arg_valuekey_format_auxiliary:nnn{#1}##1
	}
}

\cs_new_protected:Npn\__semantex_three_arg_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_four_arg_valuekey_format_auxiliary:nnn{#1}##1
	}
}

\cs_new_protected:Npn\__semantex_four_arg_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_five_arg_valuekey_format_auxiliary:nnn{#1}##1
	}
}

\cs_new_protected:Npn\__semantex_five_arg_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_six_arg_valuekey_format_auxiliary:nnn{#1}##1
	}
}

\cs_new_protected:Npn\__semantex_six_arg_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_seven_arg_valuekey_format_auxiliary:nnn{#1}##1
	}
}

\cs_new_protected:Npn\__semantex_seven_arg_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_eight_arg_valuekey_format_auxiliary:nnn{#1}##1
	}
}

\cs_new_protected:Npn\__semantex_eight_arg_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_nine_arg_valuekey_format_auxiliary:nnn{#1}##1
	}
}

\cs_new_protected:Npn\__semantex_nine_arg_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
	}
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%		COMMANDS HANDLING THE PARSE ROUTINE
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\cs_new_protected:Npn\semantex_parse:n#1
{
	% This command runs all the keys that the user may have
	% stored via the parseoptions key
	\exp_args:NNx\cs_set_protected:Nn\l__semantex_parse_temp_cs:n
		% \cs_set:Nx gave us ##1 where we wanted #1
	{
		\semantex_data_tl_get_exp_not:nn { #1 } { parseoptions }
	}
	\l__semantex_parse_temp_cs:n { #1 }
	\semantex_data_tl_clear:nn { #1 } { parseoptions }
}

\cs_new_protected:Npn\semantex_add_to_parse_options:nn#1#2
{
	\tl_set:Nn\l__semantex_parseoptions_auxiliary_temp_tl{}
	\semantex_preprocess_keys:nN { #2 } \l__semantex_parseoptions_auxiliary_temp_tl
	\semantex_add_raw_commands_to_parse_options:no { #1 } { \l__semantex_parseoptions_auxiliary_temp_tl }
}

\cs_new_protected:Npn\semantex_add_raw_commands_to_parse_options:nn#1#2
{
	\semantex_data_tl_put_right:nnn { #1 } { parseoptions } { #2 }
}

\cs_generate_variant:Nn \semantex_add_raw_commands_to_parse_options:nn { no }

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%		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_commands_to_output_options:no { #1 } { \l__semantex_output_options_auxiliary_temp_tl }
}

\cs_new_protected:Npn\semantex_add_raw_commands_to_output_options:nn#1#2
{
	\semantex_data_tl_put_right:nnn { #1 } { outputoptions } { #2 }
}

\cs_generate_variant:Nn \semantex_add_raw_commands_to_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{\semantex_keys_set:on{\semantex_this:}{#1}}
\cs_new_protected:Npn\SemantexKeysSet#1{\semantex_keys_set:on{\semantex_this:}{#1}}
\cs_new_protected:Npn\SemantexSetKeysx#1{\semantex_keys_set_x:on{\semantex_this:}{#1}}
\cs_new_protected:Npn\SemantexKeysSetx#1{\semantex_keys_set_x:on{\semantex_this:}{#1}}
\cs_new_protected:Npn\SemantexSetArgKeys#1{\semantex_arg_keys_set:nn { \semantex_this: } { #1 }}
\cs_new_protected:Npn\SemantexArgKeysSet#1{\semantex_arg_keys_set:nn { \semantex_this: } { #1 }}
\cs_new_protected:Npn\SemantexSetArgKeysx#1{\semantex_arg_keys_set_x:nn { \semantex_this: } { #1 }}
\cs_new_protected:Npn\SemantexArgKeysSetx#1{\semantex_arg_keys_set_x:nn { \semantex_this: } { #1 }}
\cs_new_protected:Npn\SemantexSetArgSingleKeys#1{\semantex_arg_singlekeys_set:nn { \semantex_this: } { #1 } }
\cs_new_protected:Npn\SemantexArgSingleKeysSet#1{\semantex_arg_singlekeys_set:nn { \semantex_this: } { #1 } }
\cs_new_protected:Npn\SemantexSetArgSingleKeysx#1{\semantex_arg_singlekeys_set_x:nn { \semantex_this: } { #1 } }
\cs_new_protected:Npn\SemantexArgSingleKeysSetx#1{\semantex_arg_singlekeys_set_x:nn { \semantex_this: } { #1 } }
\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~\SemantexSetup~on~line~\msg_line_number: } {}

\msg_new:nnnn { semantex } { semantex_setup_key_value_not_found } {  Unknown~value~#2~passed~to~key~#1~in~\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~#1on~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 } { 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~setkeysx={...}? } {}

\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_ } { object~\cs:w }
	\tl_replace_all:Nnn \l__semantex_error_output_format_temp { class_ } { class~\cs:w }
	\tl_put_right:Nn \l__semantex_error_output_format_temp { \cs_end: }
	\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_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 }
{
	{definekeys[1]}{execute={ \semantex_define_valuekeys:nn { ##1 } { #1 } }},
}

\semantex_new_simple_class:Nw \SemantexBaseObject [
	definekeys[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
		{definekeys}{ execute={ \semantex_define_singlekeys:nn { ##1 } { #1 } } },
		{definekeys[0]}{ execute={ \semantex_define_singlekeys:nn { ##1 } { #1 } } },
		{definekeys[{0}]}{ execute={ \semantex_define_singlekeys:nn { ##1 } { #1 } } },
		{definekeys[{1}]}{ execute={ \semantex_define_valuekeys:nn { ##1 } { #1 } } },
		{definekeys[2]}{ execute={ \semantex_define_two_valuekeys:nn { ##1 } { #1 } } },
		{definekeys[{2}]}{ execute={ \semantex_define_two_valuekeys:nn { ##1 } { #1 } } },
		{definekeys[3]}{ execute={ \semantex_define_three_valuekeys:nn { ##1 } { #1 } } },
		{definekeys[{3}]}{ execute={ \semantex_define_three_valuekeys:nn { ##1 } { #1 } } },
		{definekeys[4]}{ execute={ \semantex_define_four_valuekeys:nn { ##1 } { #1 } } },
		{definekeys[{4}]}{ execute={ \semantex_define_four_valuekeys:nn { ##1 } { #1 } } },
		{definekeys[5]}{ execute={ \semantex_define_five_valuekeys:nn { ##1 } { #1 } } },
		{definekeys[{5}]}{ execute={ \semantex_define_five_valuekeys:nn { ##1 } { #1 } } },
		{definekeys[6]}{ execute={ \semantex_define_six_valuekeys:nn { ##1 } { #1 } } },
		{definekeys[{6}]}{ execute={ \semantex_define_six_valuekeys:nn { ##1 } { #1 } } },
		{definekeys[7]}{ execute={ \semantex_define_seven_valuekeys:nn { ##1 } { #1 } } },
		{definekeys[{7}]}{ execute={ \semantex_define_seven_valuekeys:nn { ##1 } { #1 } } },
		{definekeys[8]}{ execute={ \semantex_define_eight_valuekeys:nn { ##1 } { #1 } } },
		{definekeys[{8}]}{ execute={ \semantex_define_eight_valuekeys:nn { ##1 } { #1 } } },
		{definekeys[9]}{ execute={ \semantex_define_nine_valuekeys:nn { ##1 } { #1 } } },
		{definekeys[{9}]}{ execute={ \semantex_define_nine_valuekeys:nn { ##1 } { #1 } } },
		{removekey}{ execute={ \semantex_remove_singlekey:nn { ##1 } { #1 } } },
		{removekey[0]}{ execute={ \semantex_remove_singlekey:nn { ##1 } { #1 } } },
		{removekey[{0}]}{ execute={ \semantex_remove_singlekey:nn { ##1 } { #1 } } },
		{removekey[1]}{ execute={ \semantex_remove_valuekey:nn { ##1 } { #1 } } },
		{removekey[{1}]}{ execute={ \semantex_remove_valuekey:nn { ##1 } { #1 } } },
		{removekey[2]}{ execute={ \semantex_remove_valuekey:nn { ##1 } { #1 } } },
		{removekey[{2}]}{ execute={ \semantex_remove_valuekey:nn { ##1 } { #1 } } },
		{removekey[3]}{ execute={ \semantex_remove_valuekey:nn { ##1 } { #1 } } },
		{removekey[{3}]}{ execute={ \semantex_remove_valuekey:nn { ##1 } { #1 } } },
		{removekey[4]}{ execute={ \semantex_remove_valuekey:nn { ##1 } { #1 } } },
		{removekey[{5}]}{ execute={ \semantex_remove_valuekey:nn { ##1 } { #1 } } },
		{removekey[6]}{ execute={ \semantex_remove_valuekey:nn { ##1 } { #1 } } },
		{removekey[{6}]}{ execute={ \semantex_remove_valuekey:nn { ##1 } { #1 } } },
		{removekey[7]}{ execute={ \semantex_remove_valuekey:nn { ##1 } { #1 } } },
		{removekey[{7}]}{ execute={ \semantex_remove_valuekey:nn { ##1 } { #1 } } },
		{removekey[8]}{ execute={ \semantex_remove_valuekey:nn { ##1 } { #1 } } },
		{removekey[{8}]}{ execute={ \semantex_remove_valuekey:nn { ##1 } { #1 } } },
		{removekey[9]}{ execute={ \semantex_remove_valuekey:nn { ##1 } { #1 } } },
		{removekey[{9}]}{ execute={ \semantex_remove_valuekey:nn { ##1 } { #1 } } },
		% Keys for setting up the argument keyval interface:
		{defineargkeys}{ execute={ \semantex_define_arg_singlekeys:nn { ##1 } { #1 } } },
		{defineargkeys[0]}{ execute={ \semantex_define_arg_singlekeys:nn { ##1 } { #1 } } },
		{defineargkeys[{0}]}{ execute={ \semantex_define_arg_singlekeys:nn { ##1 } { #1 } } },
		{defineargkeys[1]}{ execute={ \semantex_define_arg_valuekeys:nn { ##1 } { #1 } } },
		{defineargkeys[{1}]}{ execute={ \semantex_define_arg_valuekeys:nn { ##1 } { #1 } } },
		{defineargkeys[2]}{ execute={ \semantex_define_arg_two_valuekeys:nn { ##1 } { #1 } } },
		{defineargkeys[{2}]}{ execute={ \semantex_define_arg_two_valuekeys:nn { ##1 } { #1 } } },
		{defineargkeys[3]}{ execute={ \semantex_define_arg_three_valuekeys:nn { ##1 } { #1 } } },
		{defineargkeys[{3}]}{ execute={ \semantex_define_arg_three_valuekeys:nn { ##1 } { #1 } } },
		{defineargkeys[4]}{ execute={ \semantex_define_arg_four_valuekeys:nn { ##1 } { #1 } } },
		{defineargkeys[{4}]}{ execute={ \semantex_define_arg_four_valuekeys:nn { ##1 } { #1 } } },
		{defineargkeys[5]}{ execute={ \semantex_define_arg_five_valuekeys:nn { ##1 } { #1 } } },
		{defineargkeys[{5}]}{ execute={ \semantex_define_arg_five_valuekeys:nn { ##1 } { #1 } } },
		{defineargkeys[6]}{ execute={ \semantex_define_arg_six_valuekeys:nn { ##1 } { #1 } } },
		{defineargkeys[{6}]}{ execute={ \semantex_define_arg_six_valuekeys:nn { ##1 } { #1 } } },
		{defineargkeys[7]}{ execute={ \semantex_define_arg_seven_valuekeys:nn { ##1 } { #1 } } },
		{defineargkeys[{7}]}{ execute={ \semantex_define_arg_seven_valuekeys:nn { ##1 } { #1 } } },
		{defineargkeys[8]}{ execute={ \semantex_define_arg_eight_valuekeys:nn { ##1 } { #1 } } },
		{defineargkeys[{8}]}{ execute={ \semantex_define_arg_eight_valuekeys:nn { ##1 } { #1 } } },
		{defineargkeys[9]}{ execute={ \semantex_define_arg_nine_valuekeys:nn { ##1 } { #1 } } },
		{defineargkeys[{9}]}{ execute={ \semantex_define_arg_nine_valuekeys:nn { ##1 } { #1 } } },
		{removeargkey}{ execute={ \semantex_remove_arg_singlekey:nn { ##1 } { #1 } } },
		{removeargkey[0]}{ execute={ \semantex_remove_arg_singlekey:nn { ##1 } { #1 } } },
		{removeargkey[{0}]}{ execute={ \semantex_remove_arg_singlekey:nn { ##1 } { #1 } } },
		{removeargkey[1]}{ execute={ \semantex_remove_arg_valuekey:nn { ##1 } { #1 } } },
		{removeargkey[{1}]}{ execute={ \semantex_remove_arg_valuekey:nn { ##1 } { #1 } } },
		{removeargkey[2]}{ execute={ \semantex_remove_arg_valuekey:nn { ##1 } { #1 } } },
		{removeargkey[{2}]}{ execute={ \semantex_remove_arg_valuekey:nn { ##1 } { #1 } } },
		{removeargkey[3]}{ execute={ \semantex_remove_arg_valuekey:nn { ##1 } { #1 } } },
		{removeargkey[{3}]}{ execute={ \semantex_remove_arg_valuekey:nn { ##1 } { #1 } } },
		{removeargkey[4]}{ execute={ \semantex_remove_arg_valuekey:nn { ##1 } { #1 } } },
		{removeargkey[{5}]}{ execute={ \semantex_remove_arg_valuekey:nn { ##1 } { #1 } } },
		{removeargkey[6]}{ execute={ \semantex_remove_arg_valuekey:nn { ##1 } { #1 } } },
		{removeargkey[{6}]}{ execute={ \semantex_remove_arg_valuekey:nn { ##1 } { #1 } } },
		{removeargkey[7]}{ execute={ \semantex_remove_arg_valuekey:nn { ##1 } { #1 } } },
		{removeargkey[{7}]}{ execute={ \semantex_remove_arg_valuekey:nn { ##1 } { #1 } } },
		{removeargkey[8]}{ execute={ \semantex_remove_arg_valuekey:nn { ##1 } { #1 } } },
		{removeargkey[{8}]}{ execute={ \semantex_remove_arg_valuekey:nn { ##1 } { #1 } } },
		{removeargkey[9]}{ execute={ \semantex_remove_arg_valuekey:nn { ##1 } { #1 } } },
		{removeargkey[{9}]}{ execute={ \semantex_remove_arg_valuekey:nn { ##1 } { #1 } } },
		% Keys for programming:
		{dataprovide}{ execute={ \semantex_data_tl_provide:nn { ##1 } { \tl_trim_spaces:n { #1 } } } },
		{dataclear}{
			execute={ \semantex_data_tl_clear:nn { ##1 } { \tl_trim_spaces:n { #1 } } },
		},
		{keysset}{ execute={ \semantex_keys_set:nn { ##1 } { #1 } } },
		{setkeys}{ execute={ \semantex_keys_set:nn { ##1 } { #1 } } },
		{keyssetx}{ execute={ \semantex_keys_set_x:nn { ##1 } { #1 } } },
		{setkeysx}{ execute={ \semantex_keys_set_x:nn { ##1 } { #1 } } },
		{boolprovide}{
			execute={
				\semantex_data_bool_provide:nn { ##1 } { \tl_trim_spaces:n { #1 } }
			},
		},
		{boolsettrue}{
			execute={
				\semantex_data_bool_set_true:nn { ##1 } { \tl_trim_spaces:n { #1 } }
			},
		},
		{boolsetfalse}{
			execute={
				\semantex_data_bool_set_false:nn { ##1 } { \tl_trim_spaces:n { #1 } }
			},
		},
		{intprovide}{
			execute={
				\semantex_data_int_provide:nn { ##1 } { \tl_trim_spaces:n { #1 } }
			},
		},
		{intclear}{
			execute={
				\semantex_data_int_clear:nn { ##1 } { \tl_trim_spaces:n { #1 } }
			},
		},
		{intincr}{
			execute={
				\semantex_data_int_incr:nn { ##1 } { \tl_trim_spaces:n { #1 } }
			},
		},
		{ERROR}{
			execute={
				\semantex_error_generic:nn { ##1 } { #1 }
			},
		},
	},
	definekeys[2]={
		{dataset}{
			execute={
				\semantex_data_tl_set:nnn { ##1 } { \tl_trim_spaces:n { #1 } } { #2 }
			},
		},
		{datasetx}{
			execute={
				\semantex_data_tl_set:nnx { ##1 } { \tl_trim_spaces:n { #1 } } { #2 }
			},
		},
		{dataputright}{
			execute={
				\semantex_data_tl_put_right:nnn { ##1 } { \tl_trim_spaces:n { #1 } } { #2 }
			},
		},
		{dataputrightx}{
			execute={
				\semantex_data_tl_put_right:nnx { ##1 } { \tl_trim_spaces:n { #1 } } { #2 }
			},
		},
		{dataputleft}{
			execute={
				\semantex_data_tl_put_left:nnn { ##1 } { \tl_trim_spaces:n { #1 } } { #2 }
			},
		},
		{dataputleftx}{
			execute={
				\semantex_data_tl_put_left:nnx { ##1 } { \tl_trim_spaces:n { #1 } } { #2 }
			},
		},
		{ifblankT}{
			execute={
				\tl_if_blank:xTF { #1 }
				{ \semantex_keys_set:nn { ##1 } { #2 } }
				{ }
			},
		},
		{ifblankF}{
			execute={
				\tl_if_blank:xTF { #1 }
				{ }
				{ \semantex_keys_set:nn { ##1 } { #2 } }
			},
		},
		{boolifT}{
			execute={
				\semantex_data_bool_get:nnTF { ##1 }
					{ \tl_trim_spaces:n { #1 } }
					{ \semantex_keys_set:nn { ##1 } { #2 } }
					{ }
			},
		},
		{boolifF}{
			execute={
				\semantex_data_bool_get:nnTF { ##1 }
					{ \tl_trim_spaces:n { #1 } }
					{ }
					{ \semantex_keys_set:nn { ##1 } { #2 } }
			},
		},
		{intset}{
			execute={
				\semantex_data_int_set:nnn { ##1 } { \tl_trim_spaces:n { #1 } } { #2 }
			},
		},
		{ERRORkeyvaluenotfound}{
			execute={
				\semantex_error_key_value_not_found:nnn { ##1 } { #1 } { #2 }
			},
		},
		{ERRORargkeyvaluenotfound}{
			execute={
				\semantex_error_arg_key_value_not_found:nnn { ##1 } { #1 } { #2 }
			},
		},
	},
	definekeys[3]={
		{strifeqT}{
			execute={
				\str_if_eq:xxTF { #1 } { #2 }
				{ \semantex_keys_set:nn { ##1 } { #3 } }
				{ }
			},
		},
		{strifeqF}{
			execute={
				\str_if_eq:xxTF { #1 } { #2 }
				{ }
				{ \semantex_keys_set:nn { ##1 } { #3 } }
			},
		},
		{ifblankTF}{
			execute={
				\tl_if_blank:xTF { #1 }
				{ \semantex_keys_set:nn { ##1 } { #2 } }
				{ \semantex_keys_set:nn { ##1 } { #3 } }
			},
		},
		{boolifTF}{
			execute={
				\semantex_data_bool_get:nnTF { ##1 }
					{ \tl_trim_spaces:n { #1 } }
					{ \semantex_keys_set:nn { ##1 } { #2 } }
					{ \semantex_keys_set:nn { ##1 } { #3 } }
			},
		},
		{intifgreaterT}{
			execute={
				\int_compare:nNnTF { #1 } > { #2 }
				{ \semantex_keys_set:nn { ##1 } { #3 } }
				{ }
			},
		},
		{intifgreaterF}{
			execute={
				\int_compare:nNnTF { #1 } > { #2 }
				{ }
				{ \semantex_keys_set:nn { ##1 } { #3 } }
			},
		},
		{intifeqT}{
			execute={
				\int_compare:nNnTF { #1 } = { #2 }
				{ \semantex_keys_set:nn { ##1 } { #3 } }
				{ }
			},
		},
		{intifeqF}{
			execute={
				\int_compare:nNnTF { #1 } = { #2 }
				{ }
				{ \semantex_keys_set:nn { ##1 } { #3 } }
			},
		},
		{intiflessT}{
			execute={
				\int_compare:nNnTF { #1 } < { #2 }
				{ \semantex_keys_set:nn { ##1 } { #3 } }
				{ }
			},
		},
		{intiflessF}{
			execute={
				\int_compare:nNnTF { #1 } < { #2 }
				{ }
				{ \semantex_keys_set:nn { ##1 } { #3 } }
			},
		},
	},
	definekeys[4]={
		{strifeqTF}{
			execute={
				\str_if_eq:xxTF { #1 } { #2 }
				{ \semantex_keys_set:nn { ##1 } { #3 } }
				{ \semantex_keys_set:nn { ##1 } { #4 } }
			},
		},
		{intifgreaterTF}{
			execute={
				\int_compare:nNnTF { #1 } > { #2 }
				{ \semantex_keys_set:nn { ##1 } { #3 } }
				{ \semantex_keys_set:nn { ##1 } { #4 } }
			},
		},
		{intifeqTF}{
			execute={
				\int_compare:nNnTF { #1 } = { #2 }
				{ \semantex_keys_set:nn { ##1 } { #3 } }
				{ \semantex_keys_set:nn { ##1 } { #4 } }
			},
		},
		{intiflessTF}{
			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
	%
	%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
	dataprovide=symbol,
	boolprovide=uppergrading,
	boolsettrue=uppergrading,
	boolprovide=output,
	dataprovide=outputoptions,
	boolprovide=par,
	boolsettrue=par,
	boolprovide=flexpar,
	dataprovide=parseoptions,
	dataprovide=texclass,
	boolprovide=leftargument,
	dataprovide=heightphantom,
	dataprovide=slantingphantom,
	execute={ \semantex_data_seq_provide:nn { \semantex_this: } { commands_sequence } },
	definekeys[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 } } },
		{clone}{ execute={ \semantex_data_clone_object:nn { ##1 } { #1 } } },
		{texclass}{ execute={ \semantex_data_tl_set:nnn { ##1 } { texclass } { #1 } } },
		{symbol}{
			execute={
				\semantex_data_tl_set:nnn { ##1 } { symbol } { #1 }
				\semantex_data_tl_set:nnn { ##1 } { heightphantom } { #1 }
				\semantex_data_tl_set:nnn { ##1 } { slantingphantom } { #1 }
			}
		},
		{symbolputright}{ execute={ \semantex_data_tl_put_right:nnn { ##1 } { symbol } { #1 } } },
		{symbolputleft}{ execute={ \semantex_data_tl_put_left:nnn { ##1 } { symbol } { #1 } } },
		{heightphantom}{ execute={ \semantex_data_tl_set:nnn { ##1 } { heightphantom } { #1 } } },
		{slantingphantom}{ execute={ \semantex_data_tl_set:nnn { ##1 } { slantingphantom } { #1 } } },
		{parseoptions}{ execute={ \semantex_add_to_parse_options:nn { ##1 } { #1 } } },
		{command}{ execute={ \semantex_data_seq_put_right:nnn { ##1 } { commands_sequence } { #1 } } },
		{output}{ execute={ \semantex_set_output:nn { ##1 } { #1 } } },
		{outputoptions}{ execute={ \semantex_add_to_output_options:nn { ##1 } { #1 } } },
		{dooutput}{
			strifeqTF={#1}{true}
			{
				boolsettrue={output},
			}
			{
				strifeqTF={#1}{false}
				{
					boolsetfalse={output},
				}
				{
					ERRORkeyvaluenotfound={dooutput}{#1},
				}
			},
		},
		{gradingposition}{
			strifeqTF={#1}{upper}
			{
				boolsettrue={uppergrading},
			}
			{
				strifeqTF={#1}{lower}
				{
					boolsetfalse={uppergrading},
				}
				{
					ERRORkeyvaluenotfound={gradingposition}{#1},
				},
			},
		},
		{gradingpos}{
			strifeqTF={#1}{upper}
			{
				boolsettrue={uppergrading},
			}
			{
				strifeqTF={#1}{lower}
				{
					boolsetfalse={uppergrading},
				}
				{
					ERRORkeyvaluenotfound={gradingpos}{#1},
				},
			},
		},
		{default}{si={#1}},
		{degreedefault}{sd={#1}},
		{arg}{ execute={ \semantex_arg_singlekeys_set:nn { ##1 } { #1 } } },
		{*withothersep}{
			d*withothersep={#1},
		},
		{**withothersep}{
			d**withothersep={#1},
		},
	},
	output=\SemantexBaseObject,
	definekeys={
		{return}{ execute={ \semantex_return:n { ##1 } } },
		{innerreturn}{ execute={ \semantex_inner_return:n { ##1 } } },
		{rightreturn}{ execute={ \semantex_right_return:n { ##1 } } },
		{leftreturn}{ execute={ \semantex_left_return:n { ##1 } } },
		{rightindexreturn}{ execute={ \semantex_right_index_return:n { ##1 } } },
		{leftindexreturn}{ execute={ \semantex_left_index_return:n { ##1 } } },
		{indexreturn}{ leftindexreturn, rightindexreturn },
		{rightargreturn}{ execute={ \semantex_right_arg_return:n { ##1 } } },
		{leftargreturn}{ execute={ \semantex_left_arg_return:n { ##1 } } },
		{argreturn}{ execute={ \semantex_arg_return:n { ##1 } } },
		{parse}{ execute={ \semantex_parse:n { ##1 } } },
		{clearcommand}{ execute={ \semantex_data_seq_clear:nn { ##1 } { commands_sequence } } },
		{...}{sidots},
		{-}{sislot},
		{*}{sd*},
		{**}{sd**},
	},
	% The "spar" routine:
	definekeys={
		{spar}{spar=},
	},
	definekeys[1]={
		{spar}{ execute={ \semantex_spar:nn { ##1 } { #1 } } },
		{sparsize}{ execute={ \semantex_data_tl_set:nnn { ##1 } { sparsize } { #1 } } },
		{leftspar}{ execute={ \semantex_data_tl_set:nnn { ##1 } { leftspar } { #1 } } },
		{rightspar}{ execute={ \semantex_data_tl_set:nnn { ##1 } { rightspar } { #1 } } },
	},
	definekeys[2]={
		{otherspar}{ execute={ \semantex_other_spar:nnn { ##1 } { #1 } { #2 } } },
	},
	definekeys[3]={
		{Otherspar}{ execute={ \semantex_other_spar_with_size:nnnn { ##1 } { #1 } { #2 } { #3 } } },
	},
	leftspar=(,
	rightspar=),
	sparsize=normal,
	% The argument:
	dataprovide=arg,
	boolprovide=nextargwithsep,
	intprovide=numberofarguments,
	dataprovide=prearg,
	dataprovide=postarg,
	definekeys={
		{argdots}{setargkeys={...}},
		{arg...}{setargkeys={dots}},
		{cargdots}{setargkeys={cdots}},
		{carg...}{setargkeys={c...}},
		{argslot}{setargkeys={slot}},
		{arg-}{setargkeys={-}},
		{cargslot}{setargkeys={cslot}},
		{carg-}{setargkeys={c-}},
		{cleararg}{ execute={
				\semantex_data_tl_clear:nn { ##1 } { arg }
				\semantex_data_int_clear:nn { ##1 } { numberofarguments }
				\semantex_data_bool_set_false:nn { ##1 } { nextargwithsep }
			}
		},
		{clearprearg}{ execute={ \semantex_data_tl_clear:nn { ##1 } { prearg } } },
		{clearpostarg}{ execute={ \semantex_data_tl_clear:nn { ##1 } { postarg } } },
	},
	definekeys[1]={
		{setargkeys}{ execute={ \semantex_arg_keys_set:nn { ##1 } { #1 } } },
		{argkeysset}{ execute={ \semantex_arg_keys_set:nn { ##1 } { #1 } } },
		{setargkeysx}{ execute={ \semantex_arg_keys_set_x:nn { ##1 } { #1 } } },
		{argkeyssetx}{ execute={ \semantex_arg_keys_set_x:nn { ##1 } { #1 } } },
		{setargsinglekeys}{ execute={ \semantex_arg_singlekeys_set:nn { ##1 } { #1 } } },
		{argsinglekeysset}{ execute={ \semantex_arg_singlekeys_set:nn { ##1 } { #1 } } },
		{setargsinglekeysx}{ execute={ \semantex_arg_singlekeys_set_x:nn { ##1 } { #1 } } },
		{argsinglekeyssetx}{ execute={ \semantex_arg_singlekeys_set_x:nn { ##1 } { #1 } } },
		{setoneargsinglekey}{ execute={ \semantex_arg_singlekey:nn { ##1 } { #1 } } },
		{oneargsinglekeyset}{ execute={ \semantex_arg_singlekey:nn { ##1 } { #1 } } },
		{setoneargsinglekeyx}{ execute={ \semantex_arg_singlekey_x:nn { ##1 } { #1 } } },
		{oneargsinglekeysetx}{ execute={ \semantex_arg_singlekey_x:nn { ##1 } { #1 } } },
		{setargwithoutkeyval}{ execute={ \semantex_arg_without_keyval:nn { ##1 } { #1 } } },
		{argwithoutkeyvalset}{ execute={ \semantex_arg_without_keyval:nn { ##1 } { #1 } } },
		{setargwithoutkeyvalx}{ execute={ \semantex_arg_without_keyval:nx { ##1 } { #1 } } },
		{argwithoutkeyvalsetx}{ execute={ \semantex_arg_without_keyval:nx { ##1 } { #1 } } },
		{prearg}{ execute={ \semantex_data_tl_put_left:nnn { ##1 } { prearg } { #1 } } },
		{postarg}{ execute={ \semantex_data_tl_put_left:nnn { ##1 } { postarg } { #1 } } },
		{setargsep}{ execute={ \semantex_data_tl_set:nnn { ##1 } { argsep } { #1 } } },
		{setargslot}{ execute={ \semantex_data_tl_set:nnn { ##1 } { argslot } { #1 } } },
		{setargdots}{ execute={ \semantex_data_tl_set:nnn { ##1 } { argdots } { #1 } } },
		{argkeyval}{
			strifeqTF={#1}{true}
			{
				definekeys[1]={
					{arg}{execute={ \semantex_arg_keys_set:nn { ########1 } { ####1 } }},
				},
			}
			{
				strifeqTF={#1}{false}
				{
					definekeys[1]={
						{arg}{ execute={ \semantex_arg_without_keyval:nn { ########1 } { ####1 } } },
					},
				}
				{
					strifeqTF={#1}{singlekeys}
					{
						definekeys[1]={
							{arg}{ execute={ \semantex_arg_singlekeys_set:nn { ########1 } { ####1 } } },
						},
					}
					{
						strifeqTF={#1}{onesinglekey}
						{
							definekeys[1]={
								{arg}{ execute={ \semantex_arg_singlekey:nn { ########1 } { ####1 } } },
							},
						}
						{
							ERRORkeyvaluenotfound={argkeyval}{#1},
						},
					},
				},
			},
		},
		{argposition}{
			strifeqTF={#1}{left}
			{
				boolsettrue={leftargument},
			}
			{
				strifeqTF={#1}{right}
				{
					boolsetfalse={leftargument},
				}
				{
					ERRORkeyvaluenotfound={argposition}{#1},
				},
			},
		},
		{nextargwithsep}{
			strifeqTF={#1}{true}
			{
				boolsettrue={nextargwithsep},
			}
			{
				strifeqTF={#1}{false}
				{
					boolsetfalse={nextargwithsep},
				}
				{
					ERRORkeyvaluenotfound={nextargwithsep}{#1},
				},
			},
		},
		{sarg}{setargkeys={s={#1}}},
		{carg}{setargkeys={c={#1}}},
		{argdotswithothersep}{setargkeys={dotswithothersep={#1}}},
		{arg...withothersep}{setargkeys={dotswithothersep={#1}}},
		{argslotwithothersep}{setargkeys={slotwithothersep={#1}}},
		{arg-withothersep}{setargkeys={slotwithothersep={#1}}},
	},
	definekeys[2]={
		{argwithothersep}{setargkeys={othersep={#1}{#2}}},
	},
	setargsep={,},
	setargslot={ {-} },
	setargdots={ \dots },
	% Parentheses:
	definekeys={
		{par}{usepar=true},
		{neverpar}{usepar=never},
		{nopar}{usepar=false},
	},
	definekeys[1]={
		{par}{
			execute={
				\semantex_data_tl_set:nnn { ##1 } { parsize } { #1 }
				\semantex_data_bool_set_true:nn { ##1 } { par }
			},
		},
		{parsize}{
			execute={
				\semantex_data_tl_set:nnn { ##1 } { parsize } { #1 }
			},
		},
		{leftpar}{
			execute={ \semantex_data_tl_set:nnn { ##1 } { leftpar } { #1 } },
		},
		{rightpar}{
			execute={ \semantex_data_tl_set:nnn { ##1 } { rightpar } { #1 } },
		},
		{usepar}{
			strifeqTF={#1}{true}
			{
				boolsettrue={par},
				boolsetfalse={flexpar},
			}
			{
				strifeqTF={#1}{false}
				{
					boolsetfalse={par},
					boolsettrue={flexpar},
				}
				{
					strifeqTF={#1}{never}
					{
						boolsetfalse={par},
						boolsetfalse={flexpar},
					}
					{
						ERRORkeyvaluenotfound={usepar}{#1},
					},
				},
			},
		},
	},
	leftpar=(,
	rightpar=),
	par=normal,
	% Accents, primes, bullets, etc.:
	definekeys={
		{smash}{command=\smash},
		{prime}{upper={\prime}},
		{'}{prime},
		{''}{prime,prime},
		{'''}{prime,prime,prime},
	},
	% Upper indices:
	dataprovide=upper,
	boolprovide=nextupperwithsep,
	intprovide=numberofupperindices,
	dataprovide=preupper,
	dataprovide=postupper,
	definekeys={
		{upperslot}{ setkeysx={ upper=\semantex_data_tl_get_exp_not:nn { ##1 } { upperslot } } },
		{upper-}{upperslot},
		{supperslot}{ setkeysx={ supper=\semantex_data_tl_get_exp_not:nn { ##1 } { upperslot } } },
		{supper-}{supperslot},
		{cupperslot}{ setkeysx={ cupper=\semantex_data_tl_get_exp_not:nn { ##1 } { upperslot } } },
		{cupper-}{cupperslot},
		{upperdots}{ setkeysx={ upper=\semantex_data_tl_get_exp_not:nn { ##1 } { upperdots } } },
		{upper...}{upperdots},
		{supperdots}{ setkeysx={ supper=\semantex_data_tl_get_exp_not:nn { ##1 } { upperdots } } },
		{supper...}{supperdots},
		{cupperdots}{ setkeysx={ cupper=\semantex_data_tl_get_exp_not:nn { ##1 } { upperdots } } },
		{cupper...}{cupperdots},
		{clearupper}{
			execute={
				\semantex_data_tl_clear:nn { ##1 } { upper }
				\semantex_data_bool_set_false:nn { ##1 } { nextupperwithsep }
				\semantex_data_int_clear:nn { ##1 } { numberofupperindices }
			},
		},
		{clearpreupper}{
			execute={ \semantex_data_tl_clear:nn { ##1 } { preupper } },
		},
		{clearpostupper}{
			execute={ \semantex_data_tl_clear:nn { ##1 } { postupper } },
		},
		{upper*}{upper=\SemantexBullet},
		{upper**}{upper=\SemantexDoubleBullet},
		{supper*}{supper=\SemantexBullet},
		{supper**}{supper=\SemantexDoubleBullet},
		{cupper*}{cupper=\SemantexBullet},
		{cupper**}{cupper=\SemantexDoubleBullet},
	},
	definekeys[1]={
		{upper}{
			execute={
				\tl_if_blank:nF { #1 }
				{
					\semantex_data_tl_put_right:nnn { ##1 } { upper } { #1 }
					\semantex_data_bool_set_true:nn { ##1 } { nextupperwithsep }
					\semantex_data_int_incr:nn { ##1 } { numberofupperindices }
				}
			},
		},
		{supper}{
			execute={
				\tl_if_blank:nF { #1 }
				{
					\semantex_data_bool_get:nnTF { ##1 } { nextupperwithsep }
					{
						\semantex_data_tl_put_right:nnx { ##1 } { upper }
						{ \semantex_data_tl_get_exp_not:nn { ##1 } { uppersep } }
						\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 } { nextupperwithsep }
					\semantex_data_int_incr:nn { ##1 } { numberofupperindices }
				}
			},
		},
		{cupper}{
			execute={
				\tl_if_blank:nF{#1}
				{
					\semantex_data_bool_get:nnTF { ##1 } { nextupperwithsep }
					{
						\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 } { nextupperwithsep }
					\semantex_data_int_incr:nn { ##1 } { numberofupperindices }
				}
			}
		},
		{preupper}{
			execute={
				\tl_if_blank:nF{#1}{
					\semantex_data_tl_put_left:nnn { ##1 } { preupper } { #1 }
				}
			},
		},
		{postupper}{
			execute={
				\tl_if_blank:nF{#1}{
					\semantex_data_tl_put_right:nnn { ##1 } { postupper } { #1 }
				}
			},
		},
		{upperputleft}{
			execute={
				\tl_if_blank:nF { #1 }
				{
					\semantex_data_tl_put_left:nnn { ##1 } { upper } { #1 }
					\semantex_data_bool_set_true:nn { ##1 } { nextupperwithsep }
					\semantex_data_int_incr:nn { ##1 } { numberofupperindices }
				}			
			},
		},
		{setupperslot}{
			execute={ \semantex_data_tl_set:nnn { ##1 } { upperslot } { #1 } },
		},
		{upperslotwithothersep}{
			execute={
				\semantex_valuekey:nnx { ##1 } { upperwithothersep }
				{
					{ \exp_not:n { #1 } }
					{ \semantex_data_tl_get_exp_not:nn { ##1 } { upperslot } }
				}
			},
		},
		{upper-withothersep}{
			execute={
				\semantex_valuekey:nnx { ##1 } { upperwithothersep }
				{
					{ \exp_not:n { #1 } }
					{ \semantex_data_tl_get_exp_not:nn { ##1 } { upperslot } }
				}
			},
		},
		{setupperdots}{
			execute={ \semantex_data_tl_set:nnn { ##1 } { upperdots } { #1 } },
		},
		{upperdotswithothersep}{
			execute={
				\semantex_valuekey:nnx { ##1 } { upperwithothersep }
				{
					{ \exp_not:n { #1 } }
					{ \semantex_data_tl_get_exp_not:nn { ##1 } { upperdots } }
				}
			},
		},
		{upper...withothersep}{
			execute={
				\semantex_valuekey:nnx { ##1 } { upperwithothersep }
				{
					{ \exp_not:n { #1 } }
					{ \semantex_data_tl_get_exp_not:nn { ##1 } { upperdots } }
				}
			},
		},
		{upper*withothersep}{upperwithothersep={#1}{\SemantexBullet}},
		{upper**withothersep}{upperwithothersep={#1}{\SemantexDoubleBullet}},
		{setuppersep}{
			execute={ \semantex_data_tl_set:nnn { ##1 } { uppersep } { #1 } },
		},
		{nextupperwithsep}{
			strifeqTF={#1}{false}
			{
				boolsetfalse={nextupperwithsep},
			}
			{
				strifeqTF={#1}{true}
				{
					boolsettrue={nextupperwithsep},
				}
				{
					ERRORkeyvaluenotfound={nextupperwithsep}{#1},
				},
			},
		},
	},
	definekeys[2]={
		{upperwithothersep}{
			execute={
				\semantex_data_bool_get:nnTF { ##1 } { nextupperwithsep }
					{ \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 } { nextupperwithsep }
				\semantex_data_int_incr:nn { ##1 } { numberofupperindices }
			},
		},
	},
	setuppersep={ , },
	setupperdots={ \dots },
	setupperslot={ {-} },
	% Lower indices:
	dataprovide=lower,
	boolprovide=nextlowerwithsep,
	intprovide=numberoflowerindices,
	dataprovide=prelower,
	dataprovide=postlower,
	definekeys={
		{lowerslot}{ setkeysx={ lower=\semantex_data_tl_get_exp_not:nn { ##1 } { lowerslot } } },
		{lower-}{lowerslot},
		{slowerslot}{ setkeysx={ slower=\semantex_data_tl_get_exp_not:nn { ##1 } { lowerslot } } },
		{slower-}{slowerslot},
		{clowerslot}{ setkeysx={ clower=\semantex_data_tl_get_exp_not:nn { ##1 } { lowerslot } } },
		{clower-}{clowerslot},
		{lowerdots}{ setkeysx={ lower=\semantex_data_tl_get_exp_not:nn { ##1 } { lowerdots } } },
		{lower...}{lowerdots},
		{slowerdots}{ setkeysx={ slower=\semantex_data_tl_get_exp_not:nn { ##1 } { lowerdots } } },
		{slower...}{slowerdots},
		{clowerdots}{ setkeysx={ clower=\semantex_data_tl_get_exp_not:nn { ##1 } { lowerdots } } },
		{clower...}{clowerdots},
		{clearlower}{
			execute={
				\semantex_data_tl_clear:nn { ##1 } { lower }
				\semantex_data_bool_set_false:nn { ##1 } { nextlowerwithsep }
				\semantex_data_int_clear:nn { ##1 } { numberoflowerindices }
			},
		},
		{clearprelower}{
			execute={ \semantex_data_tl_clear:nn { ##1 } { prelower } },
		},
		{clearpostlower}{
			execute={ \semantex_data_tl_clear:nn { ##1 } { postlower } },
		},
		{lower*}{lower=\SemantexBullet},
		{lower**}{lower=\SemantexDoubleBullet},
		{slower*}{slower=\SemantexBullet},
		{slower**}{slower=\SemantexDoubleBullet},
		{clower*}{clower=\SemantexBullet},
		{clower**}{clower=\SemantexDoubleBullet},
	},
	definekeys[1]={
		{lower}{
			execute={
				\tl_if_blank:nF{#1}{
					\semantex_data_tl_put_right:nnn { ##1 } { lower } { #1 }
					\semantex_data_bool_set_true:nn { ##1 } { nextlowerwithsep }
					\semantex_data_int_incr:nn { ##1 } { numberoflowerindices }
				}
			},
		},
		{slower}{
			execute={
				\tl_if_blank:nF { #1 }
				{
					\semantex_data_bool_get:nnTF { ##1 } { nextlowerwithsep }
					{
						\semantex_data_tl_put_right:nnx { ##1 } { lower }
						{ \semantex_data_tl_get_exp_not:nn { ##1 } { lowersep } }
						\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 } { nextlowerwithsep }
					\semantex_data_int_incr:nn { ##1 } { numberoflowerindices }
				}
			},
		},
		{clower}{
			execute={
				\tl_if_blank:nF{#1}
				{
					\semantex_data_bool_get:nnTF { ##1 } { nextlowerwithsep }
					{
						\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 } { nextlowerwithsep }
					\semantex_data_int_incr:nn { ##1 } { numberoflowerindices }
				}
			}
		},
		{prelower}{
			execute={
				\tl_if_blank:nF{#1}{
					\semantex_data_tl_put_left:nnn { ##1 } { prelower } { #1 }
				}
			},
		},
		{postlower}{
			execute={
				\tl_if_blank:nF{#1}{
					\semantex_data_tl_put_right:nnn { ##1 } { postlower } { #1 }
				}
			},
		},
		{lowerputleft}{
			execute={
				\tl_if_blank:nF { #1 }
				{
					\semantex_data_tl_put_left:nnn { ##1 } { lower } { #1 }
					\semantex_data_bool_set_true:nn { ##1 } { nextlowerwithsep }
					\semantex_data_int_incr:nn { ##1 } { numberoflowerindices }
				}			
			},
		},
		{setlowerslot}{
			execute={ \semantex_data_tl_set:nnn { ##1 } { lowerslot } { #1 } },
		},
		{lowerslotwithothersep}{
			execute={
				\semantex_valuekey:nnx { ##1 } { lowerwithothersep }
				{
					{ \exp_not:n { #1 } }
					{ \semantex_data_tl_get_exp_not:nn { ##1 } { lowerslot } }
				}
			},
		},
		{lower-withothersep}{
			execute={
				\semantex_valuekey:nnx { ##1 } { lowerwithothersep }
				{
					{ \exp_not:n { #1 } }
					{ \semantex_data_tl_get_exp_not:nn { ##1 } { lowerslot } }
				}
			},
		},
		{setlowerdots}{
			execute={ \semantex_data_tl_set:nnn { ##1 } { lowerdots } { #1 } },
		},
		{lowerdotswithothersep}{
			execute={
				\semantex_valuekey:nnx { ##1 } { lowerwithothersep }
				{
					{ \exp_not:n { #1 } }
					{ \semantex_data_tl_get_exp_not:nn { ##1 } { lowerdots } }
				}
			},
		},
		{lower...withothersep}{
			execute={
				\semantex_valuekey:nnx { ##1 } { lowerwithothersep }
				{
					{ \exp_not:n { #1 } }
					{ \semantex_data_tl_get_exp_not:nn { ##1 } { lowerdots } }
				}
			},
		},
		{lower*withothersep}{lowerwithothersep={#1}{\SemantexBullet}},
		{lower**withothersep}{lowerwithothersep={#1}{\SemantexDoubleBullet}},
		{setlowersep}{
			execute={ \semantex_data_tl_set:nnn { ##1 } { lowersep } { #1 } },
		},
		{nextlowerwithsep}{
			strifeqTF={#1}{false}
			{
				boolsetfalse={nextlowerwithsep},
			}
			{
				strifeqTF={#1}{true}
				{
					boolsettrue={nextlowerwithsep},
				}
				{
					ERRORkeyvaluenotfound={nextlowerwithsep}{#1},
				},
			},
		},
	},
	definekeys[2]={
		{lowerwithothersep}{
			execute={
				\semantex_data_bool_get:nnTF { ##1 } { nextlowerwithsep }
					{ \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 } { nextlowerwithsep }
				\semantex_data_int_incr:nn { ##1 } { numberoflowerindices }
			},
		},
	},
	setlowersep={ , },
	setlowerdots={ \dots },
	setlowerslot={ {-} },
	% Upper left indices:	
	dataprovide=upperleft,
	intprovide=nextupperleftwithsep,
	intprovide=numberofupperleftindices,
	dataprovide=preupperleft,
	dataprovide=postupperleft,
	definekeys={
		{upperleftslot}{ setkeysx={ upperleft=\semantex_data_tl_get_exp_not:nn { ##1 } { upperleftslot } } },
		{upperleft-}{upperleftslot},
		{supperleftslot}{ setkeysx={ supperleft=\semantex_data_tl_get_exp_not:nn { ##1 } { upperleftslot } } },
		{supperleft-}{supperleftslot},
		{cupperleftslot}{ setkeysx={ cupperleft=\semantex_data_tl_get_exp_not:nn { ##1 } { upperleftslot } } },
		{cupperleft-}{cupperleftslot},
		{upperleftdots}{ setkeysx={ upperleft=\semantex_data_tl_get_exp_not:nn { ##1 } { upperleftdots } } },
		{upperleft...}{upperleftdots},
		{supperleftdots}{ setkeysx={ supperleft=\semantex_data_tl_get_exp_not:nn { ##1 } { upperleftdots } } },
		{supperleft...}{supperleftdots},
		{cupperleftdots}{ setkeysx={ cupperleft=\semantex_data_tl_get_exp_not:nn { ##1 } { upperleftdots } } },
		{cupperleft...}{cupperleftdots},
		{clearupperleft}{
			execute={
				\semantex_data_tl_clear:nn { ##1 } { upperleft }
				\semantex_data_bool_set_false:nn { ##1 } { nextupperleftwithsep }
				\semantex_data_int_clear:nn { ##1 } { numberofupperleftindices }
			},
		},
		{clearpreupperleft}{
			execute={ \semantex_data_tl_clear:nn { ##1 } { preupperleft } },
		},
		{clearpostupperleft}{
			execute={ \semantex_data_tl_clear:nn { ##1 } { postupperleft } },
		},
		{upperleft*}{upperleft=\SemantexBullet},
		{upperleft**}{upperleft=\SemantexDoubleBullet},
		{supperleft*}{supperleft=\SemantexBullet},
		{supperleft**}{supperleft=\SemantexDoubleBullet},
		{cupperleft*}{cupperleft=\SemantexBullet},
		{cupperleft**}{cupperleft=\SemantexDoubleBullet},
	},
	definekeys[1]={
		{upperleft}{
			execute={
				\tl_if_blank:nF{#1}{
					\semantex_data_tl_put_left:nnn { ##1 } { upperleft } { #1 }
					\semantex_data_bool_set_true:nn { ##1 } { nextupperleftwithsep }
					\semantex_data_int_incr:nn { ##1 } { numberofupperleftindices }
				}
			},
		},
		{supperleft}{
			execute={
				\tl_if_blank:nF { #1 }
				{
					\semantex_data_bool_get:nnTF { ##1 } { nextupperleftwithsep }
					{
						\semantex_data_tl_put_left:nnx { ##1 } { upperleft }
						{ \semantex_data_tl_get_exp_not:nn { ##1 } { upperleftsep } }
						\semantex_data_tl_put_left:nnn { ##1 } { upperleft } { #1 }
					}
					{
						\semantex_data_tl_put_left:nnn { ##1 } { upperleft } { #1 }
					}
					\semantex_data_bool_set_true:nn { ##1 } { nextupperleftwithsep }
					\semantex_data_int_incr:nn { ##1 } { numberofupperleftindices }
				}
			},
		},
		{cupperleft}{
			execute={
				\tl_if_blank:nF{#1}
				{
					\semantex_data_bool_get:nnTF { ##1 } { nextupperleftwithsep }
					{
						\semantex_data_tl_put_left:nnn { ##1 } { upperleft } { , #1 }
					}
					{
						\semantex_data_tl_put_left:nnn { ##1 } { upperleft } { #1 }
					}
					\semantex_data_bool_set_true:nn { ##1 } { nextupperleftwithsep }
					\semantex_data_int_incr:nn { ##1 } { numberofupperleftindices }
				}
			}
		},
		{preupperleft}{
			execute={
				\tl_if_blank:nF{#1}{
					\semantex_data_tl_put_left:nnn { ##1 } { preupperleft } { #1 }
				}
			},
		},
		{postupperleft}{
			execute={
				\tl_if_blank:nF{#1}{
					\semantex_data_tl_put_right:nnn { ##1 } { postupperleft } { #1 }
				}
			},
		},
		{upperleftputright}{
			execute={
				\tl_if_blank:nF { #1 }
				{
					\semantex_data_tl_put_right:nnn { ##1 } { upperleft } { #1 }
					\semantex_data_bool_set_true:nn { ##1 } { nextupperleftwithsep }
					\semantex_data_int_incr:nn { ##1 } { numberofupperleftindices }
				}			
			},
		},
		{setupperleftslot}{
			execute={ \semantex_data_tl_set:nnn { ##1 } { upperleftslot } { #1 } },
		},
		{upperleftslotwithothersep}{
			execute={
				\semantex_valuekey:nnx { ##1 } { upperleftwithothersep }
				{
					{ \exp_not:n { #1 } }
					{ \semantex_data_tl_get_exp_not:nn { ##1 } { upperleftslot } }
				}
			},
		},
		{upperleft-withothersep}{
			execute={
				\semantex_valuekey:nnx { ##1 } { upperleftwithothersep }
				{
					{ \exp_not:n { #1 } }
					{ \semantex_data_tl_get_exp_not:nn { ##1 } { upperleftslot } }
				}
			},
		},
		{setupperleftdots}{
			execute={ \semantex_data_tl_set:nnn { ##1 } { upperleftdots } { #1 } },
		},
		{upperleftdotswithothersep}{
			execute={			
				\semantex_valuekey:nnx { upperleftwithothersep }
				{
					{ \exp_not:n { #1 } }
					{ \semantex_data_tl_get_exp_not:nn { ##1 } { upperleftdots } }
				}
			},
		},
		{upperleft...withothersep}{
			execute={			
				\semantex_valuekey:nnx { upperleftwithothersep }
				{
					{ \exp_not:n { #1 } }
					{ \semantex_data_tl_get_exp_not:nn { ##1 } { upperleftdots } }
				}
			},
		},
		{upperleft*withothersep}{upperleftwithothersep={#1}{\SemantexBullet}},
		{upperleft**withothersep}{upperleftwithothersep={#1}{\SemantexDoubleBullet}},
		{setupperleftsep}{
			execute={ \semantex_data_tl_set:nnn { ##1 } { upperleftsep } { #1 } },
		},
		{nextupperleftwithsep}{
			strifeqTF={#1}{false}
			{
				boolsetfalse={nextupperleftwithsep},
			}
			{
				strifeqTF={#1}{true}
				{
					boolsettrue={nextupperleftwithsep},
				}
				{
					ERRORkeyvaluenotfound={nextupperleftwithsep}{#1},
				},
			},
		},
	},
	definekeys[2]={
		{upperleftwithothersep}{
			execute={
				\semantex_data_bool_get:nnTF { ##1 } { nextupperleftwithsep }
					{ \semantex_data_tl_put_left:nnn { ##1 } { upperleft } { #2 #1 } }
					{ \semantex_data_tl_put_left:nnn { ##1 } { upperleft } { #2 } }
				\semantex_data_bool_set_true:nn { ##1 } { nextupperleftwithsep }
				\semantex_data_int_incr:nn { ##1 } { numberofupperleftindices }
			},
		},
	},
	setupperleftsep={ , },
	setupperleftdots={ \dots },
	setupperleftslot={ {-} },
	% Lower left indices:
	dataprovide=lowerleft,
	boolprovide=nextlowerleftwithsep,
	intprovide=numberoflowerleftindices,
	dataprovide=prelowerleft,
	dataprovide=postlowerleft,
	definekeys={
		{lowerleftslot}{ setkeysx={ lowerleft=\semantex_data_tl_get_exp_not:nn { ##1 } { lowerleftslot } } },
		{lowerleft-}{lowerleftslot},
		{slowerleftslot}{ setkeysx={ slowerleft=\semantex_data_tl_get_exp_not:nn { ##1 } { lowerleftslot } } },
		{slowerleft-}{slowerleftslot},
		{clowerleftslot}{ setkeysx={ clowerleft=\semantex_data_tl_get_exp_not:nn { ##1 } { lowerleftslot } } },
		{clowerleft-}{clowerleftslot},
		{lowerleftdots}{ setkeysx={ lowerleft=\semantex_data_tl_get_exp_not:nn { ##1 } { lowerleftdots } } },
		{lowerleft...}{lowerleftdots},
		{slowerleftdots}{ setkeysx={ slowerleft=\semantex_data_tl_get_exp_not:nn { ##1 } { lowerleftdots } } },
		{slowerleft...}{slowerleftdots},
		{clowerleftdots}{ setkeysx={ clowerleft=\semantex_data_tl_get_exp_not:nn { ##1 } { lowerleftdots } } },
		{clowerleft...}{clowerleftdots},
		{clearlowerleft}{
			execute={
				\semantex_data_tl_clear:nn { ##1 } { lowerleft }
				\semantex_data_bool_set_false:nn { ##1 } { nextlowerleftwithsep }
				\semantex_data_int_clear:nn { ##1 } { numberoflowerleftindices }
			},
		},
		{clearprelowerleft}{
			execute={ \semantex_data_tl_clear:nn { ##1 } { prelowerleft } },
		},
		{clearpostlowerleft}{
			execute={ \semantex_data_tl_clear:nn { ##1 } { postlowerleft } },
		},
		{lowerleft*}{lowerleft=\SemantexBullet},
		{lowerleft**}{lowerleft=\SemantexDoubleBullet},
		{slowerleft*}{slowerleft=\SemantexBullet},
		{slowerleft**}{slowerleft=\SemantexDoubleBullet},
		{clowerleft*}{clowerleft=\SemantexBullet},
		{clowerleft**}{clowerleft=\SemantexDoubleBullet},
	},
	definekeys[1]={
		{lowerleft}{
			execute={
				\tl_if_blank:nF{#1}{
					\semantex_data_tl_put_left:nnn { ##1 } { lowerleft } { #1 }
					\semantex_data_bool_set_true:nn { ##1 } { nextlowerleftwithsep }
					\semantex_data_int_incr:nn { ##1 } { numberoflowerleftindices }
				}
			},
		},
		{slowerleft}{
			execute={
				\tl_if_blank:nF { #1 }
				{
					\semantex_data_bool_get:nnTF { ##1 } { nextlowerleftwithsep }
					{
						\semantex_data_tl_put_left:nnx { ##1 } { lowerleft }
						{ \semantex_data_tl_get_exp_not:nn { ##1 } { lowerleftsep } }
						\semantex_data_tl_put_left:nnn { ##1 } { lowerleft } { #1 }
					}
					{
						\semantex_data_tl_put_left:nnn { ##1 } { lowerleft } { #1 }
					}
					\semantex_data_bool_set_true:nn { ##1 } { nextlowerleftwithsep }
					\semantex_data_int_incr:nn { ##1 } { numberoflowerleftindices }
				}
			},
		},
		{clowerleft}{
			execute={
				\tl_if_blank:nF{#1}
				{
					\semantex_data_bool_get:nnTF { ##1 } { nextlowerleftwithsep }
					{
						\semantex_data_tl_put_left:nnn { ##1 } { lowerleft } { , #1 }
					}
					{
						\semantex_data_tl_put_left:nnn { ##1 } { lowerleft } { #1 }
					}
					\semantex_data_bool_set_true:nn { ##1 } { nextlowerleftwithsep }
					\semantex_data_int_incr:nn { ##1 } { numberoflowerleftindices }
				}
			}
		},
		{prelowerleft}{
			execute={
				\tl_if_blank:nF{#1}{
					\semantex_data_tl_put_left:nnn { ##1 } { prelowerleft } { #1 }
				}
			},
		},
		{postlowerleft}{
			execute={
				\tl_if_blank:nF{#1}{
					\semantex_data_tl_put_right:nnn { ##1 } { postlowerleft } { #1 }
				}
			},
		},
		{lowerleftputright}{
			execute={
				\tl_if_blank:nF { #1 }
				{
					\semantex_data_tl_put_right:nnn { ##1 } { lowerleft } { #1 }
					\semantex_data_bool_set_true:nn { ##1 } { nextlowerleftwithsep }
					\semantex_data_int_incr:nn { ##1 } { numberoflowerleftindices }
				}			
			},
		},
		{setlowerleftslot}{
			execute={ \semantex_data_tl_set:nnn { ##1 } { lowerleftslot } { #1 } },
		},
		{lowerleftslotwithothersep}{
			execute={
				\semantex_valuekey:nnx { ##1 } { lowerleftwithothersep }
				{
					{ \exp_not:n { #1 } }
					{ \semantex_data_tl_get_exp_not:nn { ##1 } { lowerleftslot } },
				}
			},
		},
		{lowerleft-withothersep}{
			execute={
				\semantex_valuekey:nnx { ##1 } { lowerleftwithothersep }
				{
					{ \exp_not:n { #1 } }
					{ \semantex_data_tl_get_exp_not:nn { ##1 } { lowerleftslot } },
				}
			},
		},
		{setlowerleftdots}{
			execute={ \semantex_data_tl_set:nnn { ##1 } { lowerleftdots } { #1 } },
		},
		{lowerleftdotswithothersep}{
			execute={
				\semantex_valuekey:nnx { ##1 } { lowerleftwithothersep }
				{
					{ \exp_not:n { #1 } }
					{ \semantex_data_tl_get_exp_not:nn { ##1 } { lowerleftdots } }
				}
			},
		},
		{lowerleft...withothersep}{
			execute={
				\semantex_valuekey:nnx { ##1 } { lowerleftwithothersep }
				{
					{ \exp_not:n { #1 } }
					{ \semantex_data_tl_get_exp_not:nn { ##1 } { lowerleftdots } }
				}
			},
		},
		{lowerleft*withothersep}{lowerleftwithothersep={#1}{\SemantexBullet}},
		{lowerleft**withothersep}{lowerleftwithothersep={#1}{\SemantexDoubleBullet}},
		{setlowerleftsep}{
			execute={ \semantex_data_tl_set:nnn { ##1 } { lowerleftsep } { #1 } },
		},
		{nextlowerleftwithsep}{
			strifeqTF={#1}{false}
			{
				boolsetfalse={nextlowerleftwithsep},
			}
			{
				strifeqTF={#1}{true}
				{
					boolsettrue={nextlowerleftwithsep},
				}
				{
					ERRORkeyvaluenotfound={nextlowerleftwithsep}{#1},
				},
			},
		},
	},
	definekeys[2]={
		{lowerleftwithothersep}{
			execute={
				\semantex_data_bool_get:nnTF { ##1 } { nextlowerleftwithsep }
					{ \semantex_data_tl_put_left:nnn { ##1 } { lowerleft } { #2 #1 } }
					{ \semantex_data_tl_put_left:nnn { ##1 } { lowerleft } { #2 } }
				\semantex_data_bool_set_true:nn { ##1 } { nextlowerleftwithsep }
				\semantex_data_int_incr:nn { ##1 } { numberoflowerleftindices }
			},
		},
	},
	setlowerleftsep={ , },
	setlowerleftdots={ \dots },
	setlowerleftslot={ {-} },
	% The "d" index:
	definekeys={
		{dslot}{
			boolifTF={uppergrading}
				{ upperslot }
				{ lowerslot },
		},
		{d-}{dslot},
		{sdslot}{
			boolifTF={uppergrading}
				{ supperslot }
				{ slowerslot },
		},
		{sd-}{sdslot},
		{cdslot}{
			boolifTF={uppergrading}
				{ cupperslot }
				{ clowerslot },
		},
		{cd-}{cdslot},
		{ddots}{
			boolifTF={uppergrading}
				{ upperdots }
				{ lowerdots },
		},
		{d...}{ddots},
		{sddots}{
			boolifTF={uppergrading}
				{ supperdots }
				{ slowerdots },
		},
		{sd...}{sddots},
		{cddots}{
			boolifTF={uppergrading}
				{ cupperdots }
				{ clowerdots },
		},
		{cd...}{cddots},
		{cleard}{
			boolifTF={uppergrading}
				{ clearupper }
				{ clearlower },
		},
		{clearpred}{
			boolifTF={uppergrading}
				{ clearpreupper }
				{ clearprelower },
		},
		{clearpostd}{
			boolifTF={uppergrading}
				{ clearpostupper }
				{ clearpostlower },
		},
		{d*}{
			boolifTF={uppergrading}
				{ upper* }
				{ lower* },
		},
		{d**}{
			boolifTF={uppergrading}
				{ upper** }
				{ lower** },
		},
		{sd*}{
			boolifTF={uppergrading}
				{ supper* }
				{ slower* },
		},
		{sd**}{
			boolifTF={uppergrading}
				{ supper** }
				{ slower** },
		},
		{cd*}{
			boolifTF={uppergrading}
				{ cupper* }
				{ clower* },
		},
		{cd**}{
			boolifTF={uppergrading}
				{ cupper** }
				{ clower** },
		},
	},
	definekeys[1]={
		{d}{
			execute={
				\semantex_data_bool_get:nnTF { ##1 } { uppergrading }
					{ \semantex_valuekey:nnn { ##1 } { upper } { #1 } }
					{ \semantex_valuekey:nnn { ##1 } { lower } { #1 } }
			},
		},
		{sd}{
			execute={
				\semantex_data_bool_get:nnTF { ##1 } { uppergrading }
					{ \semantex_valuekey:nnn { ##1 } { supper } { #1 } }
					{ \semantex_valuekey:nnn { ##1 } { slower } { #1 } }
			},
		},
		{cd}{
			execute={
				\semantex_data_bool_get:nnTF { ##1 } { uppergrading }
					{ \semantex_valuekey:nnn { ##1 } { cupper } { #1 } }
					{ \semantex_valuekey:nnn { ##1 } { clower } { #1 } }
			},
		},
		{pred}{
			boolifTF={uppergrading}
			{
				preupper={#1},
			}
			{
				prelower={#1},
			},
		},
		{postd}{
			boolifTF={uppergrading}
			{
				postupper={#1},
			}
			{
				postlower={#1},
			},
		},
		{dputleft}{
			boolifTF={uppergrading}
			{
				upperputleft={#1},
			}
			{
				lowerputleft={#1},
			},
		},
		{setdslot}{
			boolifTF={uppergrading}
			{
				setupperslot={#1},
			}
			{
				setlowerslot={#1},
			}
		},
		{dslotwithothersep}{
			boolifTF={uppergrading}
			{
				upperslotwithothersep={#1},
			}
			{
				lowerslotwithothersep={#1},
			},
		},
		{d-withothersep}{
			dslotwithothersep={#1},
		},
		{setddots}{
			boolifTF={uppergrading}
			{
				setupperdots={#1},
			}
			{
				setlowerdots={#1},
			}
		},
		{ddotswithothersep}{
			boolifTF={uppergrading}
			{
				upperdotswithothersep={#1},
			}
			{
				lowerdotswithothersep={#1},
			},
		},
		{d...withothersep}{
			ddotswithothersep={#1},
		},
		{d*withothersep}{
			boolifTF={uppergrading}
				{ upper*withothersep={#1} }
				{ lower*withothersep={#1} },
		},
		{d**withothersep}{
			boolifTF={uppergrading}
				{ upper**withothersep={#1} }
				{ lower**withothersep={#1} },
		},
		{setdsep}{
			boolifTF={uppergrading}
			{
				setuppersep={#1},
			}
			{
				setlowersep={#1},
			},
		},
		{nextdwithsep}{
			strifeqTF={#1}{true}
			{
				boolifTF={uppergrading}
				{
					nextupperwithsep=true,
				}
				{
					nextlowerwithsep=true,
				},
			}
			{
				strifeqTF={#1}{false}
				{
					boolifTF={uppergrading}
					{
						nextupperwithsep=false,
					}
					{
						nextlowerwithsep=false,
					},
				}
				{
					ERRORkeyvaluenotfound={nextdwithothersep}{#1},
				},
			},
		},
	},
	definekeys[2]={
		{dwithothersep}{
			boolifTF={uppergrading}
			{
				upperwithothersep={#1}{#2},
			}
			{
				lowerwithothersep={#1}{#2},
			},
		},
	},
	% The "i" index:
	definekeys={
		{islot}{
			boolifTF={uppergrading}
				{ lowerslot }
				{ upperslot },
		},
		{i-}{islot},
		{sislot}{
			boolifTF={uppergrading}
				{ slowerslot }
				{ supperslot },
		},
		{si-}{sislot},
		{cislot}{
			boolifTF={uppergrading}
				{ clowerslot }
				{ cupperslot },
		},
		{ci-}{cislot},
		{idots}{
			boolifTF={uppergrading}
				{ lowerdots }
				{ upperdots },
		},
		{i...}{idots},
		{sidots}{
			boolifTF={uppergrading}
				{ slowerdots }
				{ supperdots },
		},
		{si...}{sidots},
		{cidots}{
			boolifTF={uppergrading}
				{ clowerdots }
				{ cupperdots },
		},
		{ci...}{cidots},
		{cleari}{
			boolifTF={uppergrading}
				{ clearlower }
				{ clearupper },
		},
		{clearprei}{
			boolifTF={uppergrading}
				{ clearprelower }
				{ clearpreupper },
		},
		{clearposti}{
			boolifTF={uppergrading}
				{ clearpostlower }
				{ clearpostupper },
		},
		{i*}{
			boolifTF={uppergrading}
				{ lower* }
				{ upper* },
		},
		{i**}{
			boolifTF={uppergrading}
				{ lower** }
				{ upper** },
		},
		{si*}{
			boolifTF={uppergrading}
				{ slower* }
				{ supper* },
		},
		{si**}{
			boolifTF={uppergrading}
				{ slower** }
				{ supper** },
		},
		{ci*}{
			boolifTF={uppergrading}
				{ clower* }
				{ cupper* },
		},
		{ci**}{
			boolifTF={uppergrading}
				{ clower** }
				{ cupper** },
		},
	},
	definekeys[1]={
		{i}{
			execute={
				\semantex_data_bool_get:nnTF { ##1 } { uppergrading }
					{ \semantex_valuekey:nnn { ##1 } { lower } { #1 } }
					{ \semantex_valuekey:nnn { ##1 } { upper } { #1 } }
			},
		},
		{si}{
			execute={
				\semantex_data_bool_get:nnTF { ##1 } { uppergrading }
					{ \semantex_valuekey:nnn { ##1 } { slower } { #1 } }
					{ \semantex_valuekey:nnn { ##1 } { supper } { #1 } }
			},
		},
		{ci}{
			execute={
				\semantex_data_bool_get:nnTF { ##1 } { uppergrading }
					{ \semantex_valuekey:nnn { ##1 } { clower } { #1 } }
					{ \semantex_valuekey:nnn { ##1 } { cupper } { #1 } }
			},
		},
		{prei}{
			boolifTF={uppergrading}
			{
				prelower={#1},
			}
			{
				preupper={#1},
			},
		},
		{posti}{
			boolifTF={uppergrading}
			{
				postlower={#1},
			}
			{
				postupper={#1},
			},
		},
		{iputleft}{
			boolifTF={uppergrading}
			{
				lowerputleft={#1},
			}{
				upperputleft={#1},
			},
		},
		{setislot}{
			boolifTF={uppergrading}
			{
				setlowerslot={#1},
			}
			{
				setupperslot={#1},
			}
		},
		{islotwithothersep}{
			boolifTF={uppergrading}
			{
				lowerslotwithothersep={#1},
			}
			{
				upperslotwithothersep={#1},
			},
		},
		{i-withothersep}{
			islotwithothersep={#1},
		},
		{setidots}{
			boolifTF={uppergrading}
			{
				setlowerdots={#1},
			}
			{
				setupperdots={#1},
			}
		},
		{idotswithothersep}{
			boolifTF={uppergrading}
			{
				lowerdotswithothersep={#1},
			}
			{
				upperdotswithothersep={#1},
			},
		},
		{i...withothersep}{
			idotswithothersep={#1},
		},
		{i*withothersep}{
			boolifTF={uppergrading}
				{ lower*withothersep={#1} }
				{ upper*withothersep={#1} },
		},
		{i**withothersep}{
			boolifTF={uppergrading}
				{ lower**withothersep={#1} }
				{ upper**withothersep={#1} },
		},
		{setisep}{
			boolifTF={uppergrading}
			{
				setlowersep={#1},
			}
			{
				setuppersep={#1},
			},
		},
		{nextiwithsep}{
			strifeqTF={#1}{true}
			{
				boolifTF={uppergrading}
				{
					nextlowerwithsep={#1},
				}
				{
					nextupperwithsep={#1},
				},
			}
			{
				strifeqTF={#1}{false}
				{
					boolifTF={uppergrading}
					{
						nextupperwithsep={#1},
					}
					{
						nextlowerwithsep={#1},
					},
				}
				{
					ERRORkeyvaluenotfound={nextiwithothersep}{#1},
				},
			},
		},
	},
	definekeys[2]={
		{iwithothersep}{
			execute={
				\semantex_data_bool_get:nnTF { ##1 } { uppergrading }
					{ \semantex_valuekey:nnn { ##1 } { lowerwithothersep } { { #1 } { #2 } } }
					{ \semantex_valuekey:nnn { ##1 } { upperwithothersep } { { #1 } { #2 } } }
			},
		},
	},
	% Argument keyval interface
	defineargkeys[1]={
		{execute}{execute={#1}},
		{setkeys}{ execute={ \semantex_keys_set:nn { ##1 } { #1 } } },
		{keysset}{ execute={ \semantex_keys_set:nn { ##1 } { #1 } } },
		{setkeysx}{ execute={ \semantex_keys_set_x:nn { ##1 } { #1 } } },
		{keyssetx}{ execute={ \semantex_keys_set_x:nn { ##1 } { #1 } } },
		{setargkeys}{ execute={ \semantex_arg_keys_set:nn { ##1 } { #1 } } },
		{argkeysset}{ execute={ \semantex_arg_keys_set:nn { ##1 } { #1 } } },
		{setargkeysx}{ execute={ \semantex_arg_keys_set_x:nn { ##1 } { #1 } } },
		{argkeyssetx}{ execute={ \semantex_arg_keys_set_x:nn { ##1 } { #1 } } },
		{setargsinglekeys}{ execute={ \semantex_arg_singlekeys_set:nn { ##1 } { #1 } } },
		{argsinglekeysset}{ execute={ \semantex_arg_singlekeys_set:nn { ##1 } { #1 } } },
		{setargsinglekeysx}{ execute={ \semantex_arg_singlekeys_set_x:nn { ##1 } { #1 } } },
		{argsinglekeyssetx}{ execute={ \semantex_arg_singlekeys_set_x:nn { ##1 } { #1 } } },
		{setoneargsinglekey}{ execute={ \semantex_arg_singlekey:nn { ##1 } { #1 } } },
		{oneargsinglekeyset}{ execute={ \semantex_arg_singlekey:nn { ##1 } { #1 } } },
		{setoneargsinglekeyx}{ execute={ \semantex_arg_singlekey_x:nn { ##1 } { #1 } } },
		{oneargsinglekeysetx}{ execute={ \semantex_arg_singlekey_x:nn { ##1 } { #1 } } },
		{setargwithoutkeyval}{ execute={ \semantex_arg_without_keyval:nn { ##1 } { #1 } } },
		{argwithoutkeyvalset}{ execute={ \semantex_arg_without_keyval:nn { ##1 } { #1 } } },
		{setargwithoutkeyvalx}{ execute={ \semantex_arg_without_keyval:nx { ##1 } { #1 } } },
		{argwithoutkeyvalsetx}{ execute={ \semantex_arg_without_keyval:nx { ##1 } { #1 } } },
		{default}{s={#1}},
		{-withothersep}{slotwithothersep={#1}},
		{...withothersep}{dotswithothersep={#1}},
		{s}{
			execute={
				\semantex_data_bool_get:nnTF { ##1 } { nextargwithsep }
				{
					\semantex_data_tl_put_right:nnx { ##1 } { arg }
					{
						\semantex_data_tl_get_exp_not:nn { ##1 } { argsep }
					}
				}
				{
					% do nothing
				}
				\semantex_data_tl_put_right:nnn { ##1 } { arg } { #1 }
				\semantex_data_int_incr:nn { ##1 } { numberofarguments }
				\semantex_data_bool_set_true:nn { ##1 } { nextargwithsep }
			}
		},
		{c}{
			execute={
				\semantex_data_bool_get:nnTF { ##1 } { nextargwithsep }
				{
					\semantex_data_tl_put_right:nnn { ##1 } { arg } { , #1 }
				}
				{
					\semantex_data_tl_put_right:nnn { ##1 } { arg } { #1 }
				}
				\semantex_data_int_incr:nn { ##1 } { numberofarguments }
				\semantex_data_bool_set_true:nn { ##1 } { nextargwithsep }
			}
		},
		{dotswithothersep}{
			execute={
				\semantex_arg_valuekey:nnx { ##1 } { othersep }
				{
					{ \exp_not:n { #1 } }
					{ \semantex_data_tl_get_exp_not:nn { ##1 } { argdots } }
				}
			},
		},
		{slotwithothersep}{
			execute={
				\semantex_arg_valuekey:nnx { ##1 } { othersep }
				{
					{ \exp_not:n { #1 } }
					{ \semantex_data_tl_get_exp_not:nn { ##1 } { argslot } }
				}
			},
		},
	},
	defineargkeys={
		{dots}{
			execute={
				\semantex_arg_valuekey:nnx { ##1 } { s }
				{
					\semantex_data_tl_get_exp_not:nn { ##1 } { argdots }
				}
			},
		},
		{...}{dots},
		{cdots}{
			execute={
				\semantex_arg_valuekey:nnx { ##1 } { c }
				{
					\semantex_data_tl_get_exp_not:nn { ##1 } { argdots }
				}
			},
		},
		{c...}{cdots},
		{slot}{
			execute={
				\semantex_arg_valuekey:nnx { ##1 } { s }
				{
					\semantex_data_tl_get_exp_not:nn { ##1 } { argslot }
				}
			},
		},
		{-}{slot},
		{cslot}{
			execute={
				\semantex_arg_valuekey:nnx { ##1 } { c }
				{
					\semantex_data_tl_get_exp_not:nn { ##1 } { argslot }
				}
			},
		},
		{c-}{cslot},
	},
	defineargkeys[2]={
		{othersep}{
			execute={
				\semantex_data_bool_get:nnTF { ##1 } { nextargwithsep }
				{
					\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 } { numberofarguments }
				\semantex_data_bool_set_true:nn { ##1 } { nextargwithsep }
			},
		},
	},
]

\cs_set_eq:NN\__semantex_old_version_of_semantex_new_object_of_class_SemantexBaseObject:Nw \__semantex_new_object_of_class_SemantexBaseObject:Nw

\cs_set_protected:Npn \__semantex_new_object_of_class_SemantexBaseObject:Nw#1
{
	\msg_error:nnn { semantex } { created_a_SemantexBaseObject } { #1 }
	\__semantex_old_version_of_semantex_new_object_of_class_SemantexBaseObject:Nw #1
}


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

\ProcessKeysOptions { semantex }

% ... and they lived happily ever after.