Index: /cpp/frams/genetics/preconfigured.h
===================================================================
--- /cpp/frams/genetics/preconfigured.h	(revision 713)
+++ /cpp/frams/genetics/preconfigured.h	(revision 714)
@@ -1,4 +1,4 @@
 // This file is a part of Framsticks SDK.  http://www.framsticks.com/
-// Copyright (C) 1999-2015  Maciej Komosinski and Szymon Ulatowski.
+// Copyright (C) 1999-2017  Maciej Komosinski and Szymon Ulatowski.
 // See LICENSE.txt for details.
 
@@ -15,25 +15,28 @@
 class PreconfiguredGenetics
 {
-  public:
-DefaultGenoConvManager gcm;
-GenMan genman;
-Geno::Validators validators;
-ModelGenoValidator model_validator; //validation through conversion
+public:
+	DefaultGenoConvManager gcm;
+	GenMan genman;
+	Geno::Validators validators;
+	ModelGenoValidator model_validator; //validation through conversion
 
-PreconfiguredGenetics()
+	PreconfiguredGenetics()
 	{
-	gcm.addDefaultConverters(); //without converters, the application would only handle "format 0" genotypes
-	if (Geno::useConverters(&gcm)!=NULL)
-		logPrintf("PreconfiguredGenetics", "init", LOG_WARN, "Geno converters already configured"); //someone is using multiple PreconfiguredGenetics objects? (or other potentially unsafe configuration)
-	if (Geno::useValidators(&validators)!=NULL)
-		logPrintf("PreconfiguredGenetics", "init", LOG_WARN, "Geno validators already configured");
-	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.
+		gcm.addDefaultConverters(); //without converters, the application would only handle "format 0" genotypes
+		if (Geno::useConverters(&gcm) != NULL)
+			logPrintf("PreconfiguredGenetics", "init", LOG_WARN, "Geno converters already configured"); //someone is using multiple PreconfiguredGenetics objects? (or other potentially unsafe configuration)
+		if (Geno::useValidators(&validators) != NULL)
+			logPrintf("PreconfiguredGenetics", "init", LOG_WARN, "Geno validators already configured");
+		static const char* genactive_classes[] = { "N", "G", "T", "S", "*", "|", "@", NULL };
+		NeuroClass::resetActive();
+		NeuroClass::setGenActive(genactive_classes);
+		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.
 	}
 
-~PreconfiguredGenetics()
+	~PreconfiguredGenetics()
 	{
-	Geno::useConverters(NULL);
-	Geno::useValidators(NULL);
+		Geno::useConverters(NULL);
+		Geno::useValidators(NULL);
 	}
 };
Index: /cpp/frams/model/modelparts.cpp
===================================================================
--- /cpp/frams/model/modelparts.cpp	(revision 713)
+++ /cpp/frams/model/modelparts.cpp	(revision 714)
@@ -1,4 +1,4 @@
 // This file is a part of Framsticks SDK.  http://www.framsticks.com/
-// Copyright (C) 1999-2015  Maciej Komosinski and Szymon Ulatowski.
+// Copyright (C) 1999-2017  Maciej Komosinski and Szymon Ulatowski.
 // See LICENSE.txt for details.
 
@@ -30,499 +30,533 @@
 
 template<>
-char ModelUserTags::reg[5]={0};
+char ModelUserTags::reg[5] = { 0 };
 
 /////////////////////////
 
 PartBase::~PartBase()
-{if (mapped) delete mapped;}
+{
+	if (mapped) delete mapped;
+}
 
 void PartBase::notifyMappingChange()
 {
-if (owner) owner->partmappingchanged=1;
+	if (owner) owner->partmappingchanged = 1;
 }
 
 void PartBase::setMapping(const IRange &r)
 {
-if (mapped) (*mapped)=r;
-else mapped=new MultiRange(r);
-notifyMappingChange();
+	if (mapped) (*mapped) = r;
+	else mapped = new MultiRange(r);
+	notifyMappingChange();
 }
 
 void PartBase::clearMapping()
 {
-if (mapped) {delete mapped; mapped=0;}
+	if (mapped) { delete mapped; mapped = 0; }
 }
 
 void PartBase::addMapping(const IRange &r)
 {
-if (mapped) mapped->add(r);
-else mapped=new MultiRange(r);
-notifyMappingChange();
+	if (mapped) mapped->add(r);
+	else mapped = new MultiRange(r);
+	notifyMappingChange();
 }
 
 void PartBase::setMapping(const MultiRange &mr)
 {
-if (mapped) (*mapped)=mr;
-else mapped=new MultiRange(mr);
-notifyMappingChange();
+	if (mapped) (*mapped) = mr;
+	else mapped = new MultiRange(mr);
+	notifyMappingChange();
 }
 
 void PartBase::addMapping(const MultiRange &mr)
 {
-if (mapped) mapped->add(mr);
-else mapped=new MultiRange(mr);
-notifyMappingChange();
-}
-
-void PartBase::setInfo(const SString& name,const SString& value)
-{
-strSetField(info,name,value);
-}
-
-void PartBase::setInfo(const SString& name,int value)
-{
-setInfo(name,SString::valueOf(value));
-}
-
-void PartBase::setInfo(const SString& name,double value)
-{
-setInfo(name,SString::valueOf(value));
+	if (mapped) mapped->add(mr);
+	else mapped = new MultiRange(mr);
+	notifyMappingChange();
+}
+
+void PartBase::setInfo(const SString& name, const SString& value)
+{
+	strSetField(info, name, value);
+}
+
+void PartBase::setInfo(const SString& name, int value)
+{
+	setInfo(name, SString::valueOf(value));
+}
+
+void PartBase::setInfo(const SString& name, double value)
+{
+	setInfo(name, SString::valueOf(value));
 }
 
 SString PartBase::getInfo(const SString& name)
 {
-return strGetField(info,name);
+	return strGetField(info, name);
 }
 
 /////////////////////////
 
-NeuroClass::NeuroClass(ParamEntry *_props,SString _description,
-		       int _prefinputs,int _prefoutput,int _preflocation,
-		       int *_vectordata,bool own_vd,int vhints)
+NeuroClass::NeuroClass(ParamEntry *_props, SString _description,
+	int _prefinputs, int _prefoutput, int _preflocation,
+	int *_vectordata, bool own_vd, int vhints)
 	:ownedvectordata(own_vd),
-	 name(_props->name),longname(_props->id),description(_description),
-	 props(_props),ownedprops(false),
-	 prefinputs(_prefinputs),
-	 prefoutput(_prefoutput),
-	 preflocation(_preflocation),
-	 vectordata(_vectordata),
-	 visualhints(vhints),impl_count(0),/*impl(0),*/active(1),genactive(0)
+	name(_props->name), longname(_props->id), description(_description),
+	props(_props), ownedprops(false),
+	prefinputs(_prefinputs),
+	prefoutput(_prefoutput),
+	preflocation(_preflocation),
+	vectordata(_vectordata),
+	visualhints(vhints), impl_count(0),/*impl(0),*/active(1), genactive(0)
 {}
 
 NeuroClass::~NeuroClass()
 {
-setSymbolGlyph(0,0);
-if (props && ownedprops)
-	ParamObject::freeParamTab(props);
+	setSymbolGlyph(0, 0);
+	if (props && ownedprops)
+		ParamObject::freeParamTab(props);
 }
 
 NeuroClass::NeuroClass()
 	:ownedvectordata(0),
-	 name("Invalid"),
-	 props(empty_paramtab),ownedprops(false),
-	 prefinputs(0), prefoutput(0),
-	 preflocation(0), vectordata(0), 
-	 visualhints(0),impl_count(0), /*impl(0),*/ active(1), genactive(0)
+	name("Invalid"),
+	props(empty_paramtab), ownedprops(false),
+	prefinputs(0), prefoutput(0),
+	preflocation(0), vectordata(0),
+	visualhints(0), impl_count(0), /*impl(0),*/ active(1), genactive(0)
 {}
 
+void NeuroClass::resetActive()
+{
+	for (int i = 0; i < Neuro::getClassCount(); i++)
+	{
+		Neuro::getClass(i)->genactive = 0;
+		Neuro::getClass(i)->active = 1;
+	}
+}
+
+void NeuroClass::setGenActive(const char* genactive_classes[])
+{
+	for (const char** n = genactive_classes; *n; n++)
+	{
+		NeuroClass* cls = Neuro::getClass(*n);
+		if (cls) cls->genactive = 1;
+	}
+}
+
 SString NeuroClass::getSummary()
 {
-SString t;
-t=getDescription();
-if (t.len()) t+="\n\n";
-t+="Characteristics:\n";
-if(getPreferredInputs())
-	{
-	if (getPreferredInputs()<0) t+="   supports any number of inputs\n";
-	else if (getPreferredInputs()==1) t+="   uses single input\n";
-	else t+=SString::sprintf("   uses %d inputs\n",getPreferredInputs());
-	}
-else t+="   does not use inputs\n";
-if(getPreferredOutput())
-	t+="   provides output value\n";
-else
-	t+="   does not provide output value\n";
-switch(getPreferredLocation())
-	{
-	case 0: t+="   does not require location in body\n"; break;
-	case 1: t+="   should be located on a Part\n"; break;
-	case 2: t+="   should be located on a Joint\n"; break;
-	}
-Param p=getProperties();
-if (p.getPropCount())
-	{
-	if (t.len()) t+="\n\n";
-	t+="Properties:\n";
-	const char *h;
+	SString t;
+	t = getDescription();
+	if (t.len()) t += "\n\n";
+	t += "Characteristics:\n";
+	if (getPreferredInputs())
+	{
+		if (getPreferredInputs() < 0) t += "   supports any number of inputs\n";
+		else if (getPreferredInputs() == 1) t += "   uses single input\n";
+		else t += SString::sprintf("   uses %d inputs\n", getPreferredInputs());
+	}
+	else t += "   does not use inputs\n";
+	if (getPreferredOutput())
+		t += "   provides output value\n";
+	else
+		t += "   does not provide output value\n";
+	switch (getPreferredLocation())
+	{
+	case 0: t += "   does not require location in body\n"; break;
+	case 1: t += "   should be located on a Part\n"; break;
+	case 2: t += "   should be located on a Joint\n"; break;
+	}
+	Param p = getProperties();
+	if (p.getPropCount())
+	{
+		if (t.len()) t += "\n\n";
+		t += "Properties:\n";
+		const char *h;
+		int i;
+		for (i = 0; i < p.getPropCount(); i++)
+		{
+			if (i) t += "\n";
+			t += "   "; t += p.name(i); t += " ("; t += p.id(i); t += ") ";
+			t += p.describeType(i);
+			if (h = p.help(i)) if (*h) { t += " - "; t += h; }
+		}
+	}
+	return t;
+}
+
+/////////////////////////
+
+/////////////////////////////////////
+
+Neuro::Neuro(double _state, double _inertia, double _force, double _sigmo)
+	:PartBase(getDefaultStyle()), state(_state)
+#ifdef MODEL_V1_COMPATIBLE
+	,inertia(_inertia),force(_force),sigmo(_sigmo)
+#endif
+{
+#ifdef MODEL_V1_COMPATIBLE
+	olditems=0;
+#endif
+	flags = 0;
+	myclass = 0;
+	knownclass = 1;
+	part_refno = -1; joint_refno = -1;
+}
+
+Neuro::Neuro(void) :PartBase(getDefaultStyle())
+{
+	defassign();
+	state = 0.0;
+	myclass = NULL;
+	myclassname = "N";//default d="N" but f0.def is unable to set this (d is GETSET, not a regular FIELD)
+	knownclass = 0;
+	refno = 0;
+	pos = Pt3D_0; rot = Pt3D_0;
+	parent = 0; part = 0; joint = 0;
+	parentcount = 0;
+#ifdef MODEL_V1_COMPATIBLE
+	olditems=0;
+#endif
+	flags = 0;
+	part_refno = -1; joint_refno = -1;
+}
+
+
+Neuro::~Neuro()
+{
+#ifdef MODEL_V1_COMPATIBLE
+	if (olditems) delete olditems;
+#endif
 	int i;
-	for(i=0;i<p.getPropCount();i++)
-		{
-		if (i) t+="\n";
-		t+="   "; t+=p.name(i); t+=" ("; t+=p.id(i); t+=") ";
-		t+=p.describeType(i);
-		if (h=p.help(i)) if (*h) {t+=" - "; t+=h;}
-		}
-	}
-return t;
-}
-
-/////////////////////////
-
-/////////////////////////////////////
-
-Neuro::Neuro(double _state,double _inertia,double _force,double _sigmo)
-	:PartBase(getDefaultStyle()),state(_state)
+	for (i = 0; i < inputs.size(); i++)
+	{
+		NInput &ni = inputs(i);
+		if (ni.info) delete ni.info;
+	}
+}
+
+SString** Neuro::inputInfo(int i)
+{
+	if (i >= getInputCount()) return 0;
+	return &inputs(i).info;
+}
+
+void Neuro::setInputInfo(int i, const SString& name, const SString &value)
+{
+	SString **s = inputInfo(i);
+	if (!s) return;
+	if (!*s) *s = new SString();
+	strSetField(**s, name, value);
+}
+
+void Neuro::setInputInfo(int i, const SString& name, int value)
+{
+	setInputInfo(i, name, SString::valueOf(value));
+}
+
+void Neuro::setInputInfo(int i, const SString& name, double value)
+{
+	setInputInfo(i, name, SString::valueOf(value));
+}
+
+SString Neuro::getInputInfo(int i)
+{
+	SString **s = inputInfo(i);
+	if (!s) return SString();
+	if (!*s) return SString();
+	return **s;
+}
+
+SString Neuro::getInputInfo(int i, const SString& name)
+{
+	SString **s = inputInfo(i);
+	if (!s) return SString();
+	if (!*s) return SString();
+	return strGetField(**s, name);
+}
+
+void Neuro::operator=(const Neuro& src)
+{
+	refno = src.refno;
 #ifdef MODEL_V1_COMPATIBLE
-,inertia(_inertia),force(_force),sigmo(_sigmo)
+	neuro_refno=-1;
+	conn_refno=-1;
+	force=src.force;
+	sigmo=src.sigmo;
+	inertia=src.inertia;
+	weight=src.weight;
+	olditems=0;
 #endif
-{
-#ifdef MODEL_V1_COMPATIBLE
-olditems=0;
-#endif
-flags=0;
-myclass=0;
-knownclass=1;
-part_refno=-1; joint_refno=-1;
-}
-
-Neuro::Neuro(void):PartBase(getDefaultStyle())
-{
-defassign();
-state=0.0;
-myclass=NULL;
-myclassname="N";//default d="N" but f0.def is unable to set this (d is GETSET, not a regular FIELD)
-knownclass=0;
-refno=0;
-pos=Pt3D_0; rot=Pt3D_0;
-parent=0; part=0; joint=0;
-parentcount=0;
-#ifdef MODEL_V1_COMPATIBLE
-olditems=0;
-#endif
-flags=0;
-part_refno=-1; joint_refno=-1;
-}
-
-
-Neuro::~Neuro()
-{
-#ifdef MODEL_V1_COMPATIBLE
-if (olditems) delete olditems;
-#endif
-int i;
-for(i=0;i<inputs.size();i++)
-	{
-	NInput &ni=inputs(i);
-	if (ni.info) delete ni.info;
-	}
-}
-
-SString** Neuro::inputInfo(int i)
-{
-if (i>=getInputCount()) return 0;
-return &inputs(i).info;
-}
-
-void Neuro::setInputInfo(int i,const SString& name,const SString &value)
-{
-SString **s=inputInfo(i);
-if (!s) return;
-if (!*s) *s=new SString();
-strSetField(**s,name,value);
-}
-
-void Neuro::setInputInfo(int i,const SString& name,int value)
-{
-setInputInfo(i,name,SString::valueOf(value));
-}
-
-void Neuro::setInputInfo(int i,const SString& name,double value)
-{
-setInputInfo(i,name,SString::valueOf(value));
-}
-
-SString Neuro::getInputInfo(int i)
-{
-SString **s=inputInfo(i);
-if (!s) return SString();
-if (!*s) return SString();
-return **s;
-}
-
-SString Neuro::getInputInfo(int i,const SString& name)
-{
-SString **s=inputInfo(i);
-if (!s) return SString();
-if (!*s) return SString();
-return strGetField(**s,name);
-}
-
-void Neuro::operator=(const Neuro& src)
-{
-refno=src.refno;
-#ifdef MODEL_V1_COMPATIBLE
-neuro_refno=-1;
-conn_refno=-1;
-force=src.force;
-sigmo=src.sigmo;
-inertia=src.inertia;
-weight=src.weight;
-olditems=0;
-#endif
-state=src.state;
-part_refno=-1;
-joint_refno=-1;
-pos=src.pos; rot=src.rot;
-parent=0; part=0; joint=0;
-parentcount=0;
-flags=0;
-myclass=src.myclass;
-knownclass=src.knownclass;
-myclassname=src.myclassname;
-myclassparams=src.myclassparams;
+	state = src.state;
+	part_refno = -1;
+	joint_refno = -1;
+	pos = src.pos; rot = src.rot;
+	parent = 0; part = 0; joint = 0;
+	parentcount = 0;
+	flags = 0;
+	myclass = src.myclass;
+	knownclass = src.knownclass;
+	myclassname = src.myclassname;
+	myclassparams = src.myclassparams;
 }
 
 void Neuro::attachToPart(int i)
-{attachToPart((i>=0)?owner->getPart(i):0);}
+{
+	attachToPart((i >= 0) ? owner->getPart(i) : 0);
+}
 
 void Neuro::attachToJoint(int i)
-{attachToJoint((i>=0)?owner->getJoint(i):0);}
+{
+	attachToJoint((i >= 0) ? owner->getJoint(i) : 0);
+}
 
 int Neuro::getClassCount()
-{return NeuroLibrary::staticlibrary.getClassCount();}
+{
+	return NeuroLibrary::staticlibrary.getClassCount();
+}
 
 NeuroClass* Neuro::getClass(int classindex)
-{return NeuroLibrary::staticlibrary.getClass(classindex);}
+{
+	return NeuroLibrary::staticlibrary.getClass(classindex);
+}
 
 NeuroClass* Neuro::getClass(const SString& classname)
-{return NeuroLibrary::staticlibrary.findClass(classname);}
+{
+	return NeuroLibrary::staticlibrary.findClass(classname);
+}
 
 int Neuro::getClassIndex(const NeuroClass*nc)
-{return NeuroLibrary::staticlibrary.classes.find((void*)nc);}
+{
+	return NeuroLibrary::staticlibrary.classes.find((void*)nc);
+}
 
 NeuroClass* Neuro::getClass()
 {
-checkClass();
-return myclass;
+	checkClass();
+	return myclass;
 }
 
 void Neuro::setClass(NeuroClass* cl)
 {
-myclass=cl;
-myclassname=cl->getName();
-knownclass=1;
+	myclass = cl;
+	myclassname = cl->getName();
+	knownclass = 1;
 }
 
 SString Neuro::getClassName(int classindex)
 {
-NeuroClass *cl=NeuroLibrary::staticlibrary.getClass(classindex);
-return cl? cl->getName() : SString();
+	NeuroClass *cl = NeuroLibrary::staticlibrary.getClass(classindex);
+	return cl ? cl->getName() : SString();
 }
 
 void Neuro::setDetails(const SString& details)
 {
-int colon=details.indexOf(':');
-if (colon>=0) {myclassname=details.substr(0,colon); myclassparams=details.substr(colon+1);}
-else {myclassname=details; myclassparams=0;}
-knownclass=0;
+	int colon = details.indexOf(':');
+	if (colon >= 0) { myclassname = details.substr(0, colon); myclassparams = details.substr(colon + 1); }
+	else { myclassname = details; myclassparams = 0; }
+	knownclass = 0;
 }
 
 SString Neuro::getDetails()
 {
-SString ret=getClassName();
-if (myclassparams.len()) {if (!ret.len()) ret="N"; ret+=":"; ret+=myclassparams;}
-return ret;
+	SString ret = getClassName();
+	if (myclassparams.len()) { if (!ret.len()) ret = "N"; ret += ":"; ret += myclassparams; }
+	return ret;
 }
 
 void Neuro::checkClass()
 {
-if (knownclass) return;
-myclass=getClass(myclassname);
-knownclass=1;
+	if (knownclass) return;
+	myclass = getClass(myclassname);
+	knownclass = 1;
 }
 
 SyntParam Neuro::classProperties(bool handle_defaults_when_saving)
 {
-NeuroClass *cl=getClass();
-ParamEntry *pe = cl ? cl->getParamTab() : emptyParamTab;
-return SyntParam(pe,&myclassparams,handle_defaults_when_saving);
+	NeuroClass *cl = getClass();
+	ParamEntry *pe = cl ? cl->getParamTab() : emptyParamTab;
+	return SyntParam(pe, &myclassparams, handle_defaults_when_saving);
 }
 
 SString Neuro::getClassName()
 {
-return myclassname;
+	return myclassname;
 }
 
 void Neuro::setClassName(const SString& clazz)
 {
-myclassname=clazz;
-knownclass=0;
-}
-
-int Neuro::addInput(Neuro* child,double weight,const SString *info)
-{
-inputs+=NInput(child,weight,(info&&(info->len()))?new SString(*info):0);
-child->parentcount++;
-if (child->parentcount==1) {child->parent=this;}
-return inputs.size()-1;
+	myclassname = clazz;
+	knownclass = 0;
+}
+
+int Neuro::addInput(Neuro* child, double weight, const SString *info)
+{
+	inputs += NInput(child, weight, (info && (info->len())) ? new SString(*info) : 0);
+	child->parentcount++;
+	if (child->parentcount == 1) { child->parent = this; }
+	return inputs.size() - 1;
 }
 
 int Neuro::findInput(Neuro* child) const
 {
-for(int i=0;i<inputs.size();i++)
-	if (inputs(i).n==child) return i;
-return -1;
-}
-
-Neuro* Neuro::getInput(int i,double &weight) const
-{
-if (i>=getInputCount()) return 0;
-NInput &inp=inputs(i);
-weight=inp.weight;
-return inp.n;
+	for (int i = 0; i < inputs.size(); i++)
+		if (inputs(i).n == child) return i;
+	return -1;
+}
+
+Neuro* Neuro::getInput(int i, double &weight) const
+{
+	if (i >= getInputCount()) return 0;
+	NInput &inp = inputs(i);
+	weight = inp.weight;
+	return inp.n;
 }
 
 double Neuro::getInputWeight(int i) const
 {
-return inputs(i).weight;
-}
-
-void Neuro::setInputWeight(int i,double w)
-{
-inputs(i).weight=w;
-}
-
-void Neuro::setInput(int i,Neuro* n)
-{
-NInput &inp=inputs(i);
-inp.n=n;
-}
-
-void Neuro::setInput(int i,Neuro* n,double w)
-{
-NInput &inp=inputs(i);
-inp.n=n;
-inp.weight=w;
+	return inputs(i).weight;
+}
+
+void Neuro::setInputWeight(int i, double w)
+{
+	inputs(i).weight = w;
+}
+
+void Neuro::setInput(int i, Neuro* n)
+{
+	NInput &inp = inputs(i);
+	inp.n = n;
+}
+
+void Neuro::setInput(int i, Neuro* n, double w)
+{
+	NInput &inp = inputs(i);
+	inp.n = n;
+	inp.weight = w;
 }
 
 void Neuro::removeInput(int refno)
 {
-Neuro *child=getInput(refno);
-child->parentcount--;
-if (child->parent==this) child->parent=0;
-SString *s=inputs(refno).info;
-if (s) delete s;
-inputs.remove(refno);
+	Neuro *child = getInput(refno);
+	child->parentcount--;
+	if (child->parent == this) child->parent = 0;
+	SString *s = inputs(refno).info;
+	if (s) delete s;
+	inputs.remove(refno);
 }
 
 int Neuro::removeInput(Neuro* child)
 {
-int i=findInput(child);
-if (i>=0) removeInput(i);
-return i;
+	int i = findInput(child);
+	if (i >= 0) removeInput(i);
+	return i;
 }
 
 int Neuro::getOutputsCount() const
 {
-   int c=0;
-   for(int i=0;i<owner->getNeuroCount();i++)
-     for(int j=0;j<owner->getNeuro(i)->getInputCount();j++) c+=owner->getNeuro(i)->getInput(j)==this;
-   return c;
+	int c = 0;
+	for (int i = 0; i < owner->getNeuroCount(); i++)
+		for (int j = 0; j < owner->getNeuro(i)->getInputCount(); j++) c += owner->getNeuro(i)->getInput(j) == this;
+	return c;
 }
 
 int Neuro::isOldEffector()
 {
-static SString bend("|"),rot("@");
-return ((getClassName()==bend)||(getClassName()==rot));
+	static SString bend("|"), rot("@");
+	return ((getClassName() == bend) || (getClassName() == rot));
 }
 
 int Neuro::isOldReceptor()
 {
-static SString g("G"),t("T"),s("S");
-return ((getClassName()==g)||(getClassName()==t)||(getClassName()==s));
+	static SString g("G"), t("T"), s("S");
+	return ((getClassName() == g) || (getClassName() == t) || (getClassName() == s));
 }
 
 int Neuro::isOldNeuron()
 {
-static SString n("N");
-return (getClassName()==n);
+	static SString n("N");
+	return (getClassName() == n);
 }
 
 int Neuro::isNNConnection()
 {
-static SString conn("-");
-return (getClassName()==conn);
-}
-
-int Neuro::findInputs(SList& result,const char* classname,const Part* part,const Joint* joint) const
-{
-Neuro *nu;
-SString cn(classname);
-int n0=result.size();
-for(int i=0;nu=getInput(i);i++)
-	{
-	if (part)
-		if (nu->part != part) continue;
-	if (joint)
-		if (nu->joint != joint) continue;
-	if (classname)
-		if (nu->getClassName() != cn) continue;
-	result+=(void*)nu;
-	}
-return result.size()-n0;
-}
-
-int Neuro::findOutputs(SList& result,const char* classname,const Part* part,const Joint* joint) const
+	static SString conn("-");
+	return (getClassName() == conn);
+}
+
+int Neuro::findInputs(SList& result, const char* classname, const Part* part, const Joint* joint) const
+{
+	Neuro *nu;
+	SString cn(classname);
+	int n0 = result.size();
+	for (int i = 0; nu = getInput(i); i++)
+	{
+		if (part)
+			if (nu->part != part) continue;
+		if (joint)
+			if (nu->joint != joint) continue;
+		if (classname)
+			if (nu->getClassName() != cn) continue;
+		result += (void*)nu;
+	}
+	return result.size() - n0;
+}
+
+int Neuro::findOutputs(SList& result, const char* classname, const Part* part, const Joint* joint) const
 { // not very efficient...
-Neuro *nu,*inp;
-SString cn(classname);
-SList found;
-int n0=result.size();
-for(int i=0;nu=getModel().getNeuro(i);i++)
-	{
-	if (part)
-		if (nu->part != part) continue;
-	if (joint)
-		if (nu->joint != joint) continue;
-	if (classname)
-		if (inp->getClassName() != cn) continue;
-	for (int j=0;inp=nu->getInput(j);j++)
-		if (inp==this)
+	Neuro *nu, *inp;
+	SString cn(classname);
+	SList found;
+	int n0 = result.size();
+	for (int i = 0; nu = getModel().getNeuro(i); i++)
+	{
+		if (part)
+			if (nu->part != part) continue;
+		if (joint)
+			if (nu->joint != joint) continue;
+		if (classname)
+			if (inp->getClassName() != cn) continue;
+		for (int j = 0; inp = nu->getInput(j); j++)
+			if (inp == this)
 			{
-			result+=(void*)nu;
+			result += (void*)nu;
 			break;
 			}
 	}
-return result.size()-n0;
+	return result.size() - n0;
 }
 
 void Neuro::get_inputCount(PARAMGETARGS)
-{ret->setInt(inputs.size());}
-
-void Neuro::p_getInputNeuroDef(ExtValue *args,ExtValue *ret)
-{
-int i=args->getInt();
-if ((i<0)||(i>=inputs.size()))
-	ret->setEmpty();
-else
-	ret->setObject(ExtObject(&Neuro::getStaticParam(),inputs(i).n));
-}
-
-void Neuro::p_getInputWeight(ExtValue *args,ExtValue *ret)
-{
-int i=args->getInt();
-if ((i<0)||(i>=inputs.size()))
-	ret->setEmpty();
-else
-	ret->setDouble(inputs(i).weight);
-}
-
-void Neuro::p_getInputNeuroIndex(ExtValue *args,ExtValue *ret)
-{
-int i=args->getInt();
-if ((i<0)||(i>=inputs.size()))
-	ret->setInt(-1);
-else
-	ret->setInt(inputs(i).n->refno);
+{
+	ret->setInt(inputs.size());
+}
+
+void Neuro::p_getInputNeuroDef(ExtValue *args, ExtValue *ret)
+{
+	int i = args->getInt();
+	if ((i < 0) || (i >= inputs.size()))
+		ret->setEmpty();
+	else
+		ret->setObject(ExtObject(&Neuro::getStaticParam(), inputs(i).n));
+}
+
+void Neuro::p_getInputWeight(ExtValue *args, ExtValue *ret)
+{
+	int i = args->getInt();
+	if ((i < 0) || (i >= inputs.size()))
+		ret->setEmpty();
+	else
+		ret->setDouble(inputs(i).weight);
+}
+
+void Neuro::p_getInputNeuroIndex(ExtValue *args, ExtValue *ret)
+{
+	int i = args->getInt();
+	if ((i < 0) || (i >= inputs.size()))
+		ret->setInt(-1);
+	else
+		ret->setInt(inputs(i).n->refno);
 }
 
@@ -530,5 +564,5 @@
 {
 #ifndef SDK_WITHOUT_FRAMS
-NeuroClassExt::makeStaticObject(ret,getClass());
+	NeuroClassExt::makeStaticObject(ret, getClass());
 #endif
 }
@@ -538,73 +572,73 @@
 void OldItems::buildlist()
 { // guaranteed to work only for old NN layouts
- // (neurons,neuro connections, old receptors and effectors)
-if (listok) return;
- // inputs can contain both neuroitem connections (details="") and direct neuron references (details="N")
- // in OldItems we create neuroitems freom direct references
-for(int i=0;i<neuro.getInputCount();i++)
-	{
-	float w;
-	Neuro *n=neuro.getInput(i,w);
-	if (n->isOldNeuron())
+	// (neurons,neuro connections, old receptors and effectors)
+	if (listok) return;
+	// inputs can contain both neuroitem connections (details="") and direct neuron references (details="N")
+	// in OldItems we create neuroitems freom direct references
+	for(int i=0;i<neuro.getInputCount();i++)
+	{
+		float w;
+		Neuro *n=neuro.getInput(i,w);
+		if (n->isOldNeuron())
 		{
-		Neuro *ni=new Neuro();
-		ni->setClassName("-");
-		ni->weight=w;
-		ni->neuro_refno=neuro.refno;
-		ni->conn_refno=n->refno;
-		items+=ni;
-		syntitems+=ni;
+			Neuro *ni=new Neuro();
+			ni->setClassName("-");
+			ni->weight=w;
+			ni->neuro_refno=neuro.refno;
+			ni->conn_refno=n->refno;
+			items+=ni;
+			syntitems+=ni;
 		}
-	else
+		else
 		{
-		items+=n;
-		n->weight=w;
+			items+=n;
+			n->weight=w;
 		}
 	}
-SList outputs;
-neuro.findOutputs(outputs);
-FOREACH(Neuro*,n,outputs)
-	{
-	if (n->isNNConnection() || n->isOldNeuron())
-		outputs-=n;
-	}
-items+=outputs;
-listok=1;
+	SList outputs;
+	neuro.findOutputs(outputs);
+	FOREACH(Neuro*,n,outputs)
+	{
+		if (n->isNNConnection() || n->isOldNeuron())
+			outputs-=n;
+	}
+	items+=outputs;
+	listok=1;
 }
 
 void OldItems::freelist()
 {
-FOREACH(Neuro*,n,syntitems)
-	delete n;
-syntitems.clear();
-items.clear();
-listok=0;
+	FOREACH(Neuro*,n,syntitems)
+		delete n;
+	syntitems.clear();
+	items.clear();
+	listok=0;
 }
 
 int OldItems::getItemCount()
 {
-buildlist();
-return items.size();
+	buildlist();
+	return items.size();
 }
 
 NeuroItem *OldItems::getNeuroItem(int i)
 {
-buildlist();
-return (NeuroItem*)items(i);
+	buildlist();
+	return (NeuroItem*)items(i);
 }
 
 NeuroItem *OldItems::addNewNeuroItem()
 {
-Neuro *nu=neuro.getModel().addNewNeuro();
-nu->setClassName("-");
-if (listok) items+=nu;
-neuro.addInput(nu);
-return (NeuroItem*)nu;
+	Neuro *nu=neuro.getModel().addNewNeuro();
+	nu->setClassName("-");
+	if (listok) items+=nu;
+	neuro.addInput(nu);
+	return (NeuroItem*)nu;
 }
 
 int OldItems::findNeuroItem(NeuroItem *ni)
 {
-buildlist();
-return items.find((void*)ni);
+	buildlist();
+	return items.find((void*)ni);
 }
 #endif
@@ -613,7 +647,11 @@
 
 SString Part::getDefaultStyle()
-{return SString("part");}
+{
+	return SString("part");
+}
 SString Joint::getDefaultStyle()
-{return SString("joint");}
+{
+	return SString("joint");
+}
 /*
 const SString& Neuro::getDefaultStyle()
@@ -623,61 +661,63 @@
 */
 SString Neuro::getDefaultStyle()
-{return SString("neuro");}
-
-Part::Part(enum Shape s):PartBase(getDefaultStyle())
-{
-o=Orient_1;
-p=Pt3D_0;
-rot=Pt3D_0;
-flags=0;
-defassign();
-shape=s;
-mass=1;
+{
+	return SString("neuro");
+}
+
+Part::Part(enum Shape s) :PartBase(getDefaultStyle())
+{
+	o = Orient_1;
+	p = Pt3D_0;
+	rot = Pt3D_0;
+	flags = 0;
+	defassign();
+	shape = s;
+	mass = 1;
 }
 
 void Part::operator=(const Part& src)
 {
-p=src.p; o=src.o;
-flags=src.flags;
-mass=src.mass; density=src.density;
-friction=src.friction;
-ingest=src.ingest;
-assim=src.assim;
-size=src.size;
-rot=src.rot;
-refno=src.refno;
-vcolor=src.vcolor;
-vsize=src.vsize;
-vis_style=src.vis_style;
-shape=src.shape;
-scale=src.scale;
-hollow=src.hollow;
+	p = src.p; o = src.o;
+	flags = src.flags;
+	mass = src.mass; density = src.density;
+	friction = src.friction;
+	ingest = src.ingest;
+	assim = src.assim;
+	size = src.size;
+	rot = src.rot;
+	refno = src.refno;
+	vcolor = src.vcolor;
+	vsize = src.vsize;
+	vis_style = src.vis_style;
+	shape = src.shape;
+	scale = src.scale;
+	hollow = src.hollow;
 }
 
 void Part::setOrient(const Orient &_o)
 {
-o=_o;
-rot.getAngles(o.x,o.z);
+	o = _o;
+	rot.getAngles(o.x, o.z);
 }
 
 void Part::setRot(const Pt3D &r)
 {
-rot=r;
-o=Orient_1;
-o.rotate(rot);
-}
-
-void Part::setPositionAndRotationFromAxis(const Pt3D &p1,const Pt3D &p2)
-{
-Pt3D x=p2-p1;
-Pt3D dir(x.y,x.z,x.x);
-p=p1+x*0.5;
-rot.getAngles(x,dir);
+	rot = r;
+	o = Orient_1;
+	o.rotate(rot);
+}
+
+void Part::setPositionAndRotationFromAxis(const Pt3D &p1, const Pt3D &p2)
+{
+	Pt3D x = p2 - p1;
+	Pt3D dir(x.y, x.z, x.x);
+	p = p1 + x*0.5;
+	rot.getAngles(x, dir);
 }
 
 Param& Part::getStaticParam()
 {
-static Param p(f0_part_paramtab,0,"Part");
-return p;
+	static Param p(f0_part_paramtab, 0, "Part");
+	return p;
 }
 
@@ -685,78 +725,78 @@
 ///////////////////////////
 
-Joint::Joint():PartBase(getDefaultStyle())
-{
-rot=Pt3D_0;
-defassign();
-d.x=JOINT_DELTA_MARKER;
-d.y=JOINT_DELTA_MARKER;
-d.z=JOINT_DELTA_MARKER;
-part1=0; part2=0;
-flags=0;
-usedelta=0;
+Joint::Joint() :PartBase(getDefaultStyle())
+{
+	rot = Pt3D_0;
+	defassign();
+	d.x = JOINT_DELTA_MARKER;
+	d.y = JOINT_DELTA_MARKER;
+	d.z = JOINT_DELTA_MARKER;
+	part1 = 0; part2 = 0;
+	flags = 0;
+	usedelta = 0;
 }
 
 void Joint::operator=(const Joint& src)
 {
-rot=src.rot;
-d=src.d;
-shape=src.shape;
-stamina=src.stamina;
-stif=src.stif; rotstif=src.rotstif;
-vis_style=src.vis_style;
-vcolor=src.vcolor;
-part1=0; part2=0;
-flags=src.flags;
-usedelta=src.usedelta;
-refno=src.refno;
-}
-
-void Joint::attachToParts(Part* p1,Part* p2)
-{
-part1=p1;
-part2=p2;
-if (p1 && p2)
-	{
-	o=rot;
-	if (usedelta)
+	rot = src.rot;
+	d = src.d;
+	shape = src.shape;
+	stamina = src.stamina;
+	stif = src.stif; rotstif = src.rotstif;
+	vis_style = src.vis_style;
+	vcolor = src.vcolor;
+	part1 = 0; part2 = 0;
+	flags = src.flags;
+	usedelta = src.usedelta;
+	refno = src.refno;
+}
+
+void Joint::attachToParts(Part* p1, Part* p2)
+{
+	part1 = p1;
+	part2 = p2;
+	if (p1 && p2)
+	{
+		o = rot;
+		if (usedelta)
 		{
-		p1->o.transform(p2->o,o);
-//		p2->o.x=p1->o/o.x; p2->o.y=p1->o/o.y; p2->o.z=p1->o/o.z;
-		p2->p=p2->o.transform(d)+p1->p;
+			p1->o.transform(p2->o, o);
+			//		p2->o.x=p1->o/o.x; p2->o.y=p1->o/o.y; p2->o.z=p1->o/o.z;
+			p2->p = p2->o.transform(d) + p1->p;
 		}
 	}
 }
 
-void Joint::attachToParts(int p1,int p2)
-{
-attachToParts((p1>=0)?owner->getPart(p1):0,(p2>=0)?owner->getPart(p2):0);
+void Joint::attachToParts(int p1, int p2)
+{
+	attachToParts((p1 >= 0) ? owner->getPart(p1) : 0, (p2 >= 0) ? owner->getPart(p2) : 0);
 }
 
 void Joint::resetDelta()
 {
-d=Pt3D(JOINT_DELTA_MARKER,JOINT_DELTA_MARKER,JOINT_DELTA_MARKER);
+	d = Pt3D(JOINT_DELTA_MARKER, JOINT_DELTA_MARKER, JOINT_DELTA_MARKER);
 }
 
 void Joint::resetDeltaMarkers()
 {
-if (d.x==JOINT_DELTA_MARKER) d.x=0;
-if (d.y==JOINT_DELTA_MARKER) d.y=0;
-if (d.z==JOINT_DELTA_MARKER) d.z=0;
+	if (d.x == JOINT_DELTA_MARKER) d.x = 0;
+	if (d.y == JOINT_DELTA_MARKER) d.y = 0;
+	if (d.z == JOINT_DELTA_MARKER) d.z = 0;
 }
 
 void Joint::useDelta(bool use)
 {
-usedelta=use;
+	usedelta = use;
 }
 
 bool Joint::isDelta()
 {
-return usedelta;
+	return usedelta;
 }
 
 Param& Joint::getStaticParam()
 {
-static Param p(f0_joint_paramtab,0,"Joint");
-return p;
+	static Param p(f0_joint_paramtab, 0, "Joint");
+	return p;
 }
 
@@ -772,13 +812,13 @@
 ParamEntry f0_old_neuro_tab[]=
 {
-{"Connections",2,6,"n",},
-{"Other properties",},
-{"p",0,0,"part ref#","d",FIELD(part_refno),},
-{"j",0,0,"joint ref#","d",FIELD(joint_refno),},
-{"s",1,0,"state","f",FIELD(state),},
-{"in",1,0,"Inertia","f",FIELD(inertia),},
-{"fo",1,0,"Force","f",FIELD(force),},
-{"si",1,0,"Sigmoid","f",FIELD(sigmo),},
-{0,0,0,},
+	{"Connections",2,6,"n",},
+	{"Other properties",},
+	{"p",0,0,"part ref#","d",FIELD(part_refno),},
+	{"j",0,0,"joint ref#","d",FIELD(joint_refno),},
+	{"s",1,0,"state","f",FIELD(state),},
+	{"in",1,0,"Inertia","f",FIELD(inertia),},
+	{"fo",1,0,"Force","f",FIELD(force),},
+	{"si",1,0,"Sigmoid","f",FIELD(sigmo),},
+	{0,0,0,},
 }; 
 #undef FIELDSTRUCT
@@ -787,20 +827,20 @@
 ParamEntry f0_neuroitem_paramtab[]=
 {
-{"Connections",3,12,"ni",},
-{"Geometry",},
-{"Other",},
-{"n",0,0,"neuron ref#","d",FIELD(neuro_refno),},
-{"c",2,0,"connection ref#","d",FIELD(conn_refno),},
-{"w",2,0,"connection weight","f",FIELD(weight),},
-{"p",0,0,"part ref#","d",FIELD(part_refno),},
-{"j",0,0,"joint ref#","d",FIELD(joint_refno),},
-{"px",1,0,"position.x","f",FIELD(pos.x),},
-{"py",1,0,"position.y","f",FIELD(pos.y),},
-{"pz",1,0,"position.z","f",FIELD(pos.z),},
-{"rx",1,0,"rotation.x","f",FIELD(rot.x),},
-{"ry",1,0,"rotation.y","f",FIELD(rot.y),},
-{"rz",1,0,"rotation.z","f",FIELD(rot.z),},
-{"d",2,0,"item details","s",GETSET(details),},
-{0,0,0,},
+	{"Connections",3,12,"ni",},
+	{"Geometry",},
+	{"Other",},
+	{"n",0,0,"neuron ref#","d",FIELD(neuro_refno),},
+	{"c",2,0,"connection ref#","d",FIELD(conn_refno),},
+	{"w",2,0,"connection weight","f",FIELD(weight),},
+	{"p",0,0,"part ref#","d",FIELD(part_refno),},
+	{"j",0,0,"joint ref#","d",FIELD(joint_refno),},
+	{"px",1,0,"position.x","f",FIELD(pos.x),},
+	{"py",1,0,"position.y","f",FIELD(pos.y),},
+	{"pz",1,0,"position.z","f",FIELD(pos.z),},
+	{"rx",1,0,"rotation.x","f",FIELD(rot.x),},
+	{"ry",1,0,"rotation.y","f",FIELD(rot.y),},
+	{"rz",1,0,"rotation.z","f",FIELD(rot.z),},
+	{"d",2,0,"item details","s",GETSET(details),},
+	{0,0,0,},
 }; 
 #undef FIELDSTRUCT
@@ -809,54 +849,54 @@
 ////////////////////////////////////////
 
-ParamEntry Neuro::emptyParamTab[]=
-{
-{"Undefined Neuro",1,0,"?",},
-{0,0,0,},
+ParamEntry Neuro::emptyParamTab[] =
+{
+	{ "Undefined Neuro", 1, 0, "?", },
+	{ 0, 0, 0, },
 };
 
 Param Part::extraProperties()
 {
-return Param(f0_part_xtra_paramtab,this);
+	return Param(f0_part_xtra_paramtab, this);
 }
 
 Param Joint::extraProperties()
 {
-return Param(f0_joint_xtra_paramtab,this);
+	return Param(f0_joint_xtra_paramtab, this);
 }
 
 Param Neuro::extraProperties()
 {
-return Param(f0_neuro_xtra_paramtab,this);
+	return Param(f0_neuro_xtra_paramtab, this);
 }
 
 Param Part::properties()
 {
-return Param(f0_part_paramtab,this);
+	return Param(f0_part_paramtab, this);
 }
 
 Param Joint::properties()
 {
-return Param(usedelta?f0_joint_paramtab:f0_nodeltajoint_paramtab,this);
+	return Param(usedelta ? f0_joint_paramtab : f0_nodeltajoint_paramtab, this);
 }
 
 Param Neuro::properties()
 {
-return Param(f0_neuro_paramtab,this);
-}
-
-class NeuroExtParamTab: public ParamTab
-{
-  public:
-NeuroExtParamTab():ParamTab(f0_neuro_paramtab)
+	return Param(f0_neuro_paramtab, this);
+}
+
+class NeuroExtParamTab : public ParamTab
+{
+public:
+	NeuroExtParamTab() :ParamTab(f0_neuro_paramtab)
 	{
 #define FIELDSTRUCT NeuroExt
-	ParamEntry entry={"class",2,0,"neuro class","s",GETSET(neuroclass)};
+		ParamEntry entry = { "class", 2, 0, "neuro class", "s", GETSET(neuroclass) };
 #undef FIELDSTRUCT
-	add(&entry);
+		add(&entry);
 
 #define FIELDSTRUCT Neuro
-	ParamEntry entry2={"state",2,0,"state","f",FIELD(state)};
+		ParamEntry entry2 = { "state", 2, 0, "state", "f", FIELD(state) };
 #undef FIELDSTRUCT
-	add(&entry2);
+		add(&entry2);
 	}
 };
@@ -864,6 +904,6 @@
 Param& Neuro::getStaticParam()
 {
-static Param p(f0_neuro_paramtab,0,"NeuroDef");
-return p;
+	static Param p(f0_neuro_paramtab, 0, "NeuroDef");
+	return p;
 }
 
@@ -872,5 +912,5 @@
 NeuroConn::NeuroConn()
 {
-defassign();
+	defassign();
 }
 
@@ -879,13 +919,15 @@
 ParamEntry *NeuroExt::getParamTab()
 {
-static NeuroExtParamTab tab;
-return tab.getParamTab();
+	static NeuroExtParamTab tab;
+	return tab.getParamTab();
 }
 
 void NeuroExt::get_neuroclass(PARAMGETARGS)
-{ret->setString(getClassName());}
+{
+	ret->setString(getClassName());
+}
 
 int NeuroExt::set_neuroclass(PARAMSETARGS)
-{setClassName(arg->getString());return PSET_CHANGED;}
-
-
+{
+	setClassName(arg->getString()); return PSET_CHANGED;
+}
Index: /cpp/frams/model/modelparts.h
===================================================================
--- /cpp/frams/model/modelparts.h	(revision 713)
+++ /cpp/frams/model/modelparts.h	(revision 714)
@@ -1,4 +1,4 @@
 // This file is a part of Framsticks SDK.  http://www.framsticks.com/
-// Copyright (C) 1999-2015  Maciej Komosinski and Szymon Ulatowski.
+// Copyright (C) 1999-2017  Maciej Komosinski and Szymon Ulatowski.
 // See LICENSE.txt for details.
 
@@ -26,5 +26,5 @@
 class MultiRange;
 
-typedef UserTags<Model,void*,5> ModelUserTags;
+typedef UserTags<Model, void*, 5> ModelUserTags;
 
 /** Common base for model elements. */
@@ -32,32 +32,32 @@
 {
 public:
-SString vis_style;
-PartBase(const SString& s):vis_style(s),mapped(0) {}
-~PartBase();
-static SString getDefaultStyle(){return SString("none");}
-MultiRange *mapped;
-enum PartBaseFlags { Selected=1 };
-int flags;
-Model *owner;	///< backlink to the model
-
-SString info;
-
-Model &getModel() const {return *owner;}
-
-ModelUserTags userdata;
-
-void notifyMappingChange();
-
-void clearMapping();
-MultiRange* getMapping() {return mapped;}
-void setMapping(const IRange &mr);
-void addMapping(const IRange &mr);
-void setMapping(const MultiRange &mr);
-void addMapping(const MultiRange &mr);
-
-void setInfo(const SString& name,const SString& value);
-void setInfo(const SString& name,int value);
-void setInfo(const SString& name,double value);
-SString getInfo(const SString& name);
+	SString vis_style;
+	PartBase(const SString& s) :vis_style(s), mapped(0) {}
+	~PartBase();
+	static SString getDefaultStyle(){ return SString("none"); }
+	MultiRange *mapped;
+	enum PartBaseFlags { Selected = 1 };
+	int flags;
+	Model *owner;	///< backlink to the model
+
+	SString info;
+
+	Model &getModel() const { return *owner; }
+
+	ModelUserTags userdata;
+
+	void notifyMappingChange();
+
+	void clearMapping();
+	MultiRange* getMapping() { return mapped; }
+	void setMapping(const IRange &mr);
+	void addMapping(const IRange &mr);
+	void setMapping(const MultiRange &mr);
+	void addMapping(const MultiRange &mr);
+
+	void setInfo(const SString& name, const SString& value);
+	void setInfo(const SString& name, int value);
+	void setInfo(const SString& name, double value);
+	SString getInfo(const SString& name);
 };
 
@@ -65,108 +65,110 @@
 /// You can use this class for querying and adjusting constructed
 /// model properties
-class Part: public PartBase
-{
-friend class Model;
-static SString getDefaultStyle();
-Part(double _mass,double _size,double _density,double _friction,double _ingest,double _assim)
-	  :PartBase(getDefaultStyle()),mass(_mass),size(_size),density(_density),friction(_friction),ingest(_ingest),assim(_assim)
+class Part : public PartBase
+{
+	friend class Model;
+	static SString getDefaultStyle();
+	Part(double _mass, double _size, double _density, double _friction, double _ingest, double _assim)
+		:PartBase(getDefaultStyle()), mass(_mass), size(_size), density(_density), friction(_friction), ingest(_ingest), assim(_assim)
 	{}
-void defassign();
-public:
-// base properties - have special meaning and therefore are often accessed directly for convenience
-Pt3D p;    ///< 3d coordinates of the part
-Orient o;  ///< orientation in 3d space (rotation matrix)
-/// ParamInterface object is preferred way to get/set other properties.
-Param extraProperties();
-Param properties();
-paInt refno;
-Pt3D rot;///< rotation angles
-
-///
-paInt shape;///default=old Framsticks compatible, do not mix with shapes>0
-enum Shape {SHAPE_BALL_AND_STICK=0, SHAPE_ELLIPSOID=1, SHAPE_CUBOID=2, SHAPE_CYLINDER=3};
-double mass,size,density,friction,ingest,assim,hollow;
-Pt3D scale;
-Pt3D food;
-//SList points; // collistion points
-//Slist neurons; // "select * from owner->neurons where part=this" ;-)
-
-Pt3D vcolor;
-double vsize;
-
-Part(enum Shape s=SHAPE_BALL_AND_STICK);
-Part(const Part& src):PartBase(getDefaultStyle()) {operator=(src);}
-void operator=(const Part& src);
-
-void setPositionAndRotationFromAxis(const Pt3D &p1,const Pt3D &p2);
-void setOrient(const Orient &o);///< set part.o and calculates part.rot (rotation angles)
-void setRot(const Pt3D &r);///< set part.rot (rotation angles) and calculate part.o
-
-static Param& getStaticParam();
+	void defassign();
+public:
+	// base properties - have special meaning and therefore are often accessed directly for convenience
+	Pt3D p;    ///< 3d coordinates of the part
+	Orient o;  ///< orientation in 3d space (rotation matrix)
+	/// ParamInterface object is preferred way to get/set other properties.
+	Param extraProperties();
+	Param properties();
+	paInt refno;
+	Pt3D rot;///< rotation angles
+
+	///
+	paInt shape;///default=old Framsticks compatible, do not mix with shapes>0
+	enum Shape { SHAPE_BALL_AND_STICK = 0, SHAPE_ELLIPSOID = 1, SHAPE_CUBOID = 2, SHAPE_CYLINDER = 3 };
+	double mass, size, density, friction, ingest, assim, hollow;
+	Pt3D scale;
+	Pt3D food;
+	//SList points; // collistion points
+	//Slist neurons; // "select * from owner->neurons where part=this" ;-)
+
+	Pt3D vcolor;
+	double vsize;
+
+	Part(enum Shape s = SHAPE_BALL_AND_STICK);
+	Part(const Part& src) :PartBase(getDefaultStyle()) { operator=(src); }
+	void operator=(const Part& src);
+
+	void setPositionAndRotationFromAxis(const Pt3D &p1, const Pt3D &p2);
+	void setOrient(const Orient &o);///< set part.o and calculates part.rot (rotation angles)
+	void setRot(const Pt3D &r);///< set part.rot (rotation angles) and calculate part.o
+
+	static Param& getStaticParam();
 };
 
 /// Imaginary connection between two parts.
 /// Joint has no mass nor intertia but can transfer forces.
-class Joint: public PartBase
-{
-friend class Model;
-SString getDefaultStyle();
-Joint(double _stamina,double _stif,double _rotstif,double _d)
-	:PartBase(getDefaultStyle()),stamina(_stamina),stif(_stif),rotstif(_rotstif)
-	{d=Pt3D(_d,0,0);}
-void defassign();
-void resetDeltaMarkers();
-public:
-// base properties:
-paInt p1_refno,p2_refno; ///< parts' reference numbers
-
-Part *part1,*part2;	///< references to parts
-class Pt3D d;		///< position delta between parts
-class Pt3D rot;	///< orientation delta between parts expressed as 3 angles
-enum Shape {SHAPE_BALL_AND_STICK=0, SHAPE_FIXED=1};
-paInt shape;///< ball-and-stick=old Framsticks compatible, creates a physical rod between parts (cylinder or cuboid), do not mix with shape>0,  fixed=merge parts into one physical entity
-
-Joint();
-Joint(const Joint& src):PartBase(getDefaultStyle()) {operator=(src);}
-void operator=(const Joint& src);
-
-/** connect two parts with this joint.
-    p2 position will be adjusted if delta option is in effect.
-    @see isDelta()
-  */
-void attachToParts(Part* p1,Part* p2);
-/// @see attachToParts(Part*,Part*)
-void attachToParts(int p1,int p2);
-
-/** discard delta information but don't disable delta flag.
-    delta will be calculated from parts positions during final consistency check.
- */
-void resetDelta();
-
-/** enable or disable delta option.
-    delta value is not changed.
- */
-void useDelta(bool use);
-
-/** @return true if delta option is in effect.
-    @see useDelta(), resetDelta(), useDelta()
-*/
-bool isDelta(); 
-
-/// ParamInterface object is preferred way to get/set other properties.
-Param extraProperties();
-Param properties();
-
-// do not touch these:
-paInt refno; ///< this joint's reference number
-double stamina;
-double stif,rotstif;	///< stiffness for moving and bending forces
-class Orient o;	///< orientation delta between parts as rotation matrix
-/** flag: generated f0 should include delta data.
-    set by 'singlestep' if j: attributes use delta option */
-bool usedelta;
-Pt3D vcolor;
-
-static Param& getStaticParam();
+class Joint : public PartBase
+{
+	friend class Model;
+	SString getDefaultStyle();
+	Joint(double _stamina, double _stif, double _rotstif, double _d)
+		:PartBase(getDefaultStyle()), stamina(_stamina), stif(_stif), rotstif(_rotstif)
+	{
+		d = Pt3D(_d, 0, 0);
+	}
+	void defassign();
+	void resetDeltaMarkers();
+public:
+	// base properties:
+	paInt p1_refno, p2_refno; ///< parts' reference numbers
+
+	Part *part1, *part2;	///< references to parts
+	class Pt3D d;		///< position delta between parts
+	class Pt3D rot;	///< orientation delta between parts expressed as 3 angles
+	enum Shape { SHAPE_BALL_AND_STICK = 0, SHAPE_FIXED = 1 };
+	paInt shape;///< ball-and-stick=old Framsticks compatible, creates a physical rod between parts (cylinder or cuboid), do not mix with shape>0,  fixed=merge parts into one physical entity
+
+	Joint();
+	Joint(const Joint& src) :PartBase(getDefaultStyle()) { operator=(src); }
+	void operator=(const Joint& src);
+
+	/** connect two parts with this joint.
+		p2 position will be adjusted if delta option is in effect.
+		@see isDelta()
+		*/
+	void attachToParts(Part* p1, Part* p2);
+	/// @see attachToParts(Part*,Part*)
+	void attachToParts(int p1, int p2);
+
+	/** discard delta information but don't disable delta flag.
+		delta will be calculated from parts positions during final consistency check.
+		*/
+	void resetDelta();
+
+	/** enable or disable delta option.
+		delta value is not changed.
+		*/
+	void useDelta(bool use);
+
+	/** @return true if delta option is in effect.
+		@see useDelta(), resetDelta(), useDelta()
+		*/
+	bool isDelta();
+
+	/// ParamInterface object is preferred way to get/set other properties.
+	Param extraProperties();
+	Param properties();
+
+	// do not touch these:
+	paInt refno; ///< this joint's reference number
+	double stamina;
+	double stif, rotstif;	///< stiffness for moving and bending forces
+	class Orient o;	///< orientation delta between parts as rotation matrix
+	/** flag: generated f0 should include delta data.
+		set by 'singlestep' if j: attributes use delta option */
+	bool usedelta;
+	Pt3D vcolor;
+
+	static Param& getStaticParam();
 };
 
@@ -177,5 +179,5 @@
 class NeuroClass;
 
-typedef UserTags<NeuroClass,void*,5> NeuroClassUserTags;
+typedef UserTags<NeuroClass, void*, 5> NeuroClassUserTags;
 
 /** Information about neuron class.
@@ -183,94 +185,104 @@
 class NeuroClass
 {
-bool ownedvectordata;
-void operator=(const NeuroClass& nosuchthich){}
-  public:
-SString name,longname,description;
-ParamEntry *props;
-bool ownedprops;//< destructor will free props using ParamObject::freeParamTab
-paInt prefinputs,prefoutput;
-paInt preflocation;
-int *vectordata;
-paInt visualhints;
-
-//void *impl;
-int impl_count;
-bool active;
-int genactive;
-NeuroClassUserTags userdata;
-
-//////////////////////
-~NeuroClass();
-NeuroClass();
-NeuroClass(ParamEntry *_props,SString _description,
-	   int _prefinputs,int _prefoutput,int _preflocation,int *_vectordata,bool own_vd=1,int vhints=0);
-/** class name for use in Neuro::setClassName(), Neuro::setDetails() (former 'moredata' field),
-    eg. "N","-",G" */
-const SString& getName() {return name;}
-/** human friendly name, eg. "Neuron","Link","Gyroscope"  */
-const SString& getLongName() {return longname;}
-/** long description */
-const SString& getDescription() {return description;}
-ParamEntry* getParamTab() {return props;}
-
-/** NeuroClass specific properties, recognized by all neurons of this class */
-Param getProperties() {return Param(props);}
-
-/** preferred number of inputs, -1 = no preference (any number will go).
-    extra inputs may be ignored by the object (depends on the class).
- */
-int getPreferredInputs() {return (int)prefinputs;}
-
-/** @return 0 if this object doesn't provide useful output signal. */
-int getPreferredOutput() {return (int)prefoutput;}
-
-/** @return 0 if the object doesn't need any assignment to the body element.
-    @return 1 = it likes to be attached to the Part ( @see Neuro::attachToPart() )
-    @return 2 = the object prefers to have the Joint ( @see Neuro::attachToJoint() )
- */
-int getPreferredLocation() {return (int)preflocation;}
-/** vector drawing to be used in neuro net diagram.
-    interpretation:
-       {   
-           LEN = datalength (excluding this number) 
-           NL = number_of_lines
-line#1 ->  NS = number_of_segments, x1,y1, x2,y2, ... xNS-1,yNS-1,
-         ...
-line#NL -> NS = number_of_segments, x1,y1, x2,y2, ... xNS-1,yNS-1,
-       }
- */
-int* getSymbolGlyph()
- {return vectordata;}
-void setSymbolGlyph(int *data,bool owned=1)
- {if (vectordata&&ownedvectordata) delete []vectordata;
- vectordata=data; ownedvectordata=owned;}
-/** additional information about how the neuron should be drawn
-    used by structure view (and maybe some other components).
-    return value is defined by the enum Hint
-    @see enum Hint
- */
-int getVisualHints()
- {return (int)visualhints;}
-
-enum Hint
-	/** don't draw neurons of this class */
- { Invisible=1,
-	/** don't draw classname label below the neuron */
-   DontShowClass=2,
-	/** draw the neuron at the first part when attached to joint (default is in the middle) */
-   AtFirstPart=4,
-	/** draw the neuron at the second part when attached to joint (default is in the middle) */
-   AtSecondPart=8,
-	/** use effector colour for this neuro unit */
-   EffectorClass=16,
-	/** use receptor colour for this neuro unit */
-   ReceptorClass=32,
-   V1BendMuscle=64,
-   V1RotMuscle=128,
-   LinearMuscle=256
- };
-
-/** textual summary, automatically generated from other properties (like the neuro class tooltip) */
-SString getSummary();
+	bool ownedvectordata;
+	void operator=(const NeuroClass& nosuchthich){}
+public:
+	SString name, longname, description;
+	ParamEntry *props;
+	bool ownedprops;//< destructor will free props using ParamObject::freeParamTab
+	paInt prefinputs, prefoutput;
+	paInt preflocation;
+	int *vectordata;
+	paInt visualhints;
+
+	//void *impl;
+	int impl_count;
+	bool active;
+	bool genactive;
+	NeuroClassUserTags userdata;
+
+	//////////////////////
+	~NeuroClass();
+	NeuroClass();
+	NeuroClass(ParamEntry *_props, SString _description,
+		int _prefinputs, int _prefoutput, int _preflocation, int *_vectordata, bool own_vd = 1, int vhints = 0);
+	/** class name for use in Neuro::setClassName(), Neuro::setDetails() (former 'moredata' field),
+		eg. "N","-",G" */
+	const SString& getName() { return name; }
+	/** human friendly name, eg. "Neuron","Link","Gyroscope"  */
+	const SString& getLongName() { return longname; }
+	/** long description */
+	const SString& getDescription() { return description; }
+	ParamEntry* getParamTab() { return props; }
+
+	/** NeuroClass specific properties, recognized by all neurons of this class */
+	Param getProperties() { return Param(props); }
+
+	/** preferred number of inputs, -1 = no preference (any number will go).
+		extra inputs may be ignored by the object (depends on the class).
+		*/
+	int getPreferredInputs() { return (int)prefinputs; }
+
+	/** @return 0 if this object doesn't provide useful output signal. */
+	int getPreferredOutput() { return (int)prefoutput; }
+
+	/** @return 0 if the object doesn't need any assignment to the body element.
+		@return 1 = it likes to be attached to the Part ( @see Neuro::attachToPart() )
+		@return 2 = the object prefers to have the Joint ( @see Neuro::attachToJoint() )
+		*/
+	int getPreferredLocation() { return (int)preflocation; }
+	/** vector drawing to be used in neuro net diagram.
+		interpretation:
+		{
+		LEN = datalength (excluding this number)
+		NL = number_of_lines
+		line#1 ->  NS = number_of_segments, x1,y1, x2,y2, ... xNS-1,yNS-1,
+		...
+		line#NL -> NS = number_of_segments, x1,y1, x2,y2, ... xNS-1,yNS-1,
+		}
+		*/
+	int* getSymbolGlyph()
+	{
+		return vectordata;
+	}
+	void setSymbolGlyph(int *data, bool owned = 1)
+	{
+		if (vectordata&&ownedvectordata) delete[]vectordata;
+		vectordata = data; ownedvectordata = owned;
+	}
+	/** additional information about how the neuron should be drawn
+		used by structure view (and maybe some other components).
+		return value is defined by the enum Hint
+		@see enum Hint
+		*/
+	int getVisualHints()
+	{
+		return (int)visualhints;
+	}
+
+	enum Hint
+		/** don't draw neurons of this class */
+	{
+		Invisible = 1,
+		/** don't draw classname label below the neuron */
+		DontShowClass = 2,
+		/** draw the neuron at the first part when attached to joint (default is in the middle) */
+		AtFirstPart = 4,
+		/** draw the neuron at the second part when attached to joint (default is in the middle) */
+		AtSecondPart = 8,
+		/** use effector colour for this neuro unit */
+		EffectorClass = 16,
+		/** use receptor colour for this neuro unit */
+		ReceptorClass = 32,
+		V1BendMuscle = 64,
+		V1RotMuscle = 128,
+		LinearMuscle = 256
+	};
+
+	/** textual summary, automatically generated from other properties (like the neuro class tooltip) */
+	SString getSummary();
+
+	static void resetActive(); ///< set default values of active and genactive for all classes
+	static void setGenActive(const char* classes[]); ///< set genactive for specified classes
 };
 
@@ -283,227 +295,229 @@
 class OldItems
 {
-Neuro &neuro;
-SList syntitems; ///< to be deleted
-SList items;
-int listok;
-  public:
-OldItems(Neuro &n):neuro(n),listok(0) {}
-~OldItems() {freelist();}
-void buildlist();
-void freelist();
-
-int getItemCount();
-NeuroItem *getNeuroItem(int i);
-NeuroItem *addNewNeuroItem();
-int findNeuroItem(NeuroItem *n);
+	Neuro &neuro;
+	SList syntitems; ///< to be deleted
+	SList items;
+	int listok;
+public:
+	OldItems(Neuro &n):neuro(n),listok(0) {}
+	~OldItems() {freelist();}
+	void buildlist();
+	void freelist();
+
+	int getItemCount();
+	NeuroItem *getNeuroItem(int i);
+	NeuroItem *addNewNeuroItem();
+	int findNeuroItem(NeuroItem *n);
 };
 #endif
 
 /** Single processing unit in Framsticks NN.  */
-class Neuro: public PartBase
-{
-friend class Model;
-static SString getDefaultStyle();
-
-struct NInput { Neuro *n; double weight; SString *info;
-	NInput(Neuro *_n,double w,SString *i=0):n(_n),weight(w),info(i) {} };
-
-SListTempl<NInput> inputs;
-
-NeuroClass *myclass;
-bool knownclass;
-SString myclassname, myclassparams;
-/** set myclass and make knownclass=true */
-void checkClass();
-SString** inputInfo(int i);
-void defassign();
-
-public:
-enum NeuroFlags { HoldState=2 };
-Param properties();
-Param extraProperties();
-
-void setInputInfo(int i,const SString& name,const SString &value);
-void setInputInfo(int i,const SString& name,int value);
-void setInputInfo(int i,const SString& name,double value);
-SString getInputInfo(int i);
-SString getInputInfo(int i,const SString& name);
-
-NeuroClass* getClass();
-void setClass(NeuroClass*);
-
-SString getClassParams() {return myclassparams;}
-void setClassParams(const SString& cp) {myclassparams=cp;}
-
-SString getClassName();
-void setClassName(const SString& clazz);
-
-/** return neuro unit details encoded as <CLASS> ":" <PROPERTIES>
-    
-    new Neuro can be created as root object (without parent) or can be 
-    the child of existing Neuro. Children of the Neuro are its inputs.
-    Standard Framsticks neuron calculates the sum of all input units - other processing
-    units don't have to treat them equally and can even ignore some of them.
-    There are hints about expected inputs in the class database, @see getClass
-
-    Application should not assume anything about classes and its properties
-    except for two standard classes: (information about all current classes
-    can be retrieved with getClass/getClassProperties methods)
-    - getClassName()="N" is the standard Framsticks neuron, accepts any number of inputs,
-      compatible with old Neuro object
-    - getClassName()="-" is the neuron link, compatible with old Neuro-Neuro link
-      (NeuroItem with empty details)
-    Empty details defaults to "-" if the parent unit is specified,
-    and "N" if the unit has no parent.
- */
-SString getDetails();
-
-/** details = classname + ":" + classparams
-    @see getDetails()
- */
-void setDetails(const SString&);
+class Neuro : public PartBase
+{
+	friend class Model;
+	static SString getDefaultStyle();
+
+	struct NInput {
+		Neuro *n; double weight; SString *info;
+		NInput(Neuro *_n, double w, SString *i = 0) :n(_n), weight(w), info(i) {}
+	};
+
+	SListTempl<NInput> inputs;
+
+	NeuroClass *myclass;
+	bool knownclass;
+	SString myclassname, myclassparams;
+	/** set myclass and make knownclass=true */
+	void checkClass();
+	SString** inputInfo(int i);
+	void defassign();
+
+public:
+	enum NeuroFlags { HoldState = 2 };
+	Param properties();
+	Param extraProperties();
+
+	void setInputInfo(int i, const SString& name, const SString &value);
+	void setInputInfo(int i, const SString& name, int value);
+	void setInputInfo(int i, const SString& name, double value);
+	SString getInputInfo(int i);
+	SString getInputInfo(int i, const SString& name);
+
+	NeuroClass* getClass();
+	void setClass(NeuroClass*);
+
+	SString getClassParams() { return myclassparams; }
+	void setClassParams(const SString& cp) { myclassparams = cp; }
+
+	SString getClassName();
+	void setClassName(const SString& clazz);
+
+	/** return neuro unit details encoded as <CLASS> ":" <PROPERTIES>
+
+		new Neuro can be created as root object (without parent) or can be
+		the child of existing Neuro. Children of the Neuro are its inputs.
+		Standard Framsticks neuron calculates the sum of all input units - other processing
+		units don't have to treat them equally and can even ignore some of them.
+		There are hints about expected inputs in the class database, @see getClass
+
+		Application should not assume anything about classes and its properties
+		except for two standard classes: (information about all current classes
+		can be retrieved with getClass/getClassProperties methods)
+		- getClassName()="N" is the standard Framsticks neuron, accepts any number of inputs,
+		compatible with old Neuro object
+		- getClassName()="-" is the neuron link, compatible with old Neuro-Neuro link
+		(NeuroItem with empty details)
+		Empty details defaults to "-" if the parent unit is specified,
+		and "N" if the unit has no parent.
+		*/
+	SString getDetails();
+
+	/** details = classname + ":" + classparams
+		@see getDetails()
+		*/
+	void setDetails(const SString&);
 
 #define STATRICKCLASS Neuro
-PARAMGETDEF(details) {arg1->setString(getDetails());}
-PARAMSETDEF(details) {setDetails(arg1->getString());return PSET_CHANGED;}
-PARAMGETDEF(inputCount);
-PARAMPROCDEF(p_getInputNeuroDef);
-PARAMPROCDEF(p_getInputNeuroIndex);
-PARAMPROCDEF(p_getInputWeight);
-PARAMGETDEF(classObject);
+	PARAMGETDEF(details) { arg1->setString(getDetails()); }
+	PARAMSETDEF(details) { setDetails(arg1->getString()); return PSET_CHANGED; }
+	PARAMGETDEF(inputCount);
+	PARAMPROCDEF(p_getInputNeuroDef);
+	PARAMPROCDEF(p_getInputNeuroIndex);
+	PARAMPROCDEF(p_getInputWeight);
+	PARAMGETDEF(classObject);
 #undef STATRICKCLASS
 
-///@param handle_defaults_when_saving see SyntParam
-SyntParam classProperties(bool handle_defaults_when_saving=true);
-// base properties:
-paInt refno; ///< unique reference number (former 'neuro' refno)
-
-paInt part_refno; ///< can be used by some items as the part ref#
-paInt joint_refno; ///< can be used by some items as the joint ref#
-
-Pt3D pos,rot;	///< default = zero
-
-ModelUserTags userdata;
-
-Neuro();
-Neuro(double _state,double _inertia,double _force,double _sigmo);
-Neuro(const Neuro& src):PartBase(getDefaultStyle()) {operator=(src);}
-
-~Neuro();
-
-void operator=(const Neuro& src);
-
-/** Attach this Neuro to the specified Part or detach it from the body if p==NULL.
-    Neuro can be attached to either Part or Joint, but not both.
-    @see getPart()
- */
-void attachToPart(Part* p) {part=p; joint=0;}
-
-/** Attach this Neuro to the specified Joint or detach it from the body if p==NULL.
-    Neuro can be attached to either Part or Joint, but not both.
-    @see getJoint()
- */
-void attachToJoint(Joint* j) {joint=j; part=0;}
-
-void attachToPart(int i);
-void attachToJoint(int i);
-
-/** @return Part the Neuro is attached to, or NULL if it has no defined location on the body.
-    @see attachToPart()
- */
-Part *getPart() {return part;}
-
-/** @return Joint the Neuro is attached to, or NULL if it has no defined location on the body.
-    @see attachToJoint()
- */
-Joint *getJoint() {return joint;}
-
-int isOldEffector();
-int isOldReceptor();
-int isOldNeuron();
-int isNNConnection();
-
-/** @return the number of inputs connected to this Neuro.
-    Functions like getInput(), getInputWeight() will accept connection number [0..InputCount-1]
- */
-int getInputCount() const {return inputs.size();}
-
-/// @return the number of output connections (including possible self-connections)
-int getOutputsCount() const;
-
-/** @return the Neuro connected as i-th input */
-Neuro* getInput(int i) const {return (i>=inputs.size())?0:inputs(i).n;}
-/** @return the Neuro connected as i-th input.
-    @param weight
- */
-Neuro* getInput(int i,double &weight) const;
-/** @return connectin weight for i-th input */
-double getInputWeight(int i) const;
-/** change connection weight for i-th input */
-void setInputWeight(int i,double weight);
-/** connect i-th input with another neuron */
-void setInput(int i,Neuro*n);
-/** connect i-th input with another neuron */
-void setInput(int i,Neuro*n,double weight);
-/** add new input. @return its reference number */
-int addInput(Neuro* child,double weight=1.0,const SString* info=0);
-/** @return reference number [0..InputCount-1] of the input
-   or -1 if 'child' is not connected with this Neuro.*/
-int findInput(Neuro* child) const;
-void removeInput(paInt refno);
-/**    @return reference number of the child connection, like findInput() */
-int removeInput(Neuro* child);
-
-int findInputs(SList& result,const char* classname=0,const Part* part=0,const Joint* joint=0) const;
-int findOutputs(SList& result,const char* classname=0,const Part* part=0,const Joint* joint=0) const;
-
-/* class database retrieval */
-static int getClassCount();
-/** @return Neuro class name.
-    @param classindex 0 .. getClassCount()
- */
-static SString getClassName(int classindex);
-static NeuroClass* getClass(int classindex);
-static NeuroClass* getClass(const SString& classname);
-static int getClassIndex(const NeuroClass*nc);
+	///@param handle_defaults_when_saving see SyntParam
+	SyntParam classProperties(bool handle_defaults_when_saving = true);
+	// base properties:
+	paInt refno; ///< unique reference number (former 'neuro' refno)
+
+	paInt part_refno; ///< can be used by some items as the part ref#
+	paInt joint_refno; ///< can be used by some items as the joint ref#
+
+	Pt3D pos, rot;	///< default = zero
+
+	ModelUserTags userdata;
+
+	Neuro();
+	Neuro(double _state, double _inertia, double _force, double _sigmo);
+	Neuro(const Neuro& src) :PartBase(getDefaultStyle()) { operator=(src); }
+
+	~Neuro();
+
+	void operator=(const Neuro& src);
+
+	/** Attach this Neuro to the specified Part or detach it from the body if p==NULL.
+		Neuro can be attached to either Part or Joint, but not both.
+		@see getPart()
+		*/
+	void attachToPart(Part* p) { part = p; joint = 0; }
+
+	/** Attach this Neuro to the specified Joint or detach it from the body if p==NULL.
+		Neuro can be attached to either Part or Joint, but not both.
+		@see getJoint()
+		*/
+	void attachToJoint(Joint* j) { joint = j; part = 0; }
+
+	void attachToPart(int i);
+	void attachToJoint(int i);
+
+	/** @return Part the Neuro is attached to, or NULL if it has no defined location on the body.
+		@see attachToPart()
+		*/
+	Part *getPart() { return part; }
+
+	/** @return Joint the Neuro is attached to, or NULL if it has no defined location on the body.
+		@see attachToJoint()
+		*/
+	Joint *getJoint() { return joint; }
+
+	int isOldEffector();
+	int isOldReceptor();
+	int isOldNeuron();
+	int isNNConnection();
+
+	/** @return the number of inputs connected to this Neuro.
+		Functions like getInput(), getInputWeight() will accept connection number [0..InputCount-1]
+		*/
+	int getInputCount() const { return inputs.size(); }
+
+	/// @return the number of output connections (including possible self-connections)
+	int getOutputsCount() const;
+
+	/** @return the Neuro connected as i-th input */
+	Neuro* getInput(int i) const { return (i >= inputs.size()) ? 0 : inputs(i).n; }
+	/** @return the Neuro connected as i-th input.
+		@param weight
+		*/
+	Neuro* getInput(int i, double &weight) const;
+	/** @return connectin weight for i-th input */
+	double getInputWeight(int i) const;
+	/** change connection weight for i-th input */
+	void setInputWeight(int i, double weight);
+	/** connect i-th input with another neuron */
+	void setInput(int i, Neuro*n);
+	/** connect i-th input with another neuron */
+	void setInput(int i, Neuro*n, double weight);
+	/** add new input. @return its reference number */
+	int addInput(Neuro* child, double weight = 1.0, const SString* info = 0);
+	/** @return reference number [0..InputCount-1] of the input
+	   or -1 if 'child' is not connected with this Neuro.*/
+	int findInput(Neuro* child) const;
+	void removeInput(paInt refno);
+	/**    @return reference number of the child connection, like findInput() */
+	int removeInput(Neuro* child);
+
+	int findInputs(SList& result, const char* classname = 0, const Part* part = 0, const Joint* joint = 0) const;
+	int findOutputs(SList& result, const char* classname = 0, const Part* part = 0, const Joint* joint = 0) const;
+
+	/* class database retrieval */
+	static int getClassCount();
+	/** @return Neuro class name.
+		@param classindex 0 .. getClassCount()
+		*/
+	static SString getClassName(int classindex);
+	static NeuroClass* getClass(int classindex);
+	static NeuroClass* getClass(const SString& classname);
+	static int getClassIndex(const NeuroClass*nc);
 
 #ifdef MODEL_V1_COMPATIBLE
-friend class OldItems;
-paInt neuro_refno; ///< parent ref# (called neuro_refno for compatibility with old Neuro class), @see moredata
-paInt conn_refno; ///< the other neuron ref# in N-N connections, can be used by some other items
-double weight; ///< weight of the N-N connection and (all?) receptors
-double inertia,force,sigmo; //!!!
-
-/** @deprecated provided only for compatibility with old Neuro/NeuroItem classes.
-    use getInputCount() instead. @sa getInputCount() */
-int getItemCount() {return oldItems().getItemCount();}
-
-/** @deprecated provided only for compatibility with old Neuro/NeuroItem classes.
-    use getInput() instead. @sa getInput() */
-NeuroItem* getNeuroItem(int i) {return oldItems().getNeuroItem(i);}
+	friend class OldItems;
+	paInt neuro_refno; ///< parent ref# (called neuro_refno for compatibility with old Neuro class), @see moredata
+	paInt conn_refno; ///< the other neuron ref# in N-N connections, can be used by some other items
+	double weight; ///< weight of the N-N connection and (all?) receptors
+	double inertia,force,sigmo; //!!!
+
+	/** @deprecated provided only for compatibility with old Neuro/NeuroItem classes.
+		use getInputCount() instead. @sa getInputCount() */
+	int getItemCount() {return oldItems().getItemCount();}
+
+	/** @deprecated provided only for compatibility with old Neuro/NeuroItem classes.
+		use getInput() instead. @sa getInput() */
+	NeuroItem* getNeuroItem(int i) {return oldItems().getNeuroItem(i);}
 #endif
 
-  protected:
+protected:
 #ifdef MODEL_V1_COMPATIBLE
-/** old Neuro compatibility */
-OldItems* olditems;
-OldItems& oldItems() {if (!olditems) olditems=new OldItems(*this); return *olditems;}
-void invalidateOldItems() {if (olditems) olditems->freelist();}
+	/** old Neuro compatibility */
+	OldItems* olditems;
+	OldItems& oldItems() {if (!olditems) olditems=new OldItems(*this); return *olditems;}
+	void invalidateOldItems() {if (olditems) olditems->freelist();}
 #endif
 
-  public:
-
-// not really private, but you should not access those directly
-double state;
-
-/** may reference parent neuron if parentcount is exacty 1. parent is invalid otherwise. @sa parentcount */
-Neuro *parent;
-int parentcount; ///< @sa parent
-
-Part *part;	///< link to the Part
-Joint *joint;	///< link to the Joint - required by some objects (eg.muscles)
-Orient o;	///< rotation matrix calculated from "rot"
-static ParamEntry emptyParamTab[];
-static Param& getStaticParam();
+public:
+
+	// not really private, but you should not access those directly
+	double state;
+
+	/** may reference parent neuron if parentcount is exacty 1. parent is invalid otherwise. @sa parentcount */
+	Neuro *parent;
+	int parentcount; ///< @sa parent
+
+	Part *part;	///< link to the Part
+	Joint *joint;	///< link to the Joint - required by some objects (eg.muscles)
+	Orient o;	///< rotation matrix calculated from "rot"
+	static ParamEntry emptyParamTab[];
+	static Param& getStaticParam();
 };
 
@@ -515,29 +529,29 @@
 {
 public:
-NeuroItem() {}
+	NeuroItem() {}
 };
 #endif
 
-class NeuroExt: public Neuro
-{
-  public:
+class NeuroExt : public Neuro
+{
+public:
 #define STATRICKCLASS NeuroExt
-PARAMGETDEF(neuroclass);
-PARAMSETDEF(neuroclass);
+	PARAMGETDEF(neuroclass);
+	PARAMSETDEF(neuroclass);
 #undef STATRICKCLASS
-static ParamEntry *getParamTab();
+	static ParamEntry *getParamTab();
 };
 
 class NeuroConn
 {
-void defassign();
-  public:
-int n1_refno,n2_refno;
-double weight;
-SString info;
-NeuroConn();
-};
-
-extern ParamEntry f0_part_paramtab[],f0_joint_paramtab[],f0_nodeltajoint_paramtab[],f0_neuro_paramtab[],f0_neuroconn_paramtab[],f0_neuroitem_paramtab[];
+	void defassign();
+public:
+	int n1_refno, n2_refno;
+	double weight;
+	SString info;
+	NeuroConn();
+};
+
+extern ParamEntry f0_part_paramtab[], f0_joint_paramtab[], f0_nodeltajoint_paramtab[], f0_neuro_paramtab[], f0_neuroconn_paramtab[], f0_neuroitem_paramtab[];
 
 #endif
Index: /cpp/frams/neuro/geneticneuroparam.cpp
===================================================================
--- /cpp/frams/neuro/geneticneuroparam.cpp	(revision 713)
+++ /cpp/frams/neuro/geneticneuroparam.cpp	(revision 714)
@@ -1,4 +1,4 @@
 // This file is a part of Framsticks SDK.  http://www.framsticks.com/
-// Copyright (C) 1999-2015  Maciej Komosinski and Szymon Ulatowski.
+// Copyright (C) 1999-2017  Maciej Komosinski and Szymon Ulatowski.
 // See LICENSE.txt for details.
 
@@ -6,13 +6,17 @@
 #include <frams/neuro/neurolibrary.h>
 
-GeneticNeuroParam::GeneticNeuroParam(const char* groupname,const char* myname,
-				   const char* prefix,const char* typ)
-	:NeuroLibParam(groupname,myname,prefix),types(typ)
+GeneticNeuroParam::GeneticNeuroParam(const char* groupname, const char* myname,
+	const char* prefix, const char* typ)
+	:NeuroLibParam(groupname, myname, prefix), types(typ)
 {}
 
 paInt GeneticNeuroParam::getInt(int i)
-{return Neuro::getClass(i)->genactive;}
+{
+	return Neuro::getClass(i)->genactive ? 1 : 0;
+}
 
-int GeneticNeuroParam::setInt(int i,paInt v)
-{Neuro::getClass(i)->genactive=v;return PSET_CHANGED;}
+int GeneticNeuroParam::setInt(int i, paInt v)
+{
+	Neuro::getClass(i)->genactive = (v != 0); return PSET_CHANGED;
+}
 
Index: /cpp/frams/neuro/geneticneuroparam.h
===================================================================
--- /cpp/frams/neuro/geneticneuroparam.h	(revision 713)
+++ /cpp/frams/neuro/geneticneuroparam.h	(revision 714)
@@ -1,4 +1,4 @@
 // This file is a part of Framsticks SDK.  http://www.framsticks.com/
-// Copyright (C) 1999-2015  Maciej Komosinski and Szymon Ulatowski.
+// Copyright (C) 1999-2017  Maciej Komosinski and Szymon Ulatowski.
 // See LICENSE.txt for details.
 
@@ -8,14 +8,14 @@
 #include "neurolibparam.h"
 
-class GeneticNeuroParam: public NeuroLibParam
+class GeneticNeuroParam : public NeuroLibParam
 {
-  protected:
-const char* types;
-  public:
-GeneticNeuroParam(const char* groupname,const char* myname, const char* prefix,const char* typ=0);
+protected:
+	const char* types;
+public:
+	GeneticNeuroParam(const char* groupname, const char* myname, const char* prefix, const char* typ = 0);
 
-paInt getInt(int i);
-int setInt(int i,paInt v);
-const char *type(int i) {return types?types:NeuroLibParam::type(i);}
+	paInt getInt(int i);
+	int setInt(int i, paInt v);
+	const char *type(int i) { return types ? types : NeuroLibParam::type(i); }
 };
 
