texlive[55902] Master/texmf-dist: semantex (21jul20)

commits+karl at tug.org commits+karl at tug.org
Tue Jul 21 23:40:12 CEST 2020


Revision: 55902
          http://tug.org/svn/texlive?view=revision&revision=55902
Author:   karl
Date:     2020-07-21 23:40:12 +0200 (Tue, 21 Jul 2020)
Log Message:
-----------
semantex (21jul20)

Modified Paths:
--------------
    trunk/Master/texmf-dist/doc/latex/semantex/README.md
    trunk/Master/texmf-dist/doc/latex/semantex/semantex.pdf
    trunk/Master/texmf-dist/doc/latex/semantex/semantex.tex
    trunk/Master/texmf-dist/tex/latex/semantex/semantex.sty

Modified: trunk/Master/texmf-dist/doc/latex/semantex/README.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/semantex/README.md	2020-07-21 21:40:00 UTC (rev 55901)
+++ trunk/Master/texmf-dist/doc/latex/semantex/README.md	2020-07-21 21:40:12 UTC (rev 55902)
@@ -1,4 +1,4 @@
-SemanTeX - object-oriented mathematics
+SemanTeX - semantic mathematics
 --------------------------------------
 
 The SemanTeX package for LaTeX delivers a more semantic,

Modified: trunk/Master/texmf-dist/doc/latex/semantex/semantex.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/semantex/semantex.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/semantex/semantex.tex	2020-07-21 21:40:00 UTC (rev 55901)
+++ trunk/Master/texmf-dist/doc/latex/semantex/semantex.tex	2020-07-21 21:40:12 UTC (rev 55902)
@@ -34,7 +34,7 @@
 	
 \usepackage[nameinlink]{cleveref}
 
-\title{Seman\!\TeX: Semantic mathematics (v$0.201\alpha$)}
+\title{Seman\!\TeX: Semantic mathematics (v$0.3\alpha$)}
 \date{\today}
 \author{Sebastian Ørsted (\href{mailto:sorsted at gmail.com}{sorsted at gmail.com})}
 
@@ -293,6 +293,7 @@
 \NewObject\MyVar\vn{n}
 \NewObject\MyVar\vp{p}
 \NewObject\MyVar\vU{U}
+\NewObject\MyVar\vx{x}
 \NewObject\MyVar\sheafF{\mathcal{F}}
 
 % Now we set up the class \MyVar:
@@ -318,7 +319,7 @@
 
 $ \vf[conj,der=\vn] $
 
-$ \vg[inv,res=\vU]{x} $
+$ \vg[inv,res=\vU]{\vx} $
 
 $ \vh[inverseimage]{\sheafF}[spar,stalk=\vp]
 	= \sheafF[stalk=\vh{\vp}] $
@@ -335,7 +336,7 @@
 \usepackage{semantex}
 \end{lstlisting}
 The \semantex system is object-oriented; all entities are objects of some class. When you load the package, there
-is only one class by default, which is simply called \lstinline!\SemantexVariable!.
+is only one class by default, which is simply called \lstinline!\SemantexBaseObject!.
 You should think of this as a low-level class, the parent of all other classes. Therefore, I highly advice against using it directly or modifying it.
 Instead, we create a new, more high-level variable class.
 We choose to call it \lstinline!\MyVar!.
@@ -771,19 +772,19 @@
 		},
 		{freealg}{
 			par,
-			leftpar=\noexpand\langle,
-			rightpar=\noexpand\rangle,
+			leftpar=\langle,
+			rightpar=\rangle,
 		},
 		{powerseries}{
 			par,
-			leftpar=\noexpand\llbracket,
-			rightpar=\noexpand\rrbracket,
+			leftpar=\llbracket,
+			rightpar=\rrbracket,
 		},
 		{laurent}{
 			par,
 			leftpar=(, rightpar=),
-			prearg={\!\!\noexpand\SemantexDelimiterSize(},
-			postarg={\noexpand\SemantexDelimiterSize)\!\!},
+			prearg={\!\!\SemantexDelimiterSize(},
+			postarg={\SemantexDelimiterSize)\!\!},
 			% These are printed before and after the argument.
 			% The command "\SemantexDelimiterSize" is substituted
 			% by \big, \Big, ..., or whatever size the
@@ -796,19 +797,19 @@
 	singlekeys={
 		{freealg}{
 			par,
-			leftpar=\noexpand\langle,
-			rightpar=\noexpand\rangle,
+			leftpar=\langle,
+			rightpar=\rangle,
 		},
 		{powerseries}{
 			par,
-			leftpar=\noexpand\llbracket,
-			rightpar=\noexpand\rrbracket,
+			leftpar=\llbracket,
+			rightpar=\rrbracket,
 		},
 		{laurent}{
 			par,
 			leftpar=(, rightpar=),
-			prearg={\!\!\noexpand\SemantexDelimiterSize(},
-			postarg={\noexpand\SemantexDelimiterSize)\!\!},
+			prearg={\!\!\SemantexDelimiterSize(},
+			postarg={\SemantexDelimiterSize)\!\!},
 			% These are printed before and after the argument.
 			% The command "\SemantexDelimiterSize" is substituted
 			% by \big, \Big, ..., or whatever size the
@@ -816,10 +817,7 @@
 		},
 	},
 }
-For expansion reasons (which I am not completely sure of),
-we need \lstinline!\noexpand! before these commands.
-In general, whenever something fails, try throwing in \lstinline!\noexpand!'s in front of suspicious-looking commands,
-and things will usually work out just fine. See for yourself:
+See for yourself:
 \begin{LTXexample}
 $\vk[freealg]{\vx}$,
 $\vk[powerseries]{\vy}$,
@@ -831,7 +829,7 @@
 \begin{lstlisting}
 \SetupClass\MyVar{
 	singlekeys={
-		{op}{upper={\noexpand\mathrm{op}}},
+		{op}{upper={\mathrm{op}}},
 			% opposite groups, rings, categories, etc.
 		{algclosure}{overline},
 			% algebraic closure
@@ -863,7 +861,7 @@
 \end{lstlisting}
 \SetupClass\MyVar{
 	singlekeys={
-		{op}{upper={\noexpand\mathrm{op}}},
+		{op}{upper={\mathrm{op}}},
 			% opposite groups, rings, categories, etc.
 		{algclosure}{overline},
 			% algebraic closure
@@ -1015,26 +1013,26 @@
 \begin{lstlisting}
 \SetupClass\MyVar{
 	singlekeys={
-		{overline}{command=\noexpand\overline},
+		{overline}{command=\overline},
 	},
 }
 \end{lstlisting}
 \SetupClass\MyVar{
 	singlekeys={
-		{overline}{command=\noexpand\overline},
+		{overline}{command=\overline},
 	},
 }
-This is how the key \lstinline!overline! is defined internally, except it is defined on the level of the superclass \lstinline!\SemantexVariable! instead. We need the key \lstinline!\noexpand! in order for everything to expand properly. This is only necessary for some commands, and to tell the truth, I haven't quite figured out the system of which commands need it and which ones do not. However, as usual, if something does not work, try throwing in some \lstinline!\noexpand!'s and see if it solves the problem.
+This is how the key \lstinline!overline! is defined internally, except it is defined on the level of the superclass \lstinline!\SemantexBaseObject! instead.
 Here are some more examples of predefined keys that use the command key:
 \begin{lstlisting}
 \SetupClass\MyVar{ % do not add these -- they are already predefined!
 	novalueskeys={
-		{smash}{command=\noexpand\smash},
-		{tilde}{command=\noexpand\tilde},
+		{smash}{command=\smash},
+		{tilde}{command=\tilde},
 		{widetilde}{command=\widetilde},
-		{bar}{command=\noexpand\bar},
-		{bold}{command=\noexpand\mathbf},
-		{roman}{command=\noexpand\mathrm},
+		{bar}{command=\bar},
+		{bold}{command=\mathbf},
+		{roman}{command=\mathrm},
 	},
 }
 \end{lstlisting}
@@ -1339,8 +1337,8 @@
 \SetupClass\MyVar{
 	singlekeys={
 		{reduced}{command=\widetilde},
-		{cech}{command=\noexpand\check},
-		{hyper{command=\noexpand\mathbb},
+		{cech}{command=\check},
+		{hyper{command=\mathbb},
 	},
 }
 \end{lstlisting}
@@ -1347,8 +1345,8 @@
 \SetupClass\MyVar{
 	singlekeys={
 		{reduced}{command=\widetilde},
-		{cech}{command=\noexpand\check},
-		{hyper}{command=\noexpand\mathbb},
+		{cech}{command=\check},
+		{hyper}{command=\mathbb},
 	},
 }
 
@@ -1380,21 +1378,21 @@
 	valuekeys={
 		{Lder} {
 			innerreturn,leftreturn,
-			symbolputleft=\noexpand\mathbb{L}^{#1},
+			symbolputleft=\mathbb{L}^{#1},
 		},
 		{Rder} {
 			innerreturn,leftreturn,
-			symbolputleft=\noexpand\mathbb{R}^{#1},
+			symbolputleft=\mathbb{R}^{#1},
 		},
 	},
 	singlekeys={
 		{Lder} {
 			innerreturn,leftreturn,
-			symbolputleft=\noexpand\mathbb{L},
+			symbolputleft=\mathbb{L},
 		},
 		{Rder} {
 			innerreturn,leftreturn,
-			symbolputleft=\noexpand\mathbb{R},
+			symbolputleft=\mathbb{R},
 		},
 	},
 }
@@ -1403,21 +1401,21 @@
 	valuekeys={
 		{Lder} {
 			innerreturn,leftreturn,
-			symbolputleft=\noexpand\mathbb{L}^{#1},
+			symbolputleft=\mathbb{L}^{#1},
 		},
 		{Rder} {
 			innerreturn,leftreturn,
-			symbolputleft=\noexpand\mathbb{R}^{#1},
+			symbolputleft=\mathbb{R}^{#1},
 		},
 	},
 	singlekeys={
 		{Lder} {
 			innerreturn,leftreturn,
-			symbolputleft=\noexpand\mathbb{L},
+			symbolputleft=\mathbb{L},
 		},
 		{Rder} {
 			innerreturn,leftreturn,
-			symbolputleft=\noexpand\mathbb{R},
+			symbolputleft=\mathbb{R},
 		},
 	},
 }
@@ -1470,27 +1468,19 @@
 These work exactly like \lstinline!singlekeys! and~\lstinline!valuekeys!.
 \begin{lstlisting}
 \SetupClass\MyVar{
+	argkeyval=true, % this turns keyval syntax in arguments on
 	argvaluekeys={
 		{coef}{ othersep={;}{#1}  },
 	},
 }
 \end{lstlisting}
-(But it will not quite work yet -- stay tuned for a moment!)
 The key \lstinline!othersep! is a key that controls the separator
 between the current argument and the previous argument (it will only be printed if there was a previous argument). By default, this separator is a comma. So in the syntax~\lstinline!\co{*}{\vX,coef=\vR}!,
 there are two arguments, \lstinline!\vX! and~\lstinline!\vR!, and the separator is a semicolon.
 
-However, even with the above setup, the notation \lstinline!\co{*}{\vX,coef=\vR}! will not work
-just yet. For the keys you define using \lstinline!argvaluekeys!
-are turned off by default. To turn them on for the object~\lstinline!\co!, run the following code:
-\begin{lstlisting}
-\SetupObject\co{
-	valuekeys={
-		{arg}{argwithkeyval={#1}},
-	},
-}
-\end{lstlisting}
-The reason the keys are turned off by default is that keys in arguments that support values are only used in very rare cases, like cohomology with coefficients. If such keys were turned on in general, it would mess up
+As you see above, we had to turn keyval syntax on in order for it to work.
+By default, only singlekeys are turned on in the argument, not valuekeys.
+The reason is that valuekeys in arguments are only useful in very rare cases, like cohomology with coefficients. If such keys were turned on in general, it would mess up
 every occurrence of an equality sign in arguments, and the following
 would not work:
 \begin{LTXexample}
@@ -1500,9 +1490,12 @@
 }$
 \end{LTXexample}
 
+The key~\lstinline!argkeyval! can take four arguments: \lstinline!true! (as above),
+\lstinline!false! (no singlekeys or valuekeys allowed), \lstinline!singlekeys! (the default behaviour where only singlekeys are turned on), and \lstinline!onesinglekey! (only allows one singlekey).
+
 It should be noted that there are several predefined
-keys (of type \mbox{\lstinline!singlekey!)} which are defined on the level
-of the class \lstinline!\SemantexVariable!. The full list is:\fxfatal{Finish this}
+singlekeys which are defined on the level
+of the class \lstinline!\SemantexBaseObject!. The full list is:\fxfatal{Finish this}
 
 \begin{itemize}
 	\item slot, \ldots
@@ -1677,6 +1670,9 @@
 
 Let me add that \semantex uses a very clear separation between the input syntax and the underlying machinery. Because of this, if the user needs a different kind of class type, it is not very hard to create one. You must simply open the source code of \semantex, find the class you want to modify, and then copy the definition of the command~\lstinline!\New⟨Class type⟩Class! and modify it in whatever way you want.
 
+There is another class type, called the \lstinline!plain! class type, which is the class
+type of the class~\lstinline!\SemantexBaseObject!. This class is pretty useless as all it does is print its symbol, without allowing any keyval syntax, so don't use it.
+
 \chapter{The \texorpdfstring{\texttt{Delimiter}}{Delimiter} class type}
 
 \NewDelimiterClass\MyDelim[parent=\MyVar]
@@ -1824,7 +1820,7 @@
 
 \chapter{The \texttt{parse} routine}
 
-As you can see above, \semantex has a ``waterfall-like'' behaviour. It runs keys in the order it receives them. This works fine most of the time, but for some more complicated constructions, it is useful to be able to provide a data set in any order and have them printed in a fixed order. For this purpose, we have the \lstinline!parse! routine.
+As you can see above, \semantex has a \enquote{waterfall-like} behaviour. It runs keys in the order it receives them. This works fine most of the time, but for some more complicated constructions, it is useful to be able to provide a data set in any order and have them printed in a fixed order. For this purpose, we have the \lstinline!parse! routine.
 
 
 
@@ -1834,99 +1830,131 @@
 	\operatorname{Mat}}
 $ \Mat[\vn\times\vm]{\vk} $.
 \end{LTXexample}\endgroup%
-\noindent However, this is not quite as systematic and semantic as we might have wanted. Indeed, what if later you would like to change the notation to~\( \MyVar{\operatorname{Mat}}[\vn,\vm]{\vk} \)?
-Therefore, we do something like the following instead (we explain the notation below):
-\begin{lstlisting}
 \NewObject\MyVar\Mat{\operatorname{Mat}}[
-	execute={
-		\SemantexDataProvide{rows}
-		\SemantexDataProvide{columns}
-		 % provides data sets for number of rows and columns
-		 % for this object
+	% We provide data sets "rows" and "columns" to
+	% be set up by the user later
+	dataprovide={rows},
+	dataprovide={columns},
+	valuekeys={
+		{rows}{ dataset={rows}{#1} }, % set the rows data set
+		{columns}{ dataset={columns}{#1} }, % set the columns data set
 	},
-	valuekeys={
-		{rows}{
-			execute={
-				\SemantexDataSet{rows}{#1}
+	parseoptions={ % Here we add code to the parse routine
+		% We check whether columns = rows. If so, we only write
+		% the number once
+		ifeqTF={\SemantexDataGetExpNot{columns}}{\SemantexDataGetExpNot{rows}}
+		{
+			% We use a very weird key called "setkeysx" -- this
+			% fully executes the content of the keys before
+			% setting them
+			setkeysx={
+				lower={\SemantexDataGetExpNot{columns}},
 			},
-		},
-		{columns}{
-			execute={
-				\SemantexDataSet{columns}{#1}
+		}
+		{
+			setkeysx={
+				lower={
+					\SemantexDataGetExpNot{rows}
+					\times
+					\SemantexDataGetExpNot{columns}
+				},
 			},
 		},
 	},
-	parseoptions={
-		execute={
-			\SemantexStrIfEqTF{\SemantexDataGetExpNot{columns}}
-			{\SemantexDataGetExpNot{rows}}
-			% tests if rows = columns
-			{
-				\SemantexKeysSetx{
-					lower={
-						\SemantexDataGetExpNot{columns}
-					}
-				}
-			}
-			{
-				\SemantexKeysSetx{
-					lower={
-						\SemantexDataGetExpNot{rows}
-						\times
-						\SemantexDataGetExpNot{columns}
-					}
-				}
-			}
-		},
-	},	
-]
-\end{lstlisting}%
+]%
+\noindent However, this is not quite as systematic and semantic as we might have wanted. Indeed, what if later you would like to change the notation to~\( \MyVar{\operatorname{Mat}}[\vn,\vm]{\vk} \)? (In this case, you could use multi-value keys, though.)
+In this chapter, we show how to eanble a syntax like the following instead:
+\begin{LTXexample}
+$ \Mat[rows=\vn,columns=\vm]{\vk} $, $ \Mat[rows=\vn,columns=\vn]{\vk} $
+\end{LTXexample}
+
+The important ingredient here is the \lstinline!parse! routine. This routine is executed right before the function is being rendered, and you can add code to it via the
+key~\lstinline!parseoptions!. However, we need a bit more programming keys to make it work. Let us see it in action and explain the syntax below:
+\begin{lstlisting}
 \NewObject\MyVar\Mat{\operatorname{Mat}}[
-	execute={
-		\SemantexDataProvide{rows}
-		\SemantexDataProvide{columns}
+	% We provide data sets "rows" and "columns" to
+	% be set up by the user later
+	dataprovide={rows},
+	dataprovide={columns},
+	valuekeys={
+		{rows}{ dataset={rows}{#1} }, % set the rows data set
+		{columns}{ dataset={columns}{#1} }, % set the columns data set
 	},
-	valuekeys={
-		{rows}{
-			execute={
-				\SemantexDataSet{rows}{#1}
+	parseoptions={ % Here we add code to the parse routine
+		% We check whether columns = rows. If so, we only write
+		% the number once
+		ifeqTF={\SemantexDataGetExpNot{columns}}
+					 {\SemantexDataGetExpNot{rows}}
+		{
+			% We use a very weird key called "setkeysx" -- this
+			% fully executes the content of the keys before
+			% setting them
+			setkeysx={
+				lower={\SemantexDataGetExpNot{columns}},
 			},
-		},
-		{columns}{
-			execute={
-				\SemantexDataSet{columns}{#1}
+		}
+		{
+			setkeysx={
+				lower={
+					\SemantexDataGetExpNot{rows}
+					\times
+					\SemantexDataGetExpNot{columns}
+				},
 			},
 		},
 	},
-	parseoptions={
-		execute={
-			\SemantexStrIfEqTF{\SemantexDataGetExpNot{columns}}{\SemantexDataGetExpNot{rows}}
-			{
-				\SemantexKeysSetx{
-					lower={
-						\SemantexDataGetExpNot{columns}
-					}
-				}
-			}
-			{
-				\SemantexKeysSetx{
-					lower={
-						\SemantexDataGetExpNot{rows}
-						\times
-						\SemantexDataGetExpNot{columns}
-					}
-				}
-			}
-		},
-	},	
-]%
-Now we can do the following:
-\begin{LTXexample}
-$ \Mat[rows=\vn,columns=\vm]{\vk} $, $ \Mat[rows=\vn,columns=\vn]{\vk} $
-\end{LTXexample}
+]
+\end{lstlisting}
 
-The key~\lstinline!execute! is a key that basically just executes code. You can in principle write any \TeX\ code there, and it will be applied right at the spot. However, inside the \lstinline!execute!~key, you can also use the following locally defined commands. These can be used to handle the data that is associated with the object in question. I don't have time to document them right now, so you'll have to guess what they do from the name for now, or you can find their definition in the source code of the package.
+Here we used a lot of programmking keys. Let us see the full list of them.
+(An important notice: For some of these keys, such as \lstinline!boolifTF!, you currently cannot use spaces in the \lstinline!⟨bool⟩! argument, so e.g. \lstinline!boolifTF{ mybool } { ... } { ... }! will not work; you have to write \lstinline!boolifTF{mybool}!. I am trying to solve this problem, but have not yet been able to do so.)
+
 \begin{lstlisting}
+dataprovide={⟨data⟩}, % provides data
+dataset={⟨data⟩}{⟨value⟩}, % sets data
+datasetx={⟨data⟩}{⟨value⟩}, % sets data after expanding it
+dataputright={⟨data⟩}{⟨value⟩}, % adds to the right of data
+dataputrightx={⟨data⟩}{⟨value⟩}, % adds to the right of data after expanding it
+dataputleft={⟨data⟩}{⟨value⟩}, % adds to the left of data
+dataputleftx={⟨data⟩}{⟨value⟩}, % adds to the left of data after expanding it
+dataclear={⟨data⟩,} % clears a piece of data
+setkeys={⟨keys⟩},	% sets the keys in question, which is rather useless since you could have just written those keys directly instead
+keysset={⟨keys⟩}, % equivalent to setkeys
+setkeysx={⟨keys⟩},	% executes the keys in question after expanding them
+keysset={⟨keys⟩}, % equivalent to setkeysx
+ifeqTF={⟨str1⟩}{⟨str2⟩}{⟨if true⟩}{⟨if false⟩}, % checks if strings are equal
+ifeqT={⟨str1⟩}{⟨str2⟩}{⟨if true⟩},
+ifeqF={⟨str1⟩}{⟨str2⟩}{⟨if false⟩},
+ifblankTF={⟨str⟩}{⟨if true⟩}{⟨if false⟩}, % checks if string is blank
+ifblankT={⟨str⟩}{⟨if true⟩},
+ifblankF={⟨str⟩}{⟨if false⟩},
+boolprovide={⟨bool⟩}, % provides a boolean
+boolsettrue={⟨bool⟩}, % sets the boolean to true
+boolsetfalse={⟨bool⟩}, % sets the boolean to false
+boolifTF={⟨bool⟩}{⟨if true⟩}{⟨if false⟩}, % checks if boolean is true
+boolifT={⟨bool⟩}{⟨if true⟩},
+boolifF={⟨bool⟩}{⟨if false⟩,
+intprovide={⟨int⟩}, % provides an integer
+intclear={⟨int⟩}, % sets the integer to 0
+intincr={⟨int⟩}, % adds 1 to the integer
+intset={⟨int⟩}{⟨value⟩}, % sts the integer
+intifgreaterthanTF={⟨num1⟩}{num2⟩}{⟨if true⟩}{⟨if false⟩}, % checks which number of greater
+intifgreaterthanT={⟨num1⟩}⟨{num2⟩}{⟨if true⟩},
+intifgreaterthanF={⟨num1⟩}{⟨num2⟩}{⟨if false⟩},
+intifequalTF={⟨num1⟩}{num2⟩}{⟨if true⟩}{⟨if false⟩}, % checks if the numbers are equal
+intifequalT={⟨num1⟩}⟨{num2⟩}{⟨if true⟩},
+intifequalF={⟨num1⟩}{⟨num2⟩}{⟨if false⟩},
+intiflessthanTF={⟨num1⟩}{num2⟩}{⟨if true⟩}{⟨if false⟩}, % checks which number of less
+intiflessthanT={⟨num1⟩}⟨{num2⟩}{⟨if true⟩},
+intiflessthanF={⟨num1⟩}{⟨num2⟩}{⟨if false⟩},
+ERRORkeyvaluenotfound={⟨key⟩}{⟨value⟩}, % throws an error saying that the key has been set to an unkonwn value
+ERROR={⟨error text⟩}, % throws a general error with the provided error test
+execute={⟨error text⟩}, % executes the code in question
+\end{lstlisting}
+
+When using these keys (including inside the key~\lstinline!execute!), you can use a number of commands that provide and manipulate data. Most of them are just command versions of the keys above, and for now, I leave it to the reader to guess what they do based on the above picture:
+
+\begin{lstlisting}
 \SemantexDataProvide
 \SemantexDataSet
 \SemantexDataSetx
@@ -1956,25 +1984,26 @@
 \SemantexIntClear
 \SemantexIntIncr
 \SemantexIntSet
-\SemantexIntIfPositiveTF
-\SemantexIntIfPositiveT
-\SemantexIntIfPositiveF
-\SemantexIntIfGreaterThanOneTF
-\SemantexIntIfGreaterThanOneT
-\SemantexIntIfGreaterThanOneF
-\SemantexExpNot
+\SemantexIntIfGreaterThanTF
+\SemantexIntIfGreaterThanT
+\SemantexIntIfGreaterThanF
+\SemantexIntIfEqualTF
+\SemantexIntIfEqualT
+\SemantexIntIfEqualF
+\SemantexIntIfLessThanTF
+\SemantexIntIfLessThanT
+\SemantexIntIfLessThanF
+\SemantexExpNot##1
+\SemantexERRORKeyValueNotFound
+\SemantexERROR
 \end{lstlisting}
 
-The key~\lstinline!parseoptions! is a key that is executed right before rendering the object.  This is where you write whatever the system is supposed to \emph{do} with the data sets you provide. You can also force it to be applied at any point by using the \lstinline!parse!~key.
-
 Let us look at a more complicated example: Let us create a command for partial derivatives:
 
 \NewObject\MyVar\partialdif[
 	nopar,
-	execute={
-		\SemantexBoolProvide{raisedfunction}
-		\SemantexBoolSetTrue{raisedfunction}
-	},
+	boolprovide={raisefunction},
+	boolsettrue={raisefunction},
 	setidots=\cdots,
 	setisep=\,,
 	valuekeys={
@@ -1981,64 +2010,85 @@
 		{default}{
 			si={\partial #1},
 		},
-	},
-	singlekeys={
-		{raisedfunction}{
-			execute={
-				\SemantexBoolSetTrue{raisedfunction}
+		{raise}{
+			ifeqTF={#1}{true}
+			{
+				boolsettrue={raisefunction},
+			}
+			{
+				ifeqTF={#1}{false}
+				{
+					boolsetfalse={raisefunction},
+				}
+				{
+					ERRORkeyvaluenotfound={raise}{#1},
+				},
 			},
 		},
-		{noraisedfunction}{
-			execute={
-				\SemantexBoolSetFalse{raisedfunction}
-			},
-		},
 	},
 	parseoptions={
-		execute={
-			\SemantexIfBlankTF{ \SemantexDataGet{upper} }
+		ifblankTF={ \SemantexDataGet{upper} }
+		{
+			intifgreaterthanTF={ \SemantexIntGet{numberoflowerindices} } { 1 }
 			{
-				\SemantexKeysSetx{
+				setkeysx={
 					symbol={
 						\frac
 						{
 							\partial ^ { \SemantexIntGet{numberoflowerindices} }
-							\SemantexBoolIfT{raisedfunction}
+							\SemantexBoolIfT{raisefunction}
 							{
-								\SemantexDataGetExpNot{arg}
+								\SemantexDataGet{arg}
 							}
 						}
 						{
-							\SemantexDataGetExpNot{lower}
+							\SemantexDataGet{lower}
 						}
 					},
-				}
+				},
 			}
 			{
-				\SemantexKeysSetx{
+				setkeysx={
 					symbol={
 						\frac
 						{
-							\partial ^ { \SemantexDataGet{upper} }
-							\SemantexBoolIfT{raisedfunction}
+							\partial
+							\SemantexBoolIfT{raisefunction}
 							{
-								\SemantexDataGetExpNot{arg}
+								\SemantexDataGet{arg}
 							}
 						}
 						{
-							\SemantexDataGetExpNot{lower}
+							\SemantexDataGet{lower}
 						}
 					},
 				}
-			}
-			\SemantexDataClear{lower}
-			\SemantexDataClear{upper}
-			\SemantexBoolIfT{raisedfunction}
-			{
-				\SemantexDataClear{arg}
-				\SemantexIntClear{numberofarguments}
-			}
+			},
+		}
+		{
+			setkeysx={
+				symbol={
+					\frac
+					{
+						\partial ^ { \SemantexDataGet{upper} }
+						\SemantexBoolIfT{raisefunction}
+						{
+							\SemantexDataGet{arg}
+						}
+					}
+					{
+						\SemantexDataGet{lower}
+					}
+				},
+			},
 		},
+		dataclear={lower},
+		dataclear={upper},
+		boolifT={raisefunction}
+		{
+			dataclear={arg},
+			dataclear={numberofarguments},
+		},
 	},
 ]
 
@@ -2045,10 +2095,8 @@
 \begin{lstlisting}
 \NewObject\MyVar\partialdif[
 	nopar,
-	execute={
-		\SemantexBoolProvide{raisedfunction}
-		\SemantexBoolSetTrue{raisedfunction}
-	},
+	boolprovide={raisefunction},
+	boolsettrue={raisefunction},
 	setidots=\cdots,
 	setisep=\,,
 	valuekeys={
@@ -2055,64 +2103,85 @@
 		{default}{
 			si={\partial #1},
 		},
-	},
-	singlekeys={
-		{raisedfunction}{
-			execute={
-				\SemantexBoolSetTrue{raisedfunction}
+		{raise}{
+			ifeqTF={#1}{true}
+			{
+				boolsettrue={raisefunction},
+			}
+			{
+				ifeqTF={#1}{false}
+				{
+					boolsetfalse={raisefunction},
+				}
+				{
+					ERRORkeyvaluenotfound={raise}{#1},
+				},
 			},
 		},
-		{noraisedfunction}{
-			execute={
-				\SemantexBoolSetFalse{raisedfunction}
-			},
-		},
 	},
 	parseoptions={
-		execute={
-			\SemantexIfBlankTF{ \SemantexDataGet{upper} }
+		ifblankTF={ \SemantexDataGet{upper} }
+		{
+			intifgreaterthanTF={ \SemantexIntGet{numberoflowerindices} } { 1 }
 			{
-				\SemantexKeysSetx{
+				setkeysx={
 					symbol={
 						\frac
 						{
 							\partial ^ { \SemantexIntGet{numberoflowerindices} }
-							\SemantexBoolIfT{raisedfunction}
+							\SemantexBoolIfT{raisefunction}
 							{
-								\SemantexDataGetExpNot{arg}
+								\SemantexDataGet{arg}
 							}
 						}
 						{
-							\SemantexDataGetExpNot{lower}
+							\SemantexDataGet{lower}
 						}
 					},
-				}
+				},
 			}
 			{
-				\SemantexKeysSetx{
+				setkeysx={
 					symbol={
 						\frac
 						{
-							\partial ^ { \SemantexDataGet{upper} }
-							\SemantexBoolIfT{raisedfunction}
+							\partial
+							\SemantexBoolIfT{raisefunction}
 							{
-								\SemantexDataGetExpNot{arg}
+								\SemantexDataGet{arg}
 							}
 						}
 						{
-							\SemantexDataGetExpNot{lower}
+							\SemantexDataGet{lower}
 						}
 					},
 				}
-			}
-			\SemantexDataClear{lower}
-			\SemantexDataClear{upper}
-			\SemantexBoolIfT{raisedfunction}
-			{
-				\SemantexDataClear{arg}
-				\SemantexIntClear{numberofarguments}
-			}
+			},
+		}
+		{
+			setkeysx={
+				symbol={
+					\frac
+					{
+						\partial ^ { \SemantexDataGet{upper} }
+						\SemantexBoolIfT{raisefunction}
+						{
+							\SemantexDataGet{arg}
+						}
+					}
+					{
+						\SemantexDataGet{lower}
+					}
+				},
+			},
 		},
+		dataclear={lower},
+		dataclear={upper},
+		boolifT={raisefunction}
+		{
+			dataclear={arg},
+			dataclear={numberofarguments},
+		},
 	},
 ]
 \end{lstlisting}
@@ -2128,13 +2197,13 @@
 		d=\vn]{ \vf }
 \]
 \[
-	\partialdif[\vx,\vy,\vz,noraisedfunction]{ \vf } ,
+	\partialdif[\vx,\vy,\vz,raise=false]{ \vf } ,
 	\partialdif[\vu^2,\vv^2,
-		d=4,noraisedfunction]{
+		d=4,raise=false]{
 			\vf },
 	\partialdif[\vx[1],
 		\vx[2],...,\vx[\vn],
-		d=\vn,noraisedfunction]{
+		d=\vn,raise=false]{
 			\vf	}
 \]
 \end{LTXexample}
@@ -2151,7 +2220,10 @@
 
 \chapter{Bugs}
 
-Lots of things can be improved in the system, including the order in which things are being expanded internally. I am not going to explain this is detail for now, but hope to correct this in the future. For now, the system seems to work fine as long as you do \enquote{normal} things and insert~\lstinline!\noexpand!'s whenever something goes wrong. The only real bug that I currently know of occurs if you use the key~\lstinline!Otherspar! in a heading. Then it all dies painfully.
+The biggest unsolved problem I know of is how to correctly strip spaces in programming keys such as \lstinline!boolifTF!. Similarly, I would also like to allow keys to be defined using the
+syntax~\lstinline!{ inv } { upper=-1 }! rather than~\lstinline!{inv}{ upper=-1 }!. This will hopefully be solved soon.
+
+For now, the system seems to work fine as long as you do \enquote{normal} things. The only real bug that I currently know of occurs if you use the key~\lstinline!Otherspar! in a heading. Then it all dies painfully.
 Then again, why the heck would you do that in the first place? Who scales parentheses in headings?
 
 %\input{testground}

Modified: trunk/Master/texmf-dist/tex/latex/semantex/semantex.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/semantex/semantex.sty	2020-07-21 21:40:00 UTC (rev 55901)
+++ trunk/Master/texmf-dist/tex/latex/semantex/semantex.sty	2020-07-21 21:40:12 UTC (rev 55902)
@@ -1,6 +1,17 @@
 \RequirePackage{expl3,xparse}
-\ProvidesExplPackage{semantex}{2020/07/07}{0.201alpha}{}
+\ProvidesExplPackage{semantex}{2020/07/21}{0.3alpha}{}
 
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%												%
+%		SemanTeX -- semantic mathematics		%
+%		https://ctan.org/pkg/semantex			%
+%		(C) 2020 Sebastian Ørsted				%
+%       sorsted at gmail.com						%
+%												%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %
 %    ERROR MESSAGES
@@ -32,10 +43,16 @@
 
 \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~object~#2~on~line~\msg_line_number: } {}
+\msg_new:nnnn { semantex } { created_object_of_unknown_class } { Unknown~class~#1~declared~as~class~of~#2~on~line~\msg_line_number: } {}
 
-\msg_new:nnnn { semantex } { created_a_SemantexVariable } { Never~create~objects~of~class~\SemantexVariable;~create~a~new~class~yourself~instead.~You~created~the~object~#1~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
@@ -50,6 +67,8 @@
 	\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 }
@@ -87,29 +106,89 @@
 %
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
+\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 } { #2 }
+	\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 { ifoutput=true, symbol = { ##1 }, ##2 }
+			\semantex_render_class:Nn #1 {
+				\semantex_class_do_output:N #1
+				\semantex_class_set_symbol:Nn #1 { ##1 }
+				\semantex_class_set_keys:Nn #1 { ##2 }
+			}
 		}
 		{
-			\semantex_render_class:Nn #1 { symbol = { ##1 } }
+			\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 { ifoutput=true, symbol = { ##2 }, ##1, ##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 { symbol = { ##2 },  ##1 }
+			\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{}}
@@ -120,10 +199,15 @@
 		% ##3 = options
 		\IfValueTF{##2}
 		{
-			\semantex_new_object:NNn { #1 } ##1 { symbol = { ##2 }, ##3 }
+			\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 { ##3 }
+			\semantex_new_object:NNn #1 ##1 {
+				\semantex_object_set_keys:Nn ##1 { ##3 }
+			}
 		}
 		% create the object with name ##1
 		\DeclareDocumentCommand{##1}{o}{
@@ -130,7 +214,10 @@
 		% the actual \##1 command
 			\IfValueTF { ####1 }
 			{
-				\semantex_render_object:Nn ##1 { ifoutput=true,####1 }
+				\semantex_render_object:Nn ##1 {
+					\semantex_object_do_output:N ##1
+					\semantex_object_set_keys:Nn ##1 { ####1 }
+				}
 			}
 			{
 				\semantex_render_object:Nn ##1 { }
@@ -147,7 +234,8 @@
 {
 	% #1 = class name
 	% #2 = options
-	\semantex_new_class:Nn { #1 } { #2 }
+	\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 }
@@ -154,19 +242,34 @@
 			{
 				\IfValueTF { ##3 }
 				{
-					\semantex_render_class:Nn #1 { ifoutput=true,symbol={##1},##2,arg={##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 { ifoutput=true,symbol={##1},##2}
+					\semantex_render_class:Nn #1 { 
+						\semantex_class_do_output:N #1
+						\semantex_class_set_symbol:Nn #1 { ##1 }
+						\semantex_class_set_keys:Nn #1 { ##2 }
+					}
 				}
 			}
 			{
 				\IfValueTF { ##3 }
 				{
-					\semantex_render_class:Nn #1 { ifoutput=true,symbol={##1},arg={##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 { symbol={##1} }
+					\semantex_render_class:Nn #1 {
+						\semantex_class_set_symbol:Nn #1 { ##1 }
+					}
 				}
 			}
 	}
@@ -174,19 +277,38 @@
 		\IfValueTF { ##3 }
 		{
 			\IfValueTF { ##4 }{
-				\semantex_render_class:Nn #1 { ifoutput=true,symbol={##2}, ##1, ##3,arg={##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 { ifoutput=true,symbol={##2}, ##1, ##3 }
+				\semantex_render_class:Nn #1 {
+					\semantex_class_do_output:N #1
+					\semantex_class_set_symbol:Nn #1 { ##2 }
+					##1
+					\semantex_class_set_keys:Nn #1 { ##3 }
+				}
 			}
 		}
 		{
 			\IfValueTF { ##4 }
 			{
-				\semantex_render_class:Nn #1 { ifoutput=true,symbol={##2}, ##1,arg={##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 { symbol={##2}, ##1 }
+				\semantex_render_class:Nn #1 {
+					\semantex_class_set_symbol:Nn #1 { ##2 }
+					##1
+				}
 			}
 		}
 	}
@@ -198,10 +320,15 @@
 		% ##3 = options
 		\IfValueTF{##2}
 		{
-			\semantex_new_object:NNn { #1 } ##1 { symbol = { ##2 }, ##3 }
+			\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 { ##3 }
+			\semantex_new_object:NNn #1 ##1 {
+				\semantex_object_set_keys:Nn ##1 { ##3 }
+			}
 		}
 		% creates the object with name ##1
 		\DeclareDocumentCommand{##1}{og}{
@@ -209,16 +336,26 @@
 			\IfValueTF{####1}{
 				\IfValueTF{####2}
 				{
-					\semantex_render_object:Nn ##1 { ifoutput=true,####1, arg={####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 { ifoutput=true,####1}
+					\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 { ifoutput=true,arg={####2} }
+					\semantex_render_object:Nn ##1 {
+						\semantex_object_do_output:N ##1
+						\semantex_object_set_arg:Nn ##1 { ####2 }
+					}
 				}
 				{
 					\semantex_render_object:Nn ##1 {}
@@ -234,7 +371,7 @@
 {
 	% #1 = class name
 	% #2 = options
-	\semantex_new_class:Nn { #1 } { #2 }
+	\semantex_new_class:Nn { #1 } { \semantex_class_set_keys:Nn #1 { #2 } }
 	\DeclareDocumentCommand{#1}{mogg}{
 		% the actual \#1 command
 		\IfValueTF{##2}
@@ -245,10 +382,21 @@
 				{
 					\IfValueTF { ##4 }
 					{
-						\semantex_render_class:Nn #1 { ifoutput=true,symbol={##1}, ##2, *, arg={##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 { ifoutput=true,symbol={##1}, ##2, * }
+						\semantex_render_class:Nn #1 {
+							\semantex_class_do_output:N #1
+							\semantex_class_set_symbol:Nn #1 { ##1 }
+							\semantex_class_set_keys:Nn #1 { ##2 }
+							\semantex_class_use_bullet:N #1
+						}
 					}	
 				}
 				{
@@ -256,19 +404,41 @@
 					{
 						\IfValueTF { ##4 }
 						{
-							\semantex_render_class:Nn #1 { ifoutput=true,symbol={##1}, ##2, **, arg={##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 { ifoutput=true,symbol={##1}, ##2, ** }
+							\semantex_render_class:Nn #1 {
+								\semantex_class_do_output:N #1
+								\semantex_class_set_symbol:Nn #1 { ##1 }
+								\semantex_class_set_keys:Nn #1 { ##2 }
+								\semantex_class_use_double_bullet:N #1
+							}
 						}
 					}
 					{
 						\IfValueTF { ##4 }
 						{
-							\semantex_render_class:Nn #1 { ifoutput=true,symbol={##1}, ##2, degreedefault={##3}, arg={##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 { ifoutput=true,symbol={##1}, ##2, degreedefault={##3} }
+							\semantex_render_class:Nn #1 {
+								\semantex_class_do_output:N #1
+								\semantex_class_set_symbol:Nn #1 { ##1 }
+								\semantex_class_set_keys:Nn #1 { ##2 }
+								\semantex_class_set_degreedefault:Nn #1 { ##3 }
+							}
 						}
 					}
 				}
@@ -276,10 +446,19 @@
 			{
 				\IfValueTF { ##4 }
 				{
-					\semantex_render_class:Nn #1 { ifoutput=true,symbol={##1}, ##2, arg={##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 { ifoutput=true,symbol={##1}, ##2 }
+					\semantex_render_class:Nn #1 {
+						\semantex_class_do_output:N #1
+						\semantex_class_set_symbol:Nn #1 { ##1 }
+						\semantex_class_set_keys:Nn #1 { ##2 }
+					}
 				}
 			}
 		}
@@ -290,10 +469,19 @@
 				{
 					\IfValueTF { ##4 }
 					{
-						\semantex_render_class:Nn #1 { ifoutput=true, symbol={##1}, *, arg={##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 { ifoutput=true, symbol={##1}, *}
+						\semantex_render_class:Nn #1 {
+							\semantex_class_do_output:N #1
+							\semantex_class_set_symbol:N #1 { ##1 }
+							\semantex_class_use_bullet:N #1
+						}
 					}
 				}
 				{
@@ -301,19 +489,37 @@
 					{
 						\IfValueTF { ##4 }
 						{
-							\semantex_render_class:Nn #1 { ifoutput=true,symbol={##1}, **, arg={##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 { ifoutput=true,symbol={##1}, ** }
+							\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 { ifoutput=true,symbol={##1},  degreedefault={##3}, arg={##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 { ifoutput=true,symbol={##1},  degreedefault={##3} }
+							\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 }
+							}
 						}
 					}
 				}
@@ -321,10 +527,16 @@
 			{
 				\IfValueTF { ##4 }
 				{
-					\semantex_render_class:Nn #1 { ifoutput=true,symbol={##1}, arg={##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 { symbol={##1}, arg={##4} }
+					\semantex_render_class:Nn #1 {
+						\semantex_class_set_symbol:Nn #1 { ##1 }
+					}
 				}
 			}
 		}
@@ -338,10 +550,23 @@
 				{
 					\IfValueTF { ##5 }
 					{
-						\semantex_render_class:Nn #1 { ifoutput=true,symbol={##2}, ##1, ##3, *, arg={##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 { ifoutput=true,symbol={##2}, ##1, ##3, * }
+						\semantex_render_class:Nn #1 {
+							\semantex_class_do_output:N #1
+							\semantex_class_set_symbol:Nn #1 { ##2 }
+							##1
+							\semantex_class_set_keys:Nn #1 { ##3 }
+							\semantex_class_use_bullet:N #1
+						}
 					}
 				}
 				{
@@ -349,19 +574,45 @@
 					{
 						\IfValueTF { ##5 }
 						{
-							\semantex_render_class:Nn #1 {ifoutput=true, symbol={##2}, ##1, ##3, **, arg={##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 {ifoutput=true, symbol={##2}, ##1, ##3, ** }
+							\semantex_render_class:Nn #1 {
+								\semantex_class_do_output:N #1
+								\semantex_class_set_symbol:Nn #1 { ##2 }
+								##1
+								\semantex_class_set_keys:Nn #1 { ##3 }
+								\semantex_class_use_double_bullet:N #1
+							}
 						}
 					}
 					{
 						\IfValueTF { ##5 }
 						{
-							\semantex_render_class:Nn #1 { ifoutput=true,symbol={##2}, ##1,##3, degreedefault={##4}, arg={##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 { ifoutput=true,symbol={##2}, ##1,##3, degreedefault={##4} }
+							\semantex_render_class:Nn #1 {
+								\semantex_class_do_output:N #1
+								\semantex_class_set_symbol:Nn #1 { ##2 }
+								##1
+								\semantex_class_set_keys:Nn #1 { ##3 }
+								\semantex_class_set_degreedefault:Nn #1 { ##4 }
+							}
 						}
 					}
 				}
@@ -369,10 +620,21 @@
 			{
 				\IfValueTF { ##5 }
 				{
-					\semantex_render_class:Nn #1 { ifoutput=true,symbol={##2}, ##1, ##3, arg={##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 { ifoutput=true,symbol={##2}, ##1, ##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 }
+					}
 				}
 			}
 		}
@@ -383,10 +645,21 @@
 				{
 					\IfValueTF { ##5 }
 					{
-						\semantex_render_class:Nn #1 { ifoutput=true, symbol={##2} ,##1, *, arg={##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 { ifoutput=true, symbol={##2} ,##1, *}
+						\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
+						}
 					}
 				}
 				{
@@ -394,19 +667,41 @@
 					{
 						\IfValueTF { ##5 }
 						{
-							\semantex_render_class:Nn #1 { ifoutput=true, symbol={##2} , ##1,  **, arg={##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 { ifoutput=true, symbol={##2} , ##1,  ** }
+							\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 { ifoutput=true, symbol={##2}, ##1,  degreedefault={##4}, arg={##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 { ifoutput=true, symbol={##2}, ##1,  degreedefault={##4} }
+							\semantex_render_class:Nn #1 {
+								\semantex_class_do_output:N #1
+								\semantex_class_set_symbol:Nn #1 { ##2 }
+								##1
+								\semantex_class_set_degreedefault:Nn #1 { ##4 }
+							}
 						}
 					}
 				}
@@ -414,10 +709,18 @@
 			{
 				\IfValueTF { ##5 }
 				{
-					\semantex_render_class:Nn #1 { ifoutput=true,symbol={##2}, ##1, arg={##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 { symbol={##2}, ##1 }
+					\semantex_render_class:Nn #1 {
+						\semantex_class_set_symbol:Nn #1 { ##2 }
+						##1
+					}
 				}
 			}
 		}
@@ -430,10 +733,15 @@
 		% ##3 = options
 		\IfValueTF{##2}
 		{
-			\semantex_new_object:NNn { #1 } { ##1 }{ symbol = { ##2 }, ##3 }
+			\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 }{ ##3 }
+			\semantex_new_object:NNn #1 { ##1 }{
+				\semantex_object_set_keys:Nn ##1 { ##3 }
+			}
 		}
 		% creates the object with name ##1
 		\DeclareDocumentCommand{##1}{ogg}{
@@ -446,10 +754,19 @@
 					{
 						\IfValueTF{####3}
 						{
-							\semantex_render_object:Nn ##1 {  ifoutput=true,####1, *, arg={ ####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 {  ifoutput=true,####1, * }
+							\semantex_render_object:Nn ##1 {
+								\semantex_object_do_output:N ##1
+								\semantex_object_set_keys:Nn ##1 { ####1 }
+								\semantex_object_use_bullet:N ##1
+							}
 						}
 					}
 					{
@@ -457,19 +774,37 @@
 						{
 							\IfValueTF{####3}
 							{
-								\semantex_render_object:Nn ##1 { ifoutput=true, ####1, **, arg={ ####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 { ifoutput=true, ####1, ** }
+								\semantex_render_object:Nn ##1 {
+									\semantex_object_do_output:N ##1
+									\semantex_object_set_keys:Nn ##1 { ####1 }
+									\semantex_object_use_double_bullet:N ##1
+								}
 							}
 						}
 						{
 							\IfValueTF{####3}
 							{
-								\semantex_render_object:Nn ##1 {  ifoutput=true,####1, degreedefault={ ####2 }, arg={ ####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 {  ifoutput=true,####1, degreedefault={ ####2 } }
+								\semantex_render_object:Nn ##1 {
+									\semantex_object_do_output:N ##1
+									\semantex_object_set_keys:Nn ##1 { ####1 }
+									\semantex_object_set_degreedefault:Nn ##1 { ####2 }
+								}
 							}
 						}
 					}
@@ -477,10 +812,17 @@
 				{
 					\IfValueTF{####3}
 					{
-						\semantex_render_object:Nn ##1 {  ifoutput=true,####1, arg={ ####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 {  ifoutput=true,####1 }
+						\semantex_render_object:Nn ##1 {
+							\semantex_object_do_output:N ##1
+							\semantex_object_set_keys:Nn ##1 { ####1 }
+						}
 					}
 				}
 			}
@@ -491,10 +833,17 @@
 					{
 						\IfValueTF{####3}
 						{
-							\semantex_render_object:Nn ##1 { ifoutput=true, *, arg={ ####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 { ifoutput=true, * }
+							\semantex_render_object:Nn ##1 {
+								\semantex_object_do_output:N ##1
+								\semantex_object_use_bullet:N ##1
+							}
 						}
 					}
 					{
@@ -502,19 +851,33 @@
 						{
 							\IfValueTF{####3}
 							{
-								\semantex_render_object:Nn ##1 {   ifoutput=true,**, arg={ ####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 {   ifoutput=true,** }
+								\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 { ifoutput=true,degreedefault={ ####2 }, arg={ ####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 { ifoutput=true,degreedefault={ ####2 } }
+								\semantex_render_object:Nn ##1 {
+									\semantex_object_do_output:N ##1
+									\semantex_object_set_degreedefault:Nn ##1 { ####2 }
+								}
 							}
 						}
 					}
@@ -522,7 +885,10 @@
 				{
 					\IfValueTF{####3}
 					{
-						\semantex_render_object:Nn ##1 { ifoutput=true, arg={ ####3 } }
+						\semantex_render_object:Nn ##1 {
+							\semantex_object_do_output:N ##1
+							\semantex_object_set_arg:Nn ##1 { ####3 }
+						}
 					}
 					{
 						\semantex_render_object:Nn ##1 { }
@@ -539,9 +905,7 @@
 {
 	% #1 = class name
 	% #2 = options
-	\semantex_new_class:Nn { #1 } {
-		#2
-	}
+	\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 }
@@ -548,19 +912,34 @@
 		{
 			\IfValueTF { ##3 }
 			{
-				\semantex_render_class:Nn #1 { ifoutput=true, symbol = { ##1 }, ##2, arg = { ##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 { ifoutput=true, symbol = { ##1 }, ##2 }
+				\semantex_render_class:Nn #1 {
+					\semantex_class_do_output:N #1
+					\semantex_class_set_symbol:Nn #1 { ##1 }
+					\semantex_class_set_keys:Nn #1 { ##2 }
+				}
 			}
 		}
 		{
 			\IfValueTF { ##3 }
 			{
-				\semantex_render_class:Nn #1 { ifoutput=true, symbol = { ##1 }, arg = { ##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 { symbol = { ##1 } }
+				\semantex_render_class:Nn #1 {
+					\semantex_class_set_symbol:Nn #1 { ##1 }
+				}
 			}
 		}
 	}
@@ -571,19 +950,38 @@
 		{
 			\IfValueTF { ##4 }
 			{
-				\semantex_render_class:Nn #1 { ifoutput=true, symbol = { ##2 }, ##1, ##3, arg = { ##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 { ifoutput=true, symbol = { ##2 }, ##1, ##3 }
+				\semantex_render_class:Nn #1 {
+					\semantex_class_do_output:N #1
+					\semantex_class_set_symbol:Nn #1 { ##2 }
+					##1
+					\semantex_class_set_keys:Nn #1{ ##3 }
+				}
 			}
 		}
 		{
 			\IfValueTF { ##4 }
 			{
-				\semantex_render_class:Nn #1 { ifoutput=true, symbol = { ##2 }, ##1, arg = { ##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 { symbol = { ##2 }, ##1 }
+				\semantex_render_class:Nn #1 {
+					\semantex_class_set_symbol:Nn #1 { ##2 }
+					##1
+				}
 			}
 		}
 	}
@@ -593,7 +991,11 @@
 		% ##1 = command name, with backslash
 		% ##2 = symbol
 		% ##3 = options
-		\semantex_new_object:NNn { #1 } { ##1 }{ leftpar = { ##2 }, rightpar = { ##3 }, ##4 }
+		\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
@@ -601,16 +1003,26 @@
 			{
 				\IfValueTF { ####2 }
 				{
-					\semantex_render_object:Nn ##1 { ifoutput=true,####1, arg = { ####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 { ifoutput=true,####1  }
+					\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 { ifoutput=true, arg = { ####2 } }
+					\semantex_render_object:Nn ##1 {
+						\semantex_object_do_output:N ##1
+						\semantex_object_set_arg:Nn ##1 { ####2 }
+					}
 				}
 				{
 					\semantex_render_object:Nn ##1 { }
@@ -636,9 +1048,8 @@
 	}
 }
 
-%\cs_new:Npn\MakeObject#1{ \use:c { __semantex_make_object_of_class_#1:nw } }
-
-\cs_new:Npn \__semantex_new_class_or_object:nn#1#2{
+\cs_new:Npn \__semantex_new_class_or_object:nn#1#2
+{
 	% create new object
 	% #1 = name of command, without backslash
 	% #2 = standard keyval setup
@@ -645,26 +1056,28 @@
 
 	\semantex_data_tl_provide:nn { #1 } { parent }
 
-	\semantex_data_tl_set:nnn { #1 } { parent } { class_SemantexVariable }
+	\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 { ##2 } { ##1 } { #1 } }
+	{ \semantex_valuekey:nnn { #1 } { ##1 } { ##2 } }
 
 	\cs_set:cpn { __semantex_data_cs_#1_singlekey:n } ##1 % command controlling singlekeys
-	{ \semantex_singlekey:nn { ##1 } { #1 } }
-	
+	{ \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 { ##2 } { ##1 }{ #1 } }
+	{ \semantex_arg_valuekey:nnn { #1 } { ##1 } { ##2 } }
 	
 	\cs_set:cpn { __semantex_data_cs_#1_arg_singlekey:n } ##1
-	{ \semantex_arg_singlekey:nn { ##1 } { #1 } }
+	{ \semantex_arg_singlekey:nn { #1 } { ##1 } }
 	
-	% initially sets up the keyval interface of the object
-	\semantex_keys_set:nn { #1 } { #2 }
+	\cs_set:cpn { __semantex_data_cs_#1_outputoptions:n } ##1 {}
 	
-%	\seq_put_right:Nx \g__semantex_all_objects_seq { #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 }
@@ -672,13 +1085,13 @@
 \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 SemantexVariable
-	\semantex_class_if_exist:NTF { #1 }
+	% #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_class_register:N #1
 		\__semantex_new_class_or_object:xn { class_\cs_to_str:N #1 } { #2 }
 	}
 }
@@ -685,16 +1098,121 @@
 
 \cs_set:Npn \semantex_new_object:NNn#1#2#3
 {
-	\semantex_object_if_exist:NTF { #2 }
+	\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_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
@@ -733,20 +1251,22 @@
 	% #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
-		\semantex_primitive_valuekey_parse:nn { #1 } { } % Run the "parse" routine, i.e. the collection of code that the user has added to the parse register
+		%\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_primitive_valuekey_innerreturn:nn { #1 }{}
+			\__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_primitive_valuekey_leftreturn:nn { #1 }{}
+					\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_leftreturn:nn { #1 }{}
 				}
 				{
-					\semantex_primitive_valuekey_rightreturn:nn { #1 }{}
+					\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_rightreturn:nn { #1 }{}
 				}
 			}
 			{
@@ -759,20 +1279,28 @@
 					__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
 				{
-					upperputleft={\semantex_data_tl_get_exp_not:nn { #1 } { upper }},
-					lowerputleft={\semantex_data_tl_get_exp_not:nn { #1 } { lower }},
-					upperleftputright={\semantex_data_tl_get_exp_not:nn { #1 } { upperleft }},
-					lowerleftputright={\semantex_data_tl_get_exp_not:nn { #1 } { lowerleft }},
-					preupper={\semantex_data_tl_get_exp_not:nn { #1 } { preupper }},
-					postupper={\semantex_data_tl_get_exp_not:nn { #1 } { postupper }},
-					prelower={\semantex_data_tl_get_exp_not:nn { #1 } { prelower }},
-					postlower={\semantex_data_tl_get_exp_not:nn { #1 } { postlower }},
-					preupperleft={\semantex_data_tl_get_exp_not:nn { #1 } { preupperleft }},
-					postupperleft={\semantex_data_tl_get_exp_not:nn { #1 } { postupperleft }},
-					prelowerleft={\semantex_data_tl_get_exp_not:nn { #1 } { prelowerleft }},
-					postlowerleft={\semantex_data_tl_get_exp_not:nn { #1 } { postlowerleft }},
-					texclass={\semantex_data_tl_get:nn { #1 } { texclass }},
-					\semantex_data_tl_get_exp_not:nn { #1 } { outputoptions },
+					\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
@@ -781,7 +1309,7 @@
 			}
 		}
 		{
-			\semantex_primitive_valuekey_return:nn { #1 }{} % Returns the object/class, i.e. adds all remaining indices and arguments to it
+			\__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
@@ -801,6 +1329,20 @@
 	\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
@@ -1019,7 +1561,7 @@
 %		\use:c { g__semantex_data_tl_#1_#2 }
 %	}
 %	{
-%		\tl_if_eq:nnTF { #1 } { SemantexVariable }
+%		\tl_if_eq:nnTF { #1 } { SemantexBaseObject }
 %		{
 %			\msg_error:nnnn { semantex } { data_tl_not_found } { #2 } { #3 }
 %		}
@@ -1052,8 +1594,8 @@
 		\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
-		\msg_error:nnxnn { semantex } { class_not_found } { \l__semantex_data_parent_set_temp } { parent } { #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 }
 	}
 }
 
@@ -1064,11 +1606,13 @@
 		\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
-		\msg_error:nnxnn { semantex } { class_not_found } { \l__semantex_data_class_set_temp } { class } { #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 }
@@ -1076,8 +1620,8 @@
 		\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
-		\msg_error:nnxnn { semantex } { object_not_found } { \l__semantex_data_copy_object_temp } { copy } { #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 }
 	}
 }
 
@@ -1088,11 +1632,69 @@
 		\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
-		\msg_error:nnxnn { semantex } { object_not_found } { \l__semantex_data_clone_object_temp } { clone } { #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
@@ -1116,10 +1718,10 @@
 		\use:c { g__semantex_data_tl_#1_#2 }
 	}
 	{
-		\str_if_eq:nnTF { #1 } { class_SemantexVariable } % Apparently, f-type expansion seemed to work here for once
+		\str_if_eq:nnTF { #1 } { class_SemantexBaseObject } % Apparently, f-type expansion seemed to work here for once
 		{
-			\semantex_error_output_format:nN { #3 } \__semantex_data_tl_get_auxiliary_temp
-			\msg_error:nnxn { semantex } { data_tl_not_found } { \__semantex_data_tl_get_auxiliary_temp } { #2 }
+			\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 }
@@ -1159,10 +1761,10 @@
 		\exp_not:v { g__semantex_data_tl_#1_#2 }
 	}
 	{
-		\str_if_eq:nnTF { #1 } { class_SemantexVariable } % Apparently, f-type expansion seemed to work here for once
+		\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
-			\msg_error:nnxn { semantex } { data_tl_not_found } { \l__semantex_data_tl_get_exp_not_auxiliary_temp } { #2 }
+			\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 }
@@ -1191,10 +1793,10 @@
 		\tl_set_eq:Nc #3 { g__semantex_data_tl_#1_#2 }
 	}
 	{
-		\str_if_eq:nnTF { #1 } { class_SemantexVariable }
+		\str_if_eq:nnTF { #1 } { class_SemantexBaseObject }
 		{
-			\semantex_error_output_format:nN { #4 } \l__semantex_data_tl_get_store_auxiliary_temp
-			\msg_error:nnxn { semantex } { data_tl_not_found } { \l__semantex_data_tl_get_store_auxiliary_temp } { #2 }
+			\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 }
@@ -1240,7 +1842,7 @@
 	\tl_set:cn { g__semantex_data_tl_#1_#2 } { #3 }
 }
 
-\cs_generate_variant:Nn \semantex_data_tl_set:nnn { nnx }
+\cs_generate_variant:Nn \semantex_data_tl_set:nnn { nnx , xnn , xnx }
 
 \cs_new:Npn \semantex_data_tl_put_right:nnn#1#2#3
 {
@@ -1318,10 +1920,10 @@
 			\int_use:c { g__semantex_data_int_#1_#2 }
 		}
 		{
-			\str_if_eq:nnTF { #1 } { class_SemantexVariable }
+			\str_if_eq:nnTF { #1 } { class_SemantexBaseObject }
 			{
-				\semantex_error_output_format:nN { #3 } \__semantex_data_int_get_auxiliary_temp
-				\msg_error:nnxn { semantex } { data_int_not_found } { \__semantex_data_int_get_auxiliary_temp } { #2 }
+				\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 }
@@ -1329,10 +1931,10 @@
 		}
 	}
 	{
-		\str_if_eq:nnTF { #1 } { class_SemantexVariable }
+		\str_if_eq:nnTF { #1 } { class_SemantexBaseObject }
 		{
-			\semantex_error_output_format:nN { #3 } \__semantex_data_int_get_auxiliary_temp
-			\msg_error:nnxn { semantex } { data_int_not_found } { \__semantex_data_int_get_auxiliary_temp } { #2 }
+			\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 }
@@ -1361,10 +1963,10 @@
 			\int_set_eq:Nc#3 { g__semantex_data_int_#1_#2 }
 		}
 		{
-			\str_if_eq:nnTF { #1 } { class_SemantexVariable }
+			\str_if_eq:nnTF { #1 } { class_SemantexBaseObject }
 			{
-				\semantex_error_output_format:nN { #4 } \l__semantex_data_int_get_store_auxiliary_temp
-				\msg_error:nnxn { semantex } { data_int_not_found } { \l__semantex_data_int_get_store_auxiliary_temp } { #2 }
+				\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 }
@@ -1372,10 +1974,10 @@
 		}
 	}
 	{
-		\str_if_eq:nnTF { #1 } { class_SemantexVariable }
+		\str_if_eq:nnTF { #1 } { class_SemantexBaseObject }
 		{
-			\semantex_error_output_format:nN { #4 } \l__semantex_data_int_get_store_auxiliary_temp
-			\msg_error:nnxn { semantex } { data_int_not_found } { \l__semantex_data_int_get_store_auxiliary_temp } { #2 }
+			\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 }
@@ -1424,6 +2026,21 @@
 	\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 }
@@ -1499,143 +2116,6 @@
 	\seq_clear:c { g__semantex_data_seq_#1_#2 }
 }
 
-% COMMANDS FOR HANDLING DATA OF TYPE PROPERTY LIST:
-
-\cs_new:Npn \semantex_data_prop_provide:nn#1#2
-{
-	% #1 = name of the object
-	% #2 = name of the prop
-	\prop_if_exist:cF { g__semantex_data_prop_#1_#2 } { \prop_new:c { g__semantex_data_prop_#1_#2 } }
-}
-
-\cs_new:Npn \semantex_data_prop_put:nnnn#1#2#3#4
-{
-	\semantex_data_prop_provide:nn { #1 } { #2 } % important that we do not inherit! This is crucial for getting the right inheritance for key interfaces
-	\prop_put:cnn { g__semantex_data_prop_#1_#2 } { #3 } { #4 }
-}
-
-\cs_new:Npn\semantex_data_prop_remove:nnn#1#2#3
-{
-	\prop_if_exist:cT { g__semantex_data_prop_#1_#2 }
-	{
-		\prop_remove:cn { g__semantex_data_prop_#1_#2 } { #3 }
-	}
-}
-
-
-\cs_new:Npn \semantex_valuekey_get:nnNTF#1#2#3#4#5{%
-	% #1 = name of the object
-	% #2 = keyval data to get
-	% #3 = command to store possible data in
-	% #4 = if true (not to be used)
-	% #5 = if false
-	\prop_get:cnNTF { g__semantex_data_prop_#1_custom_valuekeys } { #2 } #3
-	{
-		#4
-	}
-	{
-		\str_if_eq:nnTF { #1 } { class_SemantexVariable }
-		{
-			#5
-		}
-		{
-			\semantex_valuekey_get:fnNTF { \semantex_data_parent_get:n { #1 } } { #2 } #3 { #4 } { #5 }
-		}
-	}
-}
-
-\cs_new:Npn\semantex_valuekey_remove:nn#1#2
-{
-	\semantex_data_prop_remove:nnn { #1 } { custom_valuekeys } { #2 }
-}
-
-\cs_generate_variant:Nn \semantex_valuekey_get:nnNTF { fnNTF, vnNTF, xnNTF }
-
-\cs_new:Npn \semantex_singlekey_get:nnNTF#1#2#3#4#5{%
-	% #1 = name of the object
-	% #2 = singlekey data to get
-	% #3 = command to store possible data in
-	% #4 = if true (not to be used)
-	% #5 = if false
-	\prop_get:cnNTF { g__semantex_data_prop_#1_custom_singlekeys } { #2 } #3
-	{
-		#4
-	}
-	{
-		\str_if_eq:nnTF { #1 } { class_SemantexVariable }
-		{
-			#5
-		}
-		{
-			\semantex_singlekey_get:fnNTF { \semantex_data_parent_get:n { #1 } } { #2 } #3 { #4 } { #5 }
-		}
-	}
-}
-
-\cs_new:Npn\semantex_singlekey_remove:nn#1#2
-{
-	\semantex_data_prop_remove:nnn { #1 } { custom_singlekeys } { #2 }
-}
-
-\cs_generate_variant:Nn \semantex_singlekey_get:nnNTF { fnNTF, vnNTF, xnNTF }
-
-\cs_new:Npn \semantex_arg_valuekey_get:nnNTF#1#2#3#4#5{%
-	% #1 = name of the object
-	% #2 = keyval data to get
-	% #3 = command to store possible data in
-	% #4 = if true (not to be used)
-	% #5 = if false
-	\prop_get:cnNTF { g__semantex_data_prop_#1_custom_arg_valuekeys } { #2 }#3%\l_semantex_valuekey_get_temp
-	{
-		#4
-	}
-	{
-		\str_if_eq:nnTF { #1 } { class_SemantexVariable }
-		{
-			#5
-		}
-		{
-			\semantex_arg_valuekey_get:fnNTF { \semantex_data_parent_get:n { #1 } } { #2 } #3 { #4 } { #5 }
-		}
-	}
-}
-
-\cs_generate_variant:Nn \semantex_arg_valuekey_get:nnNTF { fnNTF, vnNTF, xnNTF }
-
-\cs_new:Npn\semantex_arg_valuekey_remove:nn#1#2
-{
-	\semantex_data_prop_remove:nnn { #1 } { custom_arg_valuekeys } { #2 }
-}
-
-
-\cs_new:Npn \semantex_arg_singlekey_get:nnNTF#1#2#3#4#5{%
-	% #1 = name of the object
-	% #2 = singlekey data to get
-	% #3 = command to store possible data in
-	% #4 = if true (not to be used)
-	% #5 = if false
-	\prop_get:cnNTF { g__semantex_data_prop_#1_custom_arg_singlekeys } { #2 } #3
-	{
-		#4
-	}
-	{
-		\str_if_eq:nnTF { #1 } { class_SemantexVariable }
-		{
-			#5
-		}
-		{
-			\semantex_arg_singlekey_get:fnNTF { \semantex_data_parent_get:n { #1 } } { #2 } #3 { #4 } { #5 }
-		}
-	}
-}
-
-\cs_generate_variant:Nn \semantex_arg_singlekey_get:nnNTF { fnNTF, vnNTF, xnNTF }
-
-\cs_new:Npn\semantex_arg_singlekey_remove:nn#1#2
-{
-	\semantex_data_prop_remove:nnn { #1 } { custom_arg_singlekeys } { #2 }
-}
-
 % COMMANDS FOR HANDLING DATA OF TYPE BOOLEAN:
 
 \cs_new:Npn\semantex_data_bool_get:nnTF#1#2#3#4
@@ -1651,7 +2131,7 @@
 			\bool_if:cTF { g__semantex_data_bool_#1_if_#2 } { #3 } { #4 }
 		}
 		{
-			\str_if_eq:nnTF { #1 } { class_SemantexVariable }
+			\str_if_eq:nnTF { #1 } { class_SemantexBaseObject }
 			{
 				#4
 			}
@@ -1661,7 +2141,7 @@
 		}
 	}
 	{
-		\str_if_eq:nnTF { #1 } { class_SemantexVariable }
+		\str_if_eq:nnTF { #1 } { class_SemantexBaseObject }
 		{
 			#4
 		}
@@ -1704,6 +2184,8 @@
 	\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
@@ -1714,36 +2196,15 @@
 
 % COMMANDS FOR HANDLING COMMAND SEQUENCE DATA AND KEYVAL SYNTAX:
 
-\cs_new:Npn\semantex_data_cs_get:nnn#1#2#3
-{
-	% #1 = name of the object
-	% #2 = command sequence to get
-	% #3 = what to apply said command sequence to
-	\cs_if_exist:cTF { __semantex_data_cs_#1_#2:n }
-	{
-		\use:c { __semantex_data_cs_#1_#2:n } { #3 }
-	}
-	{
-		\str_if_eq:nnTF { #1 } { class_SemantexVariable }
-		{
-			% should probably throw an error by now, but later!
-		}
-		{
-			\semantex_data_cs_get:xnn { \semantex_data_parent_get:n {#1} } { #2 } { #3 }
-		}
-	}
-}
+\cs_generate_variant:Nn \keyval_parse:NNn { cco , ccn }
 
-\cs_generate_variant:Nn \semantex_data_cs_get:nnn { xnn }
-
-\cs_generate_variant:Nn \keyval_parse:NNn { cco }
-
 \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:cco % Could be nice to get rid of o-type expansion, but so far has not been possible
+	\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 }
@@ -1754,7 +2215,7 @@
 	% The central command for doing keyval setup for the argument
 	% #1 = object
 	% #2 = keys
-	\keyval_parse:cco % See last command
+	\keyval_parse:ccn % See last command
 	{ __semantex_data_cs_#1_arg_singlekey:n }
 	{ __semantex_data_cs_#1_arg_valuekey:nn }
 	{ #2 }
@@ -1775,35 +2236,163 @@
 \DeclareDocumentCommand\SetupClass{mm}{ % a user-level command for setting up the object
 	% #1 = class
 	% #2 = setup
-	\semantex_keys_set:xn { class_\cs_to_str:N #1 }{ #2 }
+	\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_keys_set:xn { object_\cs_to_str:N #1 } { #2 }
+	\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 PRIMITIVE VALUEKEYS
+%    THE VALUEKEYS FOR \SemantexBaseObject
 %
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-% Now for the commands that are the basis of the keyval interface.
-% This basis consists of a collection of so-called "primitive"
-% valuekeys, which all use the syntax
-% \semantex_primitive_<nameOfValuekey>:nn
-% These are like primitive TeX commands -- they are not defined in
-% terms of other keys, and all other keys have to defined in terms
-% of these, one way or another.
+% 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. To keep the system as simple as possible, I chose only to
-% make primitive valuekeys, so there is no such thing as a primitive
-% singlekey. Therefore, for instance, the singlekey "return" is
-% defined as "return=", where return is a primitive valuekey that
-% does not use the value of the key for anything.
+% the key.
 
 % First, some very simple keys that we shall need over and over again:
 
@@ -1870,22 +2459,22 @@
 
 \cs_generate_variant:Nn \tl_if_blank:nF { xF }
 
-\cs_new:Npn\semantex_primitive_valuekey_execute:nn#1#2
+\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}{##1}}
-	\cs_set:Npn\SemantexDataSet##1##2{\semantex_data_tl_set:nnn{#1}{##1}{##2}}
-	\cs_set:Npn\SemantexDataSetx##1##2{\semantex_data_tl_set:nnx{#1}{##1}{##2}}
-	\cs_set:Npn\SemantexDataPutRight##1##2{\semantex_data_tl_put_right:nnn{#1}{##1}{##2}}
-	\cs_set:Npn\SemantexDataPutRightx##1##2{\semantex_data_tl_put_right:nnx{#1}{##1}{##2}}
-	\cs_set:Npn\SemantexDataPutLeft##1##2{\semantex_data_tl_put_left:nnn{#1}{##1}{##2}}
-	\cs_set:Npn\SemantexDataPutLeftx##1##2{\semantex_data_tl_put_left:nnx{#1}{##1}{##2}}
-	\cs_set:Npn\SemantexDataGet##1{\semantex_data_tl_get:nn{#1}{##1}}
-	\cs_set:Npn\SemantexDataGetExpNot##1{\semantex_data_tl_get_exp_not:nn{#1}{##1}}
-	\cs_set:Npn\SemantexDataClear##1{\semantex_data_tl_clear:nn{#1}{##1}}
+	\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}}
@@ -1894,56 +2483,515 @@
 	\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}{##1}}
-	\cs_set:Npn\SemantexBoolSetTrue##1{\semantex_data_bool_set_true:nn{#1}{##1}}
-	\cs_set:Npn\SemantexBoolSetFalse##1{\semantex_data_bool_set_false:nn{#1}{##1}}
-	\cs_set:Npn\SemantexBoolIfTF##1##2##3{\semantex_data_bool_get:nnTF{#1}{##1}{##2}{##3}}
-	\cs_set:Npn\SemantexBoolIfT##1##2{\semantex_data_bool_get:nnTF{#1}{##1}{##2}{}}
-	\cs_set:Npn\SemantexBoolIfF##1##2{\semantex_data_bool_get:nnTF{#1}{##1}{}{##2}}
-	\cs_set:Npn\SemantexIntProvide##1{\semantex_data_int_provide:nn{#1}{##1}}
-	\cs_set:Npn\SemantexIntGet##1{\semantex_data_int_get:nn{#1}{##1}}
-	\cs_set:Npn\SemantexIntClear##1{\semantex_data_int_clear:nn{#1}{##1}}
-	\cs_set:Npn\SemantexIntIncr##1{\semantex_data_int_incr:nn{#1}{##1}}
-	\cs_set:Npn\SemantexIntSet##1##2{\semantex_data_int_set:nnn{#1}{##1}{##2}}
-	\cs_set:Npn\SemantexIntIfPositiveTF##1##2##3{\semantex_data_int_if_positive:nnTF{#1}{##1}{##2}{##3}}
-	\cs_set:Npn\SemantexIntIfPositiveT##1##2{\semantex_data_int_if_positive:nnT{#1}{##1}{##2}}
-	\cs_set:Npn\SemantexIntIfPositiveF##1##2{\semantex_data_int_if_positive:nnF{#1}{##1}{##2}}
-	\cs_set:Npn\SemantexIntIfGreaterThanOneTF##1##2##3{\semantex_data_int_if_greater_than_one:nnTF{#1}{##1}{##2}{##3}}
-	\cs_set:Npn\SemantexIntIfGreaterThanOneT##1##2{\semantex_data_int_if_greater_than_one:nnT{#1}{##1}{##2}}
-	\cs_set:Npn\SemantexIntIfGreaterThanOneF##1##2{\semantex_data_int_if_greater_than_one:nnF{#1}{##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_primitive_valuekey_parse:nn#1#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_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
 	}
-	\semantex_data_tl_clear:nn { #1 } { parseoptions } % this is probably necessary
 }
 
-\cs_new:Npn\semantex_primitive_valuekey_parseoptions:nn#1#2
+
+\cs_new:Npn\__semantex_parseoptions_process_singlekey:nnN#1#2#3
 {
-	% This adds keys to the parseoptions token list
-	\semantex_data_tl_put_right:nnn { #1 } { parseoptions } { #2 }
+	\tl_put_right:Nn#3
+	{
+		\semantex_singlekey:nn { #1 } { #2 }
+	}
 }
 
-\cs_new:Npn\semantex_primitive_valuekey_return: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_primitive_valuekey_innerreturn:nn { #1 }{}
-	\semantex_primitive_valuekey_rightreturn:nn { #1 }{}
-	\semantex_primitive_valuekey_leftreturn:nn { #1 }{}
+	\__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_primitive_valuekey_innerreturn:nn#1#2
+\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
@@ -1966,7 +3014,7 @@
 
 \cs_generate_variant:Nn \semantex_keys_set:nn { nx , no }
 
-\cs_new:Npn\semantex_primitive_valuekey_rightreturn:nn#1#2
+\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 }
@@ -1987,7 +3035,7 @@
 }
 
 
-\cs_new:Npn\semantex_primitive_valuekey_leftreturn:nn#1#2
+\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 }
@@ -2081,13 +3129,13 @@
 	\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__semantex_primitive_valuekey_rightreturn_parsize_temp
+	\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__semantex_primitive_valuekey_rightreturn_parsize_temp }
+			{ \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 } }
 			{
@@ -2107,7 +3155,7 @@
 			\semantex_data_int_if_greater_than_one:nnTF { #1 } { numberofarguments }
 			{
 				\__semantex_parentheses_store:nnnnN
-				{ \l__semantex_primitive_valuekey_rightreturn_parsize_temp }
+				{ \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 } }
 				{
@@ -2210,724 +3258,818 @@
 
 
 
-\cs_new:Npn\semantex_primitive_valuekey_parent:nn#1#2{
+\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_primitive_valuekey_class: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_new:Npn\semantex_primitive_valuekey_copy: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_primitive_valuekey_clone: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_primitive_valuekey_valuekeys:nn#1#2{
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_valuekeys:nn#1#2{
 	% Add new valuekeys
-	\semantex_data_prop_provide:nn { #1 } { custom_valuekeys }
 	\clist_map_inline:nn { #2 }{
-		\__semantex_valuekey_equality_format_auxiliary:nnn{#1}##1
+		\__semantex_valuekey_format_auxiliary:nnn{#1}##1
 	}
 }
 
-\cs_generate_variant:Nn\semantex_data_prop_put:nnnn {nnno}
+\cs_new:Npn\__semantex_process_singlekey:nnN#1#2#3
+{
+	\tl_put_right:Nn#3
+	{
+		\semantex_singlekey:nn { #1 } { #2 }
+	}
+}
 
-\cs_new:Npn\__semantex_valuekey_equality_format_auxiliary:nnn#1#2#3
+\cs_generate_variant:Nn \semantex_valuekey:nnn { nnx }
+
+\cs_new:Npn\__semantex_process_valuekey:nnnN#1#2#3#4
 {
-	\cs_set:Npn\l__semantex_valuekey_equality_format_auxiliary_temp:n##1{#3}
-	\semantex_data_prop_put:nnno {#1} {custom_valuekeys} {#2}
+	\tl_if_eq:nnTF { #2 } { execute }
 	{
-		\l__semantex_valuekey_equality_format_auxiliary_temp:n
+		\tl_put_right:Nn#4
 		{
-			\l__semantex_key_value_temp
+			#3
 		}
 	}
-	%IM Remove spaces in #2
+	{
+		\tl_put_right:Nn#4
+		{
+			\semantex_valuekey:nnn { #1 } { #2 } { #3 }
+		}	
+	}
 }
 
-\cs_new:Npn\semantex_primitive_valuekey_removevaluekey:nn#1#2
+\cs_new:Npn\__semantex_valuekey_format_auxiliary:nnn#1#2#3
 {
-	\semantex_valuekey_remove:nn { #1 } { #2 }
+	\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_set_eq:cN { semantex_primitive_valuekey_1valuekeys:nn } \semantex_primitive_valuekey_valuekeys:nn
+\cs_generate_variant:Nn \cs_set:Npn { cpo }
 
-\cs_new:cpn { semantex_primitive_valuekey_2valuekeys:nn }#1#2{
+\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
-	\semantex_data_prop_provide:nn { #1 } { custom_valuekeys }
 	\clist_map_inline:nn { #2 }{
-		\__semantex_two_valuekey_equality_format_auxiliary:nnn{#1}##1
+		\__semantex_two_valuekey_format_auxiliary:nnn{#1}##1
 	}
 }
 
-\cs_new:Npn\__semantex_two_valuekey_equality_format_auxiliary:nnn#1#2#3
+\cs_new:Npn\__semantex_two_valuekey_format_auxiliary:nnn#1#2#3
 {
-	\cs_set:Npn\l__semantex_two_valuekey_equality_format_auxiliary_temp:nn##1##2{#3}
-	\semantex_data_prop_put:nnno {#1} {custom_valuekeys} {#2}
+	\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_equality_format_auxiliary_temp:nn
+		\l__semantex_two_valuekey_format_auxiliary_temp:nn
 		{
-			\exp_not:N\semantex_grab_first_argument_of_two:nn\l__semantex_key_value_temp
+			\semantex_grab_first_argument_of_two:nn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_second_argument_of_two:nn\l__semantex_key_value_temp
+			\semantex_grab_second_argument_of_two:nn ##1
 		}
 	}
-	%IM Remove spaces in #2
 }
+\cs_generate_variant:Nn \__semantex_valuekey_format_auxiliary:nnn { nno }
 
-\cs_new:cpn { semantex_primitive_valuekey_3valuekeys:nn }#1#2{
+\cs_new:cpn { __semantex_data_cs_custom_valuekey_class_SemantexBaseObject_3valuekeys:nn }#1#2{
 	% Add new valuekeys
-	\semantex_data_prop_provide:nn { #1 } { custom_valuekeys }
 	\clist_map_inline:nn { #2 }{
-		\__semantex_three_valuekey_equality_format_auxiliary:nnn{#1}##1
+		\__semantex_three_valuekey_format_auxiliary:nnn{#1}##1
 	}
 }
 
-\cs_new:Npn\__semantex_three_valuekey_equality_format_auxiliary:nnn#1#2#3
+\cs_new:Npn\__semantex_three_valuekey_format_auxiliary:nnn#1#2#3
 {
-	\cs_set:Npn\l__semantex_three_valuekey_equality_format_auxiliary_temp:nnn##1##2##3{#3}
-	\semantex_data_prop_put:nnno {#1} {custom_valuekeys} {#2}
+	\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_equality_format_auxiliary_temp:nnn
+		\l__semantex_three_valuekey_format_auxiliary_temp:nnn
 		{
-			\exp_not:N\semantex_grab_first_argument_of_three:nnn\l__semantex_key_value_temp
+			\semantex_grab_first_argument_of_three:nnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_second_argument_of_three:nnn\l__semantex_key_value_temp
+			\semantex_grab_second_argument_of_three:nnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_third_argument_of_three:nnn\l__semantex_key_value_temp
+			\semantex_grab_third_argument_of_three:nnn ##1
 		}
 	}
 	%IM Remove spaces in #2
 }
 
-\cs_new:cpn { semantex_primitive_valuekey_4valuekeys:nn }#1#2{
+\cs_new:cpn { __semantex_data_cs_custom_valuekey_class_SemantexBaseObject_4valuekeys:nn }#1#2{
 	% Add new valuekeys
-	\semantex_data_prop_provide:nn { #1 } { custom_valuekeys }
 	\clist_map_inline:nn { #2 }{
-		\__semantex_four_valuekey_equality_format_auxiliary:nnn{#1}##1
+		\__semantex_four_valuekey_format_auxiliary:nnn{#1}##1
 	}
 }
 
-\cs_new:Npn\__semantex_four_valuekey_equality_format_auxiliary:nnn#1#2#3
+\cs_new:Npn\__semantex_four_valuekey_format_auxiliary:nnn#1#2#3
 {
-	\cs_set:Npn\l__semantex_four_valuekey_equality_format_auxiliary_temp:nnnn##1##2##3##4{#3}
-	\semantex_data_prop_put:nnno {#1} {custom_valuekeys} {#2}
+	\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_equality_format_auxiliary_temp:nnnn
+		\l__semantex_four_valuekey_format_auxiliary_temp:nnnn
 		{
-			\exp_not:N\semantex_grab_first_argument_of_four:nnnn\l__semantex_key_value_temp
+			\semantex_grab_first_argument_of_four:nnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_second_argument_of_four:nnnn\l__semantex_key_value_temp
+			\semantex_grab_second_argument_of_four:nnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_third_argument_of_four:nnnn\l__semantex_key_value_temp
+			\semantex_grab_third_argument_of_four:nnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_fourth_argument_of_four:nnnn\l__semantex_key_value_temp
+			\semantex_grab_fourth_argument_of_four:nnnn ##1
 		}
 	}
 	%IM Remove spaces in #2
 }
 
-\cs_new:cpn { semantex_primitive_valuekey_5valuekeys:nn }#1#2{
+\cs_new:cpn { __semantex_data_cs_custom_valuekey_class_SemantexBaseObject_5valuekeys:nn }#1#2{
 	% Add new valuekeys
-	\semantex_data_prop_provide:nn { #1 } { custom_valuekeys }
 	\clist_map_inline:nn { #2 }{
-		\__semantex_five_valuekey_equality_format_auxiliary:nnn{#1}##1
+		\__semantex_five_valuekey_format_auxiliary:nnn{#1}##1
 	}
 }
 
-\cs_new:Npn\__semantex_five_valuekey_equality_format_auxiliary:nnn#1#2#3
+\cs_new:Npn\__semantex_five_valuekey_format_auxiliary:nnn#1#2#3
 {
-	\cs_set:Npn\l__semantex_five_valuekey_equality_format_auxiliary_temp:nnnnn##1##2##3##4##5{#3}
-	\semantex_data_prop_put:nnno {#1} {custom_valuekeys} {#2}
+	\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_equality_format_auxiliary_temp:nnnnn
+		\l__semantex_five_valuekey_format_auxiliary_temp:nnnnn
 		{
-			\exp_not:N\semantex_grab_first_argument_of_five:nnnnn\l__semantex_key_value_temp
+			\semantex_grab_first_argument_of_five:nnnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_second_argument_of_five:nnnnn\l__semantex_key_value_temp
+			\semantex_grab_second_argument_of_five:nnnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_third_argument_of_five:nnnnn\l__semantex_key_value_temp
+			\semantex_grab_third_argument_of_five:nnnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_fourth_argument_of_five:nnnnn\l__semantex_key_value_temp
+			\semantex_grab_fourth_argument_of_five:nnnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_fifth_argument_of_five:nnnnn\l__semantex_key_value_temp
+			\semantex_grab_fifth_argument_of_five:nnnnn ##1
 		}
 	}
 	%IM Remove spaces in #2
 }
 
-\cs_new:cpn { semantex_primitive_valuekey_6valuekeys:nn }#1#2{
+\cs_new:cpn { __semantex_data_cs_custom_valuekey_class_SemantexBaseObject_6valuekeys:nn }#1#2{
 	% Add new valuekeys
-	\semantex_data_prop_provide:nn { #1 } { custom_valuekeys }
 	\clist_map_inline:nn { #2 }{
-		\__semantex_six_valuekey_equality_format_auxiliary:nnn{#1}##1
+		\__semantex_six_valuekey_format_auxiliary:nnn{#1}##1
 	}
 }
 
-\cs_new:Npn\__semantex_six_valuekey_equality_format_auxiliary:nnn#1#2#3
+\cs_new:Npn\__semantex_six_valuekey_format_auxiliary:nnn#1#2#3
 {
-	\cs_set:Npn\l__semantex_six_valuekey_equality_format_auxiliary_temp:nnnnnn##1##2##3##4##5##6{#3}
-	\semantex_data_prop_put:nnno {#1} {custom_valuekeys} {#2}
+	\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_equality_format_auxiliary_temp:nnnnnn
+		\l__semantex_six_valuekey_format_auxiliary_temp:nnnnnn
 		{
-			\exp_not:N\semantex_grab_first_argument_of_six:nnnnnn\l__semantex_key_value_temp
+			\semantex_grab_first_argument_of_six:nnnnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_second_argument_of_six:nnnnnn\l__semantex_key_value_temp
+			\semantex_grab_second_argument_of_six:nnnnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_third_argument_of_six:nnnnnn\l__semantex_key_value_temp
+			\semantex_grab_third_argument_of_six:nnnnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_fourth_argument_of_six:nnnnnn\l__semantex_key_value_temp
+			\semantex_grab_fourth_argument_of_six:nnnnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_fifth_argument_of_six:nnnnnn\l__semantex_key_value_temp
+			\semantex_grab_fifth_argument_of_six:nnnnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_sixth_argument_of_six:nnnnnn\l__semantex_key_value_temp
+			\semantex_grab_sixth_argument_of_six:nnnnnn ##1
 		}
 	}
 	%IM Remove spaces in #2
 }
 
-\cs_new:cpn { semantex_primitive_valuekey_7valuekeys:nn }#1#2{
+\cs_new:cpn { __semantex_data_cs_custom_valuekey_class_SemantexBaseObject_7valuekeys:nn }#1#2{
 	% Add new valuekeys
-	\semantex_data_prop_provide:nn { #1 } { custom_valuekeys }
 	\clist_map_inline:nn { #2 }{
-		\__semantex_seven_valuekey_equality_format_auxiliary:nnn{#1}##1
+		\__semantex_seven_valuekey_format_auxiliary:nnn{#1}##1
 	}
 }
 
-\cs_new:Npn\__semantex_seven_valuekey_equality_format_auxiliary:nnn#1#2#3
+\cs_new:Npn\__semantex_seven_valuekey_format_auxiliary:nnn#1#2#3
 {
-	\cs_set:Npn\l__semantex_seven_valuekey_equality_format_auxiliary_temp:nnnnnnn##1##2##3##4##5##6##7{#3}
-	\semantex_data_prop_put:nnno {#1} {custom_valuekeys} {#2}
+	\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_equality_format_auxiliary_temp:nnnnnnn
+		\l__semantex_seven_valuekey_format_auxiliary_temp:nnnnnnn
 		{
-			\exp_not:N\semantex_grab_first_argument_of_seven:nnnnnnn\l__semantex_key_value_temp
+			\semantex_grab_first_argument_of_seven:nnnnnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_second_argument_of_seven:nnnnnnn\l__semantex_key_value_temp
+			\semantex_grab_second_argument_of_seven:nnnnnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_third_argument_of_seven:nnnnnnn\l__semantex_key_value_temp
+			\semantex_grab_third_argument_of_seven:nnnnnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_fourth_argument_of_seven:nnnnnnn\l__semantex_key_value_temp
+			\semantex_grab_fourth_argument_of_seven:nnnnnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_fifth_argument_of_seven:nnnnnnn\l__semantex_key_value_temp
+			\semantex_grab_fifth_argument_of_seven:nnnnnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_sixth_argument_of_seven:nnnnnnn\l__semantex_key_value_temp
+			\semantex_grab_sixth_argument_of_seven:nnnnnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_seventh_argument_of_seven:nnnnnnn\l__semantex_key_value_temp
+			\semantex_grab_seventh_argument_of_seven:nnnnnnn ##1
 		}
 	}
 	%IM Remove spaces in #2
 }
 
-\cs_new:cpn { semantex_primitive_valuekey_8valuekeys:nn }#1#2{
+\cs_new:cpn { __semantex_data_cs_custom_valuekey_class_SemantexBaseObject_8valuekeys:nn }#1#2{
 	% Add new valuekeys
-	\semantex_data_prop_provide:nn { #1 } { custom_valuekeys }
 	\clist_map_inline:nn { #2 }{
-		\__semantex_eight_valuekey_equality_format_auxiliary:nnn{#1}##1
+		\__semantex_eight_valuekey_format_auxiliary:nnn{#1}##1
 	}
 }
 
-\cs_new:Npn\__semantex_eight_valuekey_equality_format_auxiliary:nnn#1#2#3
+\cs_new:Npn\__semantex_eight_valuekey_format_auxiliary:nnn#1#2#3
 {
-	\cs_set:Npn\l__semantex_eight_valuekey_equality_format_auxiliary_temp:nnnnnnnn##1##2##3##4##5##6##7##8{#3}
-	\semantex_data_prop_put:nnno {#1} {custom_valuekeys} {#2}
+	\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_equality_format_auxiliary_temp:nnnnnnnn
+		\l__semantex_eight_valuekey_format_auxiliary_temp:nnnnnnnn
 		{
-			\exp_not:N\semantex_grab_first_argument_of_eight:nnnnnnnn\l__semantex_key_value_temp
+			\semantex_grab_first_argument_of_eight:nnnnnnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_second_argument_of_eight:nnnnnnnn\l__semantex_key_value_temp
+			\semantex_grab_second_argument_of_eight:nnnnnnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_third_argument_of_eight:nnnnnnnn\l__semantex_key_value_temp
+			\semantex_grab_third_argument_of_eight:nnnnnnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_fourth_argument_of_eight:nnnnnnnn\l__semantex_key_value_temp
+			\semantex_grab_fourth_argument_of_eight:nnnnnnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_fifth_argument_of_eight:nnnnnnnn\l__semantex_key_value_temp
+			\semantex_grab_fifth_argument_of_eight:nnnnnnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_sixth_argument_of_eight:nnnnnnnn\l__semantex_key_value_temp
+			\semantex_grab_sixth_argument_of_eight:nnnnnnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_seventh_argument_of_eight:nnnnnnnn\l__semantex_key_value_temp
+			\semantex_grab_seventh_argument_of_eight:nnnnnnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_eighth_argument_of_eight:nnnnnnnn\l__semantex_key_value_temp
+			\semantex_grab_eighth_argument_of_eight:nnnnnnnn ##1
 		}
 	}
 	%IM Remove spaces in #2
 }
 
-\cs_new:cpn { semantex_primitive_valuekey_9valuekeys:nn }#1#2{
+\cs_new:cpn { __semantex_data_cs_custom_valuekey_class_SemantexBaseObject_9valuekeys:nn }#1#2{
 	% Add new valuekeys
-	\semantex_data_prop_provide:nn { #1 } { custom_valuekeys }
 	\clist_map_inline:nn { #2 }{
-		\__semantex_nine_valuekey_equality_format_auxiliary:nnn{#1}##1
+		\__semantex_nine_valuekey_format_auxiliary:nnn{#1}##1
 	}
 }
 
-\cs_new:Npn\__semantex_nine_valuekey_equality_format_auxiliary:nnn#1#2#3
+\cs_new:Npn\__semantex_nine_valuekey_format_auxiliary:nnn#1#2#3
 {
-	\cs_set:Npn\l__semantex_nine_valuekey_equality_format_auxiliary_temp:nnnnnnnnn##1##2##3##4##5##6##7##8##9{#3}
-	\semantex_data_prop_put:nnno {#1} {custom_valuekeys} {#2}
+	\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_equality_format_auxiliary_temp:nnnnnnnnn
+		\l__semantex_nine_valuekey_format_auxiliary_temp:nnnnnnnnn
 		{
-			\exp_not:N\semantex_grab_first_argument_of_nine:nnnnnnnnn\l__semantex_key_value_temp
+			\semantex_grab_first_argument_of_nine:nnnnnnnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_second_argument_of_nine:nnnnnnnnn\l__semantex_key_value_temp
+			\semantex_grab_second_argument_of_nine:nnnnnnnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_third_argument_of_nine:nnnnnnnnn\l__semantex_key_value_temp
+			\semantex_grab_third_argument_of_nine:nnnnnnnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_fourth_argument_of_nine:nnnnnnnnn\l__semantex_key_value_temp
+			\semantex_grab_fourth_argument_of_nine:nnnnnnnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_fifth_argument_of_nine:nnnnnnnnn\l__semantex_key_value_temp
+			\semantex_grab_fifth_argument_of_nine:nnnnnnnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_sixth_argument_of_nine:nnnnnnnnn\l__semantex_key_value_temp
+			\semantex_grab_sixth_argument_of_nine:nnnnnnnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_seventh_argument_of_nine:nnnnnnnnn\l__semantex_key_value_temp
+			\semantex_grab_seventh_argument_of_nine:nnnnnnnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_eighth_argument_of_nine:nnnnnnnnn\l__semantex_key_value_temp
+			\semantex_grab_eighth_argument_of_nine:nnnnnnnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_ninth_argument_of_nine:nnnnnnnnn\l__semantex_key_value_temp
+			\semantex_grab_ninth_argument_of_nine:nnnnnnnnn ##1
 		}
 	}
 	%IM Remove spaces in #2
 }
 
-\cs_new:Npn\semantex_primitive_valuekey_singlekeys:nn#1#2{
-	% Add keys taking no values
-	\semantex_data_prop_provide:nn { #1 } { custom_singlekeys }
-	\clist_map_inline:nn { #2 }{
-		\__semantex_singlekeys_noequality_format_auxiliary:nnn{#1}##1
-	}
-}
+\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_new:Npn \__semantex_singlekeys_noequality_format_auxiliary:nnn#1#2#3{
-	\semantex_data_prop_put:nnnn {#1} {custom_singlekeys} {#2} {#3}
-}
+\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_primitive_valuekey_novaluekeys:nn\semantex_primitive_valuekey_singlekeys:nn % Previously, "singlekeys" was called "novaluekeys", so I am keeping this alias for backwards compatibility
 
-\cs_set_eq:cN { semantex_primitive_valuekey_0valuekeys:nn } \semantex_primitive_valuekey_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_new:Npn\semantex_primitive_valuekey_removesinglekey:nn#1#2
+\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
 {
-	\semantex_singlekey_remove:nn { #1 } { #2 }
+	\tl_put_right:Nn#3
+	{
+		\semantex_arg_singlekey:nn { #1 } { #2 }
+	}
 }
 
-\cs_set_eq:NN\semantex_primitive_valuekey_removenovaluekey:nn\semantex_primitive_valuekey_removesinglekey:nn % Previously, "singlekeys" was called "novaluekeys", so I am keeping this alias for backwards compatibility
+\cs_generate_variant:Nn \semantex_valuekey:nnn { nnx }
 
-\cs_set_eq:cN { semantex_primitive_valuekey_remove0valuekey:nn } \semantex_primitive_valuekey_removesinglekey:nn
+\cs_new:Npn\__semantex_process_arg_valuekey:nnnN#1#2#3#4
+{
+	\tl_put_right:Nn#4
+	{
+		\semantex_arg_valuekey:nnn { #1 } { #2 } { #3 }
+	}	
+}
 
-% KEYS FOR SETTING UP THE ARGUMENT KEYVAL INTERFACE:
-
-\cs_new:Npn\semantex_primitive_valuekey_argvaluekeys:nn#1#2{
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_argvaluekeys:nn#1#2{
 	% Add argument valuekeys
-	\semantex_data_prop_provide:nn { #1 } { custom_arg_valuekeys }
 	\clist_map_inline:nn { #2 }{
-		\__semantex_arg_valuekey_equality_format_auxiliary:nnn{#1}##1
+		\__semantex_arg_valuekey_format_auxiliary:nnn{#1}##1
 	}
 }
 
-\cs_new:Npn \__semantex_arg_valuekey_equality_format_auxiliary:nnn#1#2#3
+\cs_new:Npn \__semantex_arg_valuekey_format_auxiliary:nnn#1#2#3
 {
-	\cs_set:Npn\l__semantex_arg_valuekey_equality_format_auxiliary_temp:n##1{#3}
-	\semantex_data_prop_put:nnno {#1} {custom_arg_valuekeys} {#2}
+	\tl_set:Nn\l__semantex_arg_valuekey_auxiliary_temp_tl{}
+	\cs_set:Npn\l__semantex_arg_valuekey_auxiliary_singlekey_temp_cs:n##1
 	{
-		\l__semantex_arg_valuekey_equality_format_auxiliary_temp:n{
-			\l__semantex_arg_key_value_temp
+		\__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_primitive_valuekey_removeargvaluekey:nn#1#2
+\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
 {
-	\semantex_arg_valuekey_remove:nn { #1 } { #2 }
+	\cs_undefine:c { __semantex_data_cs_custom_arg_singlekey_#1_#2:n }
 }
 
-\cs_set_eq:cN { semantex_primitive_valuekey_arg1valuekeys:nn } \semantex_primitive_arg_valuekey_arg_valuekeys:nn
+\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_new:cpn { semantex_primitive_valuekey_arg2valuekeys:nn }#1#2{
+\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
-	\semantex_data_prop_provide:nn { #1 } { custom_arg_valuekeys }
 	\clist_map_inline:nn { #2 }{
-		\__semantex_two_arg_valuekey_equality_format_auxiliary:nnn{#1}##1
+		\__semantex_two_arg_valuekey_format_auxiliary:nnn{#1}##1
 	}
 }
 
-\cs_new:Npn\__semantex_two_arg_valuekey_equality_format_auxiliary:nnn#1#2#3
+\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_equality_format_auxiliary_temp:nn##1##2{#3}
-	\semantex_data_prop_put:nnno {#1} {custom_arg_valuekeys} {#2}
+	\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_equality_format_auxiliary_temp:nn
+		\l__semantex_two_arg_valuekey_format_auxiliary_temp:nn
 		{
-			\exp_not:N\semantex_grab_first_argument_of_two:nn\l__semantex_arg_key_value_temp
+			\semantex_grab_first_argument_of_two:nn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_second_argument_of_two:nn\l__semantex_arg_key_value_temp
+			\semantex_grab_second_argument_of_two:nn ##1
 		}
 	}
 	%IM Remove spaces in #2
 }
 
-\cs_new:cpn { semantex_primitive_valuekey_arg3valuekeys:nn }#1#2{
+\cs_new:cpn { __semantex_data_cs_custom_valuekey_class_SemantexBaseObject_arg3valuekeys:nn }#1#2{
 	% Add new valuekeys
-	\semantex_data_prop_provide:nn { #1 } { custom_arg_valuekeys }
 	\clist_map_inline:nn { #2 }{
-		\__semantex_three_arg_valuekey_equality_format_auxiliary:nnn{#1}##1
+		\__semantex_three_arg_valuekey_format_auxiliary:nnn{#1}##1
 	}
 }
 
-\cs_new:Npn\__semantex_three_arg_valuekey_equality_format_auxiliary:nnn#1#2#3
+\cs_new:Npn\__semantex_three_arg_valuekey_format_auxiliary:nnn#1#2#3
 {
-	\cs_set:Npn\l__semantex_three_arg_valuekey_equality_format_auxiliary_temp:nnn##1##2##3{#3}
-	\semantex_data_prop_put:nnno {#1} {custom_arg_valuekeys} {#2}
+	\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_equality_format_auxiliary_temp:nnn
+		\l__semantex_three_arg_valuekey_format_auxiliary_temp:nnn
 		{
-			\exp_not:N\semantex_grab_first_argument_of_three:nnn\l__semantex_arg_key_value_temp
+			\semantex_grab_first_argument_of_three:nnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_second_argument_of_three:nnn\l__semantex_arg_key_value_temp
+			\semantex_grab_second_argument_of_three:nnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_third_argument_of_three:nnn\l__semantex_arg_key_value_temp
+			\semantex_grab_third_argument_of_three:nnn ##1
 		}
 	}
 	%IM Remove spaces in #2
 }
 
-\cs_new:cpn { semantex_primitive_valuekey_arg4valuekeys:nn }#1#2{
+\cs_new:cpn { __semantex_data_cs_custom_valuekey_class_SemantexBaseObject_arg4valuekeys:nn }#1#2{
 	% Add new valuekeys
-	\semantex_data_prop_provide:nn { #1 } { custom_arg_valuekeys }
 	\clist_map_inline:nn { #2 }{
-		\__semantex_four_arg_valuekey_equality_format_auxiliary:nnn{#1}##1
+		\__semantex_four_arg_valuekey_format_auxiliary:nnn{#1}##1
 	}
 }
 
-\cs_new:Npn\__semantex_four_arg_valuekey_equality_format_auxiliary:nnn#1#2#3
+\cs_new:Npn\__semantex_four_arg_valuekey_format_auxiliary:nnn#1#2#3
 {
-	\cs_set:Npn\l__semantex_four_arg_valuekey_equality_format_auxiliary_temp:nnnn##1##2##3##4{#3}
-	\semantex_data_prop_put:nnno {#1} {custom_arg_valuekeys} {#2}
+	\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_equality_format_auxiliary_temp:nnnn
+		\l__semantex_four_arg_valuekey_format_auxiliary_temp:nnnn
 		{
-			\exp_not:N\semantex_grab_first_argument_of_four:nnnn\l__semantex_arg_key_value_temp
+			\semantex_grab_first_argument_of_four:nnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_second_argument_of_four:nnnn\l__semantex_arg_key_value_temp
+			\semantex_grab_second_argument_of_four:nnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_third_argument_of_four:nnnn\l__semantex_arg_key_value_temp
+			\semantex_grab_third_argument_of_four:nnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_fourth_argument_of_four:nnnn\l__semantex_arg_key_value_temp
+			\semantex_grab_fourth_argument_of_four:nnnn ##1
 		}
 	}
 	%IM Remove spaces in #2
 }
 
-\cs_new:cpn { semantex_primitive_valuekey_arg5valuekeys:nn }#1#2{
+\cs_new:cpn { __semantex_data_cs_custom_valuekey_class_SemantexBaseObject_arg5valuekeys:nn }#1#2{
 	% Add new valuekeys
-	\semantex_data_prop_provide:nn { #1 } { custom_arg_valuekeys }
 	\clist_map_inline:nn { #2 }{
-		\__semantex_five_arg_valuekey_equality_format_auxiliary:nnn{#1}##1
+		\__semantex_five_arg_valuekey_format_auxiliary:nnn{#1}##1
 	}
 }
 
-\cs_new:Npn\__semantex_five_arg_valuekey_equality_format_auxiliary:nnn#1#2#3
+\cs_new:Npn\__semantex_five_arg_valuekey_format_auxiliary:nnn#1#2#3
 {
-	\cs_set:Npn\l__semantex_five_arg_valuekey_equality_format_auxiliary_temp:nnnnn##1##2##3##4##5{#3}
-	\semantex_data_prop_put:nnno {#1} {custom_arg_valuekeys} {#2}
+	\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_equality_format_auxiliary_temp:nnnnn
+		\l__semantex_five_arg_valuekey_format_auxiliary_temp:nnnnn
 		{
-			\exp_not:N\semantex_grab_first_argument_of_five:nnnnn\l__semantex_arg_key_value_temp
+			\semantex_grab_first_argument_of_five:nnnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_second_argument_of_five:nnnnn\l__semantex_arg_key_value_temp
+			\semantex_grab_second_argument_of_five:nnnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_third_argument_of_five:nnnnn\l__semantex_arg_key_value_temp
+			\semantex_grab_third_argument_of_five:nnnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_fourth_argument_of_five:nnnnn\l__semantex_arg_key_value_temp
+			\semantex_grab_fourth_argument_of_five:nnnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_fifth_argument_of_five:nnnnn\l__semantex_arg_key_value_temp
+			\semantex_grab_fifth_argument_of_five:nnnnn ##1
 		}
 	}
 	%IM Remove spaces in #2
 }
 
-\cs_new:cpn { semantex_primitive_valuekey_arg6valuekeys:nn }#1#2{
+\cs_new:cpn { __semantex_data_cs_custom_valuekey_class_SemantexBaseObject_arg6valuekeys:nn }#1#2{
 	% Add new valuekeys
-	\semantex_data_prop_provide:nn { #1 } { custom_arg_valuekeys }
 	\clist_map_inline:nn { #2 }{
-		\__semantex_six_arg_valuekey_equality_format_auxiliary:nnn{#1}##1
+		\__semantex_six_arg_valuekey_format_auxiliary:nnn{#1}##1
 	}
 }
 
-\cs_new:Npn\__semantex_six_arg_valuekey_equality_format_auxiliary:nnn#1#2#3
+\cs_new:Npn\__semantex_six_arg_valuekey_format_auxiliary:nnn#1#2#3
 {
-	\cs_set:Npn\l__semantex_six_arg_valuekey_equality_format_auxiliary_temp:nnnnnn##1##2##3##4##5##6{#3}
-	\semantex_data_prop_put:nnno {#1} {custom_arg_valuekeys} {#2}
+	\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_equality_format_auxiliary_temp:nnnnnn
+		\l__semantex_six_arg_valuekey_format_auxiliary_temp:nnnnnn
 		{
-			\exp_not:N\semantex_grab_first_argument_of_six:nnnnnn\l__semantex_arg_key_value_temp
+			\semantex_grab_first_argument_of_six:nnnnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_second_argument_of_six:nnnnnn\l__semantex_arg_key_value_temp
+			\semantex_grab_second_argument_of_six:nnnnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_third_argument_of_six:nnnnnn\l__semantex_arg_key_value_temp
+			\semantex_grab_third_argument_of_six:nnnnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_fourth_argument_of_six:nnnnnn\l__semantex_arg_key_value_temp
+			\semantex_grab_fourth_argument_of_six:nnnnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_fifth_argument_of_six:nnnnnn\l__semantex_arg_key_value_temp
+			\semantex_grab_fifth_argument_of_six:nnnnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_sixth_argument_of_six:nnnnnn\l__semantex_arg_key_value_temp
+			\semantex_grab_sixth_argument_of_six:nnnnnn ##1
 		}
 	}
 	%IM Remove spaces in #2
 }
 
-\cs_new:cpn { semantex_primitive_valuekey_arg7valuekeys:nn }#1#2{
+\cs_new:cpn { __semantex_data_cs_custom_valuekey_class_SemantexBaseObject_arg7valuekeys:nn }#1#2{
 	% Add new valuekeys
-	\semantex_data_prop_provide:nn { #1 } { custom_arg_valuekeys }
 	\clist_map_inline:nn { #2 }{
-		\__semantex_seven_arg_valuekey_equality_format_auxiliary:nnn{#1}##1
+		\__semantex_seven_arg_valuekey_format_auxiliary:nnn{#1}##1
 	}
 }
 
-\cs_new:Npn\__semantex_seven_arg_valuekey_equality_format_auxiliary:nnn#1#2#3
+\cs_new:Npn\__semantex_seven_arg_valuekey_format_auxiliary:nnn#1#2#3
 {
-	\cs_set:Npn\l__semantex_seven_arg_valuekey_equality_format_auxiliary_temp:nnnnnnn##1##2##3##4##5##6##7{#3}
-	\semantex_data_prop_put:nnno {#1} {custom_arg_valuekeys} {#2}
+	\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_equality_format_auxiliary_temp:nnnnnnn
+		\l__semantex_seven_arg_valuekey_format_auxiliary_temp:nnnnnnn
 		{
-			\exp_not:N\semantex_grab_first_argument_of_seven:nnnnnnn\l__semantex_arg_key_value_temp
+			\semantex_grab_first_argument_of_seven:nnnnnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_second_argument_of_seven:nnnnnnn\l__semantex_arg_key_value_temp
+			\semantex_grab_second_argument_of_seven:nnnnnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_third_argument_of_seven:nnnnnnn\l__semantex_arg_key_value_temp
+			\semantex_grab_third_argument_of_seven:nnnnnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_fourth_argument_of_seven:nnnnnnn\l__semantex_arg_key_value_temp
+			\semantex_grab_fourth_argument_of_seven:nnnnnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_fifth_argument_of_seven:nnnnnnn\l__semantex_arg_key_value_temp
+			\semantex_grab_fifth_argument_of_seven:nnnnnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_sixth_argument_of_seven:nnnnnnn\l__semantex_arg_key_value_temp
+			\semantex_grab_sixth_argument_of_seven:nnnnnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_seventh_argument_of_seven:nnnnnnn\l__semantex_arg_key_value_temp
+			\semantex_grab_seventh_argument_of_seven:nnnnnnn ##1
 		}
 	}
 	%IM Remove spaces in #2
 }
 
-\cs_new:cpn { semantex_primitive_valuekey_arg8valuekeys:nn }#1#2{
+\cs_new:cpn { __semantex_data_cs_custom_valuekey_class_SemantexBaseObject_arg8valuekeys:nn }#1#2{
 	% Add new valuekeys
-	\semantex_data_prop_provide:nn { #1 } { custom_arg_valuekeys }
 	\clist_map_inline:nn { #2 }{
-		\__semantex_eight_arg_valuekey_equality_format_auxiliary:nnn{#1}##1
+		\__semantex_eight_arg_valuekey_format_auxiliary:nnn{#1}##1
 	}
 }
 
-\cs_new:Npn\__semantex_eight_arg_valuekey_equality_format_auxiliary:nnn#1#2#3
+\cs_new:Npn\__semantex_eight_arg_valuekey_format_auxiliary:nnn#1#2#3
 {
-	\cs_set:Npn\l__semantex_eight_arg_valuekey_equality_format_auxiliary_temp:nnnnnnnn##1##2##3##4##5##6##7##8{#3}
-	\semantex_data_prop_put:nnno {#1} {custom_arg_valuekeys} {#2}
+	\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_equality_format_auxiliary_temp:nnnnnnnn
+		\l__semantex_eight_arg_valuekey_format_auxiliary_temp:nnnnnnnn
 		{
-			\exp_not:N\semantex_grab_first_argument_of_eight:nnnnnnnn\l__semantex_arg_key_value_temp
+			\semantex_grab_first_argument_of_eight:nnnnnnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_second_argument_of_eight:nnnnnnnn\l__semantex_arg_key_value_temp
+			\semantex_grab_second_argument_of_eight:nnnnnnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_third_argument_of_eight:nnnnnnnn\l__semantex_arg_key_value_temp
+			\semantex_grab_third_argument_of_eight:nnnnnnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_fourth_argument_of_eight:nnnnnnnn\l__semantex_arg_key_value_temp
+			\semantex_grab_fourth_argument_of_eight:nnnnnnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_fifth_argument_of_eight:nnnnnnnn\l__semantex_arg_key_value_temp
+			\semantex_grab_fifth_argument_of_eight:nnnnnnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_sixth_argument_of_eight:nnnnnnnn\l__semantex_arg_key_value_temp
+			\semantex_grab_sixth_argument_of_eight:nnnnnnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_seventh_argument_of_eight:nnnnnnnn\l__semantex_arg_key_value_temp
+			\semantex_grab_seventh_argument_of_eight:nnnnnnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_eighth_argument_of_eight:nnnnnnnn\l__semantex_arg_key_value_temp
+			\semantex_grab_eighth_argument_of_eight:nnnnnnnn ##1
 		}
 	}
 	%IM Remove spaces in #2
 }
 
-\cs_new:cpn { semantex_primitive_valuekey_arg9valuekeys:nn }#1#2{
+\cs_new:cpn { __semantex_data_cs_custom_valuekey_class_SemantexBaseObject_arg9valuekeys:nn }#1#2{
 	% Add new valuekeys
-	\semantex_data_prop_provide:nn { #1 } { custom_arg_valuekeys }
 	\clist_map_inline:nn { #2 }{
-		\__semantex_nine_arg_valuekey_equality_format_auxiliary:nnn{#1}##1
+		\__semantex_nine_arg_valuekey_format_auxiliary:nnn{#1}##1
 	}
 }
 
-\cs_new:Npn\__semantex_nine_arg_valuekey_equality_format_auxiliary:nnn#1#2#3
+\cs_new:Npn\__semantex_nine_arg_valuekey_format_auxiliary:nnn#1#2#3
 {
-	\cs_set:Npn\l__semantex_nine_arg_valuekey_equality_format_auxiliary_temp:nnnnnnnnn##1##2##3##4##5##6##7##8##9{#3}
-	\semantex_data_prop_put:nnno {#1} {custom_arg_valuekeys} {#2}
+	\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_equality_format_auxiliary_temp:nnnnnnnnn
+		\l__semantex_nine_arg_valuekey_format_auxiliary_temp:nnnnnnnnn
 		{
-			\exp_not:N\semantex_grab_first_argument_of_nine:nnnnnnnnn\l__semantex_arg_key_value_temp
+			\semantex_grab_first_argument_of_nine:nnnnnnnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_second_argument_of_nine:nnnnnnnnn\l__semantex_arg_key_value_temp
+			\semantex_grab_second_argument_of_nine:nnnnnnnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_third_argument_of_nine:nnnnnnnnn\l__semantex_arg_key_value_temp
+			\semantex_grab_third_argument_of_nine:nnnnnnnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_fourth_argument_of_nine:nnnnnnnnn\l__semantex_arg_key_value_temp
+			\semantex_grab_fourth_argument_of_nine:nnnnnnnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_fifth_argument_of_nine:nnnnnnnnn\l__semantex_arg_key_value_temp
+			\semantex_grab_fifth_argument_of_nine:nnnnnnnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_sixth_argument_of_nine:nnnnnnnnn\l__semantex_arg_key_value_temp
+			\semantex_grab_sixth_argument_of_nine:nnnnnnnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_seventh_argument_of_nine:nnnnnnnnn\l__semantex_arg_key_value_temp
+			\semantex_grab_seventh_argument_of_nine:nnnnnnnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_eighth_argument_of_nine:nnnnnnnnn\l__semantex_arg_key_value_temp
+			\semantex_grab_eighth_argument_of_nine:nnnnnnnnn ##1
 		}
 		{
-			\exp_not:N\semantex_grab_ninth_argument_of_nine:nnnnnnnnn\l__semantex_arg_key_value_temp
+			\semantex_grab_ninth_argument_of_nine:nnnnnnnnn ##1
 		}
 	}
 	%IM Remove spaces in #2
 }
 
-\cs_new:Npn\semantex_primitive_valuekey_argsinglekeys:nn#1#2{
-	% Add argument keys taking no values
-	\semantex_data_prop_provide:nn { #1 } { custom_arg_singlekeys }
-	\clist_map_inline:nn { #2 }{
-		\__semantex_arg_singlekeys_noequality_format_auxiliary:nnn{#1}##1
-	}
-}
+\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_new:Npn \__semantex_arg_singlekeys_noequality_format_auxiliary:nnn#1#2#3{
-	\semantex_data_prop_put:nnnn {#1} {custom_arg_singlekeys} {#2} {#3}
-}
+\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:NN\semantex_primitive_valuekey_argnovaluekeys:nn\semantex_primitive_valuekey_argsinglekeys: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
 
-\cs_new:Npn\semantex_primitive_valuekey_removeargsinglekey:nn#1#2
-{
-	\semantex_arg_singlekey_remove:nn { #1 } { #2 }
-}
-
-\cs_set_eq:NN\semantex_primitive_valuekey_removeargnovaluekey:nn\semantex_primitive_valuekey_removeargsinglekey:nn % Previously, "singlekeys" was called "novaluekeys", so I am keeping this alias for backwards compatibility
-
-\cs_set_eq:cN { semantex_primitive_valuekey_removearg0valuekey:nn } \semantex_primitive_valuekey_removeargsinglekey:nn
-
 % THESE ARE REALLY THE COMMANDS MANIPULATING DATA:
 
-\cs_new:Npn\semantex_primitive_valuekey_symbol:nn#1#2{
+\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_new:Npn\semantex_primitive_valuekey_texclass:nn#1#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_primitive_valuekey_setslot:nn#1#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_primitive_valuekey_symbolputright:nn#1#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_primitive_valuekey_symbolputleft:nn#1#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_primitive_valuekey_command:nn#1#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_primitive_valuekey_clearcommand:nn#1#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_primitive_valuekey_argwithkeyval:nn#1#2{
+\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
@@ -2936,17 +4078,17 @@
 	% to arg keyvals)
 }
 
-\cs_new:Npn\semantex_primitive_valuekey_argwithsinglekeys:nn#1#2{
+\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_primitive_valuekey_argwithonesinglekey: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 }}}}
+	\use:c { __semantex_data_cs_#1_arg_singlekey:n } { #2 }
 }
 
-\cs_new:Npn\semantex_primitive_valuekey_argwithoutkeyval:nn#1#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
@@ -2954,19 +4096,19 @@
 }
 
 
-\cs_new:Npn\semantex_primitive_valuekey_setargsep:nn#1#2
+\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_primitive_valuekey_setargdots:nn#1#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_primitive_valuekey_setargslot:nn#1#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 } }
@@ -2973,7 +4115,7 @@
 }
 
 
-\cs_new:Npn\semantex_primitive_valuekey_prearg:nn#1#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}
 	{
@@ -2981,12 +4123,12 @@
 	}
 }
 
-\cs_new:Npn\semantex_primitive_valuekey_clearprearg:nn#1#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_primitive_valuekey_postarg:nn#1#2{
+\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}
 	{
@@ -2994,12 +4136,12 @@
 	}
 }
 
-\cs_new:Npn\semantex_primitive_valuekey_clearpostarg:nn#1#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_primitive_valuekey_output:nn#1#2
+\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 }
@@ -3007,19 +4149,74 @@
 		\semantex_data_tl_set:nnx { #1 } { output } { class_\cs_to_str:N #2 }
 	}
 	{
-		\semantex_error_output_format:nN { #1 } \__semantex_primitive_valuekey_output_temp
-		\msg_error:nnxnn { semantex } { class_not_found } { \__semantex_primitive_valuekey_output_temp } { output } { #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_primitive_valuekey_outputoptions:nn#1#2{
-	% Sets possible options to pass to the output class
-	\semantex_data_tl_put_right:nnn { #1 } { outputoptions } { ,#2, }
+\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_new:Npn\semantex_primitive_valuekey_ifleftargument:nn#1#2{
+\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 }
 	{
@@ -3031,13 +4228,13 @@
 			\semantex_data_bool_set_false:nn { #1 } { leftargument }
 		}
 		{
-			\semantex_error_output_format:nN { #1 } \l__semantex_primitive_valuekey_ifleftargumen_temp
-			\msg_error:nnxnn { semantex } { key_value_not_found } { \l__semantex_primitive_valuekey_ifleftargumen_temp } { ifleftargument } { #2 }
+			\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_primitive_valuekey_ifoutput:nn#1#2{ %IMPLEMENT THIS
+\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 }
 	{
@@ -3049,13 +4246,13 @@
 			\semantex_data_bool_set_false:nn { #1 } { output }
 		}
 		{
-			\semantex_error_output_format:nN { #1 } \l__semantex_primitive_valuekey_ifoutput_temp
-			\msg_error:nnxnn { semantex } { key_value_not_found } { \l__semantex_primitive_valuekey_ifoutput_temp } { ifoutput } { #2 }
+			\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_primitive_valuekey_gradingposition:nn#1#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 }
@@ -3068,17 +4265,17 @@
 				\semantex_data_bool_set_false:nn { #1 } { uppergrading }
 			}
 			{
-				\semantex_error_output_format:nN { #1 } \l__semantex_primitive_valuekey_gradingposition_temp
-				\msg_error:nnxnn { semantex } { key_value_not_found } { \l__semantex_primitive_valuekey_gradingposition_temp } { gradingposition } { #2 }
+				\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_primitive_valuekey_gradingpos:nn \semantex_primitive_valuekey_gradingposition:nn
+\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_primitive_valuekey_upper:nn#1#2{
+\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 } }
@@ -3089,7 +4286,7 @@
 
 
 
-\cs_new:Npn\semantex_primitive_valuekey_supper:nn#1#2{
+\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}
 	{
@@ -3107,7 +4304,7 @@
 	}
 }
 
-\cs_new:Npn\semantex_primitive_valuekey_upperputleft:nn#1#2{
+\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 } }
@@ -3116,14 +4313,14 @@
 	}
 }
 
-\cs_new:Npn\semantex_primitive_valuekey_preupper:nn#1#2{
+\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:cn { #1 } { preupper } { \exp_not:n{ #2 } }
+		\semantex_data_tl_put_left:nnn { #1 } { preupper } { \exp_not:n{ #2 } }
 	}
 }
-\cs_new:Npn\semantex_primitive_valuekey_postupper:nn#1#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}
 	{
@@ -3131,79 +4328,79 @@
 	}
 }
 
-\cs_new:Npn\semantex_primitive_valuekey_clearupper:nn#1#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_primitive_valuekey_clearpreupper:nn#1#2{
+\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_primitive_valuekey_clearpostupper:nn#1#2{
+\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_primitive_valuekey_setupperdots:nn#1#2
+\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_primitive_valuekey_upper:nn { nx }
+\cs_generate_variant:Nn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upper:nn { nx }
 
-\cs_new:Npn\semantex_primitive_valuekey_upperdots:nn#1#2
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upperdots:nn#1#2
 {
-	\semantex_primitive_valuekey_upper:nx { #1 } { \semantex_data_tl_get:nn { #1 } { upperdots } }
+	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upper:nx { #1 } { \semantex_data_tl_get:nn { #1 } { upperdots } }
 }
 
-\cs_new:Npn\semantex_primitive_valuekey_setupperslot:nn#1#2
+\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_primitive_valuekey_upperslot:nn#1#2
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upperslot:nn#1#2
 {
-	\semantex_primitive_valuekey_upper:nx { #1 } { \semantex_data_tl_get:nn { #1 } { upperslot } }
+	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upper:nx { #1 } { \semantex_data_tl_get:nn { #1 } { upperslot } }
 }
 
-\cs_generate_variant:Nn \semantex_primitive_valuekey_supper:nn { nx }
+\cs_generate_variant:Nn \__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_supper:nn { nx }
 
-\cs_new:Npn\semantex_primitive_valuekey_supperdots:nn#1#2
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_supperdots:nn#1#2
 {
-	\semantex_primitive_valuekey_supper:nx { #1 } { \semantex_data_tl_get:nn { #1 } { upperdots } }
+	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_supper:nx { #1 } { \semantex_data_tl_get:nn { #1 } { upperdots } }
 }
 
-\cs_new:Npn\semantex_primitive_valuekey_supperslot:nn#1#2
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_supperslot:nn#1#2
 {
-	\semantex_primitive_valuekey_supper:nx { #1 } { \semantex_data_tl_get:nn { #1 } { upperslot } }
+	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_supper:nx { #1 } { \semantex_data_tl_get:nn { #1 } { upperslot } }
 }
 
-\cs_generate_variant:Nn \semantex_primitive_valuekey_cupper:nn { nx }
+\cs_generate_variant:Nn \__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cupper:nn { nx }
 
-\cs_new:Npn\semantex_primitive_valuekey_cupperdots:nn#1#2
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cupperdots:nn#1#2
 {
-	\semantex_primitive_valuekey_cupper:nx { #1 } { \semantex_data_tl_get:nn { #1 } { upperdots } }
+	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cupper:nx { #1 } { \semantex_data_tl_get:nn { #1 } { upperdots } }
 }
 
-\cs_new:Npn\semantex_primitive_valuekey_cupperslot:nn#1#2
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cupperslot:nn#1#2
 {
-	\semantex_primitive_valuekey_cupper:nx { #1 } { \semantex_data_tl_get:nn { #1 } { upperslot } }
+	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cupper:nx { #1 } { \semantex_data_tl_get:nn { #1 } { upperslot } }
 }
 
-\cs_generate_variant:Nn \semantex_primitive_valuekey_upperwithothersep:nn { nx }
+\cs_generate_variant:Nn \__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upperwithothersep:nn { nx }
 
-\cs_new:Npn\semantex_primitive_valuekey_upperdotswithothersep:nn#1#2
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upperdotswithothersep:nn#1#2
 {
-	\semantex_primitive_valuekey_upperwithothersep:nx { #1 } { { \exp_not:n { #2 } } { \semantex_data_tl_get:nn { #1 } { upperdots } } }
+	\__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_primitive_valuekey_upperslotwithothersep:nn#1#2
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upperslotwithothersep:nn#1#2
 {
-	\semantex_primitive_valuekey_upperwithothersep:nx { #1 } { { \exp_not:n { #2 } } { \semantex_data_tl_get:nn { #1 } { upperslot } } }
+	\__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_primitive_valuekey_lower:nn#1#2{
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lower:nn#1#2{
 	% Adds to the lower index
 	\tl_if_blank:nF{#2}
 	{
@@ -3213,7 +4410,7 @@
 	}
 }
 
-\cs_new:Npn\semantex_primitive_valuekey_slower:nn#1#2{
+\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}
 	{
@@ -3231,7 +4428,7 @@
 	}
 }
 
-\cs_new:Npn\semantex_primitive_valuekey_lowerputleft:nn#1#2{
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lowerputleft:nn#1#2{
 	% Adds to the lower index
 	\tl_if_blank:nF{#2}
 	{
@@ -3241,7 +4438,7 @@
 	}
 }
 
-\cs_new:Npn\semantex_primitive_valuekey_prelower:nn#1#2{
+\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}
 	{
@@ -3249,7 +4446,7 @@
 	}
 }
 
-\cs_new:Npn\semantex_primitive_valuekey_postlower:nn#1#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}
 	{
@@ -3257,79 +4454,79 @@
 	}
 }
 
-\cs_new:Npn\semantex_primitive_valuekey_clearlower:nn#1#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_primitive_valuekey_clearprelower:nn#1#2{
+\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_primitive_valuekey_clearpostlower:nn#1#2{
+\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_primitive_valuekey_setlowerdots:nn#1#2
+\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_primitive_valuekey_lower:nn { nx }
+\cs_generate_variant:Nn \__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lower:nn { nx }
 
-\cs_new:Npn\semantex_primitive_valuekey_lowerdots:nn#1#2
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lowerdots:nn#1#2
 {
-	\semantex_primitive_valuekey_lower:nx { #1 } { \semantex_data_tl_get:nn { #1 } { lowerdots } }
+	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lower:nx { #1 } { \semantex_data_tl_get:nn { #1 } { lowerdots } }
 }
 
-\cs_new:Npn\semantex_primitive_valuekey_setlowerslot:nn#1#2
+\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_primitive_valuekey_lowerslot:nn#1#2
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lowerslot:nn#1#2
 {
-	\semantex_primitive_valuekey_lower:nx { #1 } { \semantex_data_tl_get:nn { #1 } { lowerslot } }
+	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lower:nx { #1 } { \semantex_data_tl_get:nn { #1 } { lowerslot } }
 }
 
-\cs_generate_variant:Nn \semantex_primitive_valuekey_slower:nn { nx }
+\cs_generate_variant:Nn \__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_slower:nn { nx }
 
-\cs_new:Npn\semantex_primitive_valuekey_slowerdots:nn#1#2
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_slowerdots:nn#1#2
 {
-	\semantex_primitive_valuekey_slower:nx { #1 } { \semantex_data_tl_get:nn { #1 } { lowerdots } }
+	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_slower:nx { #1 } { \semantex_data_tl_get:nn { #1 } { lowerdots } }
 }
 
-\cs_new:Npn\semantex_primitive_valuekey_slowerslot:nn#1#2
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_slowerslot:nn#1#2
 {
-	\semantex_primitive_valuekey_slower:nx { #1 } { \semantex_data_tl_get:nn { #1 } { lowerslot } }
+	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_slower:nx { #1 } { \semantex_data_tl_get:nn { #1 } { lowerslot } }
 }
 
-\cs_generate_variant:Nn \semantex_primitive_valuekey_clower:nn { nx }
+\cs_generate_variant:Nn \__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clower:nn { nx }
 
-\cs_new:Npn\semantex_primitive_valuekey_clowerdots:nn#1#2
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clowerdots:nn#1#2
 {
-	\semantex_primitive_valuekey_clower:nx { #1 } { \semantex_data_tl_get:nn { #1 } { lowerdots } }
+	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clower:nx { #1 } { \semantex_data_tl_get:nn { #1 } { lowerdots } }
 }
 
-\cs_new:Npn\semantex_primitive_valuekey_clowerslot:nn#1#2
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clowerslot:nn#1#2
 {
-	\semantex_primitive_valuekey_clower:nx { #1 } { \semantex_data_tl_get:nn { #1 } { lowerslot } }
+	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clower:nx { #1 } { \semantex_data_tl_get:nn { #1 } { lowerslot } }
 }
 
-\cs_generate_variant:Nn \semantex_primitive_valuekey_lowerwithothersep:nn { nx }
+\cs_generate_variant:Nn \__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lowerwithothersep:nn { nx }
 
-\cs_new:Npn\semantex_primitive_valuekey_lowerdotswithothersep:nn#1#2
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lowerdotswithothersep:nn#1#2
 {
-	\semantex_primitive_valuekey_lowerwithothersep:nx { #1 } { { \exp_not:n { #2 } } { \semantex_data_tl_get:nn { #1 } { lowerdots } } }
+	\__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_primitive_valuekey_lowerslotwithothersep:nn#1#2
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lowerslotwithothersep:nn#1#2
 {
-	\semantex_primitive_valuekey_lowerwithothersep:nx { #1 } { { \exp_not:n { #2 } } { \semantex_data_tl_get:nn { #1 } { lowerslot } } }
+	\__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_primitive_valuekey_upperwithothersep:nn#1#2{
+\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 }
@@ -3353,7 +4550,7 @@
 }
 
 
-\cs_new:Npn\semantex_primitive_valuekey_lowerwithothersep:nn#1#2{
+\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 }
@@ -3376,7 +4573,7 @@
 	\semantex_data_int_incr:nn { #1 } { numberofupperindices }
 }
 
-\cs_new:Npn\semantex_primitive_valuekey_cupper:nn#1#2{
+\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}
 	{
@@ -3393,7 +4590,7 @@
 }
 
 
-\cs_new:Npn\semantex_primitive_valuekey_clower:nn#1#2{
+\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}
 	{
@@ -3409,7 +4606,7 @@
 	}
 }
 
-\cs_new:Npn\semantex_primitive_valuekey_ifnextupperwithsep:nn#1#2
+\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 }
@@ -3422,13 +4619,13 @@
 			\semantex_data_bool_set_true:nn { #1 } { nextupperwithsep }
 		}
 		{
-			\semantex_error_output_format:nN { #1 } \l__semantex_primitive_valuekey_ifnextupperwithsep_temp
-			\msg_error:nnxnn { semantex } { key_value_not_found } { \l__semantex_primitive_valuekey_ifnextupperwithsep_temp } { ifnextupperwithsep } { #2 }
+			\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_primitive_valuekey_ifnextlowerwithsep:nn#1#2 % should be removed later
+\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 }
@@ -3441,19 +4638,19 @@
 			\semantex_data_bool_set_true:nn { #1 } { nextlowerwithsep }
 		}
 		{
-			\semantex_error_output_format:nN { #1 } \l__semantex_primitive_valuekey_ifnextlowerwithsep_temp
-			\msg_error:nnxnn { semantex } { key_value_not_found } { \l__semantex_primitive_valuekey_ifnextlowerwithsep_temp } { ifnextlowerwithsep } { #2 }
+			\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_primitive_valuekey_setuppersep:nn#1#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_primitive_valuekey_setlowersep:nn#1#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 }}
@@ -3461,7 +4658,7 @@
 
 %--------------- Left indices: (I don't repeat all of the documentation)
 
-\cs_new:Npn\semantex_primitive_valuekey_upperleft:nn#1#2{
+\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 } }
@@ -3470,7 +4667,7 @@
 	}
 }
 
-\cs_new:Npn\semantex_primitive_valuekey_supperleft:nn#1#2{
+\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 }
@@ -3487,7 +4684,7 @@
 	}
 }
 
-\cs_new:Npn\semantex_primitive_valuekey_upperleftputright:nn#1#2{
+\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 }
@@ -3495,7 +4692,7 @@
 	}
 }
 
-\cs_new:Npn\semantex_primitive_valuekey_preupperleft:nn#1#2{
+\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 } }
@@ -3502,7 +4699,7 @@
 	}
 }
 
-\cs_new:Npn\semantex_primitive_valuekey_postupperleft:nn#1#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}
 	{
@@ -3510,79 +4707,79 @@
 	}
 }
 
-\cs_new:Npn\semantex_primitive_valuekey_clearupperleft:nn#1#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_primitive_valuekey_clearpreupperleft:nn#1#2{
+\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_primitive_valuekey_clearpostupperleft:nn#1#2{
+\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_primitive_valuekey_setupperleftdots:nn#1#2
+\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_primitive_valuekey_upperleft:nn { nx }
+\cs_generate_variant:Nn \__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upperleft:nn { nx }
 
-\cs_new:Npn\semantex_primitive_valuekey_upperleftdots:nn#1#2
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upperleftdots:nn#1#2
 {
-	\semantex_primitive_valuekey_upperleft:nx { #1 } { \semantex_data_tl_get:nn { #1 } { upperleftdots } }
+	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upperleft:nx { #1 } { \semantex_data_tl_get:nn { #1 } { upperleftdots } }
 }
 
-\cs_new:Npn\semantex_primitive_valuekey_setupperleftslot:nn#1#2
+\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_primitive_valuekey_upperleftslot:nn#1#2
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upperleftslot:nn#1#2
 {
-	\semantex_primitive_valuekey_upperleft:nx { #1 } { \semantex_data_tl_get:nn { #1 } { upperleftslot } }
+	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upperleft:nx { #1 } { \semantex_data_tl_get:nn { #1 } { upperleftslot } }
 }
 
-\cs_generate_variant:Nn \semantex_primitive_valuekey_supperleft:nn { nx }
+\cs_generate_variant:Nn \__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_supperleft:nn { nx }
 
-\cs_new:Npn\semantex_primitive_valuekey_supperleftdots:nn#1#2
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_supperleftdots:nn#1#2
 {
-	\semantex_primitive_valuekey_supperleft:nx { #1 } { \semantex_data_tl_get:nn { #1 } { upperleftdots } }
+	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_supperleft:nx { #1 } { \semantex_data_tl_get:nn { #1 } { upperleftdots } }
 }
 
-\cs_new:Npn\semantex_primitive_valuekey_supperleftslot:nn#1#2
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_supperleftslot:nn#1#2
 {
-	\semantex_primitive_valuekey_supperleft:nx { #1 } { \semantex_data_tl_get:nn { #1 } { upperleftslot } }
+	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_supperleft:nx { #1 } { \semantex_data_tl_get:nn { #1 } { upperleftslot } }
 }
 
-\cs_generate_variant:Nn \semantex_primitive_valuekey_cupperleft:nn { nx }
+\cs_generate_variant:Nn \__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cupperleft:nn { nx }
 
-\cs_new:Npn\semantex_primitive_valuekey_cupperleftdots:nn#1#2
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cupperleftdots:nn#1#2
 {
-	\semantex_primitive_valuekey_cupperleft:nx { #1 } { \semantex_data_tl_get:nn { #1 } { upperleftdots } }
+	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cupperleft:nx { #1 } { \semantex_data_tl_get:nn { #1 } { upperleftdots } }
 }
 
-\cs_new:Npn\semantex_primitive_valuekey_cupperleftslot:nn#1#2
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cupperleftslot:nn#1#2
 {
-	\semantex_primitive_valuekey_cupperleft:nx { #1 } { \semantex_data_tl_get:nn { #1 } { upperleftslot } }
+	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cupperleft:nx { #1 } { \semantex_data_tl_get:nn { #1 } { upperleftslot } }
 }
 
-\cs_generate_variant:Nn \semantex_primitive_valuekey_upperleftwithothersep:nn { nx }
+\cs_generate_variant:Nn \__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upperleftwithothersep:nn { nx }
 
-\cs_new:Npn\semantex_primitive_valuekey_upperleftdotswithothersep:nn#1#2
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upperleftdotswithothersep:nn#1#2
 {
-	\semantex_primitive_valuekey_upperleftwithothersep:nx { #1 } { { \exp_not:n { #2 } } { \semantex_data_tl_get:nn { #1 } { upperleftdots } } }
+	\__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_primitive_valuekey_upperleftslotwithothersep:nn#1#2
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upperleftslotwithothersep:nn#1#2
 {
-	\semantex_primitive_valuekey_upperleftwithothersep:nx { #1 } { { \exp_not:n { #2 } } { \semantex_data_tl_get:nn { #1 } { upperleftslot } } }
+	\__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_primitive_valuekey_lowerleft:nn#1#2{
+\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 } }
@@ -3591,7 +4788,7 @@
 	}
 }
 
-\cs_new:Npn\semantex_primitive_valuekey_slowerleft:nn#1#2{
+\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 }
@@ -3608,7 +4805,7 @@
 	}
 }
 
-\cs_new:Npn\semantex_primitive_valuekey_lowerleftputright:nn#1#2{
+\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 } }
@@ -3617,7 +4814,7 @@
 	}
 }
 
-\cs_new:Npn\semantex_primitive_valuekey_prelowerleft:nn#1#2{
+\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 } }
@@ -3624,7 +4821,7 @@
 	}
 }
 
-\cs_new:Npn\semantex_primitive_valuekey_postlowerleft:nn#1#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 } }
@@ -3631,7 +4828,7 @@
 	}
 }
 
-\cs_new:Npn\semantex_primitive_valuekey_upperleftwithothersep:nn#1#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 } {
@@ -3648,7 +4845,7 @@
 }
 
 
-\cs_new:Npn\semantex_primitive_valuekey_lowerleftwithothersep:nn#1#2{
+\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 } {
@@ -3664,79 +4861,79 @@
 	\semantex_data_int_incr:nn { #1 } { numberoflowerleftindices }
 }
 
-\cs_new:Npn\semantex_primitive_valuekey_clearlowerleft:nn#1#2{
+\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_primitive_valuekey_clearprelowerleft:nn#1#2{
+\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_primitive_valuekey_clearpostlowerleft:nn#1#2{
+\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_primitive_valuekey_setlowerleftdots:nn#1#2
+\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_primitive_valuekey_lowerleft:nn { nx }
+\cs_generate_variant:Nn \__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lowerleft:nn { nx }
 
-\cs_new:Npn\semantex_primitive_valuekey_lowerleftdots:nn#1#2
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lowerleftdots:nn#1#2
 {
-	\semantex_primitive_valuekey_lowerleft:nx { #1 } { \semantex_data_tl_get:nn { #1 } { lowerleftdots } }
+	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lowerleft:nx { #1 } { \semantex_data_tl_get:nn { #1 } { lowerleftdots } }
 }
 
-\cs_new:Npn\semantex_primitive_valuekey_setlowerleftslot:nn#1#2
+\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_primitive_valuekey_lowerleftslot:nn#1#2
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lowerleftslot:nn#1#2
 {
-	\semantex_primitive_valuekey_lowerleft:nx { #1 } { \semantex_data_tl_get:nn { #1 } { lowerleftslot } }
+	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lowerleft:nx { #1 } { \semantex_data_tl_get:nn { #1 } { lowerleftslot } }
 }
 
-\cs_generate_variant:Nn \semantex_primitive_valuekey_slowerleft:nn { nx }
+\cs_generate_variant:Nn \__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_slowerleft:nn { nx }
 
-\cs_new:Npn\semantex_primitive_valuekey_slowerleftdots:nn#1#2
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_slowerleftdots:nn#1#2
 {
-	\semantex_primitive_valuekey_slowerleft:nx { #1 } { \semantex_data_tl_get:nn { #1 } { lowerleftdots } }
+	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_slowerleft:nx { #1 } { \semantex_data_tl_get:nn { #1 } { lowerleftdots } }
 }
 
-\cs_new:Npn\semantex_primitive_valuekey_slowerleftslot:nn#1#2
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_slowerleftslot:nn#1#2
 {
-	\semantex_primitive_valuekey_slowerleft:nx { #1 } { \semantex_data_tl_get:nn { #1 } { lowerleftslot } }
+	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_slowerleft:nx { #1 } { \semantex_data_tl_get:nn { #1 } { lowerleftslot } }
 }
 
-\cs_generate_variant:Nn \semantex_primitive_valuekey_clowerleft:nn { nx }
+\cs_generate_variant:Nn \__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clowerleft:nn { nx }
 
-\cs_new:Npn\semantex_primitive_valuekey_clowerleftdots:nn#1#2
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clowerleftdots:nn#1#2
 {
-	\semantex_primitive_valuekey_clowerleft:nx { #1 } { \semantex_data_tl_get:nn { #1 } { lowerleftdots } }
+	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clowerleft:nx { #1 } { \semantex_data_tl_get:nn { #1 } { lowerleftdots } }
 }
 
-\cs_new:Npn\semantex_primitive_valuekey_clowerleftslot:nn#1#2
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clowerleftslot:nn#1#2
 {
-	\semantex_primitive_valuekey_clowerleft:nx { #1 } { \semantex_data_tl_get:nn { #1 } { lowerleftslot } }
+	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clowerleft:nx { #1 } { \semantex_data_tl_get:nn { #1 } { lowerleftslot } }
 }
 
-\cs_generate_variant:Nn \semantex_primitive_valuekey_lowerleftwithothersep:nn { nx }
+\cs_generate_variant:Nn \__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lowerleftwithothersep:nn { nx }
 
-\cs_new:Npn\semantex_primitive_valuekey_lowerleftdotswithothersep:nn#1#2
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lowerleftdotswithothersep:nn#1#2
 {
-	\semantex_primitive_valuekey_lowerleftwithothersep:nx { #1 } { { \exp_not:n { #2 } } { \semantex_data_tl_get:nn { #1 } { lowerleftdots } } }
+	\__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_primitive_valuekey_lowerleftslotwithothersep:nn#1#2
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lowerleftslotwithothersep:nn#1#2
 {
-	\semantex_primitive_valuekey_lowerleftwithothersep:nx { #1 } { { \exp_not:n { #2 } } { \semantex_data_tl_get:nn { #1 } { lowerleftslot } } }
+	\__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_primitive_valuekey_cupperleft:nn#1#2{
+\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 }
@@ -3752,7 +4949,7 @@
 }
 
 
-\cs_new:Npn\semantex_primitive_valuekey_clowerleft:nn#1#2{
+\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 }
@@ -3767,7 +4964,7 @@
 	}
 }
 
-\cs_new:Npn\semantex_primitive_valuekey_ifnextupperleftwithsep:nn#1#2
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ifnextupperleftwithsep:nn#1#2
 {
 	\tl_if_eq:nnTF { #2 } { false }
 	{
@@ -3779,14 +4976,14 @@
 			\semantex_data_bool_set_true:nn { #1 } { nextupperleftwithsep }
 		}
 		{
-			\semantex_error_output_format:nN { #1 } \l__semantex_primitive_valuekey_ifnextupperleftwithsep_temp
-			\msg_error:nnxnn { semantex } { key_value_not_found } { \l__semantex_primitive_valuekey_ifnextupperleftwithsep_temp } { ifnextupperleftwithsep } { #2 }
+			\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_primitive_valuekey_ifnextlowerleftwithsep:nn#1#2
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ifnextlowerleftwithsep:nn#1#2
 {
 	\tl_if_eq:nnTF { #2 } { false }
 	{
@@ -3798,18 +4995,18 @@
 			\semantex_data_bool_set_true:nn { #1 } { nextlowerleftwithsep }
 		}
 		{
-			semantex_error_output_format:nN { #1 } \l__semantex_primitive_valuekey_ifnextlowerleftwithsep_temp
-			\msg_error:nnxnn { semantex } { key_value_not_found } { \l__semantex_primitive_valuekey_ifnextlowerleftwithsep_temp } { ifnextlowerleftwithsep } { #2 }
+			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_primitive_valuekey_setupperleftsep:nn#1#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_primitive_valuekey_setlowerleftsep:nn#1#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 } }
 }
@@ -3817,351 +5014,351 @@
 % Contrary to what you might think, the following commands ARE
 % sometimes needed.
 
-\cs_new:Npn\semantex_primitive_valuekey_ifnextdwithsep:nn#1#2 % should be removed later
+\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_primitive_valuekey_ifnextupperwithsep:nn { #1 } { #2 } }
-		{ \semantex_primitive_valuekey_ifnextlowerwithsep:nn { #1 } { #2 } }
+		{ \__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_primitive_valuekey_ifnextupperwithsep:nn { #1 } { #2 } }
-			{ \semantex_primitive_valuekey_ifnextlowerwithsep:nn { #1 } { #2 } }
+			{ \__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_primitive_valuekey_ifnextdwithsep_temp
-			\msg_error:nnxnn { semantex } { key_value_not_found } { \l__semantex_primitive_valuekey_ifnextdwithsep_temp } { ifnextdwithsep } { #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_primitive_valuekey_ifnextdegwithsep:nn\semantex_primitive_valuekey_ifnextdwithsep
+\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_primitive_valuekey_ifnextdegreewithsep:nn\semantex_primitive_valuekey_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_primitive_valuekey_ifnextiwithsep:nn#1#2
+\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_primitive_valuekey_ifnextlowerwithsep:nn { #1 } { #2 } }
-		{ \semantex_primitive_valuekey_ifnextupperwithsep:nn { #1 } { #2 } }
+		{ \__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_primitive_valuekey_ifnextlowerwithsep:nn { #1 } { #2 } }
-			{ \semantex_primitive_valuekey_ifnextupperwithsep:nn { #1 } { #2 } }
+			{ \__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_primitive_valuekey_ifnextiwithsep_temp
-			\msg_error:nnxnn { semantex } { key_value_not_found } { \l__semantex_primitive_valuekey_ifnextiwithsep_temp } { ifnextiwithsep } { #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_primitive_valuekey_ifnextindexwithsep:nn\semantex_primitive_valuekey_ifnextiwithsep:nn
+\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_primitive_valuekey_d:nn#1#2
+\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_primitive_valuekey_upper:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upper:nn { #1 } { #2 }
 	}
 	{
-		\semantex_primitive_valuekey_lower:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lower:nn { #1 } { #2 }
 	}
 }
 
-\cs_set_eq:NN\semantex_primitive_valuekey_deg:nn\semantex_primitive_valuekey_d:nn
+\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_primitive_valuekey_degree:nn\semantex_primitive_valuekey_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_primitive_valuekey_sd:nn#1#2
+\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_primitive_valuekey_supper:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_supper:nn { #1 } { #2 }
 	}
 	{
-		\semantex_primitive_valuekey_slower:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_slower:nn { #1 } { #2 }
 	}
 }
 
-\cs_set_eq:NN\semantex_primitive_valuekey_sdeg:nn\semantex_primitive_valuekey_sd:nn
+\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_primitive_valuekey_sdegree:nn\semantex_primitive_valuekey_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_primitive_valuekey_cd:nn#1#2{ %IM Maybe remove this.
+\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_primitive_valuekey_cupper:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cupper:nn { #1 } { #2 }
 	}
 	{
-		\semantex_primitive_valuekey_clower:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clower:nn { #1 } { #2 }
 	}
 }
 
-\cs_set_eq:NN\semantex_primitive_valuekey_sdeg:nn\semantex_primitive_valuekey_cd:nn
+\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_primitive_valuekey_sdegree:nn\semantex_primitive_valuekey_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_primitive_valuekey_i:nn#1#2{
+\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_primitive_valuekey_lower:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lower:nn { #1 } { #2 }
 	}
 	{
-		\semantex_primitive_valuekey_upper:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upper:nn { #1 } { #2 }
 	}
 }
 
-\cs_set_eq:NN\semantex_primitive_valuekey_index:nn\semantex_primitive_valuekey_i:nn
+\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_primitive_valuekey_si:nn#1#2{
+\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_primitive_valuekey_slower:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_slower:nn { #1 } { #2 }
 	}
 	{
-		\semantex_primitive_valuekey_supper:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_supper:nn { #1 } { #2 }
 	}
 }
 
-\cs_set_eq:NN\semantex_primitive_valuekey_sindex:nn\semantex_primitive_valuekey_si:nn
+\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_primitive_valuekey_ci:nn#1#2{
+\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_primitive_valuekey_clower:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clower:nn { #1 } { #2 }
 	}
 	{
-		\semantex_primitive_valuekey_cupper:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cupper:nn { #1 } { #2 }
 	}
 }
 
-\cs_set_eq:NN\semantex_primitive_valuekey_cindex:nn\semantex_primitive_valuekey_ci:nn
+\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_primitive_valuekey_dwithothersep:nn#1#2
+\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_primitive_valuekey_upperwithothersep:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upperwithothersep:nn { #1 } { #2 }
 	}
 	{
-		\semantex_primitive_valuekey_lowerwithothersep:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lowerwithothersep:nn { #1 } { #2 }
 	}
 }
 
-\cs_set_eq:NN\semantex_primitive_valuekey_degwithothersep:nn\semantex_primitive_valuekey_dwithothersep:nn
+\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_primitive_valuekey_degreewithothersep:nn\semantex_primitive_valuekey_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_primitive_valuekey_iwithothersep:nn#1#2{
+\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_primitive_valuekey_lowerwithothersep:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lowerwithothersep:nn { #1 } { #2 }
 	}
 	{
-		\semantex_primitive_valuekey_upperwithothersep:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upperwithothersep:nn { #1 } { #2 }
 	}
 }
 
-\cs_set_eq:NN\semantex_primitive_valuekey_indexwithothersep:nn\semantex_primitive_valuekey_iwithothersep:nn
+\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_primitive_valuekey_setdsep:nn#1#2
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setdsep:nn#1#2
 {
 	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
 	{
-		\semantex_primitive_valuekey_setuppersep:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setuppersep:nn { #1 } { #2 }
 	}
 	{
-		\semantex_primitive_valuekey_setlowersep:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setlowersep:nn { #1 } { #2 }
 	}
 }
 
-\cs_set_eq:NN\semantex_primitive_valuekey_setdegsep:nn\semantex_primitive_valuekey_setdsep:nn
+\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_primitive_valuekey_setdegreesep:nn\semantex_primitive_valuekey_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_primitive_valuekey_setisep:nn#1#2
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setisep:nn#1#2
 {
 	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
 	{
-		\semantex_primitive_valuekey_setlowersep:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setlowersep:nn { #1 } { #2 }
 	}
 	{
-		\semantex_primitive_valuekey_setuppersep:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setuppersep:nn { #1 } { #2 }
 	}
 }
 
-\cs_set_eq:NN\semantex_primitive_valuekey_setindexsep:nn\semantex_primitive_valuekey_setisep:nn
+\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_primitive_valuekey_pred:nn#1#2
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_pred:nn#1#2
 {
 	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
 	{
-		\semantex_primitive_valuekey_preupper:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_preupper:nn { #1 } { #2 }
 	}
 	{
-		\semantex_primitive_valuekey_prelower:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_prelower:nn { #1 } { #2 }
 	}
 }
 
-\cs_set_eq:NN\semantex_primitive_valuekey_predeg:nn\semantex_primitive_valuekey_pred:nn
+\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_primitive_valuekey_predegree:nn\semantex_primitive_valuekey_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_primitive_valuekey_postd:nn#1#2
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_postd:nn#1#2
 {
 	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
 	{
-		\semantex_primitive_valuekey_postupper:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_postupper:nn { #1 } { #2 }
 	}
 	{
-		\semantex_primitive_valuekey_postlower:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_postlower:nn { #1 } { #2 }
 	}
 }
 
-\cs_set_eq:NN\semantex_primitive_valuekey_postdeg:nn\semantex_primitive_valuekey_postd:nn
+\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_primitive_valuekey_postdegree:nn\semantex_primitive_valuekey_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_primitive_valuekey_cleard:nn#1#2
+\cs_set:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cleard:nn#1#2
 {
 	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
 	{
-		\semantex_primitive_valuekey_clearupper:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clearupper:nn { #1 } { #2 }
 	}
 	{
-		\semantex_primitive_valuekey_clearlower:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clearlower:nn { #1 } { #2 }
 	}
 }
 
-\cs_set_eq:NN\semantex_primitive_valuekey_cleardeg:nn\semantex_primitive_valuekey_cleard:nn
+\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_primitive_valuekey_cleardegree:nn\semantex_primitive_valuekey_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_primitive_valuekey_clearpred:nn#1#2
+\cs_set:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clearpred:nn#1#2
 {
 	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
 	{
-		\semantex_primitive_valuekey_clearpreupper:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clearpreupper:nn { #1 } { #2 }
 	}
 	{
-		\semantex_primitive_valuekey_clearprelower:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clearprelower:nn { #1 } { #2 }
 	}
 }
 
-\cs_set_eq:NN\semantex_primitive_valuekey_clearpredeg:nn\semantex_primitive_valuekey_clearpred:nn
+\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_primitive_valuekey_clearpredegree:nn\semantex_primitive_valuekey_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_primitive_valuekey_clearpostd:nn#1#2
+\cs_set:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clearpostd:nn#1#2
 {
 	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
 	{
-		\semantex_primitive_valuekey_clearpostupper:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clearpostupper:nn { #1 } { #2 }
 	}
 	{
-		\semantex_primitive_valuekey_clearpostlower:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clearpostlower:nn { #1 } { #2 }
 	}
 }
 
-\cs_set_eq:NN\semantex_primitive_valuekey_clearpostdeg:nn\semantex_primitive_valuekey_clearpostd:nn
+\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_primitive_valuekey_clearpostdegree:nn\semantex_primitive_valuekey_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_primitive_valuekey_prei:nn#1#2
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_prei:nn#1#2
 {
 	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
 	{
-		\semantex_primitive_valuekey_prelower:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_prelower:nn { #1 } { #2 }
 	}
 	{
-		\semantex_primitive_valuekey_preupper:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_preupper:nn { #1 } { #2 }
 	}
 }
 
-\cs_set_eq:NN\semantex_primitive_valuekey_preindex:nn\semantex_primitive_valuekey_prei:nn
+\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_primitive_valuekey_posti:nn#1#2
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_posti:nn#1#2
 {
 	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
 	{
-		\semantex_primitive_valuekey_postlower:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_postlower:nn { #1 } { #2 }
 	}
 	{
-		\semantex_primitive_valuekey_postupper:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_postupper:nn { #1 } { #2 }
 	}
 }
 
-\cs_set_eq:NN\semantex_primitive_valuekey_postindex:nn\semantex_primitive_valuekey_posti:nn
+\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_primitive_valuekey_cleari:nn#1#2
+\cs_set:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cleari:nn#1#2
 {
 	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
 	{
-		\semantex_primitive_valuekey_clearlower:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clearlower:nn { #1 } { #2 }
 	}
 	{
-		\semantex_primitive_valuekey_clearupper:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clearupper:nn { #1 } { #2 }
 	}
 }
 
-\cs_set_eq:NN\semantex_primitive_valuekey_clearindex:nn\semantex_primitive_valuekey_cleari:nn
+\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_primitive_valuekey_clearprei:nn#1#2
+\cs_set:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clearprei:nn#1#2
 {
 	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
 	{
-		\semantex_primitive_valuekey_clearprelower:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clearprelower:nn { #1 } { #2 }
 	}
 	{
-		\semantex_primitive_valuekey_clearpreupper:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clearpreupper:nn { #1 } { #2 }
 	}
 }
 
-\cs_set_eq:NN\semantex_primitive_valuekey_clearpreindex:nn\semantex_primitive_valuekey_clearprei:nn
+\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_primitive_valuekey_clearposti:nn#1#2
+\cs_set:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clearposti:nn#1#2
 {
 	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
 	{
-		\semantex_primitive_valuekey_clearpostlower:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clearpostlower:nn { #1 } { #2 }
 	}
 	{
-		\semantex_primitive_valuekey_clearpostupper:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clearpostupper:nn { #1 } { #2 }
 	}
 }
 
-\cs_set_eq:NN\semantex_primitive_valuekey_clearpostindex:nn\semantex_primitive_valuekey_clearposti:nn
+\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_primitive_valuekey_setddots:nn#1#2
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setddots:nn#1#2
 {
 	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
 	{
@@ -4172,139 +5369,139 @@
 	}
 }
 
-\cs_set_eq:NN\semantex_primitive_valuekey_setdegdots:nn\semantex_primitive_valuekey_setddots:nn
+\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_primitive_valuekey_setdegreedots:nn\semantex_primitive_valuekey_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_primitive_valuekey_ddots:nn#1#2
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ddots:nn#1#2
 {
 	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
 	{
-		\semantex_primitive_valuekey_upperdots:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upperdots:nn { #1 } { #2 }
 	}
 	{
-		\semantex_primitive_valuekey_lowerdots:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lowerdots:nn { #1 } { #2 }
 	}
 }
 
-\cs_set_eq:NN\semantex_primitive_valuekey_degdots:nn\semantex_primitive_valuekey_ddots:nn
+\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_primitive_valuekey_degreedots:nn\semantex_primitive_valuekey_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_primitive_valuekey_setdslot:nn#1#2
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setdslot:nn#1#2
 {
 	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
 	{
-		\semantex_primitive_valuekey_setupperslot:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setupperslot:nn { #1 } { #2 }
 	}
 	{
-		\semantex_primitive_valuekey_setlowerslot:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setlowerslot:nn { #1 } { #2 }
 	}
 }
 
-\cs_set_eq:NN\semantex_primitive_valuekey_setdegslot:nn\semantex_primitive_valuekey_setdslot:nn
+\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_primitive_valuekey_setdegreeslot:nn\semantex_primitive_valuekey_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_primitive_valuekey_dslot:nn#1#2
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_dslot:nn#1#2
 {
 	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
 	{
-		\semantex_primitive_valuekey_upperslot:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upperslot:nn { #1 } { #2 }
 	}
 	{
-		\semantex_primitive_valuekey_lowerslot:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lowerslot:nn { #1 } { #2 }
 	}
 }
 
-\cs_set_eq:NN\semantex_primitive_valuekey_degslot:nn\semantex_primitive_valuekey_dslot:nn
+\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_primitive_valuekey_degreeslot:nn\semantex_primitive_valuekey_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_primitive_valuekey_sddots:nn#1#2
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_sddots:nn#1#2
 {
 	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
 	{
-		\semantex_primitive_valuekey_supperdots:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_supperdots:nn { #1 } { #2 }
 	}
 	{
-		\semantex_primitive_valuekey_slowerdots:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_slowerdots:nn { #1 } { #2 }
 	}
 }
 
-\cs_set_eq:NN\semantex_primitive_valuekey_sdegdots:nn\semantex_primitive_valuekey_sddots:nn
+\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_primitive_valuekey_sdegreedots:nn\semantex_primitive_valuekey_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_primitive_valuekey_sdslot:nn#1#2
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_sdslot:nn#1#2
 {
 	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
 	{
-		\semantex_primitive_valuekey_supperslot:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_supperslot:nn { #1 } { #2 }
 	}
 	{
-		\semantex_primitive_valuekey_slowerslot:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_slowerslot:nn { #1 } { #2 }
 	}
 }
 
-\cs_set_eq:NN\semantex_primitive_valuekey_sdegslot:nn\semantex_primitive_valuekey_sdslot:nn
+\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_primitive_valuekey_sdegreeslot:nn\semantex_primitive_valuekey_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_primitive_valuekey_cddots:nn#1#2
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cddots:nn#1#2
 {
 	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
 	{
-		\semantex_primitive_valuekey_cupperdots:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cupperdots:nn { #1 } { #2 }
 	}
 	{
-		\semantex_primitive_valuekey_clowerdots:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clowerdots:nn { #1 } { #2 }
 	}
 }
 
-\cs_set_eq:NN\semantex_primitive_valuekey_cdegdots:nn\semantex_primitive_valuekey_cddots:nn
+\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_primitive_valuekey_cdegreedots:nn\semantex_primitive_valuekey_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_primitive_valuekey_cdslot:nn#1#2
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cdslot:nn#1#2
 {
 	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
 	{
-		\semantex_primitive_valuekey_cupperslot:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cupperslot:nn { #1 } { #2 }
 	}
 	{
-		\semantex_primitive_valuekey_clowerslot:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clowerslot:nn { #1 } { #2 }
 	}
 }
 
-\cs_set_eq:NN\semantex_primitive_valuekey_cdegslot:nn\semantex_primitive_valuekey_cdslot:nn
+\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_primitive_valuekey_cdegreeslot:nn\semantex_primitive_valuekey_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_primitive_valuekey_ddotswithothersep:nn#1#2
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ddotswithothersep:nn#1#2
 {
 	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
 	{
-		\semantex_primitive_valuekey_upperdotswithothersep:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upperdotswithothersep:nn { #1 } { #2 }
 	}
 	{
-		\semantex_primitive_valuekey_lowerdotswithothersep:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lowerdotswithothersep:nn { #1 } { #2 }
 	}
 }
 
-\cs_set_eq:NN\semantex_primitive_valuekey_degdotswithothersep:nn\semantex_primitive_valuekey_ddotswithothersep:nn
+\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_primitive_valuekey_degreedotswithothersep:nn\semantex_primitive_valuekey_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_primitive_valuekey_dslotwithothersep:nn#1#2
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_dslotwithothersep:nn#1#2
 {
 	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
 	{
-		\semantex_primitive_valuekey_upperslotwithothersep:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upperslotwithothersep:nn { #1 } { #2 }
 	}
 	{
-		\semantex_primitive_valuekey_lowerslotwithothersep:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lowerslotwithothersep:nn { #1 } { #2 }
 	}
 }
 
@@ -4312,7 +5509,7 @@
 
 %----------------------------------------------------------
 
-\cs_new:Npn\semantex_primitive_valuekey_setidots:nn#1#2
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setidots:nn#1#2
 {
 	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
 	{
@@ -4323,168 +5520,172 @@
 	}
 }
 
-\cs_set_eq:NN\semantex_primitive_valuekey_setindexdots:nn\semantex_primitive_valuekey_setidots:nn
+\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_primitive_valuekey_setdegreedots:nn\semantex_primitive_valuekey_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_primitive_valuekey_idots:nn#1#2
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_idots:nn#1#2
 {
 	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
 	{
-		\semantex_primitive_valuekey_lowerdots:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lowerdots:nn { #1 } { #2 }
 	}
 	{
-		\semantex_primitive_valuekey_upperdots:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upperdots:nn { #1 } { #2 }
 	}
 }
 
-\cs_set_eq:NN\semantex_primitive_valuekey_indexdots:nn\semantex_primitive_valuekey_idots:nn
+\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_primitive_valuekey_degreedots:nn\semantex_primitive_valuekey_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_primitive_valuekey_setislot:nn#1#2
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setislot:nn#1#2
 {
 	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
 	{
-		\semantex_primitive_valuekey_setlowerslot:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setlowerslot:nn { #1 } { #2 }
 	}
 	{
-		\semantex_primitive_valuekey_setupperslot:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_setupperslot:nn { #1 } { #2 }
 	}
 }
 
-\cs_set_eq:NN\semantex_primitive_valuekey_setindexslot:nn\semantex_primitive_valuekey_setislot:nn
+\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_primitive_valuekey_setdegreeslot:nn\semantex_primitive_valuekey_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_primitive_valuekey_islot:nn#1#2
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_islot:nn#1#2
 {
 	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
 	{
-		\semantex_primitive_valuekey_lowerslot:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lowerslot:nn { #1 } { #2 }
 	}
 	{
-		\semantex_primitive_valuekey_upperslot:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upperslot:nn { #1 } { #2 }
 	}
 }
 
-\cs_set_eq:NN\semantex_primitive_valuekey_indexslot:nn\semantex_primitive_valuekey_islot:nn
+\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_primitive_valuekey_degreeslot:nn\semantex_primitive_valuekey_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_primitive_valuekey_sidots:nn#1#2
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_sidots:nn#1#2
 {
 	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
 	{
-		\semantex_primitive_valuekey_slowerdots:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_slowerdots:nn { #1 } { #2 }
 	}
 	{
-		\semantex_primitive_valuekey_supperdots:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_supperdots:nn { #1 } { #2 }
 	}
 }
 
-\cs_set_eq:NN\semantex_primitive_valuekey_sindexdots:nn\semantex_primitive_valuekey_sidots:nn
+\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_primitive_valuekey_sdegreedots:nn\semantex_primitive_valuekey_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_primitive_valuekey_sislot:nn#1#2
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_sislot:nn#1#2
 {
 	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
 	{
-		\semantex_primitive_valuekey_slowerslot:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_slowerslot:nn { #1 } { #2 }
 	}
 	{
-		\semantex_primitive_valuekey_supperslot:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_supperslot:nn { #1 } { #2 }
 	}
 }
 
-\cs_set_eq:NN\semantex_primitive_valuekey_sindexslot:nn\semantex_primitive_valuekey_sislot:nn
+\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_primitive_valuekey_sdegreeslot:nn\semantex_primitive_valuekey_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_primitive_valuekey_cidots:nn#1#2
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cidots:nn#1#2
 {
 	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
 	{
-		\semantex_primitive_valuekey_clowerdots:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clowerdots:nn { #1 } { #2 }
 	}
 	{
-		\semantex_primitive_valuekey_cupperdots:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cupperdots:nn { #1 } { #2 }
 	}
 }
 
-\cs_set_eq:NN\semantex_primitive_valuekey_cindexdots:nn\semantex_primitive_valuekey_cidots:nn
+\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_primitive_valuekey_cdegreedots:nn\semantex_primitive_valuekey_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_primitive_valuekey_cislot:nn#1#2
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cislot:nn#1#2
 {
 	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
 	{
-		\semantex_primitive_valuekey_clowerslot:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_clowerslot:nn { #1 } { #2 }
 	}
 	{
-		\semantex_primitive_valuekey_cupperslot:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_cupperslot:nn { #1 } { #2 }
 	}
 }
 
-\cs_set_eq:NN\semantex_primitive_valuekey_cindexslot:nn\semantex_primitive_valuekey_cislot:nn
+\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_primitive_valuekey_cdegreeslot:nn\semantex_primitive_valuekey_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_primitive_valuekey_idotswithothersep:nn#1#2
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_idotswithothersep:nn#1#2
 {
 	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
 	{
-		\semantex_primitive_valuekey_lowerdotswithothersep:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lowerdotswithothersep:nn { #1 } { #2 }
 	}
 	{
-		\semantex_primitive_valuekey_upperdotswithothersep:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upperdotswithothersep:nn { #1 } { #2 }
 	}
 }
 
-\cs_set_eq:NN\semantex_primitive_valuekey_indexdotswithothersep:nn\semantex_primitive_valuekey_idotswithothersep:nn
+\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_primitive_valuekey_degreedotswithothersep:nn\semantex_primitive_valuekey_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_primitive_valuekey_islotwithothersep:nn#1#2
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_islotwithothersep:nn#1#2
 {
 	\semantex_data_bool_get:nnTF { #1 } { uppergrading }
 	{
-		\semantex_primitive_valuekey_lowerslotwithothersep:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_lowerslotwithothersep:nn { #1 } { #2 }
 	}
 	{
-		\semantex_primitive_valuekey_upperslotwithothersep:nn { #1 } { #2 }
+		\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_upperslotwithothersep:nn { #1 } { #2 }
 	}
 }
 
 %----------------------------------------------------------
 
-\cs_set_eq:NN\semantex_primitive_valuekey_degslotwithothersep:nn\semantex_primitive_valuekey_dslotwithothersep:nn
+\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_primitive_valuekey_degreeslotwithothersep:nn\semantex_primitive_valuekey_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_primitive_valuekey_par:nn#1#2{
+\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_primitive_valuekey_ifpar:nn { #1 } { true }
+	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_ifpar:nn { #1 } { true }
 }
 
-\cs_new:Npn\semantex_primitive_valuekey_parsize:nn#1#2{
+\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_primitive_valuekey_leftpar:nn#1#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_new:Npn\semantex_primitive_valuekey_rightpar:nn#1#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_new:Npn\semantex_primitive_valuekey_ifpar:nn#1#2{ %IMPLEMENT THIS
+\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 }
@@ -4505,50 +5706,50 @@
 				\semantex_data_bool_set_true:nn { #1 } { flexpar }
 			}
 			{
-				\semantex_error_output_format:nN { #1 } \l__semantex_primitive_valuekey_ifpar_temp
-				\msg_error:nnxnn { semantex } { key_value_not_found } { \l__semantex_primitive_valuekey_ifpar_temp } { ifpar } { #2 }
+				\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_primitive_valuekey_spar:nn#1#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_primitive_valuekey_return:nn { #1 }{}
+	\__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_primitive_valuekey_spar_sparsize_temp
+		\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_primitive_valuekey_spar_sparsize_temp }
+		{ \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_primitive_valuekey_spar_temp
+		\l__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_spar_temp_tl
 		\semantex_data_tl_set:nnx { #1 } { symbol }
 		{
-			\exp_not:V\l__semantex_primitive_valuekey_spar_temp
+			\exp_not:V\l__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_spar_temp_tl
 		}
 	}
 	{
-		\tl_set:Nn \l__semantex_primitive_valuekey_spar_sparsize_temp { \exp_not:n { #2 } }
+		\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_primitive_valuekey_spar_sparsize_temp }
+		{ \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_primitive_valuekey_spar_temp
+		\l__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_spar_temp_tl
 		\semantex_data_tl_set:nnx { #1 } { symbol }
 		{
-			\exp_not:V\l__semantex_primitive_valuekey_spar_temp
+			\exp_not:V\l__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_spar_temp_tl
 		}
 	}
 }
 
 
-\cs_new:Npn\semantex_primitive_valuekey_ifnextargwithsep:nn#1#2
+\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 }
@@ -4561,72 +5762,72 @@
 			\semantex_data_bool_set_false:nn { #1 } { nextargwithsep }
 		}
 		{
-			\semantex_error_output_format:nN { #1 } \l__semantex_primitive_valuekey_ifnextargwithsep_temp
-			\msg_error:nnxnn { semantex } { key_value_not_found } { \l__semantex_primitive_valuekey_ifnextargwithsep_temp } { ifnextargwithsep } { #2 }
+			\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_primitive_valuekey_otherspar:nn#1#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_primitive_valuekey_otherspar_auxiliary:nnn { #1 } #2
+	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_otherspar_auxiliary:nnn { #1 } #2
 }
 
-\cs_new:Npn\__semantex_primitive_valuekey_otherspar_auxiliary:nnn#1#2#3
+\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_primitive_valuekey_return:nn { #1 }{}
-	\semantex_data_tl_get_store:nnN { #1 } { sparsize } \l__semantex_primitive_valuekey_otherspar_sparsize_temp
+	\__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_primitive_valuekey_otherspar_sparsize_temp }
+	{ \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_primitive_valuekey_otherspar_temp
+	\l__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_otherspar_temp_tl
 	\semantex_data_tl_set:nnx { #1 } { symbol }
 	{
-		\exp_not:V\l__semantex_primitive_valuekey_otherspar_temp
+		\exp_not:V\l__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_otherspar_temp_tl
 	}
 }
 
-\cs_new:Npn\semantex_primitive_valuekey_Otherspar:nn#1#2
+\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_primitive_valuekey_Otherspar_auxiliary:nnnn { #1 } #2
+	\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_Otherspar_auxiliary:nnnn { #1 } #2
 }
 
-\cs_new:Npn\__semantex_primitive_valuekey_Otherspar_auxiliary:nnnn#1#2#3#4
+\cs_new:Npn\__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_Otherspar_auxiliary:nnnn#1#2#3#4
 {
-	\tl_set:Nn\l__semantex_primitive_valuekey_Otherspar_sparsize_temp
+	\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_primitive_valuekey_Otherspar_sparsize_temp }
+	{ \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_primitive_valuekey_Otherspar_temp
+	\l__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_Otherspar_temp_tl
 	\semantex_data_tl_set:nnx { #1 } { symbol }
 	{
-		\exp_not:V\l__semantex_primitive_valuekey_Otherspar_temp
+		\exp_not:V\l__semantex_data_cs_custom_valuekey_class_SemantexBaseObject_Otherspar_temp_tl
 	}
 }
 
-\cs_new:Npn\semantex_primitive_valuekey_sparsize:nn#1#2{
+\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_primitive_valuekey_leftspar:nn#1#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_primitive_valuekey_rightspar:nn#1#2{
+\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.
@@ -4634,49 +5835,6 @@
 
 \cs_generate_variant:Nn \semantex_keys_set:nn { nx, no, nV } % Only the first one is currently being used
 
-\cs_new:Npn \semantex_valuekey:nnn#1#2#3{
-	% Takes care of valuekeys, keys taking a value
-	% For the sake of implementation, the arguments
-	% come in a strange order
-	% #1 = value of key
-	% #2 = name of the key
-	% #3 = object
-	\tl_set:Nn\l__semantex_key_value_temp{\exp_not:n{#1}}
-	%IM think about using extra {...} to avoid interference with keyval str
-	\semantex_valuekey_get:nnNTF { #3 } { #2 } \l__semantex_custom_valuekey_temp
-	{
-		\semantex_keys_set:nx { #3 }
-		{ \l__semantex_custom_valuekey_temp }
-	}
-	{
-		\cs_if_exist:cTF { semantex_primitive_valuekey_#2:nn }
-		{
-			\use:c { semantex_primitive_valuekey_#2:nn }{ #3 }{ #1 }
-		}
-		{
-			\semantex_error_output_format:nN { #3 } \__semantex_valuekey_unknown_key_temp
-			\msg_error:nnxn { semantex } { valuekey_not_found } { \__semantex_valuekey_unknown_key_temp } { #2 }
-		}
-	}
-}
-
-\cs_new:Npn \semantex_singlekey:nn#1#2
-{
-	% #1 = name of the key
-	% #2 = object
-%	Takes care of single keys, keys without a value
-	\semantex_singlekey_get:nnNTF { #2 } { #1 } \l__semantex_custom_singlekey_temp
-	{
-		\semantex_keys_set:nx { #2 }
-		{
-			\l__semantex_custom_singlekey_temp
-		}
-	}
-	{
-		\semantex_keys_set:nn { #2 } { default = { #1 } }
-	}
-}
-
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %
 %    COMMANDS CONTROLLING THE ARGUMENT KEYVAL INTERFACE
@@ -4683,7 +5841,7 @@
 %
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
-\cs_new:Npn \semantex_primitive_arg_valuekey_othersep:nn#1#2
+\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
@@ -4708,7 +5866,9 @@
 	\semantex_data_bool_set_true:nn { #1 } { nextargwithsep }
 }
 
-\cs_new:Npn \semantex_primitive_arg_valuekey_s:nn#1#2
+\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 }
@@ -4725,207 +5885,204 @@
 		% this was mostly to create symmetry with the below case where
 		% cx is strictly necessary.
 	}
-%	\semantex_primitive_valuekey_ifoutput:nn { #1 } { true }
+%	\__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_primitive_arg_valuekey_s:nn { nx }
+\cs_generate_variant:Nn \__semantex_data_cs_custom_arg_valuekey_class_SemantexBaseObject_s:nn { nx }
 
-\cs_new:Npn \semantex_primitive_arg_valuekey_dots:nn#1#2
+\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_primitive_arg_valuekey_s:nx { #1 } { \semantex_data_tl_get_exp_not:nn { #1 } { argdots } }
+	\__semantex_data_cs_custom_arg_valuekey_class_SemantexBaseObject_s:nx { #1 } { \semantex_data_tl_get_exp_not:nn { #1 } { argdots } }
 }
 
-\cs_new:Npn \semantex_primitive_arg_valuekey_slot:nn#1#2
+\cs_new:Npn \__semantex_data_cs_custom_arg_valuekey_class_SemantexBaseObject_slot:nn#1#2
 {
 	% Writes the slot in teh argument
-	\semantex_primitive_arg_valuekey_s:nx { #1 } { \semantex_data_tl_get_exp_not:nn { #1 } { argslot } }
+	\__semantex_data_cs_custom_arg_valuekey_class_SemantexBaseObject_s:nx { #1 } { \semantex_data_tl_get_exp_not:nn { #1 } { argslot } }
 }
 
-\cs_generate_variant:Nn \semantex_arg_keys_set:nn { nx }
+\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_arg_valuekey:nnn#1#2#3
+\cs_new:Npn \__semantex_data_cs_custom_arg_valuekey_class_SemantexBaseObject_cslot:nn#1#2
 {
-	% Takes care of valuekeys, keys with a value
-	% For the sake of implementation, the arguments
-	% come in a strange order
-	% #1 = value of key
-	% #2 = name of the key
-	% #3 = object
-	\tl_set:Nn\l__semantex_arg_key_value_temp{\exp_not:n{#1}} % stores the content of the key in the temporary command \l__semantex_key_value_temp
-	\semantex_arg_valuekey_get:nnNTF { #3 } { #2 } \l__semantex_custom_arg_valuekey_temp
-	{
-		\semantex_arg_keys_set:nx { #3 } { \l__semantex_custom_arg_valuekey_temp }
-	}
-	{
-		\cs_if_exist:cTF { semantex_primitive_arg_valuekey_#2:nn }
-		{
-			\use:c { semantex_primitive_arg_valuekey_#2:nn }{ #3 }{ #1 }
-		}
-		{
-%			\msg_error:nnnn { semantex } { arg_valuekey_not_found } { #2 } { #3 }
-			\semantex_error_output_format:nN { #3 } \__semantex_arg_valuekey_unknown_key_temp
-			\msg_error:nnxn { semantex } { arg_valuekey_not_found } { \__semantex_arg_valuekey_unknown_key_temp } { #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_arg_singlekey:nn#1#2
+\cs_new:Npn \__semantex_data_cs_custom_arg_valuekey_class_SemantexBaseObject_slotwithothersep:nn#1#2
 {
-	% #1 = name of the key
-	% #2 = object
-%	% takes care of single keys, keys without a value
-% the class key is not actually necessary
-	\semantex_arg_singlekey_get:nnNTF { #2 } { #1 } \l__semantex_custom_arg_singlekey_temp
-	{
-		%\exp_args:NNno
-		%\exp_args:Nno
-		\semantex_arg_keys_set:nx { #2 }
-		{
-			\l__semantex_custom_arg_singlekey_temp
-		}
-	}
-	{
-		\semantex_data_tl_inherit_x:nn { #2 } { arg }
-		\semantex_arg_keys_set:nn { #2 } { default={\exp_not:n { #1 } }}
-		%IM THis \exp_not:n was added late, might be needed elsewhere, too.
-	}
+	% 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 SemantexVariable
+%    SETTING UP THE BASE CLASS SemantexBaseObject
 %
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 
-\semantex_data_tl_provide:nn { class_SemantexVariable } { output }
+\semantex_data_tl_provide:nn { class_SemantexBaseObject } { output }
 
-\semantex_data_tl_set:nnn { class_SemantexVariable } { output } { class_SemantexVariable }
+\semantex_data_tl_set:nnn { class_SemantexBaseObject } { output } { class_SemantexBaseObject }
 
-\semantex_data_tl_provide:nn { class_SemantexVariable } { upper }
+\semantex_data_tl_provide:nn { class_SemantexBaseObject } { upper }
 
-\semantex_data_tl_provide:nn { class_SemantexVariable } { uppersep }
+\semantex_data_tl_provide:nn { class_SemantexBaseObject } { uppersep }
 
-\semantex_data_tl_set:nnn { class_SemantexVariable } { 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_SemantexVariable } { lower }
+\semantex_data_tl_provide:nn { class_SemantexBaseObject } { lower }
 
-\semantex_data_tl_provide:nn { class_SemantexVariable } { lowersep }
+\semantex_data_tl_provide:nn { class_SemantexBaseObject } { lowersep }
 
-\semantex_data_tl_set:nnn { class_SemantexVariable } { lowersep } { , }
+\semantex_data_tl_set:nnn { class_SemantexBaseObject } { lowersep } { , }
 
-\semantex_data_tl_provide:nn { class_SemantexVariable } { preupper }
+\semantex_data_tl_provide:nn { class_SemantexBaseObject } { preupper }
 
-\semantex_data_tl_provide:nn { class_SemantexVariable } { postupper }
+\semantex_data_tl_provide:nn { class_SemantexBaseObject } { postupper }
 
-\semantex_data_tl_provide:nn { class_SemantexVariable } { prelower }
+\semantex_data_tl_provide:nn { class_SemantexBaseObject } { prelower }
 
-\semantex_data_tl_provide:nn { class_SemantexVariable } { postlower }
+\semantex_data_tl_provide:nn { class_SemantexBaseObject } { postlower }
 
-\semantex_data_tl_provide:nn { class_SemantexVariable } { upperleft }
+\semantex_data_tl_provide:nn { class_SemantexBaseObject } { upperleft }
 
-\semantex_data_tl_provide:nn { class_SemantexVariable } { upperleftsep }
+\semantex_data_tl_provide:nn { class_SemantexBaseObject } { upperleftsep }
 
-\semantex_data_tl_set:nnn { class_SemantexVariable } { 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_SemantexVariable } { lowerleft }
+\semantex_data_tl_provide:nn { class_SemantexBaseObject } { lowerleft }
 
-\semantex_data_tl_provide:nn { class_SemantexVariable } { lowerleftsep }
+\semantex_data_tl_provide:nn { class_SemantexBaseObject } { lowerleftsep }
 
-\semantex_data_tl_set:nnn { class_SemantexVariable } { lowerleftsep } { , }
+\semantex_data_tl_set:nnn { class_SemantexBaseObject } { lowerleftsep } { , }
 
 
-\semantex_data_tl_provide:nn { class_SemantexVariable } { preupperleft }
+\semantex_data_tl_provide:nn { class_SemantexBaseObject } { preupperleft }
 
-\semantex_data_tl_provide:nn { class_SemantexVariable } { postupperleft }
+\semantex_data_tl_provide:nn { class_SemantexBaseObject } { postupperleft }
 
-\semantex_data_tl_provide:nn { class_SemantexVariable } { prelowerleft }
+\semantex_data_tl_provide:nn { class_SemantexBaseObject } { prelowerleft }
 
-\semantex_data_tl_provide:nn { class_SemantexVariable } { postlowerleft }
+\semantex_data_tl_provide:nn { class_SemantexBaseObject } { postlowerleft }
 
-\semantex_data_int_provide:nn { class_SemantexVariable } { numberofarguments }
+\semantex_data_int_provide:nn { class_SemantexBaseObject } { numberofarguments }
 
-\semantex_data_bool_provide:nn { class_SemantexVariable } { nextargwithsep }
+\semantex_data_bool_provide:nn { class_SemantexBaseObject } { nextargwithsep }
 
-\semantex_data_bool_provide:nn { class_SemantexVariable } { nextupperleftwithsep }
-\semantex_data_bool_provide:nn { class_SemantexVariable } { nextlowerleftwithsep }
+\semantex_data_bool_provide:nn { class_SemantexBaseObject } { nextupperleftwithsep }
+\semantex_data_bool_provide:nn { class_SemantexBaseObject } { nextlowerleftwithsep }
 
-\semantex_data_int_provide:nn { class_SemantexVariable } { numberofupperleftindices }
-\semantex_data_int_provide:nn { class_SemantexVariable } { numberoflowerleftindices }
+\semantex_data_int_provide:nn { class_SemantexBaseObject } { numberofupperleftindices }
+\semantex_data_int_provide:nn { class_SemantexBaseObject } { numberoflowerleftindices }
 
-\semantex_data_tl_provide:nn { class_SemantexVariable } { prearg }
+\semantex_data_tl_provide:nn { class_SemantexBaseObject } { prearg }
 
-\semantex_data_tl_provide:nn { class_SemantexVariable } { postarg }
+\semantex_data_tl_provide:nn { class_SemantexBaseObject } { postarg }
 
-\semantex_data_tl_provide:nn { class_SemantexVariable } { arg }
+\semantex_data_tl_provide:nn { class_SemantexBaseObject } { arg }
 
-\semantex_data_tl_provide:nn { class_SemantexVariable } { argsep }
-\semantex_data_tl_set:nnn { class_SemantexVariable } { argsep } {,}
+\semantex_data_tl_provide:nn { class_SemantexBaseObject } { argsep }
+\semantex_data_tl_set:nnn { class_SemantexBaseObject } { argsep } {,}
 
-\semantex_data_tl_provide:nn { class_SemantexVariable } { argslot }
-\semantex_data_tl_set:nnn { class_SemantexVariable } { argslot } { \SemantexSlot }
+\semantex_data_tl_provide:nn { class_SemantexBaseObject } { argslot }
+\semantex_data_tl_set:nnn { class_SemantexBaseObject } { argslot } { \SemantexSlot }
 
-\semantex_data_tl_provide:nn { class_SemantexVariable } { argdots }
-\semantex_data_tl_set:nnn { class_SemantexVariable } { argdots } {\dots}
+\semantex_data_tl_provide:nn { class_SemantexBaseObject } { argdots }
+\semantex_data_tl_set:nnn { class_SemantexBaseObject } { argdots } {\dots}
 
-\semantex_data_tl_provide:nn { class_SemantexVariable } { symbol }
+\semantex_data_tl_provide:nn { class_SemantexBaseObject } { symbol }
 
-\semantex_data_seq_provide:nn { class_SemantexVariable } { commands_sequence }
+\semantex_data_seq_provide:nn { class_SemantexBaseObject } { commands_sequence }
 
-\semantex_data_bool_provide:nn { class_SemantexVariable } { uppergrading }
-\semantex_data_bool_set_true:nn { class_SemantexVariable } { uppergrading }
+\semantex_data_bool_provide:nn { class_SemantexBaseObject } { uppergrading }
+\semantex_data_bool_set_true:nn { class_SemantexBaseObject } { uppergrading }
 
-\semantex_data_bool_provide:nn { class_SemantexVariable } { output }
+\semantex_data_bool_provide:nn { class_SemantexBaseObject } { output }
 
-\semantex_data_tl_provide:nn { class_SemantexVariable } { outputoptions }
+\semantex_data_tl_provide:nn { class_SemantexBaseObject } { outputoptions }
 
-\semantex_data_bool_provide:nn { class_SemantexVariable } { nextupperwithsep }
-\semantex_data_bool_provide:nn { class_SemantexVariable } { nextlowerwithsep }
+\semantex_data_bool_provide:nn { class_SemantexBaseObject } { nextupperwithsep }
+\semantex_data_bool_provide:nn { class_SemantexBaseObject } { nextlowerwithsep }
 
-\semantex_data_int_provide:nn { class_SemantexVariable } { numberofupperindices }
-\semantex_data_int_provide:nn { class_SemantexVariable } { numberoflowerindices }
+\semantex_data_int_provide:nn { class_SemantexBaseObject } { numberofupperindices }
+\semantex_data_int_provide:nn { class_SemantexBaseObject } { numberoflowerindices }
 
-\semantex_data_bool_provide:nn { class_SemantexVariable } { par }
-\semantex_data_bool_set_true:nn { class_SemantexVariable } { par }
+\semantex_data_bool_provide:nn { class_SemantexBaseObject } { par }
+\semantex_data_bool_set_true:nn { class_SemantexBaseObject } { par }
 
-\semantex_data_bool_provide:nn { class_SemantexVariable } { flexpar }
+\semantex_data_bool_provide:nn { class_SemantexBaseObject } { flexpar }
 
-\semantex_data_tl_provide:nn { class_SemantexVariable } { parseoptions }
+\semantex_data_tl_provide:nn { class_SemantexBaseObject } { parseoptions }
 
-\semantex_data_tl_provide:nn { class_SemantexVariable } { texclass }
+\semantex_data_tl_provide:nn { class_SemantexBaseObject } { texclass }
 
-\semantex_data_bool_provide:nn { class_SemantexVariable } { leftargument }
+\semantex_data_bool_provide:nn { class_SemantexBaseObject } { leftargument }
 
-\semantex_data_tl_provide:nn { class_SemantexVariable } { upperdots }
-\semantex_data_tl_provide:nn { class_SemantexVariable } { upperslot }
+\semantex_data_tl_provide:nn { class_SemantexBaseObject } { upperdots }
+\semantex_data_tl_provide:nn { class_SemantexBaseObject } { upperslot }
 
-\semantex_data_tl_provide:nn { class_SemantexVariable } { lowerdots }
-\semantex_data_tl_provide:nn { class_SemantexVariable } { lowerslot }
+\semantex_data_tl_provide:nn { class_SemantexBaseObject } { lowerdots }
+\semantex_data_tl_provide:nn { class_SemantexBaseObject } { lowerslot }
 
-\semantex_data_tl_provide:nn { class_SemantexVariable } { upperleftdots }
-\semantex_data_tl_provide:nn { class_SemantexVariable } { upperleftslot }
+\semantex_data_tl_provide:nn { class_SemantexBaseObject } { upperleftdots }
+\semantex_data_tl_provide:nn { class_SemantexBaseObject } { upperleftslot }
 
-\semantex_data_tl_provide:nn { class_SemantexVariable } { lowerleftdots }
-\semantex_data_tl_provide:nn { class_SemantexVariable } { lowerleftslot }
+\semantex_data_tl_provide:nn { class_SemantexBaseObject } { lowerleftdots }
+\semantex_data_tl_provide:nn { class_SemantexBaseObject } { lowerleftslot }
 
-%\tl_set:Nn\g_objectmath_SemantexVariable_upper { hej }
-%\tl_set:Nn \SemantexVariable_output { class_SemantexVariable }
-%\bool_new:N \SemantexVariable_output_if_provided
-%\bool_set_true:N \SemantexVariable_output_if_provided
+%\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_variable_class:Nw \SemantexVariable [
-	%parent=SemantexVariable,
-	output=\SemantexVariable,
+\semantex_new_plain_class:Nw \SemantexBaseObject [
+	%parent=SemantexBaseObject,
+	output=\SemantexBaseObject,
 	ifoutput=false,
 	symbol=,
 	gradingposition=upper,
@@ -4983,14 +6140,37 @@
 		{si**}{si=\g_semantex_double_bullet},
 		{ci*}{ci=\g_semantex_bullet},
 		{ci**}{ci=\g_semantex_double_bullet},
-		{smash}{command=\noexpand\smash},
-%		(widebar}{command=\noexpand\widebar},%For unknown reasons, this only seems to work when run as a primitive
-		{tilde}{command=\noexpand\tilde},
+		{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=\noexpand\overline},
-		{bar}{command=\noexpand\bar},
-		{bold}{command=\noexpand\mathbf},
-		{roman}{command=\noexpand\mathrm},
+		{overline}{command=\overline},
+		{bar}{command=\bar},
+		{bold}{command=\mathbf},
+		{roman}{command=\mathrm},
 		{mathord}{texclass=\mathord},
 		{mathbin}{texclass=\mathbin},
 		{mathop}{texclass=\mathop},
@@ -5124,32 +6304,29 @@
 		{sdegree-}{sdegreeslot=},
 		{...}{sidots=},
 		{-}{sislot=},
-		% The following four commands do not work due to expansion issues:
-%		{useargwithkeyval}{useargwithkeyval=},
 %		{argwithkeyval}{
 %			valuekeys={
-%				{arg}{argwithkeyval={\noexpand\l__semantex_key_value_temp}},
+%				{arg}{argwithkeyval={####1}},
 %			},
 %		},
 %		{argwithsinglekeys}{
 %			valuekeys={
-%				{arg}{argwithsinglekeys={\noexpand\l__semantex_key_value_temp}},
+%				{arg}{argwithsinglekeys={####1}},
 %			},
 %		},
 %		{argwithoutkeyval}{
 %			valuekeys={
-%				{arg}{argwithoutkeyval={\noexpand\l__semantex_key_value_temp}},
+%				{arg}{argwithoutkeyval={####1}},
 %			},
 %		},
 %		{argwithonesinglekey}{
 %			valuekeys={
-%				{arg}{argwithonesinglekey={\noexpand\l__semantex_key_value_temp}},
+%				{arg}{argwithonesinglekey={####1}},
 %			},
 %		},
 	},
 	valuekeys={
 		{default}{sindex={#1}},
-%		{arg}{argwithkeyval={#1}},
 		{arg}{argwithsinglekeys={#1}},
 		{degreedefault}{sdegree={#1}},
 		{*withothersep}{degreewithothersep={#1}{\g_semantex_bullet}},
@@ -5164,25 +6341,87 @@
 		{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},
+						},
+					},
+				},
+			},
+		},
 	},
-%	argwithsinglekeys,
 	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=},
 	},
-	%command=,
-%	useargwithkeyval,
 ]
 
-\cs_set_eq:NN\__semantex_old_version_of_semantex_new_object_of_class_SemantexVariable:Nw \__semantex_new_object_of_class_SemantexVariable:Nw
+\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_SemantexVariable:Nw#1
+\cs_set:Npn \__semantex_new_object_of_class_SemantexBaseObject:Nw#1
 {
-	\msg_error:nnn { semantex } { created_a_SemantexVariable } { #1 }
-	\__semantex_old_version_of_semantex_new_object_of_class_SemantexVariable:Nw #1
+	\msg_error:nnn { semantex } { created_a_SemantexBaseObject } { #1 }
+	\__semantex_old_version_of_semantex_new_object_of_class_SemantexBaseObject:Nw #1
 }
\ No newline at end of file



More information about the tex-live-commits mailing list.