diff --git a/sefht.geany b/sefht.geany
index d0398d5b8b6441edfdb4f4e83a8bff4edd65e0f9..b495feff54e5269614e2e28f129f2273cdaf483a 100644
--- a/sefht.geany
+++ b/sefht.geany
@@ -64,7 +64,7 @@ FILE_NAME_31=1303;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fp
 FILE_NAME_32=10846;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_33=1068;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_34=1287;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fvalidator_tag_data.h;0;8
-FILE_NAME_35=23338;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fvalidator_attr.c;0;8
+FILE_NAME_35=19943;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fvalidator_attr.c;0;8
 FILE_NAME_36=1051;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fvalidator_attr.h;0;8
 FILE_NAME_37=1413;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fvalidator_attr_data.h;0;8
 FILE_NAME_38=924;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fsrc%2Flib%2Fsefht%2Fstatus.h;0;8
@@ -83,8 +83,8 @@ FILE_NAME_50=4221;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fp
 FILE_NAME_51=994;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_text_mark.c;0;8
 FILE_NAME_52=2447;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_validator.c;0;8
 FILE_NAME_53=9409;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_validator_tag.c;0;8
-FILE_NAME_54=45433;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_validator_attr.c;0;8
-FILE_NAME_55=556;None;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftodo.txt;0;8
+FILE_NAME_54=54966;C;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftests%2Ftest_validator_attr.c;0;8
+FILE_NAME_55=521;None;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Ftodo.txt;0;8
 FILE_NAME_56=201;YAML;0;EUTF-8;0;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2F.gitlab-ci.yml;0;4
 FILE_NAME_57=71;Sh;0;EUTF-8;1;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fgitlab-ci%2Fupload.sh.in;0;8
 FILE_NAME_58=806;Sh;0;EUTF-8;0;1;0;%2Fhome%2Fjonathan%2FDokumente%2Fprojekte%2Fprgm%2Finternet%2Fweb%2FSeFHT%2Fgitlab-ci%2Frelease.sh.in;0;4
diff --git a/src/lib/sefht/validator_attr.c b/src/lib/sefht/validator_attr.c
index 81d9754fcd8bdf6112abc97791b56819ef51d461..b566c6b4d7259cfc4f92ab25cf9aef86bfe23281 100644
--- a/src/lib/sefht/validator_attr.c
+++ b/src/lib/sefht/validator_attr.c
@@ -184,6 +184,19 @@ remove_tag_for_all_attrs (struct SH_Validator * validator,
 	/*@modifies fileSystem@*/
 	/*@modifies status@*/;
 
+static inline
+bool
+attr_global_remove_tag (struct attr_info * attr,
+                        const struct tag_info * tags,
+                        const size_t tag_n,
+                        const char * tag,
+                        /*@null@*/ /*@out@*/ struct SH_Status * status)
+	/*@modifies attr->tags@*/
+	/*@modifies attr->tag_n@*/
+	/*@globals fileSystem@*/
+	/*@modifies fileSystem@*/
+	/*@modifies status@*/;
+
 
 static inline
 bool
@@ -846,6 +859,9 @@ remove_tag_for_all_attrs (struct SH_Validator * validator,
 				{
 					return FALSE;
 				}
+				/* rescan current index,
+				 * as the current attr just vanished */
+				index--;
 			}
 		}
 		else
@@ -866,6 +882,47 @@ remove_tag_for_all_attrs (struct SH_Validator * validator,
 	return TRUE;
 }
 
+static inline
+bool
+attr_global_remove_tag (struct attr_info * attr,
+                        const struct tag_info * tags,
+                        const size_t tag_n,
+                        const char * tag,
+                        /*@null@*/ /*@out@*/ struct SH_Status * status)
+	/*@modifies attr->tags@*/
+	/*@modifies attr->tag_n@*/
+	/*@globals fileSystem@*/
+	/*@modifies fileSystem@*/
+	/*@modifies status@*/
+{
+	attr->tags = malloc ((tag_n-1) * sizeof (struct attr_tag_info));
+	if (NULL == attr->tags)
+	{
+		set_status (status, E_ALLOC, 3, "malloc failed");
+		return FALSE;
+	}
+
+	for (size_t index = 0; index < tag_n; index++)
+	{
+		size_t position;
+
+		/* remove this tag */
+		if (tag == tags[index].name) continue;
+
+		find_attr_tag (attr, tags[index].name, &position);
+
+		for (size_t i = attr->tag_n; i > position; i--)
+		{
+			attr->tags[i] = attr->tags[i-1];
+		}
+		attr->tags[position].name = tags[index].name;
+		attr->tag_n++;
+	}
+
+	set_success (status);
+	return TRUE;
+}
+
 bool
 SH_Validator_check_attr (struct SH_Validator * validator,
                          /*@null@*/ const char * tag,
@@ -1010,6 +1067,19 @@ SH_Validator_deregister_attr (struct SH_Validator * validator,
 			return remove_attr (validator, index, status);
 		}
 
+		if ((0 == attr->tag_n) && (1 == validator->tag_n))
+		{
+			/* TODO: define whether this is an error */
+			if (0 != strcmp (tag, validator->tags[0].name))
+			{
+				set_status (status, E_VALUE, 2,
+				            "no such tag");
+				return FALSE;
+			}
+
+			return remove_attr (validator, index, status);
+		}
+
 		if (!find_tag (validator, tag, &index))
 		{
 			/* TODO: define whether this is an error */
@@ -1021,11 +1091,10 @@ SH_Validator_deregister_attr (struct SH_Validator * validator,
 
 		if (0 == attr->tag_n)
 		{
-			set_status (status, E_STATE, 2,
-			            "can't remove specific tag "
-			            "for global attribute, "
-			            "please localize first");
-			return FALSE;
+			return attr_global_remove_tag (attr,
+			                               validator->tags,
+			                               validator->tag_n,
+			                               tag, status);
 		}
 
 		if (!find_attr_tag (attr, tag, &index))
diff --git a/tests/test_validator_attr.c b/tests/test_validator_attr.c
index 1fd121ee216fed644fdcca7a9327193c2344c44b..495d81b476dffe803ef984efb1183bfee18c1193 100644
--- a/tests/test_validator_attr.c
+++ b/tests/test_validator_attr.c
@@ -814,32 +814,47 @@ START_TEST(test_validator_deregister_no_status)
 	ck_assert_int_eq (TRUE, result);
 	result = REGISTER (validator, "body", "class", NULL);
 	ck_assert_int_eq (TRUE, result);
+	result = REGISTER (validator, NULL, "v", NULL);
+	ck_assert_int_eq (TRUE, result);
+	result = REGISTER (validator, NULL, "w", NULL);
+	ck_assert_int_eq (TRUE, result);
 	result = REGISTER (validator, NULL, "x", NULL);
 	ck_assert_int_eq (TRUE, result);
 	result = REGISTER (validator, NULL, "y", NULL);
 	ck_assert_int_eq (TRUE, result);
+	result = REGISTER (validator, NULL, "z", NULL);
+	ck_assert_int_eq (TRUE, result);
 	#undef REGISTER
 
 	/* test - consistency */
-	ck_assert_int_eq (6, validator->attr_n);
+	ck_assert_int_eq (9, validator->attr_n);
 	ck_assert_str_eq ("attr", validator->attrs[0].name);
 	ck_assert_str_eq ("class", validator->attrs[1].name);
 	ck_assert_str_eq ("id", validator->attrs[2].name);
 	ck_assert_str_eq ("name", validator->attrs[3].name);
-	ck_assert_str_eq ("x", validator->attrs[4].name);
-	ck_assert_str_eq ("y", validator->attrs[5].name);
+	ck_assert_str_eq ("v", validator->attrs[4].name);
+	ck_assert_str_eq ("w", validator->attrs[5].name);
+	ck_assert_str_eq ("x", validator->attrs[6].name);
+	ck_assert_str_eq ("y", validator->attrs[7].name);
+	ck_assert_str_eq ("z", validator->attrs[8].name);
 	ck_assert_int_eq (2, validator->attrs[0].tag_n);
 	ck_assert_int_eq (2, validator->attrs[1].tag_n);
 	ck_assert_int_eq (2, validator->attrs[2].tag_n);
 	ck_assert_int_eq (2, validator->attrs[3].tag_n);
 	ck_assert_int_eq (0, validator->attrs[4].tag_n);
 	ck_assert_int_eq (0, validator->attrs[5].tag_n);
+	ck_assert_int_eq (0, validator->attrs[6].tag_n);
+	ck_assert_int_eq (0, validator->attrs[7].tag_n);
+	ck_assert_int_eq (0, validator->attrs[8].tag_n);
 	ck_assert_ptr_ne (NULL, validator->attrs[0].tags);
 	ck_assert_ptr_ne (NULL, validator->attrs[1].tags);
 	ck_assert_ptr_ne (NULL, validator->attrs[2].tags);
 	ck_assert_ptr_ne (NULL, validator->attrs[3].tags);
 	ck_assert_ptr_eq (NULL, validator->attrs[4].tags);
 	ck_assert_ptr_eq (NULL, validator->attrs[5].tags);
+	ck_assert_ptr_eq (NULL, validator->attrs[6].tags);
+	ck_assert_ptr_eq (NULL, validator->attrs[7].tags);
+	ck_assert_ptr_eq (NULL, validator->attrs[8].tags);
 
 	#define STR_EQ ck_assert_str_eq
 	/* The storage order depends on the relative position of memory,
@@ -887,22 +902,31 @@ START_TEST(test_validator_deregister_no_status)
 	ck_assert_int_eq (TRUE, result);
 
 	/* test - consistency */
-	ck_assert_int_eq (5, validator->attr_n);
+	ck_assert_int_eq (8, validator->attr_n);
 	ck_assert_str_eq ("class", validator->attrs[0].name);
 	ck_assert_str_eq ("id", validator->attrs[1].name);
 	ck_assert_str_eq ("name", validator->attrs[2].name);
-	ck_assert_str_eq ("x", validator->attrs[3].name);
-	ck_assert_str_eq ("y", validator->attrs[4].name);
+	ck_assert_str_eq ("v", validator->attrs[3].name);
+	ck_assert_str_eq ("w", validator->attrs[4].name);
+	ck_assert_str_eq ("x", validator->attrs[5].name);
+	ck_assert_str_eq ("y", validator->attrs[6].name);
+	ck_assert_str_eq ("z", validator->attrs[7].name);
 	ck_assert_int_eq (2, validator->attrs[0].tag_n);
 	ck_assert_int_eq (2, validator->attrs[1].tag_n);
 	ck_assert_int_eq (2, validator->attrs[2].tag_n);
 	ck_assert_int_eq (0, validator->attrs[3].tag_n);
 	ck_assert_int_eq (0, validator->attrs[4].tag_n);
+	ck_assert_int_eq (0, validator->attrs[5].tag_n);
+	ck_assert_int_eq (0, validator->attrs[6].tag_n);
+	ck_assert_int_eq (0, validator->attrs[7].tag_n);
 	ck_assert_ptr_ne (NULL, validator->attrs[0].tags);
 	ck_assert_ptr_ne (NULL, validator->attrs[1].tags);
 	ck_assert_ptr_ne (NULL, validator->attrs[2].tags);
 	ck_assert_ptr_eq (NULL, validator->attrs[3].tags);
 	ck_assert_ptr_eq (NULL, validator->attrs[4].tags);
+	ck_assert_ptr_eq (NULL, validator->attrs[5].tags);
+	ck_assert_ptr_eq (NULL, validator->attrs[6].tags);
+	ck_assert_ptr_eq (NULL, validator->attrs[7].tags);
 
 
 	/* test - non existent attr */
@@ -921,19 +945,28 @@ START_TEST(test_validator_deregister_no_status)
 	ck_assert_int_eq (FALSE, result);
 
 	/* test - consistency */
-	ck_assert_int_eq (4, validator->attr_n);
+	ck_assert_int_eq (7, validator->attr_n);
 	ck_assert_str_eq ("class", validator->attrs[0].name);
 	ck_assert_str_eq ("id", validator->attrs[1].name);
-	ck_assert_str_eq ("x", validator->attrs[2].name);
-	ck_assert_str_eq ("y", validator->attrs[3].name);
+	ck_assert_str_eq ("v", validator->attrs[2].name);
+	ck_assert_str_eq ("w", validator->attrs[3].name);
+	ck_assert_str_eq ("x", validator->attrs[4].name);
+	ck_assert_str_eq ("y", validator->attrs[5].name);
+	ck_assert_str_eq ("z", validator->attrs[6].name);
 	ck_assert_int_eq (2, validator->attrs[0].tag_n);
 	ck_assert_int_eq (2, validator->attrs[1].tag_n);
 	ck_assert_int_eq (0, validator->attrs[2].tag_n);
 	ck_assert_int_eq (0, validator->attrs[3].tag_n);
+	ck_assert_int_eq (0, validator->attrs[4].tag_n);
+	ck_assert_int_eq (0, validator->attrs[5].tag_n);
+	ck_assert_int_eq (0, validator->attrs[6].tag_n);
 	ck_assert_ptr_ne (NULL, validator->attrs[0].tags);
 	ck_assert_ptr_ne (NULL, validator->attrs[1].tags);
 	ck_assert_ptr_eq (NULL, validator->attrs[2].tags);
 	ck_assert_ptr_eq (NULL, validator->attrs[3].tags);
+	ck_assert_ptr_eq (NULL, validator->attrs[4].tags);
+	ck_assert_ptr_eq (NULL, validator->attrs[5].tags);
+	ck_assert_ptr_eq (NULL, validator->attrs[6].tags);
 
 
 	#define STR_EQ ck_assert_str_eq
@@ -969,48 +1002,142 @@ START_TEST(test_validator_deregister_no_status)
 	ck_assert_int_eq (FALSE, result);
 
 	/* test - consistency */
-	ck_assert_int_eq (4, validator->attr_n);
+	ck_assert_int_eq (7, validator->attr_n);
 	ck_assert_str_eq ("class", validator->attrs[0].name);
 	ck_assert_str_eq ("id", validator->attrs[1].name);
-	ck_assert_str_eq ("x", validator->attrs[2].name);
-	ck_assert_str_eq ("y", validator->attrs[3].name);
+	ck_assert_str_eq ("v", validator->attrs[2].name);
+	ck_assert_str_eq ("w", validator->attrs[3].name);
+	ck_assert_str_eq ("x", validator->attrs[4].name);
+	ck_assert_str_eq ("y", validator->attrs[5].name);
+	ck_assert_str_eq ("z", validator->attrs[6].name);
 	ck_assert_int_eq (1, validator->attrs[0].tag_n);
 	ck_assert_int_eq (1, validator->attrs[1].tag_n);
 	ck_assert_int_eq (0, validator->attrs[2].tag_n);
 	ck_assert_int_eq (0, validator->attrs[3].tag_n);
+	ck_assert_int_eq (0, validator->attrs[4].tag_n);
+	ck_assert_int_eq (0, validator->attrs[5].tag_n);
+	ck_assert_int_eq (0, validator->attrs[6].tag_n);
 	ck_assert_ptr_ne (NULL, validator->attrs[0].tags);
 	ck_assert_ptr_ne (NULL, validator->attrs[1].tags);
 	ck_assert_ptr_eq (NULL, validator->attrs[2].tags);
 	ck_assert_ptr_eq (NULL, validator->attrs[3].tags);
+	ck_assert_ptr_eq (NULL, validator->attrs[4].tags);
+	ck_assert_ptr_eq (NULL, validator->attrs[5].tags);
+	ck_assert_ptr_eq (NULL, validator->attrs[6].tags);
 	ck_assert_str_eq ("body", validator->attrs[0].tags[0].name);
 	ck_assert_str_eq ("body", validator->attrs[1].tags[0].name);
 
-	/* test - global attr */
-	result = SH_Validator_deregister_attr (validator, "html", "x",
+	/* test - global attr, to local */
+	result = SH_Validator_deregister_attr (validator, "html", "v",
+	                                       NULL);
+	ck_assert_int_eq (TRUE, result);
+
+	/* test - global attr, non existent tag */
+	result = SH_Validator_deregister_attr (validator, "nav", "w",
 	                                       NULL);
 	ck_assert_int_eq (FALSE, result);
 
+	/* test - global attr, total remove */
+	result = SH_Validator_deregister_attr (validator, NULL, "w",
+	                                       NULL);
+	ck_assert_int_eq (TRUE, result);
+
+	/* test - consistency */
+	ck_assert_int_eq (6, validator->attr_n);
+	ck_assert_str_eq ("class", validator->attrs[0].name);
+	ck_assert_str_eq ("id", validator->attrs[1].name);
+	ck_assert_str_eq ("v", validator->attrs[2].name);
+	ck_assert_str_eq ("x", validator->attrs[3].name);
+	ck_assert_str_eq ("y", validator->attrs[4].name);
+	ck_assert_str_eq ("z", validator->attrs[5].name);
+	ck_assert_int_eq (1, validator->attrs[0].tag_n);
+	ck_assert_int_eq (1, validator->attrs[1].tag_n);
+	ck_assert_int_eq (1, validator->attrs[2].tag_n);
+	ck_assert_int_eq (0, validator->attrs[3].tag_n);
+	ck_assert_int_eq (0, validator->attrs[4].tag_n);
+	ck_assert_int_eq (0, validator->attrs[5].tag_n);
+	ck_assert_ptr_ne (NULL, validator->attrs[0].tags);
+	ck_assert_ptr_ne (NULL, validator->attrs[1].tags);
+	ck_assert_ptr_ne (NULL, validator->attrs[2].tags);
+	ck_assert_ptr_eq (NULL, validator->attrs[3].tags);
+	ck_assert_ptr_eq (NULL, validator->attrs[4].tags);
+	ck_assert_ptr_eq (NULL, validator->attrs[5].tags);
+	ck_assert_str_eq ("body", validator->attrs[0].tags[0].name);
+	ck_assert_str_eq ("body", validator->attrs[1].tags[0].name);
+	ck_assert_str_eq ("body", validator->attrs[2].tags[0].name);
+
+	/* test - global attr, auto remove */
+	result = SH_Validator_deregister_tag (validator, "html", NULL);
+	ck_assert_int_eq (TRUE, result);
+
+	result = SH_Validator_deregister_attr (validator, "body", "x",
+	                                       NULL);
+	ck_assert_int_eq (TRUE, result);
+
 	/* test - global attr, non existent tag */
-	result = SH_Validator_deregister_attr (validator, "nav", "x",
+	result = SH_Validator_deregister_attr (validator, "nav", "y",
 	                                       NULL);
 	ck_assert_int_eq (FALSE, result);
 
 	/* test - global attr, total remove */
-	result = SH_Validator_deregister_attr (validator, NULL, "x",
+	result = SH_Validator_deregister_attr (validator, NULL, "y",
 	                                       NULL);
 	ck_assert_int_eq (TRUE, result);
 
 	/* test - consistency */
-	ck_assert_int_eq (3, validator->attr_n);
+	ck_assert_int_eq (4, validator->attr_n);
+	ck_assert_str_eq ("class", validator->attrs[0].name);
+	ck_assert_str_eq ("id", validator->attrs[1].name);
+	ck_assert_str_eq ("v", validator->attrs[2].name);
+	ck_assert_str_eq ("z", validator->attrs[3].name);
+	ck_assert_int_eq (1, validator->attrs[0].tag_n);
+	ck_assert_int_eq (1, validator->attrs[1].tag_n);
+	ck_assert_int_eq (1, validator->attrs[2].tag_n);
+	ck_assert_int_eq (0, validator->attrs[3].tag_n);
+	ck_assert_ptr_ne (NULL, validator->attrs[0].tags);
+	ck_assert_ptr_ne (NULL, validator->attrs[1].tags);
+	ck_assert_ptr_ne (NULL, validator->attrs[2].tags);
+	ck_assert_ptr_eq (NULL, validator->attrs[3].tags);
+	ck_assert_str_eq ("body", validator->attrs[0].tags[0].name);
+	ck_assert_str_eq ("body", validator->attrs[1].tags[0].name);
+	ck_assert_str_eq ("body", validator->attrs[2].tags[0].name);
+
+	/* test - last tag, auto remove local attrs */
+	result = SH_Validator_deregister_tag (validator, "body", NULL);
+	ck_assert_int_eq (TRUE, result);
+
+	/* test - consistency */
+	ck_assert_int_eq (1, validator->attr_n);
+	ck_assert_str_eq ("z", validator->attrs[0].name);
+	ck_assert_int_eq (0, validator->attrs[0].tag_n);
+	ck_assert_ptr_eq (NULL, validator->attrs[0].tags);
+
+	/* undo auto remove */
+	#define REGISTER SH_Validator_register_attr
+	result = REGISTER (validator, "body", "id", NULL);
+	ck_assert_int_eq (TRUE, result);
+	result = REGISTER (validator, "body", "class", NULL);
+	ck_assert_int_eq (TRUE, result);
+	result = REGISTER (validator, NULL, "v", NULL);
+	ck_assert_int_eq (TRUE, result);
+	result = REGISTER (validator, NULL, "z", NULL);
+	ck_assert_int_eq (TRUE, result);
+	#undef REGISTER
+
+	/* test - consistency */
+	ck_assert_int_eq (4, validator->attr_n);
 	ck_assert_str_eq ("class", validator->attrs[0].name);
 	ck_assert_str_eq ("id", validator->attrs[1].name);
-	ck_assert_str_eq ("y", validator->attrs[2].name);
+	ck_assert_str_eq ("v", validator->attrs[2].name);
+	ck_assert_str_eq ("z", validator->attrs[3].name);
 	ck_assert_int_eq (1, validator->attrs[0].tag_n);
 	ck_assert_int_eq (1, validator->attrs[1].tag_n);
 	ck_assert_int_eq (0, validator->attrs[2].tag_n);
+	ck_assert_int_eq (0, validator->attrs[3].tag_n);
 	ck_assert_ptr_ne (NULL, validator->attrs[0].tags);
 	ck_assert_ptr_ne (NULL, validator->attrs[1].tags);
 	ck_assert_ptr_eq (NULL, validator->attrs[2].tags);
+	ck_assert_ptr_eq (NULL, validator->attrs[3].tags);
 	ck_assert_str_eq ("body", validator->attrs[0].tags[0].name);
 	ck_assert_str_eq ("body", validator->attrs[1].tags[0].name);
 
@@ -1055,32 +1182,47 @@ START_TEST(test_validator_deregister_with_status)
 	ck_assert_int_eq (TRUE, result);
 	result = REGISTER (validator, "body", "class", NULL);
 	ck_assert_int_eq (TRUE, result);
+	result = REGISTER (validator, NULL, "v", NULL);
+	ck_assert_int_eq (TRUE, result);
+	result = REGISTER (validator, NULL, "w", NULL);
+	ck_assert_int_eq (TRUE, result);
 	result = REGISTER (validator, NULL, "x", NULL);
 	ck_assert_int_eq (TRUE, result);
 	result = REGISTER (validator, NULL, "y", NULL);
 	ck_assert_int_eq (TRUE, result);
+	result = REGISTER (validator, NULL, "z", NULL);
+	ck_assert_int_eq (TRUE, result);
 	#undef REGISTER
 
 	/* test - consistency */
-	ck_assert_int_eq (6, validator->attr_n);
+	ck_assert_int_eq (9, validator->attr_n);
 	ck_assert_str_eq ("attr", validator->attrs[0].name);
 	ck_assert_str_eq ("class", validator->attrs[1].name);
 	ck_assert_str_eq ("id", validator->attrs[2].name);
 	ck_assert_str_eq ("name", validator->attrs[3].name);
-	ck_assert_str_eq ("x", validator->attrs[4].name);
-	ck_assert_str_eq ("y", validator->attrs[5].name);
+	ck_assert_str_eq ("v", validator->attrs[4].name);
+	ck_assert_str_eq ("w", validator->attrs[5].name);
+	ck_assert_str_eq ("x", validator->attrs[6].name);
+	ck_assert_str_eq ("y", validator->attrs[7].name);
+	ck_assert_str_eq ("z", validator->attrs[8].name);
 	ck_assert_int_eq (2, validator->attrs[0].tag_n);
 	ck_assert_int_eq (2, validator->attrs[1].tag_n);
 	ck_assert_int_eq (2, validator->attrs[2].tag_n);
 	ck_assert_int_eq (2, validator->attrs[3].tag_n);
 	ck_assert_int_eq (0, validator->attrs[4].tag_n);
 	ck_assert_int_eq (0, validator->attrs[5].tag_n);
+	ck_assert_int_eq (0, validator->attrs[6].tag_n);
+	ck_assert_int_eq (0, validator->attrs[7].tag_n);
+	ck_assert_int_eq (0, validator->attrs[8].tag_n);
 	ck_assert_ptr_ne (NULL, validator->attrs[0].tags);
 	ck_assert_ptr_ne (NULL, validator->attrs[1].tags);
 	ck_assert_ptr_ne (NULL, validator->attrs[2].tags);
 	ck_assert_ptr_ne (NULL, validator->attrs[3].tags);
 	ck_assert_ptr_eq (NULL, validator->attrs[4].tags);
 	ck_assert_ptr_eq (NULL, validator->attrs[5].tags);
+	ck_assert_ptr_eq (NULL, validator->attrs[6].tags);
+	ck_assert_ptr_eq (NULL, validator->attrs[7].tags);
+	ck_assert_ptr_eq (NULL, validator->attrs[8].tags);
 
 	#define STR_EQ ck_assert_str_eq
 	/* The storage order depends on the relative position of memory,
@@ -1134,22 +1276,31 @@ START_TEST(test_validator_deregister_with_status)
 	ck_assert_int_eq (SUCCESS, status.status);
 
 	/* test - consistency */
-	ck_assert_int_eq (5, validator->attr_n);
+	ck_assert_int_eq (8, validator->attr_n);
 	ck_assert_str_eq ("class", validator->attrs[0].name);
 	ck_assert_str_eq ("id", validator->attrs[1].name);
 	ck_assert_str_eq ("name", validator->attrs[2].name);
-	ck_assert_str_eq ("x", validator->attrs[3].name);
-	ck_assert_str_eq ("y", validator->attrs[4].name);
+	ck_assert_str_eq ("v", validator->attrs[3].name);
+	ck_assert_str_eq ("w", validator->attrs[4].name);
+	ck_assert_str_eq ("x", validator->attrs[5].name);
+	ck_assert_str_eq ("y", validator->attrs[6].name);
+	ck_assert_str_eq ("z", validator->attrs[7].name);
 	ck_assert_int_eq (2, validator->attrs[0].tag_n);
 	ck_assert_int_eq (2, validator->attrs[1].tag_n);
 	ck_assert_int_eq (2, validator->attrs[2].tag_n);
 	ck_assert_int_eq (0, validator->attrs[3].tag_n);
 	ck_assert_int_eq (0, validator->attrs[4].tag_n);
+	ck_assert_int_eq (0, validator->attrs[5].tag_n);
+	ck_assert_int_eq (0, validator->attrs[6].tag_n);
+	ck_assert_int_eq (0, validator->attrs[7].tag_n);
 	ck_assert_ptr_ne (NULL, validator->attrs[0].tags);
 	ck_assert_ptr_ne (NULL, validator->attrs[1].tags);
 	ck_assert_ptr_ne (NULL, validator->attrs[2].tags);
 	ck_assert_ptr_eq (NULL, validator->attrs[3].tags);
 	ck_assert_ptr_eq (NULL, validator->attrs[4].tags);
+	ck_assert_ptr_eq (NULL, validator->attrs[5].tags);
+	ck_assert_ptr_eq (NULL, validator->attrs[6].tags);
+	ck_assert_ptr_eq (NULL, validator->attrs[7].tags);
 
 
 	/* test - non existent attr */
@@ -1174,19 +1325,28 @@ START_TEST(test_validator_deregister_with_status)
 	ck_assert_int_eq (E_VALUE, status.status);
 
 	/* test - consistency */
-	ck_assert_int_eq (4, validator->attr_n);
+	ck_assert_int_eq (7, validator->attr_n);
 	ck_assert_str_eq ("class", validator->attrs[0].name);
 	ck_assert_str_eq ("id", validator->attrs[1].name);
-	ck_assert_str_eq ("x", validator->attrs[2].name);
-	ck_assert_str_eq ("y", validator->attrs[3].name);
+	ck_assert_str_eq ("v", validator->attrs[2].name);
+	ck_assert_str_eq ("w", validator->attrs[3].name);
+	ck_assert_str_eq ("x", validator->attrs[4].name);
+	ck_assert_str_eq ("y", validator->attrs[5].name);
+	ck_assert_str_eq ("z", validator->attrs[6].name);
 	ck_assert_int_eq (2, validator->attrs[0].tag_n);
 	ck_assert_int_eq (2, validator->attrs[1].tag_n);
 	ck_assert_int_eq (0, validator->attrs[2].tag_n);
 	ck_assert_int_eq (0, validator->attrs[3].tag_n);
+	ck_assert_int_eq (0, validator->attrs[4].tag_n);
+	ck_assert_int_eq (0, validator->attrs[5].tag_n);
+	ck_assert_int_eq (0, validator->attrs[6].tag_n);
 	ck_assert_ptr_ne (NULL, validator->attrs[0].tags);
 	ck_assert_ptr_ne (NULL, validator->attrs[1].tags);
 	ck_assert_ptr_eq (NULL, validator->attrs[2].tags);
 	ck_assert_ptr_eq (NULL, validator->attrs[3].tags);
+	ck_assert_ptr_eq (NULL, validator->attrs[4].tags);
+	ck_assert_ptr_eq (NULL, validator->attrs[5].tags);
+	ck_assert_ptr_eq (NULL, validator->attrs[6].tags);
 
 
 	#define STR_EQ ck_assert_str_eq
@@ -1226,54 +1386,154 @@ START_TEST(test_validator_deregister_with_status)
 	ck_assert_int_eq (E_VALUE, status.status);
 
 	/* test - consistency */
-	ck_assert_int_eq (4, validator->attr_n);
+	ck_assert_int_eq (7, validator->attr_n);
 	ck_assert_str_eq ("class", validator->attrs[0].name);
 	ck_assert_str_eq ("id", validator->attrs[1].name);
-	ck_assert_str_eq ("x", validator->attrs[2].name);
-	ck_assert_str_eq ("y", validator->attrs[3].name);
+	ck_assert_str_eq ("v", validator->attrs[2].name);
+	ck_assert_str_eq ("w", validator->attrs[3].name);
+	ck_assert_str_eq ("x", validator->attrs[4].name);
+	ck_assert_str_eq ("y", validator->attrs[5].name);
+	ck_assert_str_eq ("z", validator->attrs[6].name);
 	ck_assert_int_eq (1, validator->attrs[0].tag_n);
 	ck_assert_int_eq (1, validator->attrs[1].tag_n);
 	ck_assert_int_eq (0, validator->attrs[2].tag_n);
 	ck_assert_int_eq (0, validator->attrs[3].tag_n);
+	ck_assert_int_eq (0, validator->attrs[4].tag_n);
+	ck_assert_int_eq (0, validator->attrs[4].tag_n);
+	ck_assert_int_eq (0, validator->attrs[5].tag_n);
 	ck_assert_ptr_ne (NULL, validator->attrs[0].tags);
 	ck_assert_ptr_ne (NULL, validator->attrs[1].tags);
 	ck_assert_ptr_eq (NULL, validator->attrs[2].tags);
 	ck_assert_ptr_eq (NULL, validator->attrs[3].tags);
+	ck_assert_ptr_eq (NULL, validator->attrs[4].tags);
+	ck_assert_ptr_eq (NULL, validator->attrs[5].tags);
+	ck_assert_ptr_eq (NULL, validator->attrs[6].tags);
 	ck_assert_str_eq ("body", validator->attrs[0].tags[0].name);
 	ck_assert_str_eq ("body", validator->attrs[1].tags[0].name);
 
-	/* test - global attr */
+	/* test - global attr, to local */
 	_status_preinit (status);
-	result = SH_Validator_deregister_attr (validator, "html", "x",
+	result = SH_Validator_deregister_attr (validator, "html", "v",
+	                                       &status);
+	ck_assert_int_eq (TRUE, result);
+	ck_assert_int_eq (SUCCESS, status.status);
+
+	/* test - global attr, non existent tag */
+	_status_preinit (status);
+	result = SH_Validator_deregister_attr (validator, "nav", "w",
 	                                       &status);
 	ck_assert_int_eq (FALSE, result);
-	ck_assert_int_eq (E_STATE, status.status);
+	ck_assert_int_eq (E_VALUE, status.status);
+
+	/* test - global attr, total remove */
+	_status_preinit (status);
+	result = SH_Validator_deregister_attr (validator, NULL, "w",
+	                                       &status);
+	ck_assert_int_eq (TRUE, result);
+	ck_assert_int_eq (SUCCESS, status.status);
+
+	/* test - consistency */
+	ck_assert_int_eq (6, validator->attr_n);
+	ck_assert_str_eq ("class", validator->attrs[0].name);
+	ck_assert_str_eq ("id", validator->attrs[1].name);
+	ck_assert_str_eq ("v", validator->attrs[2].name);
+	ck_assert_str_eq ("x", validator->attrs[3].name);
+	ck_assert_str_eq ("y", validator->attrs[4].name);
+	ck_assert_str_eq ("z", validator->attrs[5].name);
+	ck_assert_int_eq (1, validator->attrs[0].tag_n);
+	ck_assert_int_eq (1, validator->attrs[1].tag_n);
+	ck_assert_int_eq (1, validator->attrs[2].tag_n);
+	ck_assert_int_eq (0, validator->attrs[3].tag_n);
+	ck_assert_int_eq (0, validator->attrs[4].tag_n);
+	ck_assert_int_eq (0, validator->attrs[5].tag_n);
+	ck_assert_ptr_ne (NULL, validator->attrs[0].tags);
+	ck_assert_ptr_ne (NULL, validator->attrs[1].tags);
+	ck_assert_ptr_ne (NULL, validator->attrs[2].tags);
+	ck_assert_ptr_eq (NULL, validator->attrs[3].tags);
+	ck_assert_ptr_eq (NULL, validator->attrs[4].tags);
+	ck_assert_ptr_eq (NULL, validator->attrs[5].tags);
+	ck_assert_str_eq ("body", validator->attrs[0].tags[0].name);
+	ck_assert_str_eq ("body", validator->attrs[1].tags[0].name);
+	ck_assert_str_eq ("body", validator->attrs[2].tags[0].name);
+
+	/* test - global attr, auto remove */
+	result = SH_Validator_deregister_tag (validator, "html", NULL);
+	ck_assert_int_eq (TRUE, result);
+
+	_status_preinit (status);
+	result = SH_Validator_deregister_attr (validator, "body", "x",
+	                                       &status);
+	ck_assert_int_eq (TRUE, result);
+	ck_assert_int_eq (SUCCESS, status.status);
 
 	/* test - global attr, non existent tag */
 	_status_preinit (status);
-	result = SH_Validator_deregister_attr (validator, "nav", "x",
+	result = SH_Validator_deregister_attr (validator, "nav", "y",
 	                                       &status);
 	ck_assert_int_eq (FALSE, result);
 	ck_assert_int_eq (E_VALUE, status.status);
 
 	/* test - global attr, total remove */
 	_status_preinit (status);
-	result = SH_Validator_deregister_attr (validator, NULL, "x",
+	result = SH_Validator_deregister_attr (validator, NULL, "y",
 	                                       &status);
 	ck_assert_int_eq (TRUE, result);
 	ck_assert_int_eq (SUCCESS, status.status);
 
 	/* test - consistency */
-	ck_assert_int_eq (3, validator->attr_n);
+	ck_assert_int_eq (4, validator->attr_n);
+	ck_assert_str_eq ("class", validator->attrs[0].name);
+	ck_assert_str_eq ("id", validator->attrs[1].name);
+	ck_assert_str_eq ("v", validator->attrs[2].name);
+	ck_assert_str_eq ("z", validator->attrs[3].name);
+	ck_assert_int_eq (1, validator->attrs[0].tag_n);
+	ck_assert_int_eq (1, validator->attrs[1].tag_n);
+	ck_assert_int_eq (1, validator->attrs[2].tag_n);
+	ck_assert_int_eq (0, validator->attrs[3].tag_n);
+	ck_assert_ptr_ne (NULL, validator->attrs[0].tags);
+	ck_assert_ptr_ne (NULL, validator->attrs[1].tags);
+	ck_assert_ptr_ne (NULL, validator->attrs[2].tags);
+	ck_assert_ptr_eq (NULL, validator->attrs[3].tags);
+	ck_assert_str_eq ("body", validator->attrs[0].tags[0].name);
+	ck_assert_str_eq ("body", validator->attrs[1].tags[0].name);
+	ck_assert_str_eq ("body", validator->attrs[2].tags[0].name);
+
+	/* test - last tag, auto remove local attrs */
+	result = SH_Validator_deregister_tag (validator, "body", NULL);
+	ck_assert_int_eq (TRUE, result);
+
+	/* test - consistency */
+	ck_assert_int_eq (1, validator->attr_n);
+	ck_assert_str_eq ("z", validator->attrs[0].name);
+	ck_assert_int_eq (0, validator->attrs[0].tag_n);
+	ck_assert_ptr_eq (NULL, validator->attrs[0].tags);
+
+	/* undo auto remove */
+	#define REGISTER SH_Validator_register_attr
+	result = REGISTER (validator, "body", "id", NULL);
+	ck_assert_int_eq (TRUE, result);
+	result = REGISTER (validator, "body", "class", NULL);
+	ck_assert_int_eq (TRUE, result);
+	result = REGISTER (validator, NULL, "v", NULL);
+	ck_assert_int_eq (TRUE, result);
+	result = REGISTER (validator, NULL, "z", NULL);
+	ck_assert_int_eq (TRUE, result);
+	#undef REGISTER
+
+	/* test - consistency */
+	ck_assert_int_eq (4, validator->attr_n);
 	ck_assert_str_eq ("class", validator->attrs[0].name);
 	ck_assert_str_eq ("id", validator->attrs[1].name);
-	ck_assert_str_eq ("y", validator->attrs[2].name);
+	ck_assert_str_eq ("v", validator->attrs[2].name);
+	ck_assert_str_eq ("z", validator->attrs[3].name);
 	ck_assert_int_eq (1, validator->attrs[0].tag_n);
 	ck_assert_int_eq (1, validator->attrs[1].tag_n);
 	ck_assert_int_eq (0, validator->attrs[2].tag_n);
+	ck_assert_int_eq (0, validator->attrs[3].tag_n);
 	ck_assert_ptr_ne (NULL, validator->attrs[0].tags);
 	ck_assert_ptr_ne (NULL, validator->attrs[1].tags);
 	ck_assert_ptr_eq (NULL, validator->attrs[2].tags);
+	ck_assert_ptr_eq (NULL, validator->attrs[3].tags);
 	ck_assert_str_eq ("body", validator->attrs[0].tags[0].name);
 	ck_assert_str_eq ("body", validator->attrs[1].tags[0].name);
 
diff --git a/todo.txt b/todo.txt
index dfdca0521cbf71a4c7c3b413aab8d33a5e789ee1..828f94eacb2adcbb9c0dd9151159a0495be74e69 100644
--- a/todo.txt
+++ b/todo.txt
@@ -20,7 +20,6 @@ Fragment:
 
 Validator:
 - check for global attributes
-- change global to local attribute
 - add tag types
-- fix cursed behaviour, when removing fails
+- fix cursed behaviour, when removing fails (remove_tag_for_all_attrs)
 - initialize from file