Index: cpp/frams/genetics/f1/conv_f1.cpp
===================================================================
--- cpp/frams/genetics/f1/conv_f1.cpp	(revision 346)
+++ cpp/frams/genetics/f1/conv_f1.cpp	(revision 348)
@@ -102,5 +102,5 @@
 SString GenoConv_f1::convert(SString &i,MultiMap *map)
 {
-const char* g=(const char*)i;
+const char* g=i.c_str();
 Builder builder(g,map?1:0);
 builder.model.open();
@@ -403,10 +403,10 @@
 					lastNeuroClassParam();
 					//special handling: muscle properties (can be overwritten by subsequent property assignments)
-					if (!strcmp(cls->getName(),"|"))
+					if (!strcmp(cls->getName().c_str(),"|"))
 						{
 						neuro_cls_param->setDoubleById("p",lastjoint_muscle_power);
 						neuro_cls_param->setDoubleById("r",props.bendrange);
 						}
-					else if (!strcmp(cls->getName(),"@"))
+					else if (!strcmp(cls->getName().c_str(),"@"))
 						{
 						neuro_cls_param->setDoubleById("p",lastjoint_muscle_power);
@@ -485,5 +485,5 @@
 	SString name(begin,colon-begin);
 	SString value(colon+1,end-(colon+1));
-	addClassParam(name,value);
-	}
-}
+	addClassParam(name.c_str(),value.c_str());
+	}
+}
Index: cpp/frams/genetics/f4/f4_general.cpp
===================================================================
--- cpp/frams/genetics/f4/f4_general.cpp	(revision 346)
+++ cpp/frams/genetics/f4/f4_general.cpp	(revision 348)
@@ -714,5 +714,5 @@
 	// transform geno from string to nodes
 	f4rootnode = new f4_node();
-	res = f4_processrec((const char*)genome, (unsigned)0, f4rootnode);
+	res = f4_processrec(genome.c_str(), (unsigned)0, f4rootnode);
 	if ((res < 0) || (1 != f4rootnode->childCount()))
 	{
@@ -1197,5 +1197,5 @@
 		buf = (char*)realloc(buf, len + 1);
 	}
-	strcpy(buf, (const char*)out);
+	strcpy(buf, out.c_str());
 }
 
Index: cpp/frams/genetics/f9/oper_f9.cpp
===================================================================
--- cpp/frams/genetics/f9/oper_f9.cpp	(revision 346)
+++ cpp/frams/genetics/f9/oper_f9.cpp	(revision 348)
@@ -42,5 +42,5 @@
 		if (strchr(turtle_commands_f9, gene[i])) validated += gene[i];  //validated contains only turtle_commands_f9
 	free(gene);
-	gene = strdup(validated); //reallocate
+	gene = strdup(validated.c_str()); //reallocate
 	return GENOPER_OK;
 }
@@ -84,5 +84,5 @@
 		}
 		free(gene);
-		gene = strdup(newgeno); //reallocate
+		gene = strdup(newgeno.c_str()); //reallocate
 	}
 
Index: cpp/frams/genetics/fF/conv_fF.cpp
===================================================================
--- cpp/frams/genetics/fF/conv_fF.cpp	(revision 346)
+++ cpp/frams/genetics/fF/conv_fF.cpp	(revision 348)
@@ -39,5 +39,5 @@
 {
 	fF_growth_params gp;
-	if (!gp.load(in)) //invalid input genotype?
+	if (!gp.load(in.c_str())) //invalid input genotype?
 		return ""; //so we return an invalid f0 genotype
 
Index: cpp/frams/genetics/fF/fF_genotype.h
===================================================================
--- cpp/frams/genetics/fF/fF_genotype.h	(revision 346)
+++ cpp/frams/genetics/fF/fF_genotype.h	(revision 348)
@@ -43,5 +43,5 @@
 		SString tmp;
 		param.save2(tmp, NULL/*object containing default values for comparison*/, false/*add CR*/, false/*force field names*/);
-		return string((const char*)tmp);
+		return string(tmp.c_str());
 	}
 };
Index: cpp/frams/genetics/fT/oper_fTest.cpp
===================================================================
--- cpp/frams/genetics/fT/oper_fTest.cpp	(revision 346)
+++ cpp/frams/genetics/fT/oper_fTest.cpp	(revision 348)
@@ -77,5 +77,5 @@
 		if (strchr("ATGC", gene[i])) validated += gene[i];  //validated contains only ATGC
 	free(gene);
-	gene = strdup(validated); //reallocate
+	gene = strdup(validated.c_str()); //reallocate
 	return GENOPER_OK;
 }
Index: cpp/frams/genetics/genman.cpp
===================================================================
--- cpp/frams/genetics/genman.cpp	(revision 346)
+++ cpp/frams/genetics/genman.cpp	(revision 348)
@@ -199,5 +199,5 @@
 {
 	SString ggs=g.getGene();
-	const char *gg = ggs;
+	const char *gg = ggs.c_str();
 	GenoOperators *gf = getOper_f(g.getFormat());
 	int check1;
@@ -237,5 +237,5 @@
 	if (gf == NULL)
 		return Geno(SString::empty(), -1, SString::empty(), SString::sprintf("GENOPER_NOOPER: Validate(): don't know how to handle genetic format %c", format));
-	char *g2 = strdup(geny.getGene()); //copy for validation
+	char *g2 = strdup(geny.getGene().c_str()); //copy for validation
 	int res = gf->validate(g2);
 	SString sg2 = g2;
@@ -263,5 +263,5 @@
 	while (!ok)
 	{
-		char *gn = strdup(gv.getGene()); //copy for mutation
+		char *gn = strdup(gv.getGene().c_str()); //copy for mutation
 		chg = 0;
 		if (gf->mutate(gn, chg, method) == GENOPER_OK)
@@ -284,14 +284,14 @@
 		if (!ok && (count - pcount > 100))
 		{
-			FMprintf("GenMan", "Mutate", 2, "Tried 100x and failed: %s", (const char*)g.getGene());
+			FMprintf("GenMan", "Mutate", 2, "Tried 100x and failed: %s", g.getGene().c_str());
 			return Geno("", -1, "", "GENOPER_OPFAIL: Mutate() tried 100x and failed");
 		}
 	}
 	mutchg += chg;
-	if (history) saveLink((const char*)g.getGene(), "", (const char*)gv.getGene(), chg);
+	if (history) saveLink(g.getGene().c_str(), "", gv.getGene().c_str(), chg);
 	SString mutinfo;
-	if (extmutinfo == 0) mutinfo = SString::sprintf("%.2f%% mutation of '%s'", 100 * chg, (const char*)g.getName()); else
-		if (extmutinfo == 1) mutinfo = SString::sprintf("%.2f%% mutation(%d) of '%s'", 100 * chg, method, (const char*)g.getName()); else
-			mutinfo = SString::sprintf("%.2f%% mutation(%s) of '%s'", 100 * chg, gf->mutation_method_names ? gf->mutation_method_names[method] : "unspecified method name", (const char*)g.getName());
+	if (extmutinfo == 0) mutinfo = SString::sprintf("%.2f%% mutation of '%s'", 100 * chg, g.getName().c_str()); else
+		if (extmutinfo == 1) mutinfo = SString::sprintf("%.2f%% mutation(%d) of '%s'", 100 * chg, method, g.getName().c_str()); else
+			mutinfo = SString::sprintf("%.2f%% mutation(%s) of '%s'", 100 * chg, gf->mutation_method_names ? gf->mutation_method_names[method] : "unspecified method name", g.getName().c_str());
 	gv.setComment(mutinfo);
 	return gv;
@@ -324,6 +324,6 @@
 	{
 		float chg1, chg2;
-		char *g1n = strdup(g1.getGene()); //copy for crossover
-		char *g2n = strdup(g2.getGene()); //copy for crossover
+		char *g1n = strdup(g1.getGene().c_str()); //copy for crossover
+		char *g2n = strdup(g2.getGene().c_str()); //copy for crossover
 		chg1 = chg2 = 0;
 		if (gf->crossOver(g1n, g2n, chg1, chg2) == GENOPER_OK)
@@ -351,5 +351,5 @@
 		if (!ok && (count - pcount > 100))
 		{
-			FMprintf("GenMan", "CrossOver", 2, "Tried 100x and failed: %s and %s", (const char*)g1.getGene(), (const char*)g2.getGene());
+			FMprintf("GenMan", "CrossOver", 2, "Tried 100x and failed: %s and %s", g1.getGene().c_str(), g2.getGene().c_str());
 			return Geno("", -1, "", "GENOPER_OPFAIL: CrossOver() tried 100x and failed");
 		}
@@ -357,7 +357,7 @@
 	// result in g1v
 	xochg += chg;
-	if (history) saveLink((const char*)g1.getGene(), (const char*)g2.getGene(), (const char*)g1v.getGene(), chg);
+	if (history) saveLink(g1.getGene().c_str(), g2.getGene().c_str(), g1v.getGene().c_str(), chg);
 	SString xoinfo = SString::sprintf("Crossing over of '%s' (%.2f%%) and '%s' (%.2f%%)",
-		(const char*)g1.getName(), 100 * chg, (const char*)g2.getName(), 100 * (1 - chg));
+		g1.getName().c_str(), 100 * chg, g2.getName().c_str(), 100 * (1 - chg));
 	g1v.setComment(xoinfo);
 	return g1v;
@@ -369,5 +369,5 @@
 	if (format != g2.getFormat()) return GENOPER_NOOPER;
 	GenoOperators *gf = getOper_f(format);
-	if (!gf) return GENOPER_NOOPER; else return gf->similarity(g1.getGene(), g2.getGene());
+	if (!gf) return GENOPER_NOOPER; else return gf->similarity(g1.getGene().c_str(), g2.getGene().c_str());
 }
 
@@ -378,5 +378,5 @@
 	GenoOperators *gf = getOper_f(G.getFormat());
 	if (!gf) return GENSTYLE_CS(0, 0); //black & valid
-	else return gf->style(G.getGene(), pos);
+	else return gf->style(G.getGene().c_str(), pos);
 }
 
@@ -391,5 +391,5 @@
 		if (posmapped == -1) styletab[pos] = GENSTYLE_COMMENT;
 		else if (!gf) styletab[pos] = GENSTYLE_CS(0, 0); //black & valid
-		else styletab[pos] = gf->style(geny, posmapped);
+		else styletab[pos] = gf->style(geny.c_str(), posmapped);
 	}
 }
@@ -448,10 +448,10 @@
 void GenMan::p_htmlize(ExtValue *args, ExtValue *ret)
 {
-	ret->setString(HTMLize(args->getString()));
+	ret->setString(HTMLize(args->getString().c_str()));
 }
 
 void GenMan::p_htmlizeshort(ExtValue *args, ExtValue *ret)
 {
-	ret->setString(HTMLizeShort(args->getString()));
+	ret->setString(HTMLizeShort(args->getString().c_str()));
 }
 
Index: cpp/frams/genetics/geno.cpp
===================================================================
--- cpp/frams/genetics/geno.cpp	(revision 346)
+++ cpp/frams/genetics/geno.cpp	(revision 348)
@@ -7,9 +7,14 @@
 #include <frams/model/model.h>
 
-GenoConvManager *Geno::converters = NULL;
-
-THREAD_LOCAL_DEF(Geno::Validators, geno_validators);
-
-Geno::Validators& Geno::getValidators() {return tlsGetRef(geno_validators);}
+THREAD_LOCAL_DEF_PTR(Geno::Validators, geno_validators);
+THREAD_LOCAL_DEF_PTR(GenoConvManager, geno_converters);
+
+Geno::Validators* Geno::getValidators() {return tlsGetPtr(geno_validators);}
+GenoConvManager* Geno::getConverters() {return tlsGetPtr(geno_converters);}
+
+Geno::Validators* Geno::useValidators(Validators* val)
+{return tlsSetPtr(geno_validators,val);}
+GenoConvManager* Geno::useConverters(GenoConvManager* gcm)
+{return tlsSetPtr(geno_converters,gcm);}
 
 void Geno::init(const SString& genstring, char genformat, const SString& genname, const SString& comment)
@@ -78,5 +83,5 @@
 	if (!name.len()) name = genname;
 	if (!txt.len()) txt = comment;
-	multiline = (strchr((const char*)gen, '\n') != 0);
+	multiline = (strchr(gen.c_str(), '\n') != 0);
 	// mapoutshift...?
 }
@@ -237,8 +242,11 @@
 	if (isvalid >= 0) return;
 	if (gen.len() == 0) { isvalid = 0; return; }
-	Validators& vals=getValidators();
-	FOREACH(GenoValidator*, v, vals)
+	Validators* vals=getValidators();
+	if (vals!=NULL)
+		{
+	FOREACH(GenoValidator*, v, (*vals))
 		if ((isvalid = v->testGenoValidity(*this)) >= 0)
 			return;
+		}
 	isvalid = 0;
 	FMprintf("Geno", "validate", FMLV_WARN, "Wrong configuration? No genotype validators defined for genetic format f%c.", format);
@@ -255,4 +263,5 @@
 	if (otherformat == getFormat()) { if (converter_missing) *converter_missing = false; return *this; }
 #ifndef NO_GENOCONVMANAGER
+	GenoConvManager *converters=getConverters();
 	if (converters)
 	{
Index: cpp/frams/genetics/geno.h
===================================================================
--- cpp/frams/genetics/geno.h	(revision 346)
+++ cpp/frams/genetics/geno.h	(revision 348)
@@ -118,11 +118,9 @@
 
 	// managing global Geno-related objects (used for validation and conversion)
-	static Validators& getValidators();
-	static void addValidator(GenoValidator* gv,int at_position=9999) { getValidators().insert(at_position,gv); }
-	static void removeValidator(GenoValidator* gv) { getValidators() -= gv; }
-	static void useConverters(GenoConvManager& gcm) { converters = &gcm; }
-	static GenoConvManager &getConverters() { return *converters; }
-protected:
-	static GenoConvManager *converters;
+	static Validators* useValidators(Validators* val);
+	static Validators* getValidators();
+
+	static GenoConvManager* useConverters(GenoConvManager* gcm);
+	static GenoConvManager* getConverters();
 };
 
Index: cpp/frams/genetics/oper_fx.cpp
===================================================================
--- cpp/frams/genetics/oper_fx.cpp	(revision 346)
+++ cpp/frams/genetics/oper_fx.cpp	(revision 348)
@@ -192,5 +192,5 @@
 	for (int i = 0; i<Neuro::getClassCount(); i++)
 	{
-		const char *n = Neuro::getClass(i)->name;
+		const char *n = Neuro::getClass(i)->name.c_str();
 		int l = (int)strlen(n);
 		if (len >= l && l>Len && (strncmp(s, n, l) == 0)) { I = Neuro::getClass(i); Len = l; }
Index: cpp/frams/genetics/preconfigured.h
===================================================================
--- cpp/frams/genetics/preconfigured.h	(revision 346)
+++ cpp/frams/genetics/preconfigured.h	(revision 348)
@@ -18,4 +18,5 @@
 DefaultGenoConvManager gcm;
 GenMan genman;
+Geno::Validators validators;
 ModelGenoValidator model_validator; //validation through conversion
 
@@ -23,24 +24,11 @@
 	{
 	gcm.addDefaultConverters(); //without converters, the application would only handle "format 0" genotypes
-	Geno::useConverters(gcm);
+	Geno::useConverters(&gcm);
 
-	Geno::addValidator(&genman); //primary validation: use the extended validity checking (through dedicated genetic operators)
-	Geno::addValidator(&model_validator); //secondary validation: this simple validator handles all cases when there is no dedicated genetic validation operator, but a converter for a particular format is available. Converters may be less strict in detecting invalid genotypes but using them and checking whether they produced a valid f0 genotype is also some way to tell whether the initial genotype was valid. Otherwise, without dedicated genetic validation operator, we would have no validity check at all.
-	}
-};
-
-/** Initialization procedure for applications adding their own validators */
-class PreconfiguredGenetics_NoValidators
-{
-  public:
-DefaultGenoConvManager gcm;
-
-PreconfiguredGenetics_NoValidators()
-	{
-	gcm.addDefaultConverters(); //without converters, the application would only handle "format 0" genotypes
-	Geno::useConverters(gcm);
+	Geno::useValidators(&validators);
+	validators+=&genman; //primary validation: use the extended validity checking (through dedicated genetic operators)
+	validators+=&model_validator; //secondary validation: this simple validator handles all cases when there is no dedicated genetic validation operator, but a converter for a particular format is available. Converters may be less strict in detecting invalid genotypes but using them and checking whether they produced a valid f0 genotype is also some way to tell whether the initial genotype was valid. Otherwise, without dedicated genetic validation operator, we would have no validity check at all.
 	}
 };
 
 #endif
-
