Index: cpp/frams/genetics/fB/fB_oper.cpp
===================================================================
--- cpp/frams/genetics/fB/fB_oper.cpp	(revision 797)
+++ 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;
 	}
