Index: cpp/common/threads.h
===================================================================
--- cpp/common/threads.h	(revision 347)
+++ cpp/common/threads.h	(revision 348)
@@ -90,5 +90,5 @@
 };
 
-#else
+#else //ifdef MULTITHREADED
 
 template<class T> class ThreadSingleton
@@ -102,5 +102,16 @@
 };
 
-#endif
+template<class T> class ThreadSingletonPtr
+{
+T *object;
+
+  public:
+
+ThreadSingletonPtr():object(NULL) {}
+T* get() {return object;}
+T* setptr(T* o) {T* previous=object; object=o; return previous;}
+};
+
+#endif //ifdef MULTITHREADED
 
 ////////////////////////////////////
Index: cpp/frams/_demos/f0_variants_test.cpp
===================================================================
--- cpp/frams/_demos/f0_variants_test.cpp	(revision 347)
+++ cpp/frams/_demos/f0_variants_test.cpp	(revision 348)
@@ -79,11 +79,13 @@
 DefaultGenoConvManager gcm;
 gcm.addDefaultConverters();
-Geno::useConverters(gcm);
+Geno::useConverters(&gcm);
 
+Geno::Validators validators;
+Geno::useValidators(&validators);
 ModelGenoValidator model_validator;
-Geno::addValidator(&model_validator); //This simple validator handles all cases where a converter for a particular format is available but there is no genetic operator. Converters may be less strict in detecting invalid genotypes but it is better than nothing
+validators+=&model_validator; //This simple validator handles all cases where a converter for a particular format is available but there is no genetic operator. Converters may be less strict in detecting invalid genotypes but it is better than nothing
 
 SString gen(argc>1?argv[1]:"X[|G:1.23]");
-if (!strcmp(gen,"-"))
+if (!strcmp(gen.c_str(),"-"))
 	{
 	gen=0;
@@ -92,7 +94,7 @@
 	}
 Geno g(gen);
-printf("\nSource genotype: '%s'\n",(const char*)g.getGene());
+printf("\nSource genotype: '%s'\n",g.getGene().c_str());
 printf("                  ( format %c %s)\n",
-       g.getFormat(), (const char*)g.getComment());
+       g.getFormat(), g.getComment().c_str());
 
 Model m(g);//.getConverted('0'));
@@ -112,6 +114,6 @@
 save_as_f0(f0_no_skipping_defaults,m,false);
 
-printf("\n==== with defdata (skips default values) ======\n%s\n",(const char*)f0_skipping_defaults);
-printf("\n==== without defdata (saves all fields) ======\n%s\n",(const char*)f0_no_skipping_defaults);
+printf("\n==== with defdata (skips default values) ======\n%s\n",f0_skipping_defaults.c_str());
+printf("\n==== without defdata (saves all fields) ======\n%s\n",f0_no_skipping_defaults.c_str());
 
 return 0;
Index: cpp/frams/_demos/full_props.cpp
===================================================================
--- cpp/frams/_demos/full_props.cpp	(revision 347)
+++ cpp/frams/_demos/full_props.cpp	(revision 348)
@@ -97,5 +97,5 @@
 Geno f0_g;
 m.makeGeno(f0_g,NULL,reverse);//third arg is "handle_defaults" == whether f0 should omit default property values
-puts((const char*)f0_g.toString());
+puts(f0_g.toString().c_str());
 
 return 0;
Index: cpp/frams/_demos/geno_test.cpp
===================================================================
--- cpp/frams/_demos/geno_test.cpp	(revision 347)
+++ cpp/frams/_demos/geno_test.cpp	(revision 348)
@@ -24,5 +24,5 @@
 	}
 SString gen(argv[1]);
-if (!strcmp(gen,"-"))
+if (!strcmp(gen.c_str(),"-"))
 	{
 	gen=0;
Index: cpp/frams/_demos/genoconv_test.cpp
===================================================================
--- cpp/frams/_demos/genoconv_test.cpp	(revision 347)
+++ cpp/frams/_demos/genoconv_test.cpp	(revision 348)
@@ -77,5 +77,5 @@
 {
 SString dst;
-const char* src=in;
+const char* src=in.c_str();
 const char* t;
 int insideneuron=0;
@@ -112,5 +112,5 @@
 {
 printf("Genotype:\n%s\nFormat: %c\nValid: %s\nComment: %s\n",
-	(const char*)g.getGene(),g.getFormat(),g.isValid()?"yes":"no",(const char*)g.getComment());
+	g.getGene().c_str(),g.getFormat(),g.isValid()?"yes":"no",g.getComment().c_str());
 }
 
@@ -124,8 +124,10 @@
 gcm.addConverter(new GenoConv_Test2());
 gcm.addConverter(new GenoConv_Test3());
-Geno::useConverters(gcm);
+Geno::useConverters(&gcm);
 
+Geno::Validators validators;
 ModelGenoValidator model_validator;
-Geno::addValidator(&model_validator);
+validators+=&model_validator;
+Geno::useValidators(&validators);
 
 const char* src=(argc>1)?argv[1]:"X";
Index: cpp/frams/_demos/genomanipulation.cpp
===================================================================
--- cpp/frams/_demos/genomanipulation.cpp	(revision 347)
+++ cpp/frams/_demos/genomanipulation.cpp	(revision 348)
@@ -34,5 +34,5 @@
 	const char* type=pi.type(i);
 	if (*type=='p') continue;
-	printf("%2d. %8s = %-20s %-3s %-10s  %-10s\n",i,pi.id(i),(const char*)pi.get(i),pi.type(i),pi.name(i),pi.grname(pi.group(i)));
+	printf("%2d. %8s = %-20s %-3s %-10s  %-10s\n",i,pi.id(i),pi.get(i).c_str(),pi.type(i),pi.name(i),pi.grname(pi.group(i)));
 	}
 }
@@ -47,10 +47,10 @@
 pi.getMinMax(i,minprop,maxprop,def);
 printf("      Change property #%d to random value from range [%g..%g]\n",i,minprop,maxprop);
-printf("      Current value of '%s' (%s) is '%s'\n",pi.id(i),pi.name(i),(const char*)pi.get(i));
+printf("      Current value of '%s' (%s) is '%s'\n",pi.id(i),pi.name(i),pi.get(i).c_str());
 char t[100];
 sprintf(t,"%g",minprop+(rnd01)*(maxprop-minprop));
 printf("      Setting new value... [ using ParamInterface::set() ]\n");
 pi.set(i,t);
-printf("      The value is now '%s'\n",(const char*)pi.get(i));
+printf("      The value is now '%s'\n",pi.get(i).c_str());
 }
 
@@ -79,5 +79,5 @@
 CHANGE_ONE_PROPERTY(p->extraProperties());
 p->getModel().close();
-printf("\nLet's see f0... (check out part #%d !)\n\n%s\n", p->refno, (const char*)p->getModel().getF0Geno().getGene());
+printf("\nLet's see f0... (check out part #%d !)\n\n%s\n", p->refno, p->getModel().getF0Geno().getGene().c_str());
 }
 
@@ -91,5 +91,5 @@
 j->getModel().close();
 printf("The Part's position is changed, but everything else stays intact:\n\n%s\n",
-       (const char*)j->getModel().getF0Geno().getGene());
+       j->getModel().getF0Geno().getGene().c_str());
 }
 
@@ -104,5 +104,5 @@
 j->getModel().close();
 printf("Position of the second Part referenced by this joint (part #%d) is now changed:\n\n%s\n",
-       j->part2->refno, (const char*)j->getModel().getF0Geno().getGene());
+       j->part2->refno, j->getModel().getF0Geno().getGene().c_str());
 printf("If no delta fields are defined, they will be computed automatically.\n"
        "You can always delete existing delta values by using Joint::resetDelta().\n"
@@ -112,5 +112,5 @@
 j->resetDelta();
 j->getModel().close();
-printf("As you can see, Joint's delta fields have altered:\n\n%s\n", (const char*)j->getModel().getF0Geno().getGene());
+printf("As you can see, Joint's delta fields have altered:\n\n%s\n", j->getModel().getF0Geno().getGene().c_str());
 }
 
@@ -123,5 +123,5 @@
 j->getModel().close();
 printf("f0 is now:\n\n%s\n...so this is %s joint.\n",
-       (const char*)j->getModel().getF0Geno().getGene(), option?"a delta":"an absolute");
+       j->getModel().getF0Geno().getGene().c_str(), option?"a delta":"an absolute");
 
 }
@@ -155,5 +155,5 @@
 CHANGE_ONE_PROPERTY(j->extraProperties());
 j->getModel().close();
-printf("And after that we have this genotype:\n\n%s\n", (const char*)j->getModel().getF0Geno().getGene());
+printf("And after that we have this genotype:\n\n%s\n", j->getModel().getF0Geno().getGene().c_str());
 }
 
@@ -178,15 +178,15 @@
 printf("\nThe most unusual thing is 'details' field (d).\n"
        "It is something like separate object with its own set of properties.\n"
-       "Currently the value of 'd' is '%s'.\n",(const char*)n->getDetails());
+       "Currently the value of 'd' is '%s'.\n",n->getDetails().c_str());
 
 {
 NeuroClass* cl=n->getClass();
 if (!cl)
-	printf("It should contain the class name but the meaning of '%s' is unknown\n",(const char*)n->getDetails());
+	printf("It should contain the class name but the meaning of '%s' is unknown\n",n->getDetails().c_str());
 else
 {
 
 printf("'%s' is the class name (Neuro::getClassName() == '%s') and means '%s'.\n",
-       (const char*)cl->getName(),(const char*)cl->getName(),(const char*)cl->getLongName());
+       cl->getName().c_str(),cl->getName().c_str(),cl->getLongName().c_str());
 printf("Neuro::getClass() gives you information about basic characteristic\n"
        "of the class, that can be analyzed automatically.\n");
@@ -208,5 +208,5 @@
 	p.update();
 	n->getModel().close();
-	printf("After that, 'details' contains the new object: '%s'.\n",(const char*)n->getDetails());
+	printf("After that, 'details' contains the new object: '%s'.\n",n->getDetails().c_str());
 	}
 else
@@ -224,8 +224,8 @@
 	NeuroClass* cl=n->getClass(i);
 	Param p=cl->getProperties();
-	printf("%2d.%6s  %-20s  %2d\n",i,(const char*)cl->getName(),(const char*)cl->getLongName(),p.getPropCount());
+	printf("%2d.%6s  %-20s  %2d\n",i,cl->getName().c_str(),cl->getLongName().c_str(),p.getPropCount());
 	}
 int cl=rand() % n->getClassCount();
-printf("\nLet's change the Neuro's class to '%s'...\n",(const char*)n->getClassName(cl));
+printf("\nLet's change the Neuro's class to '%s'...\n",n->getClassName(cl).c_str());
 n->getModel().open();
 n->setClass(n->getClass(cl));
@@ -242,6 +242,6 @@
 if (n->getInputCount()>0)
 {
-	printf("Info for input #0 = \"%s\"\n",(const char*)n->getInputInfo(0));
-	printf("Info for input #0, field \"%s\" = \"%s\"\n", "abc", (const char*)n->getInputInfo(0,"abc"));
+	printf("Info for input #0 = \"%s\"\n",n->getInputInfo(0).c_str());
+	printf("Info for input #0, field \"%s\" = \"%s\"\n", "abc", n->getInputInfo(0,"abc").c_str());
 	n->setInputInfo(0,"test",44);
 	n->setInputInfo(0,"abc","yeah");
@@ -250,5 +250,5 @@
 n->getModel().close();
 printf("The final object description will be then: '%s'\nAnd the full f0 genotype:\n\n%s\n",
-       (const char*)n->getDetails(), (const char*)n->getModel().getF0Geno().getGene());
+       n->getDetails().c_str(), n->getModel().getF0Geno().getGene().c_str());
 
 
@@ -257,8 +257,8 @@
 void findingConverters()
 {
-GenoConverter *gc=Geno::getConverters().findConverters(0,'1');
+GenoConverter *gc=Geno::getConverters()->findConverters(0,'1');
 if (gc) printf("found converter accepting f1: \"%s\"\n",gc->name);
 SListTempl<GenoConverter*> found;
-Geno::getConverters().findConverters(&found,-1,'0');
+Geno::getConverters()->findConverters(&found,-1,'0');
 printf("found %d converter(s) producing f0\n",found.size());
 }
@@ -274,5 +274,5 @@
 
 SString gen(argc>1?argv[1]:"X[|G:1.23]");
-if (!strcmp(gen,"-"))
+if (!strcmp(gen.c_str(),"-"))
 	{
 	gen=0;
@@ -281,7 +281,7 @@
 	}
 Geno g(gen);
-printf("\nSource genotype: '%s'\n",(const char*)g.getGene());
+printf("\nSource genotype: '%s'\n",g.getGene().c_str());
 printf("                  ( format %c %s)\n",
-       g.getFormat(), (const char*)g.getComment());
+       g.getFormat(), g.getComment().c_str());
 
 Model m(g);//.getConverted('0'));
@@ -292,5 +292,5 @@
 	return 2;	
 	}
-printf("Converted to f0:\n%s\n",(const char*)m.getF0Geno().getGene());
+printf("Converted to f0:\n%s\n",m.getF0Geno().getGene().c_str());
 
 printf("Model contains: %d part(s)\n"
@@ -340,5 +340,5 @@
 		NeuroItem *ni=n->getNeuroItem(j);
 		printf("        item #%d - '%s', conn=%d, weight=%g\n",
-		       j,(const char*)ni->getDetails(),ni->conn_refno,ni->weight);
+		       j,ni->getDetails().c_str(),ni->conn_refno,ni->weight);
 		}
 	}
Index: cpp/frams/_demos/genooper_test.cpp
===================================================================
--- cpp/frams/_demos/genooper_test.cpp	(revision 347)
+++ cpp/frams/_demos/genooper_test.cpp	(revision 348)
@@ -9,5 +9,5 @@
 {
 	printf("Genotype: %s\nFormat: %c\nValid: %s\nComment: %s\n",
-		(const char*)g.getGene(), g.getFormat(), g.isValid() ? "yes" : "no", g.getComment().len() == 0 ? "(empty)" : (const char*)g.getComment());
+		g.getGene().c_str(), g.getFormat(), g.isValid() ? "yes" : "no", g.getComment().len() == 0 ? "(empty)" : g.getComment().c_str());
 }
 
@@ -47,5 +47,5 @@
 	printGenAndTitle(gvalidated, "validated");
 
-	printf("\nHTMLized: %s\n", (const char*)genetics.genman.HTMLize((const char*)gvalidated.getGene()));
+	printf("\nHTMLized: %s\n", genetics.genman.HTMLize(gvalidated.getGene().c_str()).c_str());
 
 	return 0;
Index: cpp/frams/_demos/geometry/apices_test.cpp
===================================================================
--- cpp/frams/_demos/geometry/apices_test.cpp	(revision 347)
+++ cpp/frams/_demos/geometry/apices_test.cpp	(revision 348)
@@ -47,5 +47,5 @@
 	// Finishing result Model and printing its genotype.
 	resultModel.close();
-	puts((const char*)resultModel.getF0Geno().toString());
+	puts(resultModel.getF0Geno().toString().c_str());
 }
 
Index: cpp/frams/_demos/geometry/geometrytestutils.cpp
===================================================================
--- cpp/frams/_demos/geometry/geometrytestutils.cpp	(revision 347)
+++ cpp/frams/_demos/geometry/geometrytestutils.cpp	(revision 348)
@@ -25,10 +25,10 @@
 		
 		fprintf(stderr, "%d. (%6d chars) %s\n", count, genotype->genotype.len(),
-			(const char*)genotype->name);
+			genotype->name.c_str());
 	}
 	
 	if (loader.getStatus() == MiniGenotypeLoader::OnError)
 	{
-		fprintf(stderr, "Error: %s\n", (const char*)loader.getError());
+		fprintf(stderr, "Error: %s\n", loader.getError().c_str());
 		return 2;
 	}
@@ -58,5 +58,5 @@
 		count++;
 		
-		if ((genoIndex == count) || (strcmp((const char*)genotype->name, genoName) == 0))
+		if ((genoIndex == count) || (strcmp(genotype->name.c_str(), genoName) == 0))
 		{
 			Model model(genotype->genotype);
@@ -75,5 +75,5 @@
 	if (loader.getStatus() == MiniGenotypeLoader::OnError)
 	{
-		fprintf(stderr, "Error: %s\n", (const char*)loader.getError());
+		fprintf(stderr, "Error: %s\n", loader.getError().c_str());
 		return 2;
 	}
@@ -156,5 +156,5 @@
 		"GENO_ID - either genotype name or index (1-based)\n"
 		"SHAPE - 1=ellipsoid, 2=cuboid, 3=cylinder, others or none=random\n",
-		(const char*)header);
+		header.c_str());
 	return 1;
 }
@@ -220,5 +220,5 @@
 		"DENSITY - minimal number of samples per unit\n"
 		"SHAPE - 1=ellipsoid, 2=cuboid, 3=cylinder, others or none=random\n",
-		(const char*)header);
+		header.c_str());
 	return 1;
 }
Index: cpp/frams/_demos/geometry/info_test.cpp
===================================================================
--- cpp/frams/_demos/geometry/info_test.cpp	(revision 347)
+++ cpp/frams/_demos/geometry/info_test.cpp	(revision 348)
@@ -72,5 +72,5 @@
 	// Finishing result Model and printing its genotype.
 	resultModel.close();
-	puts((const char*)resultModel.getF0Geno().toString());
+	puts(resultModel.getF0Geno().toString().c_str());
 	
 	// Printing calculated values.
Index: cpp/frams/_demos/geometry/surface_test.cpp
===================================================================
--- cpp/frams/_demos/geometry/surface_test.cpp	(revision 347)
+++ cpp/frams/_demos/geometry/surface_test.cpp	(revision 348)
@@ -47,5 +47,5 @@
 	// Finishing result Model and printing its genotype.
 	resultModel.close();
-	puts((const char*)resultModel.getF0Geno().toString());
+	puts(resultModel.getF0Geno().toString().c_str());
 }
 
Index: cpp/frams/_demos/geometry/volume_test.cpp
===================================================================
--- cpp/frams/_demos/geometry/volume_test.cpp	(revision 347)
+++ cpp/frams/_demos/geometry/volume_test.cpp	(revision 348)
@@ -39,5 +39,5 @@
 	// Finishing result Model and printing its genotype.
 	resultModel.close();
-	puts((const char*)resultModel.getF0Geno().toString());
+	puts(resultModel.getF0Geno().toString().c_str());
 }
 
Index: cpp/frams/_demos/loader_test.cpp
===================================================================
--- cpp/frams/_demos/loader_test.cpp	(revision 347)
+++ cpp/frams/_demos/loader_test.cpp	(revision 348)
@@ -45,15 +45,15 @@
 		else
 			{
-			if (strcmp((const char*)loaded->name,selected))
+			if (strcmp(loaded->name.c_str(),selected))
 				continue;
 			}
-		puts((const char*)loaded->genotype);
+		puts(loaded->genotype.c_str());
 		return 0;
 		}
-	fprintf(stderr,"%d. %s\t(%d characters)\n",count,(const char*)loaded->name,loaded->genotype.len());
+	fprintf(stderr,"%d. %s\t(%d characters)\n",count,loaded->name.c_str(),loaded->genotype.len());
 	}
 // the loop repeats until loaded==NULL, which could be beacause of error
 if (loader.getStatus()==MiniGenotypeLoader::OnError)
-	fprintf(stderr,"Error: %s",(const char*)loader.getError());
+	fprintf(stderr,"Error: %s",loader.getError().c_str());
 // (otherwise it was the end of the file)
 if (selected)
Index: cpp/frams/_demos/loader_test_param.cpp
===================================================================
--- cpp/frams/_demos/loader_test_param.cpp	(revision 347)
+++ cpp/frams/_demos/loader_test_param.cpp	(revision 348)
@@ -84,5 +84,5 @@
 		{
 		case MultiParamLoader::OnComment:
-			fprintf(stderr, "comment: '%s'\n", (const char*)loader.getComment());
+			fprintf(stderr, "comment: '%s'\n", loader.getComment().c_str());
 			break;
 
@@ -92,5 +92,5 @@
 			// In fact, this method is used not just for truly unknown objects but also for
 			// dynamic objects that cannot be added using MultiParamLoader.addObject().
-			fprintf(stderr, "unknown object found: '%s' (will be skipped)\n", (const char*)loader.getObjectName());
+			fprintf(stderr, "unknown object found: '%s' (will be skipped)\n", loader.getObjectName().c_str());
 			break;
 
@@ -98,7 +98,7 @@
 			fprintf(stderr, "loaded:\n");
 			for (int i = 0; i < param.getPropCount(); i++)
-				fprintf(stderr, "%s=%s\n", param.id(i), (const char*)param.getText(i));
-			fprintf(stderr, "type of 'x1' is: %s\n", (const char*)data.x1.typeDescription());
-			fprintf(stderr, "type of 'x2' is: %s\n", (const char*)data.x2.typeDescription());
+				fprintf(stderr, "%s=%s\n", param.id(i), param.getText(i).c_str());
+			fprintf(stderr, "type of 'x1' is: %s\n", data.x1.typeDescription().c_str());
+			fprintf(stderr, "type of 'x2' is: %s\n", data.x2.typeDescription().c_str());
 			fprintf(stderr, "-----\n\n");
 			param.save(&virt_stdout);
@@ -112,5 +112,5 @@
 
 		case MultiParamLoader::OnError:
-			fprintf(stderr, "Error: %s", (const char*)loader.getError());
+			fprintf(stderr, "Error: %s", loader.getError().c_str());
 		}
 	}
Index: cpp/frams/_demos/multiline_f0_test.cpp
===================================================================
--- cpp/frams/_demos/multiline_f0_test.cpp	(revision 347)
+++ cpp/frams/_demos/multiline_f0_test.cpp	(revision 348)
@@ -19,5 +19,5 @@
 
 SString gen(argc>1?argv[1]:"X[|G:1.23]");
-if (!strcmp(gen,"-"))
+if (!strcmp(gen.c_str(),"-"))
 	{
 	gen=0;
@@ -26,7 +26,7 @@
 	}
 Geno g(gen);
-printf("\nSource genotype: '%s'\n",(const char*)g.getGene());
+printf("\nSource genotype: '%s'\n",g.getGene().c_str());
 printf("                  ( format %c %s)\n",
-       g.getFormat(), (const char*)g.getComment());
+       g.getFormat(), g.getComment().c_str());
 
 Model m(g);//.getConverted('0'));
@@ -37,5 +37,5 @@
 	return 2;	
 	}
-printf("Converted to f0:\n%s\n",(const char*)m.getF0Geno().getGene());
+printf("Converted to f0:\n%s\n",m.getF0Geno().getGene().c_str());
 
 printf("\nusing Param::save() to create the \"expanded\" form of the f0 genotype...\n(MultiParamLoader should be able to load this)");
@@ -87,5 +87,5 @@
 	}
 
-printf("\n============================\n%s\n",(const char*)f.getString());
+printf("\n============================\n%s\n",f.getString().c_str());
 
 return 0;
Index: cpp/frams/_demos/neuro_layout_test.cpp
===================================================================
--- cpp/frams/_demos/neuro_layout_test.cpp	(revision 347)
+++ cpp/frams/_demos/neuro_layout_test.cpp	(revision 348)
@@ -94,5 +94,5 @@
 	}
 SString gen(argv[1]);
-if (!strcmp(gen,"-"))
+if (!strcmp(gen.c_str(),"-"))
 	{
 	gen=0;
@@ -116,5 +116,5 @@
 	{
 	int *xywh=nn_layout.GetXYWH(i);
-	printf("#%-3d %s\t%d,%d\t%dx%d\n",i,(const char*)m.getNeuro(i)->getClassName(),
+	printf("#%-3d %s\t%d,%d\t%dx%d\n",i,m.getNeuro(i)->getClassName().c_str(),
 	       xywh[0],xywh[1],xywh[2],xywh[3]);
 	}
@@ -130,6 +130,6 @@
 	{
 	int *xywh=nn_layout.GetXYWH(i);
-	SString label=SString::sprintf("%d:%s",i,(const char*)m.getNeuro(i)->getClassName());
-	screen.put(xywh[0],xywh[1],(const char*)label);
+	SString label=SString::sprintf("%d:%s",i,m.getNeuro(i)->getClassName().c_str());
+	screen.put(xywh[0],xywh[1],label.c_str());
 	}
 screen.print();
Index: cpp/frams/_demos/neuro_test.cpp
===================================================================
--- cpp/frams/_demos/neuro_test.cpp	(revision 347)
+++ cpp/frams/_demos/neuro_test.cpp	(revision 348)
@@ -69,5 +69,5 @@
 	}
 SString gen(argv[1]);
-if (!strcmp(gen,"-"))
+if (!strcmp(gen.c_str(),"-"))
 	{
 	gen=0;
@@ -98,5 +98,5 @@
 			{
 			if (no_impl) no_impl_names+=',';
-			no_impl_names+=SString::sprintf("#%d.%s",i,(const char*)n->getClassName());
+			no_impl_names+=SString::sprintf("#%d.%s",i,n->getClassName().c_str());
 			no_impl++;
 			}
@@ -104,11 +104,11 @@
 			{
 			if (init_err) init_err_names+=',';
-			init_err_names+=SString::sprintf("#%d.%s",i,(const char*)n->getClassName());
+			init_err_names+=SString::sprintf("#%d.%s",i,n->getClassName().c_str());
 			init_err++;
 			}
 		}
 	printf("\n");
-	if (no_impl) printf("%d x missing implementation (%s)\n",no_impl,(const char*)no_impl_names);
-	if (init_err) printf("%d x failed initialization (%s)\n",init_err,(const char*)init_err_names);
+	if (no_impl) printf("%d x missing implementation (%s)\n",no_impl,no_impl_names.c_str());
+	if (init_err) printf("%d x failed initialization (%s)\n",init_err,init_err_names.c_str());
 	}
 int steps=1;
@@ -119,5 +119,5 @@
 	{
 	n=m.getNeuro(i);
-	printf("\t#%d.%s",i,(const char*)n->getClassName());
+	printf("\t#%d.%s",i,n->getClassName().c_str());
 	}
 printf("\n");
Index: cpp/frams/_demos/part_shapes.cpp
===================================================================
--- cpp/frams/_demos/part_shapes.cpp	(revision 347)
+++ cpp/frams/_demos/part_shapes.cpp	(revision 348)
@@ -52,5 +52,5 @@
 
 	m.close();
-	puts((const char*)m.getF0Geno().toString());
+	puts(m.getF0Geno().toString().c_str());
 	// the genotype can be fed directly to the genotype viewer, like this:
 	// part_shapes | theater -g -
Index: cpp/frams/_demos/printconvmap.cpp
===================================================================
--- cpp/frams/_demos/printconvmap.cpp	(revision 347)
+++ cpp/frams/_demos/printconvmap.cpp	(revision 348)
@@ -56,10 +56,10 @@
 SString g2=gen2;
 stripstring(g2);
-const char* g=g1;
+const char* g=g1.c_str();
 y=0;
 MultiRange *mr;
 MultiRange emptyrange;
 printN(' ',GEN1MAX);
-printf("   %s\n",(const char*)g2);
+printf("   %s\n",g2.c_str());
 int begin=map.getBegin();
 int end=map.getEnd();
@@ -83,5 +83,5 @@
 	if ((y2-y) > GEN1MAX) y2=y+GEN1MAX;
 	if (y2>(y+len1)) y2=y+len1;
-	printmapping(g+y,y2-y,*mr,g2,g2.len());
+	printmapping(g+y,y2-y,*mr,g2.c_str(),g2.len());
 	y=y2;
 	}
Index: cpp/frams/_demos/serial_test.cpp
===================================================================
--- cpp/frams/_demos/serial_test.cpp	(revision 347)
+++ cpp/frams/_demos/serial_test.cpp	(revision 348)
@@ -60,5 +60,5 @@
 				{
 				printIndent(indent+3);
-				printf("key \"%s\"\n",(const char*)it->key);
+				printf("key \"%s\"\n",it->key.c_str());
 				print((ExtValue*)it->value,indent+6,&next_trace);
 				}
@@ -67,5 +67,5 @@
 		}
 	}
-puts((const char*)v->getString());
+puts(v->getString().c_str());
 }
 
Index: cpp/frams/_demos/shapeconvert.cpp
===================================================================
--- cpp/frams/_demos/shapeconvert.cpp	(revision 347)
+++ cpp/frams/_demos/shapeconvert.cpp	(revision 348)
@@ -87,5 +87,5 @@
 
 	Geno f0_g = newmodel.getF0Geno();
-	puts((const char*)f0_g.toString());
+	puts(f0_g.toString().c_str());
 
 	return 0;
Index: cpp/frams/canvas/neurodiagram.cpp
===================================================================
--- cpp/frams/canvas/neurodiagram.cpp	(revision 347)
+++ cpp/frams/canvas/neurodiagram.cpp	(revision 348)
@@ -271,5 +271,5 @@
 	if (size.y > 4 * textHeight())
 	{
-		const char* t = label;
+		const char* t = label.c_str();
 		setColor(ColorDefs::neurosymbol);
 		drawAlignedText(size.x / 2, size.y - textHeight(), 0, t);
@@ -445,5 +445,5 @@
 NeuroProbe::NeuroProbe(NeuroSymbol* ns)
 :DCanvasWindow(DCanvasWindow::Title + DCanvasWindow::Border + DCanvasWindow::Close + DCanvasWindow::Size,
-  (const char*)ns->getLabel(), &neurochart, &neurochart)
+  ns->getLabel().c_str(), &neurochart, &neurochart)
 {
 	holdismine = 0;
Index: cpp/frams/config/version.h
===================================================================
--- cpp/frams/config/version.h	(revision 347)
+++ cpp/frams/config/version.h	(revision 348)
@@ -3,3 +3,3 @@
 // See LICENSE.txt for details.
 
-#define MAIN_REL_ID "4.0"
+#define MAIN_REL_ID "4.2rc1"
Index: cpp/frams/errmgr/stderrors.cpp
===================================================================
--- cpp/frams/errmgr/stderrors.cpp	(revision 347)
+++ cpp/frams/errmgr/stderrors.cpp	(revision 348)
@@ -29,5 +29,5 @@
 	{
 	SString msg2=SString(msg)+": \"%s\" (adjusted to \"%s\")";
-	FMprintf(msgobj,msgfun,FMLV_WARN,(const char*)msg2,(const char*)in,(const char*)corrected);
+	FMprintf(msgobj,msgfun,FMLV_WARN,msg2.c_str(),in.c_str(),corrected.c_str());
 	}
 return corrected;
Index: cpp/frams/genetics/f1/conv_f1.cpp
===================================================================
--- cpp/frams/genetics/f1/conv_f1.cpp	(revision 347)
+++ 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 347)
+++ 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 347)
+++ 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 347)
+++ 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 347)
+++ 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 347)
+++ 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 347)
+++ 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 347)
+++ 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 347)
+++ 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 347)
+++ 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 347)
+++ 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
-
Index: cpp/frams/model/autoname.cpp
===================================================================
--- cpp/frams/model/autoname.cpp	(revision 347)
+++ cpp/frams/model/autoname.cpp	(revision 348)
@@ -38,5 +38,5 @@
 	unsigned int s1 = 0, s2 = 0, s3 = 0;
 	SString g = model.getGeno().getGene();
-	const char *x = g;
+	const char *x = g.c_str();
 	for (; *x; x++) { s1 += *x; s2 = s2**x + *x; s3 = (s3^*x) + *x; }
 	char* t = buf;
Index: cpp/frams/model/model.cpp
===================================================================
--- cpp/frams/model/model.cpp	(revision 347)
+++ cpp/frams/model/model.cpp	(revision 348)
@@ -331,5 +331,5 @@
 		FMprintf("Model","build",FMLV_ERROR,
 			 geno.getName().len()?"illegal f0 code at line %d (%s)":"illegal f0 code at line %d",
-			 lnum,(const char*)geno.getName());
+			 lnum,geno.getName().c_str());
 		f0errorposition=lastpos;
 		if (convmap) delete convmap;
@@ -473,5 +473,5 @@
 		}
 	}
-g=Geno(gen,'0');
+g=Geno(gen.c_str(),'0');
 }
 
@@ -559,5 +559,5 @@
 int Model::singleStepBuild(const SString &line,const MultiRange* srcrange)
 {
-int pos=0; const char*t=(const char*)line;
+int pos=0; const char*t=line.c_str();
 for (;*t;t++,pos++)
 	if (!strchr(" \r\t",*t)) break;
@@ -943,5 +943,5 @@
 				FMprintf("Model","internalCheck",FMLV_ERROR,
 					 "delta joint cycle detected at joint#%d (%s)",
-					 i,(const char*)geno.getName());
+					 i,geno.getName().c_str());
 				}
 			j->resetDeltaMarkers();
@@ -979,5 +979,5 @@
 			ret=0;
 			FMprintf("Model","internalCheck",FMLV_ERROR,"delta too big in joint #%d (%s)",
-				 i,(const char*)geno.getName());
+				 i,geno.getName().c_str());
 			}
 			else if (j->d()<getMinJoint().d.x)
@@ -985,5 +985,5 @@
 			ret=0;
 			FMprintf("Model","internalCheck",FMLV_ERROR,"delta too small in joint #%d (%s)",
-				 i,(const char*)geno.getName());
+				 i,geno.getName().c_str());
 			}
 				}
@@ -993,5 +993,5 @@
 		{
 		FMprintf("Model","internalCheck",FMLV_ERROR,"illegal part references in joint #%d (%s)",
-			 i,(const char*)geno.getName());
+			 i,geno.getName().c_str());
 		ret=0;
 		}
@@ -1072,5 +1072,5 @@
 			{
 			FMprintf("Model","internalCheck",FMLV_ERROR,"not all parts connected (eg.#0-#%d) (%s)",
-				 i,(const char*)geno.getName());
+				 i,geno.getName().c_str());
 			ret=0;
 			break;
@@ -1085,5 +1085,5 @@
 		{
 		FMprintf("Model","internalCheck",FMLV_ERROR,"illegal self connection, joint #%d (%s)",
-			 i,(const char*)geno.getName());
+			 i,geno.getName().c_str());
 		ret=0;
 		break;
@@ -1096,5 +1096,5 @@
 			{
 			FMprintf("Model","internalCheck",FMLV_ERROR,"illegal duplicate joints #%d and #%d (%s)",
-				 i,k,(const char*)geno.getName());
+				 i,k,geno.getName().c_str());
 			ret=0;
 			break;
Index: cpp/frams/neuro/impl/neuroimpl-fuzzy-f0.cpp
===================================================================
--- cpp/frams/neuro/impl/neuroimpl-fuzzy-f0.cpp	(revision 347)
+++ cpp/frams/neuro/impl/neuroimpl-fuzzy-f0.cpp	(revision 348)
@@ -23,5 +23,5 @@
       break;
     else
-      numbers[have++]=atof(t);
+      numbers[have++]=atof(t.c_str());
 
   //check if number of read numbers (separated with semicolon) is equal to declared
@@ -122,5 +122,5 @@
         t += str.charAt(pos++);
       pos++;
-      rules[j][k]=atol(t); //convert cut out string into number
+      rules[j][k]=atol(t.c_str()); //convert cut out string into number
       //fuzzy sets - odd index table - are counted from 0,
       //so if 5 fuzzy sets declared, values acceptable are 0,1,2,3,4
Index: cpp/frams/neuro/impl/neuroimpl-fuzzy.cpp
===================================================================
--- cpp/frams/neuro/impl/neuroimpl-fuzzy.cpp	(revision 347)
+++ cpp/frams/neuro/impl/neuroimpl-fuzzy.cpp	(revision 348)
@@ -35,5 +35,5 @@
   rulesDef = new int[2*rulesNr];    //for each rule remembers number of inputs and outputs
   //check correctness of string and fill in the rulesDef
-  if (FuzzyF0String::countInputsOutputs(fuzzyRulesString, rulesDef, rulesNr) == 0)
+  if (FuzzyF0String::countInputsOutputs(fuzzyRulesString.c_str(), rulesDef, rulesNr) == 0)
   {
     defuzzParam = new double[rulesNr]; // parameters used in defuzyfication process
Index: cpp/frams/neuro/neurofactory.cpp
===================================================================
--- cpp/frams/neuro/neurofactory.cpp	(revision 347)
+++ cpp/frams/neuro/neurofactory.cpp	(revision 348)
@@ -99,5 +99,5 @@
 if (removed.len())
 	FMprintf("NeuroFactory","removeUninmplemented",FMLV_INFO,
-	 "Removed Neuro classes: %s",(const char*)removed);
+	 "Removed Neuro classes: %s",removed.c_str());
 }
 
Index: cpp/frams/neuro/neuroimpl.cpp
===================================================================
--- cpp/frams/neuro/neuroimpl.cpp	(revision 347)
+++ cpp/frams/neuro/neuroimpl.cpp	(revision 348)
@@ -73,5 +73,5 @@
 	if (!ni) { errorcount++;
 		FMprintf("NeuroNetImpl","create",FMLV_WARN,"neuron #%d (%s) implementation not available",
-			 i,(const char*)n->getClassName());
+			 i,n->getClassName().c_str());
 		continue; } // implementation not available?!
 	ni->owner=this;
@@ -88,5 +88,5 @@
 		{ ni->status=NeuroImpl::InitError; errorcount++;
 		FMprintf("NeuroNetImpl","create",FMLV_WARN,"neuron #%d (%s) initialization failed",
-			 i,(const char*)n->getClassName());
+			 i,n->getClassName().c_str());
 		continue; }
 	ni->status=NeuroImpl::InitOk;
Index: cpp/frams/neuro/neurolibparam.cpp
===================================================================
--- cpp/frams/neuro/neurolibparam.cpp	(revision 347)
+++ cpp/frams/neuro/neurolibparam.cpp	(revision 348)
@@ -51,5 +51,5 @@
 	t+=n;
 	}
-return t;
+return t.c_str();
 }
 
@@ -59,5 +59,5 @@
 t=Neuro::getClass(i)->getLongName();
 t+=" ("; t+=Neuro::getClassName(i); t+=")";
-return t;
+return t.c_str();
 }
 
@@ -66,5 +66,5 @@
 static SString t;
 t=Neuro::getClass(i)->getSummary();
-return t;
+return t.c_str();
 }
 
Index: cpp/frams/param/multiparamload.cpp
===================================================================
--- cpp/frams/param/multiparamload.cpp	(revision 347)
+++ cpp/frams/param/multiparamload.cpp	(revision 348)
@@ -107,5 +107,5 @@
 	else if (status==BeforeUnknown)
 		{
-		FMprintf("MultiParamLoader","go",FMLV_WARN,"Skipping object '%s'",(const char*)lastunknown);
+		FMprintf("MultiParamLoader","go",FMLV_WARN,"Skipping object '%s'",lastunknown.c_str());
 		loadObjectNow(&emptyparam,false);
 		continue;
@@ -126,5 +126,5 @@
 		if (buf.startsWith("#include"))
 			{
-			const char* t=strchr((const char*)buf,'\"'),*t2=0;
+			const char* t=strchr(buf.c_str(),'\"'),*t2=0;
 			if (t)
 				t2=strchr(t+1,'\"');
@@ -137,5 +137,5 @@
 				{
 				const char* thisfilename=file->VgetPath();
-				FMprintf("MultiParamLoader","go",FMLV_WARN,"invalid \"%s\"%s%s",(const char*)buf,
+				FMprintf("MultiParamLoader","go",FMLV_WARN,"invalid \"%s\"%s%s",buf.c_str(),
 					 (thisfilename?" in ":""),(thisfilename?thisfilename:""));
 				}
@@ -157,5 +157,5 @@
 		FOREACH(ExtObject*,o,objects)
 			{
-			if (!strcmp(o->interfaceName(),lastunknown)) {lastobject=*o; break;}
+			if (!strcmp(o->interfaceName(),lastunknown.c_str())) {lastobject=*o; break;}
 			}
 			if (!lastobject.isEmpty())
@@ -202,15 +202,15 @@
 	newfilename=filename;
 
-if (alreadyIncluded(newfilename))
+if (alreadyIncluded(newfilename.c_str()))
 	{
 	FMprintf("MultiParamLoader","include",FMLV_WARN,"circular reference ignored (\"%s\")",
-		    (const char*)filename);
+		    filename.c_str());
 	return;
 	}
 
-VirtFILE *f=Vfopen(newfilename,FOPEN_READ_BINARY);
+VirtFILE *f=Vfopen(newfilename.c_str(),FOPEN_READ_BINARY);
 if (!f)
 	{
-	FMprintf("MultiParamLoader","include",FMLV_WARN,"\"%s\" not found",(const char*)newfilename);
+	FMprintf("MultiParamLoader","include",FMLV_WARN,"\"%s\" not found",newfilename.c_str());
 	}
 else
Index: cpp/frams/param/mutableparam.cpp
===================================================================
--- cpp/frams/param/mutableparam.cpp	(revision 347)
+++ cpp/frams/param/mutableparam.cpp	(revision 348)
@@ -33,8 +33,8 @@
 	if (ignoreprefix)
 		{
-      const char *noprefix=(const char*)groupname(i);
+      const char *noprefix=groupname(i).c_str();
       if ((int)strlen(noprefix) < skipprefix) continue;
 		noprefix+=skipprefix;
-		if (!strcmp(noprefix,(const char*)name)) return i;
+		if (!strcmp(noprefix,name.c_str())) return i;
 		}
 		else
@@ -183,5 +183,5 @@
 void MutableParam::p_addprop(ExtValue *args,ExtValue *ret)
 {
-int i=addProperty(0,args[2].getString(),args[1].getString(),args[0].getString());
+int i=addProperty(0,args[2].getString().c_str(),args[1].getString().c_str(),args[0].getString().c_str());
 ret->setInt(i);
 }
@@ -284,7 +284,7 @@
 	{
 	SString *n=(SString*)store(i);
-	int prop=p.findId((const char*)*n);
+	int prop=p.findId(n->c_str());
 	if (prop<0)
-		prop=p.addProperty(0,(const char*)*n,"x",0,0,0,0,-1);
+		prop=p.addProperty(0,n->c_str(),"x",0,0,0,0,-1);
 	p.setExtValue(prop,*(ExtValue*)store(i+1));
 	}
Index: cpp/frams/param/mutableparam.h
===================================================================
--- cpp/frams/param/mutableparam.h	(revision 347)
+++ cpp/frams/param/mutableparam.h	(revision 348)
@@ -36,5 +36,5 @@
 int getGroupCount() {return groups.size();}
 int getPropCount() {return entries.size()+staticprops;}
-const char *grname(int i) {return (i>=groups.size()) ? 0 : (const char*)groupname(i);}
+const char *grname(int i) {return (i>=groups.size()) ? 0 : groupname(i).c_str();}
 int grmember(int g,int a);
 
Index: cpp/frams/param/param.cpp
===================================================================
--- cpp/frams/param/param.cpp	(revision 347)
+++ cpp/frams/param/param.cpp	(revision 348)
@@ -301,5 +301,5 @@
 		ws = get(i);
 	quoteTilde(ws);
-	w = ws;
+	w = ws.c_str();
 	if (ws.len() > 50) cr = 1;
 	else for (t = w; *t; t++) if ((*t == 10) || (*t == 13)) { cr = 1; break; }
@@ -372,5 +372,5 @@
 			{ // string - special case
 				SString str = getString(i);
-				if (strContainsOneOf(str, ", \\\n\r\t\""))
+				if (strContainsOneOf(str.c_str(), ", \\\n\r\t\""))
 				{
 					t += "\"";
@@ -403,5 +403,5 @@
 	{
 		if (linenum) (*linenum)++;
-		const char* t = (const char*)buf;
+		const char* t = buf.c_str();
 		p0 = t; while ((*p0 == ' ') || (*p0 == '\t')) p0++;
 		if (!*p0) break;
@@ -419,5 +419,5 @@
 					czytdotyldy(f, s);
 					int lfcount = 1;
-					const char* tmp = s;
+					const char* tmp = s.c_str();
 					while (tmp)
 						if ((tmp = strchr(tmp, '\n')))
@@ -430,5 +430,5 @@
 					if (linenum && (flags(i)&PARAM_LINECOMMENT))
 						s = SString::sprintf("@file %s\n@line %d\n", f->VgetPath(), *linenum + 1) + s;
-					set(i, (const char*)s);
+					set(i, s.c_str());
 					if (linenum)
 						(*linenum) += lfcount;
@@ -445,5 +445,5 @@
 		{
 			SString name(p0, p_len);
-			FMprintf("ParamInterface", "load", FMLV_WARN, "Unknown property '%s' while reading object '%s' (ignored)", (const char*)name, getName());
+			FMprintf("ParamInterface", "load", FMLV_WARN, "Unknown property '%s' while reading object '%s' (ignored)", name.c_str(), getName());
 		}
 
@@ -454,5 +454,5 @@
 			if (linenum)
 			{
-				const char* tmp = s;
+				const char* tmp = s.c_str();
 				int lfcount = 1;
 				while (tmp)
@@ -562,9 +562,9 @@
 			if (v.type == TObj)
 			{
-				FMprintf("ParamInterface", "set", FMLV_WARN, "Getting integer value from object reference (%s)", (const char*)v.getString());
+				FMprintf("ParamInterface", "set", FMLV_WARN, "Getting integer value from object reference (%s)", v.getString().c_str());
 				return 0;
 			}
 			else
-				return setInt(i, (const char*)v.getString());
+				return setInt(i, v.getString().c_str());
 		}
 	case 'f':
@@ -574,9 +574,9 @@
 			if (v.type == TObj)
 			{
-				FMprintf("ParamInterface", "set", FMLV_WARN, "Getting floating point value from object reference (%s)", (const char*)v.getString());
+				FMprintf("ParamInterface", "set", FMLV_WARN, "Getting floating point value from object reference (%s)", v.getString().c_str());
 				return 0;
 			}
 			else
-				return setDouble(i, (const char*)v.getString());
+				return setDouble(i, v.getString().c_str());
 		}
 	case 's': { SString t = v.getString(); return setString(i, t); }
@@ -990,9 +990,9 @@
 static const char *getline(const SString &s, int &poz, int &len)
 {
-	const char *beg = (const char*)s + poz;
-	if (poz >= s.len()) { poz = s.len(); len = 0; return (const char*)s + s.len(); }
+	const char *beg = s.c_str() + poz;
+	if (poz >= s.len()) { poz = s.len(); len = 0; return s.c_str() + s.len(); }
 	const char *lf = strchr(beg, '\n');
-	if (!lf) { lf = (const char*)s + s.len() - 1; poz = s.len(); }
-	else { poz = (int)(lf - (const char*)s) + 1; if (poz > s.len()) poz = s.len(); }
+	if (!lf) { lf = s.c_str() + s.len() - 1; poz = s.len(); }
+	else { poz = (int)(lf - s.c_str()) + 1; if (poz > s.len()) poz = s.len(); }
 	while (lf >= beg) if ((*lf == '\n') || (*lf == '\r')) lf--; else break;
 	len = (int)(lf - beg) + 1;
@@ -1014,5 +1014,5 @@
 	SString tmpvalue;
 	if (poz >= s.len()) return fields_loaded;
-	t = (const char*)s + poz;
+	t = s.c_str() + poz;
 
 	lin = getline(s, poz, len); // all fields must be encoded in a single line
@@ -1060,5 +1060,5 @@
 			{
 				SString name(t, (int)(equals_sign - t));
-				FMprintf("Param", "load2", FMLV_WARN, "Unknown property '%s' while reading object '%s' (ignored)", (const char*)name, getName());
+				FMprintf("Param", "load2", FMLV_WARN, "Unknown property '%s' while reading object '%s' (ignored)", name.c_str(), getName());
 			}
 			t = equals_sign + 1; // t=value
@@ -1081,5 +1081,5 @@
 				tmpvalue.copyFrom(quote + 1, (int)(quote2 - quote) - 1);
 				sstringUnquote(tmpvalue);
-				value = tmpvalue;
+				value = tmpvalue.c_str();
 				valstop = quote2;
 			}
Index: cpp/frams/param/param.h
===================================================================
--- cpp/frams/param/param.h	(revision 347)
+++ cpp/frams/param/param.h	(revision 348)
@@ -274,5 +274,5 @@
 			SString actual = get(i);
 			FMprintf("Param", "set", FMLV_WARN, "Setting '%s.%s = %s' exceeded allowed range (too %s). Adjusted to %s.",
-				getName(), id(i), (const char*)svaluetoset, (setflags&PSET_HITMAX) ? "big" : "small", (const char*)actual);
+				getName(), id(i), svaluetoset.c_str(), (setflags&PSET_HITMAX) ? "big" : "small", actual.c_str());
 		}
 	}
Index: cpp/frams/param/paramobj.cpp
===================================================================
--- cpp/frams/param/paramobj.cpp	(revision 347)
+++ cpp/frams/param/paramobj.cpp	(revision 348)
@@ -58,5 +58,5 @@
 		t->name = maybedup(dupentries, "create new object");
 		SString tmp = SString::sprintf("p o%s()", pi->getName());
-		t->type = maybedup(dupentries, (const char*)tmp);
+		t->type = maybedup(dupentries, tmp.c_str());
 		t->help = maybedup(dupentries, pi->help(i));
 		t->flags = 0;
Index: cpp/frams/util/extvalue.cpp
===================================================================
--- cpp/frams/util/extvalue.cpp	(revision 347)
+++ cpp/frams/util/extvalue.cpp	(revision 348)
@@ -269,5 +269,5 @@
 			if (tmp.len() > 30) tmp = tmp.substr(0, 30) + "...";
 			if (type == TString) tmp = SString("\"") + tmp + SString("\"");
-			FMprintf("ExtValue", "getObjectTarget", FMLV_WARN, "%s object expected, %s found", classname, (const char*)tmp);
+			FMprintf("ExtValue", "getObjectTarget", FMLV_WARN, "%s object expected, %s found", classname, tmp.c_str());
 		}
 		return NULL;
@@ -329,6 +329,6 @@
 static ExtValue::CompareResult compareString(const SString &a, const SString &b)
 {
-	const char* s1 = (const char*)a;
-	const char* s2 = (const char*)b;
+	const char* s1 = a.c_str();
+	const char* s2 = b.c_str();
 	return longsign(strcmp(s1, s2));
 }
@@ -415,9 +415,9 @@
 			if (context->v1 && context->v2)
 				msg += SString::sprintf(": %s %s %s",
-				(const char*)context->v1->typeAndValue(),
+				context->v1->typeAndValue().c_str(),
 				cmp_op_names[op - CmpFIRST],
-				(const char*)context->v2->typeAndValue());
-		}
-		FMprintf("ExtValue", "interpretCompare", FMLV_ERROR, "%s", (const char*)msg);
+				context->v2->typeAndValue().c_str());
+		}
+		FMprintf("ExtValue", "interpretCompare", FMLV_ERROR, "%s", msg.c_str());
 		ret = -1;
 	}
@@ -448,5 +448,5 @@
 		{
 		case TDouble:
-			FMprintf("ExtValue", "add", FMLV_WARN, "Adding %s to %s", (const char*)src.typeAndValue(), (const char*)typeAndValue());
+			FMprintf("ExtValue", "add", FMLV_WARN, "Adding %s to %s", src.typeAndValue().c_str(), typeAndValue().c_str());
 			setDouble(double(getInt()) + src.getDouble());
 			return;
@@ -487,5 +487,5 @@
 	default:;
 	}
-	FMprintf("ExtValue", "add", FMLV_ERROR, "Can't add %s to %s", (const char*)src.typeAndValue(), (const char*)typeAndValue());
+	FMprintf("ExtValue", "add", FMLV_ERROR, "Can't add %s to %s", src.typeAndValue().c_str(), typeAndValue().c_str());
 }
 
@@ -502,5 +502,5 @@
 			return;
 		case TDouble:
-			FMprintf("ExtValue", "subtract", FMLV_WARN, "Subtracting %s from %s", (const char*)src.typeAndValue(), (const char*)typeAndValue());
+			FMprintf("ExtValue", "subtract", FMLV_WARN, "Subtracting %s from %s", src.typeAndValue().c_str(), typeAndValue().c_str());
 			setDouble(double(getInt()) - src.getDouble());
 			return;
@@ -520,5 +520,5 @@
 	default:;
 	}
-	FMprintf("ExtValue", "subtract", FMLV_ERROR, "Can't subtract %s from %s", (const char*)src.typeAndValue(), (const char*)typeAndValue());
+	FMprintf("ExtValue", "subtract", FMLV_ERROR, "Can't subtract %s from %s", src.typeAndValue().c_str(), typeAndValue().c_str());
 }
 
@@ -535,5 +535,5 @@
 			return;
 		case TDouble:
-			FMprintf("ExtValue", "multiply", FMLV_WARN, "Multiplying %s by %s", (const char*)typeAndValue(), (const char*)src.typeAndValue());
+			FMprintf("ExtValue", "multiply", FMLV_WARN, "Multiplying %s by %s", typeAndValue().c_str(), src.typeAndValue().c_str());
 			setDouble(double(getInt())*src.getDouble());
 			return;
@@ -591,5 +591,5 @@
 	default:;
 	}
-	FMprintf("ExtValue", "multiply", FMLV_WARN, "Can't multiply %s by %s", (const char*)typeAndValue(), (const char*)src.typeAndValue());
+	FMprintf("ExtValue", "multiply", FMLV_WARN, "Can't multiply %s by %s", typeAndValue().c_str(), src.typeAndValue().c_str());
 }
 
@@ -621,5 +621,5 @@
 	if (a == 0.0)
 	{
-		FMprintf("ExtValue", "divide", FMLV_CRITICAL, "Division by zero: %s/0.0", (const char*)getString());
+		FMprintf("ExtValue", "divide", FMLV_CRITICAL, "Division by zero: %s/0.0", getString().c_str());
 		setInvalid();
 	}
@@ -630,5 +630,5 @@
 		if (!finite(tmp))
 		{
-			FMprintf("ExtValue", "divide", FMLV_CRITICAL, "Overflow %s/%g", (const char*)getString(), a); setInvalid();
+			FMprintf("ExtValue", "divide", FMLV_CRITICAL, "Overflow %s/%g", getString().c_str(), a); setInvalid();
 		}
 		else
@@ -652,5 +652,5 @@
 			return;
 		case TDouble:
-			FMprintf("ExtValue", "divide", FMLV_WARN, "Dividing %s by %s", (const char*)typeAndValue(), (const char*)src.typeAndValue());
+			FMprintf("ExtValue", "divide", FMLV_WARN, "Dividing %s by %s", typeAndValue().c_str(), src.typeAndValue().c_str());
 			divDouble(src.ddata());
 			return;
@@ -674,5 +674,5 @@
 	default:;
 	}
-	FMprintf("ExtValue", "divide", FMLV_ERROR, "Can't divide %s by %s", (const char*)typeAndValue(), (const char*)src.typeAndValue());
+	FMprintf("ExtValue", "divide", FMLV_ERROR, "Can't divide %s by %s", typeAndValue().c_str(), src.typeAndValue().c_str());
 }
 
@@ -687,5 +687,5 @@
 	//            ^-cur     ^-next
 	//            ^^^^^^^^^^___sub
-	const char* begin = (const char*)fmt, *end = begin + fmt.len(), *curr = begin;
+	const char* begin = fmt.c_str(), *end = begin + fmt.len(), *curr = begin;
 	int type = 0;
 
@@ -733,7 +733,7 @@
 		switch (type)
 		{
-		case 'd': a = args.getNext(); ret += SString::sprintf((const char*)sub, a ? a->getInt() : 0); break;
-		case 'f': a = args.getNext(); ret += SString::sprintf((const char*)sub, a ? a->getDouble() : 0); break;
-		case 's': {a = args.getNext(); SString tmp; if (a) tmp = a->getString(); ret += SString::sprintf((const char*)sub, (const char*)tmp); } break;
+		case 'd': a = args.getNext(); ret += SString::sprintf(sub.c_str(), a ? a->getInt() : 0); break;
+		case 'f': a = args.getNext(); ret += SString::sprintf(sub.c_str(), a ? a->getDouble() : 0); break;
+		case 's': {a = args.getNext(); SString tmp; if (a) tmp = a->getString(); ret += SString::sprintf(sub.c_str(), tmp.c_str()); } break;
 		case 't': case 'T':
 		{
@@ -779,5 +779,5 @@
 
 	case TObj: case TUnknown: case TInvalid:
-		FMprintf("ExtValue", "modulo", FMLV_WARN, "Can't apply modulo to %s", (const char*)typeDescription());
+		FMprintf("ExtValue", "modulo", FMLV_WARN, "Can't apply modulo to %s", typeDescription().c_str());
 
 	default:;
@@ -835,7 +835,7 @@
 	case TInt: return idata();
 	case TDouble: return (int)ddata();
-	case TString: return getInt((const char*)sdata());
+	case TString: return getInt(sdata().c_str());
 	case TObj:
-		FMprintf("ExtValue", "getInt", FMLV_WARN, "Getting integer value from object reference (%s)", (const char*)getString());
+		FMprintf("ExtValue", "getInt", FMLV_WARN, "Getting integer value from object reference (%s)", getString().c_str());
 		return (paInt)(intptr_t)odata().param;
 	default:;
@@ -850,7 +850,7 @@
 	case TDouble: return ddata();
 	case TInt: return (double)idata();
-	case TString: return getDouble((const char*)sdata());
+	case TString: return getDouble(sdata().c_str());
 	case TObj:
-		FMprintf("ExtValue", "getDouble", FMLV_WARN, "Getting floating point value from object reference (%s)", (const char*)getString());
+		FMprintf("ExtValue", "getDouble", FMLV_WARN, "Getting floating point value from object reference (%s)", getString().c_str());
 		return (double)(intptr_t)odata().param;
 	default:;
@@ -1095,5 +1095,5 @@
 		ExtValue tmp;
 		ret = tmp.deserialize(ret);
-		ParamInterface *cls = findDeserializableClass(clsname);
+		ParamInterface *cls = findDeserializableClass(clsname.c_str());
 		if (cls && (tmp.getType() != TUnknown) && (tmp.getType() != TInvalid))
 		{
@@ -1134,5 +1134,5 @@
 		}
 		setEmpty();
-		FMprintf("ExtValue", "deserialize", FMLV_WARN, "object of class \"%s\" could not be deserialized", (const char*)clsname);
+		FMprintf("ExtValue", "deserialize", FMLV_WARN, "object of class \"%s\" could not be deserialized", clsname.c_str());
 		return ret;
 	}
Index: cpp/frams/util/hashtable.cpp
===================================================================
--- cpp/frams/util/hashtable.cpp	(revision 347)
+++ cpp/frams/util/hashtable.cpp	(revision 348)
@@ -161,5 +161,5 @@
 	printf(" %d:",n);
 	for (;e;e=e->next)
-		printf(" (%x)%s=%p",e->hash,(const char*)e->key,e->value);
+		printf(" (%x)%s=%p",e->hash,e->key.c_str(),e->value);
 	printf("\n");
 	}
Index: cpp/frams/util/sstring.cpp
===================================================================
--- cpp/frams/util/sstring.cpp	(revision 347)
+++ cpp/frams/util/sstring.cpp	(revision 348)
@@ -251,5 +251,5 @@
 void SString::operator+=(const SString&s)
 {
-append((const char*)s,s.len());
+append(s.c_str(),s.len());
 }
 
@@ -323,5 +323,5 @@
 int SString::indexOf(const SString & substring,int start) const
 {
-char *found=strstr(buf->txt+start,((const char*)substring));
+char *found=strstr(buf->txt+start,substring.c_str());
 return found?found-buf->txt:-1;
 }
@@ -341,5 +341,5 @@
 int SString::startsWith(const char *pattern) const
 {
-const char *t=(const char*)(*this);
+const char *t=this->c_str();
 for (;*pattern;pattern++,t++)
 	if (*t != *pattern) return 0;
@@ -358,5 +358,5 @@
 {
 SString tmp=SString::sprintf("%.15g",d);
-if ((!strchr(tmp,'.'))&&(!strchr(tmp,'e'))) tmp+=".0";
+if ((!strchr(tmp.c_str(),'.'))&&(!strchr(tmp.c_str(),'e'))) tmp+=".0";
 return tmp;
 }
Index: cpp/frams/util/sstring.h
===================================================================
--- cpp/frams/util/sstring.h	(revision 347)
+++ cpp/frams/util/sstring.h	(revision 348)
@@ -144,5 +144,5 @@
 int indexOf(const SString & substring,int start=0) const;
 
-operator const char*() const {return buf->txt;} ///< get SString's readonly buffer
+const char* c_str() const {return buf->txt;} ///< get SString's readonly buffer
 //operator char*() {detachCopy(len()); return buf->txt;} ///< get SString's writable buffer
 void operator=(const char*t); ///< assign from const char*
Index: cpp/frams/util/sstringutils.cpp
===================================================================
--- cpp/frams/util/sstringutils.cpp	(revision 347)
+++ cpp/frams/util/sstringutils.cpp	(revision 348)
@@ -63,5 +63,5 @@
 int quoteTilde(SString &target)
 {
-	const char* x = target;
+	const char* x = target.c_str();
 	SString tmp;
 	char *f;
@@ -88,5 +88,5 @@
 int unquoteTilde(SString &target)
 {
-	const char* x = target;
+	const char* x = target.c_str();
 	SString tmp;
 	char *f;
@@ -134,5 +134,5 @@
 bool sstringQuote(SString& target)
 {
-	const char* x = target;
+	const char* x = target.c_str();
 	bool changed = 0;
 	SString tmp;
@@ -169,5 +169,5 @@
 int sstringUnquote(SString &target)
 {
-	const char* x = target;
+	const char* x = target.c_str();
 	SString tmp;
 	char *f;
@@ -200,10 +200,10 @@
 int strFindField(const SString& txt, const SString& name, int &end)
 {
-	const char* t = txt, *n;
+	const char* t = txt.c_str(), *n;
 	int pos = 0;
 	while (1)
 	{
 		n = strchr(t + pos, ',');
-		if ((!strncmp(t + pos, name, name.len())) && (t[pos + name.len()] == '='))
+		if ((!strncmp(t + pos, name.c_str(), name.len())) && (t[pos + name.len()] == '='))
 		{
 			if (n) end = n - t; else end = txt.len();
@@ -234,7 +234,7 @@
 		char *b = t;
 		if (txt.len()) *(t++) = ',';
-		strcpy(t, name); t += name.len();
+		strcpy(t, name.c_str()); t += name.len();
 		*(t++) = '=';
-		strcpy(t, value); t += value.len();
+		strcpy(t, value.c_str()); t += value.len();
 		txt.endAppend(t - b);
 	}
@@ -253,5 +253,5 @@
 			char *t = txt.directWrite(txt.len() + value.len() - (e - p));
 			memmove(t + p + value.len(), t + e, txt.len() - e);
-			memmove(t + p, value, value.len());
+			memmove(t + p, value.c_str(), value.len());
 			txt.endWrite(txt.len() + value.len() - (e - p));
 		}
@@ -261,5 +261,5 @@
 SString trim(SString& s)
 {
-	const unsigned char*b = (const unsigned char*)(const char*)s;
+	const unsigned char*b = (const unsigned char*)s.c_str();
 	const unsigned char*e = b + s.len();
 	while ((b < e) && (*b <= ' ')) b++;
@@ -275,5 +275,5 @@
 bool removeCR(SString& s)
 {
-	const char* p = (const char*)s;
+	const char* p = s.c_str();
 	const char* cr = strchr(p, '\r');
 	if (!cr) return false;
@@ -299,8 +299,8 @@
 		SString after = pattern.substr(aster + 1);
 		if (!word.len()) return false;
-		if (before.len()) if (!word.startsWith(before)) return false;
+		if (before.len()) if (!word.startsWith(before.c_str())) return false;
 		if (after.len())
 			if ((word.len() < after.len())
-				|| (strcmp((const char*)after, ((const char*)word) + word.len() - after.len())))
+				|| (strcmp(after.c_str(), word.c_str() + word.len() - after.len())))
 				return false;
 		return true;
Index: cpp/frams/virtfile/stringfile.cpp
===================================================================
--- cpp/frams/virtfile/stringfile.cpp	(revision 347)
+++ cpp/frams/virtfile/stringfile.cpp	(revision 348)
@@ -13,5 +13,5 @@
 	int need = (int)(size*nmemb);
 	if (need > have) { nmemb = have / size; need = (int)(size*nmemb); }
-	memcpy(ptr, ((const char*)str) + pos, need);
+	memcpy(ptr, str.c_str() + pos, need);
 	pos += need;
 	return nmemb;
@@ -32,5 +32,5 @@
 	if (size < 0) size = 0;
 	if (have > size) have = size - 1;
-	const char* src = ((const char*)str) + pos;
+	const char* src = str.c_str() + pos;
 	char *dest = s;
 	while (have-- > 0)
Index: cpp/frams/vm/framscript.l
===================================================================
--- cpp/frams/vm/framscript.l	(revision 347)
+++ cpp/frams/vm/framscript.l	(revision 348)
@@ -115,5 +115,5 @@
 int len=src.len();
 SString ret((len*11)/10+10);
-const char*t=(const char*)src;
+const char*t=src.c_str();
 while(len>0)
 	{
Index: cpp/frams/vm/framscript.y
===================================================================
--- cpp/frams/vm/framscript.y	(revision 347)
+++ cpp/frams/vm/framscript.y	(revision 348)
@@ -467,5 +467,5 @@
 		   {trctx.err->printf("%s can't be iterated\n",str($4)); return 1;}
 	   if ($4.objname) 
-		   trctx.out->printf("move %s.iterator,m[--m0]\n",(const char*)$4.getString());
+		   trctx.out->printf("move %s.iterator,m[--m0]\n",$4.getString().c_str());
 	   else
 		   trctx.out->printf("move s%d,m1\nmove [m1].\"iterator\",m[--m0]\n",0);
@@ -662,6 +662,6 @@
 
        | OBJNAME ':' IDENT    {$$.constant=0; $$.ident=0;
-                              trctx.out->printf("push %s:%s\n",(const char*)$1.getString(),
-						 (const char*)$3.getString());
+                              trctx.out->printf("push %s:%s\n",$1.getString().c_str(),
+						 $3.getString().c_str());
 			      trstack.adjust(-1);
                               }
@@ -688,6 +688,6 @@
 	trstack.adjust(-1);}
         else if (globalOk($1))
-	{ trctx.out->printf("push @%s\n%s @%s\n",(const char*)$1.getString(),
-			    $2.getInt()?"inc":"dec",(const char*)$1.getString());
+	{ trctx.out->printf("push @%s\n%s @%s\n",$1.getString().c_str(),
+			    $2.getInt()?"inc":"dec",$1.getString().c_str());
 	trstack.adjust(-1);}
 	else {badVariable($$,$1); return 1;}
@@ -697,5 +697,5 @@
                                 if (!handleAssignOp($$,$1,$3,assign_op_names[$2.getInt()]))
 	                        if (globalOk($1)) {SString t="@"; t+=$1.getString();
-                                  handleAssignOp2($$,(const char*)t,$3,assign_op_names[$2.getInt()],0,1);}
+                                  handleAssignOp2($$,t.c_str(),$3,assign_op_names[$2.getInt()],0,1);}
 				else { badVariable($$,$1); return 1; }
                               }
@@ -895,5 +895,5 @@
 		  if ($3.constant)
 			  {
-			  handleAssignOp2($$,(const char*)t,$5,assign_op_names[$4.getInt()],0,1);
+			  handleAssignOp2($$,t.c_str(),$5,assign_op_names[$4.getInt()],0,1);
 			  }
 		  else
@@ -902,5 +902,5 @@
 			  t=$1.getString();t+=".[m1]";
 			  trctx.out->printf("move s0,m1\n",str($1));
-			  handleAssignOp2($$,(const char*)t,$5,assign_op_names[$4.getInt()],sp,0);
+			  handleAssignOp2($$,t.c_str(),$5,assign_op_names[$4.getInt()],sp,0);
 			  if (sp) {trctx.out->printf("inc m0\n"); trstack.adjust(1);}
 			  }
@@ -1008,5 +1008,5 @@
      | FUNCTION IDENT
              { trctx.emitLine(); $$.constant=0; $$.ident=0; SString t=":"; t+=$1.getString(); $$.setString(t);
-	     trctx.out->printf("push :%s\n",(const char*)$2.getString());
+	     trctx.out->printf("push :%s\n",$2.getString().c_str());
 	     trstack.adjust(-1);
 	     }
@@ -1053,5 +1053,5 @@
 			     {sp=1; trctx.out->printf("move s1,m1\n");}
 		     t="[m1]."; t+=str($3);
-		     handleAssignOp2($$,(const char*)t,$5,assign_op_names[$4.getInt()],sp,0);
+		     handleAssignOp2($$,t.c_str(),$5,assign_op_names[$4.getInt()],sp,0);
 		     if (sp) {trctx.out->printf("inc m0\n");trstack.adjust(1);}
 		     }
@@ -1295,5 +1295,5 @@
 SString ret((len*11)/10+10);
 ret+='\"';
-const char*t=(const char*)s;
+const char*t=s.c_str();
 while(len>0)
 	{
@@ -1464,5 +1464,5 @@
 SymTabEntry* found=trstack.globals.find(var.getString());
 if (found) return true;
-return framscriptIsGlobalName(var.getString());
+return framscriptIsGlobalName(var.getString().c_str());
 }
 
@@ -1539,5 +1539,5 @@
 else if (globalOk(var))
 	{
-	trctx.out->printf("push @%s\n",(const char*)var.getString());
+	trctx.out->printf("push @%s\n",var.getString().c_str());
 	trstack.adjust(-1);
 	return true;
