Index: /cpp/frams/genetics/f4/f4_conv.cpp
===================================================================
--- /cpp/frams/genetics/f4/f4_conv.cpp	(revision 1239)
+++ /cpp/frams/genetics/f4/f4_conv.cpp	(revision 1240)
@@ -39,4 +39,11 @@
 	SString out = model->getF0Geno().getGenes();
 	delete model;
+
+	/* quick debugging test - print an approximate f1 conversion of every genotype converted to f0:
+	GenoConv_F41_TestOnly conv41;
+	SString f1 = conv41.convert(in, NULL, false);
+	printf("f1 = %s\n", f1.c_str());
+	*/
+
 	return out;
 }
@@ -45,5 +52,8 @@
 GenoConv_F41_TestOnly::GenoConv_F41_TestOnly()
 {
-	name = "Only for testing, approximate f4->f1 converter"; //Do not use in production! (adam)
+	name = "Only for testing, approximate f4->f1 converter";
+	// Why approximate? for example, f1 does not allow to continue after branching: X(X,X)X  <-- the last X
+	// Some modifier genes are also not perfectly converted.
+	// And neuron properties are ignored...
 	in_format = '4';
 	out_format = '1';
Index: /cpp/frams/genetics/f4/f4_general.cpp
===================================================================
--- /cpp/frams/genetics/f4/f4_general.cpp	(revision 1239)
+++ /cpp/frams/genetics/f4/f4_general.cpp	(revision 1240)
@@ -679,10 +679,17 @@
 			return true; //so continue development!
 
-	if (development_stagnation)
-		return false; //the same number of cells, no progress in development in any cell -> stagnation, end development
+	//the same number of cells, no progress in development in any cell -> stagnation!
+
+	if (development_stagnation) // stagnation was already detected in the previous step, so end development!
+	{
+		for (int i = 0; i < cell_count; i++)
+			if (C[i]->gcur != NULL) // genotype execution pointer did not reach the end
+				logPrintf("f4_Cells", "oneStep", LOG_WARN, "Finishing the development of cells due to stagnation, but cell %d did not reach the end of development", i); //let's see an example of such a genotype and investigate...
+		return false; //end development
+	}
 	else
 	{
 		development_stagnation = true; //signal (force) f4_Cell's that wait for neural connection development to make a step, because all cells stagnated and waiting cells cannot hope for new neurons to be created
-		return true;
+		return true; //one grace step. If there are some waiting cells, they must move on in the next step and set development_stagnation=false or set error. If development_stagnation is not set to false, we will finish development in the next step. This grace step may be unnecessary if there are no waiting cells, but we have no easy way to check this from here (although we could check if all cells' gcur==NULL... would this be always equivalent? Maybe some cells may stagnate with gcur!=NULL and they are not waiting for neural connections to develop and this does not mean an error? Added LOG_WARN above to detect such cases. Anyway, for gcur==NULL, f4_Cell.oneStep() exits immediately, so one grace step is not a big overhead.)
 	}
 }
@@ -879,14 +886,9 @@
 void f4_Cells::toF1GenoRec(int curc, SString &out)
 {
-	int i, j, ccount;
-	f4_Cell *thisti;
-	f4_Cell *thneu;
-	char buf[200];
-
 	if (curc >= cell_count) return;
 
 	if (C[curc]->type != CELL_STICK) return;
 
-	thisti = C[curc];
+	f4_Cell *thisti = C[curc];
 	if (thisti->dadlink != NULL)
 		*tmpcel = *(thisti->dadlink);
@@ -929,5 +931,5 @@
 
 	// neurons attached to it
-	for (i = 0; i < cell_count; i++)
+	for (int i = 0; i < cell_count; i++)
 	{
 		if (C[i]->type == CELL_NEURON)
@@ -935,14 +937,14 @@
 			if (C[i]->dadlink == thisti)
 			{
-				thneu = C[i];
+				f4_Cell *thneu = C[i];
 				out += "[";
-				// ctrl
-				//if (1 == thneu->ctrl) out += "@"; // old code; this can be easily generalized to any neuroclass if ever needed
-				//if (2 == thneu->ctrl) out += "|";
-				out += thneu->neuclass->name.c_str(); // not tested, but something like that
+				out += thneu->neuclass->name.c_str();
+				if (thneu->conns_count > 0)
+					out += ", ";
 				// connections
-				for (j = 0; j < thneu->conns_count; j++)
-				{
-					if (j) out += ",";
+				for (int j = 0; j < thneu->conns_count; j++)
+				{
+					if (j > 0) out += ", ";
+					char buf[100];
 					sprintf(buf, "%d", thneu->conns[j]->from->nr - thneu->nr);
 					out += buf;
@@ -961,6 +963,6 @@
 		out += "(";
 
-	ccount = 1;
-	for (i = 0; i < cell_count; i++)
+	int ccount = 1;
+	for (int i = 0; i < cell_count; i++)
 	{
 		if (C[i]->type == CELL_STICK)
@@ -1397,5 +1399,5 @@
 		{
 			//printf("any regular character '%c'\n", genot[pos_inout]);
-#define F4_SIMPLIFY_MODIFIERS //avoid long sequences like ...<X>llmlIilImmimiimmimifmfl<fifmmimilimmmiimiliffmfliIfififlliflimfliffififmiffmflllfflimlififfiiffifIr<r<... - another option, instead of simplifying while parsing here, would be mutations: when they add/modify/remove a modifier node, they could "clean" the tree by removing nodes when they encounter contradictory modifiers on the same subpath, and also limit the number of modifiers just as GenoOperators::simplifiedModifiers() does.
+#define F4_SIMPLIFY_MODIFIERS //avoid long, redundant sequences like ...<X>llmlIilImmimiimmimifmfl<fifmmimilimmmiimiliffmfliIfififlliflimfliffififmiffmflllfflimlififfiiffifIr<r<...
 #ifdef F4_SIMPLIFY_MODIFIERS
 			char *ptr = (char*)(genot + pos_inout);
