Index: cpp/frams/genetics/f4/f4_general.cpp
===================================================================
--- cpp/_old/f4/f4_general.cpp	(revision 193)
+++ cpp/frams/genetics/f4/f4_general.cpp	(revision 196)
@@ -1,32 +1,16 @@
-/*
- *  f4_general.cpp - f4 genotype functions.
- *
- *  f4genotype - f4 format genotype conversions for FramSticks
- *
- *  Copyright (C) 1999,2000  Adam Rotaru-Varga (adam_rotaru@yahoo.com)
- *
- *  This library is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Lesser General Public
- *  License as published by the Free Software Foundation; either
- *  version 2.1 of the License, or (at your option) any later version.
- *
- *  This library is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *  Lesser General Public License for more details.
- *
- *  You should have received a copy of the GNU Lesser General Public
- *  License along with this library; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
+// This file is a part of the Framsticks GDK.
+// Copyright (C) 2002-2014  Maciej Komosinski and Szymon Ulatowski.  See LICENSE.txt for details.
+// Refer to http://www.framsticks.com/ for further information.
+
+// Copyright (C) 1999,2000  Adam Rotaru-Varga (adam_rotaru@yahoo.com), GNU LGPL
+// Copyright (C) since 2001 Maciej Komosinski
 
 #include "f4_general.h"
-#include "nonstd.h"
-#include "framsg.h"
-#include "model.h" // for min and max attributes
-#include "geno_fx.h" //for GENOPER_ constants
+#include <common/nonstd_stl.h>
+#include <common/framsg.h>
+#include <frams/model/model.h> // for min and max attributes
+#include "../oper_fx.h" //for GENOPER_ constants
 #include <stdio.h>
-#include <math.h>
+#include <common/nonstd_math.h>
 
 #ifdef DMALLOC
@@ -37,66 +21,67 @@
 f4_Props::f4_Props()
 {
-  len      = 1.0;
-  curv     = 0.0;
-  mass     = 1.0; 
-  friction = 0.4;
-  ruch     = 0.25; // bio
-  assim    = 0.25; // bio
-  odpor    = 0.25; // bio
-  ingest   = 0.25; // bio
-  twist    = 0.0;
-  energ    = 1.0;
-  normalizeBiol4();
+	len = 1.0;
+	curv = 0.0;
+	mass = 1.0;
+	friction = 0.4;
+	ruch = 0.25; // bio
+	assim = 0.25; // bio
+	odpor = 0.25; // bio
+	ingest = 0.25; // bio
+	twist = 0.0;
+	energ = 1.0;
+	normalizeBiol4();
 }
 
 void f4_Props::normalizeBiol4()
 {
-  // must sum to 1
-  double sum = ruch + assim + odpor + ingest;
-  if (0 == sum)
-  {
-    ruch = assim = odpor = ingest = 0.25;
-  } else {
-    ruch   /= sum;
-    assim  /= sum;
-    odpor  /= sum;
-    ingest /= sum;
-  }
+	// must sum to 1
+	double sum = ruch + assim + odpor + ingest;
+	if (0 == sum)
+	{
+		ruch = assim = odpor = ingest = 0.25;
+	}
+	else {
+		ruch /= sum;
+		assim /= sum;
+		odpor /= sum;
+		ingest /= sum;
+	}
 }
 
 void f4_Props::executeModifier(char modif)
 {
-  switch (modif)
-  {
-   case 'L': len += (2.5 - len) * 0.3;
-             len = min(len, Model::getMaxJoint().d.x); break;
-   case 'l': len += (0.3 - len) * 0.3;
-             len = max(len, Model::getMinJoint().d.x); break;
-   case 'C': curv += ( 2.0 - curv) * 0.25;  break;
-   case 'c': curv += (-2.0 - curv) * 0.25;  break;
-   case 'Q': twist += ( 1.58 - twist) * 0.3; break;
-   case 'q': twist += (-1.58 - twist) * 0.3; break;
-   case 'A': assim += (1 - assim) * 0.8; normalizeBiol4(); break;
-   case 'a': assim -= assim * 0.4;       normalizeBiol4(); break;
-   case 'I': ingest += (1 - ingest) * 0.8;   normalizeBiol4(); break;
-   case 'i': ingest -= ingest * 0.4;         normalizeBiol4(); break;
-   case 'S': odpor += (1 - odpor) * 0.8; normalizeBiol4(); break;
-   case 's': odpor -= odpor * 0.4;       normalizeBiol4(); break;
-   case 'M': ruch += (1 - ruch) * 0.8;   normalizeBiol4(); break;
-   case 'm': ruch -= ruch * 0.4;         normalizeBiol4(); break;
-   case 'F': friction += (4 - friction) * 0.2; break;
-   case 'f': friction -= friction * 0.2;       break;
-   case 'W': mass += (2.0 - mass) * 0.3;   break;
-   case 'w': mass += (0.5 - mass) * 0.3;   break;
-   case 'E': energ += (10.0 - energ) * 0.1; break;
-   case 'e': energ -= energ * 0.1;          break;
-  }
+	switch (modif)
+	{
+	case 'L': len += (2.5 - len) * 0.3;
+		len = min(len, Model::getMaxJoint().d.x); break;
+	case 'l': len += (0.3 - len) * 0.3;
+		len = max(len, Model::getMinJoint().d.x); break;
+	case 'C': curv += (2.0 - curv) * 0.25;  break;
+	case 'c': curv += (-2.0 - curv) * 0.25;  break;
+	case 'Q': twist += (1.58 - twist) * 0.3; break;
+	case 'q': twist += (-1.58 - twist) * 0.3; break;
+	case 'A': assim += (1 - assim) * 0.8; normalizeBiol4(); break;
+	case 'a': assim -= assim * 0.4;       normalizeBiol4(); break;
+	case 'I': ingest += (1 - ingest) * 0.8;   normalizeBiol4(); break;
+	case 'i': ingest -= ingest * 0.4;         normalizeBiol4(); break;
+	case 'S': odpor += (1 - odpor) * 0.8; normalizeBiol4(); break;
+	case 's': odpor -= odpor * 0.4;       normalizeBiol4(); break;
+	case 'M': ruch += (1 - ruch) * 0.8;   normalizeBiol4(); break;
+	case 'm': ruch -= ruch * 0.4;         normalizeBiol4(); break;
+	case 'F': friction += (4 - friction) * 0.2; break;
+	case 'f': friction -= friction * 0.2;       break;
+	case 'W': mass += (2.0 - mass) * 0.3;   break;
+	case 'w': mass += (0.5 - mass) * 0.3;   break;
+	case 'E': energ += (10.0 - energ) * 0.1; break;
+	case 'e': energ -= energ * 0.1;          break;
+	}
 }
 
 void f4_Props::adjust()
 {
-  len = 0.5*len + 0.5*stdProps.len;
-  curv = 0.66 * curv;
-  twist = 0.66 * twist;
+	len = 0.5*len + 0.5*stdProps.len;
+	curv = 0.66 * curv;
+	twist = 0.66 * twist;
 }
 
@@ -105,8 +90,8 @@
 
 void rolling_dec(double * v) {
-  *v -= 0.7853;  // 0.7853981  45 degrees
+	*v -= 0.7853;  // 0.7853981  45 degrees
 }
 void rolling_inc(double * v) {
-  *v += 0.7853;  // 0.7853981  45 degrees
+	*v += 0.7853;  // 0.7853981  45 degrees
 }
 
@@ -114,140 +99,140 @@
 int scanrec(const char * s, unsigned int slen, char stopchar)
 {
-  unsigned int i = 0;
-  //DB( printf("    scan('%s', '%c')\n", s, stopchar); )
-  while (1)
-  {
-    if (i >= slen)  // ran out the string, should never happen with correct string
-      return 1;
-    if (stopchar == s[i])  // bumped into stopchar
-      return i;
-    if (i < slen-1)  
-    { // s[i] is not the last char
-      if (s[i] == '(') 
-      {
-        i += 2+scanrec(s+i+1, slen-i-1, ')');
-        continue;
-      }
-      if (s[i] == '<') 
-      {
-        i += 2+scanrec(s+i+1, slen-i-1, '>');
-        continue;
-      }
-      if (s[i] == '#') 
-      {
-        i += 2+scanrec(s+i+1, slen-i-1, '>');
-        continue;
-      }
-    }
-    // s[i] a non-special character
-    i++;
-  }
-  return i;
+	unsigned int i = 0;
+	//DB( printf("    scan('%s', '%c')\n", s, stopchar); )
+	while (1)
+	{
+		if (i >= slen)  // ran out the string, should never happen with correct string
+			return 1;
+		if (stopchar == s[i])  // bumped into stopchar
+			return i;
+		if (i < slen - 1)
+		{ // s[i] is not the last char
+			if (s[i] == '(')
+			{
+				i += 2 + scanrec(s + i + 1, slen - i - 1, ')');
+				continue;
+			}
+			if (s[i] == '<')
+			{
+				i += 2 + scanrec(s + i + 1, slen - i - 1, '>');
+				continue;
+			}
+			if (s[i] == '#')
+			{
+				i += 2 + scanrec(s + i + 1, slen - i - 1, '>');
+				continue;
+			}
+		}
+		// s[i] a non-special character
+		i++;
+	}
+	return i;
 }
 
 
 f4_Cell::f4_Cell(int nname,
-    f4_Cell * ndad, int nangle, f4_Props newP)
-{
-  name    = nname;
-  type    = T_UNDIFF4;
-  dadlink = ndad;
-  org     = NULL;
-  genot   = NULL;
-  gcur    = NULL;
-  active  = 1;
-  repeat.null();
-  //genoRange.clear(); -- implicit
-
-  anglepos   = nangle;
-  commacount = 0;
-  childcount = 0;
-  P          = newP;
-  rolling    = 0;
-  xrot       = 0;
-  zrot       = 0;
-  //OM = Orient_1;
-  ctrl    = 0;
-  state   = 0;
-  inertia = 0.8;
-  force   = 0.04;
-  sigmo   = 2;
-  nolink = 0;
-
-  // adjust firstend and OM if there is a stick dad
-  if (ndad != NULL)
-  {
-    // make sure it is a stick (and not a stick f4_Cell!)
-    if (T_STICK4 == ndad->type)
-    {
-      //firstend = ndad->lastend;
-      //OM = ndad->OM;
-      ndad->childcount++;
-    }
-    if (T_NEURON4 == ndad->type)
-    {
-      state   = ndad->state;
-      inertia = ndad->inertia;
-      force   = ndad->force;
-      sigmo   = ndad->sigmo;
-    }
-  }
-  // adjust lastend
-  //lastend = firstend + ((Orient)OM * (Pt3D(1,0,0) * P.len));
-  mz = 1;
+	f4_Cell * ndad, int nangle, f4_Props newP)
+{
+	name = nname;
+	type = T_UNDIFF4;
+	dadlink = ndad;
+	org = NULL;
+	genot = NULL;
+	gcur = NULL;
+	active = 1;
+	repeat.null();
+	//genoRange.clear(); -- implicit
+
+	anglepos = nangle;
+	commacount = 0;
+	childcount = 0;
+	P = newP;
+	rolling = 0;
+	xrot = 0;
+	zrot = 0;
+	//OM = Orient_1;
+	ctrl = 0;
+	state = 0;
+	inertia = 0.8;
+	force = 0.04;
+	sigmo = 2;
+	nolink = 0;
+
+	// adjust firstend and OM if there is a stick dad
+	if (ndad != NULL)
+	{
+		// make sure it is a stick (and not a stick f4_Cell!)
+		if (T_STICK4 == ndad->type)
+		{
+			//firstend = ndad->lastend;
+			//OM = ndad->OM;
+			ndad->childcount++;
+		}
+		if (T_NEURON4 == ndad->type)
+		{
+			state = ndad->state;
+			inertia = ndad->inertia;
+			force = ndad->force;
+			sigmo = ndad->sigmo;
+		}
+	}
+	// adjust lastend
+	//lastend = firstend + ((Orient)OM * (Pt3D(1,0,0) * P.len));
+	mz = 1;
 }
 
 
 f4_Cell::f4_Cell(f4_Cells * nO, int nname, f4_node * ngeno, f4_node * ngcur,
-    f4_Cell * ndad, int nangle, f4_Props newP)
-{
-  name    = nname;
-  type    = T_UNDIFF4;
-  dadlink = ndad;
-  org     = nO;
-  genot   = ngeno;
-  gcur    = ngcur;
-  active = 1;
-  repeat.null();
-  //genoRange.clear(); -- implicit
-  // preserve geno range of parent cell
-  if (NULL != ndad)
-    genoRange.add( ndad->genoRange );
-
-  anglepos   = nangle;
-  commacount = 0;
-  childcount = 0;
-  P          = newP;
-  rolling    = 0;
-  xrot       = 0;
-  zrot       = 0;
-  //OM = Orient_1;
-  ctrl    = 0;
-  state   = 0;
-  inertia = 0.8;
-  force   = 0.04;
-  sigmo   = 2;
-  nolink = 0;
-
-  // adjust firstend and OM if there is a stick dad
-  if (ndad != NULL)
-  {
-    // make sure it is a stick (and not a stick f4_Cell!)
-    if (T_STICK4 == ndad->type) {
-      //firstend = ndad->lastend;
-      //OM = ndad->OM;
-      ndad->childcount++;
-    }
-    if (T_NEURON4 == ndad->type) 
-    {
-      state   = ndad->state;
-      inertia = ndad->inertia;
-      force   = ndad->force;
-      sigmo   = ndad->sigmo;
-    }
-  }
-  // adjust lastend
-  //lastend = firstend + ((Orient)OM * (Pt3D(1,0,0) * P.len));
-  mz = 1;
+	f4_Cell * ndad, int nangle, f4_Props newP)
+{
+	name = nname;
+	type = T_UNDIFF4;
+	dadlink = ndad;
+	org = nO;
+	genot = ngeno;
+	gcur = ngcur;
+	active = 1;
+	repeat.null();
+	//genoRange.clear(); -- implicit
+	// preserve geno range of parent cell
+	if (NULL != ndad)
+		genoRange.add(ndad->genoRange);
+
+	anglepos = nangle;
+	commacount = 0;
+	childcount = 0;
+	P = newP;
+	rolling = 0;
+	xrot = 0;
+	zrot = 0;
+	//OM = Orient_1;
+	ctrl = 0;
+	state = 0;
+	inertia = 0.8;
+	force = 0.04;
+	sigmo = 2;
+	nolink = 0;
+
+	// adjust firstend and OM if there is a stick dad
+	if (ndad != NULL)
+	{
+		// make sure it is a stick (and not a stick f4_Cell!)
+		if (T_STICK4 == ndad->type) {
+			//firstend = ndad->lastend;
+			//OM = ndad->OM;
+			ndad->childcount++;
+		}
+		if (T_NEURON4 == ndad->type)
+		{
+			state = ndad->state;
+			inertia = ndad->inertia;
+			force = ndad->force;
+			sigmo = ndad->sigmo;
+		}
+	}
+	// adjust lastend
+	//lastend = firstend + ((Orient)OM * (Pt3D(1,0,0) * P.len));
+	mz = 1;
 }
 
@@ -255,350 +240,354 @@
 f4_Cell::~f4_Cell()
 {
-  // remove links
-  if (nolink)
-  {
-    int i;
-    for (i=nolink-1; i>=0; i--)
-      delete links[i];
-    nolink=0;
-  }
+	// remove links
+	if (nolink)
+	{
+		int i;
+		for (i = nolink - 1; i >= 0; i--)
+			delete links[i];
+		nolink = 0;
+	}
 }
 
 
 /* return codes:
-    >1 error at pos
-     0  halt development for a cycle
-    -1  development finished OK
-*/
+	>1 error at pos
+	0  halt development for a cycle
+	-1  development finished OK
+	*/
 int f4_Cell::onestep()
 {
-  int i, j, k, relfrom, t;
-  double w;
-  f4_Cell * tmp;
-  f4_Cell * tneu;
-  if (gcur == NULL)
-  {
-    active = 0;
-    return 0;  // stop
-  }
-  while ( NULL != gcur )
-  {
-    //DB( printf("  %d (%d) executing '%c' %d\n", name, type, gcur->name, gcur->pos); )
-    // currently this is the last one processed
-    // the current genotype code is processed
-    genoRange.add( gcur->pos );
-    switch (gcur->name)
-    {
-    case '<':
-      // cell division!
-      //DB( printf("  div! %d\n", name); )
-
-      // error: sticks cannot divide
-      if (T_STICK4 == type) {
-        // cannot fix
-        org->setError(gcur->pos);
-        return 1;  // stop
-      }
-
-      // undiff divides
-      if (T_UNDIFF4 == type) {
-        // commacount is set only when daughter turns into X
-        // daughter cell
-        // adjust new len
-        f4_Props newP = P;
-        newP.adjust();
-        tmp = new f4_Cell(org, org->nc, genot, gcur->child2,
-         this,  commacount, newP);
-        tmp->repeat = repeat;
-        repeat.null();
-        org->addCell( tmp );
-      }
-      // a neuron divides: create a new, duplicate links
-      if (T_NEURON4 == type) {
-        // daughter cell
-        tmp = new f4_Cell(org, org->nc, genot, gcur->child2,
-          // has the same dadlink
-          this->dadlink, commacount, P);
-        tmp->repeat = repeat;
-        repeat.null();
-        // it is a neuron from start
-        tmp->type = T_NEURON4;
-        // duplicate links
-        f4_CellLink * ll;
-        for (i=0; i<nolink; i++) {
-          ll = links[i];
-          tmp->addlink(ll->from, ll->w, ll->t);
-        }
-        org->addCell( tmp );
-      }
-      // adjustments for this cell
-      gcur = gcur->child;
-      // halt development
-      return 0;
-
-    case '>':
-      // finish
-      // see if there is a repet count
-      if (repeat.top > 0)
-      { // there is a repeat counter
-        if (!repeat.first()->isNull())
-        { // repeat counter is not null
-          repeat.first()->dec();
-          if (repeat.first()->count > 0)
-          {
-            // return to repeat
-            gcur = repeat.first()->node->child;
-          } else {
-            // continue
-            gcur = repeat.first()->node->child2;
-            repeat.pop();
-          }
-          break;
-        } else {
-          repeat.pop();
-        }
-      } else {
-        // error: still undiff
-        if (T_UNDIFF4 == type)
-        {
-          // fix it: insert an 'X'
-          f4_node * insertnode = new f4_node('X', NULL, gcur->pos);
-          if (org->setRepairInsert(gcur->pos, gcur, insertnode))
-            // not in repair mode, release
-            delete insertnode;
-          return 1;
-        }
-        repeat.null();
-        active = 0;  // stop
-        // eat up rest
-        gcur = NULL;
-        return 0;
-      }
-
-    case '#':
-      // repetition marker
-      if (repeat.top >= repeat_stack::stackSize)
-      {
-        // repepeat pointer stack is full, cannot remember this one.
-        // fix: delete it
-        org->setRepairRemove(gcur->pos, gcur);
-        return 1;  // stop
-      }
-      repeat.push( repeat_ptr(gcur, gcur->i1) );
-      gcur = gcur->child;
-      break;
-
-    case ',':
-      commacount++;
-      gcur = gcur->child;
-      break;
-
-    case 'r':  case 'R':
-      // error: if neuron
-      if (T_NEURON4 == type) {
-        // fix: delete it
-        org->setRepairRemove(gcur->pos, gcur);
-        return 1;  // stop
-      }
-      switch (gcur->name) {
-       case 'r':   rolling_dec( &rolling ); break;
-       case 'R':   rolling_inc( &rolling ); break;
-      }
-      gcur = gcur->child;
-      break;
-
-    case 'l':  case 'L':
-    case 'c':  case 'C':
-    case 'q':  case 'Q':
-    case 'a':  case 'A':
-    case 'i':  case 'I':
-    case 's':  case 'S':
-    case 'm':  case 'M':
-    case 'f':  case 'F':
-    case 'w':  case 'W':
-    case 'e':  case 'E':
-      // error: if neuron
-      if (T_NEURON4 == type) {
-        // fix: delete it
-        org->setRepairRemove(gcur->pos, gcur);
-        return 1;  // stop
-      }
-      P.executeModifier(gcur->name);
-      gcur = gcur->child;
-      break;
-
-    case 'X':
-      // turn undiff. cell into a stick
-      // error: already differentiated
-      if (T_UNDIFF4 != type) {
-        // fix: delete this node
-        org->setRepairRemove(gcur->pos, gcur);
-        return 1;  // stop
-      }
-      type = T_STICK4;
-      // fix dad commacount and own anglepos
-      if (NULL != dadlink) {
-        dadlink->commacount++;
-        anglepos = dadlink->commacount;
-      }
-      // change of type halts developments, see comment at 'N'
-      gcur = gcur->child;
-      return 0;
-
-    case 'N':
-      // turn undiff. cell into a neuron
-      // error: already differentiated
-      if (T_UNDIFF4 != type) {
-        // fix: delete this node
-        org->setRepairRemove(gcur->pos, gcur);
-        return 1;  // stop
-      }
-      // error: if no previous
-      if (NULL == dadlink) {
-        // fix: delete it
-        org->setRepairRemove(gcur->pos, gcur);
-        return 1;  // stop
-      }
-      type = T_NEURON4;
-      // change of type also halts development, to give other
-      // cells a chance for adjustment.  Namely, it is important
-      // to wait for other cells to turn N before adding links
-      gcur = gcur->child;
-      return 0;
-
-    case '@':
-    case '|':
-      // neuron rotating / bending
-      j = 1;
-      if ('@' == gcur->name) j = 1; // rot
-      if ('|' == gcur->name) j = 2; // bend
-      // error: not a neuron (undiff)
-      if (T_UNDIFF4 == type) {
-        // fix: delete it
-        org->setRepairRemove(gcur->pos, gcur);
-        return 1;  // stop
-      }
-      // error: not a neuron (stick)
-      if (T_NEURON4 != type) {
-        // fix: delete it
-        org->setRepairRemove(gcur->pos, gcur);
-        return 1;  // stop
-      }
-      // error: already has control
-      if (ctrl != 0) {
-        // fix: delete it
-        org->setRepairRemove(gcur->pos, gcur);
-        return 1;  // stop
-      }
-      // make neuron ctrl = 1 or 2
-      ctrl = j;
-      gcur = gcur->child;
-      break;
-
-    case '[':
-      // link to neuron
-      // error: not a neuron
-      if (T_NEURON4 != type) {
-        // fix: delete it
-        org->setRepairRemove(gcur->pos, gcur);
-        return 1;  // stop
-      }
-      // input ('*', 'G', 'T', 'S', or %d)
-      t       = gcur->i1;
-      relfrom = gcur->l1;
-      w       = gcur->f1;
-      if (t>0) {
-        // * or G
-        tneu = NULL;
-      } else {
-        // input from other neuron
-        // find neuron at relative i
-        // find own index
-        j = 0; k = 0;
-        for(i=0; i<org->nc; i++) {
-          if (org->C[i]->type == T_NEURON4) k++;
-          if (org->C[i] == this) {j=k-1; break;}
-        }
-        // find index of incoming
-        j = j + relfrom;
-        if (j<0) goto wait_link;
-        if (j>=org->nc) goto wait_link;
-        // find that neuron
-        k = 0;
-        for(i=0; i<org->nc; i++) {
-          if (org->C[i]->type == T_NEURON4) k++;
-          if (j == (k-1)) break;
-        }
-        if (i>=org->nc) goto wait_link;
-        tneu = org->C[i];
-      }
-      // add link
-      // error: could not add link (too many?)
-      if (addlink(tneu, w, t)) {
-        // cannot fix
-        org->setError(gcur->pos);
-        return 1;  // stop
-      }
-      gcur = gcur->child;
-      break;
-    wait_link:
-      // wait for other neurons to develop
-      // if there are others still active
-      active = 0;
-      j = 0;
-      for(i=0; i<org->nc; i++) {
-        if (org->C[i]->active) j++;
-      }
-      if (j>0)
-        return 0;  // there is other active, halt, try again
-      // no more actives, cannot add link, ignore, but treat not as an error
-      gcur = gcur->child;
-      break;
-
-    case ':':
-      // neuron parameter
-      // error: not a neuron
-      if (T_NEURON4 != type) {
-        // fix: delete it
-        org->setRepairRemove(gcur->pos, gcur);
-        return 1;  // stop
-      }
-      j = (int)gcur->l1;
-      switch ((char)gcur->i1) {
-       case '!': 
-        if (j) force += (1.0 - force) * 0.2;
-        else   force -= force * 0.2; break;
-       case '=': 
-        if (j) inertia += (1.0 - inertia) * 0.2;
-        else   inertia -= inertia * 0.2; break;
-       case '/': 
-        if (j) sigmo *= 1.4;
-        else   sigmo /= 1.4; break;
-       default:
-         org->setRepairRemove(gcur->pos, gcur);
-         return 1;  // stop
-      }
-      gcur = gcur->child;
-      break;
-
-    case ' ':
-      // space has no effect, should not occur
-      // fix: delete it
-      org->setRepairRemove(gcur->pos, gcur);
-      gcur = gcur->child;
-      break;
-
-    default:
-      // error: unknown code
-      char buf[40];
-      sprintf(buf, "unknown code '%c'", gcur->name);
-      FramMessage("f4_Cell", "onestep", buf, 2);
-      // fix: delete it
-      org->setRepairRemove(gcur->pos, gcur);
-      return 1; // stop
-    }
-  }
-  active = 0;  // done
-  return 0;
+	int i, j, k, relfrom, t;
+	double w;
+	f4_Cell * tmp;
+	f4_Cell * tneu;
+	if (gcur == NULL)
+	{
+		active = 0;
+		return 0;  // stop
+	}
+	while (NULL != gcur)
+	{
+		//DB( printf("  %d (%d) executing '%c' %d\n", name, type, gcur->name, gcur->pos); )
+		// currently this is the last one processed
+		// the current genotype code is processed
+		genoRange.add(gcur->pos);
+		switch (gcur->name)
+		{
+		case '<':
+			// cell division!
+			//DB( printf("  div! %d\n", name); )
+
+			// error: sticks cannot divide
+			if (T_STICK4 == type) {
+				// cannot fix
+				org->setError(gcur->pos);
+				return 1;  // stop
+			}
+
+			// undiff divides
+			if (T_UNDIFF4 == type) {
+				// commacount is set only when daughter turns into X
+				// daughter cell
+				// adjust new len
+				f4_Props newP = P;
+				newP.adjust();
+				tmp = new f4_Cell(org, org->nc, genot, gcur->child2,
+					this, commacount, newP);
+				tmp->repeat = repeat;
+				repeat.null();
+				org->addCell(tmp);
+			}
+			// a neuron divides: create a new, duplicate links
+			if (T_NEURON4 == type) {
+				// daughter cell
+				tmp = new f4_Cell(org, org->nc, genot, gcur->child2,
+					// has the same dadlink
+					this->dadlink, commacount, P);
+				tmp->repeat = repeat;
+				repeat.null();
+				// it is a neuron from start
+				tmp->type = T_NEURON4;
+				// duplicate links
+				f4_CellLink * ll;
+				for (i = 0; i < nolink; i++) {
+					ll = links[i];
+					tmp->addlink(ll->from, ll->w, ll->t);
+				}
+				org->addCell(tmp);
+			}
+			// adjustments for this cell
+			gcur = gcur->child;
+			// halt development
+			return 0;
+
+		case '>':
+			// finish
+			// see if there is a repet count
+			if (repeat.top > 0)
+			{ // there is a repeat counter
+				if (!repeat.first()->isNull())
+				{ // repeat counter is not null
+					repeat.first()->dec();
+					if (repeat.first()->count > 0)
+					{
+						// return to repeat
+						gcur = repeat.first()->node->child;
+					}
+					else {
+						// continue
+						gcur = repeat.first()->node->child2;
+						repeat.pop();
+					}
+					break;
+				}
+				else {
+					repeat.pop();
+				}
+			}
+			else {
+				// error: still undiff
+				if (T_UNDIFF4 == type)
+				{
+					// fix it: insert an 'X'
+					f4_node * insertnode = new f4_node('X', NULL, gcur->pos);
+					if (org->setRepairInsert(gcur->pos, gcur, insertnode))
+						// not in repair mode, release
+						delete insertnode;
+					return 1;
+				}
+				repeat.null();
+				active = 0;  // stop
+				// eat up rest
+				gcur = NULL;
+				return 0;
+			}
+
+		case '#':
+			// repetition marker
+			if (repeat.top >= repeat_stack::stackSize)
+			{
+				// repepeat pointer stack is full, cannot remember this one.
+				// fix: delete it
+				org->setRepairRemove(gcur->pos, gcur);
+				return 1;  // stop
+			}
+			repeat.push(repeat_ptr(gcur, gcur->i1));
+			gcur = gcur->child;
+			break;
+
+		case ',':
+			commacount++;
+			gcur = gcur->child;
+			break;
+
+		case 'r':  case 'R':
+			// error: if neuron
+			if (T_NEURON4 == type) {
+				// fix: delete it
+				org->setRepairRemove(gcur->pos, gcur);
+				return 1;  // stop
+			}
+			switch (gcur->name) {
+			case 'r':   rolling_dec(&rolling); break;
+			case 'R':   rolling_inc(&rolling); break;
+			}
+			gcur = gcur->child;
+			break;
+
+		case 'l':  case 'L':
+		case 'c':  case 'C':
+		case 'q':  case 'Q':
+		case 'a':  case 'A':
+		case 'i':  case 'I':
+		case 's':  case 'S':
+		case 'm':  case 'M':
+		case 'f':  case 'F':
+		case 'w':  case 'W':
+		case 'e':  case 'E':
+			// error: if neuron
+			if (T_NEURON4 == type) {
+				// fix: delete it
+				org->setRepairRemove(gcur->pos, gcur);
+				return 1;  // stop
+			}
+			P.executeModifier(gcur->name);
+			gcur = gcur->child;
+			break;
+
+		case 'X':
+			// turn undiff. cell into a stick
+			// error: already differentiated
+			if (T_UNDIFF4 != type) {
+				// fix: delete this node
+				org->setRepairRemove(gcur->pos, gcur);
+				return 1;  // stop
+			}
+			type = T_STICK4;
+			// fix dad commacount and own anglepos
+			if (NULL != dadlink) {
+				dadlink->commacount++;
+				anglepos = dadlink->commacount;
+			}
+			// change of type halts developments, see comment at 'N'
+			gcur = gcur->child;
+			return 0;
+
+		case 'N':
+			// turn undiff. cell into a neuron
+			// error: already differentiated
+			if (T_UNDIFF4 != type) {
+				// fix: delete this node
+				org->setRepairRemove(gcur->pos, gcur);
+				return 1;  // stop
+			}
+			// error: if no previous
+			if (NULL == dadlink) {
+				// fix: delete it
+				org->setRepairRemove(gcur->pos, gcur);
+				return 1;  // stop
+			}
+			type = T_NEURON4;
+			// change of type also halts development, to give other
+			// cells a chance for adjustment.  Namely, it is important
+			// to wait for other cells to turn N before adding links
+			gcur = gcur->child;
+			return 0;
+
+		case '@':
+		case '|':
+			// neuron rotating / bending
+			j = 1;
+			if ('@' == gcur->name) j = 1; // rot
+			if ('|' == gcur->name) j = 2; // bend
+			// error: not a neuron (undiff)
+			if (T_UNDIFF4 == type) {
+				// fix: delete it
+				org->setRepairRemove(gcur->pos, gcur);
+				return 1;  // stop
+			}
+			// error: not a neuron (stick)
+			if (T_NEURON4 != type) {
+				// fix: delete it
+				org->setRepairRemove(gcur->pos, gcur);
+				return 1;  // stop
+			}
+			// error: already has control
+			if (ctrl != 0) {
+				// fix: delete it
+				org->setRepairRemove(gcur->pos, gcur);
+				return 1;  // stop
+			}
+			// make neuron ctrl = 1 or 2
+			ctrl = j;
+			gcur = gcur->child;
+			break;
+
+		case '[':
+			// link to neuron
+			// error: not a neuron
+			if (T_NEURON4 != type) {
+				// fix: delete it
+				org->setRepairRemove(gcur->pos, gcur);
+				return 1;  // stop
+			}
+			// input ('*', 'G', 'T', 'S', or %d)
+			t = gcur->i1;
+			relfrom = gcur->l1;
+			w = gcur->f1;
+			if (t > 0) {
+				// * or G
+				tneu = NULL;
+			}
+			else {
+				// input from other neuron
+				// find neuron at relative i
+				// find own index
+				j = 0; k = 0;
+				for (i = 0; i < org->nc; i++) {
+					if (org->C[i]->type == T_NEURON4) k++;
+					if (org->C[i] == this) { j = k - 1; break; }
+				}
+				// find index of incoming
+				j = j + relfrom;
+				if (j < 0) goto wait_link;
+				if (j >= org->nc) goto wait_link;
+				// find that neuron
+				k = 0;
+				for (i = 0; i < org->nc; i++) {
+					if (org->C[i]->type == T_NEURON4) k++;
+					if (j == (k - 1)) break;
+				}
+				if (i >= org->nc) goto wait_link;
+				tneu = org->C[i];
+			}
+			// add link
+			// error: could not add link (too many?)
+			if (addlink(tneu, w, t)) {
+				// cannot fix
+				org->setError(gcur->pos);
+				return 1;  // stop
+			}
+			gcur = gcur->child;
+			break;
+		wait_link:
+			// wait for other neurons to develop
+			// if there are others still active
+			active = 0;
+			j = 0;
+			for (i = 0; i<org->nc; i++) {
+				if (org->C[i]->active) j++;
+			}
+			if (j>0)
+				return 0;  // there is other active, halt, try again
+			// no more actives, cannot add link, ignore, but treat not as an error
+			gcur = gcur->child;
+			break;
+
+		case ':':
+			// neuron parameter
+			// error: not a neuron
+			if (T_NEURON4 != type) {
+				// fix: delete it
+				org->setRepairRemove(gcur->pos, gcur);
+				return 1;  // stop
+			}
+			j = (int)gcur->l1;
+			switch ((char)gcur->i1) {
+			case '!':
+				if (j) force += (1.0 - force) * 0.2;
+				else   force -= force * 0.2; break;
+			case '=':
+				if (j) inertia += (1.0 - inertia) * 0.2;
+				else   inertia -= inertia * 0.2; break;
+			case '/':
+				if (j) sigmo *= 1.4;
+				else   sigmo /= 1.4; break;
+			default:
+				org->setRepairRemove(gcur->pos, gcur);
+				return 1;  // stop
+			}
+			gcur = gcur->child;
+			break;
+
+		case ' ':
+			// space has no effect, should not occur
+			// fix: delete it
+			org->setRepairRemove(gcur->pos, gcur);
+			gcur = gcur->child;
+			break;
+
+		default:
+			// error: unknown code
+			char buf[40];
+			sprintf(buf, "unknown code '%c'", gcur->name);
+			FramMessage("f4_Cell", "onestep", buf, 2);
+			// fix: delete it
+			org->setRepairRemove(gcur->pos, gcur);
+			return 1; // stop
+		}
+	}
+	active = 0;  // done
+	return 0;
 }
 
@@ -606,8 +595,8 @@
 int f4_Cell::addlink(f4_Cell * nfrom, double nw, long nt)
 {
-  if (nolink >= MAXINPUTS-1) return -1; // full!
-  links[nolink] = new f4_CellLink(nfrom, nw, nt);
-  nolink++;
-  return 0;
+	if (nolink >= MAXINPUTS - 1) return -1; // full!
+	links[nolink] = new f4_CellLink(nfrom, nw, nt);
+	nolink++;
+	return 0;
 }
 
@@ -615,69 +604,71 @@
 void f4_Cell::adjustRec()
 {
-  //f4_OrientMat rot;
-  int     i;
-
-  if (recProcessedFlag)
-    // already processed
-    return;
-
-  // mark it processed
-  recProcessedFlag = 1;
-
-  // make sure its parent is processed first
-  if (NULL != dadlink)
-    dadlink->adjustRec();
-
-  // count children
-  childcount = 0;
-  for(i=0; i<org->nc; i++)
-  {
-    if (org->C[i]->dadlink == this)
-      if (org->C[i]->type == T_STICK4)
-        childcount++;
-  }
-
-  if (type == T_STICK4)
-  {
-    if (NULL == dadlink)
-    {
-      //firstend = Pt3D_0;
-      // rotation due to rolling
-      xrot = rolling;
-      mz = 1;
-    } else {
-      //firstend = dadlink->lastend;
-      f4_Props Pdad = dadlink->P;
-      f4_Props Padj = Pdad;
-      Padj.adjust();
-
-      //rot = Orient_1;
-
-      // rotation due to rolling
-      xrot = rolling +
-        // rotation due to twist
-        Pdad.twist;
-      if (dadlink->commacount <= 1)
-      {
-        // rotation due to curvedness
-        zrot = Padj.curv;
-      } else {
-        zrot = Padj.curv +
-          // GDK uses 3.141 instead of PI!
-          (anglepos * 1.0/(dadlink->commacount+1) - 0.5) * 3.141 * 2.0;
-      }
-
-      //rot = rot * f4_OrientMat(yOz, xrot);
-      //rot = rot * f4_OrientMat(xOy, zrot);
-      // rotation relative to parent stick
-      //OM = rot * OM;
-
-      // rotation in world coordinates
-      //OM =  ((f4_OrientMat)dadlink->OM) * OM;
-      mz = dadlink->mz / dadlink->childcount;
-    }
-    //Pt3D lastoffset = (Orient)OM * (Pt3D(1,0,0)*P.len);
-    //lastend = firstend + lastoffset;
-  }
+	//f4_OrientMat rot;
+	int     i;
+
+	if (recProcessedFlag)
+		// already processed
+		return;
+
+	// mark it processed
+	recProcessedFlag = 1;
+
+	// make sure its parent is processed first
+	if (NULL != dadlink)
+		dadlink->adjustRec();
+
+	// count children
+	childcount = 0;
+	for (i = 0; i < org->nc; i++)
+	{
+		if (org->C[i]->dadlink == this)
+			if (org->C[i]->type == T_STICK4)
+				childcount++;
+	}
+
+	if (type == T_STICK4)
+	{
+		if (NULL == dadlink)
+		{
+			//firstend = Pt3D_0;
+			// rotation due to rolling
+			xrot = rolling;
+			mz = 1;
+		}
+		else {
+			//firstend = dadlink->lastend;
+			f4_Props Pdad = dadlink->P;
+			f4_Props Padj = Pdad;
+			Padj.adjust();
+
+			//rot = Orient_1;
+
+			// rotation due to rolling
+			xrot = rolling +
+				// rotation due to twist
+				Pdad.twist;
+			if (dadlink->commacount <= 1)
+			{
+				// rotation due to curvedness
+				zrot = Padj.curv;
+			}
+			else {
+				zrot = Padj.curv +
+					// GDK uses 3.141 instead of PI!
+					(anglepos * 1.0 / (dadlink->commacount + 1) - 0.5) * 3.141 * 2.0;
+			}
+
+			//rot = rot * f4_OrientMat(yOz, xrot);
+			//rot = rot * f4_OrientMat(xOy, zrot);
+			// rotation relative to parent stick
+			//OM = rot * OM;
+
+			// rotation in world coordinates
+			//OM =  ((f4_OrientMat)dadlink->OM) * OM;
+			mz = dadlink->mz / dadlink->childcount;
+		}
+		//Pt3D lastoffset = (Orient)OM * (Pt3D(1,0,0)*P.len);
+		//lastend = firstend + lastoffset;
+	}
 }
 
@@ -686,7 +677,7 @@
 f4_CellLink::f4_CellLink(f4_Cell * nfrom, double nw, long nt)
 {
-  from = nfrom;
-  w    = nw;
-  t    = nt;
+	from = nfrom;
+	w = nw;
+	t = nt;
 }
 
@@ -695,16 +686,16 @@
 f4_Cells::f4_Cells(f4_node * genome, int nrepair)
 {
-  // create ancestor cell
-  repair = nrepair;
-  error  = 0;
-  errorpos = -1;
-  repair_remove = NULL;
-  repair_parent = NULL;
-  repair_insert = NULL;
-  tmpcel = NULL;
-  f4rootnode = NULL;
-
-  C[0] = new f4_Cell(this, 0, genome, genome, NULL, 0, stdProps);
-  nc   = 1;
+	// create ancestor cell
+	repair = nrepair;
+	error = 0;
+	errorpos = -1;
+	repair_remove = NULL;
+	repair_parent = NULL;
+	repair_insert = NULL;
+	tmpcel = NULL;
+	f4rootnode = NULL;
+
+	C[0] = new f4_Cell(this, 0, genome, genome, NULL, 0, stdProps);
+	nc = 1;
 }
 
@@ -712,41 +703,41 @@
 f4_Cells::f4_Cells(SString & genome, int nrepair)
 {
-  int res;
-  repair = nrepair;
-  error  = 0;
-  errorpos = -1;
-  repair_remove = NULL;
-  repair_parent = NULL;
-  repair_insert = NULL;
-  tmpcel = NULL;
-  f4rootnode = NULL;
-
-  // transform geno from string to nodes
-  f4rootnode = new f4_node();
-  res = f4_processrec((const char*)genome, (unsigned)0, f4rootnode);
-  if ((res<0) || (1 != f4rootnode->childCount()))
-  {
-    error = GENOPER_OPFAIL;
-    errorpos = -1;
-  }
-
-  // create ancestor cell
-  C[0] = new f4_Cell(this, 0, f4rootnode->child, f4rootnode->child,
-    NULL, 0, stdProps);
-  nc   = 1;
+	int res;
+	repair = nrepair;
+	error = 0;
+	errorpos = -1;
+	repair_remove = NULL;
+	repair_parent = NULL;
+	repair_insert = NULL;
+	tmpcel = NULL;
+	f4rootnode = NULL;
+
+	// transform geno from string to nodes
+	f4rootnode = new f4_node();
+	res = f4_processrec((const char*)genome, (unsigned)0, f4rootnode);
+	if ((res < 0) || (1 != f4rootnode->childCount()))
+	{
+		error = GENOPER_OPFAIL;
+		errorpos = -1;
+	}
+
+	// create ancestor cell
+	C[0] = new f4_Cell(this, 0, f4rootnode->child, f4rootnode->child,
+		NULL, 0, stdProps);
+	nc = 1;
 }
 
 f4_Cells::~f4_Cells()
 {
-  // release cells
-  int i;
-  if (nc)
-  {
-    for (i=nc-1; i>=0; i--)
-      delete C[i];
-    nc = 0;
-  }
-  if (f4rootnode)
-    delete f4rootnode;
+	// release cells
+	int i;
+	if (nc)
+	{
+		for (i = nc - 1; i >= 0; i--)
+			delete C[i];
+		nc = 0;
+	}
+	if (f4rootnode)
+		delete f4rootnode;
 }
 
@@ -754,19 +745,19 @@
 int f4_Cells::onestep()
 {
-  int i, ret, oldnc, ret2;
-  oldnc = nc;
-  ret=0;
-  for (i=0; i<oldnc; i++) {
-    ret2 = C[i]->onestep();
-    if (ret2>0) {
-      // error
-      C[i]->active = 0;  // stop
-      return 0;
-    }
-    // if still active
-    if (C[i]->active)
-      ret=1;
-  }
-  return ret;
+	int i, ret, oldnc, ret2;
+	oldnc = nc;
+	ret = 0;
+	for (i = 0; i<oldnc; i++) {
+		ret2 = C[i]->onestep();
+		if (ret2>0) {
+			// error
+			C[i]->active = 0;  // stop
+			return 0;
+		}
+		// if still active
+		if (C[i]->active)
+			ret = 1;
+	}
+	return ret;
 }
 
@@ -774,41 +765,41 @@
 int f4_Cells::simulate()
 {
-  int i;
-  error = GENOPER_OK;
-
-  for (i=0; i<nc; i++)  C[i]->active = 1;
-
-  // execute onestep() in a cycle
-  while (onestep()) ;
-
-  if (GENOPER_OK != error) return error;
-
-  // fix neuron attachements
-  for(i=0; i<nc; i++)
-    if (C[i]->type == T_NEURON4) {
-      while (T_NEURON4 == C[i]->dadlink->type) {
-        C[i]->dadlink = C[i]->dadlink->dadlink;
-      }
-  }
-
-  // there should be no undiff. cells
-  // make undifferentiated cells sticks
-  for (i=0; i<nc ; i++)
-    if (C[i]->type == T_UNDIFF4) {
-      C[i]->type = T_STICK4;
-      //seterror();
-  }
-
-  // recursive adjust
-  // reset recursive traverse flags
-  for(i=0; i<nc; i++)
-    C[i]->recProcessedFlag = 0;
-  // process every cell
-  for(i=0; i<nc; i++)
-    C[i]->adjustRec();
-
-  //DB( printf("Cell simulation done, %d cells. \n", nc); )
-
-  return error;
+	int i;
+	error = GENOPER_OK;
+
+	for (i = 0; i < nc; i++)  C[i]->active = 1;
+
+	// execute onestep() in a cycle
+	while (onestep());
+
+	if (GENOPER_OK != error) return error;
+
+	// fix neuron attachements
+	for (i = 0; i < nc; i++)
+		if (C[i]->type == T_NEURON4) {
+			while (T_NEURON4 == C[i]->dadlink->type) {
+				C[i]->dadlink = C[i]->dadlink->dadlink;
+			}
+		}
+
+	// there should be no undiff. cells
+	// make undifferentiated cells sticks
+	for (i = 0; i < nc; i++)
+		if (C[i]->type == T_UNDIFF4) {
+			C[i]->type = T_STICK4;
+			//seterror();
+		}
+
+	// recursive adjust
+	// reset recursive traverse flags
+	for (i = 0; i < nc; i++)
+		C[i]->recProcessedFlag = 0;
+	// process every cell
+	for (i = 0; i < nc; i++)
+		C[i]->adjustRec();
+
+	//DB( printf("Cell simulation done, %d cells. \n", nc); )
+
+	return error;
 }
 
@@ -816,10 +807,10 @@
 void f4_Cells::addCell(f4_Cell * newcell)
 {
-  if (nc >= MAX4CELLS-1) {
-    delete newcell;
-    return;
-  }
-  C[nc] = newcell;
-  nc++;
+	if (nc >= MAX4CELLS - 1) {
+		delete newcell;
+		return;
+	}
+	C[nc] = newcell;
+	nc++;
 }
 
@@ -827,76 +818,78 @@
 void f4_Cells::setError(int nerrpos)
 {
-  error = GENOPER_OPFAIL;
-  errorpos = nerrpos;
+	error = GENOPER_OPFAIL;
+	errorpos = nerrpos;
 }
 
 void f4_Cells::setRepairRemove(int nerrpos, f4_node * rem)
 {
-  if (!repair) {
-    // not in repair mode, treat as repairable error
-    error = GENOPER_REPAIR;
-    errorpos = nerrpos;
-  } else {
-    error = GENOPER_REPAIR;
-    errorpos = nerrpos;
-    repair_remove = rem;
-  }
+	if (!repair) {
+		// not in repair mode, treat as repairable error
+		error = GENOPER_REPAIR;
+		errorpos = nerrpos;
+	}
+	else {
+		error = GENOPER_REPAIR;
+		errorpos = nerrpos;
+		repair_remove = rem;
+	}
 }
 
 int f4_Cells::setRepairInsert(int nerrpos, f4_node * parent, f4_node * insert)
 {
-  if (!repair) {
-    // not in repair mode, treat as repairable error
-    error = GENOPER_REPAIR;
-    errorpos = nerrpos;
-    return -1;
-  } else {
-    error = GENOPER_REPAIR;
-    errorpos = nerrpos;
-    repair_parent = parent;
-    repair_insert = insert;
-    return 0;
-  }
+	if (!repair) {
+		// not in repair mode, treat as repairable error
+		error = GENOPER_REPAIR;
+		errorpos = nerrpos;
+		return -1;
+	}
+	else {
+		error = GENOPER_REPAIR;
+		errorpos = nerrpos;
+		repair_parent = parent;
+		repair_insert = insert;
+		return 0;
+	}
 }
 
 void f4_Cells::repairGeno(f4_node * geno, int whichchild)
 {
-  // assemble repaired geno, if the case
-  if (!repair) return;
-  if ((NULL==repair_remove) && (NULL==repair_insert)) return;
-  // traverse genotype tree, remove / insert node
-  f4_node * g2;
-  if (1==whichchild) g2 = geno->child;
-    else             g2 = geno->child2;
-  if (NULL == g2)
-    return;
-  if (g2 == repair_remove) {
-    f4_node * oldgeno;
-    geno->removeChild(g2);
-    if (g2->child) {
-      // add g2->child as child to geno
-      if (1==whichchild) geno->child  = g2->child;
-        else             geno->child2 = g2->child;
-      g2->child->parent = geno;
-    }
-    oldgeno = g2;
-    oldgeno->child = NULL;
-    delete oldgeno;
-    if (NULL == geno->child) return;
-    // check this new
-    repairGeno(geno, whichchild);
-    return;
-  }
-  if (g2 == repair_parent) {
-    geno->removeChild(g2);
-    geno->addChild(repair_insert);
-    repair_insert->parent = geno;
-    repair_insert->child  = g2;
-    repair_insert->child2 = NULL;
-    g2->parent = repair_insert;
-  }
-  // recurse
-  if (g2->child)  repairGeno(g2, 1);
-  if (g2->child2) repairGeno(g2, 2);
+	// assemble repaired geno, if the case
+	if (!repair) return;
+	if ((NULL == repair_remove) && (NULL == repair_insert)) return;
+	// traverse genotype tree, remove / insert node
+	f4_node * g2;
+	if (1 == whichchild) g2 = geno->child;
+	else             g2 = geno->child2;
+	if (NULL == g2)
+		return;
+	if (g2 == repair_remove) {
+		f4_node * oldgeno;
+		geno->removeChild(g2);
+		if (g2->child) {
+			// add g2->child as child to geno
+			if (1 == whichchild) geno->child = g2->child;
+			else             geno->child2 = g2->child;
+			g2->child->parent = geno;
+		}
+		oldgeno = g2;
+		oldgeno->child = NULL;
+		delete oldgeno;
+		if (NULL == geno->child) return;
+		// check this new
+		repairGeno(geno, whichchild);
+		return;
+	}
+	if (g2 == repair_parent) {
+		geno->removeChild(g2);
+		geno->addChild(repair_insert);
+		repair_insert->parent = geno;
+		repair_insert->child = g2;
+		repair_insert->child2 = NULL;
+		g2->parent = repair_insert;
+	}
+	// recurse
+	if (g2->child)  repairGeno(g2, 1);
+	if (g2->child2) repairGeno(g2, 2);
 }
 
@@ -904,9 +897,9 @@
 void f4_Cells::toF1Geno(SString &out)
 {
-  if (tmpcel) delete tmpcel;
-  tmpcel = new f4_Cell(-1, NULL, 0, stdProps);
-  out = "";
-  toF1GenoRec(0, out);
-  delete tmpcel;
+	if (tmpcel) delete tmpcel;
+	tmpcel = new f4_Cell(-1, NULL, 0, stdProps);
+	out = "";
+	toF1GenoRec(0, out);
+	delete tmpcel;
 }
 
@@ -914,105 +907,106 @@
 void f4_Cells::toF1GenoRec(int curc, SString &out)
 {
-  int i, j, ccount;
-  f4_Cell * thisti;
-  f4_Cell * thneu;
-  char buf[200];
-
-  if (curc >= nc) return;
-
-  if (T_STICK4 != C[curc]->type) return;
-
-  thisti = C[curc];
-  if (NULL != thisti->dadlink)  
-    *tmpcel = *(thisti->dadlink);
-
-  // adjust length, curvedness, etc.
-  tmpcel->P.adjust();
-  while (tmpcel->P.len > thisti->P.len)
-  {
-    tmpcel->P.executeModifier('l');
-    out += "l";
-  }
-  while (tmpcel->P.len < thisti->P.len) 
-  {
-    tmpcel->P.executeModifier('L');
-    out += "L";
-  }
-  while (tmpcel->P.curv > thisti->P.curv) 
-  {
-    tmpcel->P.executeModifier('c');
-    out += "c";
-  }
-  while (tmpcel->P.curv < thisti->P.curv) 
-  {
-    tmpcel->P.executeModifier('C');
-    out += "C";
-  }
-  while (thisti->rolling > 0.0f) {
-    rolling_dec( &(thisti->rolling) );
-    out += "R";
-  }
-  while (thisti->rolling < 0.0f) {
-    rolling_inc( &(thisti->rolling) );
-    out += "r";
-  }
-
-  // output X for this stick
-  out += "X";
-
-  // neurons attached to it
-  for (i=0; i<nc; i++)
-    if (C[i]->type == T_NEURON4) {
-      if (C[i]->dadlink == thisti) {
-        thneu = C[i];
-        out += "[";
-        // ctrl
-        if (1 == thneu->ctrl) out += "@";
-        if (2 == thneu->ctrl) out += "|";
-        // links
-        for (j=0; j<thneu->nolink; j++) 
-        {
-          if (j) out += ",";
-          if (NULL == thneu->links[j]->from) 
-          {
-            // sensory
-            if (1 == thneu->links[j]->t) out += "*";
-            if (2 == thneu->links[j]->t) out += "G";
-            if (3 == thneu->links[j]->t) out += "T";
-            if (4 == thneu->links[j]->t) out += "S";
-          } else {
-            sprintf(buf, "%d", thneu->links[j]->from->name - thneu->name);
-            out += buf;
-          }
-          out += ":";
-          // weight
-          sprintf(buf, "%g", thneu->links[j]->w );
-          out += buf;
-        }
-        out += "]";
-    }
-  }
-
-  // sticks connected to it
-  if (thisti->commacount>=2)
-    out += "(";
-
-  ccount=1;
-  for (i=0; i<nc; i++)
-   if (C[i]->type == T_STICK4)
-    if (C[i]->dadlink == thisti) {
-      while (ccount < (C[i])->anglepos) {
-        ccount++;
-        out += ",";
-      }
-      toF1GenoRec(i, out);
-  }
-  while (ccount < thisti->commacount) {
-    ccount++;
-    out += ",";
-  }
-
-  if (thisti->commacount >= 2)
-    out += ")";
+	int i, j, ccount;
+	f4_Cell * thisti;
+	f4_Cell * thneu;
+	char buf[200];
+
+	if (curc >= nc) return;
+
+	if (T_STICK4 != C[curc]->type) return;
+
+	thisti = C[curc];
+	if (NULL != thisti->dadlink)
+		*tmpcel = *(thisti->dadlink);
+
+	// adjust length, curvedness, etc.
+	tmpcel->P.adjust();
+	while (tmpcel->P.len > thisti->P.len)
+	{
+		tmpcel->P.executeModifier('l');
+		out += "l";
+	}
+	while (tmpcel->P.len < thisti->P.len)
+	{
+		tmpcel->P.executeModifier('L');
+		out += "L";
+	}
+	while (tmpcel->P.curv > thisti->P.curv)
+	{
+		tmpcel->P.executeModifier('c');
+		out += "c";
+	}
+	while (tmpcel->P.curv < thisti->P.curv)
+	{
+		tmpcel->P.executeModifier('C');
+		out += "C";
+	}
+	while (thisti->rolling > 0.0f) {
+		rolling_dec(&(thisti->rolling));
+		out += "R";
+	}
+	while (thisti->rolling < 0.0f) {
+		rolling_inc(&(thisti->rolling));
+		out += "r";
+	}
+
+	// output X for this stick
+	out += "X";
+
+	// neurons attached to it
+	for (i = 0; i < nc; i++)
+		if (C[i]->type == T_NEURON4) {
+			if (C[i]->dadlink == thisti) {
+				thneu = C[i];
+				out += "[";
+				// ctrl
+				if (1 == thneu->ctrl) out += "@";
+				if (2 == thneu->ctrl) out += "|";
+				// links
+				for (j = 0; j < thneu->nolink; j++)
+				{
+					if (j) out += ",";
+					if (NULL == thneu->links[j]->from)
+					{
+						// sensory
+						if (1 == thneu->links[j]->t) out += "*";
+						if (2 == thneu->links[j]->t) out += "G";
+						if (3 == thneu->links[j]->t) out += "T";
+						if (4 == thneu->links[j]->t) out += "S";
+					}
+					else {
+						sprintf(buf, "%d", thneu->links[j]->from->name - thneu->name);
+						out += buf;
+					}
+					out += ":";
+					// weight
+					sprintf(buf, "%g", thneu->links[j]->w);
+					out += buf;
+				}
+				out += "]";
+			}
+		}
+
+	// sticks connected to it
+	if (thisti->commacount >= 2)
+		out += "(";
+
+	ccount = 1;
+	for (i = 0; i < nc; i++)
+		if (C[i]->type == T_STICK4)
+			if (C[i]->dadlink == thisti) {
+				while (ccount < (C[i])->anglepos) {
+					ccount++;
+					out += ",";
+				}
+				toF1GenoRec(i, out);
+			}
+	while (ccount < thisti->commacount) {
+		ccount++;
+		out += ",";
+	}
+
+	if (thisti->commacount >= 2)
+		out += ")";
 }
 
@@ -1023,200 +1017,204 @@
 f4_node::f4_node()
 {
-  name   = '?';
-  parent = NULL;
-  child  = NULL;
-  child2 = NULL;
-  pos    = -1;
+	name = '?';
+	parent = NULL;
+	child = NULL;
+	child2 = NULL;
+	pos = -1;
 }
 
 f4_node::f4_node(char nname, f4_node * nparent, int npos)
 {
-  name   = nname;
-  parent = nparent;
-  child  = NULL;
-  child2 = NULL;
-  pos    = npos;
-  if (parent) parent->addChild(this);
+	name = nname;
+	parent = nparent;
+	child = NULL;
+	child2 = NULL;
+	pos = npos;
+	if (parent) parent->addChild(this);
 }
 
 f4_node::~f4_node()
 {
-  // (destroy() copied here for efficiency)
-  // children are destroyed (recursively) through the destructor
-  if (NULL != child2)  delete child2;
-  if (NULL != child)   delete child;
+	// (destroy() copied here for efficiency)
+	// children are destroyed (recursively) through the destructor
+	if (NULL != child2)  delete child2;
+	if (NULL != child)   delete child;
 }
 
 int f4_node::addChild(f4_node * nchi)
 {
-  if (NULL==child) {
-    child = nchi;
-    return 0;
-  }
-  if (NULL==child2) {
-    child2 = nchi;
-    return 0;
-  }
-  return -1;
+	if (NULL == child) {
+		child = nchi;
+		return 0;
+	}
+	if (NULL == child2) {
+		child2 = nchi;
+		return 0;
+	}
+	return -1;
 }
 
 int f4_node::removeChild(f4_node * nchi)
 {
-  if (nchi==child2) {
-    child2 = NULL;
-    return 0;
-  }
-  if (nchi==child) {
-    child = NULL;
-    return 0;
-  }
-  return -1;
+	if (nchi == child2) {
+		child2 = NULL;
+		return 0;
+	}
+	if (nchi == child) {
+		child = NULL;
+		return 0;
+	}
+	return -1;
 }
 
 int f4_node::childCount()
 {
-  if (NULL!=child) {
-    if (NULL!=child2) return 2;
-                 else return 1;
-  } else {
-    if (NULL!=child2) return 1;
-                 else return 0;
-  }
+	if (NULL != child) {
+		if (NULL != child2) return 2;
+		else return 1;
+	}
+	else {
+		if (NULL != child2) return 1;
+		else return 0;
+	}
 }
 
 int f4_node::count()
 {
-  int c=1;
-  if (NULL!=child)  c+=child->count();
-  if (NULL!=child2) c+=child2->count();
-  return c;
+	int c = 1;
+	if (NULL != child)  c += child->count();
+	if (NULL != child2) c += child2->count();
+	return c;
 }
 
 f4_node * f4_node::ordNode(int n)
 {
-  int n1;
-  if (0 == n) return this;
-  n--;
-  if (NULL != child) {
-    n1 = child->count();
-    if (n<n1) return child->ordNode(n);
-    n -= n1;
-  }
-  if (NULL != child2) {
-    n1 = child2->count();
-    if (n<n1) return child2->ordNode(n);
-    n -= n1;
-  }
-  return NULL;
+	int n1;
+	if (0 == n) return this;
+	n--;
+	if (NULL != child) {
+		n1 = child->count();
+		if (n < n1) return child->ordNode(n);
+		n -= n1;
+	}
+	if (NULL != child2) {
+		n1 = child2->count();
+		if (n < n1) return child2->ordNode(n);
+		n -= n1;
+	}
+	return NULL;
 }
 
 f4_node * f4_node::randomNode()
 {
-  int n, i;
-  n = count();
-  // pick a random node, between 0 and n-1
-  i = (int)( ((float)n-0.0001) / RAND_MAX * rand());
-  return ordNode(i);
+	int n = count();
+	// pick a random node, between 0 and n-1
+	return ordNode(randomN(n));
 }
 
 f4_node * f4_node::randomNodeWithSize(int min, int max)
 {
-  // try random nodes, and accept if size in range
-  // limit to maxlim tries
-  int i, n, maxlim;
-  f4_node * nod = NULL;
-  maxlim = count();
-  for (i=0; i<maxlim; i++) {
-    nod = randomNode();
-    n = nod->count();
-    if ((n>=min) && (n<=max)) return nod;
-  }
-  // failed, doesn't matter
-  return nod;
+	// try random nodes, and accept if size in range
+	// limit to maxlim tries
+	int i, n, maxlim;
+	f4_node * nod = NULL;
+	maxlim = count();
+	for (i = 0; i < maxlim; i++) {
+		nod = randomNode();
+		n = nod->count();
+		if ((n >= min) && (n <= max)) return nod;
+	}
+	// failed, doesn't matter
+	return nod;
 }
 
 void f4_node::sprint(SString & out)
 {
-  char buf2[20];
-  // special case: repetition code
-  if ('#' == name)
-  {
-    out += "#";
-    if (i1 != 1) {
-      sprintf(buf2, "%d", i1);
-      out += buf2;
-    }
-  } else {
-  // special case: neuron link
-  if ('[' == name) {
-    out += "[";
-    if (i1>0) {
-      // sensor input
-      if (1==i1) out += "*";
-      if (2==i1) out += "G";
-      if (3==i1) out += "T";
-      if (4==i1) out += "S";
-    } else {
-      sprintf(buf2, "%ld", l1);
-      out += buf2;
-    }
-    sprintf(buf2, ":%g]", f1);
-    out += buf2;
-  } else if (':' == name) {
-    sprintf(buf2, ":%c%c:", l1 ? '+' : '-', (char)i1);
-    out += buf2;
-  } else {
-    buf2[0] = name;
-    buf2[1] = 0;
-    out += buf2;
-  }}
-  if (NULL != child)     child->sprint(out);
-  // if two children, make sure last char is a '>'
-  if (2 == childCount())
-    if (0 == out[0]) out += ">"; else
-      if ('>' != out[out.len()-1]) out += ">";
-  if (NULL != child2)    child2->sprint(out);
-  // make sure last char is a '>'
-  if (0 == out[0]) out += ">"; else
-    if ('>' != out[out.len()-1]) out += ">";
+	char buf2[20];
+	// special case: repetition code
+	if ('#' == name)
+	{
+		out += "#";
+		if (i1 != 1) {
+			sprintf(buf2, "%d", i1);
+			out += buf2;
+		}
+	}
+	else {
+		// special case: neuron link
+		if ('[' == name) {
+			out += "[";
+			if (i1 > 0) {
+				// sensor input
+				if (1 == i1) out += "*";
+				if (2 == i1) out += "G";
+				if (3 == i1) out += "T";
+				if (4 == i1) out += "S";
+			}
+			else {
+				sprintf(buf2, "%ld", l1);
+				out += buf2;
+			}
+			sprintf(buf2, ":%g]", f1);
+			out += buf2;
+		}
+		else if (':' == name) {
+			sprintf(buf2, ":%c%c:", l1 ? '+' : '-', (char)i1);
+			out += buf2;
+		}
+		else {
+			buf2[0] = name;
+			buf2[1] = 0;
+			out += buf2;
+		}
+	}
+	if (NULL != child)     child->sprint(out);
+	// if two children, make sure last char is a '>'
+	if (2 == childCount())
+		if (0 == out[0]) out += ">"; else
+			if ('>' != out[out.len() - 1]) out += ">";
+	if (NULL != child2)    child2->sprint(out);
+	// make sure last char is a '>'
+	if (0 == out[0]) out += ">"; else
+		if ('>' != out[out.len() - 1]) out += ">";
 }
 
 void f4_node::sprintAdj(char *& buf)
 {
-  unsigned int len;
-  // build in a SString, with initial size
-  SString out(strlen(buf)+2000);
-  out="";
-
-  sprint(out);
-
-  // very last '>' can be omitted
-  len = out.len();
-  if (len>1)
-    if ('>' == out[len-1]) { (out.directWrite())[len-1]=0; out.endWrite();};
-  // copy back to string
-  // if new is longer, reallocate buf
-  if (len+1 > strlen(buf)) {
-    buf = (char*) realloc(buf, len+1 );
-  }
-  strcpy(buf, (const char*) out);
+	unsigned int len;
+	// build in a SString, with initial size
+	SString out(strlen(buf) + 2000);
+	out = "";
+
+	sprint(out);
+
+	// very last '>' can be omitted
+	len = out.len();
+	if (len > 1)
+		if ('>' == out[len - 1]) { (out.directWrite())[len - 1] = 0; out.endWrite(); };
+	// copy back to string
+	// if new is longer, reallocate buf
+	if (len + 1 > strlen(buf)) {
+		buf = (char*)realloc(buf, len + 1);
+	}
+	strcpy(buf, (const char*)out);
 }
 
 f4_node * f4_node::duplicate()
 {
-  f4_node * copy;
-  copy = new f4_node(*this);
-  copy->parent = NULL;  // set later
-  copy->child  = NULL;
-  copy->child2 = NULL;
-  if (NULL != child ) {
-    copy->child  = child ->duplicate();
-    copy->child ->parent = copy;
-  }
-  if (NULL != child2 ) {
-    copy->child2 = child2->duplicate();
-    copy->child2->parent = copy;
-  }
-  return copy;
+	f4_node * copy;
+	copy = new f4_node(*this);
+	copy->parent = NULL;  // set later
+	copy->child = NULL;
+	copy->child2 = NULL;
+	if (NULL != child) {
+		copy->child = child->duplicate();
+		copy->child->parent = copy;
+	}
+	if (NULL != child2) {
+		copy->child2 = child2->duplicate();
+		copy->child2->parent = copy;
+	}
+	return copy;
 }
 
@@ -1224,7 +1222,7 @@
 void f4_node::destroy()
 {
-  // children are destroyed (recursively) through the destructor
-  if (NULL != child2)  delete child2;
-  if (NULL != child)   delete child;
+	// children are destroyed (recursively) through the destructor
+	if (NULL != child2)  delete child2;
+	if (NULL != child)   delete child;
 }
 
@@ -1234,153 +1232,155 @@
 int f4_processrec(const char * genot, unsigned pos0, f4_node * parent)
 {
-  int i, j, t, res;
-  char tc1, tc2;
-  long relfrom;
-  double w;
-  unsigned gpos, oldpos;
-  f4_node * node1, * par;
-
-  gpos = pos0;
-  par = parent;
-  if (gpos >= strlen(genot) ) return 1;
-  while (gpos<strlen(genot)) {
-    //DB( printf(" processing '%c' %d %s\n", genot[gpos], gpos, genot); )
-    switch (genot[gpos]) {
-    case '<':
-      // cell division!
-      //DB( printf("  div! %d\n", name); )
-
-      // find out genotype start for child
-      j = scanrec(genot+gpos+1, strlen(genot+gpos+1), '>');
-
-      node1 = new f4_node('<', par, gpos);
-      par = node1;
-      res = f4_processrec(genot, gpos+1,   par);
-      if (res) return res;
-      if (gpos+j+2 < strlen(genot)) {
-        res = f4_processrec(genot, gpos+j+2, par);
-        if (res) return res;
-      } else {  // ran out
-        node1 = new f4_node('>', par, strlen(genot)-1 );
-        par = node1;
-      }
-      // adjustments
-      gpos++;
-      return 0;  // OK
-
-    case '>':
-      node1 = new f4_node('>', par, gpos );
-      par = node1;
-      gpos = strlen(genot);
-      return 0;  // OK
-
-    case '#':
-      // repetition marker, 1 by default
-      if (sscanf(genot+gpos, "#%d", &i) != 1) i=1;
-      // find out genotype start for continuation
-      j = scanrec(genot+gpos+1, strlen(genot+gpos+1), '>');
-      // skip number
-      oldpos = gpos;
-      gpos++;
-      while ((genot[gpos]>='0') && (genot[gpos]<='9')) gpos++;
-      node1 = new f4_node('#', par, oldpos );
-      node1->i1 = i;
-      par = node1;
-      res = f4_processrec(genot, gpos,   node1);
-      if (res) return res;
-      if (oldpos+j+2 < strlen(genot) ) {
-        res = f4_processrec(genot, oldpos+j+2, node1);
-        if (res) return res;
-      } else {  // ran out
-        node1 = new f4_node('>', par, strlen(genot)-1 );
-      }
-      return 0;  // OK
-
-    // 'simple' nodes:
-    case ',':
-    case 'l':  case 'L':
-    case 'c':  case 'C':
-    case 'q':  case 'Q':
-    case 'r':  case 'R':
-    case 'X':  case 'N':
-    case '@':  case '|':
-    case 'a':  case 'A':
-    case 's':  case 'S':
-    case 'm':  case 'M':
-    case 'i':  case 'I':
-    case 'f':  case 'F':
-    case 'w':  case 'W':
-    case 'e':  case 'E':
-      node1 = new f4_node(genot[gpos], par, gpos );
-      par = node1;
-      gpos++;
-      break;
-
-    case '[':
-      // link to neuron
-      // input (%d, '*', 'G', 'T', 'S')
-      t = -1;
-      if (sscanf(genot+gpos, "[%ld:%lf]", &relfrom, &w) == 2) t=0;
-      else if (sscanf(genot+gpos, "[*:%lf]", &w) == 1) t=1;
-      else if (sscanf(genot+gpos, "[G:%lf]", &w) == 1) t=2;
-      else if (sscanf(genot+gpos, "[T:%lf]", &w) == 1) t=3;
-      else if (sscanf(genot+gpos, "[S:%lf]", &w) == 1) t=4;
-      // error: no correct format
-      if (t<0) return gpos+1+1;
-      node1 = new f4_node('[', par, gpos );
-      node1->i1 = t;
-      node1->l1 = relfrom;
-      node1->f1 = w;
-      par = node1;
-      j = scanrec(genot+gpos+1, strlen(genot+gpos+1), ']');
-      gpos += j+2;
-      break;
-
-    case ':':
-      // neuron parameter  +! -! += -= +/ or -/
-      if (sscanf(genot+gpos, ":%c%c:", &tc1, &tc2) != 2)
-        // error: incorrect format
-        return gpos+1+1;
-      if ('+' == tc1) j=1;
-      else if ('-' == tc1) j=0;
-      else return gpos+1+1;
-      switch (tc2) {
-       case '!':  case '=':  case '/':  break;
-       default:
-        return gpos+1+1;
-      }
-      node1 = new f4_node(':', par, gpos );
-      node1->l1 = j;
-      node1->i1 = (int)tc2;
-      par = node1;
-      j = scanrec(genot+gpos+1, strlen(genot+gpos+1), ':');
-      gpos += j+2;
-      break;
-
-    case ' ':
-    case '\n':
-    case '\t':
-      // whitespace: ignore
-      //node1 = new f4_node(' ', par, gpos );
-      //par = node1;
-      gpos++;
-      break;
-
-    default:
-      //DB( printf("unknown character '%c' ! \n", genot[gpos]); )
-      //add it, build will give the error or repair
-      node1 = new f4_node(genot[gpos], par, gpos );
-      par = node1;
-      gpos++;
-      break;
-    }
-  }
-  // should end with a '>'
-  if (par)
-    if ('>' != par->name) {
-      node1 = new f4_node('>', par, strlen(genot)-1 );
-      par = node1;
-  }
-  return 0;  // OK
+	int i, j, t, res;
+	char tc1, tc2;
+	long relfrom;
+	double w;
+	unsigned gpos, oldpos;
+	f4_node * node1, *par;
+
+	gpos = pos0;
+	par = parent;
+	if (gpos >= strlen(genot)) return 1;
+	while (gpos < strlen(genot)) {
+		//DB( printf(" processing '%c' %d %s\n", genot[gpos], gpos, genot); )
+		switch (genot[gpos]) {
+		case '<':
+			// cell division!
+			//DB( printf("  div! %d\n", name); )
+
+			// find out genotype start for child
+			j = scanrec(genot + gpos + 1, strlen(genot + gpos + 1), '>');
+
+			node1 = new f4_node('<', par, gpos);
+			par = node1;
+			res = f4_processrec(genot, gpos + 1, par);
+			if (res) return res;
+			if (gpos + j + 2 < strlen(genot)) {
+				res = f4_processrec(genot, gpos + j + 2, par);
+				if (res) return res;
+			}
+			else {  // ran out
+				node1 = new f4_node('>', par, strlen(genot) - 1);
+				par = node1;
+			}
+			// adjustments
+			gpos++;
+			return 0;  // OK
+
+		case '>':
+			node1 = new f4_node('>', par, gpos);
+			par = node1;
+			gpos = strlen(genot);
+			return 0;  // OK
+
+		case '#':
+			// repetition marker, 1 by default
+			if (sscanf(genot + gpos, "#%d", &i) != 1) i = 1;
+			// find out genotype start for continuation
+			j = scanrec(genot + gpos + 1, strlen(genot + gpos + 1), '>');
+			// skip number
+			oldpos = gpos;
+			gpos++;
+			while ((genot[gpos] >= '0') && (genot[gpos] <= '9')) gpos++;
+			node1 = new f4_node('#', par, oldpos);
+			node1->i1 = i;
+			par = node1;
+			res = f4_processrec(genot, gpos, node1);
+			if (res) return res;
+			if (oldpos + j + 2 < strlen(genot)) {
+				res = f4_processrec(genot, oldpos + j + 2, node1);
+				if (res) return res;
+			}
+			else {  // ran out
+				node1 = new f4_node('>', par, strlen(genot) - 1);
+			}
+			return 0;  // OK
+
+			// 'simple' nodes:
+		case ',':
+		case 'l':  case 'L':
+		case 'c':  case 'C':
+		case 'q':  case 'Q':
+		case 'r':  case 'R':
+		case 'X':  case 'N':
+		case '@':  case '|':
+		case 'a':  case 'A':
+		case 's':  case 'S':
+		case 'm':  case 'M':
+		case 'i':  case 'I':
+		case 'f':  case 'F':
+		case 'w':  case 'W':
+		case 'e':  case 'E':
+			node1 = new f4_node(genot[gpos], par, gpos);
+			par = node1;
+			gpos++;
+			break;
+
+		case '[':
+			// link to neuron
+			// input (%d, '*', 'G', 'T', 'S')
+			t = -1;
+			if (sscanf(genot + gpos, "[%ld:%lf]", &relfrom, &w) == 2) t = 0;
+			else if (sscanf(genot + gpos, "[*:%lf]", &w) == 1) t = 1;
+			else if (sscanf(genot + gpos, "[G:%lf]", &w) == 1) t = 2;
+			else if (sscanf(genot + gpos, "[T:%lf]", &w) == 1) t = 3;
+			else if (sscanf(genot + gpos, "[S:%lf]", &w) == 1) t = 4;
+			// error: no correct format
+			if (t < 0) return gpos + 1 + 1;
+			node1 = new f4_node('[', par, gpos);
+			node1->i1 = t;
+			node1->l1 = relfrom;
+			node1->f1 = w;
+			par = node1;
+			j = scanrec(genot + gpos + 1, strlen(genot + gpos + 1), ']');
+			gpos += j + 2;
+			break;
+
+		case ':':
+			// neuron parameter  +! -! += -= +/ or -/
+			if (sscanf(genot + gpos, ":%c%c:", &tc1, &tc2) != 2)
+				// error: incorrect format
+				return gpos + 1 + 1;
+			if ('+' == tc1) j = 1;
+			else if ('-' == tc1) j = 0;
+			else return gpos + 1 + 1;
+			switch (tc2) {
+			case '!':  case '=':  case '/':  break;
+			default:
+				return gpos + 1 + 1;
+			}
+			node1 = new f4_node(':', par, gpos);
+			node1->l1 = j;
+			node1->i1 = (int)tc2;
+			par = node1;
+			j = scanrec(genot + gpos + 1, strlen(genot + gpos + 1), ':');
+			gpos += j + 2;
+			break;
+
+		case ' ':
+		case '\n':
+		case '\t':
+			// whitespace: ignore
+			//node1 = new f4_node(' ', par, gpos );
+			//par = node1;
+			gpos++;
+			break;
+
+		default:
+			//DB( printf("unknown character '%c' ! \n", genot[gpos]); )
+			//add it, build will give the error or repair
+			node1 = new f4_node(genot[gpos], par, gpos);
+			par = node1;
+			gpos++;
+			break;
+		}
+	}
+	// should end with a '>'
+	if (par)
+		if ('>' != par->name) {
+			node1 = new f4_node('>', par, strlen(genot) - 1);
+			par = node1;
+		}
+	return 0;  // OK
 }
 
@@ -1388,21 +1388,20 @@
 f4_node * f4_processtree(const char * geno)
 {
-  f4_node * root;
-  int res;
-  root = new f4_node();
-  res = f4_processrec(geno, 0, root);
-  if (res) return NULL;
-  //DB( printf("test f4  "); )
-  DB(
-    if (root->child) {
-      char * buf = (char*) malloc( 300 );
-      DB( printf("(%d) ", root->child->count() ); )
-      buf[0]=0;
-      root->child->sprintAdj(buf);
-      DB( printf("%s\n", buf); )
-      free(buf);
-    }
-  )
-  return root->child;
-}
-
+	f4_node * root;
+	int res;
+	root = new f4_node();
+	res = f4_processrec(geno, 0, root);
+	if (res) return NULL;
+	//DB( printf("test f4  "); )
+	DB(
+		if (root->child) {
+			char * buf = (char*)malloc(300);
+			DB(printf("(%d) ", root->child->count());)
+				buf[0] = 0;
+			root->child->sprintAdj(buf);
+			DB(printf("%s\n", buf);)
+				free(buf);
+		}
+	)
+		return root->child;
+}
