diff --git a/configure.ac b/configure.ac
index e430e8a7c38b1e633573f62ca97ffe6ac9ecd2fb..13e1ff8571638bd727366243fb3022b6a6f27625 100644
--- a/configure.ac
+++ b/configure.ac
@@ -25,6 +25,7 @@ AC_CHECK_HEADER([errno.h])
 AC_CHECK_HEADER([limits.h])
 AC_CHECK_HEADER([math.h])
 AC_CHECK_HEADER([stdbool.h])
+AC_CHECK_HEADER([stdint.h])
 AC_CHECK_HEADER([stdio.h])
 AC_CHECK_HEADER([stdlib.h])
 AC_CHECK_HEADER([string.h])
diff --git a/sefht.geany b/sefht.geany
index a3b4c4c0a9787067d24c8167443deca4d7eed593..ece6a791b2dd21666dc0ea9f93e7a8fcb3ac9ab1 100644
--- a/sefht.geany
+++ b/sefht.geany
@@ -28,37 +28,39 @@ long_line_behaviour=1
 long_line_column=72
 
 [files]
-current_page=26
+current_page=22
 FILE_NAME_0=923;Sh;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fconfigure.ac;0;8
 FILE_NAME_1=73;Make;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2FMakefile.am;0;8
 FILE_NAME_2=1082;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Fmain.c;0;8
-FILE_NAME_3=298;Make;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2FMakefile.am;0;8
+FILE_NAME_3=640;Make;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2FMakefile.am;0;8
 FILE_NAME_4=1381;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fcms.c;0;8
 FILE_NAME_5=1359;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fcms.h;0;8
-FILE_NAME_6=1438;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fdata.c;0;8
+FILE_NAME_6=4939;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fdata.c;0;8
 FILE_NAME_7=1376;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fdata.h;0;8
 FILE_NAME_8=1171;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Ffragment.c;0;8
 FILE_NAME_9=2843;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Ffragment.h;0;8
-FILE_NAME_10=4671;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fnode_fragment.c;0;8
+FILE_NAME_10=1609;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fnode_fragment.c;0;8
 FILE_NAME_11=3013;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fnode_fragment.h;0;8
 FILE_NAME_12=3572;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Ftext.c;0;8
 FILE_NAME_13=1833;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Ftext.h;0;8
-FILE_NAME_14=3449;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fvalidator.c;0;8
-FILE_NAME_15=1058;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fvalidator.h;0;8
-FILE_NAME_16=4232;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fstatus.h;0;8
-FILE_NAME_17=1017;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Flog.h;0;4
-FILE_NAME_18=1077;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fmacro.h;0;8
-FILE_NAME_19=937;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fsefht.h;0;8
-FILE_NAME_20=98;Make;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2FMakefile.am;0;8
-FILE_NAME_21=872;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_cms.c;0;8
-FILE_NAME_22=3552;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_data.c;0;8
-FILE_NAME_23=10063;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_node_fragment.c;0;8
-FILE_NAME_24=5736;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_text.c;0;8
-FILE_NAME_25=6532;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_validator.c;0;8
-FILE_NAME_26=119;None;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftodo.txt;0;8
+FILE_NAME_14=1520;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fvalidator.c;0;8
+FILE_NAME_15=1503;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fvalidator.h;0;8
+FILE_NAME_16=10187;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fvalidator_tag.c;0;8
+FILE_NAME_17=1828;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fvalidator_tag.h;0;8
+FILE_NAME_18=4232;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fstatus.h;0;8
+FILE_NAME_19=1017;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Flog.h;0;4
+FILE_NAME_20=1077;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fmacro.h;0;8
+FILE_NAME_21=937;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fsefht.h;0;8
+FILE_NAME_22=1408;Make;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2FMakefile.am;0;8
+FILE_NAME_23=872;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_cms.c;0;8
+FILE_NAME_24=3552;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_data.c;0;8
+FILE_NAME_25=2373;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_node_fragment.c;0;8
+FILE_NAME_26=5736;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_text.c;0;8
+FILE_NAME_27=4687;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_validator.c;0;8
+FILE_NAME_28=165;None;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftodo.txt;0;8
 
 [VTE]
-last_dir=/home/jonathan/Dokumente/projekte/prgm/internet/web/SeFHT/tests
+last_dir=/home/jonathan/Documents/projects/prgm/internet/web/SeFHT/tests
 
 [prjorg]
 source_patterns=*.c;*.C;*.cpp;*.cxx;*.c++;*.cc;*.m;
diff --git a/src/lib/Makefile.am b/src/lib/Makefile.am
index 721a0093b70ab28724cf25f6cc7deb8264271cd8..7dc0a0f832f106354f5f663c0fe0ce7933cf0f9c 100644
--- a/src/lib/Makefile.am
+++ b/src/lib/Makefile.am
@@ -16,6 +16,9 @@ libsefht_la_SOURCES += sefht/node_fragment.c sefht/node_fragment.h
 libsefht_la_SOURCES += sefht/text.c sefht/text.h
 libsefht_la_SOURCES += sefht/validator.c sefht/validator.h
 
+EXTRA_DIST =
+EXTRA_DIST += sefht/validator_tag.c
+
 nobase_include_HEADERS =
 nobase_include_HEADERS += sefht/sefht.h
 nobase_include_HEADERS += sefht/macro.h
@@ -27,6 +30,7 @@ nobase_include_HEADERS += sefht/fragment.h
 nobase_include_HEADERS += sefht/node_fragment.h
 nobase_include_HEADERS += sefht/text.h
 nobase_include_HEADERS += sefht/validator.h
+nobase_include_HEADERS += sefht/validator_tag.h
 
 libsefht_la_CPPFLAGS = -DLIB_SEFHT_COMPILATION
 libsefht_la_LDFLAGS = -version_info 0:0:0
diff --git a/src/lib/sefht/node_fragment.c b/src/lib/sefht/node_fragment.c
index 07ce9e96a0031f398309b9de881b2e99b44fb814..2c274fbcf878c7232de10ff0707cfe346f70bd22 100644
--- a/src/lib/sefht/node_fragment.c
+++ b/src/lib/sefht/node_fragment.c
@@ -61,14 +61,6 @@ SH_NodeFragment_new (const char * tag, struct SH_Data * data,
 {
 	struct SH_NodeFragment * fragment;
 
-	if (!SH_Validator_check_tag (data->validator, tag))
-	{
-		set_status_ (status, E_VALUE, 2, strlen (tag),
-		             "Tag %s is'nt valid.\n", tag);
-
-		return NULL;
-	}
-
 	fragment = malloc (sizeof (struct SH_NodeFragment));
 	if (fragment == NULL)
 	{
diff --git a/src/lib/sefht/validator.c b/src/lib/sefht/validator.c
index 55584063cfb5dcb1d4c25e7202bf6d9217cf669d..4f871f65b26a3da9f46db832f20ce97fe0f09007 100644
--- a/src/lib/sefht/validator.c
+++ b/src/lib/sefht/validator.c
@@ -22,22 +22,20 @@
  */
 
 
-#include <errno.h>
-#include <stdbool.h>
 #include <stdlib.h>
-#include <string.h>
 
-#include "macro.h"
 #include "log.h"
 #include "status.h"
 
 #include "validator.h"
 
 
-static inline void init_tags (struct SH_Validator * validator);
 
+#include "validator_tag.c"
+
+/*@null@*/
 struct SH_Validator *
-SH_Validator_new (struct SH_Status * status)
+SH_Validator_new (/*@null@*/ /*@out@*/ struct SH_Status * status)
 {
 	struct SH_Validator * validator;
 	validator = malloc (sizeof (struct SH_Validator));
@@ -51,130 +49,58 @@ SH_Validator_new (struct SH_Status * status)
 		return NULL;
 	}
 
-	init_tags (validator);
+	if (!init_tags (validator, status))
+	{
+/* dangerous call to silence splint, should never be executed. */
+#ifdef S_SPLINT_S
+		free (validator->tags);
+#endif
+		free (validator);
+		return NULL;
+	}
 
 	set_success (status);
 
 	return validator;
 }
 
-static inline void free_tags (struct SH_Validator * validator);
-
-void
-SH_Validator_free (struct SH_Validator * validator)
-{
-	free_tags (validator);
-	free (validator);
-
-	return;
-}
-
-static inline void
-init_tags (struct SH_Validator * validator)
-{
-	validator->tag_n = 0;
-	validator->tags = malloc (0);
-	validator->last_tag = TAG_ERR;
-
-	return;
-}
-
-static inline void
-free_tags (struct SH_Validator * validator)
+/*@null@*/
+struct SH_Validator *
+SH_Validator_copy (const struct SH_Validator * validator,
+                   /*@null@*/ /*@out@*/ struct SH_Status * status)
 {
-	unsigned int index;
+	struct SH_Validator * copy;
+	copy = malloc (sizeof (struct SH_Validator));
 
-	for (index = 0; index < validator->tag_n; index++)
+	if (copy == NULL)
 	{
-		free (validator->tags[index].name);
-	}
-
-	free (validator->tags);
-	return;
-}
-
+		set_status (status, E_ALLOC, 4,
+		            "Memory allocation for "
+		            "SH_Validator failed.\n");
 
-static inline tag_t
-SH_Validator_get_tag (struct SH_Validator * validator, const char * tag)
-{
-	unsigned int index;
+		return NULL;
+	}
 
-	for (index = 0; index < validator->tag_n; index++)
+	if (!copy_tags (copy, validator, status))
 	{
-		if (strcmp (validator->tags[index].name, tag) == 0)
-		{
-			return validator->tags[index].id;
-		}
+/* dangerous call to silence splint, should never be executed. */
+#ifdef S_SPLINT_S
+		free (copy->tags);
+#endif
+		free (copy);
+		return NULL;
 	}
 
-	return TAG_ERR;
-}
+	set_success (status);
 
-bool
-SH_Validator_check_tag (struct SH_Validator * validator,
-			const char * tag)
-{
-	if (SH_Validator_get_tag (validator, tag) == TAG_ERR)
-	{
-		return FALSE;
-	}
-	else
-	{
-		return TRUE;
-	}
+	return copy;
 }
 
-tag_t
-SH_Validator_register_tag (struct SH_Validator * validator,
-                           const char * tag,
-                           struct SH_Status * status)
+void
+SH_Validator_free (/*@only@*/ struct SH_Validator * validator)
 {
-	tag_t tag_id;
-
-	/* tag already registered */
-	tag_id = SH_Validator_get_tag (validator, tag);
-	if (tag_id != TAG_ERR)
-	{
-		return tag_id;
-	}
-
-	/* abort on overflow */
-	if (validator->tag_n == UINT_MAX
-	|| validator->last_tag == TAG_MAX)
-	{
-		set_status (status, E_DOMAIN, 3,
-		            "Maximum number of tags reached.\n");
-
-		return TAG_ERR;
-	}
-
-	validator->tags = realloc (validator->tags,
-			(validator->tag_n + 1) * sizeof (struct SH_Tag));
-
-	if (validator->tags == NULL)
-	{
-		set_status (status, E_ALLOC, 5,
-		            "Memory allocation for tag failed.\n");
-
-		return TAG_ERR;
-	}
-
-	NEXT_TAG(validator->last_tag);
-
-	validator->tags[validator->tag_n].id = validator->last_tag;
-	validator->tags[validator->tag_n].name = strdup (tag);
-
-	if (validator->tags[validator->tag_n].name == NULL)
-	{
-		set_status (status, E_ALLOC, 4,
-		            "Memory allocation for tag failed.\n");
-
-		return TAG_ERR;
-	}
-
-	validator->tag_n++;
-
-	set_success (status);
+	free_tags (validator);
+	free (validator);
 
-	return validator->last_tag;
+	return;
 }
diff --git a/src/lib/sefht/validator.h b/src/lib/sefht/validator.h
index a078adaa11f81e2d59e2017df41101781e0b0be4..6afdbd93fe601993ff9a731d27bc1b2d5856d681 100644
--- a/src/lib/sefht/validator.h
+++ b/src/lib/sefht/validator.h
@@ -29,53 +29,36 @@
 #error "Only <sefht/sefht.h> can be included directly."
 #endif
 
-#include <limits.h>
-#include <stdbool.h>
-
 #include "status.h"
 
 
-typedef unsigned int tag_t;
-#define TAG_ERR 0
-#define TAG_MIN 1
-#define TAG_MAX UINT_MAX
-
-#ifdef LIB_SEFHT_COMPILATION
+typedef struct SH_Validator SH_Validator;
 
-#define NEXT_TAG(tag) tag++
+#define __VALIDATOR_H_INSIDE__
+#include "validator_tag.h"
+#undef __VALIDATOR_H_INSIDE__
 
-struct SH_Tag
-{
-	tag_t id;
-	char * name;
-};
+#ifdef LIB_SEFHT_COMPILATION
 
 struct SH_Validator
 {
-	unsigned int tag_n;
-	struct SH_Tag * tags;
-	tag_t last_tag;
+	TAG_DATA
 };
 
 #endif /* LIB_SEFHT_COMPILATION */
 
-typedef struct SH_Validator SH_Validator;
-
 
+/*@null@*/
 SH_Validator *
-SH_Validator_new (struct SH_Status * status);
+SH_Validator_new (/*@null@*/ /*@out@*/ struct SH_Status * status);
 
-void
-SH_Validator_free (SH_Validator * validator);
-
-tag_t
-SH_Validator_register_tag (SH_Validator * validator,
-                           const char * tag,
-                           struct SH_Status * status);
+/*@null@*/
+struct SH_Validator *
+SH_Validator_copy (const SH_Validator * validator,
+                   /*@null@*/ /*@out@*/ struct SH_Status * status);
 
+void
+SH_Validator_free (/*@only@*/ SH_Validator * validator);
 
-bool
-SH_Validator_check_tag (SH_Validator * validator,
-                        const char * tag);
 
 #endif /* __VALIDATOR_H__ */
diff --git a/src/lib/sefht/validator_tag.c b/src/lib/sefht/validator_tag.c
new file mode 100644
index 0000000000000000000000000000000000000000..1bdf6989fd15f9cdd883a6e51298e695c65182b5
--- /dev/null
+++ b/src/lib/sefht/validator_tag.c
@@ -0,0 +1,528 @@
+/*
+ * validator_tag.c
+ *
+ * Copyright 2022 Jonathan Schöbel <jonathan@Ubermos-2019>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ *
+ */
+
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "macro.h"
+#include "log.h"
+#include "status.h"
+
+#include "validator_tag.h"
+
+
+static inline
+bool
+init_tags (/*@out@*/ struct SH_Validator * validator,
+           /*@null@*/ /*@out@*/ struct SH_Status * status);
+
+static inline
+bool
+copy_tags (/*@out@*/ struct SH_Validator * copy,
+           const struct SH_Validator * validator,
+           /*@null@*/ /*@out@*/ struct SH_Status * status);
+
+static inline
+void
+free_tags (/*@special@*/ struct SH_Validator * validator)
+	/*@releases validator->tags@*/;
+
+static inline
+size_t
+get_tag_number (const struct SH_Validator * validator);
+
+static inline
+Tag
+add_tag (struct SH_Validator * validator,
+         const char * tag,
+         /*@null@*/ /*@out@*/ struct SH_Status * status);
+
+/*@unused@*/
+static inline
+bool
+is_tag_id (struct SH_Validator * validator, Tag id);
+
+static inline
+bool
+is_tag_name (struct SH_Validator * validator, const char * name);
+
+/*@unused@*/
+static inline
+/*@null@*/
+char *
+get_tag_name_by_id (struct SH_Validator * validator, Tag id,
+                    /*@null@*/ /*@out@*/ struct SH_Status * status);
+
+static inline
+Tag
+get_tag_id_by_name (struct SH_Validator * validator,
+                    const char * name);
+
+
+
+#define EXECUTE_ON_ALL_TAGS_IF(ITER, CONDITION, BLOCK)                 \
+do                                                                     \
+{                                                                      \
+	bool is_free;                                                  \
+	size_t index;                                                  \
+	size_t free_index;                                             \
+                                                                       \
+	for (index = 1; index <= ITER##_n; index++)                    \
+	{                                                              \
+		/* if tag is not in the list of free blocks */         \
+		is_free = FALSE;                                       \
+		for (free_index = ITER##s[0].next;                     \
+		     free_index != 0;                                  \
+		     free_index = ITER##s[free_index].next)            \
+		{                                                      \
+			if (index == free_index)                       \
+			{                                              \
+				is_free = TRUE;                        \
+				break;                                 \
+			}                                              \
+		}                                                      \
+                                                                       \
+		if (!is_free && CONDITION) BLOCK                       \
+	}                                                              \
+}                                                                      \
+while (0)
+
+#define EXECUTE_ON_ALL_TAGS(BASE, BLOCK)                               \
+        EXECUTE_ON_ALL_TAGS_IF (BASE, TRUE, BLOCK)
+
+
+static inline
+bool
+init_tags (/*@out@*/ struct SH_Validator * validator,
+           /*@null@*/ /*@out@*/ struct SH_Status * status)
+{
+	validator->tags = malloc (sizeof (struct tag_info));
+	if (validator->tags == NULL)
+	{
+		set_status (status, E_ALLOC, 3, "malloc failed");
+		return FALSE;
+	}
+
+	validator->tags[0].next = 0;
+	validator->tag_n = 0;
+	validator->last_tag = TAG_ERR;
+
+	return TRUE;
+}
+
+static inline
+bool
+copy_tags (/*@out@*/ struct SH_Validator * copy,
+           const struct SH_Validator * validator,
+           /*@null@*/ /*@out@*/ struct SH_Status * status)
+{
+	bool is_free;
+	size_t index;
+	size_t free_index;
+	size_t copy_index;
+	size_t tag_n;
+
+	tag_n = get_tag_number (validator);
+
+	/* The size calculation is save,
+	 * because validator is already allocated. */
+	copy->tags = malloc ((tag_n + 1) * sizeof (struct tag_info));
+
+	if (copy->tags == NULL)
+	{
+		set_status (status, E_ALLOC, 5, "malloc failed");
+		return FALSE;
+	}
+
+	/* copy allocation info */
+	copy->tags[0].next = 0;
+	copy->tag_n = tag_n;
+	copy->last_tag = validator->last_tag;
+
+
+	/* copy data */
+	copy_index = 0;
+	for (index = 1; index <= validator->tag_n; index++)
+	{
+		/* if tag is not in the list of free blocks */
+		is_free = FALSE;
+		for (free_index = validator->tags[0].next;
+		     free_index != 0;
+		     free_index = validator->tags[free_index].next)
+		{
+			if (index == free_index)
+			{
+				is_free = TRUE;
+				break;
+			}
+		}
+
+		if (!is_free)
+		{
+			copy->tags[copy_index].data.id =
+			              validator->tags[index].data.id;
+
+			copy->tags[copy_index].data.name = strdup (
+			              validator->tags[index].data.name);
+
+			if (copy->tags[copy_index].data.name == NULL)
+			{
+				size_t index;
+
+				set_status (status, E_ALLOC, 5,
+				            "strdup failed");
+
+				for (index = 0; index < copy_index;
+				     index++)
+				{
+					free (copy->tags[index]
+					                    .data.name);
+				}
+
+				free (copy->tags);
+
+				return FALSE;
+			}
+
+			copy_index++;
+		}
+	}
+
+	return TRUE;
+}
+
+static inline void
+free_tags (/*@special@*/ struct SH_Validator * validator)
+	/*@releases validator->tags@*/
+{
+	EXECUTE_ON_ALL_TAGS (
+	    validator->tag,
+	{
+		free (validator->tags[index].data.name);
+	});
+
+	free (validator->tags);
+	return;
+}
+
+static inline
+size_t
+get_tag_number (const struct SH_Validator * validator)
+{
+	size_t tag_n;
+
+	tag_n = 0;
+
+	EXECUTE_ON_ALL_TAGS (
+	    validator->tag,
+	{
+		/* This addition is always save,
+		 * because tag_n is always smaller than
+		 * validator->tag_n and it is also of size_t. */
+		tag_n++;
+	});
+
+	return tag_n;
+}
+
+static inline
+Tag
+add_tag (struct SH_Validator * validator,
+         const char * tag,
+         /*@null@*/ /*@out@*/ struct SH_Status * status)
+{
+	Tag tag_id;
+	size_t index;
+	bool is_new;
+
+	/* abort on overflow:
+	 * - no unused Tag or
+	 * - no unused index */
+	if ((validator->last_tag == TAG_MAX)
+	|| ((validator->tags[0].next == 0)
+	    && ((validator->tag_n >= SIZE_MAX - 1)
+	        || ((validator->tag_n + 2)
+	            > (SIZE_MAX / sizeof (struct tag_info))))))
+	{
+		set_status (status, E_DOMAIN, 2,
+		            "maximum number of tags reached");
+		return TAG_ERR;
+	}
+
+	if (validator->tags[0].next == 0)
+	/* allocate new space */
+	{
+		struct tag_info * new_tags;
+
+		/* The addition and the multiplication is save,
+		 * because we have tested for this
+		 * in the first condition. */
+		new_tags = realloc (validator->tags,
+		                    sizeof (struct tag_info)
+		                    * (validator->tag_n + 2));
+
+		if (new_tags == NULL)
+		{
+			set_status (status, E_ALLOC, 6,
+			            "realloc failed");
+
+/* bad code to silence splint, should never be executed. */
+#ifdef S_SPLINT_S
+			validator->tags = (void *) 0x12345;
+#endif
+			return TAG_ERR;
+		}
+
+		validator->tags = new_tags;
+		index = validator->tag_n + 1;
+		is_new = TRUE;
+	}
+	/* reuse old space */
+	else
+	{
+		index = validator->tags[0].next;
+		validator->tags[0].next = validator->tags[index].next;
+		is_new = FALSE;
+	}
+
+	tag_id = NEXT_TAG (validator->last_tag);
+	validator->tags[index].data.id = tag_id;
+	validator->tags[index].data.name = strdup (tag);
+
+	if (validator->tags[index].data.name == NULL)
+	{
+		set_status (status, E_ALLOC, 4, "strdup failed");
+
+		/* restore free space list */
+		if (!is_new)
+		{
+			validator->tags[index].next =                  \
+			                        validator->tags[0].next;
+			validator->tags[0].next = index;
+		}
+
+		return TAG_ERR;
+	}
+
+	/* commit changes */
+	if (is_new)
+	{
+		validator->tag_n++;
+	}
+
+	validator->last_tag = tag_id;
+
+	set_success (status);
+
+	return tag_id;
+}
+
+/*@unused@*/
+static inline
+bool
+is_tag_id (struct SH_Validator * validator, Tag id)
+{
+	EXECUTE_ON_ALL_TAGS_IF (
+	    validator->tag,
+	    (validator->tags[index].data.id == id),
+	{
+		return TRUE;
+	});
+
+	return FALSE;
+}
+
+static inline
+bool
+is_tag_name (struct SH_Validator * validator, const char * name)
+{
+	EXECUTE_ON_ALL_TAGS_IF (
+	    validator->tag,
+	    (strcmp (validator->tags[index].data.name, name) == 0),
+	{
+		return TRUE;
+	});
+
+	return FALSE;
+}
+
+/*@unused@*/
+static inline
+/*@null@*/
+char *
+get_tag_name_by_id (struct SH_Validator * validator, Tag id,
+                    /*@null@*/ /*@out@*/ struct SH_Status * status)
+{
+	char * name;
+
+	EXECUTE_ON_ALL_TAGS_IF (
+	    validator->tag,
+	    (validator->tags[index].data.id == id),
+	{
+		name = strdup (validator->tags[index].data.name);
+		if (name == NULL)
+		{
+			set_status (status, E_ALLOC, 3,
+			            "strdup failed");
+			return NULL;
+		}
+
+		return name;
+	});
+
+	return NULL;
+}
+
+static inline
+Tag
+get_tag_id_by_name (struct SH_Validator * validator,
+                    const char * name)
+{
+	EXECUTE_ON_ALL_TAGS_IF (
+	    validator->tag,
+	    (strcmp (validator->tags[index].data.name, name) == 0),
+	{
+		return validator->tags[index].data.id;
+	});
+
+	return TAG_ERR;
+}
+
+static inline
+bool
+remove_tag (struct SH_Validator * validator, Tag id,
+            /*@null@*/ /*@out@*/ struct SH_Status * status)
+{
+	#define tags validator->tags
+	#define tag_n validator->tag_n
+	EXECUTE_ON_ALL_TAGS_IF (
+	    tag,
+	    (tags[index].data.id == id),
+	{
+		free (tags[index].data.name);
+
+		if (index == tag_n)
+		{
+			struct tag_info * new_tags;
+
+			do
+			{
+				/* find next last free blocks
+				 * in the list of free blocks */
+				is_free = FALSE;
+				for (free_index = tags[0].next;
+				     free_index != 0;
+				     free_index = tags[free_index].next)
+				{
+
+				if (tags[free_index].next == (index - 1))
+				{
+					is_free = TRUE;
+					index--;
+
+					tags[free_index].next =
+					tags[tags[free_index].next].next;
+					break;
+				}
+				}
+			}
+			while (is_free);
+
+			if (index
+			> (SIZE_MAX / sizeof (struct tag_info)))
+			{
+				set_status (status, E_DOMAIN, 2,
+				      "overflow while calling realloc");
+			}
+
+			new_tags = realloc (tags,
+			                    sizeof (struct tag_info)
+			                    * index);
+
+			if (new_tags == NULL)
+			{
+				set_status (status, E_ALLOC, 4,
+				            "realloc failed");
+
+/* bad code to silence splint, should never be executed. */
+#ifdef S_SPLINT_S
+				tags = (void *) 0x12345;
+#endif
+				return FALSE;
+			}
+
+			tags = new_tags;
+		}
+		else
+		{
+			tags[index].next = tags[0].next;
+			tags[0].next = index;
+		}
+
+		set_success (status);
+		return TRUE;
+	});
+	#undef tags
+	#undef tag_n
+
+	set_status (status, E_VALUE, 68, "unknown Tag id");
+	return FALSE;
+}
+
+
+bool
+SH_Validator_check_tag (struct SH_Validator * validator,
+                        const char * tag)
+{
+	return is_tag_name (validator, tag);
+}
+
+Tag
+SH_Validator_register_tag (struct SH_Validator * validator,
+                           const char * tag,
+                           /*@null@*/ /*@out@*/
+                           struct SH_Status * status)
+{
+	Tag tag_id;
+
+	/* tag already registered */
+	tag_id = get_tag_id_by_name (validator, tag);
+	if (tag_id != TAG_ERR)
+	{
+		return tag_id;
+	}
+
+	return add_tag (validator, tag, status);
+}
+
+bool
+SH_Validator_deregister_tag (struct SH_Validator * validator,
+                             Tag id,
+                             /*@null@*/ /*@out@*/
+                             struct SH_Status * status)
+{
+	return remove_tag (validator, id, status);
+}
diff --git a/src/lib/sefht/validator_tag.h b/src/lib/sefht/validator_tag.h
new file mode 100644
index 0000000000000000000000000000000000000000..c5ec3d99a9a94eb9f0547a09591abb4341dbf64e
--- /dev/null
+++ b/src/lib/sefht/validator_tag.h
@@ -0,0 +1,86 @@
+/*
+ * validator_tag.h
+ *
+ * Copyright 2022 Jonathan Schöbel <jonathan@Ubermos-2019>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ *
+ */
+
+
+#ifndef __VALIDATOR_TAG_H__
+#define __VALIDATOR_TAG_H__
+
+#if !defined (__VALIDATOR_H__)
+#error "Please include only <sefht/validator.h>."
+#endif
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "status.h"
+
+
+typedef unsigned int Tag;
+#define TAG_ERR (Tag) 0
+#define TAG_MIN (Tag) 1
+#define TAG_MAX (Tag) SIZE_MAX
+
+#ifdef LIB_SEFHT_COMPILATION
+
+#define NEXT_TAG(tag) (tag + 1)
+
+struct tag_info
+{
+	union
+	{
+		struct
+		{
+			Tag id;
+			/*@only@*/ char * name;
+		} data;
+		size_t next;
+	};
+};
+
+#define TAG_DATA                                                       \
+	/*@only@*/ struct tag_info * tags;                             \
+	size_t tag_n;                                                  \
+	Tag last_tag;                                                  \
+
+
+#endif /* LIB_SEFHT_COMPILATION */
+
+
+
+Tag
+SH_Validator_register_tag (SH_Validator * validator,
+                           const char * tag,
+                           /*@null@*/ /*@out@*/
+                           struct SH_Status * status);
+
+bool
+SH_Validator_deregister_tag (SH_Validator * validator,
+                             Tag id,
+                             /*@null@*/ /*@out@*/
+                             struct SH_Status * status);
+
+bool
+SH_Validator_check_tag (SH_Validator * validator,
+                        const char * tag);
+
+#endif /* __VALIDATOR_TAG_H__ */
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 1fa43a0952b81e7946c9e84871e55917a0874d9d..ad3158300aeb2ae5c66eb21677424b941fb20db2 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -7,7 +7,6 @@ TESTS += sefht_cms_test
 TESTS += sefht_data_test
 TESTS += sefht_node_fragment_test
 TESTS += sefht_text_test
-TESTS += sefht_validator_test
 
 check_PROGRAMS = $(TESTS)
 
@@ -44,7 +43,3 @@ sefht_node_fragment_test_LDADD += $(LDADD)
 sefht_text_test_SOURCES = test_text.c
 sefht_text_test_LDADD =
 sefht_text_test_LDADD += $(LDADD)
-
-sefht_validator_test_SOURCES = test_validator.c
-sefht_validator_test_LDADD =
-sefht_validator_test_LDADD += $(LDADD)
diff --git a/tests/test_node_fragment.c b/tests/test_node_fragment.c
index 203d5bb32c3372dc4068320f029ba32e52449c25..be2e1a3ea010eccd065aca56b7a0d109af2e21b4 100644
--- a/tests/test_node_fragment.c
+++ b/tests/test_node_fragment.c
@@ -37,10 +37,8 @@ START_TEST(test_node_fragment)
 	struct SH_Fragment * fragment;
 	struct SH_Data * data;
 	const char * tag = "tag";
-	const char * no_tag = "no_tag";
 
 	data = SH_Data_new (NULL);
-	SH_Validator_register_tag (data->validator, tag, NULL);
 
 	/* valid tag - no error */
 	fragment = SH_NodeFragment_new (tag, data, NULL);
@@ -50,10 +48,6 @@ START_TEST(test_node_fragment)
 
 	SH_Fragment_free (fragment);
 
-	/* invalid tag - no error */
-	fragment = SH_NodeFragment_new (no_tag, data, NULL);
-	ck_assert_int_eq ((long int) fragment, (long int) NULL);
-
 	/* valid tag - error */
 	status.status = UNDEFINED;
 	fragment = SH_NodeFragment_new (tag, data, &status);
@@ -64,12 +58,6 @@ START_TEST(test_node_fragment)
 
 	SH_Fragment_free (fragment);
 
-	/* invalid tag - error */
-	status.status = UNDEFINED;
-	fragment = SH_NodeFragment_new (no_tag, data, &status);
-	ck_assert_int_eq ((long int) fragment, (long int) NULL);
-	ck_assert_int_eq (status.status, E_VALUE);
-
 	SH_Data_free (data);
 }
 END_TEST
@@ -231,8 +219,6 @@ START_TEST(test_node_fragment_tag)
 	const char * tag2 = "body";
 
 	data = SH_Data_new (NULL);
-	SH_Validator_register_tag (data->validator, tag1, NULL);
-	SH_Validator_register_tag (data->validator, tag2, NULL);
 
 	/* no error */
 	fragment = SH_NodeFragment_new (tag1, data, NULL);
@@ -449,7 +435,6 @@ START_TEST(test_node_fragment_html)
 	size_t length;
 
 	data = SH_Data_new (NULL);
-	SH_Validator_register_tag (data->validator, "html", NULL);
 
 	/* no error */
 	fragment1 = SH_NodeFragment_new ("html", data, NULL);
diff --git a/tests/test_validator.c b/tests/test_validator.c
index 12fb4b0ff0ae70afa457ebdd10cc7b59a81b41d5..a17a27d754e096481fe0494303e5b14e90755c4d 100644
--- a/tests/test_validator.c
+++ b/tests/test_validator.c
@@ -31,14 +31,14 @@
 /* test static method */
 #define static
 
-/* lower UINT_MAX as we try to reach it */
+/* lower SIZE_MAX as we try to reach it */
 #include <limits.h>
-#define UINT_MAX 20
+#define SIZE_MAX 10 * sizeof (struct tag_info)
 
 #include "macro.h"
 #include "status.h"
 
-/* C file is needed, because we wan't to override UINT_MAX and static */
+/* C file is needed, because we wan't to override SIZE_MAX and static */
 #include "validator.c"
 
 
@@ -72,8 +72,8 @@ START_TEST(test_validator_tag)
 	const char * tag5 = "main";
 	const char * tag6 = "article";
 	char * tagN;
-	tag_t tag;
-	tag_t tag_return;
+	Tag tag;
+	Tag tag_return;
 	bool check;
 
 	validator = SH_Validator_new (NULL);
@@ -85,10 +85,10 @@ START_TEST(test_validator_tag)
 	ck_assert_int_eq (validator->tag_n, 1);
 	ck_assert_int_eq (validator->last_tag, tag);
 
-	ck_assert_int_eq (validator->tags[0].id, tag);
-	ck_assert_str_eq (validator->tags[0].name, tag1);
+	ck_assert_int_eq (validator->tags[1].data.id, tag);
+	ck_assert_str_eq (validator->tags[1].data.name, tag1);
 
-	tag_return = SH_Validator_get_tag (validator, tag1);
+	tag_return = get_tag_id_by_name (validator, tag1);
 	ck_assert_int_eq (tag_return, tag);
 
 	/* retry without error */
@@ -98,8 +98,8 @@ START_TEST(test_validator_tag)
 	ck_assert_int_eq (validator->tag_n, 1);
 	ck_assert_int_eq (validator->last_tag, tag);
 
-	ck_assert_int_eq (validator->tags[0].id, tag);
-	ck_assert_str_eq (validator->tags[0].name, tag1);
+	ck_assert_int_eq (validator->tags[1].data.id, tag);
+	ck_assert_str_eq (validator->tags[1].data.name, tag1);
 
 	/* fail without error */
 	/* make method fail by filling with garbage until
@@ -110,15 +110,15 @@ START_TEST(test_validator_tag)
 	/* +3 "tag" */
 	/* +1 NULL */
 	/* = +5 */
-	tagN = calloc (((int) floor (log10 ((double) UINT_MAX))) + 5,
+	tagN = calloc (((int) floor (log10 ((double) SIZE_MAX))) + 5,
 		       sizeof (char));
 
 	/* fill with garbage */
-	while (validator->tag_n != UINT_MAX)
+	sprintf (tagN, "tag%lu", validator->tag_n);
+	while (SH_Validator_register_tag (validator, tagN, NULL) != TAG_ERR)
 	{
-		printf ("tag%d\n", validator->tag_n);
-		sprintf (tagN, "tag%d", validator->tag_n);
-		SH_Validator_register_tag (validator, tagN, NULL);
+		printf ("tag%lu\n", validator->tag_n);
+		sprintf (tagN, "tag%lu", validator->tag_n);
 	}
 
 	free (tagN);
@@ -126,10 +126,9 @@ START_TEST(test_validator_tag)
 	tag = SH_Validator_register_tag (validator, tag2, NULL);
 	ck_assert_int_eq (tag, TAG_ERR);
 
-	ck_assert_int_eq (validator->tag_n, UINT_MAX);
-	ck_assert_int_eq (validator->last_tag, (tag_t) UINT_MAX);
+	ck_assert_int_eq (validator->tag_n, 9);
 
-	tag_return = SH_Validator_get_tag (validator, tag2);
+	tag_return = get_tag_id_by_name (validator, tag2);
 	ck_assert_int_eq (tag_return, TAG_ERR);
 
 	/* fail2 without error */
@@ -142,11 +141,11 @@ START_TEST(test_validator_tag)
 	ck_assert_int_eq (validator->tag_n, 1);
 	ck_assert_int_eq (validator->last_tag, TAG_MAX);
 
-	tag_return = SH_Validator_get_tag (validator, tag3);
+	tag_return = get_tag_id_by_name (validator, tag3);
 	ck_assert_int_eq (tag_return, TAG_ERR);
 
 	/* also free garbage created for overflow test */
-	validator->tag_n = UINT_MAX;
+	validator->tag_n = 9;
 
 	/* check tag */
 	check = SH_Validator_check_tag (validator, tag1);
@@ -172,10 +171,10 @@ START_TEST(test_validator_tag)
 	ck_assert_int_eq (validator->tag_n, 1);
 	ck_assert_int_eq (validator->last_tag, tag);
 
-	ck_assert_int_eq (validator->tags[0].id, tag);
-	ck_assert_str_eq (validator->tags[0].name, tag4);
+	ck_assert_int_eq (validator->tags[1].data.id, tag);
+	ck_assert_str_eq (validator->tags[1].data.name, tag4);
 
-	tag_return = SH_Validator_get_tag (validator, tag4);
+	tag_return = get_tag_id_by_name (validator, tag4);
 	ck_assert_int_eq (tag_return, tag);
 
 	/* fail with error */
@@ -187,15 +186,15 @@ START_TEST(test_validator_tag)
 	/* +3 "tag" */
 	/* +1 NULL */
 	/* = +5 */
-	tagN = calloc (((int) floor (log10 ((double) UINT_MAX))) + 5,
+	tagN = calloc (((int) floor (log10 ((double) SIZE_MAX))) + 5,
 		       sizeof (char));
 
 	/* fill with garbage */
-	while (validator->tag_n != UINT_MAX)
+		sprintf (tagN, "tag%lu", validator->tag_n);
+	while (SH_Validator_register_tag (validator, tagN, NULL) != TAG_ERR)
 	{
-		printf ("tag%d\n", validator->tag_n);
-		sprintf (tagN, "tag%d", validator->tag_n);
-		SH_Validator_register_tag (validator, tagN, NULL);
+		printf ("tag%lu\n", validator->tag_n);
+		sprintf (tagN, "tag%lu", validator->tag_n);
 	}
 
 	free (tagN);
@@ -205,10 +204,9 @@ START_TEST(test_validator_tag)
 	ck_assert_int_eq (tag, TAG_ERR);
 	ck_assert_int_eq (status.status, E_DOMAIN);
 
-	ck_assert_int_eq (validator->tag_n, UINT_MAX);
-	ck_assert_int_eq (validator->last_tag, (tag_t) UINT_MAX);
+	ck_assert_int_eq (validator->tag_n, 9);
 
-	tag_return = SH_Validator_get_tag (validator, tag5);
+	tag_return = get_tag_id_by_name (validator, tag5);
 	ck_assert_int_eq (tag_return, TAG_ERR);
 
 	/* fail2 with error */
@@ -223,7 +221,7 @@ START_TEST(test_validator_tag)
 	ck_assert_int_eq (validator->tag_n, 1);
 	ck_assert_int_eq (validator->last_tag, TAG_MAX);
 
-	tag_return = SH_Validator_get_tag (validator, tag6);
+	tag_return = get_tag_id_by_name (validator, tag6);
 	ck_assert_int_eq (tag_return, TAG_ERR);
 
 
@@ -238,7 +236,7 @@ START_TEST(test_validator_tag)
 	ck_assert_int_eq (check, FALSE);
 
 	/* also free garbage created for overflow test */
-	validator->tag_n = UINT_MAX;
+	validator->tag_n = 9;
 
 	SH_Validator_free (validator);
 }
diff --git a/todo.txt b/todo.txt
index 688c4f4cc3a447b91b89abcdddcd69fa7da5bb46..e99c86c32a2cfc571af67384635d3dc41df0cd13 100644
--- a/todo.txt
+++ b/todo.txt
@@ -6,3 +6,6 @@ dynamic Validator initialization
 
 remove -Wno-nonnull from AM_CFLAGS
 fix warnings for tests
+
+rewrite validator test
+restructure validator