\RequirePackage{expl3,xparse}
\ProvidesExplPackage{semantex}{2020/07/21}{0.3alpha}{}


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


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


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

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

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

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

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

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

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

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

\msg_new:nnnn { semantex } { 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 } { 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~\SemantexBaseObject;~create~a~new~class~yourself~instead.~You~created~the~object~#1~on~line~\msg_line_number: } {}

\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: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:nnnnn { nnxnn }

\cs_generate_variant:Nn \msg_error:nnnn { nnxn }

\cs_generate_variant:Nn \msg_error:nnn { nnx }

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%    COMMANDS FOR BULLETS AND SLOTS
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


\box_new:N \l__semantex_bullet_box
\hbox_set:Nn \l__semantex_bullet_box { $\cdot$ }
\box_scale:Nnn \l__semantex_bullet_box {1.2} {1.2}
\tl_set:Nn\g_semantex_bullet
{
	\box_move_up:nn{-0.25ex}{\box_use:N \l__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

\tl_set:Nn \g_semantex_slot { \mathord{-} }

\tl_set_eq:NN \SemantexSlot \g_semantex_slot

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

\DeclareDocumentCommand\semantex_new_plain_class:Nw{mO{}} % new simple-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}{m}{
		% the actual \#1 command
		\semantex_render_class:Nn #1 {
			\semantex_class_set_symbol:Nn #1 { ##1 }
		}
	}
	\exp_args:Nc\DeclareDocumentCommand{__semantex_make_object_of_class_\cs_to_str:N #1_with_options:nnw}{mm}{
		\semantex_render_class:Nn #1 {
			\semantex_class_set_symbol:Nn #1 { ##2 }
			##1
		}
	}
	\exp_args:Nc\DeclareDocumentCommand{__semantex_new_object_of_class_\cs_to_str: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_render_object:Nn ##1 { }
		}
	}
}

\tl_set_eq:NN\NewPlainClass\semantex_new_plain_class:Nw

\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 } }
	%\semantex_new_class:Nn { #1 } { #2 }
	\DeclareDocumentCommand{#1}{mo}{
		% the actual \#1 command
		\IfValueTF{##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_render_class:Nn #1 {
				\semantex_class_set_symbol:Nn #1 { ##1 }
			}
		}
	}
	\exp_args:Nc\DeclareDocumentCommand{__semantex_make_object_of_class_\cs_to_str:N #1_with_options:nnw}{mmo}{
		\IfValueTF{##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_render_class:Nn #1 {
				\semantex_class_set_symbol:Nn #1 { ##2 }
				##1
			}
		}
	}
	\exp_args:Nc\DeclareDocumentCommand{__semantex_new_object_of_class_\cs_to_str: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_render_object:Nn ##1 {
					\semantex_object_do_output:N ##1
					\semantex_object_set_keys:Nn ##1 { ####1 }
				}
			}
			{
				\semantex_render_object:Nn ##1 { }
			}
		}
	}
}

\tl_set_eq:NN\NewSimpleClass\semantex_new_simple_class:Nw

%IM Consider using \semantexIfNoValueOrDotTF on the argument

\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_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_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_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_render_class:Nn #1 {
						\semantex_class_set_symbol:Nn #1 { ##1 }
					}
				}
			}
	}
	\exp_args:Nc\DeclareDocumentCommand{__semantex_make_object_of_class_\cs_to_str:N #1_with_options:nnw}{mmog}{
		\IfValueTF { ##3 }
		{
			\IfValueTF { ##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_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_class_do_output:N #1
					\semantex_class_set_symbol:Nn #1 { ##2 }
					##1
					\semantex_class_set_arg:Nn #1 { ##4 }
				}
			}
			{
				\semantex_render_class:Nn #1 {
					\semantex_class_set_symbol:Nn #1 { ##2 }
					##1
				}
			}
		}
	}
	\exp_args:Nc\DeclareDocumentCommand{__semantex_new_object_of_class_\cs_to_str: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_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_render_object:Nn ##1 {
						\semantex_object_do_output:N ##1
						\semantex_object_set_keys:Nn ##1 { ####1 }
					}
				}
			}
			{
				\IfValueTF{####2}
				{
					\semantex_render_object:Nn ##1 {
						\semantex_object_do_output:N ##1
						\semantex_object_set_arg:Nn ##1 { ####2 }
					}
				}
				{
					\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 }
			{
				\tl_if_eq:nnTF { ##3 }{ * }
				{
					\IfValueTF { ##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_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
						}
					}	
				}
				{
					\tl_if_eq:nnTF { ##3 }{ ** }
					{
						\IfValueTF { ##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_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_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_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_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_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 }
			{
				\tl_if_eq:nnTF { ##3 }{ * }
				{
					\IfValueTF { ##4 }
					{
						\semantex_render_class:Nn #1 {
							\semantex_class_do_output:N #1
							\semantex_class_set_symbol:N #1 { ##1 }
							\semantex_class_use_bullet:N #1
							\semantex_class_set_arg:Nn #1 { ##4 }
						}
					}
					{
						\semantex_render_class:Nn #1 {
							\semantex_class_do_output:N #1
							\semantex_class_set_symbol:N #1 { ##1 }
							\semantex_class_use_bullet:N #1
						}
					}
				}
				{
					\tl_if_eq:nnTF { ##3 }{ ** }
					{
						\IfValueTF { ##4 }
						{
							\semantex_render_class:Nn #1 {
								\semantex_class_do_output:N #1
								\semantex_class_set_symbol:N #1 { ##1 }
								\semantex_class_use_double_bullet:N #1
								\semantex_class_set_arg:Nn #1 { ##4 }
							}
						}
						{
							\semantex_render_class:Nn #1 {
								\semantex_class_do_output:N #1
								\semantex_class_set_symbol:N #1 { ##1 }
								\semantex_class_use_double_bullet:N #1
							}
						}
					}
					{
						\IfValueTF { ##4 }
						{
							\semantex_render_class:Nn #1 {
								\semantex_class_do_output:N #1
								\semantex_class_set_symbol:N #1 { ##1 }
								\semantex_class_set_degreedefault:Nn #1 { ##3 }
								\semantex_class_set_arg:Nn #1 { ##4 }
							}
						}
						{
							\semantex_render_class:Nn #1 {
								\semantex_class_do_output:N #1
								\semantex_class_set_symbol:N #1 { ##1 }
								\semantex_class_set_degreedefault:Nn #1 { ##3 }
							}
						}
					}
				}
			}
			{
				\IfValueTF { ##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_render_class:Nn #1 {
						\semantex_class_set_symbol:Nn #1 { ##1 }
					}
				}
			}
		}
	}
	\exp_args:Nc\DeclareDocumentCommand{__semantex_make_object_of_class_\cs_to_str:N #1_with_options:nnw}{mmogg}{
		\IfValueTF{##3}
		{
			\IfValueTF { ##4 }
			{
				\tl_if_eq:nnTF { ##4 }{ * }
				{
					\IfValueTF { ##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_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
						}
					}
				}
				{
					\tl_if_eq:nnTF { ##4 }{ ** }
					{
						\IfValueTF { ##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_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_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_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_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_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 }
			{
				\tl_if_eq:nnTF { ##4 }{ * }
				{
					\IfValueTF { ##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_render_class:Nn #1 {
							\semantex_class_do_output:N #1
							\semantex_class_set_symbol:Nn #1 { ##2 }
							##1
							\semantex_class_use_bullet:N #1
						}
					}
				}
				{
					\tl_if_eq:nnTF { ##4 }{ ** }
					{
						\IfValueTF { ##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_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_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_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_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_render_class:Nn #1 {
						\semantex_class_set_symbol:Nn #1 { ##2 }
						##1
					}
				}
			}
		}
	}
	\exp_args:Nc\DeclareDocumentCommand{__semantex_new_object_of_class_\cs_to_str: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}
				{
					\tl_if_eq:nnTF { ####2 } { * }
					{
						\IfValueTF{####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_render_object:Nn ##1 {
								\semantex_object_do_output:N ##1
								\semantex_object_set_keys:Nn ##1 { ####1 }
								\semantex_object_use_bullet:N ##1
							}
						}
					}
					{
						\tl_if_eq:nnTF { ####2 } { ** }
						{
							\IfValueTF{####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_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_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_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_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_render_object:Nn ##1 {
							\semantex_object_do_output:N ##1
							\semantex_object_set_keys:Nn ##1 { ####1 }
						}
					}
				}
			}
			{
				\IfValueTF{####2}
				{
					\tl_if_eq:nnTF { ####2 } { * }
					{
						\IfValueTF{####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_render_object:Nn ##1 {
								\semantex_object_do_output:N ##1
								\semantex_object_use_bullet:N ##1
							}
						}
					}
					{
						\tl_if_eq:nnTF { ####2 } { ** }
						{
							\IfValueTF{####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_render_object:Nn ##1 {
									\semantex_object_do_output:N ##1
									\semantex_object_use_double_bullet:N ##1
								}
							}
						}
						{
							\IfValueTF{####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_render_object:Nn ##1 {
									\semantex_object_do_output:N ##1
									\semantex_object_set_degreedefault:Nn ##1 { ####2 }
								}
							}
						}
					}
				}
				{
					\IfValueTF{####3}
					{
						\semantex_render_object:Nn ##1 {
							\semantex_object_do_output:N ##1
							\semantex_object_set_arg:Nn ##1 { ####3 }
						}
					}
					{
						\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_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_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_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_render_class:Nn #1 {
					\semantex_class_set_symbol:Nn #1 { ##1 }
				}
			}
		}
	}
	% the actual \#1 command
	\exp_args:Nc\DeclareDocumentCommand{__semantex_make_object_of_class_\cs_to_str:N #1_with_options:nnw}{mmog}
	{
		\IfValueTF { ##3 }
		{
			\IfValueTF { ##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_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_class_do_output:N #1
					\semantex_class_set_symbol:Nn #1 { ##2 }
					##1
					\semantex_class_set_arg:Nn #1 { ##4 }
				}
			}
			{
				\semantex_render_class:Nn #1 {
					\semantex_class_set_symbol:Nn #1 { ##2 }
					##1
				}
			}
		}
	}
	\exp_args:Nc\DeclareDocumentCommand{__semantex_new_object_of_class_\cs_to_str: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_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_render_object:Nn ##1 {
						\semantex_object_do_output:N ##1
						\semantex_object_set_keys:Nn ##1 { ####1 }
					}
				}
			}
			{
				\IfValueTF { ####2 }
				{
					\semantex_render_object:Nn ##1 {
						\semantex_object_do_output:N ##1
						\semantex_object_set_arg:Nn ##1 { ####2 }
					}
				}
				{
					\semantex_render_object:Nn ##1 { }
				}
			}
		}
	}
}

\cs_set_eq:NN\NewDelimiterClass\semantex_new_delimiter_class:Nw

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

\cs_new:Npn\NewObject#1
{
	\cs_if_exist_use:cF { __semantex_new_object_of_class_\cs_to_str:N#1:Nw }
	{
		\msg_error:nnnn { semantex } { created_object_of_unknown_class } { #1 }
	}
}

\cs_new:Npn \__semantex_new_class_or_object:nn#1#2
{
	% create new object
	% #1 = name of command, without backslash
	% #2 = standard keyval setup

	\semantex_data_tl_provide:nn { #1 } { parent }

	\semantex_data_tl_set:nnn { #1 } { parent } { class_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 } }

	% 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_set:cpn { __semantex_data_cs_#1_outputoptions:n } ##1 {}
	
	\cs_set:cpn { __semantex_data_cs_#1_parseoptions:n } ##1 {}
	
	% This is used to set up the class/object when creating it
	#2
}

\cs_generate_variant:Nn \__semantex_new_class_or_object:nn { xn }

\cs_new:Npn \semantex_new_class:Nn#1#2{
	% create a new class
	% #1 = name of class
	% #2 = standard keyval setup; the parent class by default is SemantexBaseObject
	\semantex_class_if_exist:NTF #1
	{
		\msg_error:nnn { semantex } { class_already_defined } { #1 }
	}
	{
		\semantex_class_register:N #1
		\__semantex_new_class_or_object:xn { class_\cs_to_str:N #1 } { #2 }
	}
}

\cs_set:Npn \semantex_new_object:NNn#1#2#3
{
	\semantex_object_if_exist:NTF #2
	{
		\msg_error:nnn { semantex } { object_already_defined } { #2 }
	}
	{
		\semantex_object_register:N #2
		\__semantex_new_class_or_object:xn { object_\cs_to_str:N #2 } {
			%class=#1, #3
			\semantex_object_set_class:Nn #2 { #1 }
			#3
		}
	}
}

% The following commands are used in the code for creating class types:

\cs_set:Npn\semantex_class_set_symbol:Nn#1#2
{
	%\semantex_data_tl_set:xnn { class_\cs_to_str:N#1 } { symbol } { #2 }
	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_symbol:xn { class_\cs_to_str:N #1 } { #2 }
}

\cs_set:Npn\semantex_object_set_symbol:Nn#1#2
{
	%\semantex_data_tl_set:xnn { object_\cs_to_str:N#1 } { symbol } { #2 }
	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_symbol:xn { object_\cs_to_str:N #1 } { #2 }
}

\cs_set:Npn\semantex_class_do_output:N#1
{
	\semantex_data_bool_set_true:xn { class_\cs_to_str:N#1 } { output }
}

\cs_set:Npn\semantex_object_do_output:N#1
{
	\semantex_data_bool_set_true:xn { object_\cs_to_str:N#1 } { output }
}

\cs_set:Npn\semantex_class_set_keys:Nn#1#2
{
	\semantex_keys_set:xn { class_\cs_to_str:N #1 } { #2 }
}

\cs_set:Npn\semantex_object_set_keys:Nn#1#2
{
	\semantex_keys_set:xn { object_\cs_to_str:N #1 } { #2 }
}

\cs_set:Npn\semantex_class_set_arg:Nn#1#2
{
	\semantex_valuekey:xnn { class_\cs_to_str:N#1 } { arg } { #2 }
}

\cs_set:Npn\semantex_object_set_arg:Nn#1#2
{
	\semantex_valuekey:xnn { object_\cs_to_str:N#1 } { arg } { #2 }
}

\cs_set:Npn\semantex_class_set_degreedefault:Nn#1#2
{
	\semantex_valuekey:xnn { class_\cs_to_str:N#1 } { degreedefault } { #2 }
	% should there be \exp_not:n around #2? Probably not, based on the above
}

\cs_set:Npn\semantex_object_set_degreedefault:Nn#1#2
{
	\semantex_valuekey:xnn { object_\cs_to_str:N#1 } { degreedefault } { #2 }
	% should there be \exp_not:n around #2? Probably not, based on the above
}

\cs_set:Npn\semantex_class_use_bullet:N#1
{
	\semantex_singlekey:xn { class_\cs_to_str:N#1 } { * }
}

\cs_set:Npn\semantex_object_use_bullet:N#1
{
	\semantex_singlekey:xn { object_\cs_to_str:N#1 } { * }
}

\cs_set:Npn\semantex_class_use_double_bullet:N#1
{
	\semantex_singlekey:xn { class_\cs_to_str:N#1 } { * }
}

\cs_set:Npn\semantex_object_use_double_bullet:N#1
{
	\semantex_singlekey:xn { object_\cs_to_str:N#1 } { * }
}

\cs_set:Npn\semantex_class_set_leftpar:Nn#1#2
{
	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_leftpar:xn { class_\cs_to_str:N#1 } { #2 }
}

\cs_set:Npn\semantex_object_set_leftpar:Nn#1#2
{
	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_leftpar:xn { object_\cs_to_str:N#1 } { #2 }
}

\cs_set:Npn\semantex_class_set_rightpar:Nn#1#2
{
	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_rightpar:xn { class_\cs_to_str:N#1 } { #2 }
}

\cs_set:Npn\semantex_object_set_rightpar:Nn#1#2
{
	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_rightpar:xn { object_\cs_to_str:N#1 } { #2 }
}

\cs_set:Npn\semantex_object_set_class:Nn#1#2
{
	\semantex_data_class_set:xn { object_\cs_to_str:N #1 } { #2 }
}

\seq_new:N \g__semantex_all_classes_seq % a register for all objects created

\cs_new:Npn\semantex_class_register:N#1
{
	\seq_put_right:Nx\g__semantex_all_classes_seq { class_\cs_to_str:N #1 }
}

\cs_new:Npn\semantex_class_if_exist:NTF#1#2#3
{
	\seq_if_in:NxTF\g__semantex_all_classes_seq { class_\cs_to_str:N#1 } { #2 } { #3 }
}

\seq_new:N \g__semantex_all_objects_seq % a register for all objects created

\cs_new:Npn\semantex_object_register:N#1
{
	\seq_put_right:Nx\g__semantex_all_objects_seq { object_\cs_to_str:N #1 }
}

\cs_new:Npn\semantex_object_if_exist:NTF#1#2#3
{
	\seq_if_in:NxTF\g__semantex_all_objects_seq { object_\cs_to_str:N#1 } { #2 } { #3 }
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%    COMMANDS FOR RENDERING OBJECTS AND CLASSES
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\cs_generate_variant:Nn\tl_if_blank:nTF { xTF }

\cs_new_protected:Npn \__semantex_render:nn#1#2
{
	% the main command for rendering a class/object
	% #1 = name of object
	% #2 = options
	\group_begin:
		\semantex_provide_user_commands:n { #1 }
		\semantex_data_tl_inherit:nn { #1 } { symbol } % Inherit the symbol from parent if not done already
		%\semantex_keys_set:nn { #1 } { #2 } % Setup the keys
		#2
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_parse:nn { #1 } { } % Run the "parse" routine, i.e. the collection of code that the user has added to the parse register
		\semantex_data_bool_get:nnTF { #1 } { output } % Checks if the object/class is supposed to output
		{
			\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_innerreturn:nn { #1 }{}
			\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_data_cs_custom_valuekey_class_SemantexBaseObject_leftreturn:nn { #1 }{}
				}
				{
					\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_rightreturn:nn { #1 }{}
				}
			}
			{
				% do nothing
			}
			\tl_set:Nx\l__semantex_render_symbol_temp { \semantex_data_tl_get:nn { #1 } { symbol } } % Stores the symbol in a temporary command
			\tl_set:Nx \l__semantex_render_temp
			{
				\exp_not:c {
					__semantex_make_object_of_\semantex_data_tl_get:nn { #1 } { output }_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 parse options to it
				{
					\exp_not:N\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upperputleft:nn { \semantex_data_tl_get:nn { #1 } { output } } { \semantex_data_tl_get_exp_not:nn { #1 } { upper } }
					\exp_not:N\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lowerputleft:nn { \semantex_data_tl_get:nn { #1 } { output } } { \semantex_data_tl_get_exp_not:nn { #1 } { lower } }
					\exp_not:N\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upperleftputright:nn { \semantex_data_tl_get:nn { #1 } { output } } { \semantex_data_tl_get_exp_not:nn { #1 } { upperleft } }
					\exp_not:N\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lowerleftputright:nn { \semantex_data_tl_get:nn { #1 } { output } } { \semantex_data_tl_get_exp_not:nn { #1 } { lowerleft } }
					\exp_not:N\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_preupper:nn { \semantex_data_tl_get:nn { #1 } { output } } { \semantex_data_tl_get_exp_not:nn { #1 } { preupper } }
					\exp_not:N\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_postupper:nn { \semantex_data_tl_get:nn { #1 } { output } } { \semantex_data_tl_get_exp_not:nn { #1 } { postupper } }
					\exp_not:N\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_prelower:nn { \semantex_data_tl_get:nn { #1 } { output } } { \semantex_data_tl_get_exp_not:nn { #1 } { prelower } }
					\exp_not:N\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_postlower:nn { \semantex_data_tl_get:nn { #1 } { output } } { \semantex_data_tl_get_exp_not:nn { #1 } { postlower } }
					\exp_not:N\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_preupperleft:nn { \semantex_data_tl_get:nn { #1 } { output } } { \semantex_data_tl_get_exp_not:nn { #1 } { preupperleft } }
					\exp_not:N\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_postupperleft:nn { \semantex_data_tl_get:nn { #1 } { output } } { \semantex_data_tl_get_exp_not:nn { #1 } { postupperleft } }
					\exp_not:N\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_prelowerleft:nn { \semantex_data_tl_get:nn { #1 } { output } } { \semantex_data_tl_get_exp_not:nn { #1 } { prelowerleft } }
					\exp_not:N\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_postlowerleft:nn { \semantex_data_tl_get:nn { #1 } { output } } { \semantex_data_tl_get_exp_not:nn { #1 } { postlowerleft } }
					\exp_not:N\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_texclass:nn { \semantex_data_tl_get:nn { #1 } { output } } { \semantex_data_tl_get:nn { #1 } { texclass } }
					%\exp_not:N\semantex_keys_set:nn { \semantex_data_tl_get:nn { #1 } { output } } { \semantex_data_tl_get_exp_not:nn { #1 } { outputoptions } }
					%\semantex_data_tl_get_exp_not:nn { #1 } { outputoptions }
					%\exp_not:c
%					\exp_args:Nc\exp_not:N
%					{ __semantex_data_cs_#1_outputoptions:n } { 
%						\semantex_data_tl_get:nn { #1 } { output }
%					}
%					\semantex_data_cs_get_exp_not:nn { #1 } { outputoptions:n } { \semantex_data_tl_get:nn { #1 } { output } }
					\semantex_data_cs_get:nn { #1 } { outputoptions:n } { \semantex_data_tl_get:nn { #1 } { output } }
					% These are the options we parse to our object -- this is all
					% information that we pass on to the output class so that it
					% can eventually render it
				}
				{ \exp_not:V \l__semantex_render_symbol_temp }
			}
		}
		{
			\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_return:nn { #1 }{} % Returns the object/class, i.e. adds all remaining indices and arguments to it
			\tl_if_blank:xTF { \semantex_data_tl_get: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_symbol_temp { \semantex_data_tl_get:nn { #1 } { symbol } }
			}
			{
				\tl_set:Nx\l__semantex_render_symbol_temp { \semantex_data_tl_get:nn { #1 } { texclass } { \semantex_data_tl_get:nn { #1 } { symbol } } }
			}
			\tl_set:Nx\l__semantex_render_temp {
				\exp_not:V \l__semantex_render_symbol_temp
			}
		}
	\exp_last_unbraced:NV
	\group_end:
	\l__semantex_render_temp % This neat trick allows outputting to different classes to work as expected
}

%\cs_generate_variant:Nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upperputleft:nn { nx }
%\cs_generate_variant:Nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lowerputleft:nn { nx }
%\cs_generate_variant:Nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upperleftputright:nn { nx }
%\cs_generate_variant:Nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lowerleftputright:nn { nx }
%\cs_generate_variant:Nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_preupper:nn { nx }
%\cs_generate_variant:Nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_postupper:nn { nx }
%\cs_generate_variant:Nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_prelower:nn { nx }
%\cs_generate_variant:Nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_postlower:nn { nx }
%\cs_generate_variant:Nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_preupperleft:nn { nx }
%\cs_generate_variant:Nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_postupperleft:nn { nx }
%\cs_generate_variant:Nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_prelowerleft:nn { nx }
%\cs_generate_variant:Nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_postlowerleft:nn { nx }
%\cs_generate_variant:Nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_texclass:nn { nx }

\cs_generate_variant:Nn \__semantex_render:nn { xn }

\cs_set:Npn\semantex_render_class:Nn#1#2 % a front-end command
{
	\__semantex_render:xn { class_\cs_to_str:N #1 } { #2 }
}

\cs_set:Npn\semantex_render_object:Nn#1#2
{
	\__semantex_render:xn { object_\cs_to_str: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
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


\tl_new:N\SemantexDelimiterSize

%%So far, this is experimental:
%%\makeatletter %this part requires amsmath
%\tl_set:Nn\semantexnormalscaling{\bBigg@{0.8}}
%\tl_set:Nn\semantexnormalscalingl{\mathopen\semantexnormalscaling}
%\tl_set:Nn\semantexnormalscalingr{\mathclose\semantexnormalscaling}
%\tl_set:Nn\semantexnormalscalingm{\mathrel\semantexnormalscaling}
%%\makeatother

\cs_new:Npn \__semantex_parentheses_normal:nnn#1#2#3
{
	\group_begin:
	%\semantexnormalscalingl#2 #4 #5 #6 \semantexnormalscalingr#3
	\mathopen#1 #3 \mathclose#2
	\group_end:
}

\cs_new:Npn \__semantex_parentheses_auto:nnn#1#2#3
{
	\group_begin:
	\tl_set:Nn\SemantexDelimiterSize{\middle}
	%\tl_set_eq:NN\SemantexDelimiterSize\middle
	\mathopen{}\mathclose\bgroup\left#1
	#3
	\aftergroup\egroup\right#2
	\group_end:
}


\cs_new:Npn \__semantex_parentheses_other:nnnn#1#2#3#4
{
	\group_begin:
	\tl_set_eq:NN\SemantexDelimiterSize#4
	%\tl_set:Nx\SemantexDelimiterSize{\exp_not:N#1}
	\mathopen#4#1 #3 \mathclose#4#2
	\group_end:
}


\cs_generate_variant:Nn \str_case:nnF { xnF }

\cs_new:Npn \__semantex_parentheses_store:nnnnN#1#2#3#4#5
% The central command handling the rendering of argument parentheses
{
	\tl_set:Nx#5
	{
		{ #2 }
		{ #3 }
		{ #4 }
	}
	\str_case:xnF { #1 } % This is where \big,\Big, etc. go. To my surprise, an x-type expansion did not cause any issues with this
	{
		{ normal } {
			\tl_put_left:Nn#5
			{
				\exp_not:N
				\__semantex_parentheses_normal:nnn
			}
		}
		{ auto } {
			\tl_put_left:Nn#5
			{
				\exp_not:N
				\__semantex_parentheses_auto:nnn
			}
		}
		{ * } {
			\tl_put_left:Nn#5
			{
				\exp_not:N
				\__semantex_parentheses_auto:nnn
			}
		}
	}
	{
		\tl_put_right:Nx#5
		{
			{ \exp_not:V #1 }
		}
		\tl_put_left:Nn#5
		{
			\exp_not:N
			\__semantex_parentheses_other:nnnn
		}
	}
}

\cs_new:Npn \__semantex_no_parentheses:n#1
{
		\group_begin:
		\tl_clear:N\SemantexDelimiterSize
		#1
		\group_end:
}

\cs_new: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
	{
		{ #1 }
	}
	\tl_put_left:Nn#2
	{
		\exp_not:N
		\__semantex_no_parentheses:n
	}
}

\cs_new:Npn \__semantex_symbol_parentheses_normal:nnn#1#2#3
{
	\mathopen#1 #3 \mathclose#2
}

\cs_new:Npn \__semantex_symbol_parentheses_auto:nnn#1#2#3
{
	\mathopen{}\mathclose\bgroup\left#1
	#3
	\aftergroup\egroup\right#2
}


\cs_new:Npn \__semantex_symbol_parentheses_other:nnnn#1#2#3#4
{
	\mathopen#4#1 #3 \mathclose#4#2
}


\cs_new:Npn \__semantex_symbol_parentheses_store:nnnnN#1#2#3#4#5
% The central command handling the rendering of symbol parentheses
{
	\tl_set:Nx#5
	{
		{ #2 }
		{ #3 }
		{ #4 }
	}
	\str_case:xnF { #1 } % This is where \big,\Big, etc. go. To my surprise, an x-type expansion did not cause any issues with this
	{
		{ normal } {
			\tl_put_left:Nn#5
			{
				\exp_not:N
				\__semantex_symbol_parentheses_normal:nnn
			}
		}
		{ auto } {
			\tl_put_left:Nn#5
			{
				\exp_not:N
				\__semantex_symbol_parentheses_auto:nnn
			}
		}
		{ * } {
			\tl_put_left:Nn#5
			{
				\exp_not:N
				\__semantex_symbol_parentheses_auto:nnn
			}
		}
	}
	{
		\tl_put_right:Nx#5
		{
			{ \exp_not:V #1 }
		}
		\tl_put_left:Nn#5
		{
			\exp_not:N
			\__semantex_symbol_parentheses_other:nnnn
		}
	}
}




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

%--------------------------------------------
% Commands to modify and obtain data

%\cs_new:Npn \semantex_data_tl_get_proto:nnn#1#2#3
%{
%	% #1 = name of object
%	% #2 = the data to get
%	% #3 = also the name of object, but being stored 
%	% 	   when passing to the parent, in order to make
%	%	   error messages meaningful
%	\tl_if_exist:cTF { g__semantex_data_tl_#1_#2 }
%	{
%		\use:c { g__semantex_data_tl_#1_#2 }
%	}
%	{
%		\tl_if_eq:nnTF { #1 } { SemantexBaseObject }
%		{
%			\msg_error:nnnn { semantex } { data_tl_not_found } { #2 } { #3 }
%		}
%		{
%			\semantex_data_tl_get_proto:nnn { \semantex_data_tl_get:nn { #1 } { parent } } { #2 } { #1 }
%		}
%	}
%}
%
%\cs_new:Npn \semantex_data_tl_get:nn#1#2
%{
%	\semantex_data_tl_get_proto:nnn { #1 } { #2 } { #1 }
%}



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

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

\cs_new:Npn \semantex_data_parent_set:nn#1#2 
{
	\semantex_class_if_exist:NTF { #2 }
	{
		\tl_set:cx { g__semantex_data_tl_#1_parent } { class_\cs_to_str:N#2 }
	}
	{
		\semantex_error_output_format:nN { #1 } \l__semantex_data_parent_set_temp_tl
		\msg_error:nnxnn { semantex } { class_not_found } { \l__semantex_data_parent_set_temp_tl } { parent } { #2 }
	}
}

\cs_new:Npn \semantex_data_class_set:nn#1#2 
{
	\semantex_class_if_exist:NTF { #2 }
	{
		\tl_set:cx { g__semantex_data_tl_#1_parent } { class_\cs_to_str:N#2 }
	}
	{
		\semantex_error_output_format:nN { #1 } \l__semantex_data_class_set_temp_tl
		\msg_error:nnxnn { semantex } { class_not_found } { \l__semantex_data_class_set_temp_tl } { class } { #2 }
	}
}

\cs_generate_variant:Nn \semantex_data_class_set:nn { xn }

\cs_new:Npn \semantex_data_copy_object:nn#1#2 
{
	\semantex_object_if_exist:NTF { #2 }
	{
		\tl_set:cx { g__semantex_data_tl_#1_parent } { object_\cs_to_str:N#2 }
	}
	{
		\semantex_error_output_format:nN { #1 } \l__semantex_data_copy_object_temp_tl
		\msg_error:nnxnn { semantex } { object_not_found } { \l__semantex_data_copy_object_temp_tl } { copy } { #2 }
	}
}

\cs_new:Npn \semantex_data_clone_object:nn#1#2 
{
	\semantex_object_if_exist:NTF { #2 }
	{
		\tl_set:cx { g__semantex_data_tl_#1_parent } { object_\cs_to_str:N#2 }
	}
	{
		\semantex_error_output_format:nN { #1 } \l__semantex_data_clone_object_temp_tl
		\msg_error:nnxnn { semantex } { object_not_found } { \l__semantex_data_clone_object_temp_tl } { clone } { #2 }
	}
}

% COMMANDS FOR HANDLING DATA CONSISTING OF COMMAND SEQUENCES:

\cs_new:Npn\semantex_data_cs_set:nnn#1#2#3
{
	\cs_set:cn { __semantex_data_cs_#1_#2 } { #3 }
}

\cs_generate_variant:Nn \cs_set:Nn { cn }

\cs_generate_variant:Nn \semantex_data_cs_set:nnn { nno , nnV , nnv }

\cs_new:Npn\semantex_data_cs_get:nn#1#2
{
	% #1 = name of the object
	% #2 = command sequence to get
	\cs_if_exist:cTF { __semantex_data_cs_#1_#2 }
	{
		\use:c { __semantex_data_cs_#1_#2 }
	}
	{
		\str_if_eq:nnTF { #1 } { class_SemantexVariable }
		{
			% should probably throw an error by now, but later!
		}
		{
			\semantex_data_cs_get:fn { \semantex_data_parent_get:n {#1} } { #2 }
		}
	}
}

\cs_generate_variant:Nn \semantex_data_cs_get:nn { fn }

\cs_new:Npn\semantex_data_cs_get_exp_not:nn#1#2
{
	% #1 = name of the object
	% #2 = command sequence to get
	\cs_if_exist:cTF { __semantex_data_cs_#1_#2 }
	{
		\exp_not:c { __semantex_data_cs_#1_#2 }
	}
	{
		\str_if_eq:nnTF { #1 } { class_SemantexVariable }
		{
			% should probably throw an error by now, but later!
		}
		{
			\semantex_data_cs_get_exp_not:fn { \semantex_data_parent_get:n {#1} } { #2 }
		}
	}
}

\cs_generate_variant:Nn \semantex_data_cs_get_exp_not:nn { fn }

\cs_new:Npn\semantex_data_cs_clear:nn#1#2
{
	\cs_set:cn { __semantex_data_cs_#1_#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_generate_variant:Nn \str_if_eq:nnTF { fnTF }

\cs_generate_variant:Nn \tl_if_eq:nnTF { fnTF }

\cs_new:Npn \__semantex_data_tl_get_auxiliary:nnn#1#2#3
{
	% #1 = name of class/object
	% #2 = the data to get
	% #3 = the original class/object, 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 } % Apparently, f-type expansion seemed to work here for once
		{
			\semantex_error_output_format:nN { #3 } \l__semantex_data_tl_get_auxiliary_temp_tl
			\msg_error:nnxn { semantex } { data_tl_not_found } { \l__semantex_data_tl_get_auxiliary_temp_tl } { #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 object
%	% #2 = the data to get
%	\tl_if_exist:cTF { g__semantex_data_tl_#1_#2 }
%	{
%		\exp_not:v { g__semantex_data_tl_#1_#2 }
%	}
%	{
%		\semantex_data_tl_get:nn { \semantex_data_parent_get:n { #1 } } { #2 }
%	}
%}

\cs_new:Npn \semantex_data_tl_get_exp_not:nn#1#2
{
	% #1 = name of object
	% #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 class/object
	% #2 = the data to get
	% #3 = the original class/object, 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 } % Apparently, f-type expansion seemed to work here for once
		{
			\semantex_error_output_format:nN { #3 } \l__semantex_data_tl_get_exp_not_auxiliary_temp_tl
			\msg_error:nnxn { semantex } { data_tl_not_found } { \l__semantex_data_tl_get_exp_not_auxiliary_temp_tl } { #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:Npn \semantex_data_tl_get_store:nnN#1#2#3% maybe should be PROTECTED??
{
	% #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:Npn \__semantex_data_tl_get_store_auxiliary:nnNn#1#2#3#4% maybe should be PROTECTED??
{
	% #1 = name of object
	% #2 = the data to get
	% #3 = where to store it
	\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 }
		{
			\semantex_error_output_format:nN { #4 } \l__semantex_data_tl_get_store_auxiliary_temp_tl
			\msg_error:nnxn { semantex } { data_tl_not_found } { \l__semantex_data_tl_get_store_auxiliary_temp_tl } { #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:Npn\semantex_data_tl_provide:nn#1#2
{
	\tl_if_exist:cF { g__semantex_data_tl_#1_#2 }
	{
		\tl_set:cn { g__semantex_data_tl_#1_#2 } {}
	}
}

\cs_new:Npn\semantex_data_tl_inherit:nn#1#2
{
	% #1 = object
	% #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_set_eq:NN\semantex_data_tl_inherit_x:nn\semantex_data_tl_inherit:nn
	% The same as inherit; historically, this one did an x type
	% expansion first, but after changes in other places, this
	% no longer appeard to be necessary. I decided to keep up the
	% separation of the two, just in case.


\cs_new: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 , xnn , xnx }

\cs_new: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: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: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: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: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{% maybe should be PROTECTED??
	% #1 = name of object
	% #2 = the intuence to get
	% #3 = the command to store it in
	\__semantex_data_int_get_auxiliary:nnn { #1 } { #2 } { #1 }
}

\cs_new:Npn \__semantex_data_int_get_auxiliary:nnn#1#2#3{% maybe should be PROTECTED??
	% #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_use:c { g__semantex_data_int_#1_#2 }
		}
		{
			\str_if_eq:nnTF { #1 } { class_SemantexBaseObject }
			{
				\semantex_error_output_format:nN { #3 } \__semantex_data_int_get_auxiliary_temp_tl
				\msg_error:nnxn { semantex } { data_int_not_found } { \__semantex_data_int_get_auxiliary_temp_tl } { #2 }
			}
			{
				\__semantex_data_int_get_auxiliary:fnn { \semantex_data_parent_get:n { #1 } } { #2 } { #3 }
			}
		}
	}
	{
		\str_if_eq:nnTF { #1 } { class_SemantexBaseObject }
		{
			\semantex_error_output_format:nN { #3 } \__semantex_data_int_get_auxiliary_temp_tl
			\msg_error:nnxn { semantex } { data_int_not_found } { \__semantex_data_int_get_auxiliary_temp_tl } { #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:Npn \semantex_data_int_get_store:nnN#1#2#3{% maybe should be PROTECTED??
	% #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:Npn\__semantex_data_int_get_store_auxiliary:nnNn#1#2#3#4{% maybe should be PROTECTED??
	% #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_error_output_format:nN { #4 } \l__semantex_data_int_get_store_auxiliary_temp_tl
				\msg_error:nnxn { semantex } { data_int_not_found } { \l__semantex_data_int_get_store_auxiliary_temp_tl } { #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_error_output_format:nN { #4 } \l__semantex_data_int_get_store_auxiliary_temp_tl
			\msg_error:nnxn { semantex } { data_int_not_found } { \l__semantex_data_int_get_store_auxiliary_temp_tl } { #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: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: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:Npn\semantex_data_int_if_positive:nnTF#1#2#3#4
{
%	\semantex_data_int_inherit:nn { #1 } { #2 } % This should not be necessary, ubt is, for unkonwn reasons
	\int_compare:nNnTF { \semantex_data_int_get:nn { #1 } { #2 } } > { 0 } { #3 } { #4 }
}

\cs_generate_variant:Nn\semantex_data_int_if_positive:nnTF { nnT }

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

\cs_new: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_generate_variant:Nn\semantex_data_int_if_greater_than_one:nnTF { nnT }

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

\cs_new:Npn\semantex_data_int_if_greater_than:nnnTF#1#2#3#4#5
{
	\int_compare:nNnTF { \semantex_data_int_get:nn { #1 } { #2 } } > { #3 } { #4 } { #5 }
}

\cs_new:Npn\semantex_data_int_if_less_than:nnnTF#1#2#3#4#5
{
	\int_compare:nNnTF { \semantex_data_int_get:nn { #1 } { #2 } } < { #3 } { #4 } { #5 }
}

\cs_new:Npn\semantex_data_int_if_equal:nnnTF#1#2#3#4#5
{
	\int_compare:nNnTF { \semantex_data_int_get:nn { #1 } { #2 } } < { #3 } { #4 } { #5 }
}

\cs_new: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:Npn \semantex_data_seq_get_store:nnN#1#2#3{% maybe should be PROTECTED??
	% #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 { vnN, nnc, vnc } % Remove these later

\cs_new: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: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 }
		}
	}
	{
		\semantex_data_seq_get_store:nnc { \semantex_data_parent_get:n { #1 } } { #2 } { 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 }
		\seq_if_exist:cF { g__semantex_data_seq_#1_#2 } { \seq_new:c { g__semantex_data_seq_#1_#2 } }
	}
}

\cs_new: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: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 { onTF, fnTF, xnTF, vnTF, nnT }

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

\cs_new:Npn\semantex_data_bool_provide:nn#1#2
{
	% #1 = name of the object
	% #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:Npn\semantex_data_bool_set_true:nn#1#2
{
	% #1 = name of the object
	% #2 = boolean to provide
	\semantex_data_bool_provide:nn { #1 } { #2 }
	\bool_set_true:c { g__semantex_data_bool_#1_if_#2 }
}

\cs_generate_variant:Nn \semantex_data_bool_set_true:nn { xn }

\cs_new:Npn\semantex_data_bool_set_false:nn#1#2
{
	% #1 = name of the object
	% #2 = boolean to provide
	\semantex_data_bool_provide:nn { #1 } { #2 }
	\bool_set_false:c { g__semantex_data_bool_#1_if_#2 }
}

% COMMANDS FOR HANDLING COMMAND SEQUENCE DATA AND KEYVAL SYNTAX:

\cs_generate_variant:Nn \keyval_parse:NNn { cco , ccn }

\cs_new:Npn \semantex_keys_set:nn#1#2
{
	\semantex_provide_user_commands:n { #1 }
	% The central command for doing keyval setup
	% #1 = object
	% #2 = keys
	\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_new:Npn \semantex_arg_keys_set:nn#1#2
{
	% The central command for doing keyval setup for the argument
	% #1 = object
	% #2 = keys
	\keyval_parse:ccn % See last command
	{ __semantex_data_cs_#1_arg_singlekey:n }
	{ __semantex_data_cs_#1_arg_valuekey:nn }
	{ #2 }
}

\cs_generate_variant:Nn \clist_map_function:nN { nc }

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

\cs_generate_variant:Nn \semantex_keys_set:nn { xn }

\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:xn { class_\cs_to_str:N #1 }{ #2 }
	}
	{
		\semantex_error_output_format:xN { class_\cs_to_str:N #1 } \l__setup_class_temp_tl
		\msg_error:nnx { semantex } { setup_unknown_class } { \l__setup_class_temp_tl }
	}
}

\DeclareDocumentCommand\SetupObject{mm}{%
	% #1 = object
	% #2 = setup
	\semantex_object_if_exist:NTF #1
	{
		\semantex_keys_set:xn { object_\cs_to_str:N #1 }{ #2 }
	}
	{
		\semantex_error_output_format:xN { object_\cs_to_str:N #1 } \l__setup_object_temp_tl
		\msg_error:nnx { semantex } { setup_unknown_object } { \l__setup_object_temp_tl }
	}
}

\cs_new:Npn\semantex_valuekey:nnn#1#2#3
{
	\__semantex_valuekey:nnnn { #1 } { #2 } { #3 } { #1 }
}

\cs_new:Npn \__semantex_valuekey:nnnn#1#2#3#4
{
	% Takes care of valuekeys, keys taking a value
	% #1 = class/object
	% #2 = name of the key
	% #3 = value
	\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_error_output_format:nN { #4 } \l__semantex_valuekey_unknown_key_temp_tl
			\msg_error:nnxn { semantex } { valuekey_not_found } { \l__semantex_valuekey_unknown_key_temp_tl } { #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 { xnn }

\cs_new:Npn\semantex_singlekey:nn#1#2
{
	\__semantex_singlekey:nnn { #1 } { #2 } { #1 }
}

\cs_new:Npn\__semantex_singlekey:nnn#1#2#3
{
	% #1 = class/object
	% #2 = name of the key
	\cs_if_exist:cTF { \tl_to_str:n{__semantex_data_cs_custom_singlekey_#1_#2:n } }
	{
		\use:c { __semantex_data_cs_custom_singlekey_#1_#2:n } { #3 }
	}
	{
		\str_if_eq:nnTF { #1 } { class_SemantexBaseObject }
		{
			\semantex_valuekey:nnn { #3 } { default } { #2 }
			%#2
		}
		{
			\__semantex_singlekey:fnn { \semantex_data_parent_get:n { #1 } } { #2 } { #3 }
		}
	}
}

\cs_generate_variant:Nn \__semantex_singlekey:nnn { fnn }

\cs_generate_variant:Nn \semantex_singlekey:nn { xn }

\cs_new:Npn\semantex_arg_valuekey:nnn#1#2#3
{
	% CHANGE ORDER OF KEYS
	\__semantex_arg_valuekey:nnnn { #1 } { #2 } { #3 } { #1 }
}

\cs_new:Npn \__semantex_arg_valuekey:nnnn#1#2#3#4
{
	% Takes care of valuekeys, keys with a value
	% For the sake of implementation, the arguments
	% come in a strange order
	% #1 = class/object
	% #2 = name of the key
	% #3 = value of the key
	\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 }
		{
			\semantex_error_output_format:nN { #4 } \l__semantex_valuekey_unknown_arg_key_temp_tl
			\msg_error:nnxn { semantex } { arg_valuekey_not_found } { \l__semantex_valuekey_unknown_arg_key_temp_tl } { #2 }
		}
		{
			\__semantex_arg_valuekey:fnnn { \semantex_data_parent_get:n { #1 } } { #2 } { #3 } { #4 }
		}
	}
}

\cs_generate_variant:Nn \__semantex_arg_valuekey:nnnn { fnnn }

\cs_new:Npn \semantex_arg_singlekey:nn#1#2
{
	\__semantex_arg_singlekey:nnn { #1 } { #2 } { #1 }
}

\cs_new:Npn \__semantex_arg_singlekey:nnn#1#2#3
{
	% #1 = class/object
	% #2 = name of the key
	\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 }
	}
	{
		\str_if_eq:nnTF { #1 } { class_SemantexBaseObject }
		{
			\semantex_arg_valuekey:nnn { #3 } { default } { #2 }
			%#2
		}
		{
			\__semantex_arg_singlekey:fnn { \semantex_data_parent_get:n { #1 } } { #2 } { #3 }
		}
	}
}

\cs_generate_variant:Nn \__semantex_arg_singlekey:nnn { fnn }

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%    THE VALUEKEYS FOR \SemantexBaseObject
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% Now for the commands that are the basis of the keyval interface,
% namely the keys providing the keyval interface for the
% class \SemantexBaseObject. For historical reasons, they are defined
% as below as standalone commands and not when delcaring the
% class \SemantexBaseObject. I hope to change this in the future, but
% this is purely a matter of aesthetics, with no practical consequences.

% For all of them, #1 = name of the class/object, and #2 = value of
% the key.

% First, some very simple keys that we shall need over and over again:

\cs_new:Npn\semantex_grab_first_argument_of_two:nn#1#2{#1}
\cs_new:Npn\semantex_grab_second_argument_of_two:nn#1#2{#2}

\cs_new:Npn\semantex_grab_first_argument_of_three:nnn#1#2#3{#1}
\cs_new:Npn\semantex_grab_second_argument_of_three:nnn#1#2#3{#2}
\cs_new:Npn\semantex_grab_third_argument_of_three:nnn#1#2#3{#3}

\cs_new:Npn\semantex_grab_first_argument_of_four:nnnn#1#2#3#4{#1}
\cs_new:Npn\semantex_grab_second_argument_of_four:nnnn#1#2#3#4{#2}
\cs_new:Npn\semantex_grab_third_argument_of_four:nnnn#1#2#3#4{#3}
\cs_new:Npn\semantex_grab_fourth_argument_of_four:nnnn#1#2#3#4{#4}

\cs_new:Npn\semantex_grab_first_argument_of_five:nnnnn#1#2#3#4#5{#1}
\cs_new:Npn\semantex_grab_second_argument_of_five:nnnnn#1#2#3#4#5{#2}
\cs_new:Npn\semantex_grab_third_argument_of_five:nnnnn#1#2#3#4#5{#3}
\cs_new:Npn\semantex_grab_fourth_argument_of_five:nnnnn#1#2#3#4#5{#4}
\cs_new:Npn\semantex_grab_fifth_argument_of_five:nnnnn#1#2#3#4#5{#5}

\cs_new:Npn\semantex_grab_first_argument_of_six:nnnnnn#1#2#3#4#5#6{#1}
\cs_new:Npn\semantex_grab_second_argument_of_six:nnnnnn#1#2#3#4#5#6{#2}
\cs_new:Npn\semantex_grab_third_argument_of_six:nnnnnn#1#2#3#4#5#6{#3}
\cs_new:Npn\semantex_grab_fourth_argument_of_six:nnnnnn#1#2#3#4#5#6{#4}
\cs_new:Npn\semantex_grab_fifth_argument_of_six:nnnnnn#1#2#3#4#5#6{#5}
\cs_new:Npn\semantex_grab_sixth_argument_of_six:nnnnnn#1#2#3#4#5#6{#6}

\cs_new:Npn\semantex_grab_first_argument_of_seven:nnnnnnn#1#2#3#4#5#6#7{#1}
\cs_new:Npn\semantex_grab_second_argument_of_seven:nnnnnnn#1#2#3#4#5#6#7{#2}
\cs_new:Npn\semantex_grab_third_argument_of_seven:nnnnnnn#1#2#3#4#5#6#7{#3}
\cs_new:Npn\semantex_grab_fourth_argument_of_seven:nnnnnnn#1#2#3#4#5#6#7{#4}
\cs_new:Npn\semantex_grab_fifth_argument_of_seven:nnnnnnn#1#2#3#4#5#6#7{#5}
\cs_new:Npn\semantex_grab_sixth_argument_of_seven:nnnnnnn#1#2#3#4#5#6#7{#6}
\cs_new:Npn\semantex_grab_seventh_argument_of_seven:nnnnnnn#1#2#3#4#5#6#7{#7}

\cs_new:Npn\semantex_grab_first_argument_of_eight:nnnnnnnn#1#2#3#4#5#6#7#8{#1}
\cs_new:Npn\semantex_grab_second_argument_of_eight:nnnnnnnn#1#2#3#4#5#6#7#8{#2}
\cs_new:Npn\semantex_grab_third_argument_of_eight:nnnnnnnn#1#2#3#4#5#6#7#8{#3}
\cs_new:Npn\semantex_grab_fourth_argument_of_eight:nnnnnnnn#1#2#3#4#5#6#7#8{#4}
\cs_new:Npn\semantex_grab_fifth_argument_of_eight:nnnnnnnn#1#2#3#4#5#6#7#8{#5}
\cs_new:Npn\semantex_grab_sixth_argument_of_eight:nnnnnnnn#1#2#3#4#5#6#7#8{#6}
\cs_new:Npn\semantex_grab_seventh_argument_of_eight:nnnnnnnn#1#2#3#4#5#6#7#8{#7}
\cs_new:Npn\semantex_grab_eighth_argument_of_eight:nnnnnnnn#1#2#3#4#5#6#7#8{#8}

\cs_new:Npn\semantex_grab_first_argument_of_nine:nnnnnnnnn#1#2#3#4#5#6#7#8#9{#1}
\cs_new:Npn\semantex_grab_second_argument_of_nine:nnnnnnnnn#1#2#3#4#5#6#7#8#9{#2}
\cs_new:Npn\semantex_grab_third_argument_of_nine:nnnnnnnnn#1#2#3#4#5#6#7#8#9{#3}
\cs_new:Npn\semantex_grab_fourth_argument_of_nine:nnnnnnnnn#1#2#3#4#5#6#7#8#9{#4}
\cs_new:Npn\semantex_grab_fifth_argument_of_nine:nnnnnnnnn#1#2#3#4#5#6#7#8#9{#5}
\cs_new:Npn\semantex_grab_sixth_argument_of_nine:nnnnnnnnn#1#2#3#4#5#6#7#8#9{#6}
\cs_new:Npn\semantex_grab_seventh_argument_of_nine:nnnnnnnnn#1#2#3#4#5#6#7#8#9{#7}
\cs_new:Npn\semantex_grab_eighth_argument_of_nine:nnnnnnnnn#1#2#3#4#5#6#7#8#9{#8}
\cs_new:Npn\semantex_grab_ninth_argument_of_nine:nnnnnnnnn#1#2#3#4#5#6#7#8#9{#9}


\cs_generate_variant:Nn\str_if_eq:nnTF {xxTF,ooTF}

\cs_generate_variant:Nn\str_if_eq:nnT {xxT, ooT}

\cs_generate_variant:Nn\str_if_eq:nnF {xxF, ooF}

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

\cs_generate_variant:Nn \tl_if_blank:nF { xF }

\cs_new:Npn\semantex_provide_user_commands:n#1
{
	% This keys just executes whatever data you plug into it.
	% Possibly, going forward, it might make more sense to define all
	% of these commands in the keyval handling command
	% so that the get commands are accessible from all keys.
	\cs_set:Npn\SemantexDataProvide##1{\semantex_data_tl_provide:nn{#1}{\tl_trim_spaces:n{##1}}}
	\cs_set:Npn\SemantexDataSet##1##2{\semantex_data_tl_set:nnn{#1}{\tl_trim_spaces:n{##1}}{##2}}
	\cs_set:Npn\SemantexDataSetx##1##2{\semantex_data_tl_set:nnx{#1}{\tl_trim_spaces:n{##1}}{##2}}
	\cs_set:Npn\SemantexDataPutRight##1##2{\semantex_data_tl_put_right:nnn{#1}{\tl_trim_spaces:n{##1}}{##2}}
	\cs_set:Npn\SemantexDataPutRightx##1##2{\semantex_data_tl_put_right:nnx{#1}{\tl_trim_spaces:n{##1}}{##2}}
	\cs_set:Npn\SemantexDataPutLeft##1##2{\semantex_data_tl_put_left:nnn{#1}{\tl_trim_spaces:n{##1}}{##2}}
	\cs_set:Npn\SemantexDataPutLeftx##1##2{\semantex_data_tl_put_left:nnx{#1}{\tl_trim_spaces:n{##1}}{##2}}
	\cs_set:Npn\SemantexDataGet##1{\semantex_data_tl_get:nn{#1}{\tl_trim_spaces:n{##1}}}
	\cs_set:Npn\SemantexDataGetExpNot##1{\semantex_data_tl_get_exp_not:nn{#1}{\tl_trim_spaces:n{##1}}}
	\cs_set:Npn\SemantexDataClear##1{\semantex_data_tl_clear:nn{#1}{\tl_trim_spaces:n{##1}}}
	\cs_set:Npn\SemantexKeysSet##1{\semantex_keys_set:nn{#1}{##1}}
	\cs_set:Npn\SemantexKeysSetx##1{\semantex_keys_set:nx{#1}{##1}}
	\cs_set:Npn\SemantexStrIfEqTF##1##2##3##4{\str_if_eq:xxTF{##1}{##2}{##3}{##4}}
	\cs_set:Npn\SemantexStrIfEqT##1##2##3{\str_if_eq:xxT{##1}{##2}{##3}}
	\cs_set:Npn\SemantexStrIfEqF##1##2##3{\str_if_eq:xxF{##1}{##2}{##3}}
	\cs_set:Npn\SemantexIfBlankTF##1##2##3{\tl_if_blank:xTF{##1}{##2}{##3}}
	\cs_set:Npn\SemantexIfBlankT##1##2{\tl_if_blank:xT{##1}{##2}}
	\cs_set:Npn\SemantexIfBlankF##1##2{\tl_if_blank:xF{##1}{##2}}
	\cs_set:Npn\SemantexBoolProvide##1{\semantex_data_bool_provide:nn{#1}{\tl_trim_spaces:n{##1}}}
	\cs_set:Npn\SemantexBoolSetTrue##1{\semantex_data_bool_set_true:nn{#1}{\tl_trim_spaces:n{##1}}}
	\cs_set:Npn\SemantexBoolSetFalse##1{\semantex_data_bool_set_false:nn{#1}{\tl_trim_spaces:n{##1}}}
	\cs_set:Npn\SemantexBoolIfTF##1##2##3{\semantex_data_bool_get:nnTF{#1}{\tl_trim_spaces:n{##1}}{##2}{##3}}
	\cs_set:Npn\SemantexBoolIfT##1##2{\semantex_data_bool_get:nnTF{#1}{\tl_trim_spaces:n{##1}}{##2}{}}
	\cs_set:Npn\SemantexBoolIfF##1##2{\semantex_data_bool_get:nnTF{#1}{\tl_trim_spaces:n{##1}}{}{##2}}
	\cs_set:Npn\SemantexIntProvide##1{\semantex_data_int_provide:nn{#1}{\tl_trim_spaces:n{##1}}}
	\cs_set:Npn\SemantexIntGet##1{\semantex_data_int_get:nn{#1}{\tl_trim_spaces:n{\tl_trim_spaces:n{##1}}}}
	\cs_set:Npn\SemantexIntClear##1{\semantex_data_int_clear:nn{#1}{\tl_trim_spaces:n{##1}}}
	\cs_set:Npn\SemantexIntIncr##1{\semantex_data_int_incr:nn{#1}{\tl_trim_spaces:n{##1}}}
	\cs_set:Npn\SemantexIntSet##1##2{\semantex_data_int_set:nnn{#1}{\tl_trim_spaces:n{##1}}{##2}}
	\cs_set:Npn\SemantexIntIfGreaterThanTF##1##2##3##4
	{
		\int_compare:nNnTF
			{ ##1 }
			>
			{ ##2 }
			{ ##3 }
			{ ##4 }
	}
	\cs_set:Npn\SemantexIntIfGreaterThanT##1##2##3
	{
		\int_compare:nNnTF
			{ ##1 }
			>
			{ ##2 }
			{ ##3 }
			{ }
	}
	\cs_set:Npn\SemantexIntIfGreaterThanF##1##2##3
	{
		\int_compare:nNnTF
			{ ##1 }
			>
			{ ##2 }
			{ }
			{ ##3 }
	}
	\cs_set:Npn\SemantexIntIfEqualTF##1##2##3##4
	{
		\int_compare:nNnTF
			{ ##1 }
			=
			{ ##2 }
			{ ##3 }
			{ ##4 }
	}
	\cs_set:Npn\SemantexIntIfEqualT##1##2##3
	{
		\int_compare:nNnTF
			{ ##1 }
			=
			{ ##2 }
			{ ##3 }
			{ }
	}
	\cs_set:Npn\SemantexIntIfEqualF##1##2##3
	{
		\int_compare:nNnTF
			{ ##1 }
			=
			{ ##2 }
			{ }
			{ ##3 }
	}
	\cs_set:Npn\SemantexIntIfLessThanTF##1##2##3##4
	{
		\int_compare:nNnTF
			{ ##1 }
			<
			{ ##2 }
			{ ##3 }
			{ ##4 }
	}
	\cs_set:Npn\SemantexIntIfLessThanT##1##2##3
	{
		\int_compare:nNnTF
			{ ##1 }
			<
			{ ##2 }
			{ ##3 }
			{ }
	}
	\cs_set:Npn\SemantexIntIfLessThanF##1##2##3
	{
		\int_compare:nNnTF
			{ ##1 }
			<
			{ ##2 }
			{ }
			{ ##3 }
	}
	\cs_set:Npn\SemantexExpNot##1{\exp_not:n{##1}}
	\cs_set:Npn\SemantexERRORKeyValueNotFound##1
	{
		\semantex_error_output_format:nN { #1 } \l__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ERRORkeyvaluenotfound_temp_tl
		\msg_error:nnxoo { semantex } { key_value_not_found }
			{ \l__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ERRORkeyvaluenotfound_temp_tl }
			{ \semantex_grab_first_argument_of_two:nn ##1 }
			{ \semantex_grab_second_argument_of_two:nn ##1 }
	}
	
	\cs_set:Npn\SemantexERROR##1
	{
		\semantex_error_output_format:nN { #1 } \l__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ERROR_temp_tl
		\msg_error:nnxoo { semantex } { generic_error }
			{ \l__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ERROR_temp_tl }
			{ \semantex_grab_first_argument_of_two:nn ##1 }
			{ \semantex_grab_second_argument_of_two:nn ##1 }
	}
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_dataprovide:nn#1#2
{
	\semantex_data_tl_provide:nn { #1 } { #2 }
}

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

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_dataset:nn#1#2
{
	\semantex_data_tl_set:nno { #1 }
		{ \tl_trim_spaces:n { \semantex_grab_first_argument_of_two:nn #2 } }
		{ \semantex_grab_second_argument_of_two:nn #2 }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_datasetx:nn#1#2
{
	\semantex_data_tl_set:nnx { #1 }
		{ \tl_trim_spaces:n { \semantex_grab_first_argument_of_two:nn #2 } }
		{ \semantex_grab_second_argument_of_two:nn #2 }
}

\cs_generate_variant:Nn \semantex_data_tl_put_right:nnn { noo , nox }

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_dataputright:nn#1#2{
	\semantex_data_tl_put_right:nno { #1 }
		{ \tl_trim_spaces:n { \semantex_grab_first_argument_of_two:nn #2 } }
		{ \semantex_grab_second_argument_of_two:nn #2 }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_dataputrightx:nn#1#2{
	\semantex_data_tl_put_right:nnx { #1 }
		{ \tl_trim_spaces:n { \semantex_grab_first_argument_of_two:nn #2 } }
		{ \semantex_grab_second_argument_of_two:nn #2 }
}

\cs_generate_variant:Nn \semantex_data_tl_put_left:nnn { noo , nox }

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_dataputleft:nn#1#2
{
	\semantex_data_tl_put_left:nno { #1 }
		{ \tl_trim_spaces:n { \semantex_grab_first_argument_of_two:nn #2 } }
		{ \semantex_grab_second_argument_of_two:nn #2 }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_dataputleftx:nn#1#2
{
	\semantex_data_tl_put_left:nnx { #1 }
		{ \tl_trim_spaces:n { \semantex_grab_first_argument_of_two:nn #2 } }
		{ \semantex_grab_second_argument_of_two:nn #2 }
}


\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_dataclear:nn#1#2
{
	\semantex_data_tl_clear:nn { #1 } { \tl_trim_spaces:n { #2 } }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_keysset:nn#1#2
{
	\semantex_keys_set:nn { #1 } { #2 }
}

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setkeys:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_keysset:nn

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_keyssetx:nn#1#2
{
	\semantex_keys_set:nx { #1 }{ #2 }
}

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setkeysx:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_keyssetx:nn

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ifeqTF:nn#1#2
{
	\str_if_eq:xxTF
		{ \semantex_grab_first_argument_of_four:nnnn #2 }
		{ \semantex_grab_second_argument_of_four:nnnn #2 }
		{ \semantex_keys_set:no { #1 } { \semantex_grab_third_argument_of_four:nnnn #2 } }
		{ \semantex_keys_set:no { #1 } { \semantex_grab_fourth_argument_of_four:nnnn #2 } }
}

\cs_generate_variant:Nn \str_if_eq:nnTF { ffTF }

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ifeqT:nn#1#2
{
	\str_if_eq:xxTF
		{ \semantex_grab_first_argument_of_three:nnn #2 }
		{ \semantex_grab_second_argument_of_three:nnn #2 }
		{ \semantex_keys_set:no { #1 } { \semantex_grab_third_argument_of_three:nnn #2 } }
		{ }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ifeqF:nn#1#2
{
	\str_if_eq:xxTF
		{ \semantex_grab_first_argument_of_three:nnn #2 }
		{ \semantex_grab_second_argument_of_three:nnn #2 }
		{ }
		{ \semantex_keys_set:no { #1 } { \semantex_grab_third_argument_of_three:nnn #2 } }
}

\cs_generate_variant:Nn \semantex_keys_set:nn { no }

\cs_generate_variant:Nn \tl_if_blank:nTF { fTF }

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ifblankTF:nn#1#2
{
	\tl_if_blank:xTF
		{ \semantex_grab_first_argument_of_three:nnn #2 }
		{ \semantex_keys_set:no { #1 } { \semantex_grab_second_argument_of_three:nnn #2 } }
		{ \semantex_keys_set:no { #1 } { \semantex_grab_third_argument_of_three:nnn #2 } }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ifblankT:nn#1#2
{
	\tl_if_blank:xTF
		{ \semantex_grab_first_argument_of_two:nn #2 }
		{ \semantex_keys_set:no { #1 } { \semantex_grab_second_argument_of_two:nn #2 } }
		{ }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ifblankF:nn#1#2
{
	\tl_if_blank:xTF
		{ \semantex_grab_first_argument_of_two:nn #2 }
		{ }
		{ semantex_keys_set:no { #1 } { \semantex_grab_second_argument_of_two:nn #2 } }
}


\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_boolprovide:nn#1#2
{
	\semantex_data_bool_provide:nn { #1 } { \tl_trim_spaces:n { #2 } }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_boolsettrue:nn#1#2
{
	\semantex_data_bool_set_true:nn { #1 } { \tl_trim_spaces:n { #2 } }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_boolsetfalse:nn#1#2
{
	\semantex_data_bool_set_false:nn { #1 } { \tl_trim_spaces:n { #2 } }
}

\cs_generate_variant:Nn \semantex_data_bool_get:nnTF { noTF, nfTF , neTF , ffTF }

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_boolifTF:nn#1#2
{
	\semantex_data_bool_get:nnTF { #1 }
		{ \tl_trim_spaces:n { \semantex_grab_first_argument_of_three:nnn #2 } }
		{ \semantex_keys_set:no { #1 } { \semantex_grab_second_argument_of_three:nnn #2 } }
		{ \semantex_keys_set:no { #1 } { \semantex_grab_third_argument_of_three:nnn #2 } }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_boolifT:nn#1#2
{
	\semantex_data_bool_get:nnTF { #1 }
		{ \tl_trim_spaces:n { \semantex_grab_first_argument_of_two:nn #2 } }
		{ \semantex_keys_set:no { #1 } { \semantex_grab_second_argument_of_two:nn #2 } }
		{ }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_boolifF:nn#1#2
{
	\semantex_data_bool_get:nnTF { #1 }
		{ \tl_trim_spaces:n { \semantex_grab_first_argument_of_two:nn #2 } }
		{ }
		{ \semantex_keys_set:no { #1 } { \semantex_grab_second_argument_of_two:nn #2 } }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_intprovide:nn#1#2
{
	\semantex_data_int_provide:nn { #1 } { \tl_trim_spaces:n { #2 } }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_intclear:nn#1#2
{
	\semantex_data_int_clear:nn { #1 } { \tl_trim_spaces:n { #2 } }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_intincr:nn#1#2
{
	\semantex_data_int_incr:nn { #1 } { \tl_trim_spaces:n { #2 } }
}

\cs_generate_variant:Nn \semantex_data_int_set:nnn { noo , nno }

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_intset:nn#1#2
{
	\semantex_data_int_set:noo { #1 }
		{ \tl_trim_spaces:n { \semantex_grab_first_argument_of_two:nn #2 } }
		{ \semantex_grab_second_argument_of_two:nn #2 }
}

\cs_generate_variant:Nn \int_compare:nNnTF { oNoTF , fNfTF , xNxTF }

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_intifgreaterthanTF:nn#1#2
{
	\int_compare:oNoTF
		{ \semantex_grab_first_argument_of_four:nnnn #2 }
		>
		{ \semantex_grab_second_argument_of_four:nnnn #2 }
		{ \semantex_keys_set:no { #1 } { \semantex_grab_third_argument_of_four:nnnn #2 } }
		{ \semantex_keys_set:no { #1 } { \semantex_grab_fourth_argument_of_four:nnnn #2 } }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_intifgreaterthanT:nn#1#2
{
	\int_compare:oNoTF
		{ \semantex_grab_first_argument_of_three:nnn #2 }
		>
		{ \semantex_grab_second_argument_of_three:nnn #2 }
		{ \semantex_keys_set:no { #1 } { \semantex_grab_third_argument_of_three:nnn #2 } }
		{ }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_intifgreaterthanF:nn#1#2
{
	\int_compare:oNoTF
		{ \semantex_grab_first_argument_of_three:nnn #2 }
		>
		{ \semantex_grab_second_argument_of_three:nnn #2 }
		{ }
		{ \semantex_keys_set:no { #1 } { \semantex_grab_third_argument_of_three:nnn #2 } }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_intifequalTF:nn#1#2
{
	\int_compare:oNoTF
		{ \semantex_grab_first_argument_of_four:nnnn #2 }
		=
		{ \semantex_grab_second_argument_of_four:nnnn #2 }
		{ \semantex_keys_set:no { #1 } { \semantex_grab_third_argument_of_four:nnnn #2 } }
		{ \semantex_keys_set:no { #1 } { \semantex_grab_fourth_argument_of_four:nnnn #2 } }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_intifequalT:nn#1#2
{
	\int_compare:oNoTF
		{ \semantex_grab_first_argument_of_three:nnn #2 }
		=
		{ \semantex_grab_second_argument_of_three:nnn #2 }
		{ \semantex_keys_set:no { #1 } { \semantex_grab_third_argument_of_three:nnn #2 } }
		{ }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_intifequalF:nn#1#2
{
	\int_compare:oNoTF
		{ \semantex_grab_first_argument_of_three:nnn #2 }
		=
		{ \semantex_grab_second_argument_of_three:nnn #2 }
		{ }
		{ \semantex_keys_set:no { #1 } { \semantex_grab_third_argument_of_three:nnn #2 } }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_intiflessthanTF:nn#1#2
{
	\int_compare:oNoTF
		{ \semantex_grab_first_argument_of_four:nnnn #2 }
		<
		{ \semantex_grab_second_argument_of_four:nnnn #2 }
		{ \semantex_keys_set:no { #1 } { \semantex_grab_third_argument_of_four:nnnn #2 } }
		{ \semantex_keys_set:no { #1 } { \semantex_grab_fourth_argument_of_four:nnnn #2 } }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_intiflessthanT:nn#1#2
{
	\int_compare:oNoTF
		{ \semantex_grab_first_argument_of_three:nnn #2 }
		<
		{ \semantex_grab_second_argument_of_three:nnn #2 }
		{ \semantex_keys_set:no { #1 } { \semantex_grab_third_argument_of_three:nnn #2 } }
		{ }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_intiflessthanF:nn#1#2
{
	\int_compare:oNoTF
		{ \semantex_grab_first_argument_of_three:nnn #2 }
		<
		{ \semantex_grab_second_argument_of_three:nnn #2 }
		{ }
		{ \semantex_keys_set:no { #1 } { \semantex_grab_third_argument_of_three:nnn #2 } }
}

\cs_generate_variant:Nn\msg_error:nnnnn { nnxoo }

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ERRORkeyvaluenotfound:nn#1#2
{
	\semantex_error_output_format:nN { #1 } \l__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ERRORkeyvaluenotfound_temp_tl
	\msg_error:nnxoo { semantex } { key_value_not_found }
		{ \l__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ERRORkeyvaluenotfound_temp_tl }
		{ \semantex_grab_first_argument_of_two:nn #2 }
		{ \semantex_grab_second_argument_of_two:nn #2 }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ERROR:nn#1#2
{
	\semantex_error_output_format:nN { #1 } \l__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ERROR_temp_tl
	\msg_error:nnxoo { semantex } { generic_error }
		{ \l__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ERROR_temp_tl }
		{ \semantex_grab_first_argument_of_two:nn #2 }
		{ \semantex_grab_second_argument_of_two:nn #2 }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_execute:nn#1#2
{
	%\exp_not:n{#2}
	% how about forget?
	#2
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_parse:nn#1#2
{
	% This command runs all the keys that the user may have
	% stored via the parseoptions key
	%\semantex_data_tl_inherit:nn { #1 } { parseoptions }
%	\semantex_keys_set:nx { #1 } {
%		\semantex_data_tl_get_exp_not:nn { #1 } { parseoptions }
%	}
%	\semantex_data_tl_clear:nn { #1 } { parseoptions } % this is probably necessary
	\semantex_data_cs_get:nn { #1 } { parseoptions:n } { #1 }
	\semantex_data_tl_clear:nn { #1 } { parseoptions } % this is probably necessary
	\semantex_data_cs_clear:nn { #1 } { parseoptions:n }
}

%\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_parseoptions:nn#1#2
%{
%	% This adds keys to the parseoptions token list
%	\semantex_data_tl_put_right:nnn { #1 } { parseoptions } { #2 }
%}


\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_parseoptions:nn#1#2{
	\tl_set:Nn\l__semantex_parseoptions_auxiliary_temp_tl{}
	\cs_set:Npn\l__semantex_parseoptions_auxiliary_singlekey_temp_cs:n##1
	{
		\__semantex_parseoptions_process_singlekey:nnN { ####1 } { ##1 } \l__semantex_parseoptions_auxiliary_temp_tl
	}
	\cs_set:Npn\l__semantex_parseoptions_auxiliary_valuekey_temp_cs:nn##1##2
	{
		\__semantex_parseoptions_process_valuekey:nnnN { ####1 } { ##1 } { ##2 } \l__semantex_parseoptions_auxiliary_temp_tl
	}
	\keyval_parse:NNn
		\l__semantex_parseoptions_auxiliary_singlekey_temp_cs:n
		\l__semantex_parseoptions_auxiliary_valuekey_temp_cs:nn
		{ #2 }
	\semantex_data_tl_put_right:nno { #1 } { parseoptions } { \l__semantex_parseoptions_auxiliary_temp_tl }
	%\exp_args:NNno\exp_args:Nno\cs_set:co { __semantex_data_cs_#1_parseoptions:n }
	%\exp_args:Nnno
	\semantex_data_cs_set:nnx { #1 } { parseoptions:n }
	{
%		g__semantex_data_tl_#1_parseoptions
%		\semantex_data_tl_get:nn { #1 } { parseoptions }
		\semantex_data_tl_get_exp_not:nn { #1 } { parseoptions }
		%\l__semantex_parseoptions_auxiliary_temp_tl
	}
}


\cs_new:Npn\__semantex_parseoptions_process_singlekey:nnN#1#2#3
{
	\tl_put_right:Nn#3
	{
		\semantex_singlekey:nn { #1 } { #2 }
	}
}

\cs_new:Npn\__semantex_parseoptions_process_valuekey:nnnN#1#2#3#4
{
	\tl_if_eq:nnTF { #2 } { execute }
	{
		\tl_put_right:Nn#4
		{
			#3
		}
	}
	{
		\tl_put_right:Nn#4
		{
			\semantex_valuekey:nnn { #1 } { #2 } { #3 }
		}
	}	
}


\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_return:nn#1#2
{
	% This is an umbrella key that runs all of the three
	% return routines, innerreturn, rightreturn, and leftreturn
	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_innerreturn:nn { #1 }{}
	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_rightreturn:nn { #1 }{}
	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_leftreturn:nn { #1 }{}
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_innerreturn:nn#1#2
{
	% This adds all of the commands added via the command key
	% to the symbol
	\semantex_data_tl_inherit:nn { #1 } { symbol }
	\semantex_data_seq_inherit:nn { #1 } { commands_sequence }
	\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 {\exp_not:N ##1}  {
					\semantex_data_tl_get_exp_not:nn { #1 } { symbol }
				}
				% This was the solution that happened to solve
				% the expansion issues best
			}
		}
	\semantex_data_seq_clear:nn { #1 } { commands_sequence }
}

\cs_generate_variant:Nn \semantex_keys_set:nn { nx , no }

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_rightreturn:nn#1#2
{
	\semantex_right_indices_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
	}
	\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:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_leftreturn:nn#1#2
{
	\semantex_left_indices_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
	}
	\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:Npn \semantex_left_indices_return_store:nN#1#2
{
	\semantex_data_tl_inherit_x:nn { #1 } { upperleft }
	\semantex_data_tl_inherit_x:nn { #1 } { lowerleft }
	\semantex_data_tl_inherit_x:nn { #1 } { preupperleft }
	\semantex_data_tl_inherit_x:nn { #1 } { postupperleft }
	\semantex_data_tl_inherit_x:nn { #1 } { prelowerleft }
	\semantex_data_tl_inherit_x:nn { #1 } { postlowerleft }
	\tl_set:Nn#2{}
	\semantex_data_int_if_positive:nnTF { #1 } { numberofupperleftindices }
	{
		\semantex_data_int_if_positive:nnTF { #1 } { numberoflowerleftindices }
		{
			\tl_put_right:Nx#2
			{
				{}\sp{
					\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 }
				}
				\sb{
					\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:Nx#2
			{
				{}\sp{
					\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
			{
				{}\sb{
					\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
		}
	}
	\semantex_data_tl_clear:nn { #1 } { upperleft }
	\semantex_data_bool_provide:nn { #1 } { nextupperleftwithsep } % is it necessary to provide it before declaring it false?
	\semantex_data_bool_set_false:nn { #1 } { nextupperleftwithsep }
	\semantex_data_tl_clear:nn { #1 } { lowerleft }
	\semantex_data_bool_provide:nn { #1 } { nextlowerleftwithsep } % is it necessary to provide it before declaring it false?
	\semantex_data_bool_set_false:nn { #1 } { nextlowerleftwithsep }
	\semantex_data_tl_clear:nn { #1 } { preupperleft }
	\semantex_data_tl_clear:nn { #1 } { postupperleft }
	\semantex_data_tl_clear:nn { #1 } { prelowerleft }
	\semantex_data_tl_clear:nn { #1 } { postlowerleft }
	\semantex_data_int_clear:nn { #1 } { numberofupperleftindices }
	\semantex_data_int_clear:nn { #1 } { numberoflowerleftindices }
}


\cs_new:Npn \semantex_arg_return_store:nN#1#2
{
	\semantex_data_tl_inherit_x:nn { #1 } { arg }
	\semantex_data_int_inherit:nn { #1 } { numberofarguments }
	%\semantex_data_tl_inherit:nn { #1 } { parsize } % This was necessary for unkonwn reasons -- otherwise it will fail when doing inheritance
	\semantex_data_tl_get_store:nnN { #1 } { parsize } \l__arg_return_store_parsize_temp_tl
	\semantex_data_bool_get:nnTF { #1 } { par }
	{
		\semantex_data_int_if_positive:nnTF { #1 } { numberofarguments }
		{
			\__semantex_parentheses_store:nnnnN
			{ \l__arg_return_store_parsize_temp_tl }
			{ \semantex_data_tl_get_exp_not:nn { #1 } { leftpar } }
			{ \semantex_data_tl_get_exp_not:nn { #1 } { rightpar } }
			{
				\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 }
			}
			#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:nnnnN
				{ \l__arg_return_store_parsize_temp_tl }
				{ \semantex_data_tl_get_exp_not:nn { #1 } { leftpar } }
				{ \semantex_data_tl_get_exp_not:nn { #1 } { rightpar } }
				{
					\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 }
				}
				#2
			}
			{
				\semantex_data_int_if_positive:nnTF { #1 } { numberofarguments }
				{
					\__semantex_no_parentheses_store:nN
					{
						\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 }
					}
					#2
				}
				{
					\tl_set:Nn#2{}
				}
			}
		}
		{
			\semantex_data_int_if_positive:nnTF { #1 } { numberofarguments }
			{
				\__semantex_no_parentheses_store:nN
				{
					\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 }
				}
				#2
			}
			{
				\tl_set:Nn#2{}
			}
		}
	}
	\semantex_data_tl_clear:nn { #1 } { arg }
	\semantex_data_tl_clear:nn { #1 } { prearg } % Is it right to clear these?
	\semantex_data_tl_clear:nn { #1 } { postarg }
	\semantex_data_int_clear:nn { #1 } { numberofarguments }
	\semantex_data_bool_provide:nn { #1 } { nextargwithsep } % is it necessary to provide it before declaring it false?
	\semantex_data_bool_set_false:nn { #1 } { nextargwithsep }
}

\cs_new:Npn \semantex_right_indices_return_store:nN#1#2
{
	\semantex_data_tl_inherit_x:nn { #1 } { upper }
	\semantex_data_tl_inherit_x:nn { #1 } { lower }
	\semantex_data_tl_inherit_x:nn { #1 } { preupper }
	\semantex_data_tl_inherit_x:nn { #1 } { postupper }
	\semantex_data_tl_inherit_x:nn { #1 } { prelower }
	\semantex_data_tl_inherit_x:nn { #1 } { postlower }
	\tl_set:Nn#2{}
	\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
	}
	\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_tl_clear:nn { #1 } { upper }
	\semantex_data_bool_provide:nn { #1 } { nextupperwithsep } % is it necessary to provide it before declaring it false?
	\semantex_data_bool_set_false:nn { #1 } { nextupperwithsep }
	\semantex_data_tl_clear:nn { #1 } { lower }
	\semantex_data_bool_provide:nn { #1 } { nextlowerwithsep } % is it necessary to provide it before declaring it false?
	\semantex_data_bool_set_false:nn { #1 } { nextlowerwithsep }
	\semantex_data_tl_clear:nn { #1 } { preupper }
	\semantex_data_tl_clear:nn { #1 } { postupper }
	\semantex_data_tl_clear:nn { #1 } { prelower }
	\semantex_data_tl_clear:nn { #1 } { postlower }
	\semantex_data_int_clear:nn { #1 } { numberofupperindices }
	\semantex_data_int_clear:nn { #1 } { numberoflowerindices }
}



\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_parent:nn#1#2{
	% Must inherit everything from the parent class
	\semantex_data_parent_set:nn { #1 } { #2 }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_class:nn#1#2{
	% Must inherit everything from the parent class
	\semantex_data_class_set:nn { #1 } { #2 }
}

\cs_generate_variant:Nn \__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_class:nn { xn }

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_copy:nn#1#2{
	% Similarly to parent and class, but inherits from other objects rather than classes
	\semantex_data_copy_object:nn { #1 } { #2 }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clone:nn#1#2{
	% Similarly to parent and class, but inherits from other objects rather than classes
	\semantex_data_clone_object:nn { #1 } { #2 }
}

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

\cs_new:Npn\__semantex_process_singlekey:nnN#1#2#3
{
	\tl_put_right:Nn#3
	{
		\semantex_singlekey:nn { #1 } { #2 }
	}
}

\cs_generate_variant:Nn \semantex_valuekey:nnn { nnx }

\cs_new:Npn\__semantex_process_valuekey:nnnN#1#2#3#4
{
	\tl_if_eq:nnTF { #2 } { execute }
	{
		\tl_put_right:Nn#4
		{
			#3
		}
	}
	{
		\tl_put_right:Nn#4
		{
			\semantex_valuekey:nnn { #1 } { #2 } { #3 }
		}	
	}
}

\cs_new:Npn\__semantex_valuekey_format_auxiliary:nnn#1#2#3
{
	\tl_set:Nn\l__semantex_valuekey_auxiliary_temp_tl{}
	\cs_set:Npn\l__semantex_valuekey_auxiliary_singlekey_temp_cs:n##1
	{
		\__semantex_process_singlekey:nnN { ####1 } { ##1 } \l__semantex_valuekey_auxiliary_temp_tl
	}
	\cs_set:Npn\l__semantex_valuekey_auxiliary_valuekey_temp_cs:nn##1##2
	{
		\__semantex_process_valuekey:nnnN { ####1 } { ##1 } { ##2 } \l__semantex_valuekey_auxiliary_temp_tl
	}
	\cs_set:Npn\l__semantex_valuekey_auxiliary_temp_cs:n##1 { #3 }
	\keyval_parse:NNo
		\l__semantex_valuekey_auxiliary_singlekey_temp_cs:n
		\l__semantex_valuekey_auxiliary_valuekey_temp_cs:nn
		{
			\l__semantex_valuekey_auxiliary_temp_cs:n { ##2 }
		}
	\cs_set:cpo { __semantex_data_cs_custom_valuekey_#1_#2:nn } ##1##2 {
		\l__semantex_valuekey_auxiliary_temp_tl
	}
	% remove spaces
}

\cs_generate_variant:Nn \cs_set:Npn { cpo }

\cs_generate_variant:Nn \keyval_parse:NNn { NNo }

%CHECK

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

\cs_new:Npn \__semantex_singlekeys_format_auxiliary:nnn#1#2#3{
	\tl_set:Nn\l__semantex_singlekey_auxiliary_temp_tl{}
	\cs_set:Npn\l__semantex_singlekey_auxiliary_singlekey_temp_cs:n##1
	{
		\__semantex_process_singlekey:nnN { ####1 } { ##1 } \l__semantex_singlekey_auxiliary_temp_tl
	}
	\cs_set:Npn\l__semantex_singlekey_auxiliary_valuekey_temp_cs:nn##1##2
	{
		\__semantex_process_valuekey:nnnN { ####1 } { ##1 } { ##2 } \l__semantex_singlekey_auxiliary_temp_tl
	}
	\cs_set:Npn\l__semantex_singlekey_auxiliary_temp_cs: { #3 }
	\keyval_parse:NNo
		\l__semantex_singlekey_auxiliary_singlekey_temp_cs:n
		\l__semantex_singlekey_auxiliary_valuekey_temp_cs:nn
			{ \l__semantex_singlekey_auxiliary_temp_cs: }
	\cs_set:cpo { __semantex_data_cs_custom_singlekey_#1_#2:n } ##1 {
		\l__semantex_singlekey_auxiliary_temp_tl
	}
%	\seq_put_right:cn { g__semantex_data_seq_#1_list_of_singlekeys } { #2 }
%	%IM Remove spaces in #2
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_removesinglekey:nn#1#2
{
	\cs_undefine:c { __semantex_data_cs_custom_singlekey_#1_#2:n }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_removevaluekey:nn#1#2
{
	\cs_undefine:c { __semantex_data_cs_custom_valuekey_#1_#2:nn }
}

\cs_set_eq:cN { __semantex_data_cs_custom_valuekey_class_SemantexBaseObject_1valuekeys:nn } \__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_valuekeys:nn

\cs_new:cpn { __semantex_data_cs_custom_valuekey_class_SemantexBaseObject_2valuekeys:nn }#1#2{
	% Add new valuekeys
	\clist_map_inline:nn { #2 }{
		\__semantex_two_valuekey_format_auxiliary:nnn{#1}##1
	}
}

\cs_new:Npn\__semantex_two_valuekey_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_two_valuekey_format_auxiliary_temp:nn##1##2{#3}
	%IM Remove spaces in #2
	\__semantex_valuekey_format_auxiliary:nno { #1 } { #2 }
	{
		\l__semantex_two_valuekey_format_auxiliary_temp:nn
		{
			\semantex_grab_first_argument_of_two:nn ##1
		}
		{
			\semantex_grab_second_argument_of_two:nn ##1
		}
	}
}
\cs_generate_variant:Nn \__semantex_valuekey_format_auxiliary:nnn { nno }

\cs_new:cpn { __semantex_data_cs_custom_valuekey_class_SemantexBaseObject_3valuekeys:nn }#1#2{
	% Add new valuekeys
	\clist_map_inline:nn { #2 }{
		\__semantex_three_valuekey_format_auxiliary:nnn{#1}##1
	}
}

\cs_new:Npn\__semantex_three_valuekey_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_three_valuekey_format_auxiliary_temp:nnn##1##2##3{#3}
	\__semantex_valuekey_format_auxiliary:nno { #1 } { #2 }
	{
		\l__semantex_three_valuekey_format_auxiliary_temp:nnn
		{
			\semantex_grab_first_argument_of_three:nnn ##1
		}
		{
			\semantex_grab_second_argument_of_three:nnn ##1
		}
		{
			\semantex_grab_third_argument_of_three:nnn ##1
		}
	}
	%IM Remove spaces in #2
}

\cs_new:cpn { __semantex_data_cs_custom_valuekey_class_SemantexBaseObject_4valuekeys:nn }#1#2{
	% Add new valuekeys
	\clist_map_inline:nn { #2 }{
		\__semantex_four_valuekey_format_auxiliary:nnn{#1}##1
	}
}

\cs_new:Npn\__semantex_four_valuekey_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_four_valuekey_format_auxiliary_temp:nnnn##1##2##3##4{#3}
	\__semantex_valuekey_format_auxiliary:nno { #1 } { #2 }
	{
		\l__semantex_four_valuekey_format_auxiliary_temp:nnnn
		{
			\semantex_grab_first_argument_of_four:nnnn ##1
		}
		{
			\semantex_grab_second_argument_of_four:nnnn ##1
		}
		{
			\semantex_grab_third_argument_of_four:nnnn ##1
		}
		{
			\semantex_grab_fourth_argument_of_four:nnnn ##1
		}
	}
	%IM Remove spaces in #2
}

\cs_new:cpn { __semantex_data_cs_custom_valuekey_class_SemantexBaseObject_5valuekeys:nn }#1#2{
	% Add new valuekeys
	\clist_map_inline:nn { #2 }{
		\__semantex_five_valuekey_format_auxiliary:nnn{#1}##1
	}
}

\cs_new:Npn\__semantex_five_valuekey_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_five_valuekey_format_auxiliary_temp:nnnnn##1##2##3##4##5{#3}
	\__semantex_valuekey_format_auxiliary:nno { #1 } { #2 }
	{
		\l__semantex_five_valuekey_format_auxiliary_temp:nnnnn
		{
			\semantex_grab_first_argument_of_five:nnnnn ##1
		}
		{
			\semantex_grab_second_argument_of_five:nnnnn ##1
		}
		{
			\semantex_grab_third_argument_of_five:nnnnn ##1
		}
		{
			\semantex_grab_fourth_argument_of_five:nnnnn ##1
		}
		{
			\semantex_grab_fifth_argument_of_five:nnnnn ##1
		}
	}
	%IM Remove spaces in #2
}

\cs_new:cpn { __semantex_data_cs_custom_valuekey_class_SemantexBaseObject_6valuekeys:nn }#1#2{
	% Add new valuekeys
	\clist_map_inline:nn { #2 }{
		\__semantex_six_valuekey_format_auxiliary:nnn{#1}##1
	}
}

\cs_new:Npn\__semantex_six_valuekey_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_six_valuekey_format_auxiliary_temp:nnnnnn##1##2##3##4##5##6{#3}
	\__semantex_valuekey_format_auxiliary:nno { #1 } { #2 }
	{
		\l__semantex_six_valuekey_format_auxiliary_temp:nnnnnn
		{
			\semantex_grab_first_argument_of_six:nnnnnn ##1
		}
		{
			\semantex_grab_second_argument_of_six:nnnnnn ##1
		}
		{
			\semantex_grab_third_argument_of_six:nnnnnn ##1
		}
		{
			\semantex_grab_fourth_argument_of_six:nnnnnn ##1
		}
		{
			\semantex_grab_fifth_argument_of_six:nnnnnn ##1
		}
		{
			\semantex_grab_sixth_argument_of_six:nnnnnn ##1
		}
	}
	%IM Remove spaces in #2
}

\cs_new:cpn { __semantex_data_cs_custom_valuekey_class_SemantexBaseObject_7valuekeys:nn }#1#2{
	% Add new valuekeys
	\clist_map_inline:nn { #2 }{
		\__semantex_seven_valuekey_format_auxiliary:nnn{#1}##1
	}
}

\cs_new:Npn\__semantex_seven_valuekey_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_seven_valuekey_format_auxiliary_temp:nnnnnnn##1##2##3##4##5##6##7{#3}
	\__semantex_valuekey_format_auxiliary:nno { #1 } { #2 }
	{
		\l__semantex_seven_valuekey_format_auxiliary_temp:nnnnnnn
		{
			\semantex_grab_first_argument_of_seven:nnnnnnn ##1
		}
		{
			\semantex_grab_second_argument_of_seven:nnnnnnn ##1
		}
		{
			\semantex_grab_third_argument_of_seven:nnnnnnn ##1
		}
		{
			\semantex_grab_fourth_argument_of_seven:nnnnnnn ##1
		}
		{
			\semantex_grab_fifth_argument_of_seven:nnnnnnn ##1
		}
		{
			\semantex_grab_sixth_argument_of_seven:nnnnnnn ##1
		}
		{
			\semantex_grab_seventh_argument_of_seven:nnnnnnn ##1
		}
	}
	%IM Remove spaces in #2
}

\cs_new:cpn { __semantex_data_cs_custom_valuekey_class_SemantexBaseObject_8valuekeys:nn }#1#2{
	% Add new valuekeys
	\clist_map_inline:nn { #2 }{
		\__semantex_eight_valuekey_format_auxiliary:nnn{#1}##1
	}
}

\cs_new:Npn\__semantex_eight_valuekey_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_eight_valuekey_format_auxiliary_temp:nnnnnnnn##1##2##3##4##5##6##7##8{#3}
	\__semantex_valuekey_format_auxiliary:nno { #1 } { #2 }
	{
		\l__semantex_eight_valuekey_format_auxiliary_temp:nnnnnnnn
		{
			\semantex_grab_first_argument_of_eight:nnnnnnnn ##1
		}
		{
			\semantex_grab_second_argument_of_eight:nnnnnnnn ##1
		}
		{
			\semantex_grab_third_argument_of_eight:nnnnnnnn ##1
		}
		{
			\semantex_grab_fourth_argument_of_eight:nnnnnnnn ##1
		}
		{
			\semantex_grab_fifth_argument_of_eight:nnnnnnnn ##1
		}
		{
			\semantex_grab_sixth_argument_of_eight:nnnnnnnn ##1
		}
		{
			\semantex_grab_seventh_argument_of_eight:nnnnnnnn ##1
		}
		{
			\semantex_grab_eighth_argument_of_eight:nnnnnnnn ##1
		}
	}
	%IM Remove spaces in #2
}

\cs_new:cpn { __semantex_data_cs_custom_valuekey_class_SemantexBaseObject_9valuekeys:nn }#1#2{
	% Add new valuekeys
	\clist_map_inline:nn { #2 }{
		\__semantex_nine_valuekey_format_auxiliary:nnn{#1}##1
	}
}

\cs_new:Npn\__semantex_nine_valuekey_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_nine_valuekey_format_auxiliary_temp:nnnnnnnnn##1##2##3##4##5##6##7##8##9{#3}
	\__semantex_valuekey_format_auxiliary:nno { #1 } { #2 }
	{
		\l__semantex_nine_valuekey_format_auxiliary_temp:nnnnnnnnn
		{
			\semantex_grab_first_argument_of_nine:nnnnnnnnn ##1
		}
		{
			\semantex_grab_second_argument_of_nine:nnnnnnnnn ##1
		}
		{
			\semantex_grab_third_argument_of_nine:nnnnnnnnn ##1
		}
		{
			\semantex_grab_fourth_argument_of_nine:nnnnnnnnn ##1
		}
		{
			\semantex_grab_fifth_argument_of_nine:nnnnnnnnn ##1
		}
		{
			\semantex_grab_sixth_argument_of_nine:nnnnnnnnn ##1
		}
		{
			\semantex_grab_seventh_argument_of_nine:nnnnnnnnn ##1
		}
		{
			\semantex_grab_eighth_argument_of_nine:nnnnnnnnn ##1
		}
		{
			\semantex_grab_ninth_argument_of_nine:nnnnnnnnn ##1
		}
	}
	%IM Remove spaces in #2
}

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_novaluekeys:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_singlekeys:nn % Previously, "singlekeys" was called "novaluekeys", so I am keeping this alias for backwards compatibility

\cs_set_eq:cN { __semantex_data_cs_custom_valuekey_class_SemantexBaseObject_0valuekeys:nn } \__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_singlekeys:nn


\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_removenovaluekey:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_removesinglekey:nn % Previously, "singlekeys" was called "novaluekeys", so I am keeping this alias for backwards compatibility

\cs_set_eq:cN { __semantex_data_cs_custom_valuekey_class_SemantexBaseObject_remove0valuekey:nn } \__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_removesinglekey:nn

% KEYS FOR SETTING UP THE ARGUMENT KEYVAL INTERFACE:

\cs_new:Npn\__semantex_process_arg_singlekey:nnN#1#2#3
{
	\tl_put_right:Nn#3
	{
		\semantex_arg_singlekey:nn { #1 } { #2 }
	}
}

\cs_generate_variant:Nn \semantex_valuekey:nnn { nnx }

\cs_new:Npn\__semantex_process_arg_valuekey:nnnN#1#2#3#4
{
	\tl_put_right:Nn#4
	{
		\semantex_arg_valuekey:nnn { #1 } { #2 } { #3 }
	}	
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_argvaluekeys:nn#1#2{
	% Add argument valuekeys
	\clist_map_inline:nn { #2 }{
		\__semantex_arg_valuekey_format_auxiliary:nnn{#1}##1
	}
}

\cs_new:Npn \__semantex_arg_valuekey_format_auxiliary:nnn#1#2#3
{
	\tl_set:Nn\l__semantex_arg_valuekey_auxiliary_temp_tl{}
	\cs_set:Npn\l__semantex_arg_valuekey_auxiliary_singlekey_temp_cs:n##1
	{
		\__semantex_process_arg_singlekey:nnN { ####1 } { ##1 } \l__semantex_arg_valuekey_auxiliary_temp_tl
	}
	\cs_set:Npn\l__semantex_arg_valuekey_auxiliary_valuekey_temp_cs:nn##1##2
	{
		\__semantex_process_arg_valuekey:nnnN { ####1 } { ##1 } { ##2 } \l__semantex_arg_valuekey_auxiliary_temp_tl
	}
	\cs_set:Npn\l__semantex_arg_valuekey_auxiliary_temp_cs:n##1 { #3 }
	\keyval_parse:NNo
		\l__semantex_arg_valuekey_auxiliary_singlekey_temp_cs:n
		\l__semantex_arg_valuekey_auxiliary_valuekey_temp_cs:nn
		{
			\l__semantex_arg_valuekey_auxiliary_temp_cs:n { ##2 }
		}
	\cs_set:cpo { __semantex_data_cs_custom_arg_valuekey_#1_#2:nn } ##1##2 {
		\l__semantex_arg_valuekey_auxiliary_temp_tl
	}
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_argsinglekeys:nn#1#2{
	% Add argument keys taking no values
	\clist_map_inline:nn { #2 }{
		\__semantex_arg_singlekeys_format_auxiliary:nnn{#1}##1
	}
}

\cs_new:Npn \__semantex_arg_singlekeys_format_auxiliary:nnn#1#2#3{
	\tl_set:Nn\l__semantex_arg_singlekey_auxiliary_temp_tl{}
	\cs_set:Npn\l__semantex_arg_singlekey_auxiliary_singlekey_temp_cs:n##1
	{
		\__semantex_process_arg_singlekey:nnN { ####1 } { ##1 } \l__semantex_arg_singlekey_auxiliary_temp_tl
	}
	\cs_set:Npn\l__semantex_arg_singlekey_auxiliary_valuekey_temp_cs:nn##1##2
	{
		\__semantex_process_arg_valuekey:nnnN { ####1 } { ##1 } { ##2 } \l__semantex_arg_singlekey_auxiliary_temp_tl
	}
	\cs_set:Npn\l__semantex_arg_singlekey_auxiliary_temp_cs: { #3 }
	\keyval_parse:NNo
		\l__semantex_arg_singlekey_auxiliary_singlekey_temp_cs:n
		\l__semantex_arg_singlekey_auxiliary_valuekey_temp_cs:nn
		{ \l__semantex_arg_singlekey_auxiliary_temp_cs: }
	\cs_set:cpo { __semantex_data_cs_custom_arg_singlekey_#1_#2:n } ##1 {
		\l__semantex_arg_singlekey_auxiliary_temp_tl
	}
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_removeargsinglekey:nn#1#2
{
	\cs_undefine:c { __semantex_data_cs_custom_arg_singlekey_#1_#2:n }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_removeargvaluekey:nn#1#2
{
	\cs_undefine:c { __semantex_data_cs_custom_arg_valuekey_#1_#2:nn }
}

\cs_set_eq:cN { __semantex_data_cs_custom_valuekey_class_SemantexBaseObject_arg1valuekeys:nn } \__semantex_data_cs_custom_arg_valuekey_class_SemantexBaseObject_arg_valuekeys:nn

\cs_new:cpn { __semantex_data_cs_custom_valuekey_class_SemantexBaseObject_arg2valuekeys:nn }#1#2{
	% Add new valuekeys
	\clist_map_inline:nn { #2 }{
		\__semantex_two_arg_valuekey_format_auxiliary:nnn{#1}##1
	}
}

\cs_generate_variant:Nn \__semantex_arg_valuekey_format_auxiliary:nnn { nno }

\cs_new:Npn\__semantex_two_arg_valuekey_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_two_arg_valuekey_format_auxiliary_temp:nn##1##2{#3}
	\__semantex_arg_valuekey_format_auxiliary:nno { #1 } { #2 }
	{
		\l__semantex_two_arg_valuekey_format_auxiliary_temp:nn
		{
			\semantex_grab_first_argument_of_two:nn ##1
		}
		{
			\semantex_grab_second_argument_of_two:nn ##1
		}
	}
	%IM Remove spaces in #2
}

\cs_new:cpn { __semantex_data_cs_custom_valuekey_class_SemantexBaseObject_arg3valuekeys:nn }#1#2{
	% Add new valuekeys
	\clist_map_inline:nn { #2 }{
		\__semantex_three_arg_valuekey_format_auxiliary:nnn{#1}##1
	}
}

\cs_new:Npn\__semantex_three_arg_valuekey_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_three_arg_valuekey_format_auxiliary_temp:nnn##1##2##3{#3}
	\__semantex_arg_valuekey_format_auxiliary:nno { #1 } { #2 }
	{
		\l__semantex_three_arg_valuekey_format_auxiliary_temp:nnn
		{
			\semantex_grab_first_argument_of_three:nnn ##1
		}
		{
			\semantex_grab_second_argument_of_three:nnn ##1
		}
		{
			\semantex_grab_third_argument_of_three:nnn ##1
		}
	}
	%IM Remove spaces in #2
}

\cs_new:cpn { __semantex_data_cs_custom_valuekey_class_SemantexBaseObject_arg4valuekeys:nn }#1#2{
	% Add new valuekeys
	\clist_map_inline:nn { #2 }{
		\__semantex_four_arg_valuekey_format_auxiliary:nnn{#1}##1
	}
}

\cs_new:Npn\__semantex_four_arg_valuekey_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_four_arg_valuekey_format_auxiliary_temp:nnnn##1##2##3##4{#3}
	\__semantex_arg_valuekey_format_auxiliary:nno { #1 } { #2 }
	{
		\l__semantex_four_arg_valuekey_format_auxiliary_temp:nnnn
		{
			\semantex_grab_first_argument_of_four:nnnn ##1
		}
		{
			\semantex_grab_second_argument_of_four:nnnn ##1
		}
		{
			\semantex_grab_third_argument_of_four:nnnn ##1
		}
		{
			\semantex_grab_fourth_argument_of_four:nnnn ##1
		}
	}
	%IM Remove spaces in #2
}

\cs_new:cpn { __semantex_data_cs_custom_valuekey_class_SemantexBaseObject_arg5valuekeys:nn }#1#2{
	% Add new valuekeys
	\clist_map_inline:nn { #2 }{
		\__semantex_five_arg_valuekey_format_auxiliary:nnn{#1}##1
	}
}

\cs_new:Npn\__semantex_five_arg_valuekey_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_five_arg_valuekey_format_auxiliary_temp:nnnnn##1##2##3##4##5{#3}
	\__semantex_arg_valuekey_format_auxiliary:nno { #1 } { #2 }
	{
		\l__semantex_five_arg_valuekey_format_auxiliary_temp:nnnnn
		{
			\semantex_grab_first_argument_of_five:nnnnn ##1
		}
		{
			\semantex_grab_second_argument_of_five:nnnnn ##1
		}
		{
			\semantex_grab_third_argument_of_five:nnnnn ##1
		}
		{
			\semantex_grab_fourth_argument_of_five:nnnnn ##1
		}
		{
			\semantex_grab_fifth_argument_of_five:nnnnn ##1
		}
	}
	%IM Remove spaces in #2
}

\cs_new:cpn { __semantex_data_cs_custom_valuekey_class_SemantexBaseObject_arg6valuekeys:nn }#1#2{
	% Add new valuekeys
	\clist_map_inline:nn { #2 }{
		\__semantex_six_arg_valuekey_format_auxiliary:nnn{#1}##1
	}
}

\cs_new:Npn\__semantex_six_arg_valuekey_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_six_arg_valuekey_format_auxiliary_temp:nnnnnn##1##2##3##4##5##6{#3}
	\__semantex_arg_valuekey_format_auxiliary:nno { #1 } { #2 }
	{
		\l__semantex_six_arg_valuekey_format_auxiliary_temp:nnnnnn
		{
			\semantex_grab_first_argument_of_six:nnnnnn ##1
		}
		{
			\semantex_grab_second_argument_of_six:nnnnnn ##1
		}
		{
			\semantex_grab_third_argument_of_six:nnnnnn ##1
		}
		{
			\semantex_grab_fourth_argument_of_six:nnnnnn ##1
		}
		{
			\semantex_grab_fifth_argument_of_six:nnnnnn ##1
		}
		{
			\semantex_grab_sixth_argument_of_six:nnnnnn ##1
		}
	}
	%IM Remove spaces in #2
}

\cs_new:cpn { __semantex_data_cs_custom_valuekey_class_SemantexBaseObject_arg7valuekeys:nn }#1#2{
	% Add new valuekeys
	\clist_map_inline:nn { #2 }{
		\__semantex_seven_arg_valuekey_format_auxiliary:nnn{#1}##1
	}
}

\cs_new:Npn\__semantex_seven_arg_valuekey_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_seven_arg_valuekey_format_auxiliary_temp:nnnnnnn##1##2##3##4##5##6##7{#3}
	\__semantex_arg_valuekey_format_auxiliary:nno { #1 } { #2 }
	{
		\l__semantex_seven_arg_valuekey_format_auxiliary_temp:nnnnnnn
		{
			\semantex_grab_first_argument_of_seven:nnnnnnn ##1
		}
		{
			\semantex_grab_second_argument_of_seven:nnnnnnn ##1
		}
		{
			\semantex_grab_third_argument_of_seven:nnnnnnn ##1
		}
		{
			\semantex_grab_fourth_argument_of_seven:nnnnnnn ##1
		}
		{
			\semantex_grab_fifth_argument_of_seven:nnnnnnn ##1
		}
		{
			\semantex_grab_sixth_argument_of_seven:nnnnnnn ##1
		}
		{
			\semantex_grab_seventh_argument_of_seven:nnnnnnn ##1
		}
	}
	%IM Remove spaces in #2
}

\cs_new:cpn { __semantex_data_cs_custom_valuekey_class_SemantexBaseObject_arg8valuekeys:nn }#1#2{
	% Add new valuekeys
	\clist_map_inline:nn { #2 }{
		\__semantex_eight_arg_valuekey_format_auxiliary:nnn{#1}##1
	}
}

\cs_new:Npn\__semantex_eight_arg_valuekey_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_eight_arg_valuekey_format_auxiliary_temp:nnnnnnnn##1##2##3##4##5##6##7##8{#3}
	\__semantex_arg_valuekey_format_auxiliary:nno { #1 } { #2 }
	{
		\l__semantex_eight_arg_valuekey_format_auxiliary_temp:nnnnnnnn
		{
			\semantex_grab_first_argument_of_eight:nnnnnnnn ##1
		}
		{
			\semantex_grab_second_argument_of_eight:nnnnnnnn ##1
		}
		{
			\semantex_grab_third_argument_of_eight:nnnnnnnn ##1
		}
		{
			\semantex_grab_fourth_argument_of_eight:nnnnnnnn ##1
		}
		{
			\semantex_grab_fifth_argument_of_eight:nnnnnnnn ##1
		}
		{
			\semantex_grab_sixth_argument_of_eight:nnnnnnnn ##1
		}
		{
			\semantex_grab_seventh_argument_of_eight:nnnnnnnn ##1
		}
		{
			\semantex_grab_eighth_argument_of_eight:nnnnnnnn ##1
		}
	}
	%IM Remove spaces in #2
}

\cs_new:cpn { __semantex_data_cs_custom_valuekey_class_SemantexBaseObject_arg9valuekeys:nn }#1#2{
	% Add new valuekeys
	\clist_map_inline:nn { #2 }{
		\__semantex_nine_arg_valuekey_format_auxiliary:nnn{#1}##1
	}
}

\cs_new:Npn\__semantex_nine_arg_valuekey_format_auxiliary:nnn#1#2#3
{
	\cs_set:Npn\l__semantex_nine_arg_valuekey_format_auxiliary_temp:nnnnnnnnn##1##2##3##4##5##6##7##8##9{#3}
	\__semantex_arg_valuekey_format_auxiliary:nno { #1 } { #2 }
	{
		\l__semantex_nine_arg_valuekey_format_auxiliary_temp:nnnnnnnnn
		{
			\semantex_grab_first_argument_of_nine:nnnnnnnnn ##1
		}
		{
			\semantex_grab_second_argument_of_nine:nnnnnnnnn ##1
		}
		{
			\semantex_grab_third_argument_of_nine:nnnnnnnnn ##1
		}
		{
			\semantex_grab_fourth_argument_of_nine:nnnnnnnnn ##1
		}
		{
			\semantex_grab_fifth_argument_of_nine:nnnnnnnnn ##1
		}
		{
			\semantex_grab_sixth_argument_of_nine:nnnnnnnnn ##1
		}
		{
			\semantex_grab_seventh_argument_of_nine:nnnnnnnnn ##1
		}
		{
			\semantex_grab_eighth_argument_of_nine:nnnnnnnnn ##1
		}
		{
			\semantex_grab_ninth_argument_of_nine:nnnnnnnnn ##1
		}
	}
	%IM Remove spaces in #2
}

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_argnovaluekeys:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_argsinglekeys:nn % Previously, "singlekeys" was called "novaluekeys", so I am keeping this alias for backwards compatibility

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_removeargnovaluekey:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_removeargsinglekey:nn % Previously, "singlekeys" was called "novaluekeys", so I am keeping this alias for backwards compatibility

\cs_set_eq:cN { __semantex_data_cs_custom_valuekey_class_SemantexBaseObject_removearg0valuekey:nn } \__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_removeargsinglekey:nn

% THESE ARE REALLY THE COMMANDS MANIPULATING DATA:

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_symbol:nn#1#2{
	% Sets the value of the symbol
	\semantex_data_tl_set:nnn { #1 } { symbol } { \exp_not:n { #2 } }
}

\cs_generate_variant:Nn \__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_symbol:nn { xn }

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_texclass:nn#1#2{
	% Sets the TeX class of the output, e.g. \mathord, \mathbin, \mathop etc.
	\semantex_data_tl_set:nnn { #1 } { texclass } { \exp_not:n { #2 } }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setslot:nn#1#2{
	% Sets the argument slot, i.e. the - in f(-,x)
	\semantex_data_tl_set:nnn { #1 } { argslot } { \exp_not:n { #2 } }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_symbolputright:nn#1#2{
	% Add something to the right of the symbol
	\semantex_data_tl_put_right:nnn { #1 } { symbol } { \exp_not:n { #2 } }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_symbolputleft:nn#1#2{
	% Add something to the left of the symbol
	\semantex_data_tl_put_left:nnn { #1 } { symbol } { \exp_not:n { #2 } }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_command:nn#1#2{
	% Adds one entry on the left of the command
	% sequence to be applied to the symbol
	\semantex_data_seq_put_right:nnn { #1 } { commands_sequence } { #2 } %IM maybe \exp_not:n { #2 }?
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clearcommand:nn#1#2{
	% Adds one entry on the left of the command
	% sequence to be applied to the symbol
	\semantex_data_seq_clear:nn { #1 } { commands_sequence }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_argwithkeyval:nn#1#2{
	% Sets the argument (allows keyval interface)
	\semantex_arg_keys_set:nn { #1 } { #2 }
	%IMPORTANT: Previously, we needed three braces around #2, but suddenly
	% this changed, even though I did not really change anything related
	% to this (except I added _auxiliary_ in the command names related
	% to arg keyvals)
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_argwithsinglekeys:nn#1#2{
	% Sets the argument (only allows singlekeys)
	\semantex_arg_singlekeys_set:nn { #1 } { #2 }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_argwithonesinglekey:nn#1#2{
	% Sets the argument (only allows one singlekey)
	\use:c { __semantex_data_cs_#1_arg_singlekey:n } { #2 }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_argwithoutkeyval:nn#1#2{
	% Sets the argument (no keyval interface allowed)
	\semantex_data_tl_put_right:nnn { #1 } { arg } { \exp_not:n { #2 } }
	\semantex_data_int_incr:nn { #1 } { numberofarguments } % Check if this has been added elsewhere
	\semantex_data_bool_set_true:nn { #1 } { nextargwithsep }
}


\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setargsep:nn#1#2
{
	% Sets the argument separator
	\semantex_data_tl_set:nnn { #1 } { argsep } { \exp_not:n { #2 } }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setargdots:nn#1#2
{
	% Sets the argument dot command
	\semantex_data_tl_set:nnn { #1 } { argdots } { \exp_not:n { #2 } }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setargslot:nn#1#2
{
	% Sets the argument dot command
	\semantex_data_tl_set:nnn { #1 } { argslot } { \exp_not:n { #2 } }
}


\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_prearg:nn#1#2{
	% Sets something to write before the argument
	\tl_if_blank:nF{#2}
	{
		\semantex_data_tl_put_left:nnn { #1 } { prearg } { \exp_not:n { #2 } }
	}
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clearprearg:nn#1#2
{
	\semantex_data_tl_clear:nn { #1 } { prearg }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_postarg:nn#1#2{
	% Sets something to write after the argument
	\tl_if_blank:nF{#2}
	{
		\semantex_data_tl_put_right:nnn { #1 } { postarg } {  \exp_not:n{ #2 } }
	}
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clearpostarg:nn#1#2
{
	\semantex_data_tl_clear:nn { #1 } { postarg }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_output:nn#1#2
{
	% Tells what class the object is supposed to output
	\semantex_class_if_exist:NTF { #2 }
	{
		\semantex_data_tl_set:nnx { #1 } { output } { class_\cs_to_str:N #2 }
	}
	{
		\semantex_error_output_format:nN { #1 } \l__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_output_temp_tl
		\msg_error:nnxnn { semantex } { class_not_found } { \l__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_output_temp_tl } { output } { #2 }
	}
	% Maybe allow output=self
}


\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_outputoptions:nn#1#2{
	\tl_set:Nn\l__semantex_outputoptions_auxiliary_temp_tl{}
	\cs_set:Npn\l__semantex_outputoptions_auxiliary_singlekey_temp_cs:n##1
	{
		\__semantex_outputoptions_process_singlekey:nnN { ####1 } { ##1 } \l__semantex_outputoptions_auxiliary_temp_tl
	}
	\cs_set:Npn\l__semantex_outputoptions_auxiliary_valuekey_temp_cs:nn##1##2
	{
		\__semantex_outputoptions_process_valuekey:nnnN { ####1 } { ##1 } { ##2 } \l__semantex_outputoptions_auxiliary_temp_tl
	}
	\keyval_parse:NNn
		\l__semantex_outputoptions_auxiliary_singlekey_temp_cs:n
		\l__semantex_outputoptions_auxiliary_valuekey_temp_cs:nn
		{ #2 }
	\semantex_data_tl_put_right:nno { #1 } { outputoptions } { \l__semantex_outputoptions_auxiliary_temp_tl }
	%\exp_args:NNno\exp_args:Nno\cs_set:co { __semantex_data_cs_#1_outputoptions:n }
	%\exp_args:Nnno
	\semantex_data_cs_set:nnx { #1 } { outputoptions:n }
	{
%		g__semantex_data_tl_#1_outputoptions
%		\semantex_data_tl_get:nn { #1 } { outputoptions }
		\semantex_data_tl_get_exp_not:nn { #1 } { outputoptions }
		%\l__semantex_outputoptions_auxiliary_temp_tl
	}
}

\cs_generate_variant:Nn \semantex_data_cs_set:nnn { nnf , nnv , nnx }

\cs_generate_variant:Nn \semantex_data_tl_put_right:nnn { nno }


\cs_new:Npn\__semantex_outputoptions_process_singlekey:nnN#1#2#3
{
	\tl_put_right:Nn#3
	{
		\exp_not:N\semantex_singlekey:nn { #1 } { \exp_not:n { #2 } }
	}
}

\cs_generate_variant:Nn \semantex_valuekey:nnn { nnx }

\cs_new:Npn\__semantex_outputoptions_process_valuekey:nnnN#1#2#3#4
{
	\tl_if_eq:nnTF { #2 } { execute }
	{
		\tl_put_right:Nn#4
		{
			\exp_not:n { #3 }
		}
	}
	{
		\tl_put_right:Nn#4
		{
			\exp_not:N\semantex_valuekey:nnn { #1 } { #2 } { \exp_not:n { #3 } }
		}	
	}
}

%----------------

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ifleftargument:nn#1#2{
	% Tells whether to rightreturn before rendering the output.
	\str_if_eq:nnTF { #2 } { true }
	{
		\semantex_data_bool_set_true:nn { #1 } { leftargument }
	}
	{
		\str_if_eq:nnTF { #2 } { false }
		{
			\semantex_data_bool_set_false:nn { #1 } { leftargument }
		}
		{
			\semantex_error_output_format:nN { #1 } \l__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ifleftargumen_temp_tl
			\msg_error:nnxnn { semantex } { key_value_not_found } { \l__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ifleftargumen_temp_tl } { ifleftargument } { #2 }
		}
	}
}
				
\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ifoutput:nn#1#2{ %IMPLEMENT THIS
	% Tells whether to output or not
	\str_if_eq:nnTF { #2 } { true }
	{
		\semantex_data_bool_set_true:nn { #1 } { output }
	}
	{
		\str_if_eq:nnTF { #2 } { false }
		{
			\semantex_data_bool_set_false:nn { #1 } { output }
		}
		{
			\semantex_error_output_format:nN { #1 } \l__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ifoutput_temp_tl
			\msg_error:nnxnn { semantex } { key_value_not_found } { \l__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ifoutput_temp_tl } { ifoutput } { #2 }
		}
	}
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_gradingposition:nn#1#2{
		% Tells whether to use upper or lower indices
		\semantex_data_bool_provide:nn { #1 } { uppergrading }
		\str_if_eq:nnTF { #2 } { upper }
		{
			\semantex_data_bool_set_true:nn { #1 } { uppergrading }
		}
		{
			\str_if_eq:nnTF { #2 } { lower }
			{
				\semantex_data_bool_set_false:nn { #1 } { uppergrading }
			}
			{
				\semantex_error_output_format:nN { #1 } \l__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_gradingposition_temp_tl
				\msg_error:nnxnn { semantex } { key_value_not_found } { \l__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_gradingposition_temp_tl } { gradingposition } { #2 }
			}
		}
}

\cs_set_eq:NN \__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_gradingpos:nn \__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_gradingposition:nn

% Upper and lower right indices:

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upper:nn#1#2{
	% adds to the upper index
	\tl_if_blank:nF{#2}{
		\semantex_data_tl_put_right:nnn { #1 } { upper } { \exp_not:n{ #2 } }
		\semantex_data_bool_set_true:nn { #1 } { nextupperwithsep }
		\semantex_data_int_incr:nn { #1 } { numberofupperindices }
	}
}



\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_supper:nn#1#2{
	% Adds to the upper index, with a separator
	\tl_if_blank:nF{#2}
	{
		\semantex_data_bool_get:nnTF { #1 } { nextupperwithsep }
		{
			\semantex_data_tl_put_right:nnx { #1 } { upper }
			{ \exp_not:n { \semantex_data_tl_get:nn { #1 } { uppersep } } }
			\semantex_data_tl_put_right:nnn { #1 } { upper } { \exp_not:n { #2 } }
		}
		{
			\semantex_data_tl_put_right:nnn { #1 } { upper } { \exp_not:n { #2 } }
		}
		\semantex_data_bool_set_true:nn { #1 } { nextupperwithsep }
		\semantex_data_int_incr:nn { #1 } { numberofupperindices }
	}
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upperputleft:nn#1#2{
	% Adds to the left of the upper index
	\tl_if_blank:nF{#2}{
		\semantex_data_tl_put_left:nnn { #1 } { upper } { \exp_not:n{ #2 } }
		\semantex_data_bool_set_true:nn { #1 } { nextupperwithsep }
		\semantex_data_int_incr:nn { #1 } { numberofupperindices }
	}
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_preupper:nn#1#2{
	% Sets what to write before upper
	\tl_if_blank:nF{#2}
	{
		\semantex_data_tl_put_left:nnn { #1 } { preupper } { \exp_not:n{ #2 } }
	}
}
\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_postupper:nn#1#2{
	% Sets what to write after upper
	\tl_if_blank:nF{#2}
	{
		\semantex_data_tl_put_right:nnn { #1 } { postupper } {  \exp_not:n{ #2 } }
	}
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clearupper:nn#1#2{
	\semantex_data_tl_clear:nn { #1 } { upper }
	\semantex_data_bool_set_false:nn { #1 } { nextupperwithsep }
	\semantex_data_int_clear:nn { #1 } { numberofupperindices }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clearpreupper:nn#1#2{
	\semantex_data_tl_clear:nn { #1 } { preupper }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clearpostupper:nn#1#2{
	\semantex_data_tl_clear:nn { #1 } { postupper }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setupperdots:nn#1#2
{
	\semantex_data_tl_set:nnn { #1 } { upperdots } { \exp_not:n { #2 } }
}

\cs_generate_variant:Nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upper:nn { nx }

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upperdots:nn#1#2
{
	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upper:nx { #1 } { \semantex_data_tl_get:nn { #1 } { upperdots } }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setupperslot:nn#1#2
{
	\semantex_data_tl_set:nnn { #1 } { upperslot } { \exp_not:n { #2 } }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upperslot:nn#1#2
{
	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upper:nx { #1 } { \semantex_data_tl_get:nn { #1 } { upperslot } }
}

\cs_generate_variant:Nn \__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_supper:nn { nx }

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_supperdots:nn#1#2
{
	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_supper:nx { #1 } { \semantex_data_tl_get:nn { #1 } { upperdots } }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_supperslot:nn#1#2
{
	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_supper:nx { #1 } { \semantex_data_tl_get:nn { #1 } { upperslot } }
}

\cs_generate_variant:Nn \__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cupper:nn { nx }

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cupperdots:nn#1#2
{
	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cupper:nx { #1 } { \semantex_data_tl_get:nn { #1 } { upperdots } }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cupperslot:nn#1#2
{
	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cupper:nx { #1 } { \semantex_data_tl_get:nn { #1 } { upperslot } }
}

\cs_generate_variant:Nn \__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upperwithothersep:nn { nx }

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upperdotswithothersep:nn#1#2
{
	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upperwithothersep:nx { #1 } { { \exp_not:n { #2 } } { \semantex_data_tl_get:nn { #1 } { upperdots } } }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upperslotwithothersep:nn#1#2
{
	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upperwithothersep:nx { #1 } { { \exp_not:n { #2 } } { \semantex_data_tl_get:nn { #1 } { upperslot } } }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lower:nn#1#2{
	% Adds to the lower index
	\tl_if_blank:nF{#2}
	{
		\semantex_data_tl_put_right:nnn { #1 } { lower } { \exp_not:n { #2 } }
		\semantex_data_bool_set_true:nn { #1 } { nextlowerwithsep }
		\semantex_data_int_incr:nn { #1 } { numberoflowerindices }
	}
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_slower:nn#1#2{
	% Adds to the lower index, with a separator
	\tl_if_blank:nF{#2}
	{
		\semantex_data_bool_get:nnTF { #1 } { nextlowerwithsep }
		{
			\semantex_data_tl_put_right:nnx { #1 } { lower }
			{ \exp_not:n { \semantex_data_tl_get:nn { #1 } { lowersep } } }
			\semantex_data_tl_put_right:nnn { #1 } { lower } { \exp_not:n { #2 } }
		}
		{
			\semantex_data_tl_put_right:nnn { #1 } { lower } { \exp_not:n { #2 } }
		}
		\semantex_data_bool_set_true:nn { #1 } { nextlowerwithsep }
		\semantex_data_int_incr:nn { #1 } { numberoflowerindices }
	}
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lowerputleft:nn#1#2{
	% Adds to the lower index
	\tl_if_blank:nF{#2}
	{
		\semantex_data_tl_put_left:nnn { #1 } { lower } { \exp_not:n { #2 } }
		\semantex_data_bool_set_true:nn { #1 } { nextlowerwithsep }
		\semantex_data_int_incr:nn { #1 } { numberoflowerindices }
	}
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_prelower:nn#1#2{
	% Sets what to write before the lower index
	\tl_if_blank:nF{#2}
	{
		\semantex_data_tl_put_left:nnn { #1 } { prelower } { \exp_not:n { #2 } }
	}
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_postlower:nn#1#2{
	% Sets what to write after the lower index
	\tl_if_blank:nF{#2}
	{
		\semantex_data_tl_put_right:nnn { #1 } { postlower } { \exp_not:n{ #2 } }
	}
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clearlower:nn#1#2{
	\semantex_data_tl_clear:nn { #1 } { lower }
	\semantex_data_bool_set_false:nn { #1 } { nextlowerwithsep }
	\semantex_data_int_clear:nn { #1 } { numberoflowerindices }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clearprelower:nn#1#2{
	\semantex_data_tl_clear:nn { #1 } { prelower }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clearpostlower:nn#1#2{
	\semantex_data_tl_clear:nn { #1 } { postlower }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setlowerdots:nn#1#2
{
	\semantex_data_tl_set:nnn { #1 } { lowerdots } { \exp_not:n { #2 } }
}

\cs_generate_variant:Nn \__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lower:nn { nx }

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lowerdots:nn#1#2
{
	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lower:nx { #1 } { \semantex_data_tl_get:nn { #1 } { lowerdots } }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setlowerslot:nn#1#2
{
	\semantex_data_tl_set:nnn { #1 } { lowerslot } { \exp_not:n { #2 } }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lowerslot:nn#1#2
{
	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lower:nx { #1 } { \semantex_data_tl_get:nn { #1 } { lowerslot } }
}

\cs_generate_variant:Nn \__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_slower:nn { nx }

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_slowerdots:nn#1#2
{
	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_slower:nx { #1 } { \semantex_data_tl_get:nn { #1 } { lowerdots } }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_slowerslot:nn#1#2
{
	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_slower:nx { #1 } { \semantex_data_tl_get:nn { #1 } { lowerslot } }
}

\cs_generate_variant:Nn \__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clower:nn { nx }

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clowerdots:nn#1#2
{
	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clower:nx { #1 } { \semantex_data_tl_get:nn { #1 } { lowerdots } }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clowerslot:nn#1#2
{
	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clower:nx { #1 } { \semantex_data_tl_get:nn { #1 } { lowerslot } }
}

\cs_generate_variant:Nn \__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lowerwithothersep:nn { nx }

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lowerdotswithothersep:nn#1#2
{
	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lowerwithothersep:nx { #1 } { { \exp_not:n { #2 } } { \semantex_data_tl_get:nn { #1 } { lowerdots } } }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lowerslotwithothersep:nn#1#2
{
	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lowerwithothersep:nx { #1 } { { \exp_not:n { #2 } } { \semantex_data_tl_get:nn { #1 } { lowerslot } } }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upperwithothersep:nn#1#2{
	% upperwithsep={separator}{contents} adds contents to the upper index
	% with the appropriate index separator
	\semantex_data_bool_get:nnTF { #1 } { nextupperwithsep }
	{
		\semantex_data_tl_put_right:nnn { #1 } { upper } {
			\exp_not:n {
				\semantex_grab_first_argument_of_two:nn #2
				\semantex_grab_second_argument_of_two:nn #2
			}
		}
	}
	{
		\semantex_data_tl_put_right:nnn { #1 } { upper } {
			\exp_not:n {
				\semantex_grab_second_argument_of_two:nn #2
			}
		}
	}
	\semantex_data_bool_set_true:nn { #1 } { nextupperwithsep }
	\semantex_data_int_incr:nn { #1 } { numberofupperindices }
}


\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lowerwithothersep:nn#1#2{
	% lowerwithsep={separator}{contents} adds contents to the lower index
	% with the appropriate index separator
	\semantex_data_bool_get:nnTF { #1 } { nextlowerwithsep }
	{
		\semantex_data_tl_put_right:nnn { #1 } { lower } {
			\exp_not:n {
				\semantex_grab_first_argument_of_two:nn  #2
				\semantex_grab_second_argument_of_two:nn #2
			}
		}
	}
	{
		\semantex_data_tl_put_right:nnn { #1 } { lower } {
			\exp_not:n {
				\semantex_grab_second_argument_of_two:nn #2
			}
		}
	}
	\semantex_data_bool_set_true:nn { #1 } { nextlowerwithsep }
	\semantex_data_int_incr:nn { #1 } { numberofupperindices }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cupper:nn#1#2{
	% Adds to the upper index, with a comma as separator
	\tl_if_blank:nF{#2}
	{
		\semantex_data_bool_get:nnTF { #1 } { nextupperwithsep }
		{
			\semantex_data_tl_put_right:nnn { #1 } { upper } { , \exp_not:n { #2 } }
		}
		{
			\semantex_data_tl_put_right:nnn { #1 } { upper } { \exp_not:n { #2 } }
		}
		\semantex_data_bool_set_true:nn { #1 } { nextupperwithsep }
		\semantex_data_int_incr:nn { #1 } { numberofupperindices }
	}
}


\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clower:nn#1#2{
	% Adds to the lower index, with a comma as separator
	\tl_if_blank:nF{#2}
	{
		\semantex_data_bool_get:nnTF { #1 } { nextlowerwithsep }
		{
			\semantex_data_tl_put_right:nnn { #1 } { lower } { , \exp_not:n { #2 } }
		}
		{
			\semantex_data_tl_put_right:nnn { #1 } { lower } { \exp_not:n { #2 } }
		}
		\semantex_data_bool_set_true:nn { #1 } { nextlowerwithsep }
		\semantex_data_int_incr:nn { #1 } { numberoflowerindices }
	}
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ifnextupperwithsep:nn#1#2
{
	% Tells whether the upper index is the first one
	\tl_if_eq:nnTF { #2 } { false }
	{
		\semantex_data_bool_set_false:nn { #1 } { nextupperwithsep }
	}
	{
		\tl_if_eq:nnTF { #2 } { true }
		{
			\semantex_data_bool_set_true:nn { #1 } { nextupperwithsep }
		}
		{
			\semantex_error_output_format:nN { #1 } \l__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ifnextupperwithsep_temp_tl
			\msg_error:nnxnn { semantex } { key_value_not_found } { \l__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ifnextupperwithsep_temp_tl } { ifnextupperwithsep } { #2 }
		}
	}
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ifnextlowerwithsep:nn#1#2 % should be removed later
{
	% Tells whether the lower index is the first one
	\tl_if_eq:nnTF { #2 } { false }
	{
		\semantex_data_bool_set_false:nn { #1 } { nextlowerwithsep }
	}
	{
		\tl_if_eq:nnTF { #2 } { true }
		{
			\semantex_data_bool_set_true:nn { #1 } { nextlowerwithsep }
		}
		{
			\semantex_error_output_format:nN { #1 } \l__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ifnextlowerwithsep_temp_tl
			\msg_error:nnxnn { semantex } { key_value_not_found } { \l__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ifnextlowerwithsep_temp_tl } { ifnextlowerwithsep } { #2 }
		}
	}
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setuppersep:nn#1#2
{
	% Sets the separator for the upper index
	\semantex_data_tl_set:nnn { #1 } { uppersep } { \exp_not:n { #2 }}
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setlowersep:nn#1#2
{
	% Sets the separator for the lower index
	\semantex_data_tl_set:nnn { #1 } { lowersep } { \exp_not:n { #2 }}
}

%--------------- Left indices: (I don't repeat all of the documentation)

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upperleft:nn#1#2{
	% adds to the upper left index
	\tl_if_blank:nF{#2}{
		\semantex_data_tl_put_left:nnn { #1 } { upperleft } { \exp_not:n{ #2 } }
		\semantex_data_bool_set_true:nn { #1 } { nextupperleftwithsep }
		\semantex_data_int_incr:nn { #1 } { numberofupperleftindices }
	}
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_supperleft:nn#1#2{
	\tl_if_blank:nF{#2}
	{
		\semantex_data_bool_get:nnTF { #1 } { nextupperwithsep }
		{
			\semantex_data_tl_put_left:nnx { #1 } { upperleft }
			{ \exp_not:n { \semantex_data_tl_get:nn { #1 } { uppersep } } }
			\semantex_data_tl_put_left:nnn { #1 } { upperleft } { \exp_not:n { #2 } }
		}
		{
			\semantex_data_tl_put_left:nnn { #1 } { upperleft } { \exp_not:n { #2 } }
		}
		\semantex_data_bool_set_true:nn { #1 } { nextupperleftwithsep }
		\semantex_data_int_incr:nn { #1 } { numberofupperleftindices }
	}
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upperleftputright:nn#1#2{
	\tl_if_blank:nF{#2}{
		\semantex_data_tl_put_right:nnn { #1 } { upperleft } { \exp_not:n{ #2 } }
		\semantex_data_bool_set_true:nn { #1 } { nextupperleftwithsep }
		\semantex_data_int_incr:nn { #1 } { numberofupperleftindices }
	}
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_preupperleft:nn#1#2{
	\tl_if_blank:nF{#2}
	{
		\semantex_data_tl_put_left:nnn { #1 } { preupperleft } { \exp_not:n{ #2 } }
	}
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_postupperleft:nn#1#2{
	% adds to the lower index
	\tl_if_blank:nF{#2}
	{
		\semantex_data_tl_put_right:nnn { #1 } { postupperleft } { \exp_not:n{ #2 } }
	}
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clearupperleft:nn#1#2{
	\semantex_data_tl_clear:nn { #1 } { upperleft }
	\semantex_data_bool_set_false:nn { #1 } { nextupperleftwithsep }
	\semantex_data_int_clear:nn { #1 } { numberofupperleftindices }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clearpreupperleft:nn#1#2{
	\semantex_data_tl_clear:nn { #1 } { preupperleft }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clearpostupperleft:nn#1#2{
	\semantex_data_tl_clear:nn { #1 } { preupperleft }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setupperleftdots:nn#1#2
{
	\semantex_data_tl_set:nnn { #1 } { upperleftdots } { \exp_not:n { #2 } }
}

\cs_generate_variant:Nn \__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upperleft:nn { nx }

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upperleftdots:nn#1#2
{
	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upperleft:nx { #1 } { \semantex_data_tl_get:nn { #1 } { upperleftdots } }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setupperleftslot:nn#1#2
{
	\semantex_data_tl_set:nnn { #1 } { upperleftslot } { \exp_not:n { #2 } }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upperleftslot:nn#1#2
{
	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upperleft:nx { #1 } { \semantex_data_tl_get:nn { #1 } { upperleftslot } }
}

\cs_generate_variant:Nn \__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_supperleft:nn { nx }

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_supperleftdots:nn#1#2
{
	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_supperleft:nx { #1 } { \semantex_data_tl_get:nn { #1 } { upperleftdots } }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_supperleftslot:nn#1#2
{
	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_supperleft:nx { #1 } { \semantex_data_tl_get:nn { #1 } { upperleftslot } }
}

\cs_generate_variant:Nn \__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cupperleft:nn { nx }

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cupperleftdots:nn#1#2
{
	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cupperleft:nx { #1 } { \semantex_data_tl_get:nn { #1 } { upperleftdots } }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cupperleftslot:nn#1#2
{
	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cupperleft:nx { #1 } { \semantex_data_tl_get:nn { #1 } { upperleftslot } }
}

\cs_generate_variant:Nn \__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upperleftwithothersep:nn { nx }

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upperleftdotswithothersep:nn#1#2
{
	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upperleftwithothersep:nx { #1 } { { \exp_not:n { #2 } } { \semantex_data_tl_get:nn { #1 } { upperleftdots } } }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upperleftslotwithothersep:nn#1#2
{
	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upperleftwithothersep:nx { #1 } { { \exp_not:n { #2 } } { \semantex_data_tl_get:nn { #1 } { upperleftslot } } }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lowerleft:nn#1#2{
	\tl_if_blank:nF{#2}
	{
		\semantex_data_tl_put_left:nnn { #1 } { lowerleft } { \exp_not:n{ #2 } }
		\semantex_data_bool_set_true:nn { #1 } { nextlowerleftwithsep }
		\semantex_data_int_incr:nn { #1 } { numberoflowerleftindices }
	}
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_slowerleft:nn#1#2{
	\tl_if_blank:nF{#2}
	{
		\semantex_data_bool_get:nnTF { #1 } { nextlowerleftwithsep }
		{
			\semantex_data_tl_put_left:nnx { #1 } { lowerleft }
			{ \exp_not:n { \semantex_data_tl_get:nn { #1 } { lowerleftsep } } }
			\semantex_data_tl_put_left:nnn { #1 } { lowerleft } { \exp_not:n { #2 } }
		}
		{
			\semantex_data_tl_put_left:nnn { #1 } { lowerleft } { \exp_not:n { #2 } }
		}
		\semantex_data_bool_set_true:nn { #1 } { nextlowerleftwithsep }
		\semantex_data_int_incr:nn { #1 } { numberoflowerleftindices }
	}
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lowerleftputright:nn#1#2{
	\tl_if_blank:nF{#2} %This test really shouldn’t be made.
	{
		\semantex_data_tl_put_right:nnn { #1 } { lowerleft } { \exp_not:n{ #2 } }
		\semantex_data_bool_set_true:nn { #1 } { nextlowerleftwithsep }
		\semantex_data_int_incr:nn { #1 } { numberoflowerleftindices }
	}
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_prelowerleft:nn#1#2{
	\tl_if_blank:nF{#2}
	{
		\semantex_data_tl_put_left:nnn { #1 } { prelowerleft } { \exp_not:n{ #2 } }
	}
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_postlowerleft:nn#1#2{
	\tl_if_blank:nF{#2}
	{
		\semantex_data_tl_put_right:nnn { #1 } { postlowerleft } { \exp_not:n{ #2 } }
	}
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upperleftwithothersep:nn#1#2{
	\semantex_data_bool_get:nnTF { #1 } { nextupperleftwithsep }
	{
		\semantex_data_tl_put_left:nnn { #1 } { upperleft } {
			\exp_not:n { \semantex_grab_second_argument_of_two:nn #2 \semantex_grab_first_argument_of_two:nn #2 }
		}
	}
	{
		\semantex_data_tl_put_left:nnn { #1 } { upperleft } {
			\exp_not:n { \semantex_grab_second_argument_of_two:nn #2 }
		}
	}
	\semantex_data_bool_set_true:nn { #1 } { nextupperleftwithsep }
	\semantex_data_int_incr:nn { #1 } { numberofupperleftindices }
}


\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lowerleftwithothersep:nn#1#2{
	\semantex_data_bool_get:nnTF { #1 } { nextlowerleftwithsep }
	{
		\semantex_data_tl_put_left:nnn { #1 } { lowerleft } {
			\exp_not:n { \semantex_grab_second_argument_of_two:nn #2 \semantex_grab_first_argument_of_two:nn #2 }
		}
	}
	{
		\semantex_data_tl_put_left:nnn { #1 } { lowerleft } {
			\exp_not:n { \semantex_grab_second_argument_of_two:nn #2 }
		}
	}
	\semantex_data_bool_set_true:nn { #1 } { nextlowerleftwithsep }
	\semantex_data_int_incr:nn { #1 } { numberoflowerleftindices }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clearlowerleft:nn#1#2{
	\semantex_data_tl_clear:nn { #1 } { lowerleft }
	\semantex_data_bool_set_false:nn { #1 } { nextlowerleftwithsep }
	\semantex_data_int_clear:nn { #1 } { numberoflowerleftindices }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clearprelowerleft:nn#1#2{
	\semantex_data_tl_clear:nn { #1 } { prelowerleft }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clearpostlowerleft:nn#1#2{
	\semantex_data_tl_clear:nn { #1 } { prelowerleft }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setlowerleftdots:nn#1#2
{
	\semantex_data_tl_set:nnn { #1 } { lowerleftdots } { \exp_not:n { #2 } }
}

\cs_generate_variant:Nn \__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lowerleft:nn { nx }

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lowerleftdots:nn#1#2
{
	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lowerleft:nx { #1 } { \semantex_data_tl_get:nn { #1 } { lowerleftdots } }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setlowerleftslot:nn#1#2
{
	\semantex_data_tl_set:nnn { #1 } { lowerleftslot } { \exp_not:n { #2 } }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lowerleftslot:nn#1#2
{
	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lowerleft:nx { #1 } { \semantex_data_tl_get:nn { #1 } { lowerleftslot } }
}

\cs_generate_variant:Nn \__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_slowerleft:nn { nx }

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_slowerleftdots:nn#1#2
{
	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_slowerleft:nx { #1 } { \semantex_data_tl_get:nn { #1 } { lowerleftdots } }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_slowerleftslot:nn#1#2
{
	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_slowerleft:nx { #1 } { \semantex_data_tl_get:nn { #1 } { lowerleftslot } }
}

\cs_generate_variant:Nn \__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clowerleft:nn { nx }

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clowerleftdots:nn#1#2
{
	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clowerleft:nx { #1 } { \semantex_data_tl_get:nn { #1 } { lowerleftdots } }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clowerleftslot:nn#1#2
{
	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clowerleft:nx { #1 } { \semantex_data_tl_get:nn { #1 } { lowerleftslot } }
}

\cs_generate_variant:Nn \__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lowerleftwithothersep:nn { nx }

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lowerleftdotswithothersep:nn#1#2
{
	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lowerleftwithothersep:nx { #1 } { { \exp_not:n { #2 } } { \semantex_data_tl_get:nn { #1 } { lowerleftdots } } }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lowerleftslotwithothersep:nn#1#2
{
	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lowerleftwithothersep:nx { #1 } { { \exp_not:n { #2 } } { \semantex_data_tl_get:nn { #1 } { lowerleftslot } } }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cupperleft:nn#1#2{
	\tl_if_blank:nF{#2}
	{
		\semantex_data_bool_get:nnTF { #1 } { nextupperleftwithsep }
		{
			\semantex_data_tl_put_left:nnn { #1 } { upperleft } { \exp_not:n { #2 } , }
		}
		{
			\semantex_data_tl_put_left:nnn { #1 } { upperleft } { \exp_not:n { #2 } }
		}
		\semantex_data_bool_set_true:nn { #1 } { nextupperleftwithsep }
		\semantex_data_int_incr:nn { #1 } { numberofupperleftindices }
	}
}


\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clowerleft:nn#1#2{
	\tl_if_blank:nF{#2}
	{
		\semantex_data_bool_get:nnTF { #1 } { nextlowerleftwithsep }
		{
			\semantex_data_tl_put_left:nnn { #1 } { lowerleft } { \exp_not:n { #2 } , }
		}
		{
			\semantex_data_tl_put_left:nnn { #1 } { lowerleft } { \exp_not:n { #2 } }
		}
		\semantex_data_bool_set_true:nn { #1 } { nextlowerleftwithsep }
		\semantex_data_int_incr:nn { #1 } { numberoflowerleftindices }
	}
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ifnextupperleftwithsep:nn#1#2
{
	\tl_if_eq:nnTF { #2 } { false }
	{
		\semantex_data_bool_set_false:nn { #1 } { nextupperleftwithsep }
	}
	{
		\tl_if_eq:nnTF { #2 } { true }
		{
			\semantex_data_bool_set_true:nn { #1 } { nextupperleftwithsep }
		}
		{
			\semantex_error_output_format:nN { #1 } \l__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ifnextupperleftwithsep_temp_tl
			\msg_error:nnxnn { semantex } { key_value_not_found } { \l__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ifnextupperleftwithsep_temp_tl } { ifnextupperleftwithsep } { #2 }
		}
	}
}


\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ifnextlowerleftwithsep:nn#1#2
{
	\tl_if_eq:nnTF { #2 } { false }
	{
		\semantex_data_bool_set_false:nn { #1 } { nextlowerleftwithsep }
	}
	{
		\tl_if_eq:nnTF { #2 } { true }
		{
			\semantex_data_bool_set_true:nn { #1 } { nextlowerleftwithsep }
		}
		{
			semantex_error_output_format:nN { #1 } \l__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ifnextlowerleftwithsep_temp_tl
			\msg_error:nnxnn { semantex } { key_value_not_found } { \l__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ifnextlowerleftwithsep_temp_tl } { ifnextlowerleftwithsep } { #2 }
		}
	}
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setupperleftsep:nn#1#2
{
	\semantex_data_tl_set:nnn { #1 } { upperleftsep } { \exp_not:n { #2 } }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setlowerleftsep:nn#1#2
{
	\semantex_data_tl_set:nnn { #1 } { lowerleftsep } { \exp_not:n { #2 } }
}

% Contrary to what you might think, the following commands ARE
% sometimes needed.

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ifnextdwithsep:nn#1#2 % should be removed later
{
	% Tells whether the d (degree) is empty or not
	\str_if_eq:nnTF { #2 } { true }
	{
		\semantex_data_bool_get:nnTF { #1 } { uppergrading }
		{ \__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ifnextupperwithsep:nn { #1 } { #2 } }
		{ \__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ifnextlowerwithsep:nn { #1 } { #2 } }
	}
	{
		\str_if_eq:nnTF { #2 } { false }
		{
			\semantex_data_bool_get:nnTF { #1 } { uppergrading }
			{ \__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ifnextupperwithsep:nn { #1 } { #2 } }
			{ \__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ifnextlowerwithsep:nn { #1 } { #2 } }
		}
		{
			\semantex_error_output_format:nN { #1 } \l__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ifnextdwithsep_temp_tl
			\msg_error:nnxnn { semantex } { key_value_not_found } { \l__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ifnextdwithsep_temp_tl } { ifnextdwithsep } { #2 }
		}
	}
}

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ifnextdegwithsep:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ifnextdwithsep

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ifnextdegreewithsep:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ifnextdwithsep

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ifnextiwithsep:nn#1#2
{
	% Tells whether the i (index) is empty or not
	\str_if_eq:nnTF { #2 } { true }
	{
		\semantex_data_bool_get:nnTF { #1 } { uppergrading }
		{ \__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ifnextlowerwithsep:nn { #1 } { #2 } }
		{ \__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ifnextupperwithsep:nn { #1 } { #2 } }
	}
	{
		\str_if_eq:nnTF { #2 } { false }
		{
			\semantex_data_bool_get:nnTF { #1 } { uppergrading }
			{ \__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ifnextlowerwithsep:nn { #1 } { #2 } }
			{ \__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ifnextupperwithsep:nn { #1 } { #2 } }
		}
		{
			\semantex_error_output_format:nN { #1 } \l__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ifnextiwithsep_temp_tl
			\msg_error:nnxnn { semantex } { key_value_not_found } { \l__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ifnextiwithsep_temp_tl } { ifnextiwithsep } { #2 }
		}
	}
}

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ifnextindexwithsep:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ifnextiwithsep:nn

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_d:nn#1#2
{
	% adds to the d-index (upper by default)
	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
		{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upper:nn { #1 } { #2 }
	}
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lower:nn { #1 } { #2 }
	}
}

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_deg:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_d:nn

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_degree:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_d:nn

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_sd:nn#1#2
{
	% adds to the d-index (upper by default)
	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_supper:nn { #1 } { #2 }
	}
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_slower:nn { #1 } { #2 }
	}
}

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_sdeg:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_sd:nn

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_sdegree:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_sd:nn

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cd:nn#1#2{ %IM Maybe remove this.
	% adds to the d-index (upper by default)
	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cupper:nn { #1 } { #2 }
	}
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clower:nn { #1 } { #2 }
	}
}

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_sdeg:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cd:nn

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_sdegree:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cd:nn


\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_i:nn#1#2{
	% adds to the i-index (lower by default)
	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
		{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lower:nn { #1 } { #2 }
	}
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upper:nn { #1 } { #2 }
	}
}

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_index:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_i:nn

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_si:nn#1#2{
	% adds to the i-index (lower by default)
	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_slower:nn { #1 } { #2 }
	}
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_supper:nn { #1 } { #2 }
	}
}

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_sindex:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_si:nn

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ci:nn#1#2{
	% adds to the i-index (lower by default)
	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clower:nn { #1 } { #2 }
	}
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cupper:nn { #1 } { #2 }
	}
}

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cindex:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ci:nn



\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_dwithothersep:nn#1#2
{
	% adds to the d-index (upper by default)
	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upperwithothersep:nn { #1 } { #2 }
	}
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lowerwithothersep:nn { #1 } { #2 }
	}
}

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_degwithothersep:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_dwithothersep:nn

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_degreewithothersep:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_dwithothersep:nn


\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_iwithothersep:nn#1#2{
	% adds to the i-index (lower by default)
	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lowerwithothersep:nn { #1 } { #2 }
	}
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upperwithothersep:nn { #1 } { #2 }
	}
}

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_indexwithothersep:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_iwithothersep:nn

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setdsep:nn#1#2
{
	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setuppersep:nn { #1 } { #2 }
	}
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setlowersep:nn { #1 } { #2 }
	}
}

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setdegsep:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setdsep:nn

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setdegreesep:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setdsep:nn

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setisep:nn#1#2
{
	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setlowersep:nn { #1 } { #2 }
	}
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setuppersep:nn { #1 } { #2 }
	}
}

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setindexsep:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setisep:nn

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_pred:nn#1#2
{
	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_preupper:nn { #1 } { #2 }
	}
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_prelower:nn { #1 } { #2 }
	}
}

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_predeg:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_pred:nn

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_predegree:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_pred:nn

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_postd:nn#1#2
{
	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_postupper:nn { #1 } { #2 }
	}
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_postlower:nn { #1 } { #2 }
	}
}

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_postdeg:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_postd:nn

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_postdegree:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_postd:nn


\cs_set:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cleard:nn#1#2
{
	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clearupper:nn { #1 } { #2 }
	}
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clearlower:nn { #1 } { #2 }
	}
}

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cleardeg:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cleard:nn

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cleardegree:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cleard:nn


\cs_set:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clearpred:nn#1#2
{
	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clearpreupper:nn { #1 } { #2 }
	}
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clearprelower:nn { #1 } { #2 }
	}
}

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clearpredeg:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clearpred:nn

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clearpredegree:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clearpred:nn


\cs_set:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clearpostd:nn#1#2
{
	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clearpostupper:nn { #1 } { #2 }
	}
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clearpostlower:nn { #1 } { #2 }
	}
}

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clearpostdeg:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clearpostd:nn

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clearpostdegree:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clearpostd:nn


\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_prei:nn#1#2
{
	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_prelower:nn { #1 } { #2 }
	}
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_preupper:nn { #1 } { #2 }
	}
}

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_preindex:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_prei:nn

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_posti:nn#1#2
{
	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_postlower:nn { #1 } { #2 }
	}
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_postupper:nn { #1 } { #2 }
	}
}

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_postindex:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_posti:nn

\cs_set:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cleari:nn#1#2
{
	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clearlower:nn { #1 } { #2 }
	}
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clearupper:nn { #1 } { #2 }
	}
}

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clearindex:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cleari:nn

\cs_set:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clearprei:nn#1#2
{
	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clearprelower:nn { #1 } { #2 }
	}
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clearpreupper:nn { #1 } { #2 }
	}
}

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clearpreindex:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clearprei:nn

\cs_set:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clearposti:nn#1#2
{
	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clearpostlower:nn { #1 } { #2 }
	}
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clearpostupper:nn { #1 } { #2 }
	}
}

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clearpostindex:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clearposti:nn


\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setddots:nn#1#2
{
	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
	{
		\semantex_data_tl_set:nnn { #1 } { upperdots } { \exp_not:n s{ #2 } }
	}
	{
		\semantex_data_tl_set:nnn { #1 } { lowerdots } { \exp_not:n { #2 } }
	}
}

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setdegdots:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setddots:nn

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setdegreedots:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setddots:nn

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ddots:nn#1#2
{
	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upperdots:nn { #1 } { #2 }
	}
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lowerdots:nn { #1 } { #2 }
	}
}

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_degdots:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ddots:nn

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_degreedots:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ddots:nn

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setdslot:nn#1#2
{
	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setupperslot:nn { #1 } { #2 }
	}
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setlowerslot:nn { #1 } { #2 }
	}
}

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setdegslot:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setdslot:nn

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setdegreeslot:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setdslot:nn

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_dslot:nn#1#2
{
	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upperslot:nn { #1 } { #2 }
	}
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lowerslot:nn { #1 } { #2 }
	}
}

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_degslot:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_dslot:nn

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_degreeslot:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_dslot:nn

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_sddots:nn#1#2
{
	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_supperdots:nn { #1 } { #2 }
	}
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_slowerdots:nn { #1 } { #2 }
	}
}

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_sdegdots:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_sddots:nn

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_sdegreedots:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_sddots:nn


\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_sdslot:nn#1#2
{
	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_supperslot:nn { #1 } { #2 }
	}
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_slowerslot:nn { #1 } { #2 }
	}
}

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_sdegslot:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_sdslot:nn

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_sdegreeslot:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_sdslot:nn

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cddots:nn#1#2
{
	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cupperdots:nn { #1 } { #2 }
	}
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clowerdots:nn { #1 } { #2 }
	}
}

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cdegdots:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cddots:nn

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cdegreedots:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cddots:nn

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cdslot:nn#1#2
{
	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cupperslot:nn { #1 } { #2 }
	}
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clowerslot:nn { #1 } { #2 }
	}
}

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cdegslot:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cdslot:nn

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cdegreeslot:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cdslot:nn

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ddotswithothersep:nn#1#2
{
	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upperdotswithothersep:nn { #1 } { #2 }
	}
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lowerdotswithothersep:nn { #1 } { #2 }
	}
}

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_degdotswithothersep:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ddotswithothersep:nn

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_degreedotswithothersep:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ddotswithothersep:nn

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_dslotwithothersep:nn#1#2
{
	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upperslotwithothersep:nn { #1 } { #2 }
	}
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lowerslotwithothersep:nn { #1 } { #2 }
	}
}



%----------------------------------------------------------

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setidots:nn#1#2
{
	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
	{
		\semantex_data_tl_set:nnn { #1 } { lowerdots } { \exp_not:n { #2 } }
	}
	{
		\semantex_data_tl_set:nnn { #1 } { upperdots } { \exp_not:n { #2 } }
	}
}

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setindexdots:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setidots:nn

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setdegreedots:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setidots:nn

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_idots:nn#1#2
{
	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lowerdots:nn { #1 } { #2 }
	}
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upperdots:nn { #1 } { #2 }
	}
}

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_indexdots:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_idots:nn

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_degreedots:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_idots:nn

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setislot:nn#1#2
{
	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setlowerslot:nn { #1 } { #2 }
	}
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setupperslot:nn { #1 } { #2 }
	}
}

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setindexslot:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setislot:nn

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setdegreeslot:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setislot:nn

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_islot:nn#1#2
{
	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lowerslot:nn { #1 } { #2 }
	}
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upperslot:nn { #1 } { #2 }
	}
}

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_indexslot:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_islot:nn

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_degreeslot:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_islot:nn

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_sidots:nn#1#2
{
	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_slowerdots:nn { #1 } { #2 }
	}
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_supperdots:nn { #1 } { #2 }
	}
}

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_sindexdots:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_sidots:nn

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_sdegreedots:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_sidots:nn


\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_sislot:nn#1#2
{
	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_slowerslot:nn { #1 } { #2 }
	}
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_supperslot:nn { #1 } { #2 }
	}
}

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_sindexslot:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_sislot:nn

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_sdegreeslot:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_sislot:nn

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cidots:nn#1#2
{
	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clowerdots:nn { #1 } { #2 }
	}
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cupperdots:nn { #1 } { #2 }
	}
}

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cindexdots:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cidots:nn

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cdegreedots:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cidots:nn

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cislot:nn#1#2
{
	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clowerslot:nn { #1 } { #2 }
	}
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cupperslot:nn { #1 } { #2 }
	}
}

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cindexslot:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cislot:nn

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cdegreeslot:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cislot:nn

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_idotswithothersep:nn#1#2
{
	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lowerdotswithothersep:nn { #1 } { #2 }
	}
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upperdotswithothersep:nn { #1 } { #2 }
	}
}

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_indexdotswithothersep:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_idotswithothersep:nn

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_degreedotswithothersep:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_idotswithothersep:nn

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_islotwithothersep:nn#1#2
{
	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lowerslotwithothersep:nn { #1 } { #2 }
	}
	{
		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upperslotwithothersep:nn { #1 } { #2 }
	}
}

%----------------------------------------------------------

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_degslotwithothersep:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_dslotwithothersep:nn

\cs_set_eq:NN\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_degreeslotwithothersep:nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_dslotwithothersep:nn

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_par:nn#1#2{
	% Turns parentheses on, and sets their size
	\semantex_data_tl_set:nnn { #1 } { parsize }{ \exp_not:n { #2 } }
	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ifpar:nn { #1 } { true }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_parsize:nn#1#2{
	% Sets the size of the parentheses
	\semantex_data_tl_set:nnn { #1 } { parsize }{ \exp_not:n { #2 } }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_leftpar:nn#1#2{
	\semantex_data_tl_set:nnn { #1 } { leftpar }{ \exp_not:n { #2 } }
}

\cs_generate_variant:Nn \__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_leftpar:nn { xn }

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_rightpar:nn#1#2{
	\semantex_data_tl_set:nnn { #1 } { rightpar }{ \exp_not:n { #2 } }
}

\cs_generate_variant:Nn \__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_rightpar:nn { xn }

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ifpar:nn#1#2{ %IMPLEMENT THIS
	% tells whether to use the output class or not
	\semantex_data_bool_provide:nn { #1 } { par }
	\str_if_eq:nnTF { #2 } { true }
	{
		\semantex_data_bool_set_true:nn { #1 } { par }
		\semantex_data_bool_set_false:nn { #1 } { flexpar }
	}
	{
		\str_if_eq:nnTF { #2 } { never }
		{
			\semantex_data_bool_set_false:nn { #1 } { par }
			\semantex_data_bool_set_false:nn { #1 } { flexpar }
		}
		{
			\str_if_eq:nnTF { #2 } { false }
			{
				\semantex_data_bool_set_false:nn { #1 } { par }
				\semantex_data_bool_set_true:nn { #1 } { flexpar }
			}
			{
				\semantex_error_output_format:nN { #1 } \l__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ifpar_temp_tl
				\msg_error:nnxnn { semantex } { key_value_not_found } { \l__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ifpar_temp_tl } { ifpar } { #2 }
			}
		}
	}
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_spar:nn#1#2
{
	% Abbreviation for "symbol parentheses"
	% Adds parentheses around the current symbol
	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_return:nn { #1 }{}
	\semantex_data_tl_inherit:nn { #1 } { symbol } % Check if really necessary
	\tl_if_blank:nTF { #2 }
	{
		\semantex_data_tl_get_store:nnN { #1 } { sparsize } \l__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_spar_sparsize_temp_tl
		\__semantex_symbol_parentheses_store:nnnnN
		{ \l__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_spar_sparsize_temp_tl }
		{ \semantex_data_tl_get:nn { #1 } { leftspar } }
		{ \semantex_data_tl_get:nn { #1 } { rightspar } }
		{ \semantex_data_tl_get_exp_not:nn { #1 } { symbol } }
		\l__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_spar_temp_tl
		\semantex_data_tl_set:nnx { #1 } { symbol }
		{
			\exp_not:V\l__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_spar_temp_tl
		}
	}
	{
		\tl_set:Nn \l__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_spar_sparsize_temp_tl { \exp_not:n { #2 } }
		\__semantex_symbol_parentheses_store:nnnnN
		{ \l__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_spar_sparsize_temp_tl }
		{ \semantex_data_tl_get:nn { #1 } { leftspar } }
		{ \semantex_data_tl_get:nn { #1 } { rightspar } }
		{ \semantex_data_tl_get_exp_not:nn { #1 } { symbol } }
		\l__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_spar_temp_tl
		\semantex_data_tl_set:nnx { #1 } { symbol }
		{
			\exp_not:V\l__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_spar_temp_tl
		}
	}
}


\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ifnextargwithsep:nn#1#2
{
	% Tells whether it is the first argument or not
	\tl_if_eq:nnTF { #2 } { true }
	{
		\semantex_data_bool_set_true:nn { #1 } { nextargwithsep }
	}
	{
		\tl_if_eq:nnTF { #2 } { false }
		{
			\semantex_data_bool_set_false:nn { #1 } { nextargwithsep }
		}
		{
			\semantex_error_output_format:nN { #1 } \l__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ifnextargwithsep_temp_tl
			\msg_error:nnxnn { semantex } { key_value_not_found } { \l__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ifnextargwithsep_temp_tl } { ifnextargwithsep } { #2 }
		}
	}
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_otherspar:nn#1#2
{
	% Uses the syntax otherspar={leftpar}{rightpar}
	% Adds a new spar, but with these as parentheses
	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_otherspar_auxiliary:nnn { #1 } #2
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_otherspar_auxiliary:nnn#1#2#3
{
	\semantex_data_tl_inherit:nn { #1 } { sparsize } % This is necessary for unknown reasons -- otherwise, it will crash when inheriting sparsize
	\semantex_data_tl_inherit:nn { #1 } { symbol }
	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_return:nn { #1 }{}
	\semantex_data_tl_get_store:nnN { #1 } { sparsize } \l__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_otherspar_sparsize_temp_tl
	\__semantex_symbol_parentheses_store:nnnnN
	{ \l__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_otherspar_sparsize_temp_tl }
	{ \exp_not:n { \exp_not:n { #2 } } }
	{ \exp_not:n { \exp_not:n { #3 } } }
	{ \semantex_data_tl_get_exp_not:nn { #1 } { symbol } }
	\l__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_otherspar_temp_tl
	\semantex_data_tl_set:nnx { #1 } { symbol }
	{
		\exp_not:V\l__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_otherspar_temp_tl
	}
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_Otherspar:nn#1#2
{
	% Uses the syntax otherspar={leftpar}{rightpar}{size}
	% Adds a new spar, but with these as parentheses and size
	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_Otherspar_auxiliary:nnnn { #1 } #2
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_Otherspar_auxiliary:nnnn#1#2#3#4
{
	\tl_set:Nn\l__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_Otherspar_sparsize_temp_tl
	{ \exp_not:n { #4 } }
	\__semantex_symbol_parentheses_store:nnnnN
	{ \l__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_Otherspar_sparsize_temp_tl }
	{ \exp_not:n { \exp_not:n { #2 } } }
	{ \exp_not:n { \exp_not:n { #3 } } }
	{ \semantex_data_tl_get_exp_not:nn { #1 } { symbol } }
	\l__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_Otherspar_temp_tl
	\semantex_data_tl_set:nnx { #1 } { symbol }
	{
		\exp_not:V\l__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_Otherspar_temp_tl
	}
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_sparsize:nn#1#2{
	% sets the size of the parentheses
	\semantex_data_tl_set:nnn { #1 } { sparsize }{ \exp_not:n { #2 } }
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_leftspar:nn#1#2{
	\semantex_data_tl_set:nnn { #1 } { leftspar }{ \exp_not:n { \exp_not:n { #2 } } }
	%IM Two \exp_not necessary for unknown reasons
	%IM Doing the same at leftpar yields an error.
}

\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_rightspar:nn#1#2{
	\semantex_data_tl_set:nnn { #1 } { rightspar }{ \exp_not:n { \exp_not:n { #2 } } }
	%IM Two \exp_not necessary for unknown reasons
	%IM Doing the same at leftpar yields an error.
}

\cs_generate_variant:Nn \semantex_keys_set:nn { nx, no, nV } % Only the first one is currently being used

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%    COMMANDS CONTROLLING THE ARGUMENT KEYVAL INTERFACE
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

\cs_new:Npn \__semantex_data_cs_custom_arg_valuekey_class_SemantexBaseObject_othersep:nn#1#2
{
	% Uses syntax sep={separator}{argument}; adds an argument
	% with the specified separator
	\semantex_data_bool_get:nnTF { #1 } { nextargwithsep }
	{
		\semantex_data_tl_put_right:nnn { #1 } { arg } {
			\exp_not:n {
				\semantex_grab_first_argument_of_two:nn #2
				\semantex_grab_second_argument_of_two:nn #2
			}
		}
	}
	{
		\semantex_data_tl_put_right:nnn { #1 } { arg } {
			\exp_not:n {
				\semantex_grab_second_argument_of_two:nn #2
			}
		}
		%IM These do not use :x, unlike the ones below
	}
	\semantex_data_int_incr:nn { #1 } { numberofarguments }
	\semantex_data_bool_set_true:nn { #1 } { nextargwithsep }
}

\cs_generate_variant:Nn \__semantex_data_cs_custom_arg_valuekey_class_SemantexBaseObject_othersep:nn { nx }

\cs_new:Npn \__semantex_data_cs_custom_arg_valuekey_class_SemantexBaseObject_s:nn#1#2
{
	% Adds to the argument, with the standard separator
	\semantex_data_bool_get:nnTF { #1 } { nextargwithsep }
	{
		\semantex_data_tl_put_right:nnx { #1 } { arg } { \exp_not:n { \semantex_data_tl_get:nn { #1 } { argsep } } }
		\semantex_data_tl_put_right:nnn { #1 } { arg } {\exp_not:n { #2 } }
		% As an experiment, I tried changing cx to cn, and it failed
		% when changing the separator on the fly.
	}
	{
		\semantex_data_tl_put_right:nnn { #1 } { arg } { \exp_not:n { #2 } }
		%IM Recently corrected
		% Previously, this was cx, but I didn’t see any point of this;
		% this was mostly to create symmetry with the below case where
		% cx is strictly necessary.
	}
%	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ifoutput:nn { #1 } { true }
	\semantex_data_int_incr:nn { #1 } { numberofarguments }
	\semantex_data_bool_set_true:nn { #1 } { nextargwithsep }
}

\cs_generate_variant:Nn \__semantex_data_cs_custom_arg_valuekey_class_SemantexBaseObject_s:nn { nx }

\cs_new:Npn \__semantex_data_cs_custom_arg_valuekey_class_SemantexBaseObject_c:nn#1#2
{
	% Adds to the argument, with the standard separator
	\semantex_data_bool_get:nnTF { #1 } { nextargwithsep }
	{
		\semantex_data_tl_put_right:nnn { #1 } { arg } { , \exp_not:n { #2 } }
		% As an experiment, I tried changing cx to cn, and it failed
		% when changing the separator on the fly.
	}
	{
		\semantex_data_tl_put_right:nnn { #1 } { arg } { \exp_not:n { #2 } }
		%IM Recently corrected
		% Previously, this was cx, but I didn’t see any point of this;
		% this was mostly to create symmetry with the below case where
		% cx is strictly necessary.
	}
%	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ifoutput:nn { #1 } { true }
	\semantex_data_int_incr:nn { #1 } { numberofarguments }
	\semantex_data_bool_set_true:nn { #1 } { nextargwithsep }
}

\cs_generate_variant:Nn \__semantex_data_cs_custom_arg_valuekey_class_SemantexBaseObject_c:nn { nx }

\cs_new:Npn \__semantex_data_cs_custom_arg_valuekey_class_SemantexBaseObject_dots:nn#1#2
{
	% Writes dots in the argument
	\__semantex_data_cs_custom_arg_valuekey_class_SemantexBaseObject_s:nx { #1 } { \semantex_data_tl_get_exp_not:nn { #1 } { argdots } }
}

\cs_new:Npn \__semantex_data_cs_custom_arg_valuekey_class_SemantexBaseObject_slot:nn#1#2
{
	% Writes the slot in teh argument
	\__semantex_data_cs_custom_arg_valuekey_class_SemantexBaseObject_s:nx { #1 } { \semantex_data_tl_get_exp_not:nn { #1 } { argslot } }
}

\cs_new:Npn \__semantex_data_cs_custom_arg_valuekey_class_SemantexBaseObject_cdots:nn#1#2
{
	% Writes dots in the argument
	\__semantex_data_cs_custom_arg_valuekey_class_SemantexBaseObject_c:nx { #1 } { \semantex_data_tl_get_exp_not:nn { #1 } { argdots } }
}

\cs_new:Npn \__semantex_data_cs_custom_arg_valuekey_class_SemantexBaseObject_cslot:nn#1#2
{
	% Writes the slot in teh argument
	\__semantex_data_cs_custom_arg_valuekey_class_SemantexBaseObject_c:nx { #1 } { \semantex_data_tl_get_exp_not:nn { #1 } { argslot } }
}

\cs_new:Npn \__semantex_data_cs_custom_arg_valuekey_class_SemantexBaseObject_dotswithothersep:nn#1#2
{
	% Writes dots in the argument
	\__semantex_data_cs_custom_arg_valuekey_class_SemantexBaseObject_othersep:nx { #1 } { { \exp_not:n { #2 } } { \semantex_data_tl_get_exp_not:nn { #1 } { argdots } } }
}

\cs_new:Npn \__semantex_data_cs_custom_arg_valuekey_class_SemantexBaseObject_slotwithothersep:nn#1#2
{
	% Writes the slot in teh argument
	\__semantex_data_cs_custom_arg_valuekey_class_SemantexBaseObject_othersep:nx { #1 } { { \exp_not:n { #2 } } { \semantex_data_tl_get_exp_not:nn { #1 } { argslot } } }
}


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


\semantex_data_tl_provide:nn { class_SemantexBaseObject } { output }

\semantex_data_tl_set:nnn { class_SemantexBaseObject } { output } { class_SemantexBaseObject }

\semantex_data_tl_provide:nn { class_SemantexBaseObject } { upper }

\semantex_data_tl_provide:nn { class_SemantexBaseObject } { uppersep }

\semantex_data_tl_set:nnn { class_SemantexBaseObject } { uppersep } { , }

%IM Also, need commands like forgetupperindex, reverting to the class standard

\semantex_data_tl_provide:nn { class_SemantexBaseObject } { lower }

\semantex_data_tl_provide:nn { class_SemantexBaseObject } { lowersep }

\semantex_data_tl_set:nnn { class_SemantexBaseObject } { lowersep } { , }

\semantex_data_tl_provide:nn { class_SemantexBaseObject } { preupper }

\semantex_data_tl_provide:nn { class_SemantexBaseObject } { postupper }

\semantex_data_tl_provide:nn { class_SemantexBaseObject } { prelower }

\semantex_data_tl_provide:nn { class_SemantexBaseObject } { postlower }

\semantex_data_tl_provide:nn { class_SemantexBaseObject } { upperleft }

\semantex_data_tl_provide:nn { class_SemantexBaseObject } { upperleftsep }

\semantex_data_tl_set:nnn { class_SemantexBaseObject } { upperleftsep } { , }

%IM do the same with all the others, INCLUDING if_uppergrading and symbol
%IM Also, need commands like forgetupperindex, reverting to the class standard

\semantex_data_tl_provide:nn { class_SemantexBaseObject } { lowerleft }

\semantex_data_tl_provide:nn { class_SemantexBaseObject } { lowerleftsep }

\semantex_data_tl_set:nnn { class_SemantexBaseObject } { lowerleftsep } { , }


\semantex_data_tl_provide:nn { class_SemantexBaseObject } { preupperleft }

\semantex_data_tl_provide:nn { class_SemantexBaseObject } { postupperleft }

\semantex_data_tl_provide:nn { class_SemantexBaseObject } { prelowerleft }

\semantex_data_tl_provide:nn { class_SemantexBaseObject } { postlowerleft }

\semantex_data_int_provide:nn { class_SemantexBaseObject } { numberofarguments }

\semantex_data_bool_provide:nn { class_SemantexBaseObject } { nextargwithsep }

\semantex_data_bool_provide:nn { class_SemantexBaseObject } { nextupperleftwithsep }
\semantex_data_bool_provide:nn { class_SemantexBaseObject } { nextlowerleftwithsep }

\semantex_data_int_provide:nn { class_SemantexBaseObject } { numberofupperleftindices }
\semantex_data_int_provide:nn { class_SemantexBaseObject } { numberoflowerleftindices }

\semantex_data_tl_provide:nn { class_SemantexBaseObject } { prearg }

\semantex_data_tl_provide:nn { class_SemantexBaseObject } { postarg }

\semantex_data_tl_provide:nn { class_SemantexBaseObject } { arg }

\semantex_data_tl_provide:nn { class_SemantexBaseObject } { argsep }
\semantex_data_tl_set:nnn { class_SemantexBaseObject } { argsep } {,}

\semantex_data_tl_provide:nn { class_SemantexBaseObject } { argslot }
\semantex_data_tl_set:nnn { class_SemantexBaseObject } { argslot } { \SemantexSlot }

\semantex_data_tl_provide:nn { class_SemantexBaseObject } { argdots }
\semantex_data_tl_set:nnn { class_SemantexBaseObject } { argdots } {\dots}

\semantex_data_tl_provide:nn { class_SemantexBaseObject } { symbol }

\semantex_data_seq_provide:nn { class_SemantexBaseObject } { commands_sequence }

\semantex_data_bool_provide:nn { class_SemantexBaseObject } { uppergrading }
\semantex_data_bool_set_true:nn { class_SemantexBaseObject } { uppergrading }

\semantex_data_bool_provide:nn { class_SemantexBaseObject } { output }

\semantex_data_tl_provide:nn { class_SemantexBaseObject } { outputoptions }

\semantex_data_bool_provide:nn { class_SemantexBaseObject } { nextupperwithsep }
\semantex_data_bool_provide:nn { class_SemantexBaseObject } { nextlowerwithsep }

\semantex_data_int_provide:nn { class_SemantexBaseObject } { numberofupperindices }
\semantex_data_int_provide:nn { class_SemantexBaseObject } { numberoflowerindices }

\semantex_data_bool_provide:nn { class_SemantexBaseObject } { par }
\semantex_data_bool_set_true:nn { class_SemantexBaseObject } { par }

\semantex_data_bool_provide:nn { class_SemantexBaseObject } { flexpar }

\semantex_data_tl_provide:nn { class_SemantexBaseObject } { parseoptions }

\semantex_data_tl_provide:nn { class_SemantexBaseObject } { texclass }

\semantex_data_bool_provide:nn { class_SemantexBaseObject } { leftargument }

\semantex_data_tl_provide:nn { class_SemantexBaseObject } { upperdots }
\semantex_data_tl_provide:nn { class_SemantexBaseObject } { upperslot }

\semantex_data_tl_provide:nn { class_SemantexBaseObject } { lowerdots }
\semantex_data_tl_provide:nn { class_SemantexBaseObject } { lowerslot }

\semantex_data_tl_provide:nn { class_SemantexBaseObject } { upperleftdots }
\semantex_data_tl_provide:nn { class_SemantexBaseObject } { upperleftslot }

\semantex_data_tl_provide:nn { class_SemantexBaseObject } { lowerleftdots }
\semantex_data_tl_provide:nn { class_SemantexBaseObject } { lowerleftslot }

%\tl_set:Nn\g_objectmath_SemantexBaseObject_upper { hej }
%\tl_set:Nn \SemantexBaseObject_output { class_SemantexBaseObject }
%\bool_new:N \SemantexBaseObject_output_if_provided
%\bool_set_true:N \SemantexBaseObject_output_if_provided


\semantex_new_plain_class:Nw \SemantexBaseObject [
	%parent=SemantexBaseObject,
	output=\SemantexBaseObject,
	ifoutput=false,
	symbol=,
	gradingposition=upper,
	%upper=,
	%lower=,
	leftpar=(,
	rightpar=),
	par=normal,
	leftspar=(,
	rightspar=),
	sparsize=normal,
	%arg=,
	setupperdots=\dots,
	setlowerdots=\dots,
	setupperslot=\g_semantex_bullet,
	setlowerslot=\g_semantex_bullet,
	setupperleftdots=\dots,
	setlowerleftdots=\dots,
	setupperleftslot=\g_semantex_bullet,
	setlowerleftslot=\g_semantex_bullet,
	singlekeys={
		{prime}{upper={\prime}},
		{'}{prime},
		{''}{prime,prime},
		{'''}{prime,prime,prime},
		{*}{sdegree=\g_semantex_bullet},
		{**}{sdegree=\g_semantex_double_bullet},
		{degree*}{degree=\g_semantex_bullet},
		{degree**}{degree=\g_semantex_double_bullet},
		{sdegree*}{sdegree=\g_semantex_bullet},
		{sdegree**}{sdegree=\g_semantex_double_bullet},
		{cdegree*}{cdegree=\g_semantex_bullet},
		{cdegree**}{cdegree=\g_semantex_double_bullet},
		{deg*}{deg=\g_semantex_bullet},
		{deg**}{deg=\g_semantex_double_bullet},
		{sdeg*}{sdeg=\g_semantex_bullet},
		{sdeg**}{sdeg=\g_semantex_double_bullet},
		{cdeg*}{cdeg=\g_semantex_bullet},
		{cdeg**}{cdeg=\g_semantex_double_bullet},
		{d*}{d=\g_semantex_bullet},
		{d**}{d=\g_semantex_double_bullet},
		{sd*}{sd=\g_semantex_bullet},
		{sd**}{sd=\g_semantex_double_bullet},
		{cd*}{cd=\g_semantex_bullet},
		{cd**}{cd=\g_semantex_double_bullet},
		{index*}{index=\g_semantex_bullet},
		{index**}{index=\g_semantex_double_bullet},
		{sindex*}{sindex=\g_semantex_bullet},
		{sindex**}{sindex=\g_semantex_double_bullet},
		{cindex*}{cindex=\g_semantex_bullet},
		{cindex**}{cindex=\g_semantex_double_bullet},
		{i*}{i=\g_semantex_bullet},
		{i**}{i=\g_semantex_double_bullet},
		{si*}{si=\g_semantex_bullet},
		{si**}{si=\g_semantex_double_bullet},
		{ci*}{ci=\g_semantex_bullet},
		{ci**}{ci=\g_semantex_double_bullet},
		{upper*}{upper=\g_semantex_bullet},
		{upper**}{upper=\g_semantex_double_bullet},
		{supper*}{supper=\g_semantex_bullet},
		{supper**}{supper=\g_semantex_double_bullet},
		{cupper*}{cupper=\g_semantex_bullet},
		{cupper**}{cupper=\g_semantex_double_bullet},
		{lower*}{lower=\g_semantex_bullet},
		{lower**}{lower=\g_semantex_double_bullet},
		{slower*}{slower=\g_semantex_bullet},
		{slower**}{slower=\g_semantex_double_bullet},
		{clower*}{clower=\g_semantex_bullet},
		{clower**}{clower=\g_semantex_double_bullet},
		{upperleft*}{upperleft=\g_semantex_bullet},
		{upperleft**}{upperleft=\g_semantex_double_bullet},
		{supperleft*}{supperleft=\g_semantex_bullet},
		{supperleft**}{supperleft=\g_semantex_double_bullet},
		{cupperleft*}{cupperleft=\g_semantex_bullet},
		{cupperleft**}{cupperleft=\g_semantex_double_bullet},
		{lowerleft*}{lowerleft=\g_semantex_bullet},
		{lowerleft**}{lowerleft=\g_semantex_double_bullet},
		{slowerleft*}{slowerleft=\g_semantex_bullet},
		{slowerleft**}{slowerleft=\g_semantex_double_bullet},
		{clowerleft*}{clowerleft=\g_semantex_bullet},
		{clowerleft**}{clowerleft=\g_semantex_double_bullet},
		{smash}{command=\smash},
		{tilde}{command=\tilde},
		{widetilde}{command=\widetilde},
		{overline}{command=\overline},
		{bar}{command=\bar},
		{bold}{command=\mathbf},
		{roman}{command=\mathrm},
		{mathord}{texclass=\mathord},
		{mathbin}{texclass=\mathbin},
		{mathop}{texclass=\mathop},
		{mathrel}{texclass=\mathrel},
		{leftreturn}{leftreturn=},
		{innerreturn}{innerreturn=},
		{rightreturn}{rightreturn=},
		{return}{return=},
		{spar}{spar=},
		{parse}{parse=},
		{par}{ifpar=true},
		{neverpar}{ifpar=never},
		{nopar}{ifpar=false},
		{clearupper}{clearupper=},
		{clearlower}{clearlower=},
		{clearupperleft}{clearupperleft=},
		{clearlowerleft}{clearlowerleft=},
		{clearcommand}{clearcommand=},
		{cleard}{cleard=},
		{cleardeg}{cleardeg=},
		{cleardegree}{cleardegree=},
		{cleari}{cleari=},
		{clearindex}{clearindex=},
		{upperdots}{upperdots=},
		{upper...}{upperdots=},
		{upperslot}{upperslot=},
		{upper-}{upperslot=},
		{lowerdots}{lowerdots=},
		{lower...}{lowerdots=},
		{lowerslot}{lowerslot=},
		{lower-}{lowerslot=},
		{upperleftdots}{upperleftdots=},
		{upperleft...}{upperleftdots=},
		{upperleftslot}{upperleftslot=},
		{upperleft-}{upperleftslot=},
		{lowerleftdots}{lowerleftdots=},
		{lowerleft...}{lowerleftdots=},
		{lowerleftslot}{lowerleftslot=},
		{lowerleft-}{lowerleftslot=},
		{idots}{idots=},
		{indexdots}{indexdots=},
		{islot}{islot=},
		{indexslot}{indexslot=},
		{i...}{idots=},
		{index...}{indexdots=},
		{i-}{islot=},
		{index-}{indexslot=},
		{ddots}{ddots=},
		{degdots}{degdots=},
		{degreedots}{degreedots=},
		{dslot}{dslot=},
		{degslot}{degslot=},
		{degreeslot}{degreeslot=},
		{d...}{ddots=},
		{deg...}{degdots=},
		{degree...}{degreedots=},
		{d-}{dslot=},
		{deg-}{degslot=},
		{degree-}{degreeslot=},
		{cupperdots}{cupperdots=},
		{cupper...}{cupperdots=},
		{cupperslot}{cupperslot=},
		{cupper-}{cupperslot=},
		{clowerdots}{clowerdots=},
		{clower...}{clowerdots=},
		{clowerslot}{clowerslot=},
		{clower-}{clowerslot=},
		{cupperleftdots}{cupperleftdots=},
		{cupperleft...}{cupperleftdots=},
		{cupperleftslot}{cupperleftslot=},
		{cupperleft-}{cupperleftslot=},
		{clowerleftdots}{clowerleftdots=},
		{clowerleft...}{clowerleftdots=},
		{clowerleftslot}{clowerleftslot=},
		{clowerleft-}{clowerleftslot=},
		{cidots}{cidots=},
		{cindexdots}{cindexdots=},
		{cislot}{cislot=},
		{cindexslot}{cindexslot=},
		{ci...}{cidots=},
		{cindex...}{cindexdots=},
		{ci-}{cislot=},
		{cindex-}{cindexslot=},
		{cddots}{cddots=},
		{cdegdots}{cdegdots=},
		{cdegreedots}{cdegreedots=},
		{cdslot}{cdslot=},
		{cdegslot}{cdegslot=},
		{cdegreeslot}{cdegreeslot=},
		{cd...}{cddots=},
		{cdeg...}{cdegdots=},
		{cdegree...}{cdegreedots=},
		{cd-}{cdslot=},
		{cdeg-}{cdegslot=},
		{cdegree-}{cdegreeslot=},
		{supperdots}{supperdots=},
		{supper...}{supperdots=},
		{supperslot}{supperslot=},
		{supper-}{supperslot=},
		{slowerdots}{slowerdots=},
		{slower...}{slowerdots=},
		{slowerslot}{slowerslot=},
		{slower-}{slowerslot=},
		{supperleftdots}{supperleftdots=},
		{supperleft...}{supperleftdots=},
		{supperleftslot}{supperleftslot=},
		{supperleft-}{supperleftslot=},
		{slowerleftdots}{slowerleftdots=},
		{slowerleft...}{slowerleftdots=},
		{slowerleftslot}{slowerleftslot=},
		{slowerleft-}{slowerleftslot=},
		{sidots}{sidots=},
		{sindexdots}{sindexdots=},
		{sislot}{sislot=},
		{sindexslot}{sindexslot=},
		{si...}{sidots=},
		{sindex...}{sindexdots=},
		{si-}{sislot=},
		{sindex-}{sindexslot=},
		{sddots}{sddots=},
		{sdegdots}{sdegdots=},
		{sdegreedots}{sdegreedots=},
		{sdslot}{sdslot=},
		{sdegslot}{sdegslot=},
		{sdegreeslot}{sdegreeslot=},
		{sd...}{sddots=},
		{sdeg...}{sdegdots=},
		{sdegree...}{sdegreedots=},
		{sd-}{sdslot=},
		{sdeg-}{sdegslot=},
		{sdegree-}{sdegreeslot=},
		{...}{sidots=},
		{-}{sislot=},
%		{argwithkeyval}{
%			valuekeys={
%				{arg}{argwithkeyval={####1}},
%			},
%		},
%		{argwithsinglekeys}{
%			valuekeys={
%				{arg}{argwithsinglekeys={####1}},
%			},
%		},
%		{argwithoutkeyval}{
%			valuekeys={
%				{arg}{argwithoutkeyval={####1}},
%			},
%		},
%		{argwithonesinglekey}{
%			valuekeys={
%				{arg}{argwithonesinglekey={####1}},
%			},
%		},
	},
	valuekeys={
		{default}{sindex={#1}},
		{arg}{argwithsinglekeys={#1}},
		{degreedefault}{sdegree={#1}},
		{*withothersep}{degreewithothersep={#1}{\g_semantex_bullet}},
		{**withothersep}{degreewithothersep={#1}{\g_semantex_double_bullet}},
		{degree*withothersep}{degreewithothersep={#1}{\g_semantex_bullet}},
		{degree**withothersep}{degreewithothersep={#1}{\g_semantex_double_bullet}},
		{deg*withothersep}{degwithothersep={#1}{\g_semantex_bullet}},
		{deg**withothersep}{degwithothersep={#1}{\g_semantex_double_bullet}},
		{d*withothersep}{dwithothersep={#1}{\g_semantex_bullet}},
		{d**withothersep}{dwithothersep={#1}{\g_semantex_double_bullet}},
		{index*withothersep}{indexwithothersep={#1}{\g_semantex_bullet}},
		{index**withothersep}{indexwithothersep={#1}{\g_semantex_double_bullet}},
		{i*withothersep}{iwithothersep={#1}{\g_semantex_bullet}},
		{i**withothersep}{iwithothersep={#1}{\g_semantex_double_bullet}},
		{upper*withothersep}{upperwithothersep={#1}{\g_semantex_bullet}},
		{upper**withothersep}{upperwithothersep={#1}{\g_semantex_double_bullet}},
		{lower*withothersep}{lowerwithothersep={#1}{\g_semantex_bullet}},
		{lower**withothersep}{lowerwithothersep={#1}{\g_semantex_double_bullet}},
		{upperleft*withothersep}{upperleftwithothersep={#1}{\g_semantex_bullet}},
		{upperleft**withothersep}{upperleftwithothersep={#1}{\g_semantex_double_bullet}},
		{lowerleft*withothersep}{lowerleftwithothersep={#1}{\g_semantex_bullet}},
		{lowerleft**withothersep}{lowerleftwithothersep={#1}{\g_semantex_double_bullet}},
		{sarg}{argwithkeyval={s={#1}}},
		{carg}{argwithkeyval={c={#1}}},
		{argwithothersep}{argwithkeyval={othersep={#1}}},
		{argdots}{argwithkeyval={...}},
		{arg...}{argwithkeyval={...}},
		{cargdots}{argwithkeyval={cdots=}},
		{carg...}{argwithkeyval={cdots=}},
		{argdotswithothersep}{argwithkeyval={dotswithothersep={#1}}},
		{arg...withothersep}{argwithkeyval={dotswithothersep={#1}}},
		{argdots}{argwithkeyval={-}},
		{arg-}{argwithkeyval={-}},
		{cargslot}{argwithkeyval={cslot=}},
		{carg-}{argwithkeyval={cslot=}},
		{argslotwithothersep}{argwithkeyval={slotwithothersep={#1}}},
		{arg-withothersep}{argwithkeyval={slotwithothersep={#1}}},
		{argkeyval}{
			ifeqTF={#1}{true}
			{
				valuekeys={
					{arg}{argwithkeyval={####1}},
				},
			}
			{
				ifeqTF={#1}{false}
				{
					valuekeys={
						{arg}{argwithoutkeyval={####1}},
					},
				}
				{
					ifeqTF={#1}{singlekeys}
					{
						valuekeys={
							{arg}{argwithsinglekeys={####1}},
						},
					}
					{
						ifeqTF={#1}{onesinglekey}
						{
							valuekeys={
								{arg}{argwithonesinglekey={####1}},
							},
						}
						{
							ERRORkeyvaluenotfound={argkeyval}{#1},
						},
					},
				},
			},
		},
	},
	argvaluekeys={
		{default}{s={#1}},
		{-withothersep}{slotwithothersep={#1}},
		{...withothersep}{dotswithothersep={#1}},
	},
	argsinglekeys={
		{slot}{slot=},
		{-}{slot=},
		{cslot}{cslot=},
		{c-}{cslot=},
%		{*}{slot=}, % would be confusing since * does not correspond to slot in the indices
		{dots}{dots=},
		{...}{dots=},
		{cdots}{cdots=},
		{c...}{cdots=},
	},
]

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

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