[avida-cvs] avida(BenKirkup) CVS commits: /current/source/cpu cpu_memory.cc hardware_4stack.cc hardware_4stack.hh hardware_base.hh hardware_cpu.cc hardware_cpu.hh head.cc head.hh test_cpu.cc test_cpu.hh test_util.cc test_util.hh /current/source/event cPopulation.events cPopulation_construct_event_auto.ci cPopulation_descr.ci cPopulation_enums_auto.ci cPopulation_event_list cPopulation_name2enum_auto.ci cPopulation_process_auto.ci population_event_factory.cc /current/source/main Makefile.am analyze.cc avida.cc callback_util.cc callback_util.hh config.cc config.hh environment.cc genebank.cc genome.hh organism.cc organism.hh phenotype.cc pop_interface.cc pop_interface.hh population.cc population.hh population_cell.cc population_cell.hh reaction_result.cc reaction_result.hh /current/source/qt-viewer event_chooser.cpp event_list_editor.cpp godbox.cpp plot_select_dia.cpp wizard.ui /current/source/support Makefile.am genesis /current/source/support/preset_organisms Makefile.am /current/source/tools datafile.cc datafile.hh /current/source/viewers Makefile.am bar_screen.cc map_screen.cc map_screen.hh symbol_util.cc text_screen.cc text_screen.hh view.cc view.hh zoom_screen.cc zoom_screen.hh

goingssh avida-cvs at alife.org
Mon Aug 11 23:01:35 PDT 2003


goingssh		Mon Aug 11 15:01:35 2003 EDT

  Modified files:              (Branch: BenKirkup)
    /avida/current/source/cpu	cpu_memory.cc hardware_4stack.cc 
                             	hardware_4stack.hh hardware_base.hh 
                             	hardware_cpu.cc hardware_cpu.hh head.cc 
                             	head.hh test_cpu.cc test_cpu.hh 
                             	test_util.cc test_util.hh 
    /avida/current/source/event	cPopulation.events 
                               	cPopulation_construct_event_auto.ci 
                               	cPopulation_descr.ci 
                               	cPopulation_enums_auto.ci 
                               	cPopulation_event_list 
                               	cPopulation_name2enum_auto.ci 
                               	cPopulation_process_auto.ci 
                               	population_event_factory.cc 
    /avida/current/source/main	Makefile.am analyze.cc avida.cc 
                              	callback_util.cc callback_util.hh 
                              	config.cc config.hh environment.cc 
                              	genebank.cc genome.hh organism.cc 
                              	organism.hh phenotype.cc 
                              	pop_interface.cc pop_interface.hh 
                              	population.cc population.hh 
                              	population_cell.cc population_cell.hh 
                              	reaction_result.cc reaction_result.hh 
    /avida/current/source/qt-viewer	event_chooser.cpp 
                                   	event_list_editor.cpp godbox.cpp 
                                   	plot_select_dia.cpp wizard.ui 
    /avida/current/source/support	Makefile.am genesis 
    /avida/current/source/support/preset_organisms	Makefile.am 
    /avida/current/source/tools	datafile.cc datafile.hh 
    /avida/current/source/viewers	Makefile.am bar_screen.cc 
                                 	map_screen.cc map_screen.hh 
                                 	symbol_util.cc text_screen.cc 
                                 	text_screen.hh view.cc view.hh 
                                 	zoom_screen.cc zoom_screen.hh 
  Log:
  updating ben's newly made branch to contain the most recent version of Avida
  
-------------- next part --------------
Index: avida/current/source/cpu/cpu_memory.cc
diff -u avida/current/source/cpu/cpu_memory.cc:1.9 avida/current/source/cpu/cpu_memory.cc:1.9.6.1
--- avida/current/source/cpu/cpu_memory.cc:1.9	Sat May 17 02:48:07 2003
+++ avida/current/source/cpu/cpu_memory.cc	Mon Aug 11 15:01:26 2003
@@ -239,4 +239,3 @@
     genome[i + pos] = in_genome[i];
   }
 }
-
Index: avida/current/source/cpu/hardware_4stack.cc
diff -u avida/current/source/cpu/hardware_4stack.cc:1.9 avida/current/source/cpu/hardware_4stack.cc:1.9.2.1
--- avida/current/source/cpu/hardware_4stack.cc:1.9	Fri Jun 13 14:49:58 2003
+++ avida/current/source/cpu/hardware_4stack.cc	Mon Aug 11 15:01:26 2003
@@ -12,6 +12,7 @@
 #include "hardware_4stack.hh"
 
 #include "../tools/string_util.hh"
+#include "../tools/random.hh"
 
 #include "../main/config.hh"
 #include "../main/inst_set.hh"
@@ -50,6 +51,7 @@
      heads[i] = in_thread.heads[i];
    }
    input_pointer = in_thread.input_pointer;
+   owner = in_thread.owner;
 }
 
 cHardware4Stack_Thread::~cHardware4Stack_Thread() {}
@@ -66,6 +68,7 @@
   input_pointer = in_thread.input_pointer;
   input_buf = in_thread.input_buf;
   output_buf = in_thread.output_buf;
+  owner = in_thread.owner;
 }
 
 void cHardware4Stack_Thread::Reset(cHardwareBase * in_hardware, int _id)
@@ -73,7 +76,7 @@
   id = _id;
 
   for (int i = 0; i < NUM_LOCAL_STACKS; i++) local_stacks[i].Clear();
-  for (int i = 0; i < NUM_HEADS; i++) heads[i].Reset(in_hardware);
+  for (int i = 0; i < NUM_HEADS; i++) heads[i].Reset(0, in_hardware);
 
   cur_head = HEAD_IP;
   input_pointer = 0;
@@ -81,11 +84,9 @@
   output_buf.Clear();
   read_label.Clear();
   next_label.Clear();
+  owner = NULL;
 }
 
-
-
-
 void cHardware4Stack_Thread::SaveState(ostream & fp){
   assert(fp.good());
   fp << "cHardware4Stack_Thread" << endl;
@@ -114,8 +115,6 @@
   next_label.SaveState(fp);
 }
 
-
-
 void cHardware4Stack_Thread::LoadState(istream & fp){
   assert(fp.good());
   cString foo;
@@ -307,98 +306,10 @@
     cInstEntry4Stack("Val-Mod",       &cHardware4Stack::Inst_Mod),
     //35
     cInstEntry4Stack("ThreadKill",   &cHardware4Stack::Inst_KillThread),
-    
-    /*
-    cInstEntry4Stack("nop-A",     &cHardware4Stack::Inst_Nop),
-    cInstEntry4Stack("nop-B",     &cHardware4Stack::Inst_Nop),
-    cInstEntry4Stack("nop-C",     &cHardware4Stack::Inst_Nop),
-
-    cInstEntry4Stack("NULL",  &cHardware4Stack::Inst_Nop),
-    cInstEntry4Stack("nop-X",     &cHardware4Stack::Inst_Nop),
-    cInstEntry4Stack("if-equ-0",  &cHardware4Stack::Inst_If0),
-    cInstEntry4Stack("if-not-0",  &cHardware4Stack::Inst_IfNot0),
-    cInstEntry4Stack("if-n-equ",  &cHardware4Stack::Inst_IfNEqu),
-    cInstEntry4Stack("if-equ",    &cHardware4Stack::Inst_IfEqu),
-    
-    cInstEntry4Stack("if-bit-1",  &cHardware4Stack::Inst_IfBit1),
-    cInstEntry4Stack("jump-f",    &cHardware4Stack::Inst_JumpF),
-    cInstEntry4Stack("jump-b",    &cHardware4Stack::Inst_JumpB),
-    cInstEntry4Stack("jump-p",    &cHardware4Stack::Inst_JumpP),
-    cInstEntry4Stack("jump-slf",  &cHardware4Stack::Inst_JumpSelf),
-    cInstEntry4Stack("call",      &cHardware4Stack::Inst_Call),
-    cInstEntry4Stack("return",    &cHardware4Stack::Inst_Return),
-
-    cInstEntry4Stack("pop",       &cHardware4Stack::Inst_Pop),
-    cInstEntry4Stack("push",      &cHardware4Stack::Inst_Push),
-    cInstEntry4Stack("swap-stk",  &cHardware4Stack::Inst_SwitchStack),
-    cInstEntry4Stack("swap",      &cHardware4Stack::Inst_Swap),
-    cInstEntry4Stack("copy-reg",  &cHardware4Stack::Inst_CopyReg),
-
-    cInstEntry4Stack("shift-r",   &cHardware4Stack::Inst_ShiftR),
-    cInstEntry4Stack("shift-l",   &cHardware4Stack::Inst_ShiftL),
-    cInstEntry4Stack("bit-1",     &cHardware4Stack::Inst_Bit1),
-    cInstEntry4Stack("set-num",   &cHardware4Stack::Inst_SetNum),
-    cInstEntry4Stack("inc",       &cHardware4Stack::Inst_Inc),
-    cInstEntry4Stack("dec",       &cHardware4Stack::Inst_Dec),
-    cInstEntry4Stack("minus-18",  &cHardware4Stack::Inst_Minus18),
-    
-    cInstEntry4Stack("add",       &cHardware4Stack::Inst_Add),
-    cInstEntry4Stack("sub",       &cHardware4Stack::Inst_Sub),
-    cInstEntry4Stack("mult",      &cHardware4Stack::Inst_Mult),
-    cInstEntry4Stack("div",       &cHardware4Stack::Inst_Div),
-    cInstEntry4Stack("mod",       &cHardware4Stack::Inst_Mod),
-    cInstEntry4Stack("nand",      &cHardware4Stack::Inst_Nand),
-    cInstEntry4Stack("nor",       &cHardware4Stack::Inst_Nor),
-    
-    cInstEntry4Stack("copy",      &cHardware4Stack::Inst_Copy),
-    cInstEntry4Stack("read",      &cHardware4Stack::Inst_ReadInst),
-    cInstEntry4Stack("write",     &cHardware4Stack::Inst_WriteInst),
-    
-    cInstEntry4Stack("compare",   &cHardware4Stack::Inst_Compare),
-    cInstEntry4Stack("if-n-cpy",  &cHardware4Stack::Inst_IfNCpy),
-    cInstEntry4Stack("allocate",  &cHardware4Stack::Inst_Allocate),
-    cInstEntry4Stack("divide",    &cHardware4Stack::Inst_DivideOld),
-    cInstEntry4Stack("inject",    &cHardware4Stack::Inst_Inject),
-    cInstEntry4Stack("inject-r",  &cHardware4Stack::Inst_InjectRand),
-    cInstEntry4Stack("get",       &cHardware4Stack::Inst_TaskGet),
-    cInstEntry4Stack("put",       &cHardware4Stack::Inst_TaskPut),
-    cInstEntry4Stack("IO",        &cHardware4Stack::Inst_TaskIO),
-    cInstEntry4Stack("search-f",  &cHardware4Stack::Inst_SearchF),
-    cInstEntry4Stack("search-b",  &cHardware4Stack::Inst_SearchB),
-    cInstEntry4Stack("mem-size",  &cHardware4Stack::Inst_MemSize),
-
-    cInstEntry4Stack("rotate-l",  &cHardware4Stack::Inst_RotateL),
-    cInstEntry4Stack("rotate-r",  &cHardware4Stack::Inst_RotateR),
-
-    cInstEntry4Stack("set-cmut",  &cHardware4Stack::Inst_SetCopyMut),
-    cInstEntry4Stack("mod-cmut",  &cHardware4Stack::Inst_ModCopyMut),
-
-    // Threading instructions
-    cInstEntry4Stack("fork-th",   &cHardware4Stack::Inst_ForkThread),
-    cInstEntry4Stack("kill-th",   &cHardware4Stack::Inst_KillThread),
-    cInstEntry4Stack("id-th",     &cHardware4Stack::Inst_ThreadID),
-
-    // Head-based instructions
-    cInstEntry4Stack("h-alloc",   &cHardware4Stack::Inst_MaxAlloc),
-    cInstEntry4Stack("h-divide",  &cHardware4Stack::Inst_HeadDivide),
-    cInstEntry4Stack("h-read",    &cHardware4Stack::Inst_HeadRead),
-    cInstEntry4Stack("h-write",   &cHardware4Stack::Inst_HeadWrite),
-    cInstEntry4Stack("h-copy",    &cHardware4Stack::Inst_HeadCopy),
-    cInstEntry4Stack("h-search",  &cHardware4Stack::Inst_HeadSearch),
-    cInstEntry4Stack("h-push",    &cHardware4Stack::Inst_HeadPush),
-    cInstEntry4Stack("h-pop",     &cHardware4Stack::Inst_HeadPop),
-    cInstEntry4Stack("set-head",  &cHardware4Stack::Inst_SetHead),
-    cInstEntry4Stack("adv-head",  &cHardware4Stack::Inst_AdvanceHead),
-    cInstEntry4Stack("mov-head",  &cHardware4Stack::Inst_MoveHead),
-    cInstEntry4Stack("jmp-head",  &cHardware4Stack::Inst_JumpHead),
-    cInstEntry4Stack("get-head",  &cHardware4Stack::Inst_GetHead),
-    cInstEntry4Stack("if-label",  &cHardware4Stack::Inst_IfLabel),
-    cInstEntry4Stack("set-flow",  &cHardware4Stack::Inst_SetFlow),
-
-
-    // Placebo instructions
-    // nop-x (included with nops)
-    cInstEntry4Stack("skip",      &cHardware4Stack::Inst_Skip)*/
+    //36
+    cInstEntry4Stack("IO", &cHardware4Stack::Inst_IO),
+    //37
+    cInstEntry4Stack("Inject", &cHardware4Stack::Inst_Inject)
   };
 
   const int n_size = sizeof(s_n_array)/sizeof(cNOPEntry4Stack);
@@ -447,7 +358,16 @@
   /* FIXME:  reorganize storage of m_functions.  -- kgn */
   m_functions = s_inst_slib->GetFunctions();
   /**/
+  inst_remainder = 0;
+ 
+  for(int x=1; x<=cConfig::GetMaxCPUThreads(); x++)
+    {
+      slice_array[x] = (x-1)*cConfig::GetThreadSlicingMethod()+1;
+    }
+
   memory_array[0] = in_organism->GetGenome();  // Initialize memory...
+  memory_array[0].Resize(GetMemory(0).GetSize()+1);
+  memory_array[0][memory_array[0].GetSize()-1] = cInstruction();
   Reset();                            // Setup the rest of the hardware...
 }
 
@@ -461,6 +381,8 @@
 {
   cHardwareBase::Recycle(new_organism, in_inst_set);
   memory_array[0] = new_organism->GetGenome();
+  memory_array[0].Resize(GetMemory(0).GetSize()+1);
+  memory_array[0][memory_array[0].GetSize()-1] = cInstruction();
   Reset();
 }
 
@@ -468,12 +390,13 @@
 void cHardware4Stack::Reset()
 {
   //global_stack.Clear();
-  thread_time_used = 0;
+  //thread_time_used = 0;
 
   // Setup the memory...
   for (int i = 1; i < NUM_MEMORY_SPACES; i++) {
       memory_array[i].Resize(1);
-      GetMemory(i).Replace(0, 1, cGenome(ConvertToInstruction(i)));
+      //GetMemory(i).Replace(0, 1, cGenome(ConvertToInstruction(i)));
+      GetMemory(i)=cGenome(ConvertToInstruction(i)); 
   }
 
   // We want to reset to have a single thread.
@@ -512,17 +435,27 @@
 void cHardware4Stack::SingleProcess(ostream * trace_fp)
 {
   organism->GetPhenotype().IncTimeUsed();
-  if (GetNumThreads() > 1) thread_time_used++;
+  //if(organism->GetCellID()==46 && IP().GetMemSpace()==2)
+  // int x=0;
 
+  //if (GetNumThreads() > 1) thread_time_used++;
+  //assert((GetHead(HEAD_WRITE).GetPosition() == Stack(STACK_BX).Top() ||
+  // Stack(STACK_BX).Top()==GetMemory(IP().GetMemSpace()).GetSize()-1 || 
+  // GetHead(HEAD_WRITE).GetPosition() == Stack(STACK_BX).Top()+1) &&
+  // (GetHead(HEAD_WRITE).GetMemSpace() == IP().GetMemSpace() ||
+  //  GetHead(HEAD_WRITE).GetMemSpace() == IP().GetMemSpace()+1));
   // If we have threads turned on and we executed each thread in a single
   // timestep, adjust the number of instructions executed accordingly.
-  const int num_inst_exec = (cConfig::GetThreadSlicingMethod() == 1) ?
-    GetNumThreads() : 1;
+  //const int num_inst_exec = (cConfig::GetThreadSlicingMethod() == 1) ?
+  //  GetNumThreads() : 1;
+
+  const int num_inst_exec = int(slice_array[GetNumThreads()]+ inst_remainder);
+  inst_remainder = slice_array[GetNumThreads()] + inst_remainder - num_inst_exec;
   
   for (int i = 0; i < num_inst_exec; i++) {
     // Setup the hardware for the next instruction to be executed.
     NextThread();
-    advance_ip = true;
+    AdvanceIP() = true;
     IP().Adjust();
 
 #ifdef BREAKPOINTS
@@ -546,7 +479,7 @@
 
       // Some instruction (such as jump) may turn advance_ip off.  Ususally
       // we now want to move to the next instruction in the memory.
-      if (advance_ip == true) IP().Advance();
+      if (AdvanceIP() == true) IP().Advance();
     } // if exec
     
   } // Previous was executed once for each thread...
@@ -728,7 +661,7 @@
   c4StackHead search_head(inst_ptr);
   cCodeLabel & search_label = GetLabel();
 
-  // Make sure the label is of size > 0.
+  // Make sure the label is of size  > 0.
 
   if (search_label.GetSize() == 0) {
     return inst_ptr;
@@ -753,9 +686,9 @@
   }
   
   // Return the last line of the found label, if it was found.
-  if (found_pos > 0) search_head.Set(found_pos - 1);
+  if (found_pos > 0) search_head.Set(found_pos - 1, IP().GetMemSpace());
   //*** I THINK THIS MIGHT HAVE BEEN WRONG...CHANGED >= to >.  -law ***//
-
+  
   // Return the found position (still at start point if not found).
   return search_head;
 }
@@ -1026,108 +959,118 @@
   return temp_head;
 }
 
-
-int cHardware4Stack::Inject(const cCodeLabel & in_label, const cGenome & injection)
+// This is the code run by the INFECTED organism.  Its function is to SPREAD infection.
+bool cHardware4Stack::InjectParasite(double mut_multiplier)
 {
-  // Make sure the genome will be below max size after injection.
-
-  const int new_size = injection.GetSize() + GetMemory(0).GetSize();
-  if (new_size > MAX_CREATURE_SIZE) return 1; // (inject fails)
-
-  const int inject_line = FindFullLabel(in_label).GetPosition();
+  const int end_pos = GetHead(HEAD_WRITE).GetPosition();
+  const int mem_space_used = GetHead(HEAD_WRITE).GetMemSpace();
 
-  // Abort if no compliment is found.
-  if (inject_line == -1) return 2; // (inject fails)
+  // Make sure the creature will still be above the minimum size,
+  if (end_pos <= 0) {
+    Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: no code to inject");
+    return false; // (inject fails)
+  }
+  
+  if (end_pos < MIN_CREATURE_SIZE) {
+    Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: new size too small");
+    return false; // (inject fails)
+  }
 
-  // Inject the code!
-  InjectCode(injection, inject_line+1);
+  GetMemory(mem_space_used).Resize(end_pos);
+  cCPUMemory injected_code = GetMemory(mem_space_used);
 
-  return 0; // (inject succeeds!)
-}
+  Inject_DoMutations(mut_multiplier, injected_code);
 
-int cHardware4Stack::InjectThread(const cCodeLabel & in_label, const cGenome & injection)
-{
-  // Make sure the genome will be below max size after injection.
+  int inject_signal = false;
 
-  const int new_size = injection.GetSize() + GetMemory(0).GetSize();
-  if (new_size > MAX_CREATURE_SIZE) return 1; // (inject fails)
+  if(injected_code.GetSize()>0)
+    inject_signal = organism->InjectParasite(injected_code);
+  
+  //************* CALL GOES HERE ******************//
+  // spin around randomly (caution: possible organism dizziness)
+  //const int num_neighbors = organism->GetNeighborhoodSize();
+  //for(unsigned int i=0; i<g_random.GetUInt(num_neighbors); i++)
+  //  organism->Rotate(1);
 
-  const int inject_line = FindFullLabel(in_label).GetPosition();
+  // If we don't have a host, stop here.
+  //cOrganism * host_organism = organism->GetNeighbor();
+  
+ 
+  //if(host_organism!=NULL)
+  //  {
+  //    
+  //  }
+ 
+  //************** CALL ENDS HERE ******************//
 
-  // Abort if no compliment is found.
-  if (inject_line == -1) return 2; // (inject fails)
+  //reset the memory space which was injected
+  GetMemory(mem_space_used)=cGenome(ConvertToInstruction(mem_space_used)); 
 
-  // Inject the code!
-  InjectCodeThread(injection, inject_line+1);
+  for(int x=0; x<NUM_HEADS; x++)
+    {
+      GetHead(x).Reset(IP().GetMemSpace(), this);
+    }
 
-  return 0; // (inject succeeds!)
+  for(int x=0; x<NUM_LOCAL_STACKS; x++)
+    {
+      Stack(x).Clear();
+    }
+  
+  AdvanceIP() = false;
+  
+  return inject_signal;
 }
 
-void cHardware4Stack::InjectCode(const cGenome & inject_code, const int line_num)
+//This is the code run by the TARGET of an injection.  This RECIEVES the infection.
+bool cHardware4Stack::InjectHost(const cCodeLabel & in_label, const cGenome & inject_code)
 {
-  assert(line_num >= 0);
-  assert(line_num <= memory_array[0].GetSize());
-  assert(memory_array[0].GetSize() + inject_code.GetSize() < MAX_CREATURE_SIZE);
-
-  // Inject the new cod.e
-  const int inject_size = inject_code.GetSize();
-  memory_array[0].Insert(line_num, inject_code);
-  
-  // Set instruction flags on the injected code
-  for (int i = line_num; i < line_num + inject_size; i++) {
-    memory_array[0].FlagInjected(i) = true;
-  }
-  organism->GetPhenotype().IsModified() = true;
-
-  // Adjust all of the heads to take into account the new mem size.
+  // Make sure the genome will be below max size after injection.
 
-  for (int i=0; i < NUM_HEADS; i++) {    
-    if (!GetHead(i).TestParasite() &&
-	GetHead(i).GetPosition() > line_num)
-      GetHead(i).Jump(inject_size);
-  }
-}
+  // xxxTEMPORARYxxx - we should have this match injection templates.  For now it simply 
+  // makes sure the target_mem_space (hardcoded to 2) is empty. - law
+  int target_mem_space = 2; 
+  if(!(isEmpty(target_mem_space)))
+    return false;
 
-void cHardware4Stack::InjectCodeThread(const cGenome & inject_code, const int line_num)
-{
-  assert(line_num >= 0);
-  assert(line_num <= memory_array[0].GetSize());
-  assert(memory_array[0].GetSize() + inject_code.GetSize() < MAX_CREATURE_SIZE);
+  assert(target_mem_space >=0 && target_mem_space < 4);
   
-  if(ForkThread())
-    {
-      // Inject the new code.
-      const int inject_size = inject_code.GetSize();
-      memory_array[0].Insert(line_num, inject_code);
-      
-      // Set instruction flags on the injected code
-      for (int i = line_num; i < line_num + inject_size; i++) {
-	memory_array[0].FlagInjected(i) = true;
+  if(ForkThread()) {
+    // Inject the new code
+    cCPUMemory oldcode = GetMemory(target_mem_space);
+    GetMemory(target_mem_space) = inject_code;
+    GetMemory(target_mem_space).Resize(inject_code.GetSize() + oldcode.GetSize());
+
+    // Copies previous instructions to the end of the injected code.
+    // Is there a faster way to do this?? -law
+    for(int x=0; x<oldcode.GetSize(); x++)
+      GetMemory(target_mem_space)[inject_code.GetSize()+x] = oldcode[x];
+  
+    // Set instruction flags on the injected code
+    for (int i = 0; i < inject_code.GetSize(); i++) {
+      memory_array[target_mem_space].FlagInjected(i) = true;
+    }
+    organism->GetPhenotype().IsModified() = true;
+    
+    // Adjust all of the heads to take into account the new mem size.
+    
+    cur_thread=GetNumThreads()-1;
+    
+    for(int i=0; i<cur_thread; i++) {
+      for(int j=0; j<NUM_HEADS; j++) {
+	if(threads[i].heads[j].GetMemSpace()==target_mem_space)
+	  threads[i].heads[j].Jump(inject_code.GetSize());
       }
-      organism->GetPhenotype().IsModified() = true;
-      organism->GetPhenotype().IsMultiThread() = true;
-      
-      // Adjust all of the heads to take into account the new mem size.
-      
-      int currthread = GetCurThread();
-      SetThread(0);
-      for (int i=0; i<GetNumThreads()-2; i++)
-	{
-	  for (int j=0; j < NUM_HEADS; j++) 
-	    {    
-	      if (!GetHead(i).TestParasite() && GetHead(i).GetPosition() > line_num)
-		GetHead(i).Jump(inject_size);
-	    }
-	  NextThread();
-	}
-      SetThread(currthread);
-          
     }
-  else
-    {
-      //Some kind of error message should go here...but what?
+    
+    for (int i=0; i < NUM_HEADS; i++) {    
+      GetHead(i).Reset(target_mem_space, this);
+    }
+    for (int i=0; i < NUM_LOCAL_STACKS; i++) {
+      Stack(i).Clear();
     }
+  }
 
+  return true; // (inject succeeds!)
 }
 
 void cHardware4Stack::Mutate(int mut_point)
@@ -1349,9 +1292,10 @@
   // Make room for the new thread.
   threads.Resize(num_threads + 1);
 
+  //IP().Advance();
+
   // Initialize the new thread to the same values as the current one.
-  threads[num_threads] = threads[cur_thread];
-  IP().Advance();
+  threads[num_threads] = threads[cur_thread]; 
 
   // Find the first free bit in thread_id_chart to determine the new
   // thread id.
@@ -1408,7 +1352,7 @@
   for(int i=NUM_LOCAL_STACKS; i<NUM_STACKS; i++)
     Stack(i).SaveState(fp);
 
-  fp << thread_time_used  << endl;
+  //fp << thread_time_used  << endl;
   fp << GetNumThreads()   << endl;
   fp << cur_thread        << endl;
 
@@ -1433,7 +1377,7 @@
     Stack(i).LoadState(fp);
 
   int num_threads;
-  fp >> thread_time_used;
+  //fp >> thread_time_used;
   fp >> num_threads;
   fp >> cur_thread;
 
@@ -1489,14 +1433,6 @@
   // Make sure the organism is okay with dividing now...
   if (organism->Divide_CheckViable() == false) return false; // (divide fails)
 
-  //mal_active=true;
-
-  // If required, make sure an allocate has occured.
-  //if (cConfig::GetRequireAllocate() && mal_active == false) {
-  // Fault(FAULT_LOC_DIVIDE, FAULT_TYPE_ERROR, "Must allocate before divide");
-  //return false; //  (divide fails)
-  //}
-
   // Make sure that neither parent nor child will be below the minimum size.
 
   const int genome_size = organism->GetGenome().GetSize();
@@ -1510,13 +1446,6 @@
     return false; // (divide fails)
   }
 
-  //This is unneccesary...Parent size cannot change
-  //if (parent_size < min_size || parent_size > max_size) {
-  //  Fault(FAULT_LOC_DIVIDE, FAULT_TYPE_ERROR,
-  //  cStringUtil::Stringf("Invalid post-divide length (%d)",parent_size));
-  //return false; // (divide fails)
-  //}
-
   // Count the number of lines executed in the parent, and make sure the
   // specified fraction has been reached.
 
@@ -1668,6 +1597,118 @@
   }
 }
 
+void cHardware4Stack::Inject_DoMutations(double mut_multiplier, cCPUMemory & injected_code)
+{
+  //sCPUStats & cpu_stats = organism->CPUStats();
+  //cCPUMemory & child_genome = organism->ChildGenome();
+  
+  organism->GetPhenotype().SetDivType(mut_multiplier);
+
+  // Divide Mutations
+  if (organism->TestDivideMut()) {
+    const UINT mut_line = g_random.GetUInt(injected_code.GetSize());
+    injected_code[mut_line] = GetRandomInst();
+    //cpu_stats.mut_stats.divide_mut_count++;
+  }
+
+  // Divide Insertions
+  if (organism->TestDivideIns() && injected_code.GetSize() < MAX_CREATURE_SIZE){
+    const UINT mut_line = g_random.GetUInt(injected_code.GetSize() + 1);
+    injected_code.Insert(mut_line, GetRandomInst());
+    //cpu_stats.mut_stats.divide_insert_mut_count++;
+  }
+
+  // Divide Deletions
+  if (organism->TestDivideDel() && injected_code.GetSize() > MIN_CREATURE_SIZE){
+    const UINT mut_line = g_random.GetUInt(injected_code.GetSize());
+    // if( injected_code.FlagCopied(mut_line) == true) copied_size_change--;
+    injected_code.Remove(mut_line);
+    //cpu_stats.mut_stats.divide_delete_mut_count++;
+  }
+
+  // Divide Mutations (per site)
+  if(organism->GetDivMutProb() > 0){
+    int num_mut = g_random.GetRandBinomial(injected_code.GetSize(), 
+				   	   organism->GetDivMutProb() / mut_multiplier);
+    // If we have lines to mutate...
+    if( num_mut > 0 ){
+      for (int i = 0; i < num_mut; i++) {
+	int site = g_random.GetUInt(injected_code.GetSize());
+	injected_code[site]=GetRandomInst();
+	//cpu_stats.mut_stats.div_mut_count++;
+      }
+    }
+  }
+
+
+  // Insert Mutations (per site)
+  if(organism->GetInsMutProb() > 0){
+    int num_mut = g_random.GetRandBinomial(injected_code.GetSize(),
+					   organism->GetInsMutProb());
+    // If would make creature to big, insert up to MAX_CREATURE_SIZE
+    if( num_mut + injected_code.GetSize() > MAX_CREATURE_SIZE ){
+      num_mut = MAX_CREATURE_SIZE - injected_code.GetSize();
+    }
+    // If we have lines to insert...
+    if( num_mut > 0 ){
+      // Build a list of the sites where mutations occured
+      static int mut_sites[MAX_CREATURE_SIZE];
+      for (int i = 0; i < num_mut; i++) {
+	mut_sites[i] = g_random.GetUInt(injected_code.GetSize() + 1);
+      }
+      // Sort the list
+      qsort( (void*)mut_sites, num_mut, sizeof(int), &IntCompareFunction );
+      // Actually do the mutations (in reverse sort order)
+      for(int i = num_mut-1; i >= 0; i--) {
+	injected_code.Insert(mut_sites[i], GetRandomInst());
+	//cpu_stats.mut_stats.insert_mut_count++;
+      }
+    }
+  }
+
+
+  // Delete Mutations (per site)
+  if( organism->GetDelMutProb() > 0 ){
+    int num_mut = g_random.GetRandBinomial(injected_code.GetSize(),
+					   organism->GetDelMutProb());
+    // If would make creature too small, delete down to MIN_CREATURE_SIZE
+    if (injected_code.GetSize() - num_mut < MIN_CREATURE_SIZE) {
+      num_mut = injected_code.GetSize() - MIN_CREATURE_SIZE;
+    }
+
+    // If we have lines to delete...
+    for (int i = 0; i < num_mut; i++) {
+      int site = g_random.GetUInt(injected_code.GetSize());
+      // if (injected_code.FlagCopied(site) == true) copied_size_change--;
+      injected_code.Remove(site);
+      //cpu_stats.mut_stats.delete_mut_count++;
+    }
+  }
+
+  // Mutations in the parent's genome
+  if (organism->GetParentMutProb() > 0) {
+    for (int i = 0; i < GetMemory(0).GetSize(); i++) {
+      if (organism->TestParentMut()) {
+	GetMemory(0)[i] = GetRandomInst();
+	//cpu_stats.mut_stats.parent_mut_line_count++;
+      }
+    }
+  }
+
+  /*
+  // Count up mutated lines
+  for(int i = 0; i < GetMemory(0).GetSize(); i++){
+    if (GetMemory(0).FlagPointMut(i) == true) {
+      cpu_stats.mut_stats.point_mut_line_count++;
+    }
+  }
+  for(int i = 0; i < injected_code.GetSize(); i++){
+    if( injected_code.FlagCopyMut(i) == true) {
+      cpu_stats.mut_stats.copy_mut_line_count++;
+    }
+    }*/
+}
+
 
 // test whether the offspring creature contains an advantageous mutation.
 void cHardware4Stack::Divide_TestFitnessMeasures()
@@ -1731,7 +1772,7 @@
 
 bool cHardware4Stack::Divide_Main(int mem_space_used, double mut_multiplier)
 {
-  int write_head_pos = threads[cur_thread].heads[HEAD_WRITE].GetPosition();
+  int write_head_pos = GetHead(HEAD_WRITE).GetPosition();
   
   // We're going to disallow division calls from memory spaces other than zero 
   // for right now -law
@@ -1748,12 +1789,7 @@
   cGenome & child_genome = organism->ChildGenome();
   GetMemory(mem_space_used).Resize(write_head_pos);
   child_genome = GetMemory(mem_space_used);
-  GetMemory(mem_space_used).Resize(1);
-  GetMemory(mem_space_used)[0].SetOp(mem_space_used);
-  for(int x=0; x<NUM_HEADS; x++)
-    {
-      threads[cur_thread].heads[x].Reset(this);
-    }
+
   // Handle Divide Mutations...
   Divide_DoMutations(mut_multiplier);
 
@@ -1770,6 +1806,52 @@
 #endif
 
   bool parent_alive = organism->ActivateDivide();
+
+  //reset the memory of the memory space that has been divided off
+  GetMemory(mem_space_used)=cGenome(ConvertToInstruction(mem_space_used)); 
+
+  // 3 Division Methods:
+  // 1) DIVIDE_METHOD_OFFSPRING - Create a child, leave parent state untouched.
+  // 2) DIVIDE_METHOD_SPLIT - Create a child, completely reset state of parent.
+  // 3) DIVIDE_METHOD_BIRTH - Create a child, reset state of parent's current thread.
+  if(parent_alive && !(cConfig::GetDivideMethod() == DIVIDE_METHOD_OFFSPRING))
+    {
+      
+      if(cConfig::GetDivideMethod() == DIVIDE_METHOD_SPLIT)
+	{
+	  //this will wipe out all parasites on a divide.
+	  Reset();
+	  
+	}
+      else if(cConfig::GetDivideMethod() == DIVIDE_METHOD_BIRTH)
+	{
+	  //if this isn't the only thread, get rid of it!
+	  // ***this can cause a concurrency problem if we have 
+	  // multiprocessor support for single organisms...don't 
+	  // think that's happening anytime soon though -law ***
+	  if(!organism->GetPhenotype().IsModified() && GetNumThreads()>1 || 
+	     GetNumThreads()>2)
+	    {
+	      KillThread();
+	    }
+
+	  //this will reset the current thread's heads and stacks.  It will 
+	  //not touch any other threads or memory spaces (ie: parasites)
+	  else
+	    {
+	      for(int x=0; x<NUM_HEADS; x++)
+		{
+		  GetHead(x).Reset(0, this);
+		}
+	      for(int x=0; x<NUM_LOCAL_STACKS; x++)
+		{
+		  Stack(x).Clear();
+		}	  
+	    }
+	}
+      AdvanceIP()=false;
+    }
+     
   return true;
 }
 
@@ -1780,6 +1862,20 @@
   ret += c;
   return ret;
 }
+
+cString cHardware4Stack::GetActiveStackID(int stackID) const
+{
+  if(stackID==STACK_AX)
+    return "AX";
+  else if(stackID==STACK_BX)
+    return "BX";
+  else if(stackID==STACK_CX)
+    return "CX";
+  else if(stackID==STACK_DX)
+    return "DX";
+  else
+    return "";
+}
   
 
 //////////////////////////
@@ -1857,9 +1953,17 @@
 //13 
 bool cHardware4Stack::Inst_SetMemory()   // Allocate maximal more
 {
-  const int mem_space_used = FindModifiedStack(STACK_BX);
-  threads[cur_thread].heads[HEAD_FLOW].Set(0, this, mem_space_used);
+  int mem_space_used = FindModifiedStack(-1);
+  
+  if(mem_space_used==-1) {
+    mem_space_used = FindFirstEmpty();
+    if(mem_space_used==-1)
+      return false;
+  }
+  
+  GetHead(HEAD_FLOW).Set(0, mem_space_used);
   return true;
+  
   //const int cur_size = GetMemory(0).GetSize();
   //const int alloc_size = Min((int) (cConfig::GetChildSizeRange() * cur_size),
   //			     MAX_CREATURE_SIZE - cur_size);
@@ -1872,12 +1976,8 @@
 //14
 bool cHardware4Stack::Inst_Divide()
 {
-  //return Inst_HeadDivideMut(1);
-  int mem_space_used = FindModifiedStack(STACK_BX);
-
+  int mem_space_used = GetHead(HEAD_WRITE).GetMemSpace();
   int mut_multiplier = 1;
-  if(mem_space_used==0)
-    mem_space_used++;
 
   return Divide_Main(mem_space_used, mut_multiplier);
 }
@@ -2026,7 +2126,7 @@
   Stack(STACK_BX).Push(GetHead(head_used).GetPosition());
   //if (head_used == HEAD_IP) {
   //  GetHead(head_used).Set(GetHead(HEAD_FLOW));
-  //  advance_ip = false;
+  //  AdvanceIP() = false;
   //}
   return true;
 }
@@ -2035,7 +2135,8 @@
 bool cHardware4Stack::Inst_HeadPop()
 {
   const int head_used = FindModifiedHead(HEAD_IP);
-  GetHead(head_used).Set(Stack(STACK_BX).Pop(), this);
+  GetHead(head_used).Set(Stack(STACK_BX).Pop(), 
+			 GetHead(head_used).GetMemSpace(), this);
   return true;
 }
 
@@ -2046,7 +2147,7 @@
   if(head_used != HEAD_FLOW)
     {
       GetHead(head_used).Set(GetHead(HEAD_FLOW));
-      if (head_used == HEAD_IP) advance_ip = false;
+      if (head_used == HEAD_IP) AdvanceIP() = false;
     }
   else
     {
@@ -2063,7 +2164,9 @@
   c4StackHead found_pos = FindLabel(0);
   if(found_pos.GetPosition()-IP().GetPosition()==0)
     {
-      GetHead(HEAD_FLOW).Set(IP().GetPosition()+1, this, IP().GetMemSpace());
+      GetHead(HEAD_FLOW).Set(IP().GetPosition()+1, IP().GetMemSpace(), this);
+      // pushing zero into STACK_AX on a missed search makes it difficult to create
+      // a self-replicating organism.  -law
       //Stack(STACK_AX).Push(0);
       Stack(STACK_BX).Push(0);
     }
@@ -2074,6 +2177,7 @@
       Stack(STACK_AX).Push(GetLabel().GetSize());
       GetHead(HEAD_FLOW).Set(found_pos);
     }  
+  
   return true; 
 }
 
@@ -2162,7 +2266,10 @@
 {
   const int stack_used = FindModifiedStack(STACK_BX);
   if (Stack(STACK_CX).Top() != 0) {
-    Stack(stack_used).Push(Stack(STACK_BX).Top() % Stack(STACK_CX).Top());
+    if(Stack(STACK_CX).Top() == -1)
+      Stack(stack_used).Push(0);
+    else
+      Stack(stack_used).Push(Stack(STACK_BX).Top() % Stack(STACK_CX).Top());
   } else {
     Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "mod: modding by 0");
   return false;
@@ -2174,1067 +2281,91 @@
 bool cHardware4Stack::Inst_KillThread()
 {
   if (!KillThread()) Fault(FAULT_LOC_THREAD_KILL, FAULT_TYPE_KILL_TH);
-  else advance_ip = false;
+  else AdvanceIP() = false;
   return true;
 }
 
-cString cHardware4Stack::GetActiveStackID(int stackID) const
+//36
+bool cHardware4Stack::Inst_IO()
 {
-  if(stackID==STACK_AX)
-    return "AX";
-  else if(stackID==STACK_BX)
-    return "BX";
-  else if(stackID==STACK_CX)
-    return "CX";
-  else if(stackID==STACK_DX)
-    return "DX";
-  else
-    return "";
-}
+  const int stack_used = FindModifiedStack(STACK_BX);
 
-/*bool cHardware4Stack::Inst_If0()          // Execute next if ?bx? ==0.
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  if (Register(reg_used) != 0)  IP().Advance();
-  return true; 
-}
+  // Do the "put" component
+  const int value_out = Stack(stack_used).Top();
+  DoOutput(value_out);  // Check for tasks compleated.
 
-bool cHardware4Stack::Inst_IfNot0()       // Execute next if ?bx? != 0.
-{ 
-  const int reg_used = FindModifiedRegister(REG_BX);
-  if (Register(reg_used) == 0)  IP().Advance();
+  // Do the "get" component
+  const int value_in = organism->GetInputAt(threads[GetCurThread()].input_pointer);
+  Stack(stack_used).Push(value_in);
+  DoInput(value_in);
   return true;
 }
 
-bool cHardware4Stack::Inst_IfGr0()       // Execute next if ?bx? ! < 0.
+int cHardware4Stack::FindFirstEmpty()
 {
-  const int reg_used = FindModifiedRegister(REG_BX);
-  if (Register(reg_used) <= 0)  IP().Advance();
-  return true;
-}
+  bool OK=true;
+  const int current_mem_space = IP().GetMemSpace();
 
-bool cHardware4Stack::Inst_IfGrEqu0()       // Execute next if ?bx? != 0.
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  if (Register(reg_used) < 0)  IP().Advance();
-  return true;
-}
+  for(int x=1; x<NUM_MEMORY_SPACES; x++)
+    {
+      OK=true;
+      
+      int index = (current_mem_space+x) % NUM_MEMORY_SPACES;
 
-bool cHardware4Stack::Inst_IfGrEqu()       // Execute next if bx > ?cx?
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  const int reg_used2 = FindComplementRegister(reg_used);
-  if (Register(reg_used) < Register(reg_used2)) IP().Advance();
-  return true;
+      for(int y=0; y<GetMemory(index).GetSize() && OK; y++)
+	{
+	  if(GetMemory(index)[y].GetOp() >= NUM_NOPS_4STACK)
+	    OK=false; 
+	}
+      for(int y=0; y<GetNumThreads() && OK; y++)
+	{
+	  for(int z=0; z<NUM_HEADS; z++)
+	    {
+	      if(threads[y].heads[z].GetMemSpace() == index)
+		OK=false;
+	    }
+	}
+      if(OK)
+	return index;
+    }
+  return -1;
 }
 
-bool cHardware4Stack::Inst_IfLess0()       // Execute next if ?bx? != 0.
+bool cHardware4Stack::isEmpty(int mem_space_used)
 {
-  const int reg_used = FindModifiedRegister(REG_BX);
-  if (Register(reg_used) >= 0)  IP().Advance();
+  for(int x=0; x<GetMemory(mem_space_used).GetSize(); x++)
+    {
+      if(GetMemory(mem_space_used)[x].GetOp() >= NUM_NOPS_4STACK)
+	return false;
+    }
   return true;
 }
 
-bool cHardware4Stack::Inst_IfLsEqu0()       // Execute next if ?bx? != 0.
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  if (Register(reg_used) > 0) IP().Advance();
-  return true;
-}
+// The inject instruction can be used instead of a divide command, paired
+// with an allocate.  Note that for an inject to work, one needs to have a
+// broad range for sizes allowed to be allocated.
+//
+// This command will cut out from read-head to write-head.
+// It will then look at the template that follows the command and inject it
+// into the complement template found in a neighboring organism.
 
-bool cHardware4Stack::Inst_IfLsEqu()       // Execute next if bx > ?cx?
+bool cHardware4Stack::Inst_Inject()
 {
-  const int reg_used = FindModifiedRegister(REG_BX);
-  const int reg_used2 = FindComplementRegister(reg_used);
-  if (Register(reg_used) >  Register(reg_used2))  IP().Advance();
-  return true;
-}
+  double mut_multiplier = 1;
 
-bool cHardware4Stack::Inst_IfBit1()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  if ((Register(reg_used) & 1) == 0)  IP().Advance();
-  return true;
+  return InjectParasite(mut_multiplier);
 }
 
-bool cHardware4Stack::Inst_IfANotEqB()     // Execute next if AX != BX
-{
-  if (Register(REG_AX) == Register(REG_BX) )  IP().Advance();
-  return true;
-}
 
-bool cHardware4Stack::Inst_IfBNotEqC()     // Execute next if BX != CX
-{
-  if (Register(REG_BX) == Register(REG_CX) )  IP().Advance();
-  return true;
-}
 
-bool cHardware4Stack::Inst_IfANotEqC()     // Execute next if AX != BX
+/*
+bool cHardware4Stack::Inst_InjectRand()
 {
-  if (Register(REG_AX) == Register(REG_CX) )  IP().Advance();
+  // Rotate to a random facing and then run the normal inject instruction
+  const int num_neighbors = organism->GetNeighborhoodSize();
+  organism->Rotate(g_random.GetUInt(num_neighbors));
+  Inst_Inject();
   return true;
 }
 
-bool cHardware4Stack::Inst_JumpF()
-{
-  ReadLabel();
-  GetLabel().Rotate(2, NUM_NOPS_4STACK);
-
-  // If there is no label, jump BX steps.
-  if (GetLabel().GetSize() == 0) {
-    GetActiveHead().Jump(Register(REG_BX));
-    return true;
-  }
-
-  // Otherwise, try to jump to the complement label.
-  const c4StackHead jump_location(FindLabel(1));
-  if ( jump_location.GetPosition() != -1 ) {
-    GetActiveHead().Set(jump_location);
-    return true;
-  }
-
-  // If complement label was not found; record an error.
-  organism->Fault(FAULT_LOC_JUMP, FAULT_TYPE_ERROR,
-		  "jump-f: No complement label");
-  return false;
-}
-
-bool cHardware4Stack::Inst_JumpB()
-{
-  ReadLabel();
-  GetLabel().Rotate(2, NUM_NOPS_4STACK);
-
-  // If there is no label, jump BX steps.
-  if (GetLabel().GetSize() == 0) {
-    GetActiveHead().Jump(-Register(REG_BX));
-    return true;
-  }
-
-  // otherwise jump to the complement label.
-  const c4StackHead jump_location(FindLabel(-1));
-  if ( jump_location.GetPosition() != -1 ) {
-    GetActiveHead().Set(jump_location);
-    return true;
-  }
-
-  // If complement label was not found; record an error.
-  organism->Fault(FAULT_LOC_JUMP, FAULT_TYPE_ERROR,
-		  "jump-b: No complement label");
-  return false;
-}
-
-bool cHardware4Stack::Inst_JumpP()
-{
-  cOrganism * other_organism = organism->GetNeighbor();
-
-  // Make sure the other organism was found and that its hardware is of the
-  // same type, or else we won't be able to be parasitic on it.
-  if (other_organism == NULL ||
-      other_organism->GetHardware().GetType() != GetType()) {
-    // Without another organism, its hard to determine if we're dealing
-    // with a parasite.  For the moment, we'll assume it is and move on.
-    // @CAO Do better!
-    organism->GetPhenotype().IsParasite() = true;
-    return true;
-  }
-
-  // Otherwise, grab the hardware from the neighbor, and use it!
-  cHardware4Stack & other_hardware = (cHardware4Stack &) other_organism->GetHardware();
-
-  ReadLabel();
-  GetLabel().Rotate(2, NUM_NOPS_4STACK);
-
-  // If there is no label, jump to line BX in creature.
-  if (GetLabel().GetSize() == 0) {
-    const int new_pos = Register(REG_BX);
-    IP().Set(new_pos, &other_hardware);
-    organism->GetPhenotype().IsParasite() = true;
-    return true;
-  }
-
-  // otherwise jump to the complement label.
-  const c4StackHead jump_location(other_hardware.FindFullLabel(GetLabel()));
-  if (jump_location.GetPosition() != -1) {
-    IP().Set(jump_location);
-    organism->GetPhenotype().IsParasite() = true;
-    return true;
-  }
-
-  // If complement label was not found; record a warning (since the
-  // actual neighbors are not under the organisms control, this is not
-  // a full-scale error).
-  organism->Fault(FAULT_LOC_JUMP, FAULT_TYPE_WARNING,
-		  "jump-p: No complement label");
-  return false;
-}
-
-bool cHardware4Stack::Inst_JumpSelf()
-{
-  ReadLabel();
-  GetLabel().Rotate(2, NUM_NOPS_4STACK);
-
-  // If there is no label, jump to line BX in creature.
-  if (GetLabel().GetSize() == 0) {
-    IP().Set(Register(REG_BX), this);
-    return true;
-  }
-
-  // otherwise jump to the complement label.
-  const c4StackHead jump_location( FindFullLabel(GetLabel()) );
-  if ( jump_location.GetPosition() != -1 ) {
-    IP().Set(jump_location);
-    return true;
-  }
-
-  // If complement label was not found; record an error.
-  organism->Fault(FAULT_LOC_JUMP, FAULT_TYPE_ERROR,
-		  "jump-slf: no complement label");
-  return false;
-}
-
-bool cHardware4Stack::Inst_Call()
-{
-  // Put the starting location onto the stack
-  const int location = IP().GetPosition();
-  StackPush(location);
-
-  // Jump to the compliment label (or by the ammount in the bx register)
-  ReadLabel();
-  GetLabel().Rotate(2, NUM_NOPS_4STACK);
-
-  if (GetLabel().GetSize() == 0) {
-    IP().Jump(Register(REG_BX));
-    return true;
-  }
-
-  const c4StackHead jump_location(FindLabel(1));
-  if (jump_location.GetPosition() != -1) {
-    IP().Set(jump_location);
-    return true;
-  }
-
-  // If complement label was not found; record an error.
-  organism->Fault(FAULT_LOC_JUMP, FAULT_TYPE_ERROR,
-		  "call: no complement label");
-  return false;
-}
-
-bool cHardware4Stack::Inst_Return()
-{
-  IP().Set(StackPop());
-  return true;
-}
-
-bool cHardware4Stack::Inst_Pop()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  Register(reg_used) = StackPop();
-  return true;
-}
-
-bool cHardware4Stack::Inst_Push()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  StackPush(Register(reg_used));
-  return true;
-}
-
-bool cHardware4Stack::Inst_PopA() { Register(REG_AX) = StackPop(); return true;}
-bool cHardware4Stack::Inst_PopB() { Register(REG_BX) = StackPop(); return true;}
-bool cHardware4Stack::Inst_PopC() { Register(REG_CX) = StackPop(); return true;}
-
-bool cHardware4Stack::Inst_SwitchStack() { SwitchStack(); return true;}
-bool cHardware4Stack::Inst_FlipStack()   { StackFlip(); return true;}
-
-bool cHardware4Stack::Inst_Swap()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  const int other_reg = FindComplementRegister(reg_used);
-  Swap(Register(reg_used), Register(other_reg));
-  return true;
-}
-
-bool cHardware4Stack::Inst_SwapAB() { Swap(Register(REG_AX), Register(REG_BX)); return true; }
-bool cHardware4Stack::Inst_SwapBC() { Swap(Register(REG_BX), Register(REG_CX)); return true; }
-bool cHardware4Stack::Inst_SwapAC() { Swap(Register(REG_AX), Register(REG_CX)); return true; }
-
-bool cHardware4Stack::Inst_CopyRegAB() { Register(REG_AX) = Register(REG_BX);   return true;
-}
-bool cHardware4Stack::Inst_CopyRegAC() { Register(REG_AX) = Register(REG_CX);   return true;
-}
-bool cHardware4Stack::Inst_CopyRegBA() { Register(REG_BX) = Register(REG_AX);   return true;
-}
-bool cHardware4Stack::Inst_CopyRegBC() { Register(REG_BX) = Register(REG_CX);   return true;
-}
-bool cHardware4Stack::Inst_CopyRegCA() { Register(REG_CX) = Register(REG_AX);   return true;
-}
-bool cHardware4Stack::Inst_CopyRegCB() { Register(REG_CX) = Register(REG_BX);   return true;
-}
-
-bool cHardware4Stack::Inst_Reset()
-{
-  Register(REG_AX) = 0;
-  Register(REG_BX) = 0;
-  Register(REG_CX) = 0;
-  StackClear();
-  return true;
-}
-
-bool cHardware4Stack::Inst_Bit1()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  Register(reg_used) |=  1;
-  return true;
-}
-
-bool cHardware4Stack::Inst_SetNum()
-{
-  ReadLabel();
-  Register(REG_BX) = GetLabel().AsInt();
-  return true;
-}
-
-bool cHardware4Stack::Inst_Zero()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  Register(reg_used) = 0;
-  return true;
-}
-
-bool cHardware4Stack::Inst_Neg()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  Register(reg_used) = 0-Register(reg_used);
-  return true;
-}
-
-bool cHardware4Stack::Inst_Square()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  Register(reg_used) = Register(reg_used) * Register(reg_used);
-  return true;
-}
-
-bool cHardware4Stack::Inst_Sqrt()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  const int value = Register(reg_used);
-  if (value > 1) Register(reg_used) = (int) sqrt((double) value);
-  else if (value < 0) {
-    Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "sqrt: value is negative");
-    return false;
-  }
-  return true;
-}
-
-bool cHardware4Stack::Inst_Log()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  const int value = Register(reg_used);
-  if (value >= 1) Register(reg_used) = (int) log((double) value);
-  else if (value < 0) {
-    Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "log: value is negative");
-    return false;
-  }
-  return true;
-}
-
-bool cHardware4Stack::Inst_Log10()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  const int value = Register(reg_used);
-  if (value >= 1) Register(reg_used) = (int) log10((double) value);
-  else if (value < 0) {
-    Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "log10: value is negative");
-    return false;
-  }
-  return true;
-}
-
-bool cHardware4Stack::Inst_Minus18()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  Register(reg_used) -= 18;
-  return true;
-}
-
-bool cHardware4Stack::Inst_Nor()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  Register(reg_used) = ~(Register(REG_BX) | Register(REG_CX));
-  return true;
-}
-
-bool cHardware4Stack::Inst_And()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  Register(reg_used) = (Register(REG_BX) & Register(REG_CX));
-  return true;
-}
-
-bool cHardware4Stack::Inst_Not()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  Register(reg_used) = ~(Register(reg_used));
-  return true;
-}
-
-bool cHardware4Stack::Inst_Order()
-{
-  if (Register(REG_BX) > Register(REG_CX)) {
-    Swap(Register(REG_BX), Register(REG_CX));
-  }
-  return true;
-}
-
-bool cHardware4Stack::Inst_Xor()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  Register(reg_used) = Register(REG_BX) ^ Register(REG_CX);
-  return true;
-}
-
-bool cHardware4Stack::Inst_Copy()
-{
-  const c4StackHead from(this, Register(REG_BX));
-  c4StackHead to(this, Register(REG_AX) + Register(REG_BX));
-  sCPUStats & cpu_stats = organism->CPUStats();
-
-  if (organism->TestCopyMut()) {
-    to.SetInst(GetRandomInst());
-    to.FlagMutated() = true;  // Mark this instruction as mutated...
-    to.FlagCopyMut() = true;  // Mark this instruction as copy mut...
-    //organism->GetPhenotype().IsMutated() = true;
-    cpu_stats.mut_stats.copy_mut_count++;
-  } else {
-    to.SetInst(from.GetInst());
-    to.FlagMutated() = false;  // UnMark
-    to.FlagCopyMut() = false;  // UnMark
-  }
-
-  to.FlagCopied() = true;  // Set the copied flag.
-  cpu_stats.mut_stats.copies_exec++;
-  return true;
-}
-
-bool cHardware4Stack::Inst_ReadInst()
-{
-  const int reg_used = FindModifiedRegister(REG_CX);
-  const c4StackHead from(this, Register(REG_BX));
-
-  // Dis-allowing mutations on read, for the moment (write only...)
-  // @CAO This allows perfect error-correction...
-  Register(reg_used) = from.GetInst().GetOp();
-  return true;
-}
-
-bool cHardware4Stack::Inst_WriteInst()
-{
-  c4StackHead to(this, Register(REG_AX) + Register(REG_BX));
-  const int reg_used = FindModifiedRegister(REG_CX);
-  const int value = Mod(Register(reg_used), GetNumInst());
-  sCPUStats & cpu_stats = organism->CPUStats();
-
-  // Change value on a mutation...
-  if (organism->TestCopyMut()) {
-    to.SetInst(GetRandomInst());
-    to.FlagMutated() = true;      // Mark this instruction as mutated...
-    to.FlagCopyMut() = true;      // Mark this instruction as copy mut...
-    //organism->GetPhenotype().IsMutated() = true;
-    cpu_stats.mut_stats.copy_mut_count++;
-  } else {
-    to.SetInst(cInstruction(value));
-    to.FlagMutated() = false;     // UnMark
-    to.FlagCopyMut() = false;     // UnMark
-  }
-
-  to.FlagCopied() = true;  // Set the copied flag.
-  cpu_stats.mut_stats.copies_exec++;
-  return true;
-}
-
-bool cHardware4Stack::Inst_StackReadInst()
-{
-  const int reg_used = FindModifiedRegister(REG_CX);
-  c4StackHead from(this, Register(reg_used));
-  StackPush(from.GetInst().GetOp());
-  return true;
-}
-
-bool cHardware4Stack::Inst_StackWriteInst()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  c4StackHead to(this, Register(REG_AX) + Register(reg_used));
-  const int value = Mod(StackPop(), GetNumInst());
-  sCPUStats & cpu_stats = organism->CPUStats();
-
-  // Change value on a mutation...
-  if (organism->TestCopyMut()) {
-    to.SetInst(GetRandomInst());
-    to.FlagMutated() = true;      // Mark this instruction as mutated...
-    to.FlagCopyMut() = true;      // Mark this instruction as copy mut...
-    //organism->GetPhenotype().IsMutated() = true;
-    cpu_stats.mut_stats.copy_mut_count++;
-  } else {
-    to.SetInst(cInstruction(value));
-    to.FlagMutated() = false;     // UnMark
-    to.FlagCopyMut() = false;     // UnMark
-  }
-
-  to.FlagCopied() = true;  // Set the copied flag.
-  cpu_stats.mut_stats.copies_exec++;
-  return true;
-}
-
-bool cHardware4Stack::Inst_Compare()
-{
-  const int reg_used = FindModifiedRegister(REG_CX);
-  c4StackHead from(this, Register(REG_BX));
-  c4StackHead to(this, Register(REG_AX) + Register(REG_BX));
-
-  // Compare is dangerous -- it can cause mutations!
-  if (organism->TestCopyMut()) {
-    to.SetInst(GetRandomInst());
-    to.FlagMutated() = true;      // Mark this instruction as mutated...
-    to.FlagCopyMut() = true;      // Mark this instruction as copy mut...
-    //organism->GetPhenotype().IsMutated() = true;
-  }
-
-  Register(reg_used) = from.GetInst().GetOp() - to.GetInst().GetOp();
-
-  return true;
-}
-
-bool cHardware4Stack::Inst_IfNCpy()
-{
-  const c4StackHead from(this, Register(REG_BX));
-  const c4StackHead to(this, Register(REG_AX) + Register(REG_BX));
-
-  // Allow for errors in this test...
-  if (organism->TestCopyMut()) {
-    if (from.GetInst() != to.GetInst()) IP().Advance();
-  } else {
-    if (from.GetInst() == to.GetInst()) IP().Advance();
-  }
-  return true;
-}
-
-bool cHardware4Stack::Inst_Allocate()   // Allocate bx more space...
-{
-  const int size = GetMemory().GetSize();
-  if( Allocate_Main(Register(REG_BX)) ) {
-    Register(REG_AX) = size;
-    return true;
-  } else return false;
-}
-
-bool cHardware4Stack::Inst_DivideOld()  
-{ 
-  return Divide_Main(Register(REG_AX));    
-}
-
-bool cHardware4Stack::Inst_CDivide() 
-{ 
-  return Divide_Main(GetMemory().GetSize() / 2);   
-}
-
-bool cHardware4Stack::Inst_CAlloc()  
-{ 
-  return Allocate_Main(GetMemory().GetSize());   
-}
-
-bool cHardware4Stack::Inst_Repro()
-{
-  // Setup child
-  cCPUMemory & child_genome = organism->ChildGenome();
-  child_genome = GetMemory();
-  organism->GetPhenotype().SetLinesCopied(GetMemory().GetSize());
-
-  int lines_executed = 0;
-  for ( int i = 0; i < GetMemory().GetSize(); i++ ) {
-    if ( GetMemory().FlagExecuted(i) == true ) lines_executed++;
-  }
-  organism->GetPhenotype().SetLinesExecuted(lines_executed);
-
-  // Perform Copy Mutations...
-  if (organism->GetCopyMutProb() > 0) { // Skip this if no mutations....
-    for (int i = 0; i < GetMemory().GetSize(); i++) {
-      if (organism->TestCopyMut()) {
-	child_genome[i]=GetRandomInst();
-	//organism->GetPhenotype().IsMutated() = true;
-      }
-    }
-  }
-  Divide_DoMutations();
-
-  // Many tests will require us to run the offspring through a test CPU;
-  // this is, for example, to see if mutations need to be reverted or if
-  // lineages need to be updated.
-  Divide_TestFitnessMeasures();
-
-#ifdef INSTRUCTION_COSTS
-  // reset first time instruction costs
-  for (int i = 0; i < inst_ft_cost.GetSize(); i++) {
-    inst_ft_cost[i] = GetInstSet().GetFTCost(cInstruction(i));
-  }
-#endif
-
-  if (cConfig::GetDivideMethod() == DIVIDE_METHOD_SPLIT) advance_ip = false;
-
-  organism->ActivateDivide();
-
-  return true;
-}
-
-// The inject instruction can be used instead of a divide command, paired
-// with an allocate.  Note that for an inject to work, one needs to have a
-// broad range for sizes allowed to be allocated.
-//
-// This command will cut out from read-head to write-head.
-// It will then look at the template that follows the command and inject it
-// into the complement template found in a neighboring organism.
-
-bool cHardware4Stack::Inst_Inject()
-{
-  AdjustHeads();
-  const int start_pos = GetHead(HEAD_READ).GetPosition();
-  const int end_pos = GetHead(HEAD_WRITE).GetPosition();
-  const int inject_size = end_pos - start_pos;
-
-  // Make sure the creature will still be above the minimum size,
-  if (inject_size <= 0) {
-    Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: no code to inject");
-    return false; // (inject fails)
-  }
-  if (start_pos < MIN_CREATURE_SIZE) {
-    Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: new size too small");
-    return false; // (inject fails)
-  }
-
-  // Since its legal to cut out the injected piece, do so.
-  cGenome inject_code( cGenomeUtil::Crop(GetMemory(), start_pos, end_pos) );
-  GetMemory().Remove(start_pos, inject_size);
-
-  // If we don't have a host, stop here.
-  cOrganism * host_organism = organism->GetNeighbor();
-  if (host_organism == NULL) return false;
-
-  // Scan for the label to match...
-  ReadLabel();
-
-  // If there is no label, abort.
-  if (GetLabel().GetSize() == 0) {
-    Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: label required");
-    return false; // (inject fails)
-  }
-
-  // Search for the label in the host...
-  GetLabel().Rotate(2, NUM_NOPS_4STACK);
-
-  const int inject_signal =
-    host_organism->GetHardware().Inject(GetLabel(), inject_code);
-  if (inject_signal == 1) {
-    Fault(FAULT_LOC_INJECT, FAULT_TYPE_WARNING, "inject: host too large.");
-    return false; // Inject failed.
-  }
-  if (inject_signal == 2) {
-    Fault(FAULT_LOC_INJECT, FAULT_TYPE_WARNING, "inject: target not in host.");
-    return false; // Inject failed.
-  }
-
-  // Set the relevent flags.
-  organism->GetPhenotype().IsModifier() = true;
-
-  return true;
-}
-
-bool cHardware4Stack::Inst_InjectRand()
-{
-  // Rotate to a random facing and then run the normal inject instruction
-  const int num_neighbors = organism->GetNeighborhoodSize();
-  organism->Rotate(g_random.GetUInt(num_neighbors));
-  Inst_Inject();
-  return true;
-}
-
-// The inject instruction can be used instead of a divide command, paired
-// with an allocate.  Note that for an inject to work, one needs to have a
-// broad range for sizes allowed to be allocated.
-//
-// This command will cut out from read-head to write-head.
-// It will then look at the template that follows the command and inject it
-// into the complement template found in a neighboring organism.
-
-bool cHardware4Stack::Inst_InjectThread()
-{
-  AdjustHeads();
-  const int start_pos = GetHead(HEAD_READ).GetPosition();
-  const int end_pos = GetHead(HEAD_WRITE).GetPosition();
-  const int inject_size = end_pos - start_pos;
-
-  // Make sure the creature will still be above the minimum size,
-  if (inject_size <= 0) {
-    Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: no code to inject");
-    return false; // (inject fails)
-  }
-  if (start_pos < MIN_CREATURE_SIZE) {
-    Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: new size too small");
-    return false; // (inject fails)
-  }
-
-  // Since its legal to cut out the injected piece, do so.
-  cGenome inject_code( cGenomeUtil::Crop(GetMemory(), start_pos, end_pos) );
-  GetMemory().Remove(start_pos, inject_size);
-
-  // If we don't have a host, stop here.
-  cOrganism * host_organism = organism->GetNeighbor();
-  if (host_organism == NULL) return false;
-
-  // Scan for the label to match...
-  ReadLabel();
-
-  // If there is no label, abort.
-  if (GetLabel().GetSize() == 0) {
-    Fault(FAULT_LOC_INJECT, FAULT_TYPE_ERROR, "inject: label required");
-    return false; // (inject fails)
-  }
-
-  // Search for the label in the host...
-  GetLabel().Rotate(2, NUM_NOPS_4STACK);
-
-  const int inject_signal =
-    host_organism->GetHardware().InjectThread(GetLabel(), inject_code);
-  if (inject_signal == 1) {
-    Fault(FAULT_LOC_INJECT, FAULT_TYPE_WARNING, "inject: host too large.");
-    return false; // Inject failed.
-  }
-  if (inject_signal == 2) {
-    Fault(FAULT_LOC_INJECT, FAULT_TYPE_WARNING, "inject: target not in host.");
-    return false; // Inject failed.
-  }
-
-  // Set the relevent flags.
-  organism->GetPhenotype().IsModifier() = true;
-
-  return true;
-}
-
-bool cHardware4Stack::Inst_TaskGet()
-{
-  const int reg_used = FindModifiedRegister(REG_CX);
-  const int value = organism->GetInput();
-  Register(reg_used) = value;
-  DoInput(value);
-  return true;
-}
-
-bool cHardware4Stack::Inst_TaskStackGet()
-{
-  const int value = organism->GetInput();
-  StackPush(value);
-  DoInput(value);
-  return true;
-}
-
-bool cHardware4Stack::Inst_TaskStackLoad()
-{
-  for (int i = 0; i < IO_SIZE; i++) StackPush( organism->GetInput() );
-  return true;
-}
-
-bool cHardware4Stack::Inst_TaskPut()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  const int value = Register(reg_used);
-  Register(reg_used) = 0;
-  DoOutput(value);
-  return true;
-}
-
-bool cHardware4Stack::Inst_TaskIO()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-
-  // Do the "put" component
-  const int value_out = Register(reg_used);
-  DoOutput(value_out);  // Check for tasks compleated.
-
-  // Do the "get" component
-  const int value_in = organism->GetInput();
-  Register(reg_used) = value_in;
-  DoInput(value_in);
-  return true;
-}
-
-bool cHardware4Stack::Inst_SearchF()
-{
-  ReadLabel();
-  GetLabel().Rotate(2, NUM_NOPS_4STACK);
-  const int search_size = FindLabel(1).GetPosition() - IP().GetPosition();
-  Register(REG_BX) = search_size;
-  Register(REG_CX) = GetLabel().GetSize();
-  return true;
-}
-
-bool cHardware4Stack::Inst_SearchB()
-{
-  ReadLabel();
-  GetLabel().Rotate(2, NUM_NOPS_4STACK);
-  const int search_size = IP().GetPosition() - FindLabel(-1).GetPosition();
-  Register(REG_BX) = search_size;
-  Register(REG_CX) = GetLabel().GetSize();
-  return true;
-}
-
-bool cHardware4Stack::Inst_MemSize()
-{
-  Register(FindModifiedRegister(REG_BX)) = GetMemory().GetSize();
-  return true;
-}
-
-
-bool cHardware4Stack::Inst_RotateL()
-{
-  const int num_neighbors = organism->GetNeighborhoodSize();
-
-   // If this organism has no neighbors, ignore rotate.
-  if (num_neighbors == 0) return false;
-
-  ReadLabel();
-
-  // Always rotate at least once.
-  organism->Rotate(-1);
-
-  // If there is no label, then the one rotation was all we want.
-  if (!GetLabel().GetSize()) return true;
-
-  // Rotate until a complement label is found (or all have been checked).
-  GetLabel().Rotate(2, NUM_NOPS_4STACK);
-  for (int i = 1; i < num_neighbors; i++) {
-    cOrganism * neighbor = organism->GetNeighbor();
-
-    // Assuming we have a neighbor and it is of the same hardware type,
-    // search for the label in it.
-    if (neighbor != NULL &&
-	neighbor->GetHardware().GetType() == GetType()) {
-
-      // If this facing has the full label, stop here.
-      cHardware4Stack & cur_hardware = (cHardware4Stack &) neighbor->GetHardware();
-      if (cur_hardware.FindFullLabel( GetLabel() ).InMemory()) return true;
-    }
-
-    // Otherwise keep rotating...
-    organism->Rotate(-1);
-  }
-  return true;
-}
-
-bool cHardware4Stack::Inst_RotateR()
-{
-  const int num_neighbors = organism->GetNeighborhoodSize();
-
-   // If this organism has no neighbors, ignore rotate.
-  if (num_neighbors == 0) return false;
-
-  ReadLabel();
-
-  // Always rotate at least once.
-  organism->Rotate(-1);
-
-  // If there is no label, then the one rotation was all we want.
-  if (!GetLabel().GetSize()) return true;
-
-  // Rotate until a complement label is found (or all have been checked).
-  GetLabel().Rotate(2, NUM_NOPS_4STACK)S;
-  for (int i = 1; i < num_neighbors; i++) {
-    cOrganism * neighbor = organism->GetNeighbor();
-
-    // Assuming we have a neighbor and it is of the same hardware type,
-    // search for the label in it.
-    if (neighbor != NULL &&
-	neighbor->GetHardware().GetType() == GetType()) {
-
-      // If this facing has the full label, stop here.
-      cHardware4Stack & cur_hardware = (cHardware4Stack &) neighbor->GetHardware();
-      if (cur_hardware.FindFullLabel( GetLabel() ).InMemory()) return true;
-    }
-
-    // Otherwise keep rotating...
-    organism->Rotate(1);
-  }
-  return true;
-}
-
-bool cHardware4Stack::Inst_SetCopyMut()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  const int new_mut_rate = Max( Register(reg_used), 1 );
-  organism->SetCopyMutProb(((double) new_mut_rate) / 10000.0);
-  return true;
-}
-
-bool cHardware4Stack::Inst_ModCopyMut()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  const double new_mut_rate = organism->GetCopyMutProb() +
-    ((double) Register(reg_used)) / 10000.0;
-  if (new_mut_rate > 0.0) organism->SetCopyMutProb(new_mut_rate);
-  return true;
-}
-// Multi-threading.
-
-bool cHardware4Stack::Inst_ThreadID()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  Register(reg_used) = GetCurThreadID();
-  return true;
-}
-
-
-// Head-based instructions
-bool cHardware4Stack::Inst_SetHead()
-{
-  const int head_used = FindModifiedHead(HEAD_IP);
-  SetActiveHead(head_used);
-  return true;
-}
-
-bool cHardware4Stack::Inst_AdvanceHead()
-{
-  const int head_used = FindModifiedHead(HEAD_WRITE);
-  GetHead(head_used).Advance();
-  return true;
-}
-
-bool cHardware4Stack::Inst_JumpHead()
-{
-  const int head_used = FindModifiedHead(HEAD_IP);
-  GetHead(head_used).Jump( Register(REG_CX) );
-  return true;
-}
-
-bool cHardware4Stack::Inst_GetHead()
-{
-  const int head_used = FindModifiedHead(HEAD_IP);
-  Register(REG_CX) = GetHead(head_used).GetPosition();
-  return true;
-}
-
-bool cHardware4Stack::Inst_HeadDivideSex()  
-{ 
-  organism->GetPhenotype().SetDivideSex(true);
-  return Inst_HeadDivide(); 
-}
-
-bool cHardware4Stack::Inst_HeadDivideAsex()  
-{ 
-  organism->GetPhenotype().SetDivideSex(false);
-  return Inst_HeadDivide(); 
-}
-
-bool cHardware4Stack::Inst_HeadDivide1()  { return Inst_HeadDivideMut(1); }
-bool cHardware4Stack::Inst_HeadDivide2()  { return Inst_HeadDivideMut(2); }
-bool cHardware4Stack::Inst_HeadDivide3()  { return Inst_HeadDivideMut(3); }
-bool cHardware4Stack::Inst_HeadDivide4()  { return Inst_HeadDivideMut(4); }
-bool cHardware4Stack::Inst_HeadDivide5()  { return Inst_HeadDivideMut(5); }
-bool cHardware4Stack::Inst_HeadDivide6()  { return Inst_HeadDivideMut(6); }
-bool cHardware4Stack::Inst_HeadDivide7()  { return Inst_HeadDivideMut(7); }
-bool cHardware4Stack::Inst_HeadDivide8()  { return Inst_HeadDivideMut(8); }
-bool cHardware4Stack::Inst_HeadDivide9()  { return Inst_HeadDivideMut(9); }
-bool cHardware4Stack::Inst_HeadDivide10()  { return Inst_HeadDivideMut(10); }
-bool cHardware4Stack::Inst_HeadDivide16()  { return Inst_HeadDivideMut(16); }
-bool cHardware4Stack::Inst_HeadDivide32()  { return Inst_HeadDivideMut(32); }
-bool cHardware4Stack::Inst_HeadDivide50()  { return Inst_HeadDivideMut(50); }
-bool cHardware4Stack::Inst_HeadDivide100()  { return Inst_HeadDivideMut(100); }
-bool cHardware4Stack::Inst_HeadDivide500()  { return Inst_HeadDivideMut(500); }
-bool cHardware4Stack::Inst_HeadDivide1000()  { return Inst_HeadDivideMut(1000); }
-bool cHardware4Stack::Inst_HeadDivide5000()  { return Inst_HeadDivideMut(5000); }
-bool cHardware4Stack::Inst_HeadDivide10000()  { return Inst_HeadDivideMut(10000); }
-bool cHardware4Stack::Inst_HeadDivide50000()  { return Inst_HeadDivideMut(50000); }
-bool cHardware4Stack::Inst_HeadDivide0_5()  { return Inst_HeadDivideMut(0.5); }
-bool cHardware4Stack::Inst_HeadDivide0_1()  { return Inst_HeadDivideMut(0.1); }
-bool cHardware4Stack::Inst_HeadDivide0_05()  { return Inst_HeadDivideMut(0.05); }
-bool cHardware4Stack::Inst_HeadDivide0_01()  { return Inst_HeadDivideMut(0.01); }
-bool cHardware4Stack::Inst_HeadDivide0_001()  { return Inst_HeadDivideMut(0.001); }
-
-bool cHardware4Stack::HeadCopy_ErrorCorrect(double reduction)
-{
-  // For the moment, this cannot be nop-modified.
-  c4StackHead & read_head = GetHead(HEAD_READ);
-  c4StackHead & write_head = GetHead(HEAD_WRITE);
-  sCPUStats & cpu_stats = organism->CPUStats();
-
-  read_head.Adjust();
-  write_head.Adjust();
-
-  // Do mutations.
-  cInstruction read_inst = read_head.GetInst();
-  if ( g_random.P(organism->GetCopyMutProb() / reduction) ) {
-    read_inst = GetRandomInst();
-    cpu_stats.mut_stats.copy_mut_count++; 
-    write_head.FlagMutated() = true;
-    write_head.FlagCopyMut() = true;
-    //organism->GetPhenotype().IsMutated() = true;
-  }
-  ReadInst(read_inst.GetOp());
-
-  cpu_stats.mut_stats.copies_exec++;
-
-  write_head.SetInst(read_inst);
-  write_head.FlagCopied() = true;  // Set the copied flag...
-
-  read_head.Advance();
-  write_head.Advance();
-  return true;
-}
-
-bool cHardware4Stack::Inst_HeadCopy2()  { return HeadCopy_ErrorCorrect(2); }
-bool cHardware4Stack::Inst_HeadCopy3()  { return HeadCopy_ErrorCorrect(3); }
-bool cHardware4Stack::Inst_HeadCopy4()  { return HeadCopy_ErrorCorrect(4); }
-bool cHardware4Stack::Inst_HeadCopy5()  { return HeadCopy_ErrorCorrect(5); }
-bool cHardware4Stack::Inst_HeadCopy6()  { return HeadCopy_ErrorCorrect(6); }
-bool cHardware4Stack::Inst_HeadCopy7()  { return HeadCopy_ErrorCorrect(7); }
-bool cHardware4Stack::Inst_HeadCopy8()  { return HeadCopy_ErrorCorrect(8); }
-bool cHardware4Stack::Inst_HeadCopy9()  { return HeadCopy_ErrorCorrect(9); }
-bool cHardware4Stack::Inst_HeadCopy10() { return HeadCopy_ErrorCorrect(10); }
-
-bool cHardware4Stack::Inst_SetFlow()
-{
-  const int reg_used = FindModifiedRegister(REG_CX);
-  GetHead(HEAD_FLOW).Set(Register(reg_used), this);
-  return true; 
-}
-
-// Direct Matching Templates
-
-bool cHardware4Stack::Inst_DMJumpF()
-{
-  ReadLabel();
-
-  // If there is no label, jump BX steps.
-  if (GetLabel().GetSize() == 0) {
-    IP().Jump(Register(REG_BX));
-    return true;
-  }
-
-  // Otherwise, jump to the label.
-  c4StackHead jump_location(FindLabel(1));
-  if (jump_location.GetPosition() != -1) {
-    IP().Set(jump_location);
-    return true;
-  }
-
-  // If complement label was not found; record an error.
-  organism->Fault(FAULT_LOC_JUMP, FAULT_TYPE_ERROR,
-		  "dm-jump-f: no complement label");
-  return false;
-}
-
-//// Placebo insts ////
-bool cHardware4Stack::Inst_Skip()
-{
-  IP().Advance();
-  return true;
-}
 */
-
Index: avida/current/source/cpu/hardware_4stack.hh
diff -u avida/current/source/cpu/hardware_4stack.hh:1.5 avida/current/source/cpu/hardware_4stack.hh:1.5.2.1
--- avida/current/source/cpu/hardware_4stack.hh:1.5	Thu Jun  5 13:14:40 2003
+++ avida/current/source/cpu/hardware_4stack.hh	Mon Aug 11 15:01:26 2003
@@ -20,15 +20,17 @@
 #include "cpu_defs.hh"
 #include "label.hh"
 #include "head.hh"
+#include "../main/config.hh"
 
 class cInstSet;
 class cInstLibBase;
 class cOrganism;
 class cMutation;
+class cInjectGenotype;
 
 //new-style constant declarations - law 
-static const int NUM_LOCAL_STACKS = 2;
-static const int NUM_GLOBAL_STACKS = 2;
+static const int NUM_LOCAL_STACKS = 3;
+static const int NUM_GLOBAL_STACKS = 1;
 static const int NUM_STACKS = NUM_LOCAL_STACKS + NUM_GLOBAL_STACKS;
 static const int STACK_AX = 0;
 static const int STACK_BX = 1;
@@ -46,16 +48,21 @@
 struct cHardware4Stack_Thread {
 private:
   int id;
+
 public:
   c4StackHead heads[NUM_HEADS];
   UCHAR cur_head;
   cCPUStack local_stacks[NUM_LOCAL_STACKS];
 
-  UCHAR input_pointer;
+  int input_pointer;
+  bool advance_ip;         // Should the IP advance after this instruction?
   tBuffer<int> input_buf;
   tBuffer<int> output_buf;
   cCodeLabel read_label;
   cCodeLabel next_label;
+  // If this thread was spawned by Inject, this will point to the genotype 
+  // of the parasite running the thread.  Otherwise, it will be NULL.
+  cInjectGenotype * owner;
 public:
   cHardware4Stack_Thread(cHardwareBase * in_hardware=NULL, int _id=-1);
   cHardware4Stack_Thread(const cHardware4Stack_Thread & in_thread, int _id=-1);
@@ -96,7 +103,7 @@
   tArray<cCPUMemory> memory_array;          // Memory...
   //cCPUStack global_stack;     // A stack that all threads share.
   cCPUStack global_stacks[NUM_GLOBAL_STACKS];
-  int thread_time_used;
+  //int thread_time_used;
 
   tArray<cHardware4Stack_Thread> threads;
   int thread_id_chart;
@@ -104,7 +111,7 @@
 
   // Flags...
   bool mal_active;         // Has an allocate occured since last dividehe?
-  bool advance_ip;         // Should the IP advance after this instruction?
+  //bool advance_ip;         // Should the IP advance after this instruction?
 
   // Instruction costs...
 #ifdef INSTRUCTION_COSTS
@@ -112,6 +119,15 @@
   tArray<int> inst_ft_cost;
 #endif
 
+  // Thread slicing...
+
+    // Keeps track of the base thread slicing number for each possible number of threads
+  float slice_array[10]; //***HACK!  How do I do this right? -law
+                         //this wouldn't compile -> [cConfig::GetMaxCPUThreads()+1]***; 
+
+  // Keeps track of fractional instructions that carry over into next update
+  float inst_remainder; 
+
 public:
   cHardware4Stack(cOrganism * in_organism, cInstSet * in_inst_set);
   ~cHardware4Stack();
@@ -136,12 +152,15 @@
 
   // --------  Stack Manipulation...  --------
   inline void StackFlip();
-  inline int GetStack(int depth=0, int stack_id=-1) const;
+  inline int GetStack(int depth=0, int stack_id=-1, int in_thread=-1) const;
   inline void StackClear();
   inline void SwitchStack();
   cString GetActiveStackID(int stackID) const;
-  inline cCPUStack & Stack(int stack_id); //retrieves appropriate stack
+  //retrieves appropriate stack
+  inline cCPUStack & Stack(int stack_id); 
   inline const cCPUStack & Stack(int stack_id) const;
+  inline cCPUStack & Stack(int stack_id, int in_thread);
+  inline const cCPUStack & Stack(int stack_id, int in_thread) const;
 
   // --------  Tasks & IO  --------
   tBuffer<int> & GetInputBuffer() { return threads[cur_thread].input_buf; }
@@ -154,9 +173,16 @@
   { threads[cur_thread].cur_head = (UCHAR) new_head; }
 
   int GetCurHead() const { return threads[cur_thread].cur_head; }
+  
   const c4StackHead & GetHead(int head_id) const
-    { return threads[cur_thread].heads[head_id]; }
-  c4StackHead & GetHead(int head_id) { return threads[cur_thread].heads[head_id];}
+  { return threads[cur_thread].heads[head_id]; }
+  c4StackHead & GetHead(int head_id) 
+  { return threads[cur_thread].heads[head_id];}
+  
+  const c4StackHead & GetHead(int head_id, int thread) const
+  { return threads[thread].heads[head_id]; }
+  c4StackHead & GetHead(int head_id, int thread) 
+  { return threads[thread].heads[head_id];}
 
   const c4StackHead & GetActiveHead() const { return GetHead(GetCurHead()); }
   c4StackHead & GetActiveHead() { return GetHead(GetCurHead()); }
@@ -167,6 +193,15 @@
     { return threads[cur_thread].heads[HEAD_IP]; }
   inline c4StackHead & IP() { return threads[cur_thread].heads[HEAD_IP]; }
 
+  inline const c4StackHead & IP(int thread) const
+  { return threads[thread].heads[HEAD_IP]; }
+  inline c4StackHead & IP(int thread) 
+  { return threads[thread].heads[HEAD_IP]; }
+
+
+  inline const bool & AdvanceIP() const
+    { return threads[cur_thread].advance_ip; }
+  inline bool & AdvanceIP() { return threads[cur_thread].advance_ip; }
 
   // --------  Label Manipulation  -------
   void ReadLabel(int max_size=MAX_LABEL_SIZE);
@@ -194,13 +229,15 @@
   inline void PrevThread(); // Shift the current thread in use.
   inline void NextThread();
   inline void SetThread(int value);
+  inline cInjectGenotype * GetThreadOwner(); 
+  inline void SetThreadOwner(cInjectGenotype * in_genotype);
 
   // --------  Tests  --------
 
   int TestParasite() const;
 
   // --------  Accessors  --------
-  int GetThreadTimeUsed() const { return thread_time_used; }
+  //int GetThreadTimeUsed() const { return thread_time_used; }
   int GetNumThreads() const     { return threads.GetSize(); }
   int GetCurThread() const      { return cur_thread; }
   int GetCurThreadID() const    { return threads[cur_thread].GetID(); }
@@ -221,12 +258,13 @@
   c4StackHead FindFullLabel(const cCodeLabel & in_label);
 
   int GetType() const { return HARDWARE_TYPE_CPU_4STACK; }
-  int Inject(const cCodeLabel & in_label, const cGenome & injection);
-  int InjectThread(const cCodeLabel & in_label, const cGenome & injection);
-  void InjectCode(const cGenome & injection, const int line_num);
-  void InjectCodeThread(const cGenome & injection, const int line_num);
+  bool InjectParasite(double mut_multiplier);
+  bool InjectHost(const cCodeLabel & in_label, const cGenome & injection);
+  int InjectThread(const cCodeLabel &, const cGenome &) { return -1; }
   void Mutate(const int mut_point);
   int PointMutate(const double mut_rate);
+  int FindFirstEmpty();
+  bool isEmpty(int mem_space_used);
 
   bool TriggerMutations(int trigger);
   bool TriggerMutations(int trigger, c4StackHead & cur_head);
@@ -265,6 +303,7 @@
   bool Divide_Main(const int mem_space_used, double mut_multiplier=1);
   bool Divide_CheckViable(const int parent_size, const int child_size, const int mem_space);
   void Divide_DoMutations(double mut_multiplier=1);
+  void Inject_DoMutations(double mut_multiplier, cCPUMemory & injected_code);
   void Divide_TestFitnessMeasures();
 
   bool HeadCopy_ErrorCorrect(double reduction);
@@ -335,212 +374,17 @@
   bool Inst_Mod();
   //35 
   bool Inst_KillThread();
-
-  /*
-  // Flow Control
-  bool Inst_If0();
-
-  bool Inst_IfNot0();
- 
-  bool Inst_IfGr0();
-  
-  bool Inst_IfGrEqu0();
-  bool Inst_IfGrEqu();
-  bool Inst_IfLess0();
- 
-  bool Inst_IfLsEqu0();
-  bool Inst_IfLsEqu();
-  bool Inst_IfBit1();
-  bool Inst_IfANotEqB();
-  bool Inst_IfBNotEqC();
-  bool Inst_IfANotEqC();
-
-  bool Inst_JumpF();
-  bool Inst_JumpB();
-  bool Inst_JumpP();
-  bool Inst_JumpSelf();
-  bool Inst_Call();
-  bool Inst_Return();
-
-  // Stack and Register Operations
-  bool Inst_Pop();
-  bool Inst_Push();
-
- 
-
-  bool Inst_PopA();
-  bool Inst_PopB();
-  bool Inst_PopC();
-
-
-  bool Inst_SwitchStack();
-  bool Inst_FlipStack();
-  bool Inst_Swap();
-  bool Inst_SwapAB();
-  bool Inst_SwapBC();
-  bool Inst_SwapAC();
-  bool Inst_CopyStack();
-  bool Inst_CopyRegAB();
-  bool Inst_CopyRegAC();
-  bool Inst_CopyRegBA();
-  bool Inst_CopyRegBC();
-  bool Inst_CopyRegCA();
-  bool Inst_CopyRegCB();
-  bool Inst_Reset();
-
-  // Single-Argument Math
-
-  bool Inst_Bit1();
-  bool Inst_SetNum();
-
-  bool Inst_Zero();
-  bool Inst_Not();
-  bool Inst_Neg();
-  bool Inst_Square();
-  bool Inst_Sqrt();
-  bool Inst_Log();
-  bool Inst_Log10();
-  bool Inst_Minus18();
-
-  // Double Argument Math
-
-  bool Inst_Nor();
-  bool Inst_And();
-  bool Inst_Order();
-  bool Inst_Xor();
-
-  // Biological
-  bool Inst_Copy();
-  bool Inst_ReadInst();
-  bool Inst_WriteInst();
-  bool Inst_StackReadInst();
-  bool Inst_StackWriteInst();
-  bool Inst_Compare();
-  bool Inst_IfNCpy();
-  bool Inst_Allocate();
-  bool Inst_DivideOld();
-  bool Inst_CAlloc();
-  bool Inst_CDivide();
-
+  //36
+  bool Inst_IO();
+  //37
   bool Inst_Inject();
+  
+  /*
   bool Inst_InjectRand();
   bool Inst_InjectThread();
   bool Inst_Repro();
-
-  // I/O and Sensory
-  bool Inst_TaskGet();
-  bool Inst_TaskStackGet();
-  bool Inst_TaskStackLoad();
-  bool Inst_TaskPut();
-  bool Inst_TaskIO();
-  bool Inst_SearchF();
-  bool Inst_SearchB();
-  bool Inst_MemSize();
-
-  // Environment
-
-  bool Inst_RotateL();
-  bool Inst_RotateR();
-  bool Inst_SetCopyMut();
-  bool Inst_ModCopyMut();
-
-  // Multi-threading...
-
-
-  bool Inst_ThreadID();
-
-  // Head-based instructions...
-
-  bool Inst_SetHead();
-  bool Inst_AdvanceHead();
-
-  bool Inst_JumpHead();
-  bool Inst_GetHead();
- 
-  bool Inst_SetFlow();
-
-  bool Inst_HeadCopy2();
-  bool Inst_HeadCopy3();
-  bool Inst_HeadCopy4();
-  bool Inst_HeadCopy5();
-  bool Inst_HeadCopy6();
-  bool Inst_HeadCopy7();
-  bool Inst_HeadCopy8();
-  bool Inst_HeadCopy9();
-  bool Inst_HeadCopy10();
-
-  bool Inst_HeadDivideSex();
-  bool Inst_HeadDivideAsex();
-
-  bool Inst_HeadDivide1();
-  bool Inst_HeadDivide2();
-  bool Inst_HeadDivide3();
-  bool Inst_HeadDivide4();
-  bool Inst_HeadDivide5();
-  bool Inst_HeadDivide6();
-  bool Inst_HeadDivide7();
-  bool Inst_HeadDivide8();
-  bool Inst_HeadDivide9();
-  bool Inst_HeadDivide10();
-  bool Inst_HeadDivide16();
-  bool Inst_HeadDivide32();
-  bool Inst_HeadDivide50();
-  bool Inst_HeadDivide100();
-  bool Inst_HeadDivide500();
-  bool Inst_HeadDivide1000();
-  bool Inst_HeadDivide5000();
-  bool Inst_HeadDivide10000();
-  bool Inst_HeadDivide50000();
-  bool Inst_HeadDivide0_5();
-  bool Inst_HeadDivide0_1();
-  bool Inst_HeadDivide0_05();
-  bool Inst_HeadDivide0_01();
-  bool Inst_HeadDivide0_001();
-
-
-  // Direct Matching Templates
-
-  bool Inst_DMJumpF();
-  bool Inst_DMJumpB();
-  bool Inst_DMCall();
-  bool Inst_DMSearchF();
-  bool Inst_DMSearchB();
-
-  // Relative Addressed Jumps
-
-  bool Inst_REJumpF();
-  bool Inst_REJumpB();
-
-  // Absoulte Addressed Jumps
-
-  bool Inst_ABSJump();
-
-
-  // Biologically inspired reproduction
-  bool Inst_BCAlloc();
-  bool Inst_BCopy();
-  bool Inst_BDivide();
-private:
-  bool Inst_BCopy_Main(double mut_prob); // Internal called by all BCopy's
-public:
-  // Bio Error Correction
-  bool Inst_BCopyDiv2();
-  bool Inst_BCopyDiv3();
-  bool Inst_BCopyDiv4();
-  bool Inst_BCopyDiv5();
-  bool Inst_BCopyDiv6();
-  bool Inst_BCopyDiv7();
-  bool Inst_BCopyDiv8();
-  bool Inst_BCopyDiv9();
-  bool Inst_BCopyDiv10();
-  bool Inst_BCopyPow2();
-  bool Inst_BIfNotCopy();
-  bool Inst_BIfCopy();
-
-
-  //// Placebo ////
-  bool Inst_Skip();
   */
+ 
 };
 
 
@@ -588,8 +432,18 @@
 
 inline void cHardware4Stack::SetThread(int value)
 {
-     if (value>=0 && value < GetNumThreads())
-          cur_thread=value;
+  if (value>=0 && value < GetNumThreads())
+    cur_thread=value;
+}
+
+inline cInjectGenotype * cHardware4Stack::GetThreadOwner() 
+{ 
+  return threads[cur_thread].owner; 
+}
+
+inline void cHardware4Stack::SetThreadOwner(cInjectGenotype * in_genotype)
+{ 
+  threads[cur_thread].owner = in_genotype; 
 }
 
 /*inline void cHardware4Stack::StackFlip()
@@ -601,17 +455,14 @@
   }
 }*/
 
-inline int cHardware4Stack::GetStack(int depth, int stack_id) const
+inline int cHardware4Stack::GetStack(int depth, int stack_id, int in_thread) const
 {
-  //int value = 0;
-
   if(stack_id<0 || stack_id>NUM_STACKS) stack_id=0;
-
-  int value = Stack(stack_id).Get(depth);
-  return value; //Stack(stack_id).Get(depth);
-  //threads[cur_thread].Stack(stack_id).Get(depth);
-
-  //return value;
+  
+  if(in_thread==-1)
+    in_thread=cur_thread;
+  
+  return Stack(stack_id, in_thread).Get(depth);
 }
 
 //inline void cHardware4Stack::StackClear()
@@ -653,4 +504,31 @@
   else
     return global_stacks[stack_id % NUM_LOCAL_STACKS];
 }
+
+inline cCPUStack& cHardware4Stack::Stack(int stack_id, int in_thread) 
+{
+  if(stack_id >= NUM_STACKS)
+      stack_id=0;
+  if(in_thread >= threads.GetSize())
+      in_thread=cur_thread;
+
+  if(stack_id < NUM_LOCAL_STACKS)
+    return threads[in_thread].local_stacks[stack_id];
+  else
+    return global_stacks[stack_id % NUM_LOCAL_STACKS];
+}
+
+inline const cCPUStack& cHardware4Stack::Stack(int stack_id, int in_thread) const 
+{
+  if(stack_id >= NUM_STACKS)
+      stack_id=0;
+  if(in_thread >= threads.GetSize())
+      in_thread=cur_thread;
+
+  if(stack_id < NUM_LOCAL_STACKS)
+    return threads[in_thread].local_stacks[stack_id];
+  else
+    return global_stacks[stack_id % NUM_LOCAL_STACKS];
+}
+
 #endif
Index: avida/current/source/cpu/hardware_base.hh
diff -u avida/current/source/cpu/hardware_base.hh:1.18 avida/current/source/cpu/hardware_base.hh:1.18.2.1
--- avida/current/source/cpu/hardware_base.hh:1.18	Thu Jun  5 13:14:40 2003
+++ avida/current/source/cpu/hardware_base.hh	Mon Aug 11 15:01:26 2003
@@ -52,7 +52,7 @@
 
   // --------  Other Virtual Tools --------
   virtual int GetType() const = 0;
-  virtual int Inject(const cCodeLabel & in_label,
+  virtual bool InjectHost(const cCodeLabel & in_label,
 		      const cGenome & injection) = 0;
   virtual int InjectThread(const cCodeLabel & in_label,
 			   const cGenome & injection) = 0;
Index: avida/current/source/cpu/hardware_cpu.cc
diff -u avida/current/source/cpu/hardware_cpu.cc:1.52 avida/current/source/cpu/hardware_cpu.cc:1.52.2.1
--- avida/current/source/cpu/hardware_cpu.cc:1.52	Mon Jun 30 15:00:57 2003
+++ avida/current/source/cpu/hardware_cpu.cc	Mon Aug 11 15:01:26 2003
@@ -1090,22 +1090,22 @@
 }
 
 
-int cHardwareCPU::Inject(const cCodeLabel & in_label, const cGenome & injection)
+bool cHardwareCPU::InjectHost(const cCodeLabel & in_label, const cGenome & injection)
 {
   // Make sure the genome will be below max size after injection.
 
   const int new_size = injection.GetSize() + GetMemory().GetSize();
-  if (new_size > MAX_CREATURE_SIZE) return 1; // (inject fails)
+  if (new_size > MAX_CREATURE_SIZE) return false; // (inject fails)
 
   const int inject_line = FindFullLabel(in_label).GetPosition();
 
   // Abort if no compliment is found.
-  if (inject_line == -1) return 2; // (inject fails)
+  if (inject_line == -1) return false; // (inject fails)
 
   // Inject the code!
   InjectCode(injection, inject_line+1);
 
-  return 0; // (inject succeeds!)
+  return true; // (inject succeeds!)
 }
 
 int cHardwareCPU::InjectThread(const cCodeLabel & in_label, const cGenome & injection)
@@ -2763,8 +2763,8 @@
   // Search for the label in the host...
   GetLabel().Rotate(1, NUM_NOPS);
 
-  const int inject_signal =
-    host_organism->GetHardware().Inject(GetLabel(), inject_code);
+  const bool inject_signal =
+    host_organism->GetHardware().InjectHost(GetLabel(), inject_code);
   if (inject_signal == 1) {
     Fault(FAULT_LOC_INJECT, FAULT_TYPE_WARNING, "inject: host too large.");
     return false; // Inject failed.
@@ -2777,7 +2777,7 @@
   // Set the relevent flags.
   organism->GetPhenotype().IsModifier() = true;
 
-  return true;
+  return inject_signal;
 }
 
 
@@ -2855,7 +2855,7 @@
 bool cHardwareCPU::Inst_TaskGet()
 {
   const int reg_used = FindModifiedRegister(REG_CX);
-  const int value = organism->GetInput();
+  const int value = organism->GetInputAt(threads[GetCurThread()].input_pointer);
   Register(reg_used) = value;
   DoInput(value);
   return true;
@@ -2863,7 +2863,7 @@
 
 bool cHardwareCPU::Inst_TaskStackGet()
 {
-  const int value = organism->GetInput();
+  const int value = organism->GetInputAt(threads[GetCurThread()].input_pointer);
   StackPush(value);
   DoInput(value);
   return true;
@@ -2871,7 +2871,8 @@
 
 bool cHardwareCPU::Inst_TaskStackLoad()
 {
-  for (int i = 0; i < IO_SIZE; i++) StackPush( organism->GetInput() );
+  for (int i = 0; i < IO_SIZE; i++) 
+    StackPush( organism->GetInputAt(threads[GetCurThread()].input_pointer) );
   return true;
 }
 
@@ -2893,7 +2894,7 @@
   DoOutput(value_out);  // Check for tasks compleated.
 
   // Do the "get" component
-  const int value_in = organism->GetInput();
+  const int value_in = organism->GetInputAt(threads[GetCurThread()].input_pointer);
   Register(reg_used) = value_in;
   DoInput(value_in);
   return true;
Index: avida/current/source/cpu/hardware_cpu.hh
diff -u avida/current/source/cpu/hardware_cpu.hh:1.31 avida/current/source/cpu/hardware_cpu.hh:1.31.2.1
--- avida/current/source/cpu/hardware_cpu.hh:1.31	Thu Jun  5 13:14:40 2003
+++ avida/current/source/cpu/hardware_cpu.hh	Mon Aug 11 15:01:27 2003
@@ -44,7 +44,7 @@
   UCHAR cur_stack;              // 0 = local stack, 1 = global stack.
   UCHAR cur_head;
 
-  UCHAR input_pointer;
+  int input_pointer;
   tBuffer<int> input_buf;
   tBuffer<int> output_buf;
   cCodeLabel read_label;
@@ -216,7 +216,7 @@
   cCPUHead FindFullLabel(const cCodeLabel & in_label);
 
   int GetType() const { return HARDWARE_TYPE_CPU_ORIGINAL; }
-  int Inject(const cCodeLabel & in_label, const cGenome & injection);
+  bool InjectHost(const cCodeLabel & in_label, const cGenome & injection);
   int InjectThread(const cCodeLabel & in_label, const cGenome & injection);
   void InjectCode(const cGenome & injection, const int line_num);
   void InjectCodeThread(const cGenome & injection, const int line_num);
Index: avida/current/source/cpu/head.cc
diff -u avida/current/source/cpu/head.cc:1.22 avida/current/source/cpu/head.cc:1.22.2.1
--- avida/current/source/cpu/head.cc:1.22	Sun Jun  8 19:36:08 2003
+++ avida/current/source/cpu/head.cc	Mon Aug 11 15:01:27 2003
@@ -508,15 +508,15 @@
   }
 }
 
-void c4StackHead::Reset(cHardwareBase * new_hardware)
+void c4StackHead::Reset(int in_mem_space, cHardwareBase * new_hardware)
 {
   if (new_hardware) main_hardware = new_hardware;
   cur_hardware  = new_hardware;
   position = 0;
-  mem_space = 0;
+  mem_space = in_mem_space;
 }
 
-void c4StackHead::Set(int new_pos, cHardwareBase * in_hardware, int in_mem_space)
+void c4StackHead::Set(int new_pos, int in_mem_space, cHardwareBase * in_hardware)
 {
   position = new_pos;
   if (in_hardware) cur_hardware = in_hardware;
Index: avida/current/source/cpu/head.hh
diff -u avida/current/source/cpu/head.hh:1.11 avida/current/source/cpu/head.hh:1.11.2.1
--- avida/current/source/cpu/head.hh:1.11	Thu Jun  5 13:14:40 2003
+++ avida/current/source/cpu/head.hh	Mon Aug 11 15:01:27 2003
@@ -125,8 +125,8 @@
   c4StackHead(const c4StackHead & in_cpu_head);
 
   void Adjust();
-  void Reset(cHardwareBase * new_hardware = NULL);
-  void Set(int new_pos, cHardwareBase * in_hardware = NULL, int in_mem_space = 0);
+  void Reset(int in_mem_space=0, cHardwareBase * new_hardware = NULL);
+  void Set(int new_pos, int in_mem_space = 0, cHardwareBase * in_hardware = NULL);
   void Set(const c4StackHead & in_head);
   void LoopJump(int jump);
   const cCPUMemory & GetMemory() const;
Index: avida/current/source/cpu/test_cpu.cc
diff -u avida/current/source/cpu/test_cpu.cc:1.42 avida/current/source/cpu/test_cpu.cc:1.42.6.1
--- avida/current/source/cpu/test_cpu.cc:1.42	Sun May 18 11:59:24 2003
+++ avida/current/source/cpu/test_cpu.cc	Mon Aug 11 15:01:27 2003
@@ -396,6 +396,12 @@
   return input_array[cur_input++];
 }
 
+int cTestCPU::GetInputAt(int & input_pointer)
+{
+  if (input_pointer >= input_array.GetSize()) input_pointer = 0;
+  return input_array[input_pointer++];
+}
+
 const tArray<double> & cTestCPU::GetResources()
 {
   assert(resource_count != NULL);
Index: avida/current/source/cpu/test_cpu.hh
diff -u avida/current/source/cpu/test_cpu.hh:1.31 avida/current/source/cpu/test_cpu.hh:1.31.6.1
--- avida/current/source/cpu/test_cpu.hh:1.31	Sat May 17 14:23:25 2003
+++ avida/current/source/cpu/test_cpu.hh	Mon Aug 11 15:01:27 2003
@@ -134,6 +134,7 @@
   static cInstSet * GetInstSet() { return inst_set; }
   static cEnvironment * GetEnvironment() { return environment; }
   static int GetInput();
+  static int GetInputAt(int & input_pointer);
   static const tArray<double> & GetResources();
   static void UpdateResources(const tArray<double> & res_change);
 };
Index: avida/current/source/cpu/test_util.cc
diff -u avida/current/source/cpu/test_util.cc:1.7 avida/current/source/cpu/test_util.cc:1.7.6.1
--- avida/current/source/cpu/test_util.cc:1.7	Sat May 17 14:23:25 2003
+++ avida/current/source/cpu/test_util.cc	Mon Aug 11 15:01:28 2003
@@ -12,6 +12,7 @@
 
 #include "../main/genome.hh"
 #include "../main/genotype.hh"
+#include "../main/inject_genotype.hh"
 #include "hardware_method.hh"
 #include "../main/inst_util.hh"
 #include "../main/organism.hh"
@@ -21,10 +22,8 @@
 #include "hardware_base.hh"
 #include "test_cpu.hh"
 
-
 using namespace std;
 
-
 void cTestUtil::PrintGenome(const cGenome & genome, cString filename,
 			    cGenotype * genotype, int update_out)
 {
@@ -121,6 +120,108 @@
   }
   fp << endl; // Skip line
 
+  // Display the genome
+  const cInstSet & inst_set =
+    test_info.GetTestOrganism()->GetHardware().GetInstSet();
+  cInstUtil::SaveGenome(fp, inst_set, genome);
+}
+
+void cTestUtil::PrintGenome(cInjectGenotype * inject_genotype, 
+			    const cGenome & genome, cString filename, int update_out)
+{
+  if (filename == "") filename.Set("p%03d-unnamed", genome.GetSize());
+
+  // Build the test info for printing.
+  cCPUTestInfo test_info;
+  test_info.TestThreads();
+  cTestCPU::TestGenome(test_info, genome);
+
+  // Open the file...
+
+  ofstream fp(filename());
+
+  // @CAO Fix!!!!!!
+  if( fp.good() == false ) {
+    cerr << "Unable to open output file '" <<  filename() << "'" <<
+    endl;
+    return;
+  }
+
+  // Print the useful info at the top...
+
+  fp << "# Filename........: " << filename << endl;
+
+  if (update_out >= 0) fp << "# Update Output...: " << update_out <<
+  endl;
+  else fp << "# Update Output...: N/A" << endl;
+
+  //fp << "# Is Viable.......: " << test_info.IsViable()
+  //<< endl
+  //   << "# Repro Cycle Size: " << test_info.GetMaxCycle()
+  //   << endl
+  //   << "# Depth to Viable.: " << test_info.GetDepthFound()
+  //   << endl;
+
+  if (inject_genotype != NULL) {
+    fp << "# Update Created..: " << inject_genotype->GetUpdateBorn()     <<
+       endl
+       << "# Genotype ID.....: " << inject_genotype->GetID()             <<
+       endl
+       << "# Parent Gen ID...: " << inject_genotype->GetParentID()       <<
+       endl
+       << "# Tree Depth......: " << inject_genotype->GetDepth()          <<
+       endl
+      //<< "# Parent Distance.: " << inject_genotype->GetParentDistance() <<
+      // endl
+      ;
+  }
+  fp << endl;
+
+  //const int num_levels = test_info.GetMaxDepth() + 1;
+  /*for (int j = 0; j < num_levels; j++) {
+    fp << "# Generation: " << j << endl;
+    cOrganism * organism = test_info.GetTestOrganism(j);
+    assert(organism != NULL);
+    cPhenotype & phenotype = organism->GetPhenotype();
+
+    fp << "# Merit...........: "
+       << setw(12) << setfill(' ') << phenotype.GetMerit() << endl;
+    fp << "# Gestation Time..: "
+       << setw(12) << setfill(' ') << phenotype.GetGestationTime() << endl;
+    fp << "# Fitness.........: "
+       << setw(12) << setfill(' ') << phenotype.GetFitness() << endl;
+    fp << "# Errors..........: "
+       << setw(12) << setfill(' ') << phenotype.GetLastNumErrors() << endl;
+    fp << "# Genome Size.....: "
+       << setw(12) << setfill(' ') << organism->GetGenome().GetSize() << endl;
+    fp << "# Copied Size.....: "
+       << setw(12) << setfill(' ') << phenotype.GetCopiedSize() << endl;
+    fp << "# Executed Size...: "
+       << setw(12) << setfill(' ') << phenotype.GetExecutedSize() << endl;
+
+    fp << "# Offspring.......: ";
+    if (phenotype.GetNumDivides() == 0)
+      fp << setw(12) << setfill(' ') << "NONE";
+    else if (phenotype.CopyTrue() == true)
+      fp << setw(12) << setfill(' ') << "SELF";
+    else if (test_info.GetCycleTo() != -1)
+      fp << setw(12) << setfill(' ') << test_info.GetCycleTo();
+    else
+      fp << setw(12) << setfill(' ') << (j+1);
+    fp << endl;
+
+    fp << endl;     // Skip line
+    }
+  
+  // Display the tasks performed...
+  cPhenotype & phenotype = test_info.GetTestOrganism()->GetPhenotype();
+  for (int i = 0; i < phenotype.GetEnvironment().GetTaskLib().GetSize(); i++) {
+    fp << "# "<< phenotype.GetEnvironment().GetTaskLib().GetTask(i).GetName()
+       << "\t" << phenotype.GetLastTaskCount()[i]
+       << endl;
+  }
+  fp << endl; // Skip line
+  */
   // Display the genome
   const cInstSet & inst_set =
     test_info.GetTestOrganism()->GetHardware().GetInstSet();
Index: avida/current/source/cpu/test_util.hh
diff -u avida/current/source/cpu/test_util.hh:1.2 avida/current/source/cpu/test_util.hh:1.2.8.1
--- avida/current/source/cpu/test_util.hh:1.2	Wed Dec  5 22:11:40 2001
+++ avida/current/source/cpu/test_util.hh	Mon Aug 11 15:01:28 2003
@@ -17,11 +17,14 @@
 
 class cGenome;
 class cGenotype;
+class cInjectGenotype;
 
 class cTestUtil {
 public:
   static void PrintGenome(const cGenome & genome, cString filename="",
 			  cGenotype * genotype=NULL, int update_out=-1);
+  static void PrintGenome(cInjectGenotype * genotype, const cGenome & genome, 
+			  cString filename="", int update_out=-1);
 };
 
 #endif
Index: avida/current/source/event/cPopulation.events
diff -u avida/current/source/event/cPopulation.events:1.40 avida/current/source/event/cPopulation.events:1.40.4.1
--- avida/current/source/event/cPopulation.events:1.40	Tue May 20 14:07:00 2003
+++ avida/current/source/event/cPopulation.events	Mon Aug 11 15:01:28 2003
@@ -77,8 +77,6 @@
   cAvidaDriver_Base::main_driver->SetDone();
 }
 
-
-
 echo
 :descr:
 /**
@@ -428,7 +426,36 @@
 cGenotype * dom = population->GetGenebank().GetBestGenotype();
 cString filename(in_filename);
 if (filename == "") filename.Set("genebank/%s", dom->GetName()());
-cTestUtil::PrintGenome(dom->GetGenome(), filename, dom, population->GetUpdate());
+cTestUtil::PrintGenome(dom->GetGenome(), filename, dom, population->GetUpdate()); 
+
+parasite_debug
+:descr:
+//midget
+:args:
+cString in_filename ""
+:body:
+population->ParasiteDebug();
+
+print_dom_parasite
+:descr:
+/**
+* Write the currently dominant injected genotype to disk.
+*
+* Parameters:
+* filename (string)
+*   The name under which the genotype should be saved. If no
+*   filename is given, the genotype is saved into the directory
+*   genebank, under the name that the genebank has associated with
+*   this genotype.
+**/
+:args:
+cString in_filename ""
+:body:
+cInjectGenotype * dom = population->GetInjectGenebank().GetBestInjectGenotype();
+if (dom!=NULL) {
+cString filename(in_filename);
+if (filename == "") filename.Set("genebank/%s", dom->GetName()());
+cTestUtil::PrintGenome(dom, dom->GetGenome(), filename, population->GetUpdate()); }
 
 print_genotype_map
 :descr:
@@ -558,6 +585,25 @@
 ofstream fp(filename());
 population->GetGenebank().DumpDetailedSummary(fp);
 
+detail_parasite_pop
+:descr:
+/**
+* Like dump_pop, but more detailed data is written out.
+*
+* Parameters:
+* filename (string) default: "detail_pop.<update>"
+*   The name of the file into which the population dump should be written.
+**/
+:args:
+cString fname ""
+:body:
+cString filename;
+if( fname == "" ){
+  filename.Set("detail_parasite_pop.%d", population->GetUpdate());
+}
+//ofstream fp(filename());
+population->GetInjectGenebank().DumpDetailedSummary(filename, population->GetUpdate());
+
 dump_historic_pop
 :descr:
 /**
@@ -783,6 +829,111 @@
    cInstUtil::RandomGenome(length, population->GetEnvironment().GetInstSet());
 population->Inject(genome, cell_id, merit, lineage_label, neutral_metric);
 
+inject_range_parasite
+:descr:
+/**
+* Injects identical organisms into a range of cells of the population.
+*
+* Parameters:
+* filename (string)
+*   The filename of the genotype to load. If this is left empty, or the keyword
+*   "START_CREATURE" is given, than the genotype specified in the genesis
+*   file under "START_CREATURE" is used.
+* start_cell (int)
+*   First cell to inject into.
+* stop_cell (int)
+*   First cell *not* to inject into.
+* merit (double) default: -1
+*   The initial merit of the organism. If set to -1, this is ignored.
+* lineage label (integer) default: 0
+*   An integer that marks all descendants of this organism.
+* neutral metric (double) default: 0
+*   A double value that randomly drifts over time.
+*
+* Example:
+*   inject_range creature.gen 0 10
+*
+* Will inject 10 organisms into cells 0 through 9.
+**/
+:args:
+cString fname_parasite "organism.parasite"
+int start_cell 0
+int end_cell -1
+double merit -1
+int lineage_label 0
+double neutral_metric 0
+int mem_space 2
+:body:
+if (fname_parasite == "START_CREATURE") fname_parasite=cConfig::GetStartCreature();
+if (end_cell == -1) end_cell = start_cell + 1;
+if (start_cell < 0 ||
+    end_cell > population->GetSize() ||
+    start_cell >= end_cell) {
+  cout << "Warning: inject_range has invalid range!";
+}
+else {
+  cGenome genome_parasite =
+     cInstUtil::LoadGenome(fname_parasite, population->GetEnvironment().GetInstSet());
+  for (int i = start_cell; i < end_cell; i++) {
+    population->Inject(genome_parasite, i, merit, lineage_label, neutral_metric, mem_space);
+  }
+  population->SetSyncEvents(true);
+}
+
+inject_range_pair
+:descr:
+/**
+* Injects identical organisms into a range of cells of the population.
+*
+* Parameters:
+* filename (string)
+*   The filename of the genotype to load. If this is left empty, or the keyword
+*   "START_CREATURE" is given, than the genotype specified in the genesis
+*   file under "START_CREATURE" is used.
+* start_cell (int)
+*   First cell to inject into.
+* stop_cell (int)
+*   First cell *not* to inject into.
+* merit (double) default: -1
+*   The initial merit of the organism. If set to -1, this is ignored.
+* lineage label (integer) default: 0
+*   An integer that marks all descendants of this organism.
+* neutral metric (double) default: 0
+*   A double value that randomly drifts over time.
+*
+* Example:
+*   inject_range creature.gen 0 10
+*
+* Will inject 10 organisms into cells 0 through 9.
+**/
+:args:
+cString fname "START_CREATURE"
+cString fname_parasite "organism.parasite"
+int start_cell 0
+int end_cell -1
+double merit -1
+int lineage_label 0
+double neutral_metric 0
+int mem_space 2
+:body:
+if (fname == "START_CREATURE") fname=cConfig::GetStartCreature();
+if (end_cell == -1) end_cell = start_cell + 1;
+if (start_cell < 0 ||
+    end_cell > population->GetSize() ||
+    start_cell >= end_cell) {
+  cout << "Warning: inject_range has invalid range!";
+}
+else {
+  cGenome genome =
+     cInstUtil::LoadGenome(fname, population->GetEnvironment().GetInstSet());
+  cGenome genome_parasite =
+     cInstUtil::LoadGenome(fname_parasite, population->GetEnvironment().GetInstSet());
+  for (int i = start_cell; i < end_cell; i++) {
+    population->Inject(genome, i, merit, lineage_label, neutral_metric);
+    population->Inject(genome_parasite, i, merit, lineage_label, neutral_metric, mem_space);
+  }
+  population->SetSyncEvents(true);
+}
 
 ################ MUTATION RATES ###############
 zero_muts
Index: avida/current/source/event/cPopulation_construct_event_auto.ci
diff -u avida/current/source/event/cPopulation_construct_event_auto.ci:1.2 avida/current/source/event/cPopulation_construct_event_auto.ci:1.2.2.1
--- avida/current/source/event/cPopulation_construct_event_auto.ci:1.2	Wed Jun  4 11:34:46 2003
+++ avida/current/source/event/cPopulation_construct_event_auto.ci	Mon Aug 11 15:01:28 2003
@@ -85,6 +85,12 @@
     case cPopulationEventFactory::EVENT_print_dom :
       event = new cPopulationEventprint_dom(arg_list);
       break;
+    case cPopulationEventFactory::EVENT_parasite_debug :
+      event = new cPopulationEventparasite_debug(arg_list);
+      break;
+    case cPopulationEventFactory::EVENT_print_dom_parasite :
+      event = new cPopulationEventprint_dom_parasite(arg_list);
+      break;
     case cPopulationEventFactory::EVENT_print_genotype_map :
       event = new cPopulationEventprint_genotype_map(arg_list);
       break;
@@ -109,6 +115,9 @@
     case cPopulationEventFactory::EVENT_detail_pop :
       event = new cPopulationEventdetail_pop(arg_list);
       break;
+    case cPopulationEventFactory::EVENT_detail_parasite_pop :
+      event = new cPopulationEventdetail_parasite_pop(arg_list);
+      break;
     case cPopulationEventFactory::EVENT_dump_historic_pop :
       event = new cPopulationEventdump_historic_pop(arg_list);
       break;
@@ -129,6 +138,12 @@
       break;
     case cPopulationEventFactory::EVENT_inject_random :
       event = new cPopulationEventinject_random(arg_list);
+      break;
+    case cPopulationEventFactory::EVENT_inject_range_parasite :
+      event = new cPopulationEventinject_range_parasite(arg_list);
+      break;
+    case cPopulationEventFactory::EVENT_inject_range_pair :
+      event = new cPopulationEventinject_range_pair(arg_list);
       break;
     case cPopulationEventFactory::EVENT_zero_muts :
       event = new cPopulationEventzero_muts(arg_list);
Index: avida/current/source/event/cPopulation_descr.ci
diff -u avida/current/source/event/cPopulation_descr.ci:1.2 avida/current/source/event/cPopulation_descr.ci:1.2.2.1
--- avida/current/source/event/cPopulation_descr.ci:1.2	Wed Jun  4 11:34:46 2003
+++ avida/current/source/event/cPopulation_descr.ci	Mon Aug 11 15:01:28 2003
@@ -28,6 +28,8 @@
   cEventEntry( "print_lineage_totals", "\n" ),
   cEventEntry( "print_lineage_counts", "\n" ),
   cEventEntry( "print_dom", "Write the currently dominant genotype to disk.\n\nParameters:\nfilename (string)\n  The name under which the genotype should be saved. If no\n  filename is given, the genotype is saved into the directory\n  genebank, under the name that the genebank has associated with\n  this genotype.\n" ),
+  cEventEntry( "parasite_debug", "\n" ),
+  cEventEntry( "print_dom_parasite", "Write the currently dominant injected genotype to disk.\n\nParameters:\nfilename (string)\n  The name under which the genotype should be saved. If no\n  filename is given, the genotype is saved into the directory\n  genebank, under the name that the genebank has associated with\n  this genotype.\n" ),
   cEventEntry( "print_genotype_map", "write a matrix of genotype ID's to a file (matlab format)\n" ),
   cEventEntry( "save_population", "Saves the full state of the population.\n\nParameters:\nfilename (string) default: save_pop.*\n  The name of the file into which the population should\n  be saved. If it is not given, then the name 'save_pop.*'\n  is used, with '*' replaced by the current update.\n" ),
   cEventEntry( "load_population", "Loads the full state of the population.\n\nParameters:\nfilename (string)\n  The name of the file to open.\n" ),
@@ -36,6 +38,7 @@
   cEventEntry( "load_dump_file", "Sets up a population based on a dump file such as written out by\ndetail_pop. It is also possible to append a history file to the dump\nfile, in order to preserve the history of a previous run.\n" ),
   cEventEntry( "dump_pop", "Writes out a line of data for each genotype in the current population. The\nline contains the genome as string, the number of organisms of that genotype,\nand the genotype ID.\n\nParameters:\nfilename (string) default: \"dump.<update>\"\n  The name of the file into which the population dump should be written.\n" ),
   cEventEntry( "detail_pop", "Like dump_pop, but more detailed data is written out.\n\nParameters:\nfilename (string) default: \"detail_pop.<update>\"\n  The name of the file into which the population dump should be written.\n" ),
+  cEventEntry( "detail_parasite_pop", "Like dump_pop, but more detailed data is written out.\n\nParameters:\nfilename (string) default: \"detail_pop.<update>\"\n  The name of the file into which the population dump should be written.\n" ),
   cEventEntry( "dump_historic_pop", "Similar to detail_pop. However, only genotypes that are not in the\ncurrent population anymore are included. Genotypes that are not in\nthe line of descent of any of the current genotypes to the ultimate\nancestor are excluded.\n\nParameters:\nfilename (string) default: \"historic_dump.<update>\"\n  The name of the file into which the historic dump should be written.\n" ),
   cEventEntry( "dump_memory", "Dump the current memory state of all CPUs to a file.\n" ),
   cEventEntry( "inject", "Injects a single organism into the population.\n\nParameters:\nfilename (string)\n  The filename of the genotype to load. If this is left empty, or the keyword\n  \"START_CREATURE\" is given, than the genotype specified in the genesis\n  file under \"START_CREATURE\" is used.\ncell ID (integer) default: 0\n  The grid-point into which the organism should be placed.\nmerit (double) default: -1\n  The initial merit of the organism. If set to -1, this is ignored.\nlineage label (integer) default: 0\n  An integer that marks all descendants of this organism.\nneutral metric (double) default: 0\n  A double value that randomly drifts over time.\n" ),
@@ -43,6 +46,8 @@
   cEventEntry( "inject_range", "Injects identical organisms into a range of cells of the population.\n\nParameters:\nfilename (string)\n  The filename of the genotype to load. If this is left empty, or the keyword\n  \"START_CREATURE\" is given, than the genotype specified in the genesis\n  file under \"START_CREATURE\" is used.\nstart_cell (int)\n  First cell to inject into.\nstop_cell (int)\n  First cell *not* to inject into.\nmerit (double) default: -1\n  The initial merit of the organism. If set to -1, this is ignored.\nlineage label (integer) default: 0\n  An integer that marks all descendants of this organism.\nneutral metric (double) default: 0\n  A double value that randomly drifts over time.\n\nExample:\n  inject_range creature.gen 0 10\n\nWill inject 10 organisms into cells 0 through 9.\n" ),
   cEventEntry( "inject_sequence", "Injects identical organisms into a range of cells of the population.\n\nParameters:\nsequence (string)\n  The genome sequence for this organism.  This is a mandatory argument.\nstart_cell (int)\n  First cell to inject into.\nstop_cell (int)\n  First cell *not* to inject into.\nmerit (double) default: -1\n  The initial merit of the organism. If set to -1, this is ignored.\nlineage label (integer) default: 0\n  An integer that marks all descendants of this organism.\nneutral metric (double) default: 0\n  A double value that randomly drifts over time.\n\nExample:\n  inject_range ckdfhgklsahnfsaggdsgajfg 0 10 100\n\nWill inject 10 organisms into cells 0 through 9 with a merit of 100.\n" ),
   cEventEntry( "inject_random", "Injects a randomly generated genome into the population.\n\nParameters:\nlength (integer) [required]\n  Number of instructions in the randomly generated genome.\ncell ID (integer) default: -1\n  The grid-point into which the genome should be placed.  Default is random.\nmerit (double) default: -1\n  The initial merit of the organism. If set to -1, this is ignored.\nlineage label (integer) default: 0\n  An integer that marks all descendants of this organism.\nneutral metric (double) default: 0\n  A double value that randomly drifts over time.\n" ),
+  cEventEntry( "inject_range_parasite", "Injects identical organisms into a range of cells of the population.\n\nParameters:\nfilename (string)\n  The filename of the genotype to load. If this is left empty, or the keyword\n  \"START_CREATURE\" is given, than the genotype specified in the genesis\n  file under \"START_CREATURE\" is used.\nstart_cell (int)\n  First cell to inject into.\nstop_cell (int)\n  First cell *not* to inject into.\nmerit (double) default: -1\n  The initial merit of the organism. If set to -1, this is ignored.\nlineage label (integer) default: 0\n  An integer that marks all descendants of this organism.\nneutral metric (double) default: 0\n  A double value that randomly drifts over time.\n\nExample:\n  inject_range creature.gen 0 10\n\nWill inject 10 organisms into cells 0 through 9.\n" ),
+  cEventEntry( "inject_range_pair", "Injects identical organisms into a range of cells of the population.\n\nParameters:\nfilename (string)\n  The filename of the genotype to load. If this is left empty, or the keyword\n  \"START_CREATURE\" is given, than the genotype specified in the genesis\n  file under \"START_CREATURE\" is used.\nstart_cell (int)\n  First cell to inject into.\nstop_cell (int)\n  First cell *not* to inject into.\nmerit (double) default: -1\n  The initial merit of the organism. If set to -1, this is ignored.\nlineage label (integer) default: 0\n  An integer that marks all descendants of this organism.\nneutral metric (double) default: 0\n  A double value that randomly drifts over time.\n\nExample:\n  inject_range creature.gen 0 10\n\nWill inject 10 organisms into cells 0 through 9.\n" ),
   cEventEntry( "zero_muts", "This event will set all mutation rates to zero...\n" ),
   cEventEntry( "mod_copy_mut", "\n" ),
   cEventEntry( "mod_div_mut", "\n" ),
@@ -80,5 +85,5 @@
   cEventEntry( "inject_resource", "Inject (add) a specified amount of a specified resource.\n" ),
   cEventEntry( "set_resource", "Set the resource amount to a specific level\n" ) };
 
-const int cEventDescrs::num_of_events = 80;
+const int cEventDescrs::num_of_events = 85;
 
Index: avida/current/source/event/cPopulation_enums_auto.ci
diff -u avida/current/source/event/cPopulation_enums_auto.ci:1.2 avida/current/source/event/cPopulation_enums_auto.ci:1.2.2.1
--- avida/current/source/event/cPopulation_enums_auto.ci:1.2	Wed Jun  4 11:34:46 2003
+++ avida/current/source/event/cPopulation_enums_auto.ci	Mon Aug 11 15:01:28 2003
@@ -28,6 +28,8 @@
   EVENT_print_lineage_totals,
   EVENT_print_lineage_counts,
   EVENT_print_dom,
+  EVENT_parasite_debug,
+  EVENT_print_dom_parasite,
   EVENT_print_genotype_map,
   EVENT_save_population,
   EVENT_load_population,
@@ -36,6 +38,7 @@
   EVENT_load_dump_file,
   EVENT_dump_pop,
   EVENT_detail_pop,
+  EVENT_detail_parasite_pop,
   EVENT_dump_historic_pop,
   EVENT_dump_memory,
   EVENT_inject,
@@ -43,6 +46,8 @@
   EVENT_inject_range,
   EVENT_inject_sequence,
   EVENT_inject_random,
+  EVENT_inject_range_parasite,
+  EVENT_inject_range_pair,
   EVENT_zero_muts,
   EVENT_mod_copy_mut,
   EVENT_mod_div_mut,
Index: avida/current/source/event/cPopulation_event_list
diff -u avida/current/source/event/cPopulation_event_list:1.2 avida/current/source/event/cPopulation_event_list:1.2.2.1
--- avida/current/source/event/cPopulation_event_list:1.2	Wed Jun  4 11:34:46 2003
+++ avida/current/source/event/cPopulation_event_list	Mon Aug 11 15:01:28 2003
@@ -29,6 +29,8 @@
 print_lineage_totals  [cString fname="lineage_totals.dat"] [int verbose=1]
 print_lineage_counts  [cString fname="lineage_counts.dat"] [int verbose=0]
 print_dom  [cString in_filename=""]
+parasite_debug  [cString in_filename=""]
+print_dom_parasite  [cString in_filename=""]
 print_genotype_map  [cString fname="genotype_map.m"]
 save_population  [cString fname=""]
 load_population  <cString fname>
@@ -37,6 +39,7 @@
 load_dump_file  <cString fname> [int update=-1]
 dump_pop  [cString fname=""]
 detail_pop  [cString fname=""]
+detail_parasite_pop  [cString fname=""]
 dump_historic_pop  [cString fname=""]
 dump_memory  [cString fname=""]
 inject  [cString fname="START_CREATURE"] [int cell_id=0] [double merit=-1] [int lineage_label=0] [double neutral_metric=0]
@@ -44,6 +47,8 @@
 inject_range  [cString fname="START_CREATURE"] [int start_cell=0] [int end_cell=-1] [double merit=-1] [int lineage_label=0] [double neutral_metric=0]
 inject_sequence  <cString seq> [int start_cell=0] [int end_cell=-1] [double merit=-1] [int lineage_label=0] [double neutral_metric=0]
 inject_random  <int length> [int cell_id=-1] [double merit=-1] [int lineage_label=0] [double neutral_metric=0]
+inject_range_parasite  [cString fname_parasite="organism.parasite"] [int start_cell=0] [int end_cell=-1] [double merit=-1] [int lineage_label=0] [double neutral_metric=0] [int mem_space=2]
+inject_range_pair  [cString fname="START_CREATURE"] [cString fname_parasite="organism.parasite"] [int start_cell=0] [int end_cell=-1] [double merit=-1] [int lineage_label=0] [double neutral_metric=0] [int mem_space=2]
 zero_muts 
 mod_copy_mut  <double cmut_inc> [int cell=-1]
 mod_div_mut  <double dmut_inc> [int cell=-1]
Index: avida/current/source/event/cPopulation_name2enum_auto.ci
diff -u avida/current/source/event/cPopulation_name2enum_auto.ci:1.2 avida/current/source/event/cPopulation_name2enum_auto.ci:1.2.2.1
--- avida/current/source/event/cPopulation_name2enum_auto.ci:1.2	Wed Jun  4 11:34:46 2003
+++ avida/current/source/event/cPopulation_name2enum_auto.ci	Mon Aug 11 15:01:28 2003
@@ -59,6 +59,10 @@
     return cPopulationEventFactory::EVENT_print_lineage_counts;
   }else if (name == "print_dom") {
     return cPopulationEventFactory::EVENT_print_dom;
+  }else if (name == "parasite_debug") {
+    return cPopulationEventFactory::EVENT_parasite_debug;
+  }else if (name == "print_dom_parasite") {
+    return cPopulationEventFactory::EVENT_print_dom_parasite;
   }else if (name == "print_genotype_map") {
     return cPopulationEventFactory::EVENT_print_genotype_map;
   }else if (name == "save_population") {
@@ -75,6 +79,8 @@
     return cPopulationEventFactory::EVENT_dump_pop;
   }else if (name == "detail_pop") {
     return cPopulationEventFactory::EVENT_detail_pop;
+  }else if (name == "detail_parasite_pop") {
+    return cPopulationEventFactory::EVENT_detail_parasite_pop;
   }else if (name == "dump_historic_pop") {
     return cPopulationEventFactory::EVENT_dump_historic_pop;
   }else if (name == "dump_memory") {
@@ -89,6 +95,10 @@
     return cPopulationEventFactory::EVENT_inject_sequence;
   }else if (name == "inject_random") {
     return cPopulationEventFactory::EVENT_inject_random;
+  }else if (name == "inject_range_parasite") {
+    return cPopulationEventFactory::EVENT_inject_range_parasite;
+  }else if (name == "inject_range_pair") {
+    return cPopulationEventFactory::EVENT_inject_range_pair;
   }else if (name == "zero_muts") {
     return cPopulationEventFactory::EVENT_zero_muts;
   }else if (name == "mod_copy_mut") {
Index: avida/current/source/event/cPopulation_process_auto.ci
diff -u avida/current/source/event/cPopulation_process_auto.ci:1.2 avida/current/source/event/cPopulation_process_auto.ci:1.2.2.1
--- avida/current/source/event/cPopulation_process_auto.ci:1.2	Wed Jun  4 11:34:46 2003
+++ avida/current/source/event/cPopulation_process_auto.ci	Mon Aug 11 15:01:28 2003
@@ -792,7 +792,62 @@
     cGenotype * dom = population->GetGenebank().GetBestGenotype();
     cString filename(in_filename);
     if (filename == "") filename.Set("genebank/%s", dom->GetName()());
-    cTestUtil::PrintGenome(dom->GetGenome(), filename, dom, population->GetUpdate());
+    cTestUtil::PrintGenome(dom->GetGenome(), filename, dom, population->GetUpdate()); 
+  }
+};
+
+///// parasite_debug /////
+
+//midget
+
+
+class cPopulationEventparasite_debug : public cPopulationEvent {
+private:
+  cString in_filename;
+public:
+  cPopulationEventparasite_debug(const cString & in_args):
+   cPopulationEvent("parasite_debug", in_args) {
+
+    cString args(in_args);
+    if (args == "") in_filename=""; else in_filename=args.PopWord();
+  }
+///// parasite_debug /////
+  void Process(){
+    population->ParasiteDebug();
+  }
+};
+
+///// print_dom_parasite /////
+
+/**
+* Write the currently dominant injected genotype to disk.
+*
+* Parameters:
+* filename (string)
+*   The name under which the genotype should be saved. If no
+*   filename is given, the genotype is saved into the directory
+*   genebank, under the name that the genebank has associated with
+*   this genotype.
+**/
+
+
+class cPopulationEventprint_dom_parasite : public cPopulationEvent {
+private:
+  cString in_filename;
+public:
+  cPopulationEventprint_dom_parasite(const cString & in_args):
+   cPopulationEvent("print_dom_parasite", in_args) {
+
+    cString args(in_args);
+    if (args == "") in_filename=""; else in_filename=args.PopWord();
+  }
+///// print_dom_parasite /////
+  void Process(){
+    cInjectGenotype * dom = population->GetInjectGenebank().GetBestInjectGenotype();
+    if (dom!=NULL) {
+    cString filename(in_filename);
+    if (filename == "") filename.Set("genebank/%s", dom->GetName()());
+    cTestUtil::PrintGenome(dom, dom->GetGenome(), filename, population->GetUpdate()); }
   }
 };
 
@@ -1024,6 +1079,38 @@
   }
 };
 
+///// detail_parasite_pop /////
+
+/**
+* Like dump_pop, but more detailed data is written out.
+*
+* Parameters:
+* filename (string) default: "detail_pop.<update>"
+*   The name of the file into which the population dump should be written.
+**/
+
+
+class cPopulationEventdetail_parasite_pop : public cPopulationEvent {
+private:
+  cString fname;
+public:
+  cPopulationEventdetail_parasite_pop(const cString & in_args):
+   cPopulationEvent("detail_parasite_pop", in_args) {
+
+    cString args(in_args);
+    if (args == "") fname=""; else fname=args.PopWord();
+  }
+///// detail_parasite_pop /////
+  void Process(){
+    cString filename;
+    if( fname == "" ){
+      filename.Set("detail_parasite_pop.%d", population->GetUpdate());
+    }
+    //ofstream fp(filename());
+    population->GetInjectGenebank().DumpDetailedSummary(filename, population->GetUpdate());
+  }
+};
+
 ///// dump_historic_pop /////
 
 /**
@@ -1357,6 +1444,151 @@
     cGenome genome =
        cInstUtil::RandomGenome(length, population->GetEnvironment().GetInstSet());
     population->Inject(genome, cell_id, merit, lineage_label, neutral_metric);
+  }
+};
+
+///// inject_range_parasite /////
+
+/**
+* Injects identical organisms into a range of cells of the population.
+*
+* Parameters:
+* filename (string)
+*   The filename of the genotype to load. If this is left empty, or the keyword
+*   "START_CREATURE" is given, than the genotype specified in the genesis
+*   file under "START_CREATURE" is used.
+* start_cell (int)
+*   First cell to inject into.
+* stop_cell (int)
+*   First cell *not* to inject into.
+* merit (double) default: -1
+*   The initial merit of the organism. If set to -1, this is ignored.
+* lineage label (integer) default: 0
+*   An integer that marks all descendants of this organism.
+* neutral metric (double) default: 0
+*   A double value that randomly drifts over time.
+*
+* Example:
+*   inject_range creature.gen 0 10
+*
+* Will inject 10 organisms into cells 0 through 9.
+**/
+
+
+class cPopulationEventinject_range_parasite : public cPopulationEvent {
+private:
+  cString fname_parasite;
+  int start_cell;
+  int end_cell;
+  double merit;
+  int lineage_label;
+  double neutral_metric;
+  int mem_space;
+public:
+  cPopulationEventinject_range_parasite(const cString & in_args):
+   cPopulationEvent("inject_range_parasite", in_args) {
+
+    cString args(in_args);
+    if (args == "") fname_parasite="organism.parasite"; else fname_parasite=args.PopWord();
+    if (args == "") start_cell=0; else start_cell=args.PopWord().AsInt();
+    if (args == "") end_cell=-1; else end_cell=args.PopWord().AsInt();
+    if (args == "") merit=-1; else merit=args.PopWord().AsDouble();
+    if (args == "") lineage_label=0; else lineage_label=args.PopWord().AsInt();
+    if (args == "") neutral_metric=0; else neutral_metric=args.PopWord().AsDouble();
+    if (args == "") mem_space=2; else mem_space=args.PopWord().AsInt();
+  }
+///// inject_range_parasite /////
+  void Process(){
+    if (fname_parasite == "START_CREATURE") fname_parasite=cConfig::GetStartCreature();
+    if (end_cell == -1) end_cell = start_cell + 1;
+    if (start_cell < 0 ||
+        end_cell > population->GetSize() ||
+        start_cell >= end_cell) {
+      cout << "Warning: inject_range has invalid range!";
+    }
+    else {
+      cGenome genome_parasite =
+         cInstUtil::LoadGenome(fname_parasite, population->GetEnvironment().GetInstSet());
+      for (int i = start_cell; i < end_cell; i++) {
+        population->Inject(genome_parasite, i, merit, lineage_label, neutral_metric, mem_space);
+      }
+      population->SetSyncEvents(true);
+    }
+  }
+};
+
+///// inject_range_pair /////
+
+/**
+* Injects identical organisms into a range of cells of the population.
+*
+* Parameters:
+* filename (string)
+*   The filename of the genotype to load. If this is left empty, or the keyword
+*   "START_CREATURE" is given, than the genotype specified in the genesis
+*   file under "START_CREATURE" is used.
+* start_cell (int)
+*   First cell to inject into.
+* stop_cell (int)
+*   First cell *not* to inject into.
+* merit (double) default: -1
+*   The initial merit of the organism. If set to -1, this is ignored.
+* lineage label (integer) default: 0
+*   An integer that marks all descendants of this organism.
+* neutral metric (double) default: 0
+*   A double value that randomly drifts over time.
+*
+* Example:
+*   inject_range creature.gen 0 10
+*
+* Will inject 10 organisms into cells 0 through 9.
+**/
+
+
+class cPopulationEventinject_range_pair : public cPopulationEvent {
+private:
+  cString fname;
+  cString fname_parasite;
+  int start_cell;
+  int end_cell;
+  double merit;
+  int lineage_label;
+  double neutral_metric;
+  int mem_space;
+public:
+  cPopulationEventinject_range_pair(const cString & in_args):
+   cPopulationEvent("inject_range_pair", in_args) {
+
+    cString args(in_args);
+    if (args == "") fname="START_CREATURE"; else fname=args.PopWord();
+    if (args == "") fname_parasite="organism.parasite"; else fname_parasite=args.PopWord();
+    if (args == "") start_cell=0; else start_cell=args.PopWord().AsInt();
+    if (args == "") end_cell=-1; else end_cell=args.PopWord().AsInt();
+    if (args == "") merit=-1; else merit=args.PopWord().AsDouble();
+    if (args == "") lineage_label=0; else lineage_label=args.PopWord().AsInt();
+    if (args == "") neutral_metric=0; else neutral_metric=args.PopWord().AsDouble();
+    if (args == "") mem_space=2; else mem_space=args.PopWord().AsInt();
+  }
+///// inject_range_pair /////
+  void Process(){
+    if (fname == "START_CREATURE") fname=cConfig::GetStartCreature();
+    if (end_cell == -1) end_cell = start_cell + 1;
+    if (start_cell < 0 ||
+        end_cell > population->GetSize() ||
+        start_cell >= end_cell) {
+      cout << "Warning: inject_range has invalid range!";
+    }
+    else {
+      cGenome genome =
+         cInstUtil::LoadGenome(fname, population->GetEnvironment().GetInstSet());
+      cGenome genome_parasite =
+         cInstUtil::LoadGenome(fname_parasite, population->GetEnvironment().GetInstSet());
+      for (int i = start_cell; i < end_cell; i++) {
+        population->Inject(genome, i, merit, lineage_label, neutral_metric);
+        population->Inject(genome_parasite, i, merit, lineage_label, neutral_metric, mem_space);
+      }
+      population->SetSyncEvents(true);
+    }
   }
 };
 
Index: avida/current/source/event/population_event_factory.cc
diff -u avida/current/source/event/population_event_factory.cc:1.6 avida/current/source/event/population_event_factory.cc:1.6.6.1
--- avida/current/source/event/population_event_factory.cc:1.6	Sat May 17 02:48:08 2003
+++ avida/current/source/event/population_event_factory.cc	Mon Aug 11 15:01:29 2003
@@ -14,6 +14,8 @@
 #include "../main/genebank.hh"
 #include "../main/genotype.hh"
 #include "../cpu/hardware_method.hh"
+#include "../main/inject_genebank.hh"
+#include "../main/inject_genotype.hh"
 #include "../main/inst_util.hh"
 #include "../main/landscape.hh"
 #include "../main/lineage_control.hh"
Index: avida/current/source/main/Makefile.am
diff -u avida/current/source/main/Makefile.am:1.28 avida/current/source/main/Makefile.am:1.28.2.1
--- avida/current/source/main/Makefile.am:1.28	Wed Jun 11 20:46:39 2003
+++ avida/current/source/main/Makefile.am	Mon Aug 11 15:01:29 2003
@@ -33,6 +33,8 @@
     genome.hh		genome.cc		\
     genome_util.hh		genome_util.cc		\
     genotype.hh		genotype.cc		\
+    inject_genebank.hh	inject_genebank.cc   	\
+    inject_genotype.hh  inject_genotype.cc	\
     inst.hh			inst.cc			\
     inst_set.hh		inst_set.cc		\
     inst_lib.hh \
@@ -41,6 +43,7 @@
     lineage.hh		lineage.cc		\
     lineage_control.hh	lineage_control.cc 	\
     mutations.hh		mutations.cc		\
+    org_message.hh      org_message.cc          \
     organism.hh		organism.cc		\
     phenotype.hh		phenotype.cc		\
     population.hh		population.cc		\
Index: avida/current/source/main/analyze.cc
diff -u avida/current/source/main/analyze.cc:1.74 avida/current/source/main/analyze.cc:1.74.2.1
--- avida/current/source/main/analyze.cc:1.74	Fri Jun 13 14:49:59 2003
+++ avida/current/source/main/analyze.cc	Mon Aug 11 15:01:29 2003
@@ -2043,77 +2043,86 @@
       }
       
       // Columns 2 to D+1 (the possible mutations)
-      for (int mod_inst = 0; mod_inst < num_insts; mod_inst++) {
-	mod_genome[line_num].SetOp(mod_inst);
-	cAnalyzeGenotype test_genotype(mod_genome, inst_set);
-	test_genotype.Recalculate();
-	const double test_fitness = test_genotype.GetFitness() / base_fitness;
-	row_fitness += test_fitness;
-	total_fitness += test_fitness;
-	col_fitness[mod_inst] += test_fitness;
-
-	// Categorize this mutation...
-	if (test_fitness == 1.0) {           // Neutral Mutation...
-	  row_neut++;
-	  total_neut++;
-	  if (file_type == FILE_TYPE_HTML) color_string = "#FFFFFF";
-	} else if (test_fitness == 0.0) {    // Lethal Mutation...
-	  row_dead++;
-	  total_dead++;
-	  if (file_type == FILE_TYPE_HTML) color_string = "#FF0000";
-	} else if (test_fitness < 1.0) {     // Detrimental Mutation...
-	  row_neg++;
-	  total_neg++;
-	  if (file_type == FILE_TYPE_HTML) color_string = "#FFFF00";
-	} else {                             // Beneficial Mutation...
-	  row_pos++;
-	  total_pos++;
-	  if (file_type == FILE_TYPE_HTML) color_string = "#00FF00";
-	}
-	  
-	// Write out this cell...
-	if (file_type == FILE_TYPE_HTML) {
-	  fp << "<th bgcolor=\"" << color_string << "\">";
-	}
-	fp << test_fitness << " ";
+      for (int mod_inst = 0; mod_inst < num_insts; mod_inst++) 
+      {
+        if (mod_inst == cur_inst) {
+          if (file_type == FILE_TYPE_HTML) {
+            color_string = "#FFFFFF";
+            fp << "<th bgcolor=\"" << color_string << "\">";
+          }
+        }
+        else {
+          mod_genome[line_num].SetOp(mod_inst);
+          cAnalyzeGenotype test_genotype(mod_genome, inst_set);
+          test_genotype.Recalculate();
+          const double test_fitness = test_genotype.GetFitness() / base_fitness;
+          row_fitness += test_fitness;
+          total_fitness += test_fitness;
+          col_fitness[mod_inst] += test_fitness;
+
+          // Categorize this mutation...
+          if (test_fitness == 1.0) {           // Neutral Mutation...
+            row_neut++;
+            total_neut++;
+            if (file_type == FILE_TYPE_HTML) color_string = "#FFFFFF";
+          } else if (test_fitness == 0.0) {    // Lethal Mutation...
+            row_dead++;
+            total_dead++;
+            if (file_type == FILE_TYPE_HTML) color_string = "#FF0000";
+          } else if (test_fitness < 1.0) {     // Detrimental Mutation...
+            row_neg++;
+            total_neg++;
+            if (file_type == FILE_TYPE_HTML) color_string = "#FFFF00";
+          } else {                             // Beneficial Mutation...
+            row_pos++;
+            total_pos++;
+            if (file_type == FILE_TYPE_HTML) color_string = "#00FF00";
+          }
+
+          // Write out this cell...
+          if (file_type == FILE_TYPE_HTML) {
+            fp << "<th bgcolor=\"" << color_string << "\">";
+          }
+          fp << test_fitness << " ";
+        }
       }
 
       // Column: Knockout
       mod_genome[line_num] = null_inst;
       cAnalyzeGenotype test_genotype(mod_genome, map_inst_set);
       test_genotype.Recalculate();
-      const double test_fitness = test_genotype.GetFitness();
+      const double test_fitness = test_genotype.GetFitness() / base_fitness;
       col_fitness[num_insts] += test_fitness;
 
       // Categorize this mutation if its in HTML mode (color only)...
       if (file_type == FILE_TYPE_HTML) {
-	if (test_fitness == base_fitness) color_string = "#FFFFFF";
-	else if (test_fitness == 0.0) color_string = "#FF0000";
-	else if (test_fitness < base_fitness) color_string = "#FFFF00";
-	else color_string = "#00FF00";
+        if (test_fitness == 1.0) color_string = "#FFFFFF";
+        else if (test_fitness == 0.0) color_string = "#FF0000";
+        else if (test_fitness < 1.0) color_string = "#FFFF00";
+        else color_string = "#00FF00";
 
-	fp << "<th bgcolor=\"" << color_string << "\">";
+        fp << "<th bgcolor=\"" << color_string << "\">";
       }
-      
+
       fp << test_fitness << " ";
 
       // Fraction Columns...
       if (file_type == FILE_TYPE_HTML) fp << "<th bgcolor=\"#FF0000\">";
-      fp << (double) row_dead / (double) num_insts << " ";
+      fp << (double) row_dead / (double) (num_insts-1) << " ";
 
       if (file_type == FILE_TYPE_HTML) fp << "<th bgcolor=\"#FFFF00\">";
-      fp << (double) row_neg / (double) num_insts << " ";
+      fp << (double) row_neg / (double) (num_insts-1) << " ";
 
       if (file_type == FILE_TYPE_HTML) fp << "<th bgcolor=\"#FFFFFF\">";
-      fp << (double) row_neut / (double) num_insts << " ";
+      fp << (double) row_neut / (double) (num_insts-1) << " ";
 
       if (file_type == FILE_TYPE_HTML) fp << "<th bgcolor=\"#00FF00\">";
-      fp << (double) row_pos / (double) num_insts << " ";
+      fp << (double) row_pos / (double) (num_insts-1) << " ";
 
 
       // Column: Average Fitness
       if (file_type == FILE_TYPE_HTML) fp << "<th>";
-      fp << row_fitness / (double) num_insts << " ";
+      fp << row_fitness / (double) (num_insts-1) << " ";
 
       // Column: Expected Entropy  @CAO Implement!
       if (file_type == FILE_TYPE_HTML) fp << "<th>";
@@ -2137,7 +2146,7 @@
 	fp << "<th>" << col_fitness[i] / max_line << " ";
       }
 
-      int total_tests = max_line * num_insts;
+      int total_tests = max_line * (num_insts-1);
       fp << "<th>" << (double) total_dead / (double) total_tests << " ";
       fp << "<th>" << (double) total_neg / (double) total_tests << " ";
       fp << "<th>" << (double) total_neut / (double) total_tests << " ";
Index: avida/current/source/main/avida.cc
diff -u avida/current/source/main/avida.cc:1.43 avida/current/source/main/avida.cc:1.43.2.1
--- avida/current/source/main/avida.cc:1.43	Fri Jun 13 14:49:59 2003
+++ avida/current/source/main/avida.cc	Mon Aug 11 15:01:29 2003
@@ -103,6 +103,7 @@
   test_interface.SetFun_Recycle(&cCallbackUtil::CB_RecycleHardware);
   test_interface.SetFun_Divide(&cCallbackUtil::CB_TestDivide);
   test_interface.SetFun_GetInput(&cCallbackUtil::CB_GetInput);
+  test_interface.SetFun_GetInputAt(&cCallbackUtil::CB_GetInputAt);
   test_interface.SetFun_GetResources(&cCallbackUtil::CB_GetResources);
   test_interface.SetFun_UpdateResources(&cCallbackUtil::CB_UpdateResources);
 
@@ -186,10 +187,13 @@
   default_interface.SetFun_Breakpoint(&cCallbackUtil::CB_Breakpoint);
   default_interface.SetFun_TestFitness(&cCallbackUtil::CB_TestFitness);
   default_interface.SetFun_GetInput(&cCallbackUtil::CB_GetInput);
+  default_interface.SetFun_GetInputAt(&cCallbackUtil::CB_GetInputAt);
   default_interface.SetFun_Debug(&cCallbackUtil::CB_Debug);
   default_interface.SetFun_GetResources(&cCallbackUtil::CB_GetResources);
   default_interface.SetFun_UpdateResources(&cCallbackUtil::CB_UpdateResources);
   default_interface.SetFun_KillCell(&cCallbackUtil::CB_KillCell);
+  default_interface.SetFun_SendMessage(&cCallbackUtil::CB_SendMessage);
+  default_interface.SetFun_InjectParasite(&cCallbackUtil::CB_InjectParasite);
 
   population = new cPopulation(default_interface, environment);
   cout << " ...done" << endl;
Index: avida/current/source/main/callback_util.cc
diff -u avida/current/source/main/callback_util.cc:1.20 avida/current/source/main/callback_util.cc:1.20.2.1
--- avida/current/source/main/callback_util.cc:1.20	Wed May 21 20:05:57 2003
+++ avida/current/source/main/callback_util.cc	Mon Aug 11 15:01:30 2003
@@ -21,6 +21,7 @@
 #include "../cpu/hardware_factory.hh"
 #include "../cpu/test_cpu.hh"
 
+#include "../main/org_message.hh"
 
 using namespace std;
 
@@ -141,6 +142,14 @@
   return cell.GetInput();
 }
 
+int cCallbackUtil::CB_GetInputAt(cPopulation * pop, int cell_id, int & input_pointer)
+{
+  if (pop == NULL) return cTestCPU::GetInputAt(input_pointer);
+  cPopulationCell & cell = pop->GetCell(cell_id);
+  assert(cell.IsOccupied());
+  return cell.GetInputAt(input_pointer);
+}
+
 int cCallbackUtil::CB_Debug(cPopulation * pop, int cell_id)
 {
   if (pop == NULL) return -1;
@@ -176,3 +185,25 @@
   cPopulationCell & death_cell = pop->GetCell(death_id);
   pop->KillOrganism(death_cell);
 }
+
+bool cCallbackUtil::CB_SendMessage(cPopulation * pop, int cell_id, cOrgMessage & mess)
+{
+  mess.SetSenderID(cell_id);
+  mess.SetTime(pop->GetUpdate());
+  cPopulationCell & cell = pop->GetCell(cell_id);
+  if(cell.ConnectionList().GetFirst() == NULL)
+    return false;
+  mess.SetRecipientID(cell.ConnectionList().GetFirst()->GetID());
+  return cell.ConnectionList().GetFirst()->GetOrganism()->ReceiveMessage(mess);
+}
+
+bool cCallbackUtil::CB_InjectParasite(cPopulation * pop, int cell_id, cOrganism * parent,
+				      const cGenome & injected_code)
+{
+  assert(pop != NULL);
+  assert(parent != NULL);
+  assert(pop->GetCell(cell_id).GetOrganism() == parent);
+
+  return pop->ActivateInject(*parent, injected_code);
+}
+
Index: avida/current/source/main/callback_util.hh
diff -u avida/current/source/main/callback_util.hh:1.10 avida/current/source/main/callback_util.hh:1.10.6.1
--- avida/current/source/main/callback_util.hh:1.10	Tue Apr  1 08:58:17 2003
+++ avida/current/source/main/callback_util.hh	Mon Aug 11 15:01:30 2003
@@ -15,6 +15,8 @@
 class cOrganism;
 class cPopulation;
 class cPopulationInterface;
+class cOrgMessage;
+class cCodeLabel;
 
 class cCallbackUtil {
 public:
@@ -32,11 +34,15 @@
   static void CB_Breakpoint();
   static double CB_TestFitness(cPopulation * pop, int cell_id);
   static int CB_GetInput(cPopulation * pop, int cell_id);
+  static int CB_GetInputAt(cPopulation * pop, int cell_id, int & input_pointer);
   static int CB_Debug(cPopulation * pop, int cell_id);
   static const tArray<double>& CB_GetResources(cPopulation * pop, int cell_id);
   static void CB_UpdateResources(cPopulation  * pop, int cell_id,
 				 const tArray<double> & res_change);
   static void CB_KillCell(cPopulation * pop, int death_id);
+  static bool CB_SendMessage(cPopulation * pop, int cell_id, cOrgMessage & mess);
+  static bool CB_InjectParasite(cPopulation * pop, int cell_id, cOrganism * parent,
+				const cGenome & injected_code);
 };
 
 #endif
Index: avida/current/source/main/config.cc
diff -u avida/current/source/main/config.cc:1.58 avida/current/source/main/config.cc:1.58.2.1
--- avida/current/source/main/config.cc:1.58	Fri Jun  6 12:46:23 2003
+++ avida/current/source/main/config.cc	Mon Aug 11 15:01:30 2003
@@ -33,6 +33,7 @@
 int cConfig::end_condition_mode;
 int cConfig::world_x;
 int cConfig::world_y;
+int cConfig::world_geometry;
 int cConfig::rand_seed;
 double cConfig::point_mut_prob;
 double cConfig::copy_mut_prob;
@@ -46,7 +47,7 @@
 int cConfig::num_instructions;
 int cConfig::hardware_type;
 int cConfig::max_cpu_threads;
-int cConfig::thread_slicing_method;
+double cConfig::thread_slicing_method;
 int cConfig::size_merit_method;
 int cConfig::base_size_merit;
 int cConfig::task_merit_method;
@@ -117,6 +118,8 @@
 		  "Width of the Avida world");
   arch_group->Add(world_y, "100", "WORLD-Y",
 		  "Height of the Avida world");
+  arch_group->Add(world_geometry, "2", "WORLD_GEOMETRY",
+		  "1 = Bounded Grid\n2 = Torus");
   arch_group->Add(rand_seed, "0", "RANDOM_SEED",
 		  "Random number seed (0 for based on time)");
   arch_group->Add(hardware_type, "0", "HARDWARE_TYPE",
@@ -154,7 +157,7 @@
   repro_group->Add(alloc_method, "0", "ALLOC_METHOD",
 		   "0 = Allocated space is set to default instruction.\n1 = Set to section of dead genome (Necrophilia)\n2 = Allocated space is set to random instruction.");
   repro_group->Add(divide_method, "1", "DIVIDE_METHOD",
-		   "0 = Divide leaves state of mother untouched.\n1 = Divide resets state of mother\n    (after the divide, we have 2 children)");
+		   "0 = Divide leaves state of mother untouched.\n1 = Divide resets state of mother (after the divide, we have 2 children)\n2 = Divide resets state of current thread only(does not touch possible parasite threads)");
   repro_group->Add(generation_inc_method, "1", "GENERATION_INC_METHOD",
 		   "0 = Only the generation of the child is\n    increased on divide.\n1 = Both the generation of the mother and child are\n    increased on divide (good with DIVIDE_METHOD 1).");
 
@@ -239,7 +242,7 @@
   time_group->Add(max_cpu_threads, "1", "MAX_CPU_THREADS",
 		  "Number of Threads a CPU can spawn");
   time_group->Add(thread_slicing_method, "0", "THREAD_SLICING_METHOD",
-		  "0 = One thread executed per time slice.\n1 = All threads executed each time slice.");
+		  "Formula for and organism's thread slicing -> 1 + (num_organism_threads-1) * THREAD_SLICING_METHOD.\n0 = One thread executed per time slice.\n1 = All threads executed each time slice.\n");
   time_group->Add(max_label_exe_size, "1", "MAX_LABEL_EXE_SIZE",
 		  "Max nops marked as executed when labels are used");
   time_group->Add(base_size_merit, "0", "BASE_SIZE_MERIT",
Index: avida/current/source/main/config.hh
diff -u avida/current/source/main/config.hh:1.51 avida/current/source/main/config.hh:1.51.2.1
--- avida/current/source/main/config.hh:1.51	Fri Jun  6 12:46:23 2003
+++ avida/current/source/main/config.hh	Mon Aug 11 15:01:30 2003
@@ -40,6 +40,7 @@
 
 #define DIVIDE_METHOD_OFFSPRING 0
 #define DIVIDE_METHOD_SPLIT     1
+#define DIVIDE_METHOD_BIRTH     2
 
 #define GENERATION_INC_OFFSPRING 0
 #define GENERATION_INC_BOTH      1
@@ -55,6 +56,10 @@
 #define SIZE_MERIT_LEAST       4
 #define SIZE_MERIT_SQRT_LEAST  5
 
+#define GEOMETRY_GLOBAL 0
+#define GEOMETRY_GRID   1
+#define GEOMETRY_TORUS  2
+
 class cConfig {
 protected:
   class cConfigEntryBase {
@@ -66,7 +71,9 @@
     cConfigEntryBase(const cString & _tag, const cString & _def,
 		     const cString & _desc)
       : genesis_tag(_tag), default_value(_def), description(_desc, '\n') { ; }
+    virtual ~cConfigEntryBase(){}
 
+    //    virtual ~cConfigEntryBase();
     const cString & GetTag() { return genesis_tag; }
     const cString & GetDefault() { return default_value; }
     const cStringList & GetDesc() { return description; }
@@ -168,6 +175,7 @@
   static int end_condition_mode;
   static int world_x;
   static int world_y;
+  static int world_geometry;
   static int rand_seed;
 
   // Mutations
@@ -185,7 +193,7 @@
   static int num_instructions;
   static int hardware_type;
   static int max_cpu_threads;
-  static int thread_slicing_method;
+  static double thread_slicing_method;
 
   // Merit info
   static int size_merit_method;
@@ -293,6 +301,7 @@
   static int GetEndConditionMode() { return end_condition_mode; }
   static int GetWorldX()         { return world_x; }
   static int GetWorldY()         { return world_y; }
+  static int GetWorldGeometry()  { return world_geometry; }
   static int GetRandSeed()       { return rand_seed; }
 
   static double GetPointMutProb()  { return point_mut_prob; }
@@ -307,8 +316,8 @@
 
   static int GetNumInstructions() { return num_instructions; }
   static int GetHardwareType() { return hardware_type; }
-  static int GetMaxCPUThreads()  { return max_cpu_threads; }
-  static int GetThreadSlicingMethod() { return thread_slicing_method; }
+  static int GetMaxCPUThreads() { return max_cpu_threads; }
+  static double GetThreadSlicingMethod() { return thread_slicing_method; }
 
   static int GetSizeMeritMethod() { return size_merit_method; }
   static int GetBaseSizeMerit()  { return base_size_merit; }
Index: avida/current/source/main/environment.cc
diff -u avida/current/source/main/environment.cc:1.13 avida/current/source/main/environment.cc:1.13.2.1
--- avida/current/source/main/environment.cc:1.13	Tue Jun 24 14:56:39 2003
+++ avida/current/source/main/environment.cc	Mon Aug 11 15:01:30 2003
@@ -181,23 +181,26 @@
       if (!AssertInputDouble(var_value, "conversion", var_type)) return false;
       new_process->SetConversion(var_value.AsDouble());
     }
-	else if (var_name == "lethal") {
-	  if (!AssertInputBool(var_value, "lethal", var_type)) return false;
-	  new_process->SetLethal(var_value.AsInt());
-	}
-	else if (var_name == "detect") {
-        cResource * test_resource = resource_lib.GetResource(var_value);
-        if (!AssertInputValid(test_resource, "product", var_type, var_value)) {
-	  return false;
+    else if (var_name == "lethal") {
+      if (!AssertInputBool(var_value, "lethal", var_type)) 
+	return false;
+      new_process->SetLethal(var_value.AsInt());
+    }
+    else if (var_name == "detect") {
+      cResource * test_resource = resource_lib.GetResource(var_value);
+      if (!AssertInputValid(test_resource, "product", var_type, var_value)) {
+	return false;
       }
       new_process->SetDetect(test_resource);
     }
-	else if (var_name == "threshold") {
-		if (!AssertInputDouble(var_value, "threshold", var_type)) return false;
-        new_process->SetDetectionThreshold(var_value.AsDouble());
+    else if (var_name == "threshold") {
+      if (!AssertInputDouble(var_value, "threshold", var_type))
+	return false;
+      new_process->SetDetectionThreshold(var_value.AsDouble());
     }
-	else if (var_name == "detectionerror") {
-	  if (!AssertInputDouble(var_value, "detectionerror", var_type)) return false;
+    else if (var_name == "detectionerror") {
+      if (!AssertInputDouble(var_value, "detectionerror", var_type)) 
+	return false;
       new_process->SetDetectionError(var_value.AsDouble());
     }
     else {
@@ -780,30 +783,28 @@
       break;
     };
 
-	// Determine detection events
-	cResource * detected = cur_process->GetDetect();
-	const int detected_id = detected->GetID();
-	int real_amount = resource_count[detected_id];
-	//Arbitrary value for infinite resource
-	if (detected == NULL) result.Detect(detected_id, 1.0);
-	else
-	{
-		double estimated_amount =
-			g_random.GetRandNormal(real_amount, cur_process->GetDetectionError()*real_amount);
-		if (estimated_amount < cur_process->GetDetectionThreshold())
-			result.Detect(detected_id, 0.0);				
-		else result.Detect(detected_id, estimated_amount);
-	};
+    // Determine detection events
+    cResource * detected = cur_process->GetDetect();
+    if (detected != NULL) {
+      const int detected_id = detected->GetID();
+      const double real_amount = resource_count[detected_id];
+      double estimated_amount =
+	   g_random.GetRandNormal(real_amount, cur_process->GetDetectionError()*real_amount);
+      if (estimated_amount < cur_process->GetDetectionThreshold()) {
+	result.Detect(detected_id, 0.0);		
+      } else {
+        result.Detect(detected_id, estimated_amount);
+      }
+    }
 
     // Determine byproducts
     cResource * product = cur_process->GetProduct();
-    if (product != NULL) 
-	{
-	int product_id = product->GetID();
-    double product_size = consumed * cur_process->GetConversion();
-    result.Produce(product_id, product_size);
-	};
+    if (product != NULL) {
+      int product_id = product->GetID();
+      double product_size = consumed * cur_process->GetConversion();
+      result.Produce(product_id, product_size);
+    }
 
-	result.Lethal(cur_process->GetLethal());
+    result.Lethal(cur_process->GetLethal());
   }
 }
Index: avida/current/source/main/genebank.cc
diff -u avida/current/source/main/genebank.cc:1.30 avida/current/source/main/genebank.cc:1.30.6.1
--- avida/current/source/main/genebank.cc:1.30	Sat May 17 02:48:08 2003
+++ avida/current/source/main/genebank.cc	Mon Aug 11 15:01:30 2003
@@ -716,8 +716,8 @@
     if (genotype_dom_time == cConfig::GetGenotypePrintDom()) {
       cString filename;
       filename.Set("genebank/%s", best_genotype->GetName()());
-      cTestUtil::PrintGenome(best_genotype->GetGenome(), filename,
-			     best_genotype, stats.GetUpdate());
+      cTestUtil::PrintGenome(best_genotype->GetGenome(), 
+			     filename, best_genotype, stats.GetUpdate());
     }
   }
 }
Index: avida/current/source/main/genome.hh
diff -u avida/current/source/main/genome.hh:1.3 avida/current/source/main/genome.hh:1.3.8.1
--- avida/current/source/main/genome.hh:1.3	Thu Feb 28 22:37:51 2002
+++ avida/current/source/main/genome.hh	Mon Aug 11 15:01:30 2003
@@ -32,6 +32,8 @@
 
   virtual void operator=(const cGenome & other_genome);
   virtual bool operator==(const cGenome & other_genome) const;
+  virtual bool operator<(const cGenome & other_genome) const
+  { return AsString() < other_genome.AsString(); }
 
   cInstruction & operator[](int index)
     { assert(index >= 0 && index < active_size);  return genome[index]; }
Index: avida/current/source/main/organism.cc
diff -u avida/current/source/main/organism.cc:1.24 avida/current/source/main/organism.cc:1.24.2.1
--- avida/current/source/main/organism.cc:1.24	Tue Jun 24 14:56:39 2003
+++ avida/current/source/main/organism.cc	Mon Aug 11 15:01:30 2003
@@ -16,6 +16,8 @@
 #include "inst_util.hh"
 #include "genome.hh"
 #include "genome_util.hh"
+#include "org_message.hh"
+#include "../main/inject_genotype.hh"
 
 #include "../cpu/cpu_defs.hh"
 #include "../cpu/hardware_base.hh"
@@ -44,6 +46,8 @@
   , max_executed(-1)
   , lineage_label(-1)
   , lineage(NULL)
+    , inbox(0)
+    , sent(0)
 {
   // Initialization of structures...
   hardware = pop_interface.NewHardware(this);
@@ -95,9 +99,54 @@
   out_buf.Add(value);
   phenotype.TestOutput(in_buf, out_buf, resource_count, res_change);
   pop_interface.UpdateResources(res_change);
-  if(phenotype.GetToDie() == 1) Die();	//Final Effect Lethal Reaction
+  //if(phenotype.GetToDie() == 1) Die();	//Final Effect Lethal Reaction
 }
 
+void cOrganism::SendMessage(cOrgMessage & mess)
+{
+  if(pop_interface.SendMessage(mess))
+    sent.Add(mess);
+  else
+    {
+      //perhaps some kind of message error buffer?
+    }
+}
+
+bool cOrganism::ReceiveMessage(cOrgMessage & mess)
+{
+  inbox.Add(mess);
+  return true;
+}
+
+bool cOrganism::InjectParasite(const cGenome & injected_code)
+{
+  return pop_interface.InjectParasite(this, injected_code);
+}
+
+bool cOrganism::InjectHost(const cCodeLabel & label, const cGenome & injected_code)
+{
+  return hardware->InjectHost(label, injected_code);
+}
+
+void cOrganism::AddParasite(cInjectGenotype * in_genotype)
+{
+  parasites.push_back(in_genotype);
+}
+
+cInjectGenotype & cOrganism::GetParasite(int x)
+{
+  return *parasites[x];
+}
+
+int cOrganism::GetNumParasites()
+{
+  return parasites.size();
+}
+
+void cOrganism::ClearParasites()
+{
+  parasites.clear();
+}
 
 int cOrganism::OK()
 {
Index: avida/current/source/main/organism.hh
diff -u avida/current/source/main/organism.hh:1.21 avida/current/source/main/organism.hh:1.21.6.1
--- avida/current/source/main/organism.hh:1.21	Sat May 17 02:48:09 2003
+++ avida/current/source/main/organism.hh	Mon Aug 11 15:01:30 2003
@@ -9,9 +9,12 @@
 #define ORGANISM_HH
 
 #include <fstream>
+#include <deque>
 
 #include "../tools/merit.hh"
 #include "../tools/tBuffer.hh"
+#include "../tools/string.hh"
+#include "../tools/tList.hh"
 
 #include "../defs.hh"
 
@@ -19,6 +22,7 @@
 #include "mutations.hh"
 #include "pop_interface.hh"
 #include "phenotype.hh"
+//#include "../main/inject_genotype.hh"
 
 #include "../cpu/cpu_memory.hh"
 #include "../cpu/cpu_stats.hh"
@@ -28,6 +32,8 @@
 class cHardwareBase;
 class cLineage;
 class cPopulation;
+class cOrgMessage;
+class cInjectGenotype;
 
 /**
  * The cOrganism class controls the running and manages all the statistics
@@ -40,7 +46,8 @@
   cGenotype * genotype;      // Information about organisms with this genome.
   cPhenotype phenotype;      // Descriptive attributes of organism.
   const cGenome initial_genome;        // Initial genome; can never be changed!
-
+  std::deque<cInjectGenotype *> parasites; // List of all parasites associated with
+                                    // this organism.
   cMutationRates mut_rates;            // Rate of all possible mutations.
   cLocalMutations mut_info;            // Info about possible mutations;
   cPopulationInterface pop_interface;  // Interface back to the population.
@@ -58,6 +65,9 @@
 #endif
   static int instance_count;
 
+  tBuffer<cOrgMessage> inbox;
+  tBuffer<cOrgMessage> sent;
+
 public:
   void PrintStatus(std::ostream & fp);
 
@@ -80,6 +90,7 @@
   void Rotate(int direction) { pop_interface.Rotate(direction); }
   void DoBreakpoint() { pop_interface.Breakpoint(); }
   int GetInput() { return pop_interface.GetInput(); }
+  int GetInputAt(int & input_pointer) { return pop_interface.GetInputAt(input_pointer); }
   void Die() { pop_interface.Die(); }
   int GetCellID() { return pop_interface.GetCellID(); }
   int GetDebugInfo() { return pop_interface.Debug(); }
@@ -88,6 +99,17 @@
   void DoInput(const int value, tBuffer<int> & in_buf, tBuffer<int> & out_buf);
   void DoOutput(const int value, tBuffer<int> & in_buf, tBuffer<int> &out_buf);
 
+  // NEW - message stuff
+  void SendMessage(cOrgMessage & mess);
+  bool ReceiveMessage(cOrgMessage & mess);
+
+  bool InjectParasite(const cGenome & genome);
+  bool InjectHost(const cCodeLabel & in_label, const cGenome & genome);
+  void AddParasite(cInjectGenotype * cur);
+  cInjectGenotype & GetParasite(int x);
+  int GetNumParasites();
+  void ClearParasites();
+		      
   int OK();
 
   double GetTestFitness();
@@ -147,8 +169,9 @@
   cLocalMutations & GetLocalMutations() { return mut_info; }
   const cPopulationInterface & PopInterface() const { return pop_interface; }
   cPopulationInterface & PopInterface() { return pop_interface; }
+  
   const cGenome & GetGenome() const { return initial_genome; }
-
+  
   int GetCurGestation() const;
   const cPhenotype & GetPhenotype() const { return phenotype; }
   cPhenotype & GetPhenotype() { return phenotype; }
Index: avida/current/source/main/phenotype.cc
diff -u avida/current/source/main/phenotype.cc:1.34 avida/current/source/main/phenotype.cc:1.34.2.1
--- avida/current/source/main/phenotype.cc:1.34	Tue Jun 24 14:56:39 2003
+++ avida/current/source/main/phenotype.cc	Mon Aug 11 15:01:30 2003
@@ -401,7 +401,7 @@
 	      sensed_resources[j] = result.GetDetected(j);
 
   //Kill any cells that did lethal reactions
-  to_die = result.GetLethal();
+  //to_die = result.GetLethal();
 
   return true;
 }
Index: avida/current/source/main/pop_interface.cc
diff -u avida/current/source/main/pop_interface.cc:1.11 avida/current/source/main/pop_interface.cc:1.11.6.1
--- avida/current/source/main/pop_interface.cc:1.11	Tue Apr  1 07:06:27 2003
+++ avida/current/source/main/pop_interface.cc	Mon Aug 11 15:01:30 2003
@@ -27,10 +27,13 @@
   , fun_breakpoint(NULL)
   , fun_test_fitness(NULL)
   , fun_get_input(NULL)
+  , fun_get_input_at(NULL)
   , fun_debug(NULL)
   , fun_get_resources(NULL)
   , fun_update_resources(NULL)
   , fun_kill_cell(NULL)
+    , fun_send_message(NULL)
+    , fun_inject_parasite(NULL)
 {
 }
 
@@ -56,6 +59,8 @@
   fun_get_resources    = in_interface.fun_get_resources;
   fun_update_resources = in_interface.fun_update_resources;
   fun_kill_cell        = in_interface.fun_kill_cell;
+  fun_send_message     = in_interface.fun_send_message;
+  fun_inject_parasite  = in_interface.fun_inject_parasite;
 }
 
 cHardwareBase * cPopulationInterface::NewHardware(cOrganism * owner)
@@ -134,6 +139,12 @@
   return (*fun_get_input)(population, cell_id);
 }
 
+int cPopulationInterface::GetInputAt(int & input_pointer)
+{
+  assert(fun_get_input_at != NULL);
+  return (*fun_get_input_at)(population, cell_id, input_pointer);
+}
+
 int cPopulationInterface::Debug()
 {
   assert(fun_debug != NULL);
@@ -152,9 +163,21 @@
   (*fun_update_resources)(population, cell_id, res_change);
 }
 
-
 void cPopulationInterface::Die()
 {
   if (fun_kill_cell == NULL) return;
   (*fun_kill_cell)(population, cell_id);
+}
+
+bool cPopulationInterface::SendMessage(cOrgMessage & mess)
+{
+  if (fun_send_message == NULL) return false;
+  return (*fun_send_message)(population, cell_id, mess);
+}
+
+bool cPopulationInterface::InjectParasite(cOrganism * parent, 
+					  const cGenome & injected_code)
+{
+  if (fun_inject_parasite == NULL) return false;
+  return (*fun_inject_parasite)(population, cell_id, parent, injected_code);
 }
Index: avida/current/source/main/pop_interface.hh
diff -u avida/current/source/main/pop_interface.hh:1.9 avida/current/source/main/pop_interface.hh:1.9.6.1
--- avida/current/source/main/pop_interface.hh:1.9	Tue Apr  1 07:06:29 2003
+++ avida/current/source/main/pop_interface.hh	Mon Aug 11 15:01:30 2003
@@ -17,6 +17,8 @@
 class cHardwareBase;
 class cOrganism;
 class cPopulation;
+class cOrgMessage;
+class cCodeLabel;
 
 typedef cHardwareBase * (*tFunNewHardware)(cPopulation *pop, cOrganism *owner);
 typedef void (*tFunRecycle)(cHardwareBase * out_hardware);
@@ -30,12 +32,16 @@
 typedef void (*tFunBreakpoint)();
 typedef double (*tFunTestFitness)(cPopulation * pop, int cell_id);
 typedef int (*tFunGetInput)(cPopulation * pop, int cell_id);
+typedef int (*tFunGetInputAt)(cPopulation * pop, int cell_id, int & input_pointer);
 typedef int (*tFunDebug)(cPopulation * pop, int cell_id);
 typedef const tArray<double> & (*tFunGetResources)
   (cPopulation * pop, int cell_id);
 typedef void (*tFunUpdateResources)
   (cPopulation * pop, int cell_id, const tArray<double> & res_change);
 typedef void (*tFunKillCell)(cPopulation * pop, int death_id);
+typedef bool (*tFunSendMessage)(cPopulation * pop, int cell_id, cOrgMessage & mess);
+typedef bool (*tFunInjectParasite)
+  (cPopulation * pop, int cell_id, cOrganism * parent, const cGenome & injected_code);
 
 class cPopulationInterface {
 private:
@@ -53,10 +59,13 @@
   tFunBreakpoint       fun_breakpoint;
   tFunTestFitness      fun_test_fitness;
   tFunGetInput         fun_get_input;
+  tFunGetInputAt       fun_get_input_at;
   tFunDebug            fun_debug;
   tFunGetResources     fun_get_resources;
   tFunUpdateResources  fun_update_resources;
   tFunKillCell         fun_kill_cell;
+  tFunSendMessage      fun_send_message;
+  tFunInjectParasite   fun_inject_parasite;
 public:
   cPopulationInterface();
   ~cPopulationInterface();
@@ -78,11 +87,14 @@
   void SetFun_Breakpoint(tFunBreakpoint fun) { fun_breakpoint = fun; }
   void SetFun_TestFitness(tFunTestFitness fun) { fun_test_fitness = fun; }
   void SetFun_GetInput(tFunGetInput fun) { fun_get_input = fun; }
+  void SetFun_GetInputAt(tFunGetInputAt fun) { fun_get_input_at = fun; }
   void SetFun_Debug(tFunDebug fun) { fun_debug = fun; }
   void SetFun_GetResources(tFunGetResources fun) { fun_get_resources = fun; }
   void SetFun_UpdateResources(tFunUpdateResources fun)
     { fun_update_resources = fun; }
   void SetFun_KillCell(tFunKillCell fun) { fun_kill_cell = fun; }
+  void SetFun_SendMessage(tFunSendMessage fun) { fun_send_message = fun; }
+  void SetFun_InjectParasite(tFunInjectParasite fun) { fun_inject_parasite = fun; }
   void CopyCallbacks(cPopulationInterface & in_interface);
 
   // Activate callbacks...
@@ -97,10 +109,13 @@
   void Breakpoint();
   double TestFitness();
   int GetInput();
+  int GetInputAt(int & input_pointer);
   int Debug();
   const tArray<double> & GetResources();
   void UpdateResources(const tArray<double> & res_change);
   void Die();
+  bool SendMessage(cOrgMessage & mess);
+  bool InjectParasite(cOrganism * parent, const cGenome & injected_code);
 };
 
 #endif
Index: avida/current/source/main/population.cc
diff -u avida/current/source/main/population.cc:1.109 avida/current/source/main/population.cc:1.109.4.1
--- avida/current/source/main/population.cc:1.109	Tue May 20 14:07:00 2003
+++ avida/current/source/main/population.cc	Mon Aug 11 15:01:30 2003
@@ -20,6 +20,8 @@
 #include "genebank.hh"
 #include "genome_util.hh"
 #include "genotype.hh"
+#include "inject_genebank.hh"
+#include "inject_genotype.hh"
 #include "inst_util.hh"
 #include "lineage.hh"
 #include "lineage_control.hh"
@@ -33,6 +35,7 @@
 #include "../cpu/hardware_base.hh"
 #include "../cpu/hardware_factory.hh"
 #include "../cpu/hardware_util.hh"
+#include "../cpu/hardware_4stack.hh"
 
 
 using namespace std;
@@ -51,6 +54,7 @@
 
   // Setup the genebank.
   genebank = new cGenebank(stats);
+  inject_genebank = new cInjectGenebank(stats);
 
   // are we logging lineages?
   if (cConfig::GetLogLineages()) {
@@ -76,26 +80,76 @@
   // Avida specific information.
   world_x = cConfig::GetWorldX();
   world_y = cConfig::GetWorldY();
+  int geometry = cConfig::GetWorldGeometry();
   const int num_cells = world_x * world_y;
   cout << "Building world " << world_x << "x" << world_y
        << " = " << num_cells << " organisms." << endl;
+  if (geometry == GEOMETRY_GRID) {
+    cout << "Geometry: Bounded grid" << endl;
+  } else if (geometry == GEOMETRY_TORUS) {
+    cout << "Geometry: Torus" << endl;
+  } else {
+    cout << "Geometry: Unknown" << endl;
+  }
 
   cell_array.Resize(num_cells);
   resource_count.ResizeSpatialGrids(world_x, world_y);
-
+  
+  bool bottom_flag, top_flag, right_flag, left_flag;
   for (int cell_id = 0; cell_id < num_cells; cell_id++) {
+    int x = cell_id % world_x;
+    int y = cell_id / world_x;
     cell_array[cell_id].Setup(cell_id, default_mut_rates);
 
+
+    if ((y == 0) && (geometry == GEOMETRY_GRID)) {
+      bottom_flag = false;
+    } else {
+      bottom_flag = true;
+    }
+    if ((y == world_y-1) && (geometry == GEOMETRY_GRID)) {
+      top_flag = false;
+    } else {
+      top_flag = true;
+    }
+    if ((x == 0) && (geometry == GEOMETRY_GRID)) {
+      left_flag = false;
+    } else {
+      left_flag = true;
+    }
+    if ((x == world_x-1) && (geometry == GEOMETRY_GRID)) {
+      right_flag = false;
+    } else {
+      right_flag = true;
+    }
+
     // Setup the connection list for each cell. (Clockwise from -1 to 1)
-    tList<cPopulationCell> & conn_list = cell_array[cell_id].ConnectionList();
-    conn_list.Push(&(cell_array[Neighbor(cell_id, world_x, world_y, -1, -1)]));
-    conn_list.Push(&(cell_array[Neighbor(cell_id, world_x, world_y,  0, -1)]));
-    conn_list.Push(&(cell_array[Neighbor(cell_id, world_x, world_y, +1, -1)]));
-    conn_list.Push(&(cell_array[Neighbor(cell_id, world_x, world_y, +1,  0)]));
-    conn_list.Push(&(cell_array[Neighbor(cell_id, world_x, world_y, +1, +1)]));
-    conn_list.Push(&(cell_array[Neighbor(cell_id, world_x, world_y,  0, +1)]));
-    conn_list.Push(&(cell_array[Neighbor(cell_id, world_x, world_y, -1, +1)]));
-    conn_list.Push(&(cell_array[Neighbor(cell_id, world_x, world_y, -1,  0)]));
+
+    tList<cPopulationCell> & conn_list=cell_array[cell_id].ConnectionList();
+    if (bottom_flag && left_flag) {
+      conn_list.Push(&(cell_array[Neighbor(cell_id,world_x,world_y, -1, -1)]));
+    }
+    if (bottom_flag) {
+      conn_list.Push(&(cell_array[Neighbor(cell_id,world_x,world_y,  0, -1)]));
+    }
+    if (bottom_flag && right_flag) {
+      conn_list.Push(&(cell_array[Neighbor(cell_id,world_x,world_y, +1, -1)]));
+    }
+    if (right_flag) {
+      conn_list.Push(&(cell_array[Neighbor(cell_id,world_x,world_y, +1,  0)]));
+    }
+    if (top_flag && right_flag) {
+      conn_list.Push(&(cell_array[Neighbor(cell_id,world_x,world_y, +1, +1)]));
+    }
+    if (top_flag) {
+      conn_list.Push(&(cell_array[Neighbor(cell_id,world_x,world_y,  0, +1)]));
+    }
+    if (top_flag && left_flag) {
+      conn_list.Push(&(cell_array[Neighbor(cell_id,world_x,world_y, -1, +1)]));
+    }
+    if (left_flag) {
+      conn_list.Push(&(cell_array[Neighbor(cell_id,world_x,world_y, -1,  0)]));
+    }
 
     // Setup the reaper queue...
     if (cConfig::GetBirthMethod() == POSITION_CHILD_FULL_SOUP_ELDEST) {
@@ -181,6 +235,7 @@
 
   if ( lineage_control != NULL ) delete lineage_control;
   delete genebank;
+  delete inject_genebank;
   delete schedule;
 }
 
@@ -291,6 +346,100 @@
   return parent_alive;
 }
 
+bool cPopulation::ActivateInject(cOrganism & parent, const cGenome & injected_code)
+{
+  assert(&parent != NULL);
+  
+  if(injected_code.GetSize() ==0)
+    return false;
+
+  cHardware4Stack & parent_cpu = (cHardware4Stack &) parent.GetHardware();
+  cInjectGenotype * parent_genotype = parent_cpu.GetThreadOwner();
+  
+  const int parent_id = parent.PopInterface().GetCellID();
+  assert(parent_id >= 0 && parent_id < cell_array.GetSize());
+  cPopulationCell & parent_cell = cell_array[ parent_id ];
+
+  int num_neighbors = parent.GetNeighborhoodSize();
+  cOrganism * target_organism = 
+    parent_cell.connection_list.GetPos(g_random.GetUInt(num_neighbors))->GetOrganism();
+
+  if(target_organism==NULL)
+    return false;
+
+  cHardware4Stack & child_cpu = (cHardware4Stack &) target_organism->GetHardware();
+  
+  if(child_cpu.GetNumThreads()==cConfig::GetMaxCPUThreads())
+    return false;
+
+  cInjectGenotype * child_genotype = parent_genotype;
+
+  if(target_organism->InjectHost(parent_cpu.GetLabel(), injected_code)) {
+    // If the parent genotype is not correct for the child, adjust it.
+    if (parent_genotype == NULL || !(parent_genotype->GetGenome() == injected_code)) {
+      child_genotype = inject_genebank->AddInjectGenotype(injected_code, parent_genotype);
+    }
+    
+    target_organism->AddParasite(child_genotype);
+    child_genotype->AddParasite();
+    //if(parent_genotype!=NULL)
+    //  parent_genotype->RemoveParasite();
+    inject_genebank->AdjustInjectGenotype(*child_genotype);
+  }
+  else
+    return false;
+
+  return true;
+
+  // And set the genotype now that we know it.
+  //child_array[i]->SetGenotype(child_genotype);
+  //parent_genotype->SetBreedStats(*child_genotype);
+  
+  // We want to make sure that the child's genotype is not deleted from the
+  // genebank before the child is placed.
+  //child_genotype->IncDeferAdjust();
+  
+  // **THIS WILL BE NECESSARY IF/WHEN WE IMPLEMENT PARASITE LINEAGES.**
+  // Do lineage tracking for the new creature, if necessary.  Must occur
+  // before old organism is removed.
+  //LineageSetupOrganism( child_array[i], parent_organism.GetLineage(),
+  //			  parent_organism.GetLineageLabel(), parent_genotype );
+  
+  // **THIS WILL BE NECESSARY ONCE WE IMPLEMENT PARASITE MUTATION RATES.**
+  //child_array[i]->MutationRates().
+  //  Copy(GetCell(target_cells[i]).MutationRates());
+  
+  // Do any statistics on the parent that just gave birth...
+  //parent_genotype->AddGestationTime( parent_phenotype.GetGestationTime() );
+  //parent_genotype->AddFitness(       parent_phenotype.GetFitness()       );
+  //parent_genotype->AddMerit(         parent_phenotype.GetMerit()         );
+  //parent_genotype->AddCopiedSize(    parent_phenotype.GetCopiedSize()    );
+  //parent_genotype->AddExecutedSize(  parent_phenotype.GetExecutedSize()  );
+
+  // Place all of the offspring...
+  /*for (int i = 0; i < child_array.GetSize(); i++) {
+    ActivateOrganism(child_array[i], GetCell(target_cells[i]));
+    cGenotype * child_genotype = child_array[i]->GetGenotype();
+    child_genotype->DecDeferAdjust();
+    genebank->AdjustGenotype(*child_genotype);
+    }*/
+}
+
+bool cPopulation::ActivateInject(const int cell_id, const cGenome & injected_code)
+{
+  cInjectGenotype * child_genotype = inject_genebank->AddInjectGenotype(injected_code);
+
+  if(cell_array[cell_id].GetOrganism()->InjectHost(cCodeLabel(), injected_code))
+    {
+      cell_array[cell_id].GetOrganism()->AddParasite(child_genotype);
+      child_genotype->AddParasite();
+      inject_genebank->AdjustInjectGenotype(*child_genotype);
+    }
+  else
+    return false;
+
+  return true;
+}
 
 void cPopulation::ActivateOrganism(cOrganism * in_organism,
 				   cPopulationCell & target_cell)
@@ -347,7 +496,6 @@
 		      in_organism->GetPhenotype().ParentTrue());
 }
 
-
 void cPopulation::KillOrganism(cPopulationCell & in_cell)
 {
   // do we actually have something to kill?
@@ -370,11 +518,15 @@
   // Do statistics
   num_organisms--;
 
-  if (organism->GetPhenotype().IsParasite() == true) {
-    genotype->AddParasite();
-  }
+  //if (organism->GetPhenotype().IsParasite() == true) {
+  //  genotype->AddParasite();
+  //}
   genotype->RemoveOrganism();
-
+  
+  for(int i=0; i<organism->GetNumParasites(); i++) {
+    organism->GetParasite(i).RemoveParasite();
+  }
+      
   // And clear it!
   in_cell.RemoveOrganism();
   delete organism;
@@ -386,7 +538,6 @@
   genebank->AdjustGenotype(*genotype);
 }
 
-
 /**
  * This function is responsible for adding an organism to a given lineage,
  * and setting the organism's lineage label and the lineage pointer.
@@ -1039,6 +1190,7 @@
 	 << mem.AsString() << endl;
     }
   }
+  return true;
 }
 
 bool cPopulation::OK()
@@ -1070,8 +1222,8 @@
  * this organism.
  **/
 
-void cPopulation::Inject(const cGenome & genome, int cell_id, double merit,
-			 int lineage_label, double neutral )
+void cPopulation::Inject(const cGenome & genome, int cell_id, double merit, 
+			 int lineage_label, double neutral, int mem_space )
 {
   // If an invalid cell was given, choose a new ID for it.
   if (cell_id < 0) {
@@ -1083,17 +1235,23 @@
     }
   }
 
-  InjectGenome( cell_id, genome );
-  cPhenotype & phenotype = GetCell(cell_id).GetOrganism()->GetPhenotype();
-  phenotype.SetNeutralMetric(neutral);
-
-  if (merit > 0) phenotype.SetMerit( cMerit(merit) );
-  schedule->Adjust(cell_id, phenotype.GetMerit());
-
-  LineageSetupOrganism(GetCell(cell_id).GetOrganism(), 0, lineage_label);
+  if(mem_space==0) {
+    InjectGenome( cell_id, genome);
+    cPhenotype & phenotype = GetCell(cell_id).GetOrganism()->GetPhenotype();
+    phenotype.SetNeutralMetric(neutral);
+    
+    if (merit > 0) phenotype.SetMerit( cMerit(merit) );
+    schedule->Adjust(cell_id, phenotype.GetMerit());
+    
+    LineageSetupOrganism(GetCell(cell_id).GetOrganism(), 0, lineage_label);
+  }
+  else
+    {
+      ActivateInject(cell_id, genome);
+    }
+      
 }
 
-
 cPopulationCell & cPopulation::GetCell(int in_num)
 {
   return cell_array[in_num];
@@ -1296,4 +1454,25 @@
     transfer_pool[j] = transfer_pool.back();
     transfer_pool.pop_back();
   }
+}
+
+void cPopulation::ParasiteDebug()
+{
+  ofstream outfile;
+  outfile.open("debug.out", ofstream::app);
+  outfile << stats.GetUpdate() << endl;
+  int total=0;
+  for(int x=0; x<cell_array.GetSize(); x++)
+    {
+      if(cell_array[x].GetOrganism()!=NULL)
+	{
+	  assert(cell_array[x].GetOrganism()->GetNumParasites()>=0 && 
+		 cell_array[x].GetOrganism()->GetNumParasites()<=1);
+	  total+=cell_array[x].GetOrganism()->GetNumParasites();
+	  if(cell_array[x].GetOrganism()->GetNumParasites())
+	    outfile << x << " ";
+	}
+    }
+  outfile << endl << total << endl;
+  outfile.close();
 }
Index: avida/current/source/main/population.hh
diff -u avida/current/source/main/population.hh:1.55 avida/current/source/main/population.hh:1.55.6.1
--- avida/current/source/main/population.hh:1.55	Sat May 17 14:54:55 2003
+++ avida/current/source/main/population.hh	Mon Aug 11 15:01:31 2003
@@ -26,6 +26,7 @@
 class cGenebank;
 class cGenome;
 class cGenotype;
+class cInjectGenebank;
 class cLineage;
 class cLineageControl;
 class cOrganism;
@@ -33,7 +34,6 @@
 class sReproData;
 class cSchedule;
 
-
 class cPopulation {
 private:
   // Components...
@@ -45,6 +45,7 @@
   // Data Tracking...
   cStats stats;                      // Main statistics object...
   cGenebank * genebank;                // Tracks genotypes
+  cInjectGenebank * inject_genebank;   // Tracks all injected code
   cLineageControl * lineage_control;   // Tracks Linages
   tList<cPopulationCell> reaper_queue; // Death order in some mass-action runs
 
@@ -100,9 +101,12 @@
   // Activate the offspring of an organism in the population
   bool ActivateOffspring(cGenome & child_genome, cOrganism & parent_organism);
 
-  // Inject and organism from the outside world.
+  bool ActivateInject(cOrganism & parent, const cGenome & injected_code);
+  bool ActivateInject(const int cell_id, const cGenome & injected_code);
+
+  // Inject an organism from the outside world.
   void Inject(const cGenome & genome, int cell_id=-1, double merit=-1,
-	      int lineage_label=0, double neutral_metric=0 );
+	      int lineage_label=0, double neutral_metric=0, int mem_space=0 );
 
   // Deactivate an organism in the population (required for deactivations)
   void KillOrganism(cPopulationCell & in_cell);
@@ -149,12 +153,14 @@
 
   cStats & GetStats() { return stats; }
   cGenebank & GetGenebank() { return *genebank; }
+  cInjectGenebank & GetInjectGenebank() { return *inject_genebank; }
   cLineageControl * GetLineageControl() { return lineage_control; }
   cEnvironment & GetEnvironment() { return environment; }
   int GetNumOrganisms() { return num_organisms; }
 
   bool GetSyncEvents() { return sync_events; }
   void SetSyncEvents(bool _in) { sync_events = _in; }
+  void ParasiteDebug();
 };
 
 #endif
Index: avida/current/source/main/population_cell.cc
diff -u avida/current/source/main/population_cell.cc:1.8 avida/current/source/main/population_cell.cc:1.8.6.1
--- avida/current/source/main/population_cell.cc:1.8	Sat May 17 02:48:10 2003
+++ avida/current/source/main/population_cell.cc	Mon Aug 11 15:01:31 2003
@@ -82,13 +82,17 @@
   return input_array[cur_input++];
 }
 
+int cPopulationCell::GetInputAt(int & input_pointer)
+{
+  if (input_pointer >= IO_SIZE) input_pointer = 0;
+  return input_array[input_pointer++];
+}
 
 int cPopulationCell::GetInput(int id)
 {
   assert(id >= 0 && id < IO_SIZE);
   return input_array[id];
 }
-
 
 void cPopulationCell::InsertOrganism(cOrganism & new_org)
 {
Index: avida/current/source/main/population_cell.hh
diff -u avida/current/source/main/population_cell.hh:1.7 avida/current/source/main/population_cell.hh:1.7.6.1
--- avida/current/source/main/population_cell.hh:1.7	Sat May 17 02:48:10 2003
+++ avida/current/source/main/population_cell.hh	Mon Aug 11 15:01:31 2003
@@ -52,7 +52,8 @@
   const cMutationRates & MutationRates() const { return mutation_rates; }
   cMutationRates & MutationRates() { return mutation_rates; }
   int GetInput();
-  int GetInput(int id);
+  int GetInput(int);
+  int GetInputAt(int & input_pointer);
 
   int GetID() const { return cell_id; }
   int GetOrganismCount() const { return organism_count; }
Index: avida/current/source/main/reaction_result.cc
diff -u avida/current/source/main/reaction_result.cc:1.3 avida/current/source/main/reaction_result.cc:1.3.2.1
--- avida/current/source/main/reaction_result.cc:1.3	Tue Jun 24 14:56:39 2003
+++ avida/current/source/main/reaction_result.cc	Mon Aug 11 15:01:31 2003
@@ -18,8 +18,8 @@
   , reactions_triggered(num_reactions)
   , bonus_add(0.0)
   , bonus_mult(1.0)
-  , active_reaction(false)
   , lethal(false)
+  , active_reaction(false)
 {
 }
 
@@ -76,10 +76,10 @@
   resources_detected[id] += num;
 }
 
-void cReactionResult::Lethal(bool num)
+void cReactionResult::Lethal(bool flag)
 {
  ActivateReaction();
- lethal = true;
+ lethal = flag;
 }
 
 void cReactionResult::MarkTask(int id)
Index: avida/current/source/main/reaction_result.hh
diff -u avida/current/source/main/reaction_result.hh:1.2 avida/current/source/main/reaction_result.hh:1.2.2.1
--- avida/current/source/main/reaction_result.hh:1.2	Tue Jun 24 14:56:39 2003
+++ avida/current/source/main/reaction_result.hh	Mon Aug 11 15:01:31 2003
@@ -20,10 +20,7 @@
   double bonus_add;
   double bonus_mult;
   bool lethal;
-  
-
   bool active_reaction;
-
   inline void ActivateReaction();
 public:
   cReactionResult(const int num_resources, const int num_tasks,
Index: avida/current/source/qt-viewer/event_chooser.cpp
diff -u avida/current/source/qt-viewer/event_chooser.cpp:1.2 avida/current/source/qt-viewer/event_chooser.cpp:1.2.2.1
--- avida/current/source/qt-viewer/event_chooser.cpp:1.2	Wed Jun  4 11:34:56 2003
+++ avida/current/source/qt-viewer/event_chooser.cpp	Mon Aug 11 15:01:32 2003
@@ -1,8 +1,8 @@
 /****************************************************************************
 ** Form implementation generated from reading ui file 'event_chooser.ui'
 **
-** Created: Wed Jun 4 14:01:36 2003
-**      by: The User Interface Compiler ($Id: event_chooser.cpp,v 1.2 2003/06/04 18:34:56 goingssh Exp $)
+** Created: Thu Jul 17 13:13:41 2003
+**      by: The User Interface Compiler ($Id: event_chooser.cpp,v 1.2.2.1 2003/08/11 22:01:32 goingssh Exp $)
 **
 ** WARNING! All changes made in this file will be lost!
 ****************************************************************************/
Index: avida/current/source/qt-viewer/event_list_editor.cpp
diff -u avida/current/source/qt-viewer/event_list_editor.cpp:1.2 avida/current/source/qt-viewer/event_list_editor.cpp:1.2.2.1
--- avida/current/source/qt-viewer/event_list_editor.cpp:1.2	Wed Jun  4 11:34:56 2003
+++ avida/current/source/qt-viewer/event_list_editor.cpp	Mon Aug 11 15:01:32 2003
@@ -1,8 +1,8 @@
 /****************************************************************************
 ** Form implementation generated from reading ui file 'event_list_editor.ui'
 **
-** Created: Wed Jun 4 14:01:35 2003
-**      by: The User Interface Compiler ($Id: event_list_editor.cpp,v 1.2 2003/06/04 18:34:56 goingssh Exp $)
+** Created: Thu Jul 17 13:13:47 2003
+**      by: The User Interface Compiler ($Id: event_list_editor.cpp,v 1.2.2.1 2003/08/11 22:01:32 goingssh Exp $)
 **
 ** WARNING! All changes made in this file will be lost!
 ****************************************************************************/
Index: avida/current/source/qt-viewer/godbox.cpp
diff -u avida/current/source/qt-viewer/godbox.cpp:1.2 avida/current/source/qt-viewer/godbox.cpp:1.2.2.1
--- avida/current/source/qt-viewer/godbox.cpp:1.2	Wed Jun  4 11:34:56 2003
+++ avida/current/source/qt-viewer/godbox.cpp	Mon Aug 11 15:01:32 2003
@@ -1,8 +1,8 @@
 /****************************************************************************
 ** Form implementation generated from reading ui file 'godbox.ui'
 **
-** Created: Wed Jun 4 14:01:34 2003
-**      by: The User Interface Compiler ($Id: godbox.cpp,v 1.2 2003/06/04 18:34:56 goingssh Exp $)
+** Created: Thu Jul 17 13:14:01 2003
+**      by: The User Interface Compiler ($Id: godbox.cpp,v 1.2.2.1 2003/08/11 22:01:32 goingssh Exp $)
 **
 ** WARNING! All changes made in this file will be lost!
 ****************************************************************************/
Index: avida/current/source/qt-viewer/plot_select_dia.cpp
diff -u avida/current/source/qt-viewer/plot_select_dia.cpp:1.2 avida/current/source/qt-viewer/plot_select_dia.cpp:1.2.2.1
--- avida/current/source/qt-viewer/plot_select_dia.cpp:1.2	Wed Jun  4 11:34:56 2003
+++ avida/current/source/qt-viewer/plot_select_dia.cpp	Mon Aug 11 15:01:32 2003
@@ -1,8 +1,8 @@
 /****************************************************************************
 ** Form implementation generated from reading ui file 'plot_select_dia.ui'
 **
-** Created: Wed Jun 4 14:01:33 2003
-**      by: The User Interface Compiler ($Id: plot_select_dia.cpp,v 1.2 2003/06/04 18:34:56 goingssh Exp $)
+** Created: Thu Jul 17 13:13:56 2003
+**      by: The User Interface Compiler ($Id: plot_select_dia.cpp,v 1.2.2.1 2003/08/11 22:01:32 goingssh Exp $)
 **
 ** WARNING! All changes made in this file will be lost!
 ****************************************************************************/
Index: avida/current/source/qt-viewer/wizard.ui
diff -u avida/current/source/qt-viewer/wizard.ui:1.8 avida/current/source/qt-viewer/wizard.ui:1.8.2.1
--- avida/current/source/qt-viewer/wizard.ui:1.8	Fri May 30 14:40:36 2003
+++ avida/current/source/qt-viewer/wizard.ui	Mon Aug 11 15:01:32 2003
@@ -1,4 +1,4 @@
-<!DOCTYPE UI><UI version="3.1" stdsetdef="1">
+<!DOCTYPE UI><UI version="3.2" stdsetdef="1">
 <class>SetupAssistant</class>
 <widget class="QWizard">
     <property name="name">
Index: avida/current/source/support/Makefile.am
diff -u avida/current/source/support/Makefile.am:1.11 avida/current/source/support/Makefile.am:1.11.2.1
--- avida/current/source/support/Makefile.am:1.11	Thu May 22 11:58:53 2003
+++ avida/current/source/support/Makefile.am	Mon Aug 11 15:01:32 2003
@@ -4,7 +4,9 @@
 	events.cfg \
 	genesis \
 	inst_set.default \
-	organism.default 
+	organism.default \
+	inst_set.4stack \
+	genesis.4stack
 
 SUBDIRS = preset_organisms
 
Index: avida/current/source/support/genesis
diff -u avida/current/source/support/genesis:1.41 avida/current/source/support/genesis:1.41.2.1
--- avida/current/source/support/genesis:1.41	Mon Jun  9 13:59:27 2003
+++ avida/current/source/support/genesis	Mon Aug 11 15:01:32 2003
@@ -13,6 +13,8 @@
 			# 1 = MAX_UPDATES _AND_ MAX_GENERATIONS is reached
 WORLD-X 60		# Width of the world in Avida mode.
 WORLD-Y 60		# Height of the world in Avida mode.
+WORLD_GEOMETRY 2        # 1 = Bounded Grid
+                        # 2 = Torus (Default)
 RANDOM_SEED 0		# Random number seed. (0 for based on time)
 HARDWARE_TYPE 0		# 0 = Original CPUs
 			# 1 = New, Stack-based CPUs
Index: avida/current/source/support/preset_organisms/Makefile.am
diff -u avida/current/source/support/preset_organisms/Makefile.am:1.2 avida/current/source/support/preset_organisms/Makefile.am:1.2.2.1
--- avida/current/source/support/preset_organisms/Makefile.am:1.2	Thu May 22 11:58:53 2003
+++ avida/current/source/support/preset_organisms/Makefile.am	Mon Aug 11 15:01:33 2003
@@ -1,6 +1,8 @@
 
 presetsdir = $(datadir)/preset_organisms
 
-presets_DATA = dummy
+presets_DATA = dummy \
+	organism.4stack \
+	organism.parasite
 
 EXTRA_DIST = $(presets_DATA)
Index: avida/current/source/tools/datafile.cc
diff -u avida/current/source/tools/datafile.cc:1.10 avida/current/source/tools/datafile.cc:1.10.6.1
--- avida/current/source/tools/datafile.cc:1.10	Sat May 17 02:48:15 2003
+++ avida/current/source/tools/datafile.cc	Mon Aug 11 15:01:33 2003
@@ -81,6 +81,14 @@
   }
 }
 
+void cDataFile::WriteBlockElement(int i, int element, int x_size)
+{
+  m_fp << i << " ";
+  if (((element + 1) % x_size) == 0) {
+    m_fp << "\n";
+  }
+}
+
 void cDataFile::WriteColumnDesc( const char * descr )
 {
   if ( !m_descr_written ){
Index: avida/current/source/tools/datafile.hh
diff -u avida/current/source/tools/datafile.hh:1.13 avida/current/source/tools/datafile.hh:1.13.6.1
--- avida/current/source/tools/datafile.hh:1.13	Sat May 17 02:48:15 2003
+++ avida/current/source/tools/datafile.hh	Mon Aug 11 15:01:33 2003
@@ -99,6 +99,7 @@
   void Write( int i,                 const char * descr );
   void Write( const char * data_str, const char * descr );
   void WriteBlockElement (double x, int element, int x_size );
+  void WriteBlockElement (int i, int element, int x_size );
 
   /**
    * Writes a descriptive string into a data file. The string is only
Index: avida/current/source/viewers/Makefile.am
diff -u avida/current/source/viewers/Makefile.am:1.15 avida/current/source/viewers/Makefile.am:1.15.2.1
--- avida/current/source/viewers/Makefile.am:1.15	Thu May 22 11:58:54 2003
+++ avida/current/source/viewers/Makefile.am	Mon Aug 11 15:01:33 2003
@@ -5,6 +5,7 @@
 
 viewer_SOURCES = ansi.cc		ansi.hh			\
 		bar_screen.cc		bar_screen.hh		\
+		environment_screen.cc	environment_screen.hh	\
 		hist_screen.cc		hist_screen.hh		\
 		map_screen.cc		map_screen.hh		\
 		menu.cc			menu.hh			\
Index: avida/current/source/viewers/bar_screen.cc
diff -u avida/current/source/viewers/bar_screen.cc:1.7 avida/current/source/viewers/bar_screen.cc:1.7.6.1
--- avida/current/source/viewers/bar_screen.cc:1.7	Sat May 17 02:48:16 2003
+++ avida/current/source/viewers/bar_screen.cc	Mon Aug 11 15:01:33 2003
@@ -7,6 +7,7 @@
 
 #include "../main/population.hh"
 #include "../main/stats.hh"
+#include "../main/environment.hh"
 
 #include "bar_screen.hh"
 
@@ -23,21 +24,39 @@
   SetBoldColor(COLOR_WHITE);
 
   Box();
-  VLine(19);
-  VLine(Width() - 14);
+  VLine(18);
+  
 
-  int offset = 7 + (prog_name.GetSize() + 1) / 2;
+  int offset = prog_name.GetSize() + 4;
+  VLine(Width() - offset - 2);
   Print(1, Width() - offset, "%s", prog_name());
 
-  Print(1, 3, "Update:");
-  Print(1, 22, "[M]ap  [S]tats  [O]ptions  [Z]oom  [Q]uit");
+  Print(1, 2, "Update:");
+
+  if(info.GetPopulation().GetEnvironment().GetResourceLib().GetSize() > 0)
+    Print(1, 20, "[M]ap [S]tats [O]ptions [Z]oom [E]nviron [Q]uit");
+  else
+    Print(1, 20, "[M]ap  [S]tats  [O]ptions  [Z]oom  [Q]uit");
 
   SetBoldColor(COLOR_CYAN);
-  Print(1, 23, 'M');
-  Print(1, 30, 'S');
-  Print(1, 39, 'O');
-  Print(1, 50, 'Z');
-  Print(1, 58, 'Q');
+
+  if(info.GetPopulation().GetEnvironment().GetResourceLib().GetSize() > 0)
+    {
+      Print(1, 21, 'M');
+      Print(1, 27, 'S');
+      Print(1, 35, 'O');
+      Print(1, 45, 'Z');
+      Print(1, 52, 'E');
+      Print(1, 62, 'Q');
+    }
+  else
+    {
+      Print(1, 21, 'M');
+      Print(1, 28, 'S');
+      Print(1, 37, 'O');
+      Print(1, 48, 'Z');
+      Print(1, 56, 'Q');
+    }
 
   Refresh();
 }
Index: avida/current/source/viewers/map_screen.cc
diff -u avida/current/source/viewers/map_screen.cc:1.10 avida/current/source/viewers/map_screen.cc:1.10.6.1
--- avida/current/source/viewers/map_screen.cc:1.10	Sat May 17 02:48:16 2003
+++ avida/current/source/viewers/map_screen.cc	Mon Aug 11 15:01:33 2003
@@ -24,7 +24,6 @@
 cMapScreen::cMapScreen(int _y_size, int _x_size, int _y_start,
       int _x_start, cViewInfo & in_info, cPopulation & in_pop) :
   cScreen(_y_size, _x_size, _y_start, _x_start, in_info),
-  mode(MAP_BASIC),
   x_size(in_pop.GetWorldX()),
   y_size(in_pop.GetWorldY()),
   population(in_pop)
@@ -37,6 +36,12 @@
 {
 }
 
+void cMapScreen::Draw()
+{
+  CenterActiveCPU();
+  Update();
+ 
+}
 void cMapScreen::Update()
 {
   // Get working in multiple modes!!
@@ -45,17 +50,17 @@
 
   const int name_x = Width() - 20;
   const int name_y = Height() - 1;
-  if (mode == MAP_BASIC)           Print(name_y, name_x, " Genotype View ");
-  else if (mode == MAP_SPECIES)    Print(name_y, name_x, " Species View  ");
-  else if (mode == MAP_COMBO)      Print(name_y, name_x, "  Combo View   ");
-  else if (mode == MAP_INJECT)     Print(name_y, name_x, " Modified View ");
-  else if (mode == MAP_RESOURCE)   Print(name_y, name_x, " Resource View ");
-  else if (mode == MAP_AGE)        Print(name_y, name_x, "   Age View    ");
-  else if (mode == MAP_BREED_TRUE) Print(name_y, name_x, "Breed True View");
-  else if (mode == MAP_PARASITE)   Print(name_y, name_x, " Parasite View ");
-  else if (mode == MAP_MUTATIONS)  Print(name_y, name_x, " Mutation View ");
-  else if (mode == MAP_THREAD)     Print(name_y, name_x, "  Thread View  ");
-  else if (mode == MAP_LINEAGE)    Print(name_y, name_x, " Lineage View  ");
+  if (info.GetMapMode() == MAP_BASIC)           Print(name_y, name_x, " Genotype View ");
+  else if (info.GetMapMode() == MAP_SPECIES)    Print(name_y, name_x, " Species View  ");
+  else if (info.GetMapMode() == MAP_COMBO)      Print(name_y, name_x, "  Combo View   ");
+  else if (info.GetMapMode() == MAP_INJECT)     Print(name_y, name_x, " Modified View ");
+  else if (info.GetMapMode() == MAP_RESOURCE)   Print(name_y, name_x, " Resource View ");
+  else if (info.GetMapMode() == MAP_AGE)        Print(name_y, name_x, "   Age View    ");
+  else if (info.GetMapMode() == MAP_BREED_TRUE) Print(name_y, name_x, "Breed True View");
+  else if (info.GetMapMode() == MAP_PARASITE)   Print(name_y, name_x, " Parasite View ");
+  else if (info.GetMapMode() == MAP_MUTATIONS)  Print(name_y, name_x, " Mutation View ");
+  else if (info.GetMapMode() == MAP_THREAD)     Print(name_y, name_x, "  Thread View  ");
+  else if (info.GetMapMode() == MAP_LINEAGE)    Print(name_y, name_x, " Lineage View  ");
 
 
   // Draw the [<] and [>] around the map mode....
@@ -76,7 +81,7 @@
   int virtual_x = corner_id % x_size;
   int virtual_y = corner_id / x_size;
 
-  info.SetupSymbolMaps(mode, HasColors());
+  info.SetupSymbolMaps(info.GetMapMode(), HasColors());
 
   for (int y = 0; y < Height() - 1 && y < y_size; y++) {
     Move(y, 0);
@@ -128,13 +133,15 @@
     break;
   case '>':
   case '.':
-    ++mode %= NUM_MAPS;
+    info.IncMapMode();
+    //++map_mode %= NUM_MAPS;
     Update();
     break;
   case '<':
   case ',':
-    mode += NUM_MAPS;
-    --mode %= NUM_MAPS;
+    info.DecMapMode();
+    //map_mode += NUM_MAPS;
+    //--map_mode %= NUM_MAPS;
     Update();
     break;
   }
Index: avida/current/source/viewers/map_screen.hh
diff -u avida/current/source/viewers/map_screen.hh:1.7 avida/current/source/viewers/map_screen.hh:1.7.8.1
--- avida/current/source/viewers/map_screen.hh:1.7	Sun Nov 11 15:21:03 2001
+++ avida/current/source/viewers/map_screen.hh	Mon Aug 11 15:01:33 2003
@@ -14,7 +14,7 @@
 
 class cMapScreen : public cScreen {
 private:
-  int mode;
+  //int mode;
 
   int x_size;
   int y_size;
@@ -33,7 +33,7 @@
   ~cMapScreen();
 
   // Virtual in base screen!
-  void Draw() { ; }
+  void Draw();
   void Update();
   void DoInput(int in_char);
 
Index: avida/current/source/viewers/symbol_util.cc
diff -u avida/current/source/viewers/symbol_util.cc:1.4 avida/current/source/viewers/symbol_util.cc:1.4.6.1
--- avida/current/source/viewers/symbol_util.cc:1.4	Sat May 17 02:48:16 2003
+++ avida/current/source/viewers/symbol_util.cc	Mon Aug 11 15:01:33 2003
@@ -13,7 +13,10 @@
 #include "../main/organism.hh"
 #include "../main/population_cell.hh"
 #include "../main/species.hh"
-
+#include "../main/config.hh"
+#include "../cpu/hardware_base.hh"
+#include "../cpu/hardware_4stack.hh"
+#include "../cpu/hardware_cpu.hh"
 
 using namespace std;
 
@@ -47,8 +50,8 @@
   // 'B' = Both         '-' = Neither
 
   if (modifier == true && modified == true)  return 'B';
-  if (modifier == true) return 'I';
-  if (modified == true) return 'H';
+  if (modifier == true) return 'I'-6;
+  if (modified == true) return 'H'-6;
   return '-';
 }
 
@@ -112,8 +115,23 @@
 //    if (thread_count < 20) return 'X';
 //    if (thread_count < 80) return 'L';
 //    if (thread_count < 200) return 'C';
-  
-  return '+';
+  //const cHardwareBase * hardware; 
+  int num_threads;
+  if(cConfig::GetHardwareType() == HARDWARE_TYPE_CPU_ORIGINAL)
+    {
+      //const cHardwareCPU & hard_cpu= (cHardwareCPU &) cell.GetOrganism()->GetHardware();
+      //num_threads = hard_cpu.GetNumThreads();
+      num_threads = ((cHardwareCPU &) cell.GetOrganism()->GetHardware()).GetNumThreads();
+      return (char) ('0' + num_threads);
+    }
+  else
+    {
+      //const cHardware4Stack & hard_4stack= (cHardware4Stack &) cell.GetOrganism()->GetHardware();
+      //num_threads = hard_4stack.GetNumThreads();
+      num_threads = ((cHardware4Stack &) cell.GetOrganism()->GetHardware()).GetNumThreads();
+      return (char) ('0' + num_threads);
+    }
+  //return '+';
 }
 
 char cSymbolUtil::GetLineageSymbol(const cPopulationCell & cell)
Index: avida/current/source/viewers/text_screen.cc
diff -u avida/current/source/viewers/text_screen.cc:1.12 avida/current/source/viewers/text_screen.cc:1.12.6.1
--- avida/current/source/viewers/text_screen.cc:1.12	Sat May 17 14:23:26 2003
+++ avida/current/source/viewers/text_screen.cc	Mon Aug 11 15:01:33 2003
@@ -28,6 +28,7 @@
   saved_inst_set = NULL;
   thread_lock = -1;
   step_organism_id = -1;
+  map_mode=0;
 
   // Handle genotype & species managing...
 
@@ -81,7 +82,8 @@
     map_method = &cSymbolUtil::GetSpeciesSymbol;
     break;
   case MAP_INJECT:
-    map_method = &cSymbolUtil::GetModifiedSymbol;
+    if (use_color) color_method = &cSymbolUtil::GetModifiedSymbol;
+    else map_method = &cSymbolUtil::GetModifiedSymbol;
     break;
   case MAP_RESOURCE:
     map_method = &cSymbolUtil::GetResourceSymbol;
@@ -102,8 +104,8 @@
     else map_method = &cSymbolUtil::GetMutSymbol;
     break;
   case MAP_THREAD:
-    if (use_color) color_method = &cSymbolUtil::GetThreadSymbol;
-    else map_method = &cSymbolUtil::GetThreadSymbol;
+    //if (use_color) color_method = &cSymbolUtil::GetThreadSymbol;
+    map_method = &cSymbolUtil::GetThreadSymbol;
     break;
   case MAP_LINEAGE:
     if (use_color) color_method = &cSymbolUtil::GetLineageSymbol;
Index: avida/current/source/viewers/text_screen.hh
diff -u avida/current/source/viewers/text_screen.hh:1.10 avida/current/source/viewers/text_screen.hh:1.10.6.1
--- avida/current/source/viewers/text_screen.hh:1.10	Sat May 17 14:54:55 2003
+++ avida/current/source/viewers/text_screen.hh	Mon Aug 11 15:01:34 2003
@@ -59,6 +59,7 @@
   int pause_level;
   int thread_lock;
   int step_organism_id;
+  int map_mode;
 
   // Instruction Libraries.
   cInstSet const * saved_inst_set;
@@ -86,7 +87,10 @@
   tArray<char> & GetColorMap() { return color_map; }
   char & MapSymbol(int pos) { return map[pos]; }
   char & ColorSymbol(int pos) { return color_map[pos]; }
-
+  int GetMapMode() { return map_mode; }
+  void IncMapMode() { ++map_mode%=NUM_MAPS; }
+  void DecMapMode();
+    
   void EngageStepMode();
   void DisEngageStepMode();
 
@@ -145,6 +149,12 @@
 //  cViewInfo
 ///////////////
 
+inline void cViewInfo::DecMapMode()
+{
+  map_mode+=NUM_MAPS; 
+  --map_mode %= NUM_MAPS; 
+}
+
 inline bool cViewInfo::InGenChart(cGenotype * in_gen)
 {
   for (int i = 0; i < NUM_SYMBOLS; i++) {
@@ -199,7 +209,7 @@
     break;
   case '0':
   default:
-    SetBoldColor(COLOR_OFF);
+    SetColor(COLOR_WHITE);
     break;
   }
 }
Index: avida/current/source/viewers/view.cc
diff -u avida/current/source/viewers/view.cc:1.10 avida/current/source/viewers/view.cc:1.10.6.1
--- avida/current/source/viewers/view.cc:1.10	Sat May 17 02:48:16 2003
+++ avida/current/source/viewers/view.cc	Mon Aug 11 15:01:34 2003
@@ -29,6 +29,7 @@
 #include "hist_screen.hh"
 #include "options_screen.hh"
 #include "zoom_screen.hh"
+#include "environment_screen.hh"
 
 
 using namespace std;
@@ -52,6 +53,7 @@
   hist_screen    = new cHistScreen    (0,0,3,0,info, in_population);
   options_screen = new cOptionsScreen (0,0,3,0,info);
   zoom_screen    = new cZoomScreen    (0,0,3,0,info, in_population);
+  environment_screen = new cEnvironmentScreen (0,0,3,0,info, in_population);
 
   info.SetActiveCell( &( in_population.GetCell(0) ) );
 }
@@ -63,6 +65,7 @@
   if (hist_screen) delete hist_screen;
   if (options_screen) delete options_screen;
   if (zoom_screen) delete zoom_screen;
+  if (environment_screen) delete environment_screen;
 
   EndProg(0);
 }
@@ -94,6 +97,8 @@
     cur_screen = options_screen;
   } else if (in_mode == MODE_ZOOM) {
     cur_screen = zoom_screen;
+  } else if (in_mode == MODE_ENVIRONMENT) {
+    cur_screen = environment_screen;
   }
 }
 
@@ -120,11 +125,12 @@
 void cView::NotifyUpdate()
 {
   // If we're locked onto a specific thread, only stop for it.
-  if (info.GetPauseLevel() == PAUSE_ADVANCE_STEP &&
+  /*if (info.GetPauseLevel() == PAUSE_ADVANCE_STEP &&
       info.GetThreadLock() != -1  &&
       info.GetThreadLock() != info.GetActiveCell()->GetOrganism()->GetHardware().ViewerLock()){
     return;
-  }
+    }*/
+
 
   bar_screen->Update();
   info.UpdateSymbols();
@@ -233,6 +239,11 @@
     case 'p':
     case 'P':
       TogglePause();
+      break;
+    case 'e':
+    case 'E':
+      if(info.GetPopulation().GetEnvironment().GetResourceLib().GetSize() > 0)
+	ChangeCurScreen(environment_screen);
       break;
     case 's':
     case 'S':
Index: avida/current/source/viewers/view.hh
diff -u avida/current/source/viewers/view.hh:1.9 avida/current/source/viewers/view.hh:1.9.8.1
--- avida/current/source/viewers/view.hh:1.9	Sun Nov 11 15:21:03 2001
+++ avida/current/source/viewers/view.hh	Mon Aug 11 15:01:34 2003
@@ -15,6 +15,7 @@
 #define MODE_HIST    3
 #define MODE_OPTIONS 4
 #define MODE_ZOOM    5
+#define MODE_ENVIRONMENT 6
 
 #include "text_screen.hh"
 
@@ -25,6 +26,7 @@
 class cHistScreen;
 class cOptionsScreen;
 class cZoomScreen;
+class cEnvironmentScreen;
 
 class cView {
 private:
@@ -34,12 +36,12 @@
   static cTextWindow * base_window;
   static cScreen * cur_screen;
   static cBarScreen * bar_screen;
-
   cMapScreen * map_screen;
   cStatsScreen * stats_screen;
   cHistScreen * hist_screen;
   cOptionsScreen * options_screen;
   cZoomScreen * zoom_screen;
+  cEnvironmentScreen * environment_screen;
 
   // Window managing functions...
 
Index: avida/current/source/viewers/zoom_screen.cc
diff -u avida/current/source/viewers/zoom_screen.cc:1.25 avida/current/source/viewers/zoom_screen.cc:1.25.2.1
--- avida/current/source/viewers/zoom_screen.cc:1.25	Thu Jun  5 13:14:42 2003
+++ avida/current/source/viewers/zoom_screen.cc	Mon Aug 11 15:01:34 2003
@@ -40,7 +40,7 @@
   memory_offset = 0;
   parasite_zoom = false;
   mode = ZOOM_MODE_STATS;
-  map_mode = MAP_BASIC;
+  //map_mode = MAP_BASIC;
   inst_view_mode = true;
   active_section = ZOOM_SECTION_MEMORY;
   task_offset = 0;
@@ -49,7 +49,7 @@
   cur_mem_space=0;
   cur_view_thread=0;
 
-  map_mode = MAP_BASIC;
+  //map_mode = MAP_BASIC;
   mini_center_id = 0;
   map_x_size = population.GetWorldX();
   map_y_size = population.GetWorldY();
@@ -80,7 +80,7 @@
   if (info.GetPauseLevel()) {
     Print(OPTIONS_Y+2, OPTIONS_X+6, "P");
     Print(OPTIONS_Y+3, OPTIONS_X+3, "N");
-    Print(OPTIONS_Y+4, OPTIONS_X+3, "Space");
+    //Print(OPTIONS_Y+4, OPTIONS_X+3, "Space");
   } else {
     Print(OPTIONS_Y+2, OPTIONS_X+3, "P");
   }
@@ -697,6 +697,7 @@
 void cZoomScreen::UpdateCPU_Original(cHardwareBase & hardware)
 {
   cHardwareCPU & hardwareCPU = (cHardwareCPU &) hardware;
+  //hardwareCPU.SetThread(cur_view_thread);
 
   // Place the registers onto the screen.
   SetBoldColor(COLOR_CYAN);
@@ -833,12 +834,19 @@
 void cZoomScreen::UpdateCPU_4Stack(cHardwareBase & hardware)
 {
   cHardware4Stack & hardware4Stack = (cHardware4Stack &) hardware;
-  hardware4Stack.SetThread(cur_view_thread);
+  
+  if(cur_view_thread>=hardware4Stack.GetNumThreads())
+    {
+      cur_view_thread=0;
+      cur_mem_space = hardware4Stack.IP(cur_view_thread).GetMemSpace();
+    }
+  //hardware4Stack.SetThread(cur_view_thread);
+  c4StackHead & cur_ip = hardware4Stack.IP(cur_view_thread);
 
-  // Place the registers onto the screen.
+  // Place the stacks onto the screen.
   SetBoldColor(COLOR_CYAN);
   for (int i = 0; i < 4; i++) {
-    Print(REG_Y+2 + i, REG_X+6, "%11d", hardware4Stack.Stack(i).Top());
+    Print(REG_Y+2 + i, REG_X+6, "%11d", hardware4Stack.Stack(i, cur_view_thread).Top());
   }
 
   // Place the active stack onto the screen.
@@ -851,13 +859,13 @@
   Print(STACK_Y, STACK_X + 8, "%s" , hardware4Stack.GetActiveStackID(cur_stack)());
 
   //SetBoldColor(COLOR_CYAN);
-  Print(STACK_Y+2, STACK_X + 2, "%11d", hardware4Stack.GetStack(0, cur_stack));
+  //Print(STACK_Y+2, STACK_X + 2, "%11d", hardware4Stack.GetStack(0, cur_stack));
   SetColor(COLOR_CYAN);
-  for (int i = 1; i <= 3; i++) {
-    Print(STACK_Y+2 + i, STACK_X+2, "%11d", hardware4Stack.GetStack(i, cur_stack));
+  for (int i = 0; i <= 3; i++) {
+    Print(STACK_Y+2 + i, STACK_X+2, "%11d", hardware4Stack.GetStack(i, cur_stack, cur_view_thread));
    }
 
-  Print(19, 74, "%2d/%2d", hardware4Stack.GetCurThread() + 1,
+  Print(19, 74, "%2d/%2d", cur_view_thread + 1,
 	hardware4Stack.GetNumThreads());
   
   // This line gets the creature that is currently executing. Usually the
@@ -884,7 +892,7 @@
   }
   
   int adj_inst_ptr = 0;
-  int base_inst_ptr = hardware4Stack.IP().GetPosition();
+  int base_inst_ptr = cur_ip.GetPosition();
   if (base_inst_ptr < 0 || parasite_zoom == true) base_inst_ptr = 0;
 
   const cInstSet & inst_set = hardware4Stack.GetInstSet();
@@ -906,7 +914,7 @@
       // If we are on the instruction about to be executed by the CPU,
       // hilight it...
       if (adj_inst_ptr == base_inst_ptr && 
-	  hardware4Stack.IP().GetMemSpace() == cur_mem_space) {
+	  hardware4Stack.IP(cur_view_thread).GetMemSpace() == cur_mem_space) {
 	SetBoldColor(COLOR_WHITE);
 	Print(MEMORY_Y + MEMORY_PRE_SIZE + 3 + i, MEMORY_X + 1, "%3d: ",
 		  adj_inst_ptr);
@@ -947,16 +955,16 @@
 	Print(MEMORY_Y + MEMORY_PRE_SIZE + 3 + i, MEMORY_X + 28, "Bp");
       }
 
-      if (adj_inst_ptr == hardware4Stack.GetHead(HEAD_READ).GetPosition() &&
-	  cur_mem_space == hardware4Stack.GetHead(HEAD_READ).GetMemSpace()) {
+      if (adj_inst_ptr == hardware4Stack.GetHead(HEAD_READ, cur_view_thread).GetPosition() &&
+	  cur_mem_space == hardware4Stack.GetHead(HEAD_READ, cur_view_thread).GetMemSpace()) {
 	Print(MEMORY_Y + MEMORY_PRE_SIZE + 3 + i, MEMORY_X + 31, "R");
       }
-      if (adj_inst_ptr == hardware4Stack.GetHead(HEAD_WRITE).GetPosition() &&
-	  cur_mem_space == hardware4Stack.GetHead(HEAD_WRITE).GetMemSpace()) {
+      if (adj_inst_ptr == hardware4Stack.GetHead(HEAD_WRITE, cur_view_thread).GetPosition() &&
+	  cur_mem_space == hardware4Stack.GetHead(HEAD_WRITE, cur_view_thread).GetMemSpace()) {
 	Print(MEMORY_Y + MEMORY_PRE_SIZE + 3 + i, MEMORY_X + 32, "W");
       }
-      if (adj_inst_ptr == hardware4Stack.GetHead(HEAD_FLOW).GetPosition() &&
-	  cur_mem_space == hardware4Stack.GetHead(HEAD_FLOW).GetMemSpace()) {
+      if (adj_inst_ptr == hardware4Stack.GetHead(HEAD_FLOW, cur_view_thread).GetPosition() &&
+	  cur_mem_space == hardware4Stack.GetHead(HEAD_FLOW, cur_view_thread).GetMemSpace()) {
 	  Print(MEMORY_Y + MEMORY_PRE_SIZE + 3 + i, MEMORY_X + 33, "F");
       }
     }
@@ -1435,6 +1443,7 @@
   return cCoords(0,0);
 }
 
+/*
 cString cZoomScreen::GetSectionName(int in_section)
 {
   switch (in_section) {
@@ -1474,6 +1483,47 @@
   }
 
   return cString("Unknown!");
+}*/
+
+char* cZoomScreen::GetSectionName(int in_section)
+{
+  switch (in_section) {
+  case ZOOM_SECTION_MEMORY:
+    if(cConfig::GetHardwareType()==HARDWARE_TYPE_CPU_ORIGINAL)
+      {
+	 return "Memory";
+      }
+    else if(cConfig::GetHardwareType()==HARDWARE_TYPE_CPU_4STACK)
+      {
+	return "Memory Space";
+      }
+    break;
+
+  case ZOOM_SECTION_REGISTERS:
+    if(cConfig::GetHardwareType()==HARDWARE_TYPE_CPU_ORIGINAL)
+      {
+	 return "Registers:";
+      }
+    else if(cConfig::GetHardwareType()==HARDWARE_TYPE_CPU_4STACK)
+      {
+	return "Stacks:";
+      }
+    break;
+
+  case ZOOM_SECTION_STACK:
+    return "Stack ";
+    break;
+
+  case ZOOM_SECTION_INPUTS:
+    return "Inputs:";
+    break;
+
+  case ZOOM_SECTION_MAP:
+    return "Mini-Map";
+    break;
+  }
+
+  return "Unknown!";
 }
 
 void cZoomScreen::SetActiveSection(int in_section)
@@ -1483,16 +1533,16 @@
     cCoords sect_coords(GetSectionCoords(active_section));
     sect_coords.Translate(2, 1);
     SetColor(COLOR_WHITE);
-    Print(sect_coords.GetY(), sect_coords.GetX(),
-	  GetSectionName(active_section)());
+    Print(sect_coords.GetY(), sect_coords.GetX(), "%s",
+	  GetSectionName(active_section));
     active_section = in_section;
   }
 
   cCoords sect_coords(GetSectionCoords(active_section));
   sect_coords.Translate(2, 1);
   SetBoldColor(COLOR_BLUE);
-  Print(sect_coords.GetY(), sect_coords.GetX(),
-	GetSectionName(active_section)());
+  Print(sect_coords.GetY(), sect_coords.GetX(), "%s",
+	GetSectionName(active_section));
   SetColor(COLOR_WHITE);
 }
 
@@ -1504,17 +1554,36 @@
   if (mode == ZOOM_MODE_STATS    && DoInputStats(in_char)) return;
   if (mode == ZOOM_MODE_GENOTYPE && DoInputGenotype(in_char)) return;
 
-  cHardware4Stack & hardware4Stack = 
-      (cHardware4Stack &) info.GetActiveCell()->GetOrganism()->GetHardware();
-
+  int num_threads;
+  if(cConfig::GetHardwareType()==HARDWARE_TYPE_CPU_ORIGINAL)
+    {
+       cHardwareCPU & hardwareCPU = 
+      (cHardwareCPU &) info.GetActiveCell()->GetOrganism()->GetHardware();
+       num_threads = hardwareCPU.GetNumThreads();
+    }
+  else if(cConfig::GetHardwareType()==HARDWARE_TYPE_CPU_4STACK)
+    {
+      cHardware4Stack & hardware4Stack = 
+	(cHardware4Stack &) info.GetActiveCell()->GetOrganism()->GetHardware();
+      num_threads = hardware4Stack.GetNumThreads();
+    }
   switch(in_char) {
   case 't':
   case 'T':
-    cur_view_thread=(cur_view_thread+1)%hardware4Stack.GetNumThreads();
-    //ThreadOptions();
-    Update();
+    if(num_threads>1)
+      {
+	memory_offset=0;
+	++cur_view_thread%=num_threads;
+	if(cConfig::GetHardwareType()==HARDWARE_TYPE_CPU_4STACK)
+	  {
+	    cHardware4Stack & hardware4Stack = 
+	      (cHardware4Stack &) info.GetActiveCell()->GetOrganism()->GetHardware();
+	    cur_mem_space=hardware4Stack.IP(cur_view_thread).GetMemSpace();
+	  }
+	//ThreadOptions();
+	Update();
+      }
     break;
-
   /*
     case 'x':
     case 'X':
@@ -1564,6 +1633,7 @@
     if (active_section == ZOOM_SECTION_MAP) {
       mini_center_id += map_x_size;
       mini_center_id %= population.GetSize();
+      cur_view_thread=0;
       if (population.GetCell(mini_center_id).IsOccupied()) {
 	memory_offset = 0;
 	info.SetActiveCell( &(population.GetCell(mini_center_id)));
@@ -1578,6 +1648,7 @@
   case KEY_UP:
     if (active_section == ZOOM_SECTION_MAP) {
       mini_center_id -= map_x_size;
+      cur_view_thread=0;
       if (mini_center_id < 0) mini_center_id += population.GetSize();
       if (population.GetCell(mini_center_id).IsOccupied()) {
 	memory_offset = 0;
@@ -1604,7 +1675,7 @@
       {
 	if(cConfig::GetHardwareType() == HARDWARE_TYPE_CPU_4STACK)
 	  {
-	    cur_mem_space=(cur_mem_space+1)%4;
+	    ++cur_mem_space%=4;
 	  }
       }
     Update(); 
@@ -1622,9 +1693,8 @@
     else if (active_section == ZOOM_SECTION_MEMORY) {
       if(cConfig::GetHardwareType()==HARDWARE_TYPE_CPU_4STACK)
 	{
-	  cur_mem_space--;
-	  if(cur_mem_space<0)
-	    cur_mem_space=3;
+	  cur_mem_space+=3;
+	  cur_mem_space%=4;
 	}
     }
     Update();
@@ -1632,7 +1702,7 @@
   case 'K':
   case 'k':
     if(cConfig::GetHardwareType()==HARDWARE_TYPE_CPU_4STACK) {
-      cur_stack=(cur_stack+1)%4;
+      ++cur_stack%=4;
     }
     Update();
     break;
@@ -1646,13 +1716,12 @@
     //break;
   case '+':
   case '=':
-    ++map_mode %= NUM_MAPS;
+    info.IncMapMode();
     Update();
     break;
   case '-':
   case '_':
-    map_mode += NUM_MAPS;
-    --map_mode %= NUM_MAPS;
+    info.DecMapMode();
     Update();
     break;
   case '\n':
@@ -1748,26 +1817,27 @@
 
   // Setup the start color for the map...
   SetColor(COLOR_WHITE);
+  mini_center_id = info.GetActiveCell()->GetID();
 
   const int name_x = MINI_MAP_X + 4;
   const int name_y = MINI_MAP_Y + 11;
-  if (mode == MAP_BASIC)           Print(name_y, name_x, "Genotypes");
-  else if (mode == MAP_SPECIES)    Print(name_y, name_x, " Species ");
-  else if (mode == MAP_COMBO)      Print(name_y, name_x, "  Combo  ");
-  else if (mode == MAP_INJECT)     Print(name_y, name_x, "Modified ");
-  else if (mode == MAP_RESOURCE)   Print(name_y, name_x, "Resources");
-  else if (mode == MAP_AGE)        Print(name_y, name_x, "   Age   ");
-  else if (mode == MAP_BREED_TRUE) Print(name_y, name_x, "BreedTrue");
-  else if (mode == MAP_PARASITE)   Print(name_y, name_x, "Parasites");
-  else if (mode == MAP_MUTATIONS)  Print(name_y, name_x, "Mutations");
-  else if (mode == MAP_THREAD)     Print(name_y, name_x, " Threads ");
-  else if (mode == MAP_LINEAGE)    Print(name_y, name_x, " Lineage ");
+  if (info.GetMapMode() == MAP_BASIC)           Print(name_y, name_x, "Genotypes");
+  else if (info.GetMapMode() == MAP_SPECIES)    Print(name_y, name_x, " Species ");
+  else if (info.GetMapMode() == MAP_COMBO)      Print(name_y, name_x, "  Combo  ");
+  else if (info.GetMapMode() == MAP_INJECT)     Print(name_y, name_x, "Modified ");
+  else if (info.GetMapMode() == MAP_RESOURCE)   Print(name_y, name_x, "Resources");
+  else if (info.GetMapMode() == MAP_AGE)        Print(name_y, name_x, "   Age   ");
+  else if (info.GetMapMode() == MAP_BREED_TRUE) Print(name_y, name_x, "BreedTrue");
+  else if (info.GetMapMode() == MAP_PARASITE)   Print(name_y, name_x, "Parasites");
+  else if (info.GetMapMode() == MAP_MUTATIONS)  Print(name_y, name_x, "Mutations");
+  else if (info.GetMapMode() == MAP_THREAD)     Print(name_y, name_x, " Threads ");
+  else if (info.GetMapMode() == MAP_LINEAGE)    Print(name_y, name_x, " Lineage ");
 
 
   int virtual_x = (mini_center_id % map_x_size) + map_x_size;
   int virtual_y = (mini_center_id / map_x_size) + map_y_size;
 
-  info.SetupSymbolMaps(mode, HasColors());
+  info.SetupSymbolMaps(info.GetMapMode(), HasColors());
 
   for (int y = -3; y <= 3 && y < map_y_size - 3; y++) {
     Move(MINI_MAP_Y + 6 + y, MINI_MAP_X + 2);
Index: avida/current/source/viewers/zoom_screen.hh
diff -u avida/current/source/viewers/zoom_screen.hh:1.8 avida/current/source/viewers/zoom_screen.hh:1.8.2.1
--- avida/current/source/viewers/zoom_screen.hh:1.8	Thu Jun  5 13:14:42 2003
+++ avida/current/source/viewers/zoom_screen.hh	Mon Aug 11 15:01:34 2003
@@ -66,7 +66,7 @@
   int map_y_size;
 
   int mode;
-  int map_mode;
+  //int map_mode;
   bool inst_view_mode;
   int memory_offset;
   bool parasite_zoom; // If true, then view original parasite code, not host
@@ -102,7 +102,8 @@
   void ViewThreads();
 
   cCoords GetSectionCoords(int in_section);
-  cString GetSectionName(int in_section);
+  //cString GetSectionName(int in_section);
+  char* GetSectionName(int in_section);
   void SetActiveSection(int in_section);
 
   void DrawMiniMap();


More information about the Avida-cvs mailing list