Index: /cpp/frams/genetics/fB/fB_conv.cpp
===================================================================
--- /cpp/frams/genetics/fB/fB_conv.cpp	(revision 801)
+++ /cpp/frams/genetics/fB/fB_conv.cpp	(revision 802)
@@ -170,5 +170,5 @@
 }
 
-bool GenoConv_fBH::getNextCharId(SString genotype, int &i)
+bool GenoConv_fBH::getNextCharId(const SString& genotype, int &i)
 {
 	i++;
@@ -191,5 +191,5 @@
 }
 
-bool GenoConv_fBH::getNeuroClass(SString gene, SString &def, int nclassdefcount)
+bool GenoConv_fBH::getNeuroClass(const SString& gene, SString &def, int nclassdefcount)
 {
 	SString lastdef = "N";
@@ -218,5 +218,5 @@
 }
 
-int GenoConv_fBH::processNextLetter(fH_Builder &creature, fH_Handle *&currhandle, Param &par, SString gene, int &propindex, int &i, std::vector<IRange> ranges[3], int &nclassdefcount)
+int GenoConv_fBH::processNextLetter(fH_Builder &creature, fH_Handle *&currhandle, Param &par, const SString& gene, int &propindex, int &i, std::vector<IRange> ranges[3], int &nclassdefcount)
 {
 	if (propindex >= par.getPropCount())
Index: /cpp/frams/genetics/fB/fB_conv.h
===================================================================
--- /cpp/frams/genetics/fB/fB_conv.h	(revision 801)
+++ /cpp/frams/genetics/fB/fB_conv.h	(revision 802)
@@ -12,10 +12,10 @@
 {
 private:
-	bool getNextCharId(SString genotype, int &i);
+	bool getNextCharId(const SString& genotype, int &i);
 	double convertCharacterTo01(char c);
 	double convertCharacterToWeight(char c);
 	static fH_Handle* convertCharacterToHandle(char c, int dims, int start, int end, std::vector<IRange> ranges[3]);
-	int processNextLetter(fH_Builder &creature, fH_Handle *&currhandle, Param &par, SString gene, int &propindex, int &i, std::vector<IRange> ranges[3], int &nclassdefcount);
-	bool getNeuroClass(SString gene, SString &def, int nclassdefcount);
+	int processNextLetter(fH_Builder &creature, fH_Handle *&currhandle, Param &par, const SString& gene, int &propindex, int &i, std::vector<IRange> ranges[3], int &nclassdefcount);
+	bool getNeuroClass(const SString& gene, SString &def, int nclassdefcount);
 
 public:
Index: /cpp/frams/genetics/fB/fB_general.h
===================================================================
--- /cpp/frams/genetics/fB/fB_general.h	(revision 801)
+++ /cpp/frams/genetics/fB/fB_general.h	(revision 802)
@@ -11,5 +11,5 @@
 {
 public:
-	static int geneCount(SString geno)
+	static int geneCount(const SString& geno)
 	{
 		int start = 0;
@@ -27,5 +27,38 @@
 	}
 
-	static SString getGene(int i, SString genotype, int &start, int &end)
+	static SString getNonNestedGene(int i, const SString& genotype, int &start, int &end)
+	{
+		int count = -1;
+		start = 0;
+		int tmp = 0;
+		SString result = "";
+		do {
+			count++;
+			if (start < genotype.len())
+				result = getNextGene(start, genotype, tmp, start);
+			else
+				start = -1;
+		} while (start != -1 && count < i);
+		start = tmp;
+		end = start;
+		return result;
+	}
+
+	static int geneCountNoNested(const SString& geno)
+	{
+		int start = 0;
+		int count = -1;
+		int tmp = 0;
+		do {
+			count++;
+			if (start < geno.len())
+				getNextGene(start, geno, tmp, start);
+			else
+				start = -1;
+		} while (start != -1);
+		return count;
+	}
+
+	static SString getGene(int i, const SString& genotype, int &start, int &end)
 	{
 		start = 0;
@@ -62,4 +95,38 @@
 	}
 
+	static SString getNextGene(int searchbegin, const SString& genotype, int &start, int &end)
+	{
+		start = searchbegin;
+		int count = -1;
+		do {
+			count++;
+			start = genotype.indexOf("aa", start) + 1;
+			int quotecount = 0;
+			for (int q = 0; q < start; q++) if (genotype[q] == '\"') quotecount++;
+			if (quotecount % 2 != 0) count--; // 'aa' sequence is within quotes
+		} while (start - 1 != -1 && count != 0);
+		if (start - 1 == -1) // there is no gene with a given "i"
+		{
+			start = -1;
+			end = -1;
+			return "";
+		}
+		end = start;
+		int quotecount = 0;
+		do {
+			quotecount = 0;
+			end = genotype.indexOf("zz", end);
+			if (end != -1)
+			{
+				for (int q = start; q < end; q++) if (genotype[q] == '\"') quotecount++;
+				if (quotecount % 2 != 0) end++;
+			}
+		} while (quotecount % 2 != 0 && end != -1);
+
+		if (end == -1) end = genotype.len();
+		else end += 2;
+		start -= 1;
+		return genotype.substr(start, end - start);
+	}
 private:
 	fB_GenoHelpers() {}
Index: /cpp/frams/genetics/fB/fB_oper.cpp
===================================================================
--- /cpp/frams/genetics/fB/fB_oper.cpp	(revision 801)
+++ /cpp/frams/genetics/fB/fB_oper.cpp	(revision 802)
@@ -19,11 +19,11 @@
 	{ "Genetics: fB: Crossover", },
 	{ "fB_mut_substitution", 1, 0, "Substitution", "f 0 1 0.6", FIELD(mutationprobs[FB_SUBSTITUTION]), "Probability of mutation by changing single random letter in genotype", },
-	{ "fB_mut_insertion", 1, 0, "Insertion", "f 0 1 0.95", FIELD(mutationprobs[FB_INSERTION]), "Probability of mutation by inserting characters in random place of genotype", },
-	{ "fB_mut_nclassins", 1, 0, "Insertion of neuron class definition", "f 0 1 0.05", FIELD(mutationprobs[FB_NCLASSINS]), "Probability of mutation by inserting neuron class definition in random place of genotype", },
+	{ "fB_mut_insertion", 1, 0, "Insertion", "f 0 1 0.095", FIELD(mutationprobs[FB_INSERTION]), "Probability of mutation by inserting characters in random place of genotype", },
+	{ "fB_mut_nclassins", 1, 0, "Insertion of neuron class definition", "f 0 1 0.005", FIELD(mutationprobs[FB_NCLASSINS]), "Probability of mutation by inserting neuron class definition in random place of genotype", },
 	{ "fB_mut_deletion", 1, 0, "Deletion", "f 0 1 0.1", FIELD(mutationprobs[FB_DELETION]), "Probability of mutation by deleting random characters in genotype", },
-	{ "fB_mut_duplication", 1, 0, "Duplication", "f 0 1 0.05", FIELD(mutationprobs[FB_DUPLICATION]), "Probability of mutation by copying single *gene* of genotype and appending it to the beginning of this genotype", },
+	{ "fB_mut_duplication", 1, 0, "Duplication", "f 0 1 0.0", FIELD(mutationprobs[FB_DUPLICATION]), "Probability of mutation by copying single *gene* of genotype and appending it to the beginning of this genotype", },
 	{ "fB_mut_translocation", 1, 0, "Translocation", "f 0 1 0.15", FIELD(mutationprobs[FB_TRANSLOCATION]), "Probability of mutation by replacing two substrings in genotype", },
-	{ "fB_cross_gene_transfer", 2, 0, "Horizontal gene transfer", "f 0 1 0.8", FIELD(crossoverprobs[FB_GENE_TRANSFER]), "Probability of crossing over by transferring single genes from both parents to beginning of each other", },
-	{ "fB_cross_crossover", 2, 0, "Crossing over", "f 0 1 0.2", FIELD(crossoverprobs[FB_CROSSING_OVER]), "Probability of crossing over by random distribution of genes from both parents to both children", },
+	{ "fB_cross_gene_transfer", 2, 0, "Horizontal gene transfer", "f 0 1 0.0", FIELD(crossoverprobs[FB_GENE_TRANSFER]), "Probability of crossing over by transferring single genes from both parents to beginning of each other", },
+	{ "fB_cross_crossover", 2, 0, "Crossing over", "f 0 1 1.0", FIELD(crossoverprobs[FB_CROSSING_OVER]), "Probability of crossing over by random distribution of genes from both parents to both children", },
 	{ 0, },
 };
@@ -281,4 +281,25 @@
 		break;
 	}
+	case FB_NCLASSINS:
+	{
+		std::list<SString> tokenized = tokenizeSequence(line);
+		std::list<SString>::iterator it = tokenized.begin();
+		int rndid = randomN(tokenized.size()); // select random insertion point
+		std::advance(it, rndid);
+		NeuroClass *cls = getRandomNeuroClass();
+		if (cls)
+		{
+			SString classdef = cls->getName();
+			Geno_fH::mutateNeuronProperties(classdef);
+			SString res = "\"";
+			res += classdef;
+			res += "\"";
+			tokenized.insert(it, res);
+			chg = (double)classdef.len() / line.len();
+			line = detokenizeSequence(tokenized);
+			break;
+		}
+	}
+	/* no break */
 	case FB_INSERTION:
 	{
@@ -291,21 +312,4 @@
 		letter.directWrite()[0] = 'a' + randomN(26);
 		tokenized.insert(it, letter);
-		line = detokenizeSequence(tokenized);
-		break;
-	}
-	case FB_NCLASSINS:
-	{
-		std::list<SString> tokenized = tokenizeSequence(line);
-		std::list<SString>::iterator it = tokenized.begin();
-		int rndid = randomN(tokenized.size()); // select random insertion point
-		std::advance(it, rndid);
-		NeuroClass *cls = getRandomNeuroClass();
-		SString classdef = cls->getName();
-		Geno_fH::mutateNeuronProperties(classdef);
-		SString res = "\"";
-		res += classdef;
-		res += "\"";
-		tokenized.insert(it, res);
-		chg = (double)classdef.len() / line.len();
 		line = detokenizeSequence(tokenized);
 		break;
@@ -416,40 +420,101 @@
 		break;
 	}
+//	case FB_CROSSING_OVER:
+//	{
+//		// iterate through all genes of the first parent and assign them
+//		// randomly to children
+//		for (int i = 0; i < fB_GenoHelpers::geneCount(parent1); i++)
+//		{
+//			int start, end;
+//			SString gene = fB_GenoHelpers::getGene(i, parent1, start, end);
+//			if (randomN(2) == 0)
+//			{
+//				child1 += gene;
+//				chg1 += 1.0f;
+//			}
+//			else
+//			{
+//				child2 += gene;
+//			}
+//		}
+//		chg1 /= fB_GenoHelpers::geneCount(parent1);
+//
+//		// do the same with second parent
+//		for (int i = 0; i < fB_GenoHelpers::geneCount(parent2); i++)
+//		{
+//			int start, end;
+//			SString gene = fB_GenoHelpers::getGene(i, parent2, start, end);
+//			if (randomN(2) == 0)
+//			{
+//				child1 += gene;
+//			}
+//			else
+//			{
+//				child2 += gene;
+//				chg2 += 1.0f;
+//			}
+//		}
+//		chg2 /= fB_GenoHelpers::geneCount(parent2);
+//		break;
+//	}
 	case FB_CROSSING_OVER:
 	{
-		// iterate through all genes of the first parent and assign them
-		// randomly to children
-		for (int i = 0; i < fB_GenoHelpers::geneCount(parent1); i++)
-		{
-			int start, end;
-			SString gene = fB_GenoHelpers::getGene(i, parent1, start, end);
-			if (randomN(2) == 0)
-			{
-				child1 += gene;
-				chg1 += 1.0f;
-			}
-			else
-			{
-				child2 += gene;
-			}
-		}
-		chg1 /= fB_GenoHelpers::geneCount(parent1);
-
-		// do the same with second parent
-		for (int i = 0; i < fB_GenoHelpers::geneCount(parent2); i++)
-		{
-			int start, end;
-			SString gene = fB_GenoHelpers::getGene(i, parent2, start, end);
-			if (randomN(2) == 0)
-			{
-				child1 += gene;
-			}
-			else
-			{
-				child2 += gene;
-				chg2 += 1.0f;
-			}
-		}
-		chg2 /= fB_GenoHelpers::geneCount(parent2);
+		// get maximal count of genes from both parents
+		int maxgenecount = max(fB_GenoHelpers::geneCountNoNested(parent1),
+				fB_GenoHelpers::geneCountNoNested(parent2));
+
+		// while there are genes in at least one genotype
+		for (int i = 0; i < maxgenecount; i++)
+		{
+			SString to1 = "", to2 = "";
+			int start = 0, end = 0;
+
+			// if both parents have genes available, then distribute them
+			if (i < fB_GenoHelpers::geneCountNoNested(parent1) &&
+					i < fB_GenoHelpers::geneCountNoNested(parent2))
+			{
+				if (randomN(2) == 0)
+				{
+					to1 = fB_GenoHelpers::getNonNestedGene(i, parent1, start, end);
+					to2 = fB_GenoHelpers::getNonNestedGene(i, parent2, start, end);
+					chg1 += 1.0f;
+					chg2 += 1.0f;
+				}
+				else
+				{
+					to1 = fB_GenoHelpers::getNonNestedGene(i, parent2, start, end);
+					to2 = fB_GenoHelpers::getNonNestedGene(i, parent1, start, end);
+				}
+			}
+			else if (i < fB_GenoHelpers::geneCountNoNested(parent1))
+			{
+				if (randomN(2) == 0)
+				{
+					to1 = fB_GenoHelpers::getNonNestedGene(i, parent1, start, end);
+					chg1 += 1.0f;
+				}
+				else
+				{
+					to2 = fB_GenoHelpers::getNonNestedGene(i, parent1, start, end);
+				}
+			}
+			else // if (i < fB_GenoHelpers::geneCountNoNested(parent2))
+			{
+				if (randomN(2) == 0)
+				{
+					to1 = fB_GenoHelpers::getNonNestedGene(i, parent2, start, end);
+				}
+				else
+				{
+					to2 = fB_GenoHelpers::getNonNestedGene(i, parent2, start, end);
+					chg2 += 1.0f;
+				}
+			}
+			child1 += to1;
+			child2 += to2;
+		}
+
+		chg1 /= fB_GenoHelpers::geneCountNoNested(parent1);
+		chg2 /= fB_GenoHelpers::geneCountNoNested(parent2);
 		break;
 	}
