[avida-cvs] avida(kaben) CVS commits: /current COPYING NEWS README configure.in /current/doc environment.html events.html /current/source defs.hh /current/source/cpu cpu_memory.cc cpu_stack.hh hardware_4stack.cc hardware_4stack.hh hardware_base.hh hardware_cpu.cc hardware_cpu.hh hardware_util.cc hardware_util.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_descr.hi 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 environment.hh genebank.cc genome.hh inject_genebank.cc inject_genebank.hh inject_genotype.cc inject_genotype.hh inst_set.cc inst_set.hh inst_util.cc main_sub.pri org_message.cc org_message.hh organism.cc organism.hh phenotype.cc phenotype.hh pop_interface.cc pop_interface.hh population.cc population.hh population_cell.cc population_cell.hh reaction.cc reaction.hh reaction_result.cc reaction_result.hh tasks.cc /current/source/qt-viewer avd_driver_controller.cc event_chooser.cpp event_chooser.h event_list_editor.cpp event_list_editor.h godbox.cpp godbox.h map_view.cc map_view.hh map_view_widget.cc map_view_widget.hh plot_select_dia.cpp plot_select_dia.h plot_widget.cc qt-viewer.pro setup_avida.cc /current/source/support Makefile.am genesis genesis.4stack inst_set.4stack /current/source/support/preset_organisms Makefile.am organism.4stack organism.parasite /current/source/third-party Makefile.am /current/source/tools datafile.cc datafile.hh slice.cc slice.hh /current/source/utils/hist_map hist_map.cc /current/source/viewers Makefile.am bar_screen.cc environment_screen.cc environment_screen.hh 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

kaben avida-cvs at alife.org
Tue Aug 26 07:30:27 PDT 2003


kaben		Mon Aug 25 23:30:27 2003 EDT

  Added files:                 (Branch: kaben)
    /avida/current/source/event	cPopulation_construct_event_auto.ci 
                               	cPopulation_descr.ci 
                               	cPopulation_descr.hi 
                               	cPopulation_enums_auto.ci 
                               	cPopulation_event_list 
                               	cPopulation_name2enum_auto.ci 
                               	cPopulation_process_auto.ci 
    /avida/current/source/main	inject_genebank.cc inject_genebank.hh 
                              	inject_genotype.cc inject_genotype.hh 
                              	org_message.cc org_message.hh 
    /avida/current/source/qt-viewer	event_chooser.cpp event_chooser.h 
                                   	event_list_editor.cpp 
                                   	event_list_editor.h godbox.cpp 
                                   	godbox.h plot_select_dia.cpp 
                                   	plot_select_dia.h 
    /avida/current/source/support	genesis.4stack inst_set.4stack 
    /avida/current/source/support/preset_organisms	organism.4stack 
                                                  	organism.parasite 
    /avida/current/source/viewers	environment_screen.cc 
                                 	environment_screen.hh 

  Modified files:              
    /avida/current	COPYING NEWS README configure.in 
    /avida/current/doc	environment.html events.html 
    /avida/current/source	defs.hh 
    /avida/current/source/cpu	cpu_memory.cc cpu_stack.hh 
                             	hardware_4stack.cc hardware_4stack.hh 
                             	hardware_base.hh hardware_cpu.cc 
                             	hardware_cpu.hh hardware_util.cc 
                             	hardware_util.hh head.cc head.hh 
                             	test_cpu.cc test_cpu.hh test_util.cc 
                             	test_util.hh 
    /avida/current/source/event	cPopulation.events 
                               	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 
                              	environment.hh genebank.cc genome.hh 
                              	inst_set.cc inst_set.hh inst_util.cc 
                              	main_sub.pri organism.cc organism.hh 
                              	phenotype.cc phenotype.hh 
                              	pop_interface.cc pop_interface.hh 
                              	population.cc population.hh 
                              	population_cell.cc population_cell.hh 
                              	reaction.cc reaction.hh 
                              	reaction_result.cc reaction_result.hh 
                              	tasks.cc 
    /avida/current/source/qt-viewer	avd_driver_controller.cc 
                                   	map_view.cc map_view.hh 
                                   	map_view_widget.cc 
                                   	map_view_widget.hh plot_widget.cc 
                                   	qt-viewer.pro setup_avida.cc 
    /avida/current/source/support	Makefile.am genesis 
    /avida/current/source/support/preset_organisms	Makefile.am 
    /avida/current/source/third-party	Makefile.am 
    /avida/current/source/tools	datafile.cc datafile.hh slice.cc 
                               	slice.hh 
    /avida/current/source/utils/hist_map	hist_map.cc 
    /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:
  
  Most effectively hosed my branch, overwriting files with older versions.
  Now mostly fixed.
  
  
  
-------------- next part --------------
Index: avida/current/COPYING
diff -u avida/current/COPYING:1.6 avida/current/COPYING:1.6.2.1
--- avida/current/COPYING:1.6	Wed May  1 13:43:32 2002
+++ avida/current/COPYING	Mon Aug 25 23:30:19 2003
@@ -26,3 +26,66 @@
 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+
+---------------------------------------------------------------------
+
+Avida uses version 1.9 of the very nice third-party package 'Trio'.
+
+Trio is a package with portable string functions, including printf()
+clones and others, and is released under the following MIT-like license:
+
+****
+
+README -- trio
+
+Trio is a package with portable string functions. Including printf() clones
+and others.
+
+ Copyright (C) 1998-2001 by Bjorn Reese and Daniel Stenberg.
+
+ Permission to use, copy, modify, and distribute this software for any
+ purpose with or without fee is hereby granted, provided that the above
+ copyright notice and this permission notice appear in all copies.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
+ CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
+
+Trio is intended to be an integral part of another application, so we
+have not done anything to create a proper installation.
+
+Compile with 'make' (edit the Makefile if you want a release build)
+
+Test the package with 'make test'
+
+Install by copying trio.h, triop.h, and libtrio.a (and man/man?/* if
+you want documentation) to the appropriate directories.
+
+Catch some usage examples in example.c
+
+Send feedback and patches to the mailing list, subscription and other
+information is found here:
+
+        http://lists.sourceforge.net/lists/listinfo/ctrio-talk
+
+Enjoy!
+
+Trio web page
+
+        http://daniel.haxx.se/trio/
+
+---------------------------------------------------------------------
+
+Avida for Windows uses version 2.6 of PDCurses, a wonderful third-party
+port of System VR4 curses for multiple platforms which has been released
+to the Public Domain, although small portions of the package are subject
+to various copyright conditions.  Visit the PDCurses webpage for more
+details:
+
+        http://pdcurses.sourceforge.net/
+
+The PDCurses package (and its predecessors) have had various 
+maintainers over the years.  The maintainer of version 2.6 is
+Mark Hessling - M.Hessling at qut.edu.au
+
Index: avida/current/NEWS
diff -u avida/current/NEWS:1.22.2.1 avida/current/NEWS:1.22.2.2
--- avida/current/NEWS:1.22.2.1	Tue May 20 05:12:18 2003
+++ avida/current/NEWS	Mon Aug 25 23:30:19 2003
@@ -4,16 +4,144 @@
 [B] = Bug fix; something that used to work wrong will now be correct.
 [M] = Major change; avida will function differently in certain circumstances.
 
+For version 2.0 beta 3:
+
+June, 03
+[F] Avida now runs and builds on Windows.  Many minor changes were made for this, 
+    .pro files were added to be used with qmake, the way the configure script searches
+    for the ncurses library was modified, pdcurses was incorporated instead of ncurses,
+    trio was added to fix some string problems, and some very minor code changes were
+    implemented to allow for some differences in the visual studio compiler. 
+
+[F] new 4 stack hardware is implemented but not yet fully functional.  It's compatible
+    with primitive and ncurses modes, however will cause qt-viewer to crash if used. 
+    No functionality associated with the original hardware has been changed.
+
+[B] set up constant time slicer to skip over empty cells, this had been throwing an assert
+    error in debug mode.
+
+[B] removed Visual Studio.net support files as they are out of date and no longer work properly.
+
+May, 03
+[F] introduced new 4 Stack CPU model.  Removed 3 registers in CPU and replaced with
+    4 stacks. Added 4th NOP which allows use of all 4 stacks.  Also changed complement system 
+    for nops.  Pairs are now as follows: A,C; B,D; C,A; D,B;
+
+[B] newer C++ compilers want scoping on templates defined inside class definition, event
+    if they are only used inside the class.
+
+[B] fixed problem with incorrect copying of instruction libraries when one instruction set was
+    initialized to another one.
+
+[F] set up Avida to pring out a genesis file if none exists.
+
+[I] working on setting up Avida to generate an instruction set file in none exists.  Attached 
+    60 character or less descriptions to each of the default instructions, and attached a flag to all 
+    instructions declaring they are default.
+
+[I] added default event files in C++ that are generated from perl so Avida can be compiled in Windows
+    without running perl script by hand as long as no new events are created or modified.
+
+[B] updated .pro files so don't have to change any properties in Visual Studio to compile
+
+[B] The hardware factory has always been creating CPU's of type cHardwareCPU even if everything else
+    was assuming cHardware4Stack.  This all works properly now.
+
+[I] added pdcurses.h and curses.lib to Avida so one doesn't have to actually check out the whole 
+    pdcurses suite to run on Windows.
+
+[I] added third party suite "Public Domain Curses" for Win32 compatability.
+
+[F] added event print_genotype_map that prints a Matlab file of the genotype IDs to a default file
+    "genotype_map.m"
+
+[B] added empty directory aclocal to CVS so don't have to create it by hand every time build Avida
+    from scratch
+
+[I] update .pri files for Windows builds
+
+[F] added Visual Studio.net support files for ncurses viewer, primitive mode, and qt-viewer.
+
+[I] cHardware4Stack now hooked into Avida and working properly
+
+[I] added new hardware type cHardware4Stack.  Not hooked into rest of Avida yet...
+
+[I] re-engineered cFile class to work based off of arrays instead of linked lists.  Each line is 
+    now stored as part of a structure which has other info associated with it, such as line numbers
+    for better error reporting.  Not being used yet, but available...
+
+[I] added HARDWARE_TYPE to genesis file and setup config to load it into Avida, it's not being used yet.
+
+[I] modified test_cup.cc to improve the default inputs in the test CPUs so they are more similar
+    to those in the environment, and ideally give more accurate answers.
+    Serup the default instruction set to be hooked in with a proper instruction library so that
+    they can be used outside of a population (i.e. in analyze mode)
+
+[B] fixed bug in testCPU
+
+[I] changed cInstLib to cInstSet and cInstSuperLib to cInstLib.  Renamed inst_lib.{cc,hh} to 
+    inst_set.{cc,hh} and inst_superlib.hh to inst_lib.hh.  Updated other files accordingly to 
+    reflect this change
+
+[I] included instruction which injects a parasite into it's own thread.  Also changed count.dat
+    so that info regarding parasites is appended to the end of the file.  Removed previous parasite
+    info which is now obsolete.
+
 For version 2.0 beta 1:
-[F] Improved cross-platform compatibility; can now build on Linux,
-    Mac OS X, and Windows XP (although this last is pretty rough).
-    Qt qmake can now be used to generate both Windows Visual Studio.net
-    project files and Mac OS X Project Builder project files.
-
-[I] Hardware_cpu now has a static instruction superlibrary containing
-    all available functions and instruction names.  Instruction
-    libraries now index into the superlibrary tables.  Windows
-    compatibility required the change away from the old code.
+[B] edited Makefile.am to reflect the fact that built event source file depends are build-tree relative
+    but cpu source file depends are source-tree relative
+
+[I] removed unused sourcecode from beneath qt subdirectory
+
+[I] introduced cInstSuperLib to contain a complete library of available instructions corresponding to
+    a given hardware class.  cInstLib now indexes into arrays provided by cInstSuperLib
+
+[B] mkdir() is not defined in win32 so added win32_mkdir_hack.hh to define it as a macro so can
+    use in windows version
+
+[B] modified namespaces, adding 'using namespace std' appropriately throughout Avida to allow
+    compilation on Windows
+
+[I] set up qt builds to be performed using qmake on seperately maintained .pro files
+
+[B] fixed error in new tasks, now cast int to double before taking log
+
+[I] added code to allow spatial resources
+
+[I] allow long lines in an input file to be split across multiple physical lines by use of
+    a \ character at the end of the line as a continuation marker
+
+[F] added two routines to aid the printing of spatial resource data:
+    writeblock - allows for the output of individual grid points
+    writeraw - allows any line to be written anywhere in an output file
+
+April, 03
+[F] added event kill_rectangle which allows user to kill all organisms in a rectangle
+    described by points (X1, Y1) and (X2, Y2).
+
+[B] no longer crashes when population dies out.
+
+[I] added version of Max function with type double.  added function Neighbor
+    that works with population and spatial resource arrays to find the current neighboring
+    cells (even at edge of matrix).
+
+[B] fixed time slicer problem where drastic drop in maximum merit would slow down a run 
+    considerably.  Added warning when analyze mode tries to load in a string sequence
+    thats supposed to represent a genome, but maximum char goes beyond instruction set size.
+
+[I] previous runs can no longer be replicated even when a random seed used is known
+    due to extensive reorganization of portions of code that handle divides.
+
+[F] initial implementation of sex.  Now exists divide-sex and divide-asex commands,
+    former facilitating recombination between two offspring by swapping a region of 
+    their code.
+
+[B] fixed hardware getting incorrect info as to if it lived through birth process.
+
+[B] removed mutation rate drifting options and old style crossovers.
+
+[I] assembled framework for sexual divides.  Mostly involved pushing some of the 
+    final offspring creation to the population and out of the organism.
 
 For version 2.0 beta 0:
 [I][O][F][B][M]
Index: avida/current/README
diff -u avida/current/README:1.2.4.17 avida/current/README:1.2.4.18
--- avida/current/README:1.2.4.17	Thu May 22 14:05:04 2003
+++ avida/current/README	Mon Aug 25 23:30:19 2003
@@ -6,7 +6,7 @@
 viewer. The installation goes into a directory called 'work' that 
 is created in your working directory. See below how to change that.
 
-There is a number of options you can give to configure to change the
+There are a number of options you can give to configure to change the
 default behavior:
   --enable-debug: Compile with debugging symbols instead of optimized.
   --enable-gnu-debug: Compile with special debugging symbols for the
@@ -38,7 +38,7 @@
 instead of 'make install'.
 
 *Important*:
-If you have already build Avida without viewer, and you want to
+If you have already built Avida without viewer, and you want to
 rebuild it with viewer, or vice versa, you have to issue a
   make viewer-clean
 between the two builds. Otherwise, strange things might happen.
Index: avida/current/configure.in
diff -u avida/current/configure.in:1.22.2.7 avida/current/configure.in:1.22.2.8
--- avida/current/configure.in:1.22.2.7	Mon Aug 25 18:46:25 2003
+++ avida/current/configure.in	Mon Aug 25 23:30:19 2003
@@ -8,7 +8,7 @@
 dnl ****************************************
 dnl        Package name and version
 dnl ****************************************
-AM_INIT_AUTOMAKE(avida, 2.0b1)
+AM_INIT_AUTOMAKE(avida, 2.0b4)
 
 
 dnl ****************************************
@@ -51,7 +51,7 @@
 dnl debugging/profiling
 AC_ARG_ENABLE(debug,
   [  --enable-debug: Compile with debugging symbols],
-  [CPPFLAGS="-g -DDEBUG"; qmake_debug="debug"],
+  [CPPFLAGS="-g -Wall -pedantic -DDEBUG"; qmake_debug="debug"],
   [CPPFLAGS="-O3 -ffast-math"; qmake_debug="release"])
 
 AC_ARG_ENABLE(gnu-debug,
Index: avida/current/doc/environment.html
diff -u avida/current/doc/environment.html:1.1.2.2 avida/current/doc/environment.html:1.1.2.3
--- avida/current/doc/environment.html:1.1.2.2	Thu May 29 11:47:49 2003
+++ avida/current/doc/environment.html	Mon Aug 25 23:30:19 2003
@@ -279,6 +279,9 @@
 <tr><td><font color="#0000AA">conversion</font>
     <td>The conversion rate to by-product resource
     <td>1.0
+<tr><td><font color="#0000AA">lethal</font>
+    <td>Whether the cell dies after performing the process
+    <td>0
 </table>
 
 <p>
Index: avida/current/doc/events.html
diff -u avida/current/doc/events.html:1.2.2.3 avida/current/doc/events.html:1.2.2.4
--- avida/current/doc/events.html:1.2.2.3	Fri May 30 14:23:34 2003
+++ avida/current/doc/events.html	Mon Aug 25 23:30:19 2003
@@ -88,61 +88,77 @@
     See the last example above to see how this event can be put into use.
     Note that this event will even create a detailed column legend at the top
     of your file so you don't need to seperately keep track of what the
-    columns mean.
-<p>
-<li><b>print_average_data</b><br>
+    columns mean.</li>
+<br>
+<li><b>print_average_data</b> [<font color="#008800">filename</font>]<br>
     A print_data shortcut that will print all of the population averages to
-    the file "average.dat".
-<p>
-<li><b>print_error_data</b><br>
+    the file "average.dat".</li>
+<br>
+<li><b>print_error_data</b> [<font color="#008800">filename</font>]<br>
     A print_data shortcut that will print all of the standard errors of the
-    population statistics to the file "error.dat".
-<p>
-<li><b>print_variance_data</b><br>
+    population statistics to the file "error.dat".</li>
+<br>
+<li><b>print_variance_data</b> [<font color="#008800">filename</font>]<br>
     A print_data shortcut that will print all of the veriances of the
-    population statistics to the file "variance.dat".
-<p>
-<li><b>print_dominant_data</b><br>
+    population statistics to the file "variance.dat".</li>
+<br>
+<li><b>print_dominant_data</b> [<font color="#008800">filename</font>]<br>
     A print_data shortcut that will print all of the statistics relating
-    to the dominant genotype to the file "dominant.dat".
-<p>
-<li><b>print_stats_data</b><br>
+    to the dominant genotype to the file "dominant.dat".</li>
+<br>
+<li><b>print_stats_data</b> [<font color="#008800">filename</font>]<br>
     A print_data shortcut that will print all of the miscellanous population
-    statistics to the file "stats.dat".
-<p>
-<li><b>print_counts_data</b><br>
+    statistics to the file "stats.dat".</li>
+<br>
+<li><b>print_counts_data</b> [<font color="#008800">filename</font>]<br>
     A print_data shortcut that will print all of the statistics the keep
     track of counts (such as the number of organisms in the population or
-    the number of instructions executed) to the file "count.dat".
-<p>
-<li><b>print_totals_data</b><br>
+    the number of instructions executed) to the file "count.dat".</li>
+<br>
+<li><b>print_totals_data</b> [<font color="#008800">filename</font>]<br>
     A print_data shortcut that will print the same information as the
     previous event, but the counts will be the totals for the entire
     length of the run (for example, the total number of organisms ever) to
-    the file "totals.dat".
-<p>
-<li><b>print_time_data</b><br>
+    the file "totals.dat".</li>
+<br>
+<li><b>print_time_data</b> [<font color="#008800">filename</font>]<br>
     A print_data shortcut that will print all of the timing related
-    statistics to the file "time.dat".
-<p>
-<li><b>print_tasks_data</b><br>
+    statistics to the file "time.dat".</li>
+<br>
+<li><b>print_tasks_data</b> [<font color="#008800">filename</font>]<br>
     Print the number of organisms that are able to perform each task to the
     file "tasks.dat".  This uses the environment configuration to determine
-    what tasks are in use.
-<p>
-<li><b>print_resource_data</b><br>
+    what tasks are in use.</li>
+<br>
+<li><b>print_tasks_exe_data</b> [<font color="#008800">filename</font>]<br>
+    ???? prints to tasks_exe.dat</li>
+<br>
+<li><b>print_mutation_data</b> [<font color="#008800">filename</font>]<br>
+    ???? prints to mutation.dat</li>
+<br>
+<li><b>print_mutation_rate_data</b> [<font color="#008800">filename</font>]<br>
+    Output (regular and log) statistics about individual copy
+    mutation rates (aver, stdev, skew, cur) to mutation_rates.dat.<br>
+    Useful only when mutation rate is set per organism.</li>
+<br>
+<li><b>print_divide_mut_data</b> [<font color="#008800">filename</font>]<br>
+    Output (regular and log) statistics about individual, per site,
+    rates divide mutation rates (aver, stdev, skew, cur) to divide_mut.dat.<br>
+    Use with multiple divide instuction set.</li>
+<br>
+
+<li><b>print_resource_data</b> [<font color="#008800">filename</font>]<br>
     Print the current counts of each resource available to the population
     to the file "resource.dat".  This uses the environment configuration to
     determine what resources are in use.  Also creates seperate files
     "resource_<i>resource_name</i>.m" (in a format that is designed to
-    be read into Matlab) for each spatial resource.
-<p>
+    be read into Matlab) for each spatial resource.</li>
+<br>
 <li><b>print_dom</b> [<font color="#008800">filename</font>]<br>
     Print the dominant organism's genome (and lots of information about it)
     into the file specified.  If no filename is given, just use the genotypes
-    assigned name.
-
-<p>
+    assigned name.</li>
+<br>
 <li><b>save_clone</b> [<font color="#008800">filename</font>]<br>
     Save a clone of this organism to the file specified; if no filename is
     given, use the name clone.update#.  The update number allows regular
@@ -150,9 +166,8 @@
     Running "avida -l filename" will start an avida population with the
     saved clone.  Note that a clone only consists of the genomes in
     the population, and their current state is lost, so the run may not
-    proceed identically as to if it had continued as it was going.
-
-<p>
+    proceed identically as to if it had continued as it was going.</li>
+<br>
 <li><b>detail_pop</b> [<font color="#008800">filename</font>]<br>
     Save the genotypes and lots of statistics about the population to the
     file specified; if not filename is given, use the name
@@ -174,18 +189,17 @@
 	10) update born<br>
 	11) update deactivated<br>
 	12) depth<br> 
-	13) genome (as a string)<br> 
-
-<p>
+	13) genome (as a string)</li>
+<br>
 <li><b>dump_historic_pop</b> [<font color="#008800">filename</font>]<br>
     This event is used to output all of the ancestors of the currently
     living population to the file specified, of "historic_dump.update#".
-    It uses the same format as the "detail_pop" event.
-<p>
-<li><b>print_genotype_map</b> [<fontcolor="#008800">filename</font>]<br>
+    It uses the same format as the "detail_pop" event.</li>
+<br>
+<li><b>print_genotype_map</b> [<font color="#008800">filename</font>]<br>
     This event is used to ouput a map of the gentype IDs for the
     population grid to a file that is suitable to be read into Matlab.
-    Default file name: genotype_map.m  
+    Default file name: genotype_map.m </li> 
 </menu>
 
 <p>
@@ -203,12 +217,12 @@
     Do a landscape analysis of the dominant genotype in the population and
     write the results to "landscape.dat".  This is a collection of 
     statistics obtained from examining all possible mutations at the distance
-    specified.  The default distance is one.
-<p>
+    specified.  The default distance is one.</li>
+<br>
 <li><b>task_snapshot</b> [<font color="#008800">filename</font>]<br>
     Run all organisms in the population through test cpus and print out the
     number of tasks each can perform.  The default filename is
-    "tasks_update#.dat".
+    "tasks_update#.dat".</li>
 </menu>
 
 <p>
@@ -224,26 +238,42 @@
     Inject a single organisms into the population.  Arguments must be
     included from left to right; if all arguments are left out, the default
     creature is the ancestral organism, and it will be injected into cell 0,
-    have an uninitialized merit, and be marked as liniage id 0.
-
-<p>
+    have an uninitialized merit, and be marked as liniage id 0.</li>
+<br>
 <li><b>inject_all</b> [<font color="#008800">filename</font>] [<font color="#008800">merit</font>] [<font color="#008800">lineage_id</font>]<br>
     Same as inject, but no cell_id is specified and the organism is placed
-    into <i>all</i> cells in the population.
-<p>
+    into <i>all</i> cells in the population.</li>
+<br>
 <li><b>apocalypse</b> [<font color="#008800">kill_prob</font>]<br>
     Using the specified probability, test each organism to see if it is killed
-    off.
-<p>
+    off.</li>
+<br>
 <li><b>serieal_transfer</b> [<font color="#008800">num_organisms</font>]<br>
     Similar to apocalypse, but we specify the exact number of organisms to
-    keep alive after the event.
-<p>
+    keep alive after the event.</li>
+<br>
 <li><b>kill_rectanle</b> [<font color="#008800">X1</font>] [<font
 color="#008800">Y1</font>] [<font color="#008800">X2</font>] [<font 
 color="#008800">Y2</font>]<br>
     Kill off all organisms in a rectangle defined by the points (X1, Y1) and 
-    (X2, Y2).
+    (X2, Y2).</li>
+</menu>
+
+<p>
+<h3>Resource Events</h3>
+
+Events that allow user to change amounts of resources in the system.
+
+<menu>
+<li><b>inject_resource</b> [<font color="#008800">res_name</font>] 
+[<font color="#008800">res_count</font>] <br> 
+    Inject (add) a specified amount of a specified resource.  <b>res_name</b> must 
+    already exist as a resource in environment file.</li>
+<br>
+<li><b>set_resource</b> [<font color="#008800">res_name</font>] 
+[<font color="#008800">res_count</font>] <br> 
+    Set the resource amount to a specific level.  <b>res_name</b> must 
+    already exist as a resource in environment file.</li>
 </menu>
 
 <p>
@@ -255,11 +285,27 @@
 <menu>
 <li><b>echo</b> [<font color="#008800">message</font>]<br>
     Print the message included when the event is triggered.  This is mostly
-    used for debugging.
+    used for debugging.</li>
 
-<p>
+<br>
 <li><b>exit</b><br>
-    Quit the current run.
+    Quit the current run.</li>
+<br>
+<li><b>exit_if_generation_greater_than</b> [<font color="#008800">max_generation</font>]<br>
+    Ends the Avida run when the current generation exceeds <b>max_generation</b>.</li>
+<br>
+<li><b>exit_if_update_greater_than</b> [<font color="#008800">max_update</font>]<br>
+    Ends the Avida run when the current generation exceeds <b>max_update</b>.</li>
+<br>
+ <li><b>exit_if_ave_lineage_label_smaller</b> [<font color="#008800">lineage_label_crit_value</font>]<br>
+     Halts the avida run if the current average lineage label is smaller
+     than <b>lineage_label_crit_value</b>.</li>
+<br>
+ <li><b>exit_if_ave_lineage_label_larger</b> [<font color="#008800">lineage_label_crit_value</font>]<br>
+     Halts the avida run if the current average lineage label is larger
+     than <b>lineage_label_crit_value</b>.</li>
+<br>
+
 </menu>
 
 
Index: avida/current/source/defs.hh
diff -u avida/current/source/defs.hh:1.25.2.5 avida/current/source/defs.hh:1.25.2.6
--- avida/current/source/defs.hh:1.25.2.5	Fri May 23 05:05:07 2003
+++ avida/current/source/defs.hh	Mon Aug 25 23:30:20 2003
@@ -18,14 +18,6 @@
 #define HTMLDIR "../work/doc_html/"
 #endif
 
-/*
-When defined, instruction sets, instruction libraries, hardware use new
-instruction set code.  The old code remains, and will be used if the
-following is not defined.
-*/
-/* XXX remove after regression tests */
-#define USE_INST_SET_CODE
-/**/
 
 // -= Various view modes =-
 #define VIEW_NEWVIEWER
@@ -83,7 +75,7 @@
 // the macro VERSION is defined by automake (in the file 'configure.in' in
 // the top-level directory).
 #ifndef VERSION
- #define VERSION "2.0b"
+ #define VERSION "2.0b4"
 #endif
 #define AVIDA_VERSION VERSION
 
Index: avida/current/source/cpu/cpu_memory.cc
diff -u avida/current/source/cpu/cpu_memory.cc:1.7.2.3 avida/current/source/cpu/cpu_memory.cc:1.7.2.4
--- avida/current/source/cpu/cpu_memory.cc:1.7.2.3	Fri May 16 15:15:53 2003
+++ avida/current/source/cpu/cpu_memory.cc	Mon Aug 25 23:30:20 2003
@@ -239,4 +239,3 @@
     genome[i + pos] = in_genome[i];
   }
 }
-
Index: avida/current/source/cpu/cpu_stack.hh
diff -u avida/current/source/cpu/cpu_stack.hh:1.2.2.2 avida/current/source/cpu/cpu_stack.hh:1.2.2.3
--- avida/current/source/cpu/cpu_stack.hh:1.2.2.2	Thu May 29 11:47:50 2003
+++ avida/current/source/cpu/cpu_stack.hh	Mon Aug 25 23:30:20 2003
@@ -35,7 +35,7 @@
   inline int Pop();
   inline int Get(int depth=0) const;
   inline void Clear();
-  inline int& Top();
+  inline int Top();
   void Flip();
 
   bool OK();
@@ -74,7 +74,7 @@
   stack_pointer = 0;
 }
 
-inline int& cCPUStack::Top()
+inline int cCPUStack::Top()
 {
   return stack[stack_pointer];
 }
Index: avida/current/source/cpu/hardware_4stack.cc
diff -u avida/current/source/cpu/hardware_4stack.cc:1.2.2.5 avida/current/source/cpu/hardware_4stack.cc:1.2.2.6
--- avida/current/source/cpu/hardware_4stack.cc:1.2.2.5	Thu May 29 11:47:50 2003
+++ avida/current/source/cpu/hardware_4stack.cc	Mon Aug 25 23:30:20 2003
@@ -1,4 +1,3 @@
-
 //////////////////////////////////////////////////////////////////////////////
 // Copyright (C) 1993 - 2003 California Institute of Technology             //
 //                                                                          //
@@ -6,12 +5,14 @@
 // before continuing.  SOME RESTRICTIONS MAY APPLY TO USE OF THIS FILE.     //
 //////////////////////////////////////////////////////////////////////////////
 
+
 #include <iomanip>
 
 #include "hardware_method.hh"
 #include "hardware_4stack.hh"
 
 #include "../tools/string_util.hh"
+#include "../tools/random.hh"
 
 #include "../main/config.hh"
 #include "../main/inst_set.hh"
@@ -43,14 +44,14 @@
 {
    id = _id;
    if (id == -1) id = in_thread.id;
-   for (int i = 0; i < NUM_REG_4STACK; i++) {
-     reg[i] = in_thread.reg[i];
+   for (int i = 0; i < NUM_LOCAL_STACKS; i++) {
+     local_stacks[i] = in_thread.local_stacks[i];
    }
    for (int i = 0; i < NUM_HEADS; i++) {
      heads[i] = in_thread.heads[i];
    }
-   stack = in_thread.stack;
    input_pointer = in_thread.input_pointer;
+   owner = in_thread.owner;
 }
 
 cHardware4Stack_Thread::~cHardware4Stack_Thread() {}
@@ -58,45 +59,41 @@
 void cHardware4Stack_Thread::operator=(const cHardware4Stack_Thread & in_thread)
 {
   id = in_thread.id;
-  for (int i = 0; i < NUM_REG_4STACK; i++) {
-    reg[i] = in_thread.reg[i];
+  for (int i = 0; i < NUM_LOCAL_STACKS; i++) {
+    local_stacks[i] = in_thread.local_stacks[i];
   }
   for (int i = 0; i < NUM_HEADS; i++) {
     heads[i] = in_thread.heads[i];
   }
-  stack = in_thread.stack;
   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)
 {
   id = _id;
 
-  for (int i = 0; i < NUM_REG_4STACK; i++) reg[i] = 0;
-  for (int i = 0; i < NUM_HEADS; i++) heads[i].Reset(in_hardware);
+  for (int i = 0; i < NUM_LOCAL_STACKS; i++) local_stacks[i].Clear();
+  for (int i = 0; i < NUM_HEADS; i++) heads[i].Reset(0, in_hardware);
 
-  stack.Clear();
-  cur_stack = 0;
   cur_head = HEAD_IP;
   input_pointer = 0;
   input_buf.Clear();
   output_buf.Clear();
   read_label.Clear();
   next_label.Clear();
+  owner = NULL;
 }
 
-
-
-
 void cHardware4Stack_Thread::SaveState(ostream & fp){
   assert(fp.good());
   fp << "cHardware4Stack_Thread" << endl;
 
-  // registers
-  for( int i=0; i<NUM_REG_4STACK; ++i ){
-    fp<<reg[i]<<endl;
+  // stacks (NOT WORKING! -law)
+  for( int i=0; i<NUM_STACKS; ++i ){
+    local_stacks[i].SaveState(fp);
   }
 
   // heads (@TCC does not handle parasites!!!)
@@ -104,10 +101,7 @@
     fp<<heads[i].GetPosition()<<endl;
   }
 
-  stack.SaveState(fp);
-
   fp<<"|"; // marker
-  fp<<cur_stack;
   fp<<cur_head;
   fp<<input_pointer;
   fp<<endl;
@@ -121,17 +115,15 @@
   next_label.SaveState(fp);
 }
 
-
-
 void cHardware4Stack_Thread::LoadState(istream & fp){
   assert(fp.good());
   cString foo;
   fp >> foo;
   assert( foo == "cHardware4Stack_Thread");
 
-  // registers
-  for( int i=0; i<NUM_REG_4STACK; ++i ){
-    fp>>reg[i];
+  // stacks (NOT WORKING!  -law)
+  for( int i=0; i<NUM_STACKS; ++i ){
+    local_stacks[i].LoadState(fp);
   }
 
   // heads (@TCC does not handle parasites!!!)
@@ -141,23 +133,12 @@
     heads[i].AbsSet(pos);
   }
 
-  // stack
-  stack.LoadState(fp);
-
   char marker; fp>>marker; assert( marker == '|' );
-  /* YIKES!  data loss below: */
-#ifdef USE_INST_SET_CODE
-  char the_cur_stack = cur_stack;
+  /* YIKES!  data loss below: */ 
   char the_cur_head = cur_head;
   char the_input_pointer = input_pointer;
-  fp.get(the_cur_stack);
   fp.get(the_cur_head);
   fp.get(the_input_pointer);
-#else /* USE_INST_SET_CODE */
-  fp.get((char)cur_stack);
-  fp.get((char)cur_head);
-  fp.get((char)input_pointer);
-#endif /* USE_INST_SET_CODE */
 
   // IO buffers
   input_buf.LoadState(fp);
@@ -169,7 +150,6 @@
 }
 
 
-#ifdef USE_INST_SET_CODE
 ///////////////
 //  cInstLib4Stack
 ///////////////
@@ -225,13 +205,11 @@
   const cInstruction & GetInstDefault(){ return inst_default; }
   const cInstruction & GetInstError(){ return inst_error; }
 };
-#endif /* USE_INST_SET_CODE */
 
 ///////////////
 //  cHardware4Stack
 ///////////////
 
-#ifdef USE_INST_SET_CODE
 const cInstruction cInstLib4Stack::inst_error(255);
 const cInstruction cInstLib4Stack::inst_default(0);
 cInstLibBase *cHardware4Stack::GetInstLib(){ return s_inst_slib; }
@@ -244,10 +222,10 @@
     int nop_mod;
   };
   static const cNOPEntry4Stack s_n_array[] = {
-    cNOPEntry4Stack("Nop-A", REG_AX),
-    cNOPEntry4Stack("Nop-B", REG_BX),
-    cNOPEntry4Stack("Nop-C", REG_CX),
-    cNOPEntry4Stack("Nop-D", REG_DX),
+    cNOPEntry4Stack("Nop-A", STACK_AX),
+    cNOPEntry4Stack("Nop-B", STACK_BX),
+    cNOPEntry4Stack("Nop-C", STACK_CX),
+    cNOPEntry4Stack("Nop-D", STACK_DX),
   };
 
   struct cInstEntry4Stack {
@@ -262,7 +240,7 @@
     cInstEntry4Stack("Nop-B",     &cHardware4Stack::Inst_Nop), 
     //3
     cInstEntry4Stack("Nop-C",     &cHardware4Stack::Inst_Nop),   
-    //4 - not implemented yet...
+    //4 
     cInstEntry4Stack("Nop-D",     &cHardware4Stack::Inst_Nop), 
     //5
     cInstEntry4Stack("Nop-X",     &cHardware4Stack::Inst_Nop),
@@ -271,155 +249,67 @@
     //7
     cInstEntry4Stack("Val-Shift-L",   &cHardware4Stack::Inst_ShiftL),
     //8
-    cInstEntry4Stack("Val-Nand",      &cHardware4Stack::Inst_Nand),
+    cInstEntry4Stack("Val-Nand",      &cHardware4Stack::Inst_Val_Nand),
     //9
-    cInstEntry4Stack("Val-Add",       &cHardware4Stack::Inst_Add),
+    cInstEntry4Stack("Val-Add",       &cHardware4Stack::Inst_Val_Add),
     //10
-    cInstEntry4Stack("Val-Sub",       &cHardware4Stack::Inst_Sub),
+    cInstEntry4Stack("Val-Sub",       &cHardware4Stack::Inst_Val_Sub),
     //11
-    cInstEntry4Stack("Val-Mult",      &cHardware4Stack::Inst_Mult),
+    cInstEntry4Stack("Val-Mult",      &cHardware4Stack::Inst_Val_Mult),
     //12
-    cInstEntry4Stack("Val-Div",       &cHardware4Stack::Inst_Div),
+    cInstEntry4Stack("Val-Div",       &cHardware4Stack::Inst_Val_Div),
     //13
-    cInstEntry4Stack("SetMemory",   &cHardware4Stack::Inst_MaxAlloc),
+    cInstEntry4Stack("SetMemory",   &cHardware4Stack::Inst_SetMemory),
     //14
-    cInstEntry4Stack("Divide",  &cHardware4Stack::Inst_HeadDivide),
+    cInstEntry4Stack("Divide",  &cHardware4Stack::Inst_Divide),
     //15
     cInstEntry4Stack("Inst-Read",    &cHardware4Stack::Inst_HeadRead),
     //16
     cInstEntry4Stack("Inst-Write",   &cHardware4Stack::Inst_HeadWrite),
     //keeping this one for the transition period
-    cInstEntry4Stack("Inst-Copy",    &cHardware4Stack::Inst_HeadCopy),
+    //cInstEntry4Stack("Inst-Copy",    &cHardware4Stack::Inst_HeadCopy),
     //17
-    cInstEntry4Stack("If-Equal",    &cHardware4Stack::Inst_IfEqu),
+    cInstEntry4Stack("If-Equal",    &cHardware4Stack::Inst_IfEqual),
     //18
-    cInstEntry4Stack("If-Not-Equal",  &cHardware4Stack::Inst_IfNEqu),
+    cInstEntry4Stack("If-Not-Equal",  &cHardware4Stack::Inst_IfNotEqual),
     //19
     cInstEntry4Stack("If-Less",   &cHardware4Stack::Inst_IfLess),
     //20
-    cInstEntry4Stack("If-Greater",    &cHardware4Stack::Inst_IfGr),
+    cInstEntry4Stack("If-Greater",    &cHardware4Stack::Inst_IfGreater),
     //21
     cInstEntry4Stack("Head-Push",    &cHardware4Stack::Inst_HeadPush),
     //22
     cInstEntry4Stack("Head-Pop",     &cHardware4Stack::Inst_HeadPop),
     //23
-    cInstEntry4Stack("Head-Move",  &cHardware4Stack::Inst_MoveHead),
+    cInstEntry4Stack("Head-Move",  &cHardware4Stack::Inst_HeadMove),
     //24
-    cInstEntry4Stack("Search",  &cHardware4Stack::Inst_HeadSearch),
+    cInstEntry4Stack("Search",  &cHardware4Stack::Inst_Search),
     //25
-    cInstEntry4Stack("Push-Next",    &cHardware4Stack::Inst_PushA),
+    cInstEntry4Stack("Push-Next",    &cHardware4Stack::Inst_PushNext),
     //26
-    cInstEntry4Stack("Push-Prev",    &cHardware4Stack::Inst_PushB),
+    cInstEntry4Stack("Push-Prev",    &cHardware4Stack::Inst_PushPrevious),
     //27
-    cInstEntry4Stack("Push-Comp",    &cHardware4Stack::Inst_PushC),
-    //28 - Not implemented yet...
-    //cInstEntry4Stack("Val-Delete", &cHardware4Stack::Inst_ValDelete
+    cInstEntry4Stack("Push-Comp",    &cHardware4Stack::Inst_PushComplement),
+    //28
+    cInstEntry4Stack("Val-Delete", &cHardware4Stack::Inst_ValDelete),
     //29
-    cInstEntry4Stack("Val-Copy",  &cHardware4Stack::Inst_CopyStack),
+    cInstEntry4Stack("Val-Copy",  &cHardware4Stack::Inst_ValCopy),
     //30
     cInstEntry4Stack("ThreadFork",   &cHardware4Stack::Inst_ForkThread),
     //31
-    cInstEntry4Stack("if-label",  &cHardware4Stack::Inst_IfLabel),
+    //cInstEntry4Stack("if-label",  &cHardware4Stack::Inst_IfLabel),
     //32
-    cInstEntry4Stack("Val-Inc",       &cHardware4Stack::Inst_Inc),
+    cInstEntry4Stack("Val-Inc",       &cHardware4Stack::Inst_Increment),
     //33
-    cInstEntry4Stack("Val-Dec",       &cHardware4Stack::Inst_Dec),
+    cInstEntry4Stack("Val-Dec",       &cHardware4Stack::Inst_Decrement),
     //34
     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_Divide),
-    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);
@@ -460,17 +350,24 @@
 
   return inst_lib;
 }
-#endif /* USE_INST_SET_CODE */
 
 cHardware4Stack::cHardware4Stack(cOrganism * in_organism, cInstSet * in_inst_set)
   : cHardwareBase(in_organism, in_inst_set)
+  , memory_array(NUM_MEMORY_SPACES)
 {
-#ifdef USE_INST_SET_CODE
   /* FIXME:  reorganize storage of m_functions.  -- kgn */
   m_functions = s_inst_slib->GetFunctions();
   /**/
-#endif /* USE_INST_SET_CODE */
-  memory = in_organism->GetGenome();  // Initialize memory...
+  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...
 }
 
@@ -483,15 +380,24 @@
 void cHardware4Stack::Recycle(cOrganism * new_organism, cInstSet * in_inst_set)
 {
   cHardwareBase::Recycle(new_organism, in_inst_set);
-  memory = new_organism->GetGenome();
+  memory_array[0] = new_organism->GetGenome();
+  memory_array[0].Resize(GetMemory(0).GetSize()+1);
+  memory_array[0][memory_array[0].GetSize()-1] = cInstruction();
   Reset();
 }
 
 
 void cHardware4Stack::Reset()
 {
-  global_stack.Clear();
-  thread_time_used = 0;
+  //global_stack.Clear();
+  //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)=cGenome(ConvertToInstruction(i)); 
+  }
 
   // We want to reset to have a single thread.
   threads.Resize(1);
@@ -503,6 +409,12 @@
 
   mal_active = false;
 
+  // Reset all stacks (local and global)
+  for(int i=0; i<NUM_STACKS; i++)
+    {
+      Stack(i).Clear();
+    }
+
 #ifdef INSTRUCTION_COSTS
   // instruction cost arrays
   const int num_inst_cost = GetNumInst();
@@ -517,24 +429,33 @@
 
 }
 
-
 // This function processes the very next command in the genome, and is made
 // to be as optimized as possible.  This is the heart of avida.
 
 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
@@ -558,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...
@@ -571,7 +492,6 @@
   }
 }
 
-
 // This method will test to see if all costs have been paid associated
 // with executing an instruction and only return true when that instruction
 // should proceed.
@@ -609,24 +529,14 @@
 bool cHardware4Stack::SingleProcess_ExecuteInst(const cInstruction & cur_inst) 
 {
   // Get a pointer to the corrisponding method...
-#ifdef USE_INST_SET_CODE
-  /* XXX start -- kgn */
   int inst_idx = GetInstSet().GetLibFunctionIndex(cur_inst);
-  /* XXX end */
-#else /* USE_INST_SET_CODE */
-  tHardwareMethod inst_ptr = GetInstSet().GetFunction(cur_inst);
-#endif /* USE_INST_SET_CODE */
       
   // Mark the instruction as executed
   IP().FlagExecuted() = true;
 	
 #ifdef EXECUTION_ERRORS
   // If there is an execution error, execute a random instruction.
-#ifdef USE_INST_SET_CODE
   if (organism->TestExeErr()) inst_idx = GetInstSet().GetRandFunctionIndex();
-#else /* USE_INST_SET_CODE */
-  if (organism->TestExeErr()) inst_ptr = GetInstSet().GetRandFunction();
-#endif /* USE_INST_SET_CODE */
 #endif /* EXECUTION_ERRORS */
 	
 #ifdef INSTRUCTION_COUNT
@@ -635,15 +545,7 @@
 #endif
 	
   // And execute it.
-#ifdef USE_INST_SET_CODE
-  /* XXX start -- kgn */
-  const bool exec_success
-  //= (this->*(s_inst_slib->GetFunctions()[inst_idx]))();
-  = (this->*(m_functions[inst_idx]))();
-  /* XXX end */
-#else /* USE_INST_SET_CODE */
-  const bool exec_success = (this->*inst_ptr)();
-#endif /* USE_INST_SET_CODE */
+  const bool exec_success = (this->*(m_functions[inst_idx]))();
 	
 #ifdef INSTRUCTION_COUNT
   // decremenet if the instruction was not executed successfully
@@ -659,7 +561,7 @@
 
 void cHardware4Stack::LoadGenome(const cGenome & new_genome)
 {
-  GetMemory() = new_genome;
+  GetMemory(0) = new_genome;
 }
 
 
@@ -667,12 +569,15 @@
 {
   bool result = true;
 
-  if (!memory.OK()) result = false;
+  for(int i = 0 ; i < NUM_MEMORY_SPACES; i++) {
+    if (!memory_array[i].OK()) result = false;
+  }
 
   for (int i = 0; i < GetNumThreads(); i++) {
     assert (threads[i].input_pointer < IO_SIZE);
 
-    if (threads[i].stack.OK() == false) result = false;
+    for(int j=0; j<NUM_LOCAL_STACKS; j++)
+    if (threads[i].local_stacks[j].OK() == false) result = false;
     if (threads[i].next_label.OK() == false) result = false;
   }
 
@@ -682,32 +587,46 @@
 void cHardware4Stack::PrintStatus(ostream & fp)
 {
   fp << organism->GetPhenotype().GetTimeUsed() << " "
-     << "IP:" << IP().GetPosition() << "    "
+     << "IP:(" << IP().GetMemSpace() << ", " << IP().GetPosition() << ")    "
 
-     << "AX:" << Register(REG_AX) << " "
-     << setbase(16) << "[0x" << Register(REG_AX) << "]  " << setbase(10)
+     << "AX:" << Stack(STACK_AX).Top() << " "
+     << setbase(16) << "[0x" << Stack(STACK_AX).Top() << "]  " << setbase(10)
 
-     << "BX:" << Register(REG_BX) << " "
-     << setbase(16) << "[0x" << Register(REG_BX) << "]  " << setbase(10)
+     << "BX:" << Stack(STACK_BX).Top() << " "
+     << setbase(16) << "[0x" << Stack(STACK_BX).Top() << "]  " << setbase(10)
 
-     << "CX:" << Register(REG_CX) << " "
-     << setbase(16) << "[0x" << Register(REG_CX) << "]" << setbase(10)
+     << "CX:" << Stack(STACK_CX).Top() << " "
+     << setbase(16) << "[0x" << Stack(STACK_CX).Top() << "]  " << setbase(10)
 
-     << "DX:" << Register(REG_DX) << " "
-     << setbase(16) << "[0x" << Register(REG_DX) << "]" << setbase(10)
+     << "DX:" << Stack(STACK_DX).Top() << " "
+     << setbase(16) << "[0x" << Stack(STACK_DX).Top() << "]  " << setbase(10)
 
      << endl;
 
-  fp << "  R-Head:" << GetHead(HEAD_READ).GetPosition() << " "
-     << "W-Head:" << GetHead(HEAD_WRITE).GetPosition()  << " "
-     << "F-Head:" << GetHead(HEAD_FLOW).GetPosition()   << "  "
+  fp << "  R-Head:(" << GetHead(HEAD_READ).GetMemSpace() << ", " 
+     << GetHead(HEAD_READ).GetPosition() << ")  " 
+     << "W-Head:(" << GetHead(HEAD_WRITE).GetMemSpace()  << ", "
+     << GetHead(HEAD_WRITE).GetPosition() << ")  "
+     << "F-Head:(" << GetHead(HEAD_FLOW).GetMemSpace()   << ",  "
+     << GetHead(HEAD_FLOW).GetPosition() << ")  "
      << "RL:" << GetReadLabel().AsString() << "   "
      << "NEXT: >> " << inst_set->GetName(IP().GetInst())() << " <<"
      << endl;
 
-  fp << "  Mem (" << GetMemory().GetSize() << "):"
-		  << "  " << GetMemory().AsString()
+  fp << "  Mem (" << GetMemory(0).GetSize() << "):"
+		  << "  " << GetMemory(0).AsString()
+		  << endl;
+  fp << "       " << GetMemory(1).GetSize() << "):"
+		  << "  " << GetMemory(1).AsString()
+		  << endl;
+  fp << "       " << GetMemory(2).GetSize() << "):"
+		  << "  " << GetMemory(2).AsString()
 		  << endl;
+  fp << "       " << GetMemory(3).GetSize() << "):"
+		  << "  " << GetMemory(3).AsString()
+		  << endl;
+  
+  
   fp.flush();
 }
 
@@ -734,15 +653,15 @@
 //
 /////////////////////////////////////////////////////////////////////////
 
-cCPUHead cHardware4Stack::FindLabel(int direction)
+c4StackHead cHardware4Stack::FindLabel(int direction)
 {
-  cCPUHead & inst_ptr = IP();
+  c4StackHead & inst_ptr = IP();
 
   // Start up a search head at the position of the instruction pointer.
-  cCPUHead search_head(inst_ptr);
+  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;
@@ -767,8 +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;
 }
@@ -935,7 +855,7 @@
 }
 
 // Search for 'in_label' anywhere in the hardware.
-cCPUHead cHardware4Stack::FindLabel(const cCodeLabel & in_label, int direction)
+c4StackHead cHardware4Stack::FindLabel(const cCodeLabel & in_label, int direction)
 {
   assert (in_label.GetSize() > 0);
 
@@ -946,7 +866,7 @@
   // FOR NOW:
   // Get something which works, no matter how inefficient!!!
 
-  cCPUHead temp_head(this);
+  c4StackHead temp_head(this);
 
   while (temp_head.InMemory()) {
     // IDEALY: Analyze the label we are in; see if the one we are looking
@@ -973,14 +893,14 @@
 
 // @CAO: direction is not currently used; should be used to indicate the
 // direction which the heads[HEAD_IP] should progress through a creature.
-cCPUHead cHardware4Stack::FindFullLabel(const cCodeLabel & in_label)
+c4StackHead cHardware4Stack::FindFullLabel(const cCodeLabel & in_label)
 {
   // cout << "Running FindFullLabel with " << in_label.AsString() <<
   // endl;
 
   assert(in_label.GetSize() > 0); // Trying to find label of 0 size!
 
-  cCPUHead temp_head(this);
+  c4StackHead temp_head(this);
 
   while (temp_head.InMemory()) {
     // If we are not in a label, jump to the next checkpoint...
@@ -1039,118 +959,128 @@
   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().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().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.GetSize());
-  assert(memory.GetSize() + inject_code.GetSize() < MAX_CREATURE_SIZE);
-
-  // Inject the new code.
-  const int inject_size = inject_code.GetSize();
-  memory.Insert(line_num, inject_code);
-  
-  // Set instruction flags on the injected code
-  for (int i = line_num; i < line_num + inject_size; i++) {
-    memory.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.GetSize());
-  assert(memory.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.Insert(line_num, inject_code);
-      
-      // Set instruction flags on the injected code
-      for (int i = line_num; i < line_num + inject_size; i++) {
-	memory.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)
 {
   // Test if trying to mutate outside of genome...
-  assert(mut_point >= 0 && mut_point < GetMemory().GetSize());
+  assert(mut_point >= 0 && mut_point < GetMemory(0).GetSize());
 
-  GetMemory()[mut_point] = GetRandomInst();
-  GetMemory().FlagMutated(mut_point) = true;
-  GetMemory().FlagPointMut(mut_point) = true;
+  GetMemory(0)[mut_point] = GetRandomInst();
+  GetMemory(0).FlagMutated(mut_point) = true;
+  GetMemory(0).FlagPointMut(mut_point) = true;
   //organism->GetPhenotype().IsMutated() = true;
   organism->CPUStats().mut_stats.point_mut_count++;
 }
@@ -1158,10 +1088,10 @@
 int cHardware4Stack::PointMutate(const double mut_rate)
 {
   const int num_muts =
-    g_random.GetRandBinomial(GetMemory().GetSize(), mut_rate);
+    g_random.GetRandBinomial(GetMemory(0).GetSize(), mut_rate);
 
   for (int i = 0; i < num_muts; i++) {
-    const int pos = g_random.GetUInt(GetMemory().GetSize());
+    const int pos = g_random.GetUInt(GetMemory(0).GetSize());
     Mutate(pos);
   }
 
@@ -1183,7 +1113,7 @@
   return TriggerMutations(trigger, IP());
 }
 
-bool cHardware4Stack::TriggerMutations(int trigger, cCPUHead & cur_head)
+bool cHardware4Stack::TriggerMutations(int trigger, c4StackHead & cur_head)
 {
   // Collect information about mutations from the organism.
   cLocalMutations & mut_info = organism->GetLocalMutations();
@@ -1196,7 +1126,7 @@
 
   // Determine what memory this mutation will be affecting.
   cCPUMemory & target_mem = (trigger == MUTATION_TRIGGER_DIVIDE) 
-    ? organism->ChildGenome() : GetMemory();
+    ? organism->ChildGenome() : GetMemory(0);
 
   // Loop through all mutations associated with this trigger and test them.
   tConstListIterator<cMutation> mut_it(mut_list);
@@ -1236,7 +1166,7 @@
 }
 
 bool cHardware4Stack::TriggerMutations_ScopeGenome(const cMutation * cur_mut,
-          cCPUMemory & target_memory, cCPUHead & cur_head, const double rate)
+          cCPUMemory & target_memory, c4StackHead & cur_head, const double rate)
 {
   // The rate we have stored indicates the probability that a single
   // mutation will occur anywhere in the genome.
@@ -1244,7 +1174,7 @@
   if (g_random.P(rate) == true) {
     // We must create a temporary head and use it to randomly determine the
     // position in the genome to be mutated.
-    cCPUHead tmp_head(cur_head);
+    c4StackHead tmp_head(cur_head);
     tmp_head.AbsSet(g_random.GetUInt(target_memory.GetSize()));
     TriggerMutations_Body(cur_mut->GetType(), target_memory, tmp_head);
     return true;
@@ -1253,7 +1183,7 @@
 }
 
 bool cHardware4Stack::TriggerMutations_ScopeLocal(const cMutation * cur_mut,
-          cCPUMemory & target_memory, cCPUHead & cur_head, const double rate)
+          cCPUMemory & target_memory, c4StackHead & cur_head, const double rate)
 {
   // The rate we have stored is the probability for a mutation at this single
   // position in the genome.
@@ -1266,7 +1196,7 @@
 }
 
 int cHardware4Stack::TriggerMutations_ScopeGlobal(const cMutation * cur_mut,
-          cCPUMemory & target_memory, cCPUHead & cur_head, const double rate)
+          cCPUMemory & target_memory, c4StackHead & cur_head, const double rate)
 {
   // The probability we have stored is per-site, so we can pull a random
   // number from a binomial distribution to determine the number of mutations
@@ -1277,7 +1207,7 @@
 
   if (num_mut > 0) {
     for (int i = 0; i < num_mut; i++) {
-      cCPUHead tmp_head(cur_head);
+      c4StackHead tmp_head(cur_head);
       tmp_head.AbsSet(g_random.GetUInt(target_memory.GetSize()));
       TriggerMutations_Body(cur_mut->GetType(), target_memory, tmp_head);
     }
@@ -1287,7 +1217,7 @@
 }
 
 void cHardware4Stack::TriggerMutations_Body(int type, cCPUMemory & target_memory,
-					 cCPUHead & cur_head)
+					 c4StackHead & cur_head)
 {
   const int pos = cur_head.GetPosition();
 
@@ -1336,7 +1266,7 @@
 void cHardware4Stack::ReadLabel(int max_size)
 {
   int count = 0;
-  cCPUHead * inst_ptr = &( IP() );
+  c4StackHead * inst_ptr = &( IP() );
 
   GetLabel().Clear();
 
@@ -1362,8 +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];
+  threads[num_threads] = threads[cur_thread]; 
 
   // Find the first free bit in thread_id_chart to determine the new
   // thread id.
@@ -1417,9 +1349,10 @@
   fp<<"cHardware4Stack"<<endl;
 
   // global_stack (in inverse order so load can just push)
-  global_stack.SaveState(fp);
+  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;
 
@@ -1440,10 +1373,11 @@
   assert( foo == "cHardware4Stack" );
 
   // global_stack
-  global_stack.LoadState(fp);
+  for(int i=NUM_LOCAL_STACKS; i<NUM_STACKS; i++)
+    Stack(i).LoadState(fp);
 
   int num_threads;
-  fp >> thread_time_used;
+  //fp >> thread_time_used;
   fp >> num_threads;
   fp >> cur_thread;
 
@@ -1458,18 +1392,6 @@
 //  Instruction Helpers...
 ////////////////////////////
 
-inline int cHardware4Stack::FindModifiedRegister(int default_register)
-{
-  assert(default_register < NUM_REG_4STACK);  // Reg ID too high.
-
-  if (GetInstSet().IsNop(IP().GetNextInst())) {
-    IP().Advance();
-    default_register = GetInstSet().GetNopMod(IP().GetInst());
-    IP().FlagExecuted() = true;
-  }
-  return default_register;
-}
-
 inline int cHardware4Stack::FindModifiedStack(int default_stack)
 {
   assert(default_stack < NUM_STACKS);  // Stack ID too high.
@@ -1482,7 +1404,6 @@
   return default_stack;
 }
 
-
 inline int cHardware4Stack::FindModifiedHead(int default_head)
 {
   assert(default_head < NUM_HEADS); // Head ID too high.
@@ -1495,13 +1416,6 @@
   return default_head;
 }
 
-
-inline int cHardware4Stack::FindComplementRegister(int base_reg)
-{
-  const int comp_reg = base_reg + 2;
-  return comp_reg%NUM_REG_4STACK;
-}
-
 inline int cHardware4Stack::FindComplementStack(int base_stack)
 {
   const int comp_stack = base_stack + 2;
@@ -1513,103 +1427,12 @@
   organism->Fault(fault_loc, fault_type, fault_desc);
 }
 
-
-bool cHardware4Stack::Allocate_Necro(const int new_size)
-{
-  GetMemory().ResizeOld(new_size);
-  return true;
-}
-
-bool cHardware4Stack::Allocate_Random(const int old_size, const int new_size)
-{
-  GetMemory().Resize(new_size);
-
-  for (int i = old_size; i < new_size; i++) {
-    GetMemory()[i] = GetInstSet().GetRandomInst();
-  }
-  return true;
-}
-
-bool cHardware4Stack::Allocate_Default(const int new_size)
-{
-  GetMemory().Resize(new_size);
-
-  // New space already defaults to default instruction...
-
-  return true;
-}
-
-bool cHardware4Stack::Allocate_Main(const int allocated_size)
-{
-  // must do divide before second allocate & must allocate positive amount...
-  if (cConfig::GetRequireAllocate() && mal_active == true) {
-    Fault(FAULT_LOC_ALLOC, FAULT_TYPE_ERROR, "Allocate already active");
-    return false;
-  }
-  if (allocated_size < 1) {
-    Fault(FAULT_LOC_ALLOC, FAULT_TYPE_ERROR,
-	  cStringUtil::Stringf("Allocate of %d too small", allocated_size));
-    return false;
-  }
-
-  const int old_size = GetMemory().GetSize();
-  const int new_size = old_size + allocated_size;
-
-  // Make sure that the new size is in range.
-  if (new_size > MAX_CREATURE_SIZE  ||  new_size < MIN_CREATURE_SIZE) {
-    Fault(FAULT_LOC_ALLOC, FAULT_TYPE_ERROR,
-	  cStringUtil::Stringf("Invalid post-allocate size (%d)",
-			       new_size));
-    return false;
-  }
-
-  const int max_alloc_size = (int) (old_size * cConfig::GetChildSizeRange());
-  if (allocated_size > max_alloc_size) {
-    Fault(FAULT_LOC_ALLOC, FAULT_TYPE_ERROR,
-	  cStringUtil::Stringf("Allocate too large (%d > %d)",
-			       allocated_size, max_alloc_size));
-    return false;
-  }
-
-  const int max_old_size =
-    (int) (allocated_size * cConfig::GetChildSizeRange());
-  if (old_size > max_old_size) {
-    Fault(FAULT_LOC_ALLOC, FAULT_TYPE_ERROR,
-	  cStringUtil::Stringf("Allocate too small (%d > %d)",
-			       old_size, max_old_size));
-    return false;
-  }
-
-  switch (cConfig::GetAllocMethod()) {
-  case ALLOC_METHOD_NECRO:
-    // Only break if this succeeds -- otherwise just do random.
-    if (Allocate_Necro(new_size) == true) break;
-  case ALLOC_METHOD_RANDOM:
-    Allocate_Random(old_size, new_size);
-    break;
-  case ALLOC_METHOD_DEFAULT:
-    Allocate_Default(new_size);
-    break;
-  }
-
-  mal_active = true;
-
-  return true;
-}
-
-
-bool cHardware4Stack::Divide_CheckViable(const int child_size,
-				      const int parent_size)
+bool cHardware4Stack::Divide_CheckViable(const int parent_size,
+				      const int child_size, const int mem_space)
 {
   // Make sure the organism is okay with dividing now...
   if (organism->Divide_CheckViable() == false) return false; // (divide fails)
 
-  // 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();
@@ -1622,18 +1445,13 @@
 	  cStringUtil::Stringf("Invalid offspring length (%d)", child_size));
     return false; // (divide fails)
   }
-  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.
 
   int executed_size = 0;
   for (int i = 0; i < parent_size; i++) {
-    if (GetMemory().FlagExecuted(i)) executed_size++;
+    if (GetMemory(0).FlagExecuted(i)) executed_size++;
   }
 
   const int min_exe_lines = (int) (parent_size * cConfig::GetMinExeLines());
@@ -1648,9 +1466,9 @@
   // sure the specified fraction has been reached.
 
   int copied_size = 0;
-  for (int i = parent_size; i < parent_size + child_size; i++) {
-    if (GetMemory().FlagCopied(i)) copied_size++;
-  }
+  for (int i = 0; i < GetMemory(mem_space).GetSize(); i++) {
+    if (GetMemory(mem_space).FlagCopied(i)) copied_size++;
+   }
 
   const int min_copied =  (int) (child_size * cConfig::GetMinCopiedLines());
   if (copied_size < min_copied) {
@@ -1757,9 +1575,9 @@
 
   // Mutations in the parent's genome
   if (organism->GetParentMutProb() > 0) {
-    for (int i = 0; i < GetMemory().GetSize(); i++) {
+    for (int i = 0; i < GetMemory(0).GetSize(); i++) {
       if (organism->TestParentMut()) {
-	GetMemory()[i] = GetRandomInst();
+	GetMemory(0)[i] = GetRandomInst();
 	cpu_stats.mut_stats.parent_mut_line_count++;
       }
     }
@@ -1767,8 +1585,8 @@
 
 
   // Count up mutated lines
-  for(int i = 0; i < GetMemory().GetSize(); i++){
-    if (GetMemory().FlagPointMut(i) == true) {
+  for(int i = 0; i < GetMemory(0).GetSize(); i++){
+    if (GetMemory(0).FlagPointMut(i) == true) {
       cpu_stats.mut_stats.point_mut_line_count++;
     }
   }
@@ -1779,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()
@@ -1840,21 +1770,25 @@
 }
 
 
-bool cHardware4Stack::Divide_Main(const int div_point, const int extra_lines, double mut_multiplier)
+bool cHardware4Stack::Divide_Main(int mem_space_used, double mut_multiplier)
 {
-  const int child_size = GetMemory().GetSize() - div_point - extra_lines;
+  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
+  if(IP().GetMemSpace()!=0)
+    return false;
 
   // Make sure this divide will produce a viable offspring.
-  const bool viable = Divide_CheckViable(child_size, div_point);
-  if (viable == false) return false;
-
+  if(!Divide_CheckViable(GetMemory(IP().GetMemSpace()).GetSize(), 
+	 		 write_head_pos, mem_space_used)) 
+    return false;
+  
   // Since the divide will now succeed, set up the information to be sent
   // to the new organism
   cGenome & child_genome = organism->ChildGenome();
-  child_genome = cGenomeUtil::Crop(memory, div_point, div_point+child_size);
-
-  // Cut off everything in this memory past the divide point.
-  GetMemory().Resize(div_point);
+  GetMemory(mem_space_used).Resize(write_head_pos);
+  child_genome = GetMemory(mem_space_used);
 
   // Handle Divide Mutations...
   Divide_DoMutations(mut_multiplier);
@@ -1871,21 +1805,78 @@
   }
 #endif
 
-  mal_active = false;
-  if (cConfig::GetDivideMethod() == DIVIDE_METHOD_SPLIT) {
-    advance_ip = false;
-  }
-
-  // Activate the child, and do more work if the parent lives through the
-  // birth.
   bool parent_alive = organism->ActivateDivide();
-  if (parent_alive) {
-    if (cConfig::GetDivideMethod() == DIVIDE_METHOD_SPLIT) Reset();
-  }
 
+  //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;
 }
 
+cString cHardware4Stack::ConvertToInstruction(int mem_space_used)
+{
+  char c = mem_space_used + 97;
+  cString ret;
+  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 "";
+}
+  
 
 //////////////////////////
 // And the instructions...
@@ -1895,7 +1886,9 @@
 bool cHardware4Stack::Inst_ShiftR()
 {
   const int stack_used = FindModifiedStack(STACK_BX);
-  Stack(stack_used).Top() >>= 1;
+  int value = Stack(stack_used).Pop();
+  value >>= 1;
+  Stack(stack_used).Push(value);
   return true;
 }
 
@@ -1903,51 +1896,53 @@
 bool cHardware4Stack::Inst_ShiftL()
 {
   const int stack_used = FindModifiedStack(STACK_BX);
-  Stack(stack_used).Top() <<= 1;
+  int value = Stack(stack_used).Pop();
+  value <<= 1;
+  Stack(stack_used).Push(value);
   return true;
 }
 
 //8
-bool cHardware4Stack::Inst_Nand()
+bool cHardware4Stack::Inst_Val_Nand()
 {
   const int stack_used = FindModifiedStack(STACK_BX);
-  Stack(stack_used).Top() = ~(Stack(STACK_BX).Top() & Stack(STACK_CX).Top());
+  Stack(stack_used).Push(~(Stack(STACK_BX).Top() & Stack(STACK_CX).Top()));
   return true;
 }
 
 //9
-bool cHardware4Stack::Inst_Add()
+bool cHardware4Stack::Inst_Val_Add()
 {
   const int stack_used = FindModifiedStack(STACK_BX);
-  Stack(stack_used).Top() = Stack(STACK_BX).Top() + Stack(STACK_CX).Top();
+  Stack(stack_used).Push(Stack(STACK_BX).Top() + Stack(STACK_CX).Top());
   return true;
 }
 
 //10
-bool cHardware4Stack::Inst_Sub()
+bool cHardware4Stack::Inst_Val_Sub()
 {
   const int stack_used = FindModifiedStack(STACK_BX);
-  Stack(stack_used).Top() = Stack(STACK_BX).Top() - Stack(STACK_CX).Top();
+  Stack(stack_used).Push(Stack(STACK_BX).Top() - Stack(STACK_CX).Top());
   return true;
 }
 
 //11
-bool cHardware4Stack::Inst_Mult()
+bool cHardware4Stack::Inst_Val_Mult()
 {
   const int stack_used = FindModifiedStack(STACK_BX);
-  Stack(stack_used).Top() = Stack(STACK_BX).Top() * Stack(STACK_CX).Top();
+  Stack(stack_used).Push(Stack(STACK_BX).Top() * Stack(STACK_CX).Top());
   return true;
 }
 
 //12
-bool cHardware4Stack::Inst_Div()
+bool cHardware4Stack::Inst_Val_Div()
 {
   const int stack_used = FindModifiedStack(STACK_BX);
   if (Stack(STACK_CX).Top() != 0) {
     if (0-INT_MAX > Stack(STACK_BX).Top() && Stack(STACK_CX).Top() == -1)
       Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "div: Float exception");
     else
-      Stack(stack_used).Top() = Stack(STACK_BX).Top() / Stack(STACK_CX).Top();
+      Stack(stack_used).Push(Stack(STACK_BX).Top() / Stack(STACK_CX).Top());
   } else {
     Fault(FAULT_LOC_MATH, FAULT_TYPE_ERROR, "div: dividing by 0");
     return false;
@@ -1956,34 +1951,50 @@
 }
 
 //13 
-bool cHardware4Stack::Inst_MaxAlloc()   // Allocate maximal more
+bool cHardware4Stack::Inst_SetMemory()   // Allocate maximal more
 {
-  const int cur_size = GetMemory().GetSize();
-  const int alloc_size = Min((int) (cConfig::GetChildSizeRange() * cur_size),
-			     MAX_CREATURE_SIZE - cur_size);
-  if( Allocate_Main(alloc_size) ) {
-    Stack(STACK_AX).Top() = cur_size;
-    return true;
-  } else return false;
+  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);
+  //if( Allocate_Main(alloc_size) ) {
+  //  Stack(STACK_AX).Push(cur_size);
+  //  return true;
+  //} else return false;
 }
 
 //14
-bool cHardware4Stack::Inst_HeadDivide()
+bool cHardware4Stack::Inst_Divide()
 {
-  return Inst_HeadDivideMut(1);
+  int mem_space_used = GetHead(HEAD_WRITE).GetMemSpace();
+  int mut_multiplier = 1;
+
+  return Divide_Main(mem_space_used, mut_multiplier);
 }
 
 bool cHardware4Stack::Inst_HeadDivideMut(double mut_multiplier)
 {
-  AdjustHeads();
-  const int divide_pos = GetHead(HEAD_READ).GetPosition();
-  int child_end =  GetHead(HEAD_WRITE).GetPosition();
-  if (child_end == 0) child_end = GetMemory().GetSize();
-  const int extra_lines = GetMemory().GetSize() - child_end;
-  bool ret_val = Divide_Main(divide_pos, extra_lines, mut_multiplier);
-  // Re-adjust heads.
-  AdjustHeads();
-  return ret_val; 
+  // Unused for the moment...
+  return true;
+  //AdjustHeads();
+  //const int divide_pos = GetHead(HEAD_READ).GetPosition();
+  //int child_end =  GetHead(HEAD_WRITE).GetPosition();
+  //if (child_end == 0) child_end = GetMemory(0).GetSize();
+  //const int extra_lines = GetMemory(0).GetSize() - child_end;
+  //bool ret_val = Divide_Main(divide_pos, extra_lines, mut_multiplier);
+  //// Re-adjust heads.
+  //AdjustHeads();
+  //return ret_val; 
 }
 
 //15
@@ -2001,7 +2012,7 @@
   } else {
     read_inst = GetHead(head_id).GetInst().GetOp();
   }
-  Stack(STACK_BX).Top() = read_inst;
+  Stack(STACK_AX).Push(read_inst);
   ReadInst(read_inst);
 
   cpu_stats.mut_stats.copies_exec++;  // @CAO, this too..
@@ -2013,11 +2024,19 @@
 bool cHardware4Stack::Inst_HeadWrite()
 {
   const int head_id = FindModifiedHead(HEAD_WRITE);
-  cCPUHead & active_head = GetHead(head_id);
-
+  c4StackHead & active_head = GetHead(head_id);
+  int mem_space_used = active_head.GetMemSpace();
+  
+  //commented out for right now...
+  if(active_head.GetPosition()>=GetMemory(mem_space_used).GetSize()-1)
+   {
+     GetMemory(mem_space_used).Resize(GetMemory(mem_space_used).GetSize()+1);
+     GetMemory(mem_space_used).Copy(GetMemory(mem_space_used).GetSize()-1, GetMemory(mem_space_used).GetSize()-2);
+   }
+
   active_head.Adjust();
 
-  int value = Stack(STACK_BX).Top();
+  int value = Stack(STACK_AX).Pop();
   if (value < 0 || value >= GetNumInst()) value = 0;
 
   active_head.SetInst(cInstruction(value));
@@ -2032,8 +2051,8 @@
 bool cHardware4Stack::Inst_HeadCopy()
 {
   // For the moment, this cannot be nop-modified.
-  cCPUHead & read_head = GetHead(HEAD_READ);
-  cCPUHead & write_head = GetHead(HEAD_WRITE);
+  c4StackHead & read_head = GetHead(HEAD_READ);
+  c4StackHead & write_head = GetHead(HEAD_WRITE);
   sCPUStats & cpu_stats = organism->CPUStats();
 
   read_head.Adjust();
@@ -2065,19 +2084,19 @@
 }
 
 //17
-bool cHardware4Stack::Inst_IfEqu()      // Execute next if bx == ?cx?
+bool cHardware4Stack::Inst_IfEqual()      // Execute next if bx == ?cx?
 {
-  const int stack_used = FindModifiedStack(STACK_BX);
-  const int stack_used2 = FindComplementStack(stack_used);
+  const int stack_used = FindModifiedStack(STACK_AX);
+  const int stack_used2 = (stack_used+1)%NUM_STACKS;
   if (Stack(stack_used).Top() != Stack(stack_used2).Top())  IP().Advance();
   return true;
 }
 
 //18
-bool cHardware4Stack::Inst_IfNEqu()     // Execute next if bx != ?cx?
+bool cHardware4Stack::Inst_IfNotEqual()     // Execute next if bx != ?cx?
 {
-  const int stack_used = FindModifiedStack(STACK_BX);
-  const int stack_used2 = FindComplementStack(stack_used);
+  const int stack_used = FindModifiedStack(STACK_AX);
+  const int stack_used2 = (stack_used+1)%NUM_STACKS;
   if (Stack(stack_used).Top() == Stack(stack_used2).Top())  IP().Advance();
   return true;
 }
@@ -2085,17 +2104,17 @@
 //19
 bool cHardware4Stack::Inst_IfLess()       // Execute next if ?bx? < ?cx?
 {
-  const int stack_used = FindModifiedStack(STACK_BX);
-  const int stack_used2 = FindComplementStack(stack_used);
+  const int stack_used = FindModifiedStack(STACK_AX);
+  const int stack_used2 = (stack_used+1)%NUM_STACKS;
   if (Stack(stack_used).Top() >=  Stack(stack_used2).Top())  IP().Advance();
   return true;
 }
 
 //20
-bool cHardware4Stack::Inst_IfGr()       // Execute next if bx > ?cx?
+bool cHardware4Stack::Inst_IfGreater()       // Execute next if bx > ?cx?
 {
-  const int stack_used = FindModifiedStack(STACK_BX);
-  const int stack_used2 = FindComplementStack(stack_used);
+  const int stack_used = FindModifiedStack(STACK_AX);
+  const int stack_used2 = (stack_used+1)%NUM_STACKS;
   if (Stack(stack_used).Top() <= Stack(stack_used2).Top())  IP().Advance();
   return true;
 }
@@ -2104,11 +2123,11 @@
 bool cHardware4Stack::Inst_HeadPush()
 {
   const int head_used = FindModifiedHead(HEAD_IP);
-  StackPush(GetHead(head_used).GetPosition());
-  if (head_used == HEAD_IP) {
-    GetHead(head_used).Set(GetHead(HEAD_FLOW));
-    advance_ip = false;
-  }
+  Stack(STACK_BX).Push(GetHead(head_used).GetPosition());
+  //if (head_used == HEAD_IP) {
+  //  GetHead(head_used).Set(GetHead(HEAD_FLOW));
+  //  AdvanceIP() = false;
+  //}
   return true;
 }
 
@@ -2116,58 +2135,102 @@
 bool cHardware4Stack::Inst_HeadPop()
 {
   const int head_used = FindModifiedHead(HEAD_IP);
-  GetHead(head_used).Set(StackPop(), this);
+  GetHead(head_used).Set(Stack(STACK_BX).Pop(), 
+			 GetHead(head_used).GetMemSpace(), this);
   return true;
 }
 
 //23 
-bool cHardware4Stack::Inst_MoveHead()
+bool cHardware4Stack::Inst_HeadMove()
 {
   const int head_used = FindModifiedHead(HEAD_IP);
-  GetHead(head_used).Set(GetHead(HEAD_FLOW));
-  if (head_used == HEAD_IP) advance_ip = false;
+  if(head_used != HEAD_FLOW)
+    {
+      GetHead(head_used).Set(GetHead(HEAD_FLOW));
+      if (head_used == HEAD_IP) AdvanceIP() = false;
+    }
+  else
+    {
+      threads[cur_thread].heads[HEAD_FLOW]++;
+    }
   return true;
 }
 
 //24
-bool cHardware4Stack::Inst_HeadSearch()
+bool cHardware4Stack::Inst_Search()
 {
   ReadLabel();
   GetLabel().Rotate(2, NUM_NOPS_4STACK);
-  cCPUHead found_pos = FindLabel(0);
-  const int search_size = found_pos.GetPosition() - IP().GetPosition();
-  Stack(STACK_BX).Top() = search_size;
-  Stack(STACK_CX).Top() = GetLabel().GetSize();
-  GetHead(HEAD_FLOW).Set(found_pos);
-  GetHead(HEAD_FLOW).Advance();
+  c4StackHead found_pos = FindLabel(0);
+  if(found_pos.GetPosition()-IP().GetPosition()==0)
+    {
+      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);
+    }
+  else
+    {
+      int search_size = found_pos.GetPosition() - IP().GetPosition() + GetLabel().GetSize() + 1;
+      Stack(STACK_BX).Push(search_size);
+      Stack(STACK_AX).Push(GetLabel().GetSize());
+      GetHead(HEAD_FLOW).Set(found_pos);
+    }  
+  
   return true; 
 }
 
 //25
-bool cHardware4Stack::Inst_PushA() { StackPush(Stack(STACK_AX).Top()); return true;}
+bool cHardware4Stack::Inst_PushNext() 
+{
+  int stack_used = FindModifiedStack(STACK_AX);
+  int successor = (stack_used+1)%NUM_STACKS;
+  Stack(successor).Push(Stack(stack_used).Pop());
+  return true;
+}
 
 //26
-bool cHardware4Stack::Inst_PushB() { StackPush(Stack(STACK_AX).Top()); return true;}
+bool cHardware4Stack::Inst_PushPrevious() 
+{
+  int stack_used = FindModifiedStack(STACK_BX);
+  int predecessor = (stack_used+NUM_STACKS-1)%NUM_STACKS;
+  Stack(predecessor).Push(Stack(stack_used).Pop());
+  return true;
+}
 
 //27
-bool cHardware4Stack::Inst_PushC() { StackPush(Stack(STACK_AX).Top()); return true;}
+bool cHardware4Stack::Inst_PushComplement() 
+{
+  int stack_used = FindModifiedStack(STACK_BX);
+  int complement = FindComplementStack(stack_used);
+  Stack(complement).Push(Stack(stack_used).Pop());
+  return true;
+}
 
-//INSTRUCTION 28 - "ValDelete" GOES HERE - law
+//28
+bool cHardware4Stack::Inst_ValDelete()
+{
+  int stack_used = FindModifiedStack(STACK_BX);
+  Stack(stack_used).Pop();
+  return true;
+}
 
 //29
-bool cHardware4Stack::Inst_CopyStack()
+bool cHardware4Stack::Inst_ValCopy()
 {
   const int stack_used = FindModifiedStack(STACK_BX);
-  const int other_stack = FindComplementStack(stack_used);
-  Stack(other_stack).Top() = Stack(stack_used).Top();
+  Stack(stack_used).Push(Stack(stack_used).Top());
   return true;
 }
 
 //30
 bool cHardware4Stack::Inst_ForkThread()
 {
-  IP().Advance();
-  if (!ForkThread()) Fault(FAULT_LOC_THREAD_FORK, FAULT_TYPE_FORK_TH);
+  if (!ForkThread()) 
+    Fault(FAULT_LOC_THREAD_FORK, FAULT_TYPE_FORK_TH);
+  else
+    IP().Advance();
   return true;
 }
 
@@ -2181,18 +2244,20 @@
 }
 
 //32
-bool cHardware4Stack::Inst_Inc()
+bool cHardware4Stack::Inst_Increment()
 {
   const int stack_used = FindModifiedStack(STACK_BX);
-  Stack(stack_used).Top() += 1;
+  int value = Stack(stack_used).Pop();
+  Stack(stack_used).Push(++value);
   return true;
 }
 
 //33
-bool cHardware4Stack::Inst_Dec()
+bool cHardware4Stack::Inst_Decrement()
 {
   const int stack_used = FindModifiedStack(STACK_BX);
-  Stack(stack_used).Top() -= 1;
+  int value = Stack(stack_used).Pop();
+  Stack(stack_used).Push(--value);
   return true;
 }
 
@@ -2201,7 +2266,10 @@
 {
   const int stack_used = FindModifiedStack(STACK_BX);
   if (Stack(STACK_CX).Top() != 0) {
-    Stack(stack_used).Top() = 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;
@@ -2213,1053 +2281,91 @@
 bool cHardware4Stack::Inst_KillThread()
 {
   if (!KillThread()) Fault(FAULT_LOC_THREAD_KILL, FAULT_TYPE_KILL_TH);
-  else advance_ip = false;
-  return true;
-}
-
-/*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; 
-}
-
-bool cHardware4Stack::Inst_IfNot0()       // Execute next if ?bx? != 0.
-{ 
-  const int reg_used = FindModifiedRegister(REG_BX);
-  if (Register(reg_used) == 0)  IP().Advance();
-  return true;
-}
-
-bool cHardware4Stack::Inst_IfGr0()       // Execute next if ?bx? ! < 0.
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  if (Register(reg_used) <= 0)  IP().Advance();
-  return true;
-}
-
-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;
-}
-
-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;
-}
-
-bool cHardware4Stack::Inst_IfLess0()       // Execute next if ?bx? != 0.
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  if (Register(reg_used) >= 0)  IP().Advance();
-  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;
-}
-
-bool cHardware4Stack::Inst_IfLsEqu()       // 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;
-}
-
-bool cHardware4Stack::Inst_IfBit1()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  if ((Register(reg_used) & 1) == 0)  IP().Advance();
-  return true;
-}
-
-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
-{
-  if (Register(REG_AX) == Register(REG_CX) )  IP().Advance();
-  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 cCPUHead 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 cCPUHead 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 cCPUHead 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 cCPUHead 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 cCPUHead 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;
+  else AdvanceIP() = false;
   return true;
 }
 
-bool cHardware4Stack::Inst_SetNum()
+//36
+bool cHardware4Stack::Inst_IO()
 {
-  ReadLabel();
-  Register(REG_BX) = GetLabel().AsInt();
-  return true;
-}
+  const int stack_used = FindModifiedStack(STACK_BX);
 
-bool cHardware4Stack::Inst_Zero()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  Register(reg_used) = 0;
-  return true;
-}
+  // Do the "put" component
+  const int value_out = Stack(stack_used).Top();
+  DoOutput(value_out);  // Check for tasks compleated.
 
-bool cHardware4Stack::Inst_Neg()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  Register(reg_used) = 0-Register(reg_used);
+  // 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_Square()
+int cHardware4Stack::FindFirstEmpty()
 {
-  const int reg_used = FindModifiedRegister(REG_BX);
-  Register(reg_used) = Register(reg_used) * Register(reg_used);
-  return true;
-}
+  bool OK=true;
+  const int current_mem_space = IP().GetMemSpace();
 
-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;
-}
+  for(int x=1; x<NUM_MEMORY_SPACES; x++)
+    {
+      OK=true;
+      
+      int index = (current_mem_space+x) % NUM_MEMORY_SPACES;
 
-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;
+      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_Log10()
+bool cHardware4Stack::isEmpty(int mem_space_used)
 {
-  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;
-  }
+  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_Minus18()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  Register(reg_used) -= 18;
-  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_Nor()
+bool cHardware4Stack::Inst_Inject()
 {
-  const int reg_used = FindModifiedRegister(REG_BX);
-  Register(reg_used) = ~(Register(REG_BX) | Register(REG_CX));
-  return true;
-}
+  double mut_multiplier = 1;
 
-bool cHardware4Stack::Inst_And()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  Register(reg_used) = (Register(REG_BX) & Register(REG_CX));
-  return true;
+  return InjectParasite(mut_multiplier);
 }
 
-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()
+/*
+bool cHardware4Stack::Inst_InjectRand()
 {
-  const int reg_used = FindModifiedRegister(REG_BX);
-  Register(reg_used) = Register(REG_BX) ^ Register(REG_CX);
+  // 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_Copy()
-{
-  const cCPUHead from(this, Register(REG_BX));
-  cCPUHead 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 cCPUHead 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()
-{
-  cCPUHead 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);
-  cCPUHead from(this, Register(reg_used));
-  StackPush(from.GetInst().GetOp());
-  return true;
-}
-
-bool cHardware4Stack::Inst_StackWriteInst()
-{
-  const int reg_used = FindModifiedRegister(REG_BX);
-  cCPUHead 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);
-  cCPUHead from(this, Register(REG_BX));
-  cCPUHead 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 cCPUHead from(this, Register(REG_BX));
-  const cCPUHead 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_Divide()  
-{ 
-  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.
-  cCPUHead & read_head = GetHead(HEAD_READ);
-  cCPUHead & 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.
-  cCPUHead 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.2.2.2 avida/current/source/cpu/hardware_4stack.hh:1.2.2.3
--- avida/current/source/cpu/hardware_4stack.hh:1.2.2.2	Thu May 29 11:47:51 2003
+++ avida/current/source/cpu/hardware_4stack.hh	Mon Aug 25 23:30:20 2003
@@ -20,44 +20,49 @@
 #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;
 static const int STACK_CX = 2;
 static const int STACK_DX = 3;
 static const int NUM_NOPS_4STACK = 4;
+static const int NUM_MEMORY_SPACES = 4; 
 
 /**
  * This class is needed to run several threads on a single genome.
  *
- * @see cCPUStack, cCPUHead, cHardware4Stack
+ * @see cCPUStack, c4StackHead, cHardware4Stack
  **/
 
 struct cHardware4Stack_Thread {
 private:
   int id;
+
 public:
-  int reg[NUM_REG_4STACK];
-  cCPUHead heads[NUM_HEADS];
-  cCPUStack stack;
-  UCHAR cur_stack;              // 0 = local stack, 1 = global stack.
+  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);
@@ -95,18 +100,18 @@
   static cInstLib4Stack *initInstLib(void);
   tHardware4StackMethod *m_functions;
 private:
-  cCPUMemory memory;          // Memory...
-  cCPUStack global_stack;     // A stack that all threads share.
+  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;
   int cur_thread;
 
   // Flags...
-  bool mal_active;         // Has an allocate occured since last divide?
-  bool advance_ip;         // Should the IP advance after this instruction?
+  bool mal_active;         // Has an allocate occured since last dividehe?
+  //bool advance_ip;         // Should the IP advance after this instruction?
 
   // Instruction costs...
 #ifdef INSTRUCTION_COSTS
@@ -114,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();
@@ -137,15 +151,16 @@
   bool GetMalActive() const   { return mal_active; }
 
   // --------  Stack Manipulation...  --------
-  inline void StackPush(int value);
-  inline int StackPop();
   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();
-  int GetActiveStackID() const { return threads[cur_thread].cur_stack; }
-  //NEW STUFF
-  inline cCPUStack & Stack(int stack_id); //retrieves appropriate stack
+  cString GetActiveStackID(int stackID) const;
+  //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; }
@@ -158,19 +173,35 @@
   { threads[cur_thread].cur_head = (UCHAR) new_head; }
 
   int GetCurHead() const { return threads[cur_thread].cur_head; }
-  const cCPUHead & GetHead(int head_id) const
-    { return threads[cur_thread].heads[head_id]; }
-  cCPUHead & GetHead(int head_id) { return threads[cur_thread].heads[head_id];}
+  
+  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];}
+  
+  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 cCPUHead & GetActiveHead() const { return GetHead(GetCurHead()); }
-  cCPUHead & GetActiveHead() { return GetHead(GetCurHead()); }
+  const c4StackHead & GetActiveHead() const { return GetHead(GetCurHead()); }
+  c4StackHead & GetActiveHead() { return GetHead(GetCurHead()); }
 
   void AdjustHeads();
 
-  inline const cCPUHead & IP() const
+  inline const c4StackHead & IP() const
     { return threads[cur_thread].heads[HEAD_IP]; }
-  inline cCPUHead & IP() { 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);
@@ -183,12 +214,14 @@
 
 
   // --------  Register Manipulation  --------
-  int Register(int reg_id) const { return threads[cur_thread].reg[reg_id]; }
-  int & Register(int reg_id) { return threads[cur_thread].reg[reg_id]; }
+  //int Register(int reg_id) const { return threads[cur_thread].reg[reg_id]; }
+  //int & Register(int reg_id) { return threads[cur_thread].reg[reg_id]; }
 
-  // --------  Memory Manipulation  --------
-  inline const cCPUMemory & Memory() const { return memory; }
-  inline cCPUMemory & Memory() { return memory; }
+  // --------  Memory Manipulation  --------}
+  inline cCPUMemory & GetMemory();
+  inline cCPUMemory & GetMemory(int mem_space);
+  inline const cCPUMemory & GetMemory(int mem_space) const;
+  inline const cCPUMemory & GetMemory() const;
 
   // --------  Thread Manipulation  --------
   bool ForkThread(); // Adds a new thread based off of cur_thread.
@@ -196,16 +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  --------
-  const cCPUMemory & GetMemory() const { return memory; }
-  cCPUMemory & GetMemory() { return memory; }
-
-  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(); }
@@ -217,32 +249,33 @@
   }
 
   // Complex label manipulation...
-  cCPUHead FindLabel(int direction);
+  c4StackHead FindLabel(int direction);
   int FindLabel_Forward(const cCodeLabel & search_label,
 			  const cGenome & search_genome, int pos);
   int FindLabel_Backward(const cCodeLabel & search_label,
 			  const cGenome & search_genome, int pos);
-  cCPUHead FindLabel(const cCodeLabel & in_label, int direction);
-  cCPUHead FindFullLabel(const cCodeLabel & in_label);
+  c4StackHead FindLabel(const cCodeLabel & in_label, int direction);
+  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, cCPUHead & cur_head);
+  bool TriggerMutations(int trigger, c4StackHead & cur_head);
   bool TriggerMutations_ScopeGenome(const cMutation * cur_mut,
-        cCPUMemory & target_memory, cCPUHead & cur_head, const double rate);
+        cCPUMemory & target_memory, c4StackHead & cur_head, const double rate);
   bool TriggerMutations_ScopeLocal(const cMutation * cur_mut,
-        cCPUMemory & target_memory, cCPUHead & cur_head, const double rate);
+        cCPUMemory & target_memory, c4StackHead & cur_head, const double rate);
   int TriggerMutations_ScopeGlobal(const cMutation * cur_mut,
-        cCPUMemory & target_memory, cCPUHead & cur_head, const double rate);
+        cCPUMemory & target_memory, c4StackHead & cur_head, const double rate);
   void TriggerMutations_Body(int type, cCPUMemory & target_memory,
-			     cCPUHead & cur_head);
+			     c4StackHead & cur_head);
 
   void ReadInst(const int in_inst);
 
@@ -250,16 +283,15 @@
   void LoadState(std::istream & fp);
 
   void InitInstSet(const cString & filename, cInstSet & inst_set);
+  cString ConvertToInstruction(int mem_space_used);
 
 
 private:
  
  /////////---------- Instruction Helpers ------------//////////
 
-  int FindModifiedRegister(int default_register);
   int FindModifiedStack(int default_stack);
   int FindModifiedHead(int default_head);
-  int FindComplementRegister(int base_reg);
   int FindComplementStack(int base_stack);
 
   void Fault(int fault_loc, int fault_type, cString fault_desc=""); 
@@ -268,10 +300,10 @@
   bool Allocate_Default(const int new_size);
   bool Allocate_Main(const int allocated_size);
 
-  bool Divide_Main(const int divide_point, const int extra_lines=0, double mut_multiplier=1);
-
-  bool Divide_CheckViable(const int child_size, const int parent_size);
+  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);
@@ -280,224 +312,79 @@
 public:
   /////////---------- Instruction Library ------------//////////
 
-  // Flow Control
-  bool Inst_If0();
-  bool Inst_IfEqu();
-  bool Inst_IfNot0();
-  bool Inst_IfNEqu();
-  bool Inst_IfGr0();
-  bool Inst_IfGr();
-  bool Inst_IfGrEqu0();
-  bool Inst_IfGrEqu();
-  bool Inst_IfLess0();
-  bool Inst_IfLess();
-  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_HeadPop();
-  bool Inst_HeadPush();
-
-  bool Inst_PopA();
-  bool Inst_PopB();
-  bool Inst_PopC();
-  bool Inst_PushA();
-  bool Inst_PushB();
-  bool Inst_PushC();
-
-  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
+  //6
   bool Inst_ShiftR();
+  //7
   bool Inst_ShiftL();
-  bool Inst_Bit1();
-  bool Inst_SetNum();
-  bool Inst_Inc();
-  bool Inst_Dec();
-  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_Add();
-  bool Inst_Sub();
-  bool Inst_Mult();
-  bool Inst_Div();
-  bool Inst_Mod();
-  bool Inst_Nand();
-  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();
+  //8
+  bool Inst_Val_Nand();
+  //9
+  bool Inst_Val_Add();
+  //10
+  bool Inst_Val_Sub();
+  //11
+  bool Inst_Val_Mult();
+  //12
+  bool Inst_Val_Div();
+  //13
+  bool Inst_SetMemory();
+  //14
   bool Inst_Divide();
-  bool Inst_CAlloc();
-  bool Inst_CDivide();
-  bool Inst_MaxAlloc();
+  //15
+  bool Inst_HeadRead();
+  //16
+  bool Inst_HeadWrite();
+  //??
+  bool Inst_HeadCopy();
+  //17
+  bool Inst_IfEqual();
+  //18
+  bool Inst_IfNotEqual();
+  //19
+  bool Inst_IfLess();
+  //20
+  bool Inst_IfGreater();
+  //21
+  bool Inst_HeadPush();
+  //22
+  bool Inst_HeadPop();
+  //23
+  bool Inst_HeadMove();
+  //24
+  bool Inst_Search();
+  //25
+  bool Inst_PushNext();
+  //26
+  bool Inst_PushPrevious();
+  //27
+  bool Inst_PushComplement();
+  //28
+  bool Inst_ValDelete();
+  //29
+  bool Inst_ValCopy();
+  //30
+  bool Inst_ForkThread();
+  //31
+  bool Inst_IfLabel();
+  //32
+  bool Inst_Increment();
+  //33
+  bool Inst_Decrement();
+  //34
+  bool Inst_Mod();
+  //35 
+  bool Inst_KillThread();
+  //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_ForkThread();
-  bool Inst_KillThread();
-  bool Inst_ThreadID();
-
-  // Head-based instructions...
-
-  bool Inst_SetHead();
-  bool Inst_AdvanceHead();
-  bool Inst_MoveHead();
-  bool Inst_JumpHead();
-  bool Inst_GetHead();
-  bool Inst_IfLabel();
-  bool Inst_HeadDivide();
-  bool Inst_HeadRead();
-  bool Inst_HeadWrite();
-  bool Inst_HeadCopy();
-  bool Inst_HeadSearch();
-  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();
+  */
+ 
 };
 
 
@@ -505,6 +392,32 @@
 //  cHardware4Stack
 //////////////////
 
+//Not used, but here to satisfy the requirements of HardwareBase
+inline const cCPUMemory & cHardware4Stack::GetMemory() const
+{
+  return memory_array[0];
+}
+
+//Not used, but here to satisfy the requirements of HardwareBase 
+inline cCPUMemory & cHardware4Stack::GetMemory()
+{
+  return memory_array[0];
+}
+
+inline const cCPUMemory & cHardware4Stack::GetMemory(int mem_space) const
+{
+  if(mem_space >= NUM_MEMORY_SPACES)
+    mem_space %= NUM_MEMORY_SPACES;
+  return memory_array[mem_space];
+}
+
+inline cCPUMemory & cHardware4Stack::GetMemory(int mem_space)
+{
+ if(mem_space >= NUM_MEMORY_SPACES)
+    mem_space %= NUM_MEMORY_SPACES;
+  return memory_array[mem_space];
+}
+
 inline void cHardware4Stack::NextThread()
 {
   cur_thread++;
@@ -519,76 +432,101 @@
 
 inline void cHardware4Stack::SetThread(int value)
 {
-     if (value>=0 && value < GetNumThreads())
-          cur_thread=value;
+  if (value>=0 && value < GetNumThreads())
+    cur_thread=value;
 }
 
-inline void cHardware4Stack::StackPush(int value)
-{
-  if (threads[cur_thread].cur_stack == 0) {
-    threads[cur_thread].stack.Push(value);
-  } else {
-    global_stack.Push(value);
-  }
+inline cInjectGenotype * cHardware4Stack::GetThreadOwner() 
+{ 
+  return threads[cur_thread].owner; 
 }
 
-inline int cHardware4Stack::StackPop()
-{
-  int pop_value;
-
-  if (threads[cur_thread].cur_stack == 0) {
-    pop_value = threads[cur_thread].stack.Pop();
-  } else {
-    pop_value = global_stack.Pop();
-  }
-
-  return pop_value;
+inline void cHardware4Stack::SetThreadOwner(cInjectGenotype * in_genotype)
+{ 
+  threads[cur_thread].owner = in_genotype; 
 }
 
-inline void cHardware4Stack::StackFlip()
+/*inline void cHardware4Stack::StackFlip()
 {
   if (threads[cur_thread].cur_stack == 0) {
     threads[cur_thread].stack.Flip();
   } else {
     global_stack.Flip();
   }
-}
+}*/
 
-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 == -1) stack_id = threads[cur_thread].cur_stack;
+  if(stack_id<0 || stack_id>NUM_STACKS) stack_id=0;
+  
+  if(in_thread==-1)
+    in_thread=cur_thread;
+  
+  return Stack(stack_id, in_thread).Get(depth);
+}
 
-  if (stack_id == 0) value = threads[cur_thread].stack.Get(depth);
-  else if (stack_id == 1) value = global_stack.Get(depth);
+//inline void cHardware4Stack::StackClear()
+//{
+  
+  //if (threads[cur_thread].cur_stack == 0) {
+  //  threads[cur_thread].stack.Clear();
+  //} else {
+  //  global_stack.Clear();
+  //}
+//}
+
+//inline void cHardware4Stack::SwitchStack()
+//{
+//  threads[cur_thread].cur_stack++;
+//  if (threads[cur_thread].cur_stack > 1) threads[cur_thread].cur_stack = 0;
+//}
 
-  return value;
+inline cCPUStack& cHardware4Stack::Stack(int stack_id)
+{
+  if(stack_id >= NUM_STACKS)
+    {
+      stack_id=0;
+    }
+  if(stack_id < NUM_LOCAL_STACKS)
+    return threads[cur_thread].local_stacks[stack_id];
+  else
+    return global_stacks[stack_id % NUM_LOCAL_STACKS];
 }
 
-inline void cHardware4Stack::StackClear()
+inline const cCPUStack& cHardware4Stack::Stack(int stack_id) const 
 {
-  if (threads[cur_thread].cur_stack == 0) {
-    threads[cur_thread].stack.Clear();
-  } else {
-    global_stack.Clear();
-  }
+  if(stack_id >= NUM_STACKS)
+    {
+      stack_id=0;
+    }
+  if(stack_id < NUM_LOCAL_STACKS)
+    return threads[cur_thread].local_stacks[stack_id];
+  else
+    return global_stacks[stack_id % NUM_LOCAL_STACKS];
 }
 
-inline void cHardware4Stack::SwitchStack()
+inline cCPUStack& cHardware4Stack::Stack(int stack_id, int in_thread) 
 {
-  threads[cur_thread].cur_stack++;
-  if (threads[cur_thread].cur_stack > 1) threads[cur_thread].cur_stack = 0;
+  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 cCPUStack& cHardware4Stack::Stack(int stack_id)
+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[cur_thread].local_stacks[stack_id];
+    return threads[in_thread].local_stacks[stack_id];
   else
     return global_stacks[stack_id % NUM_LOCAL_STACKS];
 }
Index: avida/current/source/cpu/hardware_base.hh
diff -u avida/current/source/cpu/hardware_base.hh:1.12.2.2 avida/current/source/cpu/hardware_base.hh:1.12.2.3
--- avida/current/source/cpu/hardware_base.hh:1.12.2.2	Tue May 20 05:12:19 2003
+++ avida/current/source/cpu/hardware_base.hh	Mon Aug 25 23:30:20 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;
@@ -69,6 +69,7 @@
 
   // --------  @CAO Should be rethought?  --------
   virtual cCPUMemory & GetMemory() = 0;
+  virtual cCPUMemory & GetMemory(int) = 0;
 
   // --------  DEBUG ---------
   static int GetInstanceCount() { return instance_count; }
Index: avida/current/source/cpu/hardware_cpu.cc
diff -u avida/current/source/cpu/hardware_cpu.cc:1.34.2.8 avida/current/source/cpu/hardware_cpu.cc:1.34.2.9
--- avida/current/source/cpu/hardware_cpu.cc:1.34.2.8	Mon Aug 25 18:46:26 2003
+++ avida/current/source/cpu/hardware_cpu.cc	Mon Aug 25 23:30:20 2003
@@ -13,9 +13,7 @@
 #include "../tools/string_util.hh"
 
 #include "../main/config.hh"
-#ifdef USE_INST_SET_CODE
-  #include "../main/inst_set.hh"
-#endif /* USE_INST_SET_CODE */
+#include "../main/inst_set.hh"
 #include "../main/inst_lib.hh"
 #include "../main/genome_util.hh"
 #include "../main/organism.hh"
@@ -147,7 +145,6 @@
   stack.LoadState(fp);
 
   char marker; fp>>marker; assert( marker == '|' );
-#ifdef USE_INST_SET_CODE
   /* YIKES!  data loss below: */
   char the_cur_stack = cur_stack;
   char the_cur_head = cur_head;
@@ -155,11 +152,6 @@
   fp.get(the_cur_stack);
   fp.get(the_cur_head);
   fp.get(the_input_pointer);
-#else /* USE_INST_SET_CODE */
-  fp.get((char)cur_stack);
-  fp.get((char)cur_head);
-  fp.get((char)input_pointer);
-#endif /* USE_INST_SET_CODE */
 
   // IO buffers
   input_buf.LoadState(fp);
@@ -171,7 +163,6 @@
 }
 
 
-#ifdef USE_INST_SET_CODE
 ///////////////
 //  cInstLibCPU
 ///////////////
@@ -227,13 +218,11 @@
   const cInstruction & GetInstDefault(){ return inst_default; }
   const cInstruction & GetInstError(){ return inst_error; }
 };
-#endif /* USE_INST_SET_CODE */
 
 ///////////////
 //  cHardwareCPU
 ///////////////
 
-#ifdef USE_INST_SET_CODE
 const cInstruction cInstLibCPU::inst_error(255);
 const cInstruction cInstLibCPU::inst_default(0);
 cInstLibBase *cHardwareCPU::GetInstLib(){ return s_inst_slib; }
@@ -441,6 +430,9 @@
     cInstEntryCPU("h-copy9",    &cHardwareCPU::Inst_HeadCopy9),
     cInstEntryCPU("h-copy10",   &cHardwareCPU::Inst_HeadCopy10),
 
+    cInstEntryCPU("divide-sex",    &cHardwareCPU::Inst_HeadDivideSex),
+    cInstEntryCPU("divide-asex",   &cHardwareCPU::Inst_HeadDivide1),
+
     cInstEntryCPU("h-divide1",      &cHardwareCPU::Inst_HeadDivide1),
     cInstEntryCPU("h-divide2",      &cHardwareCPU::Inst_HeadDivide2),
     cInstEntryCPU("h-divide3",      &cHardwareCPU::Inst_HeadDivide3),
@@ -540,16 +532,13 @@
 
   return inst_lib;
 }
-#endif /* USE_INST_SET_CODE */
 
 cHardwareCPU::cHardwareCPU(cOrganism * in_organism, cInstSet * in_inst_set)
   : cHardwareBase(in_organism, in_inst_set)
 {
-#ifdef USE_INST_SET_CODE
   /* FIXME:  reorganize storage of m_functions.  -- kgn */
   m_functions = s_inst_slib->GetFunctions();
   /**/
-#endif /* USE_INST_SET_CODE */
   memory = in_organism->GetGenome();  // Initialize memory...
   Reset();                            // Setup the rest of the hardware...
 }
@@ -689,24 +678,14 @@
 bool cHardwareCPU::SingleProcess_ExecuteInst(const cInstruction & cur_inst) 
 {
   // Get a pointer to the corrisponding method...
-#ifdef USE_INST_SET_CODE
-  /* XXX start -- kgn */
   int inst_idx = GetInstSet().GetLibFunctionIndex(cur_inst);
-  /* XXX end */
-#else /* USE_INST_SET_CODE */
-  tHardwareMethod inst_ptr = GetInstSet().GetFunction(cur_inst);
-#endif /* USE_INST_SET_CODE */
       
   // Mark the instruction as executed
   IP().FlagExecuted() = true;
 	
 #ifdef EXECUTION_ERRORS
   // If there is an execution error, execute a random instruction.
-#ifdef USE_INST_SET_CODE
   if (organism->TestExeErr()) inst_idx = GetInstSet().GetRandFunctionIndex();
-#else /* USE_INST_SET_CODE */
-  if (organism->TestExeErr()) inst_ptr = GetInstSet().GetRandFunction();
-#endif /* USE_INST_SET_CODE */
 #endif /* EXECUTION_ERRORS */
 	
 #ifdef INSTRUCTION_COUNT
@@ -715,15 +694,9 @@
 #endif
 	
   // And execute it.
-#ifdef USE_INST_SET_CODE
-  /* XXX start -- kgn */
   const bool exec_success
   //= (this->*(s_inst_slib->GetFunctions()[inst_idx]))();
   = (this->*(m_functions[inst_idx]))();
-  /* XXX end */
-#else /* USE_INST_SET_CODE */
-  const bool exec_success = (this->*inst_ptr)();
-#endif /* USE_INST_SET_CODE */
 	
 #ifdef INSTRUCTION_COUNT
   // decremenet if the instruction was not executed successfully
@@ -1117,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)
@@ -1721,8 +1694,47 @@
   }
 
   // Save the information we collected here...
-  organism->GetPhenotype().SetLinesExecuted(executed_size);
-  organism->GetPhenotype().SetLinesCopied(copied_size);
+  cPhenotype & phenotype = organism->GetPhenotype();
+  phenotype.SetLinesExecuted(executed_size);
+  phenotype.SetLinesCopied(copied_size);
+
+  // Determine the fitness of this organism as compared to its parent...
+  if (cConfig::GetTestSterilize() == true &&
+      phenotype.IsInjected() == false) {
+    const int merit_base =
+      cPhenotype::CalcSizeMerit(genome_size, copied_size, executed_size);
+    const double cur_fitness =
+      merit_base * phenotype.GetCurBonus() / phenotype.GetTimeUsed();
+    const double fitness_ratio = cur_fitness / phenotype.GetLastFitness();
+
+
+    //  const double neut_min = parent_fitness * FITNESS_NEUTRAL_MIN;
+    //  const double neut_max = parent_fitness * FITNESS_NEUTRAL_MAX;
+  
+    bool sterilize = false;
+  
+    if (fitness_ratio < FITNESS_NEUTRAL_MIN) {
+      if (g_random.P(organism->GetSterilizeNeg())) sterilize = true;
+    } else if (fitness_ratio <= FITNESS_NEUTRAL_MAX) {
+      if (g_random.P(organism->GetSterilizeNeut())) sterilize = true;
+    } else {
+      if (g_random.P(organism->GetSterilizePos())) sterilize = true;
+    }
+  
+//     cout << "[ min(" << genome_size
+// 	 << "," << copied_size
+// 	 << "," << executed_size
+// 	 << ") * " << phenotype.GetCurBonus()
+// 	 << " / " << phenotype.GetTimeUsed()
+// 	 << "] / " << phenotype.GetLastFitness()
+// 	 << " == " << fitness_ratio;
+
+    if (sterilize == true) {
+      //Don't let this organism have this or any more children!
+      phenotype.IsFertile() = false;
+      return false;
+    }    
+  }
 
   return true; // (divide succeeds!)
 }
@@ -2751,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.
@@ -2765,7 +2777,7 @@
   // Set the relevent flags.
   organism->GetPhenotype().IsModifier() = true;
 
-  return true;
+  return inject_signal;
 }
 
 
@@ -2843,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;
@@ -2851,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;
@@ -2859,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;
 }
 
@@ -2881,7 +2894,6 @@
   DoOutput(value_out);  // Check for tasks compleated.
 
   // Do the "get" component
-  //std::cout << "<cHardwareCPU::Inst_TaskIO> about to organism->GetInputAt()..." << std::endl;
   const int value_in = organism->GetInputAt(threads[GetCurThread()].input_pointer);
   Register(reg_used) = value_in;
   DoInput(value_in);
Index: avida/current/source/cpu/hardware_cpu.hh
diff -u avida/current/source/cpu/hardware_cpu.hh:1.19.2.4 avida/current/source/cpu/hardware_cpu.hh:1.19.2.5
--- avida/current/source/cpu/hardware_cpu.hh:1.19.2.4	Thu May 29 11:47:52 2003
+++ avida/current/source/cpu/hardware_cpu.hh	Mon Aug 25 23:30:21 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;
@@ -192,6 +192,8 @@
   // --------  Accessors  --------
   const cCPUMemory & GetMemory() const { return memory; }
   cCPUMemory & GetMemory() { return memory; }
+  const cCPUMemory & GetMemory(int value) const { return memory;}
+  cCPUMemory & GetMemory(int value) { return memory; }
 
   int GetThreadTimeUsed() const { return thread_time_used; }
   int GetNumThreads() const     { return threads.GetSize(); }
@@ -214,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/hardware_util.cc
diff -u avida/current/source/cpu/hardware_util.cc:1.12.2.8 avida/current/source/cpu/hardware_util.cc:1.12.2.9
--- avida/current/source/cpu/hardware_util.cc:1.12.2.8	Thu May 29 11:47:52 2003
+++ avida/current/source/cpu/hardware_util.cc	Mon Aug 25 23:30:21 2003
@@ -22,17 +22,10 @@
 using namespace std;
 
 
-#ifdef USE_INST_SET_CODE
 void cHardwareUtil::LoadInstSet(cString filename, cInstSet & inst_set, 
 				tDictionary<int> & nop_dict,
 				tDictionary<int> & inst_dict
 ){
-#else /* USE_INST_SET_CODE */
-void cHardwareUtil::LoadInstSet(cString & filename, cInstSet & inst_set, 
-				tDictionary<int> & nop_dict,
-				tDictionary<tHardwareMethod> & inst_dict
-){
-#endif /* USE_INST_SET_CODE */
   // If there is no filename, use the default for the appropriate hardware.
   cString default_filename = "unknown";
   if (cConfig::GetHardwareType() == HARDWARE_TYPE_CPU_ORIGINAL) {
@@ -92,45 +85,18 @@
     
     // Otherwise, this instruction will be in the set.
     // First, determine if it is a nop...
-#ifdef USE_INST_SET_CODE
-    /* XXX start -- kgn */
     int nop_mod = -1;
     if(nop_dict.Find(inst_name, nop_mod) == true) {
       inst_set.AddNop2(nop_mod, redundancy, ft_cost, cost, prob_fail);
       continue;
     }
-    /* XXX end */
-#else /* USE_INST_SET_CODE */
-    int nop_mod = -1;
-    /* XXX start -- kgn */
-    int nop_mod_2 = -1;
-    /* XXX end */
-    if (nop_dict.Find(inst_name, nop_mod) == true) {
-      inst_set.AddNop(inst_name, &cHardwareBase::Inst_Nop, nop_mod,
-		      redundancy, ft_cost, cost, prob_fail);
-      continue;
-    }
-#endif /* USE_INST_SET_CODE */
 
     // Otherwise, it had better be in the main dictionary...
-#ifdef USE_INST_SET_CODE
-    /* XXX start -- kgn */
     int fun_id = -1;
     if(inst_dict.Find(inst_name, fun_id) == true){
       inst_set.Add2(fun_id, redundancy, ft_cost, cost, prob_fail);
       continue;
     }
-    /* XXX end */
-#else /* USE_INST_SET_CODE */
-    tHardwareMethod cpu_method = NULL;
-    /* XXX start -- kgn */
-    int fun_id = -1;
-    /* XXX end */
-    if (inst_dict.Find(inst_name, cpu_method) == true) {
-      inst_set.Add(inst_name, cpu_method, redundancy, ft_cost, cost, prob_fail);
-      continue;
-    }
-#endif /* USE_INST_SET_CODE */
 
     // Oh oh!  Didn't find an instruction!
     cerr << endl
@@ -148,221 +114,9 @@
 {
   // Nops (or other modifying-instructions...)  Note: Nops must be the
   //  first instructions added to the set.
-#ifndef USE_INST_SET_CODE
-  tDictionary< int > nop_dict;
-  nop_dict.Add("nop-A", REG_AX);
-  nop_dict.Add("nop-B", REG_BX);
-  nop_dict.Add("nop-C", REG_CX);
-#endif /* !USE_INST_SET_CODE */
 
   // Build a dictionary of instructions and their corresponding methods...
-#ifndef USE_INST_SET_CODE
-  tDictionary< tHardwareMethod > inst_dict;
-
-  // Remaining instructions.
-  inst_dict.Add("nop-X",    (tHardwareMethod) &cHardwareCPU::Inst_Nop);
-  inst_dict.Add("if-equ-0", (tHardwareMethod) &cHardwareCPU::Inst_If0);
-  inst_dict.Add("if-not-0", (tHardwareMethod) &cHardwareCPU::Inst_IfNot0);
-  inst_dict.Add("if-n-equ", (tHardwareMethod) &cHardwareCPU::Inst_IfNEqu);
-  inst_dict.Add("if-equ",   (tHardwareMethod) &cHardwareCPU::Inst_IfEqu);
-  inst_dict.Add("if-grt-0", (tHardwareMethod) &cHardwareCPU::Inst_IfGr0);
-  inst_dict.Add("if-grt",   (tHardwareMethod) &cHardwareCPU::Inst_IfGr);
-  inst_dict.Add("if->=-0",  (tHardwareMethod) &cHardwareCPU::Inst_IfGrEqu0);
-  inst_dict.Add("if->=",    (tHardwareMethod) &cHardwareCPU::Inst_IfGrEqu);
-  inst_dict.Add("if-les-0", (tHardwareMethod) &cHardwareCPU::Inst_IfLess0);
-  inst_dict.Add("if-less",  (tHardwareMethod) &cHardwareCPU::Inst_IfLess);
-  inst_dict.Add("if-<=-0",  (tHardwareMethod) &cHardwareCPU::Inst_IfLsEqu0);
-  inst_dict.Add("if-<=",    (tHardwareMethod) &cHardwareCPU::Inst_IfLsEqu);
-  inst_dict.Add("if-A!=B",  (tHardwareMethod) &cHardwareCPU::Inst_IfANotEqB);
-  inst_dict.Add("if-B!=C",  (tHardwareMethod) &cHardwareCPU::Inst_IfBNotEqC);
-  inst_dict.Add("if-A!=C",  (tHardwareMethod) &cHardwareCPU::Inst_IfANotEqC);
-
-  inst_dict.Add("if-bit-1", (tHardwareMethod) &cHardwareCPU::Inst_IfBit1);
-  inst_dict.Add("jump-f",   (tHardwareMethod) &cHardwareCPU::Inst_JumpF);
-  inst_dict.Add("jump-b",   (tHardwareMethod) &cHardwareCPU::Inst_JumpB);
-  inst_dict.Add("jump-p",   (tHardwareMethod) &cHardwareCPU::Inst_JumpP);
-  inst_dict.Add("jump-slf", (tHardwareMethod) &cHardwareCPU::Inst_JumpSelf);
-  inst_dict.Add("call",     (tHardwareMethod) &cHardwareCPU::Inst_Call);
-  inst_dict.Add("return",   (tHardwareMethod) &cHardwareCPU::Inst_Return);
-
-  inst_dict.Add("pop",     (tHardwareMethod) &cHardwareCPU::Inst_Pop);
-  inst_dict.Add("push",    (tHardwareMethod) &cHardwareCPU::Inst_Push);
-  inst_dict.Add("swap-stk",(tHardwareMethod) &cHardwareCPU::Inst_SwitchStack);
-  inst_dict.Add("flip-stk",(tHardwareMethod) &cHardwareCPU::Inst_FlipStack);
-  inst_dict.Add("swap",    (tHardwareMethod) &cHardwareCPU::Inst_Swap);
-  inst_dict.Add("swap-AB", (tHardwareMethod) &cHardwareCPU::Inst_SwapAB);
-  inst_dict.Add("swap-BC", (tHardwareMethod) &cHardwareCPU::Inst_SwapBC);
-  inst_dict.Add("swap-AC", (tHardwareMethod) &cHardwareCPU::Inst_SwapAC);
-  inst_dict.Add("copy-reg",(tHardwareMethod) &cHardwareCPU::Inst_CopyReg);
-  inst_dict.Add("set_A=B", (tHardwareMethod) &cHardwareCPU::Inst_CopyRegAB);
-  inst_dict.Add("set_A=C", (tHardwareMethod) &cHardwareCPU::Inst_CopyRegAC);
-  inst_dict.Add("set_B=A", (tHardwareMethod) &cHardwareCPU::Inst_CopyRegBA);
-  inst_dict.Add("set_B=C", (tHardwareMethod) &cHardwareCPU::Inst_CopyRegBC);
-  inst_dict.Add("set_C=A", (tHardwareMethod) &cHardwareCPU::Inst_CopyRegCA);
-  inst_dict.Add("set_C=B", (tHardwareMethod) &cHardwareCPU::Inst_CopyRegCB);
-  inst_dict.Add("reset",   (tHardwareMethod) &cHardwareCPU::Inst_Reset);
-
-  inst_dict.Add("pop-A",  (tHardwareMethod) &cHardwareCPU::Inst_PopA);
-  inst_dict.Add("pop-B",  (tHardwareMethod) &cHardwareCPU::Inst_PopB);
-  inst_dict.Add("pop-C",  (tHardwareMethod) &cHardwareCPU::Inst_PopC);
-  inst_dict.Add("push-A", (tHardwareMethod) &cHardwareCPU::Inst_PushA);
-  inst_dict.Add("push-B", (tHardwareMethod) &cHardwareCPU::Inst_PushB);
-  inst_dict.Add("push-C", (tHardwareMethod) &cHardwareCPU::Inst_PushC);
-
-  inst_dict.Add("shift-r", (tHardwareMethod) &cHardwareCPU::Inst_ShiftR);
-  inst_dict.Add("shift-l", (tHardwareMethod) &cHardwareCPU::Inst_ShiftL);
-  inst_dict.Add("bit-1",   (tHardwareMethod) &cHardwareCPU::Inst_Bit1);
-  inst_dict.Add("set-num", (tHardwareMethod) &cHardwareCPU::Inst_SetNum);
-  inst_dict.Add("inc",     (tHardwareMethod) &cHardwareCPU::Inst_Inc);
-  inst_dict.Add("dec",     (tHardwareMethod) &cHardwareCPU::Inst_Dec);
-  inst_dict.Add("zero",    (tHardwareMethod) &cHardwareCPU::Inst_Zero);
-  inst_dict.Add("neg",     (tHardwareMethod) &cHardwareCPU::Inst_Neg);
-  inst_dict.Add("square",  (tHardwareMethod) &cHardwareCPU::Inst_Square);
-  inst_dict.Add("sqrt",    (tHardwareMethod) &cHardwareCPU::Inst_Sqrt);
-  inst_dict.Add("not",     (tHardwareMethod) &cHardwareCPU::Inst_Not);
-  inst_dict.Add("log",     (tHardwareMethod) &cHardwareCPU::Inst_Log);
-  inst_dict.Add("log10",     (tHardwareMethod) &cHardwareCPU::Inst_Log10);
-  inst_dict.Add("minus-17", (tHardwareMethod) &cHardwareCPU::Inst_Minus17);
-
-  inst_dict.Add("add",     (tHardwareMethod) &cHardwareCPU::Inst_Add);
-  inst_dict.Add("sub",     (tHardwareMethod) &cHardwareCPU::Inst_Sub);
-  inst_dict.Add("mult",    (tHardwareMethod) &cHardwareCPU::Inst_Mult);
-  inst_dict.Add("div",     (tHardwareMethod) &cHardwareCPU::Inst_Div);
-  inst_dict.Add("mod",     (tHardwareMethod) &cHardwareCPU::Inst_Mod);
-  inst_dict.Add("nand",    (tHardwareMethod) &cHardwareCPU::Inst_Nand);
-  inst_dict.Add("nor",     (tHardwareMethod) &cHardwareCPU::Inst_Nor);
-  inst_dict.Add("and",     (tHardwareMethod) &cHardwareCPU::Inst_And);
-  inst_dict.Add("order",   (tHardwareMethod) &cHardwareCPU::Inst_Order);
-  inst_dict.Add("xor",     (tHardwareMethod) &cHardwareCPU::Inst_Xor);
-
-  inst_dict.Add("copy",    (tHardwareMethod)&cHardwareCPU::Inst_Copy);
-  inst_dict.Add("read",    (tHardwareMethod)&cHardwareCPU::Inst_ReadInst);
-  inst_dict.Add("write",   (tHardwareMethod)&cHardwareCPU::Inst_WriteInst);
-  inst_dict.Add("stk-read",(tHardwareMethod)&cHardwareCPU::Inst_StackReadInst);
-  inst_dict.Add("stk-writ",(tHardwareMethod)&cHardwareCPU::Inst_StackWriteInst);
-
-  inst_dict.Add("compare",  (tHardwareMethod) &cHardwareCPU::Inst_Compare);
-  inst_dict.Add("if-n-cpy", (tHardwareMethod) &cHardwareCPU::Inst_IfNCpy);
-  inst_dict.Add("allocate", (tHardwareMethod) &cHardwareCPU::Inst_Allocate);
-  inst_dict.Add("divide",   (tHardwareMethod) &cHardwareCPU::Inst_Divide);
-  inst_dict.Add("c-alloc",  (tHardwareMethod) &cHardwareCPU::Inst_CAlloc);
-  inst_dict.Add("c-divide", (tHardwareMethod) &cHardwareCPU::Inst_CDivide);
-  inst_dict.Add("inject",   (tHardwareMethod) &cHardwareCPU::Inst_Inject);
-  inst_dict.Add("inject-r", (tHardwareMethod) &cHardwareCPU::Inst_InjectRand);
-  inst_dict.Add("inject-th", (tHardwareMethod) &cHardwareCPU::Inst_InjectThread);
-
-  inst_dict.Add("get",     (tHardwareMethod)&cHardwareCPU::Inst_TaskGet);
-  inst_dict.Add("stk-get", (tHardwareMethod)&cHardwareCPU::Inst_TaskStackGet);
-  inst_dict.Add("stk-load",(tHardwareMethod)&cHardwareCPU::Inst_TaskStackLoad);
-  inst_dict.Add("put",     (tHardwareMethod)&cHardwareCPU::Inst_TaskPut);
-  inst_dict.Add("IO",      (tHardwareMethod)&cHardwareCPU::Inst_TaskIO);
-  inst_dict.Add("search-f",(tHardwareMethod)&cHardwareCPU::Inst_SearchF);
-  inst_dict.Add("search-b",(tHardwareMethod)&cHardwareCPU::Inst_SearchB);
-  inst_dict.Add("mem-size",(tHardwareMethod)&cHardwareCPU::Inst_MemSize);
-
-  inst_dict.Add("rotate-l", (tHardwareMethod) &cHardwareCPU::Inst_RotateL);
-  inst_dict.Add("rotate-r", (tHardwareMethod) &cHardwareCPU::Inst_RotateR);
-
-  inst_dict.Add("set-cmut", (tHardwareMethod) &cHardwareCPU::Inst_SetCopyMut);
-  inst_dict.Add("mod-cmut", (tHardwareMethod) &cHardwareCPU::Inst_ModCopyMut);
-
-  // Threading instructions
-  inst_dict.Add("fork-th", (tHardwareMethod) &cHardwareCPU::Inst_ForkThread);
-  inst_dict.Add("kill-th", (tHardwareMethod) &cHardwareCPU::Inst_KillThread);
-  inst_dict.Add("id-th",   (tHardwareMethod) &cHardwareCPU::Inst_ThreadID);
-  
-  // Head-based instructions
-  inst_dict.Add("h-alloc",  (tHardwareMethod) &cHardwareCPU::Inst_MaxAlloc);
-  inst_dict.Add("h-divide", (tHardwareMethod) &cHardwareCPU::Inst_HeadDivide);
-  inst_dict.Add("h-read",   (tHardwareMethod) &cHardwareCPU::Inst_HeadRead);
-  inst_dict.Add("h-write",  (tHardwareMethod) &cHardwareCPU::Inst_HeadWrite);
-  inst_dict.Add("h-copy",   (tHardwareMethod) &cHardwareCPU::Inst_HeadCopy);
-  inst_dict.Add("h-search", (tHardwareMethod) &cHardwareCPU::Inst_HeadSearch);
-  inst_dict.Add("h-push",   (tHardwareMethod) &cHardwareCPU::Inst_HeadPush);  
-  inst_dict.Add("h-pop",    (tHardwareMethod) &cHardwareCPU::Inst_HeadPop);  
-  inst_dict.Add("set-head", (tHardwareMethod) &cHardwareCPU::Inst_SetHead);
-  inst_dict.Add("adv-head", (tHardwareMethod) &cHardwareCPU::Inst_AdvanceHead);
-  inst_dict.Add("mov-head", (tHardwareMethod) &cHardwareCPU::Inst_MoveHead);
-  inst_dict.Add("jmp-head", (tHardwareMethod) &cHardwareCPU::Inst_JumpHead);
-  inst_dict.Add("get-head", (tHardwareMethod) &cHardwareCPU::Inst_GetHead);
-  inst_dict.Add("if-label", (tHardwareMethod) &cHardwareCPU::Inst_IfLabel);
-  inst_dict.Add("set-flow", (tHardwareMethod) &cHardwareCPU::Inst_SetFlow);
-
-  inst_dict.Add("h-copy2",   (tHardwareMethod) &cHardwareCPU::Inst_HeadCopy2);
-  inst_dict.Add("h-copy3",   (tHardwareMethod) &cHardwareCPU::Inst_HeadCopy3);
-  inst_dict.Add("h-copy4",   (tHardwareMethod) &cHardwareCPU::Inst_HeadCopy4);
-  inst_dict.Add("h-copy5",   (tHardwareMethod) &cHardwareCPU::Inst_HeadCopy5);
-  inst_dict.Add("h-copy6",   (tHardwareMethod) &cHardwareCPU::Inst_HeadCopy6);
-  inst_dict.Add("h-copy7",   (tHardwareMethod) &cHardwareCPU::Inst_HeadCopy7);
-  inst_dict.Add("h-copy8",   (tHardwareMethod) &cHardwareCPU::Inst_HeadCopy8);
-  inst_dict.Add("h-copy9",   (tHardwareMethod) &cHardwareCPU::Inst_HeadCopy9);
-  inst_dict.Add("h-copy10",  (tHardwareMethod) &cHardwareCPU::Inst_HeadCopy10);
-
-
-  inst_dict.Add("divide-sex",     (tHardwareMethod) &cHardwareCPU::Inst_HeadDivideSex);
-  inst_dict.Add("divide-asex",    (tHardwareMethod) &cHardwareCPU::Inst_HeadDivide1);
-
-  inst_dict.Add("h-divide1",     (tHardwareMethod) &cHardwareCPU::Inst_HeadDivide1);
-  inst_dict.Add("h-divide2",     (tHardwareMethod) &cHardwareCPU::Inst_HeadDivide2);
-  inst_dict.Add("h-divide3",     (tHardwareMethod) &cHardwareCPU::Inst_HeadDivide3);
-  inst_dict.Add("h-divide4",     (tHardwareMethod) &cHardwareCPU::Inst_HeadDivide4);
-  inst_dict.Add("h-divide5",     (tHardwareMethod) &cHardwareCPU::Inst_HeadDivide5);
-  inst_dict.Add("h-divide6",     (tHardwareMethod) &cHardwareCPU::Inst_HeadDivide6);
-  inst_dict.Add("h-divide7",     (tHardwareMethod) &cHardwareCPU::Inst_HeadDivide7);
-  inst_dict.Add("h-divide8",     (tHardwareMethod) &cHardwareCPU::Inst_HeadDivide8);
-  inst_dict.Add("h-divide9",     (tHardwareMethod) &cHardwareCPU::Inst_HeadDivide9);
-  inst_dict.Add("h-divide10",    (tHardwareMethod) &cHardwareCPU::Inst_HeadDivide10);
-  inst_dict.Add("h-divide16",    (tHardwareMethod) &cHardwareCPU::Inst_HeadDivide16);
-  inst_dict.Add("h-divide32",    (tHardwareMethod) &cHardwareCPU::Inst_HeadDivide32);
-  inst_dict.Add("h-divide50",    (tHardwareMethod) &cHardwareCPU::Inst_HeadDivide50);
-  inst_dict.Add("h-divide100",   (tHardwareMethod) &cHardwareCPU::Inst_HeadDivide100);
-  inst_dict.Add("h-divide500",   (tHardwareMethod) &cHardwareCPU::Inst_HeadDivide500);
-  inst_dict.Add("h-divide1000",  (tHardwareMethod) &cHardwareCPU::Inst_HeadDivide1000);
-  inst_dict.Add("h-divide5000",  (tHardwareMethod) &cHardwareCPU::Inst_HeadDivide5000);
-  inst_dict.Add("h-divide10000",  (tHardwareMethod) &cHardwareCPU::Inst_HeadDivide10000);
-  inst_dict.Add("h-divide50000",  (tHardwareMethod) &cHardwareCPU::Inst_HeadDivide50000);
-  inst_dict.Add("h-divide0.5",   (tHardwareMethod) &cHardwareCPU::Inst_HeadDivide0_5);
-  inst_dict.Add("h-divide0.1",   (tHardwareMethod) &cHardwareCPU::Inst_HeadDivide0_1);
-  inst_dict.Add("h-divide0.05",  (tHardwareMethod) &cHardwareCPU::Inst_HeadDivide0_05);
-  inst_dict.Add("h-divide0.01",  (tHardwareMethod) &cHardwareCPU::Inst_HeadDivide0_01);
-  inst_dict.Add("h-divide0.001", (tHardwareMethod) &cHardwareCPU::Inst_HeadDivide0_001);
-
-  // High-level instructions
-  inst_dict.Add("repro",     (tHardwareMethod) &cHardwareCPU::Inst_Repro);
-  inst_dict.Add("repro-A",   (tHardwareMethod) &cHardwareCPU::Inst_Repro);
-  inst_dict.Add("repro-B",   (tHardwareMethod) &cHardwareCPU::Inst_Repro);
-  inst_dict.Add("repro-C",   (tHardwareMethod) &cHardwareCPU::Inst_Repro);
-  inst_dict.Add("repro-D",   (tHardwareMethod) &cHardwareCPU::Inst_Repro);
-  inst_dict.Add("repro-E",   (tHardwareMethod) &cHardwareCPU::Inst_Repro);
-  inst_dict.Add("repro-F",   (tHardwareMethod) &cHardwareCPU::Inst_Repro);
-  inst_dict.Add("repro-G",   (tHardwareMethod) &cHardwareCPU::Inst_Repro);
-  inst_dict.Add("repro-H",   (tHardwareMethod) &cHardwareCPU::Inst_Repro);
-  inst_dict.Add("repro-I",   (tHardwareMethod) &cHardwareCPU::Inst_Repro);
-  inst_dict.Add("repro-J",   (tHardwareMethod) &cHardwareCPU::Inst_Repro);
-  inst_dict.Add("repro-K",   (tHardwareMethod) &cHardwareCPU::Inst_Repro);
-  inst_dict.Add("repro-L",   (tHardwareMethod) &cHardwareCPU::Inst_Repro);
-  inst_dict.Add("repro-M",   (tHardwareMethod) &cHardwareCPU::Inst_Repro);
-  inst_dict.Add("repro-N",   (tHardwareMethod) &cHardwareCPU::Inst_Repro);
-  inst_dict.Add("repro-O",   (tHardwareMethod) &cHardwareCPU::Inst_Repro);
-  inst_dict.Add("repro-P",   (tHardwareMethod) &cHardwareCPU::Inst_Repro);
-  inst_dict.Add("repro-Q",   (tHardwareMethod) &cHardwareCPU::Inst_Repro);
-  inst_dict.Add("repro-R",   (tHardwareMethod) &cHardwareCPU::Inst_Repro);
-  inst_dict.Add("repro-S",   (tHardwareMethod) &cHardwareCPU::Inst_Repro);
-  inst_dict.Add("repro-T",   (tHardwareMethod) &cHardwareCPU::Inst_Repro);
-  inst_dict.Add("repro-U",   (tHardwareMethod) &cHardwareCPU::Inst_Repro);
-  inst_dict.Add("repro-V",   (tHardwareMethod) &cHardwareCPU::Inst_Repro);
-  inst_dict.Add("repro-W",   (tHardwareMethod) &cHardwareCPU::Inst_Repro);
-  inst_dict.Add("repro-X",   (tHardwareMethod) &cHardwareCPU::Inst_Repro);
-  inst_dict.Add("repro-Y",   (tHardwareMethod) &cHardwareCPU::Inst_Repro);
-  inst_dict.Add("repro-Z",   (tHardwareMethod) &cHardwareCPU::Inst_Repro);
-
-  // Placebo instructions
-  // nop-x (included with nops)
-  inst_dict.Add("skip", (tHardwareMethod) &cHardwareCPU::Inst_Skip);
-#endif /* !USE_INST_SET_CODE */
   
-#ifdef USE_INST_SET_CODE
-  /* XXX start -- kgn */
   tDictionary<int> nop_dict;
   for(int i=0; i<inst_set.GetInstLib()->GetNumNops(); i++)
     nop_dict.Add(inst_set.GetInstLib()->GetNopName(i), i);
@@ -370,8 +124,6 @@
   tDictionary<int> inst_dict;
   for(int i=0; i<inst_set.GetInstLib()->GetSize(); i++)
     inst_dict.Add(inst_set.GetInstLib()->GetName(i), i);
-  /* XXX end */
-#endif /* USE_INST_SET_CODE */
 
   // And load it on up!
   LoadInstSet(filename, inst_set, nop_dict, inst_dict);
@@ -381,299 +133,9 @@
 {
   // Nops (or other modifying-instructions...)  Note: Nops must be the
   //  first instructions added to the set.
-#ifndef USE_INST_SET_CODE
-  tDictionary< int > nop_dict;
-  nop_dict.Add("Nop-A", REG_AX);
-  nop_dict.Add("Nop-B", REG_BX);
-  nop_dict.Add("Nop-C", REG_CX);
-  nop_dict.Add("Nop-D", REG_DX);
-#endif /* !USE_INST_SET_CODE */
 
   // Build a dictionary of instructions and their corresponding methods...
-#ifndef USE_INST_SET_CODE
-  tDictionary< tHardwareMethod > inst_dict;
-  
-  // Remaining instructions.
-  //1
-  //inst_dict.Add("nop-A",     &cHardware4Stack::Inst_Nop), 
-  //2
-  //inst_dict.Add("nop-B",     &cHardware4Stack::Inst_Nop), 
-  //3
-  //inst_dict.Add("nop-C",     &cHardware4Stack::Inst_Nop),   
-  //4 - not implemented yet...
-  //inst_dict.Add("nop-D",     &cHardware4Stack::Inst_Nop), 
-  //5
-  inst_dict.Add("Nop-X", (tHardwareMethod) &cHardware4Stack::Inst_Nop);
-  //6 
-  inst_dict.Add("Val-Shift-R", (tHardwareMethod) &cHardware4Stack::Inst_ShiftR);
-  //7
-  inst_dict.Add("Val-Shift-L", (tHardwareMethod) &cHardware4Stack::Inst_ShiftL);
-  //8
-  inst_dict.Add("Val-Nand",  (tHardwareMethod) &cHardware4Stack::Inst_Nand);
-  //9
-  inst_dict.Add("Val-Add",  (tHardwareMethod) &cHardware4Stack::Inst_Add);
-  //10
-  inst_dict.Add("Val-Sub",  (tHardwareMethod)  &cHardware4Stack::Inst_Sub);
-  //11
-  inst_dict.Add("Val-Mult",  (tHardwareMethod) &cHardware4Stack::Inst_Mult);
-  //12
-  inst_dict.Add("Val-Div",   (tHardwareMethod) &cHardware4Stack::Inst_Div);
-  //13
-  inst_dict.Add("SetMemory", (tHardwareMethod) &cHardware4Stack::Inst_MaxAlloc);
-  //14
-  inst_dict.Add("Divide", (tHardwareMethod) &cHardware4Stack::Inst_HeadDivide);
-  //15
-  inst_dict.Add("Inst-Read", (tHardwareMethod) &cHardware4Stack::Inst_HeadRead);
-  //16
-  inst_dict.Add("Inst-Write", (tHardwareMethod) &cHardware4Stack::Inst_HeadWrite);
-  //keeping this one for the transition period
-  inst_dict.Add("Inst-Copy", (tHardwareMethod) &cHardware4Stack::Inst_HeadCopy);
-  //17
-  inst_dict.Add("If-Equal", (tHardwareMethod) &cHardware4Stack::Inst_IfEqu);
-  //18
-  inst_dict.Add("If-Not-Equal", (tHardwareMethod) &cHardware4Stack::Inst_IfNEqu);
-  //19
-  inst_dict.Add("If-Less", (tHardwareMethod) &cHardware4Stack::Inst_IfLess);
-  //20
-  inst_dict.Add("If-Greater", (tHardwareMethod) &cHardware4Stack::Inst_IfGr);
-  //21
-  inst_dict.Add("Head-Push",  (tHardwareMethod) &cHardware4Stack::Inst_HeadPush);
-  //22
-  inst_dict.Add("Head-Pop",  (tHardwareMethod) &cHardware4Stack::Inst_HeadPop);
-  //23
-  inst_dict.Add("Head-Move", (tHardwareMethod) &cHardware4Stack::Inst_MoveHead);
-  //24
-  inst_dict.Add("Search", (tHardwareMethod) &cHardware4Stack::Inst_HeadSearch);
-  //25
-  inst_dict.Add("Push-Next", (tHardwareMethod) &cHardware4Stack::Inst_PushA);
-  //26
-  inst_dict.Add("Push-Prev", (tHardwareMethod) &cHardware4Stack::Inst_PushB);
-  //27
-  inst_dict.Add("Push-Comp", (tHardwareMethod) &cHardware4Stack::Inst_PushC);
-  //28 - Not implemented yet...
-  //inst_dict.Add("Val-Delete", &cHardware4Stack::Inst_ValDelete
-  //29
-  inst_dict.Add("Val-Copy", (tHardwareMethod) &cHardware4Stack::Inst_CopyReg);
-  //30
-  inst_dict.Add("ThreadFork", (tHardwareMethod) &cHardware4Stack::Inst_ForkThread);
-  //31
-  inst_dict.Add("if-label", (tHardwareMethod) &cHardware4Stack::Inst_IfLabel);
-  //32
-  inst_dict.Add("Val-Inc", (tHardwareMethod) &cHardware4Stack::Inst_Inc);
-  //33
-  inst_dict.Add("Val-Dec", (tHardwareMethod) &cHardware4Stack::Inst_Dec);
-  //34
-  inst_dict.Add("Val-Mod",  (tHardwareMethod) &cHardware4Stack::Inst_Mod);
-  //35
-  inst_dict.Add("ThreadKill", (tHardwareMethod) &cHardware4Stack::Inst_KillThread);/*
-  // Remaining instructions.
-  inst_dict.Add("nop-X",    (tHardwareMethod) &cHardware4Stack::Inst_Nop);
-  inst_dict.Add("if-equ-0", (tHardwareMethod) &cHardware4Stack::Inst_If0);
-  inst_dict.Add("if-not-0", (tHardwareMethod) &cHardware4Stack::Inst_IfNot0);
-  inst_dict.Add("if-n-equ", (tHardwareMethod) &cHardware4Stack::Inst_IfNEqu);
-  inst_dict.Add("if-equ",   (tHardwareMethod) &cHardware4Stack::Inst_IfEqu);
-  inst_dict.Add("if-grt-0", (tHardwareMethod) &cHardware4Stack::Inst_IfGr0);
-  inst_dict.Add("if-grt",   (tHardwareMethod) &cHardware4Stack::Inst_IfGr);
-  inst_dict.Add("if->=-0",  (tHardwareMethod) &cHardware4Stack::Inst_IfGrEqu0);
-  inst_dict.Add("if->=",    (tHardwareMethod) &cHardware4Stack::Inst_IfGrEqu);
-  inst_dict.Add("if-les-0", (tHardwareMethod) &cHardware4Stack::Inst_IfLess0);
-  inst_dict.Add("if-less",  (tHardwareMethod) &cHardware4Stack::Inst_IfLess);
-  inst_dict.Add("if-<=-0",  (tHardwareMethod) &cHardware4Stack::Inst_IfLsEqu0);
-  inst_dict.Add("if-<=",    (tHardwareMethod) &cHardware4Stack::Inst_IfLsEqu);
-  inst_dict.Add("if-A!=B",  (tHardwareMethod) &cHardware4Stack::Inst_IfANotEqB);
-  inst_dict.Add("if-B!=C",  (tHardwareMethod) &cHardware4Stack::Inst_IfBNotEqC);
-  inst_dict.Add("if-A!=C",  (tHardwareMethod) &cHardware4Stack::Inst_IfANotEqC);
-
-  inst_dict.Add("if-bit-1", (tHardwareMethod) &cHardware4Stack::Inst_IfBit1);
-  inst_dict.Add("jump-f",   (tHardwareMethod) &cHardware4Stack::Inst_JumpF);
-  inst_dict.Add("jump-b",   (tHardwareMethod) &cHardware4Stack::Inst_JumpB);
-  inst_dict.Add("jump-p",   (tHardwareMethod) &cHardware4Stack::Inst_JumpP);
-  inst_dict.Add("jump-slf", (tHardwareMethod) &cHardware4Stack::Inst_JumpSelf);
-  inst_dict.Add("call",     (tHardwareMethod) &cHardware4Stack::Inst_Call);
-  inst_dict.Add("return",   (tHardwareMethod) &cHardware4Stack::Inst_Return);
-
-  inst_dict.Add("pop",     (tHardwareMethod) &cHardware4Stack::Inst_Pop);
-  inst_dict.Add("push",    (tHardwareMethod) &cHardware4Stack::Inst_Push);
-  inst_dict.Add("swap-stk",(tHardwareMethod) &cHardware4Stack::Inst_SwitchStack);
-  inst_dict.Add("flip-stk",(tHardwareMethod) &cHardware4Stack::Inst_FlipStack);
-  inst_dict.Add("swap",    (tHardwareMethod) &cHardware4Stack::Inst_Swap);
-  inst_dict.Add("swap-AB", (tHardwareMethod) &cHardware4Stack::Inst_SwapAB);
-  inst_dict.Add("swap-BC", (tHardwareMethod) &cHardware4Stack::Inst_SwapBC);
-  inst_dict.Add("swap-AC", (tHardwareMethod) &cHardware4Stack::Inst_SwapAC);
-  inst_dict.Add("copy-reg",(tHardwareMethod) &cHardware4Stack::Inst_CopyReg);
-  inst_dict.Add("set_A=B", (tHardwareMethod) &cHardware4Stack::Inst_CopyRegAB);
-  inst_dict.Add("set_A=C", (tHardwareMethod) &cHardware4Stack::Inst_CopyRegAC);
-  inst_dict.Add("set_B=A", (tHardwareMethod) &cHardware4Stack::Inst_CopyRegBA);
-  inst_dict.Add("set_B=C", (tHardwareMethod) &cHardware4Stack::Inst_CopyRegBC);
-  inst_dict.Add("set_C=A", (tHardwareMethod) &cHardware4Stack::Inst_CopyRegCA);
-  inst_dict.Add("set_C=B", (tHardwareMethod) &cHardware4Stack::Inst_CopyRegCB);
-  inst_dict.Add("reset",   (tHardwareMethod) &cHardware4Stack::Inst_Reset);
-
-  inst_dict.Add("pop-A",  (tHardwareMethod) &cHardware4Stack::Inst_PopA);
-  inst_dict.Add("pop-B",  (tHardwareMethod) &cHardware4Stack::Inst_PopB);
-  inst_dict.Add("pop-C",  (tHardwareMethod) &cHardware4Stack::Inst_PopC);
-  // inst_dict.Add("push-A", (tHardwareMethod) &cHardware4Stack::Inst_PushA);
-  inst_dict.Add("push-B", (tHardwareMethod) &cHardware4Stack::Inst_PushB);
-  inst_dict.Add("push-C", (tHardwareMethod) &cHardware4Stack::Inst_PushC);
-
-  inst_dict.Add("shift-r", (tHardwareMethod) &cHardware4Stack::Inst_ShiftR);
-  inst_dict.Add("shift-l", (tHardwareMethod) &cHardware4Stack::Inst_ShiftL);
-  inst_dict.Add("bit-1",   (tHardwareMethod) &cHardware4Stack::Inst_Bit1);
-  inst_dict.Add("set-num", (tHardwareMethod) &cHardware4Stack::Inst_SetNum);
-  inst_dict.Add("inc",     (tHardwareMethod) &cHardware4Stack::Inst_Inc);
-  inst_dict.Add("dec",     (tHardwareMethod) &cHardware4Stack::Inst_Dec);
-  inst_dict.Add("zero",    (tHardwareMethod) &cHardware4Stack::Inst_Zero);
-  inst_dict.Add("neg",     (tHardwareMethod) &cHardware4Stack::Inst_Neg);
-  inst_dict.Add("square",  (tHardwareMethod) &cHardware4Stack::Inst_Square);
-  inst_dict.Add("sqrt",    (tHardwareMethod) &cHardware4Stack::Inst_Sqrt);
-  inst_dict.Add("not",     (tHardwareMethod) &cHardware4Stack::Inst_Not);
-  inst_dict.Add("log",     (tHardwareMethod) &cHardware4Stack::Inst_Log);
-  inst_dict.Add("log10",   (tHardwareMethod) &cHardware4Stack::Inst_Log10);
-  inst_dict.Add("minus-18",(tHardwareMethod) &cHardware4Stack::Inst_Minus18);
-
-  inst_dict.Add("add",     (tHardwareMethod) &cHardware4Stack::Inst_Add);
-  inst_dict.Add("sub",     (tHardwareMethod) &cHardware4Stack::Inst_Sub);
-  inst_dict.Add("mult",    (tHardwareMethod) &cHardware4Stack::Inst_Mult);
-  inst_dict.Add("div",     (tHardwareMethod) &cHardware4Stack::Inst_Div);
-  inst_dict.Add("mod",     (tHardwareMethod) &cHardware4Stack::Inst_Mod);
-  inst_dict.Add("nand",    (tHardwareMethod) &cHardware4Stack::Inst_Nand);
-  inst_dict.Add("nor",     (tHardwareMethod) &cHardware4Stack::Inst_Nor);
-  inst_dict.Add("and",     (tHardwareMethod) &cHardware4Stack::Inst_And);
-  inst_dict.Add("order",   (tHardwareMethod) &cHardware4Stack::Inst_Order);
-  inst_dict.Add("xor",     (tHardwareMethod) &cHardware4Stack::Inst_Xor);
-
-  inst_dict.Add("copy",    (tHardwareMethod)&cHardware4Stack::Inst_Copy);
-  inst_dict.Add("read",    (tHardwareMethod)&cHardware4Stack::Inst_ReadInst);
-  inst_dict.Add("write",   (tHardwareMethod)&cHardware4Stack::Inst_WriteInst);
-  inst_dict.Add("stk-read",(tHardwareMethod)&cHardware4Stack::Inst_StackReadInst);
-  inst_dict.Add("stk-writ",(tHardwareMethod)&cHardware4Stack::Inst_StackWriteInst);
-
-  inst_dict.Add("compare",  (tHardwareMethod) &cHardware4Stack::Inst_Compare);
-  inst_dict.Add("if-n-cpy", (tHardwareMethod) &cHardware4Stack::Inst_IfNCpy);
-  inst_dict.Add("allocate", (tHardwareMethod) &cHardware4Stack::Inst_Allocate);
-  inst_dict.Add("divide",   (tHardwareMethod) &cHardware4Stack::Inst_Divide);
-  inst_dict.Add("c-alloc",  (tHardwareMethod) &cHardware4Stack::Inst_CAlloc);
-  inst_dict.Add("c-divide", (tHardwareMethod) &cHardware4Stack::Inst_CDivide);
-  inst_dict.Add("inject",   (tHardwareMethod) &cHardware4Stack::Inst_Inject);
-  inst_dict.Add("inject-r", (tHardwareMethod) &cHardware4Stack::Inst_InjectRand);
-  inst_dict.Add("inject-th", (tHardwareMethod) &cHardware4Stack::Inst_InjectThread);
-
-  inst_dict.Add("get",     (tHardwareMethod)&cHardware4Stack::Inst_TaskGet);
-  inst_dict.Add("stk-get", (tHardwareMethod)&cHardware4Stack::Inst_TaskStackGet);
-  inst_dict.Add("stk-load",(tHardwareMethod)&cHardware4Stack::Inst_TaskStackLoad);
-  inst_dict.Add("put",     (tHardwareMethod)&cHardware4Stack::Inst_TaskPut);
-  inst_dict.Add("IO",      (tHardwareMethod)&cHardware4Stack::Inst_TaskIO);
-  inst_dict.Add("search-f",(tHardwareMethod)&cHardware4Stack::Inst_SearchF);
-  inst_dict.Add("search-b",(tHardwareMethod)&cHardware4Stack::Inst_SearchB);
-  inst_dict.Add("mem-size",(tHardwareMethod)&cHardware4Stack::Inst_MemSize);
-
-  inst_dict.Add("rotate-l", (tHardwareMethod) &cHardware4Stack::Inst_RotateL);
-  inst_dict.Add("rotate-r", (tHardwareMethod) &cHardware4Stack::Inst_RotateR);
-
-  inst_dict.Add("set-cmut", (tHardwareMethod) &cHardware4Stack::Inst_SetCopyMut);
-  inst_dict.Add("mod-cmut", (tHardwareMethod) &cHardware4Stack::Inst_ModCopyMut);
-
-  // Threading instructions
-  inst_dict.Add("fork-th", (tHardwareMethod) &cHardware4Stack::Inst_ForkThread);
-  inst_dict.Add("kill-th", (tHardwareMethod) &cHardware4Stack::Inst_KillThread);
-  inst_dict.Add("id-th",   (tHardwareMethod) &cHardware4Stack::Inst_ThreadID);
-  
-  // Head-based instructions
-  inst_dict.Add("h-alloc",  (tHardwareMethod) &cHardware4Stack::Inst_MaxAlloc);
-  inst_dict.Add("h-divide", (tHardwareMethod) &cHardware4Stack::Inst_HeadDivide);
-  inst_dict.Add("h-read",   (tHardwareMethod) &cHardware4Stack::Inst_HeadRead);
-  inst_dict.Add("h-write",  (tHardwareMethod) &cHardware4Stack::Inst_HeadWrite);
-  inst_dict.Add("h-copy",   (tHardwareMethod) &cHardware4Stack::Inst_HeadCopy);
-  inst_dict.Add("h-search", (tHardwareMethod) &cHardware4Stack::Inst_HeadSearch);
-  inst_dict.Add("h-push",   (tHardwareMethod) &cHardware4Stack::Inst_HeadPush);  
-  inst_dict.Add("h-pop",    (tHardwareMethod) &cHardware4Stack::Inst_HeadPop);  
-  inst_dict.Add("set-head", (tHardwareMethod) &cHardware4Stack::Inst_SetHead);
-  inst_dict.Add("adv-head", (tHardwareMethod) &cHardware4Stack::Inst_AdvanceHead);
-  inst_dict.Add("mov-head", (tHardwareMethod) &cHardware4Stack::Inst_MoveHead);
-  inst_dict.Add("jmp-head", (tHardwareMethod) &cHardware4Stack::Inst_JumpHead);
-  inst_dict.Add("get-head", (tHardwareMethod) &cHardware4Stack::Inst_GetHead);
-  inst_dict.Add("if-label", (tHardwareMethod) &cHardware4Stack::Inst_IfLabel);
-  inst_dict.Add("set-flow", (tHardwareMethod) &cHardware4Stack::Inst_SetFlow);
-
-  inst_dict.Add("h-copy2",   (tHardwareMethod) &cHardware4Stack::Inst_HeadCopy2);
-  inst_dict.Add("h-copy3",   (tHardwareMethod) &cHardware4Stack::Inst_HeadCopy3);
-  inst_dict.Add("h-copy4",   (tHardwareMethod) &cHardware4Stack::Inst_HeadCopy4);
-  inst_dict.Add("h-copy5",   (tHardwareMethod) &cHardware4Stack::Inst_HeadCopy5);
-  inst_dict.Add("h-copy6",   (tHardwareMethod) &cHardware4Stack::Inst_HeadCopy6);
-  inst_dict.Add("h-copy7",   (tHardwareMethod) &cHardware4Stack::Inst_HeadCopy7);
-  inst_dict.Add("h-copy8",   (tHardwareMethod) &cHardware4Stack::Inst_HeadCopy8);
-  inst_dict.Add("h-copy9",   (tHardwareMethod) &cHardware4Stack::Inst_HeadCopy9);
-  inst_dict.Add("h-copy10",  (tHardwareMethod) &cHardware4Stack::Inst_HeadCopy10);
-
-
-  inst_dict.Add("divide-sex",     (tHardwareMethod) &cHardware4Stack::Inst_HeadDivideSex);
-  inst_dict.Add("divide-asex",    (tHardwareMethod) &cHardware4Stack::Inst_HeadDivide1);
-
-  inst_dict.Add("h-divide1",     (tHardwareMethod) &cHardware4Stack::Inst_HeadDivide1);
-  inst_dict.Add("h-divide2",     (tHardwareMethod) &cHardware4Stack::Inst_HeadDivide2);
-  inst_dict.Add("h-divide3",     (tHardwareMethod) &cHardware4Stack::Inst_HeadDivide3);
-  inst_dict.Add("h-divide4",     (tHardwareMethod) &cHardware4Stack::Inst_HeadDivide4);
-  inst_dict.Add("h-divide5",     (tHardwareMethod) &cHardware4Stack::Inst_HeadDivide5);
-  inst_dict.Add("h-divide6",     (tHardwareMethod) &cHardware4Stack::Inst_HeadDivide6);
-  inst_dict.Add("h-divide7",     (tHardwareMethod) &cHardware4Stack::Inst_HeadDivide7);
-  inst_dict.Add("h-divide8",     (tHardwareMethod) &cHardware4Stack::Inst_HeadDivide8);
-  inst_dict.Add("h-divide9",     (tHardwareMethod) &cHardware4Stack::Inst_HeadDivide9);
-  inst_dict.Add("h-divide10",    (tHardwareMethod) &cHardware4Stack::Inst_HeadDivide10);
-  inst_dict.Add("h-divide16",    (tHardwareMethod) &cHardware4Stack::Inst_HeadDivide16);
-  inst_dict.Add("h-divide32",    (tHardwareMethod) &cHardware4Stack::Inst_HeadDivide32);
-  inst_dict.Add("h-divide50",    (tHardwareMethod) &cHardware4Stack::Inst_HeadDivide50);
-  inst_dict.Add("h-divide100",   (tHardwareMethod) &cHardware4Stack::Inst_HeadDivide100);
-  inst_dict.Add("h-divide500",   (tHardwareMethod) &cHardware4Stack::Inst_HeadDivide500);
-  inst_dict.Add("h-divide1000",  (tHardwareMethod) &cHardware4Stack::Inst_HeadDivide1000);
-  inst_dict.Add("h-divide5000",  (tHardwareMethod) &cHardware4Stack::Inst_HeadDivide5000);
-  inst_dict.Add("h-divide10000",  (tHardwareMethod) &cHardware4Stack::Inst_HeadDivide10000);
-  inst_dict.Add("h-divide50000",  (tHardwareMethod) &cHardware4Stack::Inst_HeadDivide50000);
-  inst_dict.Add("h-divide0.5",   (tHardwareMethod) &cHardware4Stack::Inst_HeadDivide0_5);
-  inst_dict.Add("h-divide0.1",   (tHardwareMethod) &cHardware4Stack::Inst_HeadDivide0_1);
-  inst_dict.Add("h-divide0.05",  (tHardwareMethod) &cHardware4Stack::Inst_HeadDivide0_05);
-  inst_dict.Add("h-divide0.01",  (tHardwareMethod) &cHardware4Stack::Inst_HeadDivide0_01);
-  inst_dict.Add("h-divide0.001", (tHardwareMethod) &cHardware4Stack::Inst_HeadDivide0_001);
-
-  // High-level instructions
-  inst_dict.Add("repro",     (tHardwareMethod) &cHardware4Stack::Inst_Repro);
-  inst_dict.Add("repro-A",   (tHardwareMethod) &cHardware4Stack::Inst_Repro);
-  inst_dict.Add("repro-B",   (tHardwareMethod) &cHardware4Stack::Inst_Repro);
-  inst_dict.Add("repro-C",   (tHardwareMethod) &cHardware4Stack::Inst_Repro);
-  inst_dict.Add("repro-D",   (tHardwareMethod) &cHardware4Stack::Inst_Repro);
-  inst_dict.Add("repro-E",   (tHardwareMethod) &cHardware4Stack::Inst_Repro);
-  inst_dict.Add("repro-F",   (tHardwareMethod) &cHardware4Stack::Inst_Repro);
-  inst_dict.Add("repro-G",   (tHardwareMethod) &cHardware4Stack::Inst_Repro);
-  inst_dict.Add("repro-H",   (tHardwareMethod) &cHardware4Stack::Inst_Repro);
-  inst_dict.Add("repro-I",   (tHardwareMethod) &cHardware4Stack::Inst_Repro);
-  inst_dict.Add("repro-J",   (tHardwareMethod) &cHardware4Stack::Inst_Repro);
-  inst_dict.Add("repro-K",   (tHardwareMethod) &cHardware4Stack::Inst_Repro);
-  inst_dict.Add("repro-L",   (tHardwareMethod) &cHardware4Stack::Inst_Repro);
-  inst_dict.Add("repro-M",   (tHardwareMethod) &cHardware4Stack::Inst_Repro);
-  inst_dict.Add("repro-N",   (tHardwareMethod) &cHardware4Stack::Inst_Repro);
-  inst_dict.Add("repro-O",   (tHardwareMethod) &cHardware4Stack::Inst_Repro);
-  inst_dict.Add("repro-P",   (tHardwareMethod) &cHardware4Stack::Inst_Repro);
-  inst_dict.Add("repro-Q",   (tHardwareMethod) &cHardware4Stack::Inst_Repro);
-  inst_dict.Add("repro-R",   (tHardwareMethod) &cHardware4Stack::Inst_Repro);
-  inst_dict.Add("repro-S",   (tHardwareMethod) &cHardware4Stack::Inst_Repro);
-  inst_dict.Add("repro-T",   (tHardwareMethod) &cHardware4Stack::Inst_Repro);
-  inst_dict.Add("repro-U",   (tHardwareMethod) &cHardware4Stack::Inst_Repro);
-  inst_dict.Add("repro-V",   (tHardwareMethod) &cHardware4Stack::Inst_Repro);
-  inst_dict.Add("repro-W",   (tHardwareMethod) &cHardware4Stack::Inst_Repro);
-  inst_dict.Add("repro-X",   (tHardwareMethod) &cHardware4Stack::Inst_Repro);
-  inst_dict.Add("repro-Y",   (tHardwareMethod) &cHardware4Stack::Inst_Repro);
-  inst_dict.Add("repro-Z",   (tHardwareMethod) &cHardware4Stack::Inst_Repro);
-
-  // Placebo instructions
-  // nop-x (included with nops)
-  inst_dict.Add("skip", (tHardwareMethod) &cHardware4Stack::Inst_Skip);
-										*/
-  cout << "BLEE! Instruction Library in util has " << inst_dict.GetSize()
-       << " instructions + " << nop_dict.GetSize() << " nops." << endl;
-
-#endif /* !USE_INST_SET_CODE */
   
-#ifdef USE_INST_SET_CODE
-  /* XXX start -- kgn */
   tDictionary<int> nop_dict;
   for(int i=0; i<inst_set.GetInstLib()->GetNumNops(); i++)
     nop_dict.Add(inst_set.GetInstLib()->GetNopName(i), i);
@@ -681,8 +143,6 @@
   tDictionary<int> inst_dict;
   for(int i=0; i<inst_set.GetInstLib()->GetSize(); i++)
     inst_dict.Add(inst_set.GetInstLib()->GetName(i), i);
-  /* XXX end */
-#endif /* USE_INST_SET_CODE */
 
   cout << "Instruction Library in util has " << inst_dict.GetSize()
        << " instructions and " << nop_dict.GetSize() <<  " nops." << endl;
@@ -700,15 +160,11 @@
   // set it up.
   if (inst_filename != "" && inst_set.GetSize() == 0) {
     if (cConfig::GetHardwareType() == HARDWARE_TYPE_CPU_ORIGINAL) {
-#ifdef USE_INST_SET_CODE
       inst_set.SetInstLib(cHardwareCPU::GetInstLib());
-#endif /* USE_INST_SET_CODE */
       LoadInstSet_CPUOriginal(inst_filename, inst_set);
     }
     else if (cConfig::GetHardwareType() == HARDWARE_TYPE_CPU_4STACK) {
-#ifdef USE_INST_SET_CODE
       inst_set.SetInstLib(cHardware4Stack::GetInstLib());
-#endif /* USE_INST_SET_CODE */
       LoadInstSet_CPU4Stack(inst_filename, inst_set);
     }
   }
Index: avida/current/source/cpu/hardware_util.hh
diff -u avida/current/source/cpu/hardware_util.hh:1.2.2.4 avida/current/source/cpu/hardware_util.hh:1.2.2.5
--- avida/current/source/cpu/hardware_util.hh:1.2.2.4	Thu May 29 11:47:52 2003
+++ avida/current/source/cpu/hardware_util.hh	Mon Aug 25 23:30:21 2003
@@ -19,13 +19,8 @@
 
 class cHardwareUtil {
 public:
-#ifdef USE_INST_SET_CODE
   static void LoadInstSet( cString filename, cInstSet & inst_set, 
 	tDictionary<int> & nop_dict, tDictionary<int> & inst_dict );
-#else /* USE_INST_SET_CODE */
-  static void LoadInstSet( cString filename, cInstSet & inst_set, 
-	tDictionary<int> & nop_dict, tDictionary<tHardwareMethod> & inst_dict);
-#endif /* USE_INST_SET_CODE */
   static void LoadInstSet_CPUOriginal(const cString & filename,
 				      cInstSet & inst_set);
   static void LoadInstSet_CPU4Stack(const cString & filename,
Index: avida/current/source/cpu/head.cc
diff -u avida/current/source/cpu/head.cc:1.17.2.2 avida/current/source/cpu/head.cc:1.17.2.3
--- avida/current/source/cpu/head.cc:1.17.2.2	Tue May 20 05:12:19 2003
+++ avida/current/source/cpu/head.cc	Mon Aug 25 23:30:21 2003
@@ -256,8 +256,6 @@
   return cur_hardware->GetMemory().FlagCopyMut(position);    
 }
 
-
-
 cCPUHead & cCPUHead::operator=(const cCPUHead & in_cpu_head)
 {
   main_hardware = in_cpu_head.main_hardware;
@@ -452,6 +450,10 @@
   return pos;
 }
 
+bool cCPUHead::operator==(const cCPUHead & in_cpu_head) const {
+  return (cur_hardware == in_cpu_head.cur_hardware) &&
+    (position == in_cpu_head.position);
+}
 
 bool cCPUHead::AtEnd() const
 {
@@ -467,4 +469,202 @@
 {
   // If CPU has a head in another creature, mark it as a parasite.
   return (cur_hardware != main_hardware);
+}
+
+c4StackHead::c4StackHead() : cCPUHead() { mem_space=0; }
+
+c4StackHead::c4StackHead(cHardwareBase * in_hardware, int in_pos, int in_mem_space) 
+  : cCPUHead(in_hardware, in_pos) { mem_space = in_mem_space; }
+
+c4StackHead::c4StackHead(const c4StackHead & in_head) : cCPUHead(in_head) 
+{ 
+  mem_space = in_head.mem_space; 
+}
+
+void c4StackHead::Adjust()
+{
+  assert(cur_hardware != NULL);
+  assert(main_hardware != NULL);
+
+  const int mem_size = GetMemory().GetSize();
+
+  // If we are still in range, stop here!
+  if (position >= 0 && position < mem_size) return;
+
+  // If the memory is gone, just stick it at the begining of its parent.
+  if (mem_size == 0) {
+    cur_hardware = main_hardware;
+    position = 0;
+  }
+  else if (position <= 0) { position = 0; }
+  else if (position >= mem_size) {
+    // Always loop into the begining of the owner hardware.
+    cur_hardware = main_hardware;
+    position -= mem_size;
+    while (position >= GetMemory().GetSize()) {
+      // position back at the begining of the creature.
+      position %= GetMemory().GetSize();
+    }
+  }
+}
+
+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 = 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;
+  mem_space = in_mem_space;
+  Adjust();
+}
+
+void c4StackHead::Set(const c4StackHead & in_head)
+{
+  position = in_head.position;
+  cur_hardware = in_head.cur_hardware;
+  mem_space = in_head.mem_space;
+  Adjust();
+}
+
+void c4StackHead::LoopJump(int jump)
+{
+  position += jump;
+
+  // If we are out of range, bring back in.
+  if (position < 0 || position >= GetMemory().GetSize()) {
+    position %= GetMemory().GetSize();
+    if (position <= 0) position += GetMemory().GetSize();
+  }
+}
+
+const cCPUMemory & c4StackHead::GetMemory() const
+{
+  assert(cur_hardware != NULL);
+  return cur_hardware->GetMemory(mem_space);
+}
+
+cCPUMemory & c4StackHead::GetMemory()
+{
+  assert(cur_hardware != NULL);
+  return cur_hardware->GetMemory(mem_space);
+}
+
+const cInstruction & c4StackHead::GetInst() const
+{
+  assert(position >= 0);
+  assert(position < GetMemory().GetSize());
+  return GetMemory()[position];
+}
+
+const cInstruction & c4StackHead::GetInst(int offset) const 
+{
+  int new_pos = position + offset;
+  return GetMemory()[new_pos];
+}
+
+
+void c4StackHead::SetInst(const cInstruction & value)
+{
+  assert(cur_hardware != NULL);
+#ifdef WRITE_PROTECTION
+  if (main_hardware == cur_hardware) GetMemory()[position] = value;
+#else
+  GetMemory()[position] = value;
+  if (main_hardware != cur_hardware) cur_hardware->SetModified();
+#endif
+}
+
+void c4StackHead::InsertInst(const cInstruction & value)
+{
+  assert(cur_hardware != NULL);
+#ifdef WRITE_PROTECTION
+  if (main_hardware == cur_hardware) GetMemory().Insert(position, value);
+#else
+  GetMemory().Insert(position, value);
+  if (main_hardware != cur_hardware) cur_hardware->SetModified();
+#endif
+}
+
+void c4StackHead::RemoveInst()
+{
+  assert(cur_hardware != NULL);
+#ifdef WRITE_PROTECTION
+  if (main_hardware == cur_hardware) GetMemory().Remove(position);
+#else
+  GetMemory().Remove(position);
+  if (main_hardware != cur_hardware) cur_hardware->SetModified();
+#endif
+}
+
+const cInstruction & c4StackHead::GetNextInst()
+{
+  return (AtEnd()) ? cInstSet::GetInstError() : GetMemory()[position+1];
+}
+
+bool & c4StackHead::FlagCopied()
+{
+  assert(cur_hardware != NULL);
+  return GetMemory().FlagCopied(position);     
+}
+
+bool & c4StackHead::FlagMutated()
+{
+  assert(cur_hardware != NULL);
+  return GetMemory().FlagMutated(position);    
+}
+
+bool & c4StackHead::FlagExecuted()
+{
+  assert(cur_hardware != NULL);
+  return GetMemory().FlagExecuted(position);   
+}
+
+bool & c4StackHead::FlagBreakpoint()
+{
+  assert(cur_hardware != NULL);
+  return GetMemory().FlagBreakpoint(position); 
+}
+
+bool & c4StackHead::FlagPointMut()
+{
+  assert(cur_hardware != NULL);
+  return GetMemory().FlagPointMut(position);   
+}
+
+bool & c4StackHead::FlagCopyMut()
+{
+  assert(cur_hardware != NULL);
+  return GetMemory().FlagCopyMut(position);    
+}
+
+c4StackHead & c4StackHead::operator=(const c4StackHead & in_cpu_head)
+{
+  main_hardware = in_cpu_head.main_hardware;
+  cur_hardware  = in_cpu_head.cur_hardware;
+  position = in_cpu_head.position;
+  mem_space = in_cpu_head.mem_space;
+  return *this;
+}
+
+bool c4StackHead::operator==(const c4StackHead & in_cpu_head) const 
+{
+  return (cur_hardware == in_cpu_head.cur_hardware) && 
+    (position == in_cpu_head.position) &&
+    (mem_space == in_cpu_head.mem_space);
+}
+  
+bool c4StackHead::AtEnd() const
+{
+  return (position + 1 == GetMemory().GetSize());
+}
+
+bool c4StackHead::InMemory() const
+{
+  return (position >= 0 && position < GetMemory().GetSize());
 }
Index: avida/current/source/cpu/head.hh
diff -u avida/current/source/cpu/head.hh:1.10 avida/current/source/cpu/head.hh:1.10.2.1
--- avida/current/source/cpu/head.hh:1.10	Thu Mar 28 04:21:14 2002
+++ avida/current/source/cpu/head.hh	Mon Aug 25 23:30:21 2003
@@ -22,7 +22,7 @@
  **/
 
 class cCPUHead {
-private:
+protected:
   cHardwareBase * main_hardware;
   cHardwareBase * cur_hardware;
   int position;
@@ -35,22 +35,24 @@
   cCPUHead();
   cCPUHead(cHardwareBase * in_hardware, int in_pos = 0);
   cCPUHead(const cCPUHead & in_cpu_head);
-  ~cCPUHead() { ; }
-
-  void Reset(cHardwareBase * new_hardware = NULL);
+  virtual ~cCPUHead() { ; }
   
   /**
    * This function keeps the position within the range of the current memory.
    **/
-  void Adjust();
+  virtual void Adjust();
+
+  virtual void Reset(cHardwareBase * new_hardware = NULL);
   
   /**
    * Set the new position of the head (and adjust it into range in Set()).
    **/
 
-  void Set(int new_pos, cHardwareBase * in_hardware = NULL);
+  virtual void Set(int new_pos, cHardwareBase * in_hardware = NULL);
+  
   void AbsSet(int new_pos) { position = new_pos; }
-  void Set(const cCPUHead & in_head) {
+  
+  virtual void Set(const cCPUHead & in_head) {
     position = in_head.position;
     cur_hardware  = in_head.cur_hardware;
   }
@@ -60,7 +62,7 @@
    **/
 
   void Jump(int jump);
-  void LoopJump(int jump);
+  virtual void LoopJump(int jump);
   void AbsJump(int jump);
   
   // Other manipulation functions.
@@ -70,27 +72,27 @@
 
   // Accessors.
   int GetPosition() const { return position; }
-  const cCPUMemory & GetMemory() const;
+  virtual const cCPUMemory & GetMemory() const;
   cHardwareBase * GetCurHardware() const { return cur_hardware; }
   cHardwareBase * GetMainHardware() const { return main_hardware; }
-  const cInstruction & GetInst() const;
-  const cInstruction & GetInst(int offset) const;
+  virtual const cInstruction & GetInst() const;
+  virtual const cInstruction & GetInst(int offset) const;
   // int GetFlag(int id) const;
 
-  void SetInst(const cInstruction & value);
-  void InsertInst(const cInstruction & in_char);
-  void RemoveInst();
-  const cInstruction & GetNextInst();
-
-  bool & FlagCopied();
-  bool & FlagMutated();
-  bool & FlagExecuted();
-  bool & FlagBreakpoint();
-  bool & FlagPointMut();
-  bool & FlagCopyMut();
+  virtual void SetInst(const cInstruction & value);
+  virtual void InsertInst(const cInstruction & in_char);
+  virtual void RemoveInst();
+  virtual const cInstruction & GetNextInst();
+
+  virtual bool & FlagCopied();
+  virtual bool & FlagMutated();
+  virtual bool & FlagExecuted();
+  virtual bool & FlagBreakpoint();
+  virtual bool & FlagPointMut();
+  virtual bool & FlagCopyMut();
 
   // Operator Overloading...
-  cCPUHead & operator=(const cCPUHead & in_cpu_head);
+  virtual cCPUHead & operator=(const cCPUHead & in_cpu_head);
   cCPUHead & operator++();
   cCPUHead & operator--();
   cCPUHead & operator++(int);
@@ -100,19 +102,59 @@
     if (cur_hardware != in_cpu_head.cur_hardware) return 0;
     else return position - in_cpu_head.position;
   }
-  inline int operator==(const cCPUHead & in_cpu_head) const {
-    return (cur_hardware == in_cpu_head.cur_hardware) &&
-      (position == in_cpu_head.position);
-  }
+  virtual bool operator==(const cCPUHead & in_cpu_head) const;
 
   // Bool Tests...
   inline bool AtFront() const { return (position == 0); }
-  bool AtEnd() const;
-  bool InMemory() const;
+  virtual bool AtEnd() const;
+  virtual bool InMemory() const;
 
   // Test functions...
   int TestParasite() const;
 };
 
+class c4StackHead : public cCPUHead
+{
+private:
+  int mem_space;
+
+public:
+
+  c4StackHead();
+  c4StackHead(cHardwareBase * in_hardware, int in_pos = 0, int mem_space = 0);
+  c4StackHead(const c4StackHead & in_cpu_head);
+
+  void Adjust();
+  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;
+  cCPUMemory & GetMemory();
+  const cInstruction & GetInst() const;
+  const cInstruction & GetInst(int offset) const;
+
+  int GetMemSpace() const { return mem_space; }
+
+  void SetInst(const cInstruction & value);
+  void InsertInst(const cInstruction & in_char);
+  void RemoveInst();
+  const cInstruction & GetNextInst();
+
+  bool & FlagCopied();
+  bool & FlagMutated();
+  bool & FlagExecuted();
+  bool & FlagBreakpoint();
+  bool & FlagPointMut();
+  bool & FlagCopyMut();
+
+  // Operator Overloading...
+  c4StackHead & operator=(const c4StackHead & in_cpu_head);
+  bool operator==(const c4StackHead & in_cpu_head) const; 
+  bool AtEnd() const;
+  bool InMemory() const;
+};
 #endif
+
+
 
Index: avida/current/source/cpu/test_cpu.cc
diff -u avida/current/source/cpu/test_cpu.cc:1.37.2.2 avida/current/source/cpu/test_cpu.cc:1.37.2.3
--- avida/current/source/cpu/test_cpu.cc:1.37.2.2	Tue May 20 05:12:20 2003
+++ avida/current/source/cpu/test_cpu.cc	Mon Aug 25 23:30:21 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.29.2.2 avida/current/source/cpu/test_cpu.hh:1.29.2.3
--- avida/current/source/cpu/test_cpu.hh:1.29.2.2	Tue May 20 05:12:20 2003
+++ avida/current/source/cpu/test_cpu.hh	Mon Aug 25 23:30:21 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.5.2.2 avida/current/source/cpu/test_util.cc:1.5.2.3
--- avida/current/source/cpu/test_util.cc:1.5.2.2	Tue May 20 05:12:20 2003
+++ avida/current/source/cpu/test_util.cc	Mon Aug 25 23:30:21 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.2.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 25 23:30:21 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.36.2.4 avida/current/source/event/cPopulation.events:1.36.2.5
--- avida/current/source/event/cPopulation.events:1.36.2.4	Tue May 20 19:14:36 2003
+++ avida/current/source/event/cPopulation.events	Mon Aug 25 23:30:21 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/population_event_factory.cc
diff -u avida/current/source/event/population_event_factory.cc:1.5.2.1 avida/current/source/event/population_event_factory.cc:1.5.2.2
--- avida/current/source/event/population_event_factory.cc:1.5.2.1	Mon May 12 10:22:46 2003
+++ avida/current/source/event/population_event_factory.cc	Mon Aug 25 23:30:22 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.24.2.11 avida/current/source/main/Makefile.am:1.24.2.12
--- avida/current/source/main/Makefile.am:1.24.2.11	Thu May 22 14:29:00 2003
+++ avida/current/source/main/Makefile.am	Mon Aug 25 23:30:22 2003
@@ -16,7 +16,7 @@
 #
 # don't know why it was needed.
 #
-AVIDA_EVENT_DIR = ../event
+AVIDA_EVENT_DIR = $(srcdir)/../event
 AVIDA_CPU_DIR = $(srcdir)/../cpu
 INCLUDES = -I$(AVIDA_EVENT_DIR) -I$(AVIDA_CPU_DIR)
 #
@@ -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.63.2.6 avida/current/source/main/analyze.cc:1.63.2.7
--- avida/current/source/main/analyze.cc:1.63.2.6	Thu May 29 11:47:53 2003
+++ avida/current/source/main/analyze.cc	Mon Aug 25 23:30:22 2003
@@ -1806,8 +1806,6 @@
     }
 
     cInstSet map_inst_set(inst_set);
-#ifdef USE_INST_SET_CODE
-    /* XXX start -- kgn */
     // Locate instruction corresponding to "NULL" in the instruction library.
     {
       const cInstruction inst_lib_null_inst = map_inst_set.GetInstLib()->GetInst("NULL");
@@ -1824,12 +1822,6 @@
       map_inst_set.Add2(inst_lib_null_inst.GetOp());
     }
     const cInstruction null_inst = map_inst_set.GetInst("NULL");
-    /* XXX end */
-#else /* USE_INST_SET_CODE */
-    // Build an empty instruction into the instruction set.
-    map_inst_set.Add("NULL", &cHardwareBase::Inst_Nop);
-    const cInstruction null_inst = map_inst_set.GetInst("NULL");
-#endif /* USE_INST_SET_CODE */
 
     // Loop through all the lines of code, testing the removal of each.
     for (int line_num = 0; line_num < max_line; line_num++) {
@@ -2016,8 +2008,6 @@
 
     // Build an empty instruction into the an instruction library.
     cInstSet map_inst_set(inst_set);
-#ifdef USE_INST_SET_CODE
-    /* XXX start -- kgn */
     // Locate instruction corresponding to "NULL" in the instruction library.
     {
       const cInstruction inst_lib_null_inst = map_inst_set.GetInstLib()->GetInst("NULL");
@@ -2034,12 +2024,6 @@
       map_inst_set.Add2(inst_lib_null_inst.GetOp());
     }
     const cInstruction null_inst = map_inst_set.GetInst("NULL");
-    /* XXX end */
-#else /* USE_INST_SET_CODE */
-    // Build an empty instruction into the instruction set.
-    map_inst_set.Add("NULL", &cHardwareBase::Inst_Nop);
-    const cInstruction null_inst = map_inst_set.GetInst("NULL");
-#endif /* USE_INST_SET_CODE */
 
     cString color_string;  // For coloring cells...
 
@@ -2059,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>";
@@ -2153,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.34.2.5 avida/current/source/main/avida.cc:1.34.2.6
--- avida/current/source/main/avida.cc:1.34.2.5	Fri May 23 04:07:41 2003
+++ avida/current/source/main/avida.cc	Mon Aug 25 23:30:22 2003
@@ -82,16 +82,12 @@
 
   
   if (cConfig::GetHardwareType() == HARDWARE_TYPE_CPU_ORIGINAL) {
-#ifdef USE_INST_SET_CODE
     environment.GetInstSet().SetInstLib(cHardwareCPU::GetInstLib());
-#endif /* USE_INST_SET_CODE */
     cHardwareUtil::LoadInstSet_CPUOriginal(cConfig::GetInstFilename(),
 					   environment.GetInstSet());
   }
   else if (cConfig::GetHardwareType() == HARDWARE_TYPE_CPU_4STACK) {
-#ifdef USE_INST_SET_CODE
     environment.GetInstSet().SetInstLib(cHardware4Stack::GetInstLib());
-#endif /* USE_INST_SET_CODE */
     cHardwareUtil::LoadInstSet_CPU4Stack(cConfig::GetInstFilename(),
 					   environment.GetInstSet());
   }
@@ -107,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);
 
@@ -190,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.14.2.4 avida/current/source/main/callback_util.cc:1.14.2.5
--- avida/current/source/main/callback_util.cc:1.14.2.4	Thu May 22 01:15:02 2003
+++ avida/current/source/main/callback_util.cc	Mon Aug 25 23:30:22 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.8.2.1 avida/current/source/main/callback_util.hh:1.8.2.2
--- avida/current/source/main/callback_util.hh:1.8.2.1	Thu May 15 05:35:13 2003
+++ avida/current/source/main/callback_util.hh	Mon Aug 25 23:30:22 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.50.2.5 avida/current/source/main/config.cc:1.50.2.6
--- avida/current/source/main/config.cc:1.50.2.5	Thu May 29 11:47:54 2003
+++ avida/current/source/main/config.cc	Mon Aug 25 23:30:22 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;
@@ -70,6 +71,7 @@
 double cConfig::min_exe_lines;
 int cConfig::require_allocate;
 bool cConfig::test_on_divide;
+bool cConfig::test_sterilize;
 double cConfig::revert_fatal;
 double cConfig::revert_neg;
 double cConfig::revert_neut;
@@ -116,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",
@@ -153,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).");
 
@@ -238,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",
@@ -330,9 +334,17 @@
 
   // Determine if any variables were set that require test CPUs to be run
   // at every divide.
-  test_on_divide = (revert_fatal > 0.0) || (revert_neg > 0.0) ||
-    (revert_neut > 0.0) || (revert_pos > 0.0) || (sterilize_fatal > 0.0) ||
-    (sterilize_neg > 0.0) || (sterilize_neut > 0.0) || (sterilize_pos > 0.0);
+  test_on_divide = false;
+  if ((revert_fatal > 0.0) || (revert_neg > 0.0) || (revert_neut > 0.0) ||
+      (revert_pos > 0.0) || (fail_implicit > 0)) {
+    test_on_divide = true;
+  }
+
+  test_sterilize = false;
+  if ((sterilize_fatal > 0.0) || (sterilize_neg > 0.0) ||
+      (sterilize_neut > 0.0) || (sterilize_pos > 0.0)) {
+    test_sterilize = true;
+  }
 
   // Determine if we are only logging threshold genotypes...
   log_threshold_only = false;
Index: avida/current/source/main/config.hh
diff -u avida/current/source/main/config.hh:1.43.2.4 avida/current/source/main/config.hh:1.43.2.5
--- avida/current/source/main/config.hh:1.43.2.4	Thu May 29 11:47:54 2003
+++ avida/current/source/main/config.hh	Mon Aug 25 23:30:22 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;
@@ -221,6 +229,7 @@
 
   // For specialized experiments -- mutation reversion.
   static bool test_on_divide;
+  static bool test_sterilize;
   static double revert_fatal;
   static double revert_neg;
   static double revert_neut;
@@ -292,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; }
@@ -306,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; }
@@ -336,6 +346,7 @@
   static int GetRequireAllocate() { return require_allocate; }
 
   static bool GetTestOnDivide() { return test_on_divide; }
+  static bool GetTestSterilize() { return test_sterilize; }
   static double GetRevertFatal() { return revert_fatal; }
   static double GetRevertNeg() { return revert_neg; }
   static double GetRevertNeut() { return revert_neut; }
Index: avida/current/source/main/environment.cc
diff -u avida/current/source/main/environment.cc:1.8.2.3 avida/current/source/main/environment.cc:1.8.2.4
--- avida/current/source/main/environment.cc:1.8.2.3	Tue May 20 05:12:22 2003
+++ avida/current/source/main/environment.cc	Mon Aug 25 23:30:22 2003
@@ -8,6 +8,7 @@
 #include "../cpu/hardware_method.hh"
 #include "environment.hh"
 
+#include "../tools/random.hh"
 #include "../tools/string_util.hh"
 
 
@@ -82,6 +83,24 @@
   return true;
 }
 
+bool cEnvironment::AssertInputBool(const cString & input,
+				  const cString & name,
+				  const cString & type)
+{
+  if (input.IsNumber() == false) {
+    cerr << "Error: In " << type << "," << name << " set to non-number."
+	 << endl;
+    return false;
+  }
+  int value = input.AsInt();
+  if ((value != 1) && (value != 0))  {
+    cerr << "Error: In " << type << "," << name << " set to non-bool."
+	 << endl;
+    return false;
+  }
+  return true;
+}
+
 bool cEnvironment::AssertInputValid(void * input,
 				    const cString & name,
 				    const cString & type,
@@ -162,6 +181,28 @@
       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;
+      }
+      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 == "detectionerror") {
+      if (!AssertInputDouble(var_value, "detectionerror", var_type)) 
+	return false;
+      new_process->SetDetectionError(var_value.AsDouble());
+    }
     else {
       cerr << "Error: Unknown process variable '" << var_name
 	   << "' in reaction '" << reaction->GetName() << "'" << endl;
@@ -742,12 +783,28 @@
       break;
     };
 
+    // 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) continue;
+    if (product != NULL) {
+      int product_id = product->GetID();
+      double product_size = consumed * cur_process->GetConversion();
+      result.Produce(product_id, product_size);
+    }
 
-    int product_id = product->GetID();
-    double product_size = consumed * cur_process->GetConversion();
-    result.Produce(product_id, product_size);
+    result.Lethal(cur_process->GetLethal());
   }
 }
Index: avida/current/source/main/environment.hh
diff -u avida/current/source/main/environment.hh:1.7.2.1 avida/current/source/main/environment.hh:1.7.2.2
--- avida/current/source/main/environment.hh:1.7.2.1	Tue May 20 05:12:22 2003
+++ avida/current/source/main/environment.hh	Mon Aug 25 23:30:22 2003
@@ -35,6 +35,8 @@
 			     const cString & type);
   static bool AssertInputDouble(const cString & input, const cString & name,
 				const cString & type);
+  static bool AssertInputBool(const cString & input, const cString & name,
+				const cString & type);
   static bool AssertInputValid(void * input, const cString & name,
 			       const cString & type, const cString & value);
 
Index: avida/current/source/main/genebank.cc
diff -u avida/current/source/main/genebank.cc:1.28.2.3 avida/current/source/main/genebank.cc:1.28.2.4
--- avida/current/source/main/genebank.cc:1.28.2.3	Fri May 16 15:15:54 2003
+++ avida/current/source/main/genebank.cc	Mon Aug 25 23:30:22 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.2.1
--- avida/current/source/main/genome.hh:1.3	Thu Feb 28 22:37:51 2002
+++ avida/current/source/main/genome.hh	Mon Aug 25 23:30:22 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/inst_set.cc
diff -u avida/current/source/main/inst_set.cc:1.1.2.4 avida/current/source/main/inst_set.cc:1.1.2.5
--- avida/current/source/main/inst_set.cc:1.1.2.4	Thu May 29 11:47:54 2003
+++ avida/current/source/main/inst_set.cc	Mon Aug 25 23:30:22 2003
@@ -18,21 +18,13 @@
 //////////////////////
 
 // Initialize static variables
-/* XXX start -- kgn */
-#ifdef USE_INST_SET_CODE
 cInstruction cInstSet::inst_default2(   0 );
 cInstruction cInstSet::inst_error2  ( 255 );
-#else /* USE_INST_SET_CODE */
-/* XXX end */
-const cInstruction cInstSet::inst_default(   0 );
-const cInstruction cInstSet::inst_error  ( 255 );
-#endif /* USE_INST_SET_CODE */
 
 cInstSet::cInstSet()
 {
 }
 
-#ifdef USE_INST_SET_CODE
 cInstSet::cInstSet(const cInstSet & in_inst_set)
   : m_inst_lib(in_inst_set.m_inst_lib)
   , m_lib_name_map(in_inst_set.m_lib_name_map)
@@ -40,14 +32,6 @@
   , mutation_chart2(in_inst_set.mutation_chart2)
 {
 }
-#else /* USE_INST_SET_CODE */
-cInstSet::cInstSet(const cInstSet & in_inst_set)
-  : inst_array(in_inst_set.inst_array)
-  , nop_mods(in_inst_set.nop_mods)
-  , mutation_chart(in_inst_set.mutation_chart)
-{
-}
-#endif /* USE_INST_SET_CODE */
 
 cInstSet::~cInstSet()
 {
@@ -55,25 +39,15 @@
 
 cInstSet & cInstSet::operator=(const cInstSet & _in)
 {
-  /* XXX start -- kgn */
-#ifdef USE_INST_SET_CODE
   m_inst_lib = _in.m_inst_lib;
   m_lib_name_map = _in.m_lib_name_map;
   m_lib_nopmod_map = _in.m_lib_nopmod_map;
   mutation_chart2 = _in.mutation_chart2;
-#else /* USE_INST_SET_CODE */
-  /* XXX end */
-  inst_array = _in.inst_array;
-  nop_mods = _in.nop_mods;
-  mutation_chart = _in.mutation_chart;
-#endif /* USE_INST_SET_CODE */
   return *this;
 }
 
 bool cInstSet::OK() const
 {
-#ifdef USE_INST_SET_CODE
-  /* XXX start -- kgn */
   assert(m_lib_name_map.GetSize() < 256);
   assert(m_lib_nopmod_map.GetSize() < m_lib_name_map.GetSize());
 
@@ -88,42 +62,16 @@
   for (int i = 0; i < m_lib_name_map.GetSize(); i++) {
     assert(m_lib_name_map[i].redundancy == test_redundancy2[i]);
   }
-  /* XXX end */
-#else /* USE_INST_SET_CODE */
-
-  // assert(inst_array.OK());
-  // assert(nop_mods.OK());
-  assert(inst_array.GetSize() < 256);
-  assert(nop_mods.GetSize() < inst_array.GetSize());
-
-  // Make sure that all of the redundancies are represented the appropriate
-  // number of times.
-  tArray<int> test_redundancy(inst_array.GetSize());
-  test_redundancy.SetAll(0);
-  for (int i = 0; i < mutation_chart.GetSize(); i++) {
-    int test_id = mutation_chart[i];
-    test_redundancy[test_id]++;
-  }
-  for (int i = 0; i < inst_array.GetSize(); i++) {
-    assert(inst_array[i].redundancy == test_redundancy[i]);
-  }
-#endif /* USE_INST_SET_CODE */
 
   return true;
 }
 
 cInstruction cInstSet::GetRandomInst() const
 {
-#ifdef USE_INST_SET_CODE
   int inst_op = mutation_chart2[g_random.GetUInt(mutation_chart2.GetSize())];
-#else /* USE_INST_SET_CODE */
-  int inst_op = mutation_chart[g_random.GetUInt(mutation_chart.GetSize())];
-#endif /* USE_INST_SET_CODE */
   return cInstruction(inst_op);
 }
 
-/**/
-#ifdef USE_INST_SET_CODE
 int cInstSet::Add2(
   const int lib_fun_id,
   const int redundancy,
@@ -173,65 +121,14 @@
 
   return inst_id;
 }
-#else /* USE_INST_SET_CODE */
-/**/
-
-int cInstSet::Add(const cString & _name, tHardwareMethod _fun,
-		  const int redundancy, const int ft_cost, const int cost,
-		  const double prob_fail)
-{
-  const int inst_id = inst_array.GetSize();
-
-  assert(inst_id < 255);
-
-  // Increase the size of the array...
-  inst_array.Resize(inst_id + 1);
-
-  // Setup the new function...
-  inst_array[inst_id].name = _name;
-  inst_array[inst_id].function = _fun;
-  inst_array[inst_id].redundancy = redundancy;
-  inst_array[inst_id].cost = cost;
-  inst_array[inst_id].ft_cost = ft_cost;
-  inst_array[inst_id].prob_fail = prob_fail;
-
-  const int total_redundancy = mutation_chart.GetSize();
-  mutation_chart.Resize(total_redundancy + redundancy);
-  for (int i = 0; i < redundancy; i++) {
-    mutation_chart[total_redundancy + i] = inst_id;
-  }
-
-  return inst_id;
-}
-
-int cInstSet::AddNop(const cString & _name, tHardwareMethod _fun,
-		     const int reg, const int redundancy, const int ft_cost,
-		     const int cost, const double prob_fail)
-{ 
-  // Assert nops are at the _beginning_ of an inst_set.
-  assert(inst_array.GetSize() == nop_mods.GetSize());
-
-  const int inst_id = Add(_name, _fun, redundancy, ft_cost, cost, prob_fail);
-
-  nop_mods.Resize(inst_id + 1);
-  nop_mods[inst_id] = reg;
-
-  return inst_id;
-}
-#endif /* USE_INST_SET_CODE */
 
 cString cInstSet::FindBestMatch(const cString & in_name) const
 {
   int best_dist = 1024;
   cString best_name("");
   
-#ifdef USE_INST_SET_CODE
   for (int i = 0; i < m_lib_name_map.GetSize(); i++) {
     const cString & cur_name = m_inst_lib->GetName(m_lib_name_map[i].lib_fun_id);
-#else /* USE_INST_SET_CODE */
-  for (int i = 0; i < inst_array.GetSize(); i++) {
-    const cString & cur_name = inst_array[i].name;
-#endif /* USE_INST_SET_CODE */
     const int cur_dist = cStringUtil::EditDistance(cur_name, in_name);
     if (cur_dist < best_dist) {
       best_dist = cur_dist;
Index: avida/current/source/main/inst_set.hh
diff -u avida/current/source/main/inst_set.hh:1.1.2.3 avida/current/source/main/inst_set.hh:1.1.2.4
--- avida/current/source/main/inst_set.hh:1.1.2.3	Fri May 23 03:17:41 2003
+++ avida/current/source/main/inst_set.hh	Mon Aug 25 23:30:22 2003
@@ -35,7 +35,6 @@
  **/
 
 class cInstSet {
-#ifdef USE_INST_SET_CODE
 public:
   cInstLibBase *m_inst_lib;
   class cInstEntry2 {
@@ -53,23 +52,6 @@
   static cInstruction inst_error2;
   // static const cInstruction inst_none;
   static cInstruction inst_default2;
-#else /* USE_INST_SET_CODE */
-private:
-  // This class gives full info about a single instruction in the library.
-  class cInstEntry {
-  public:
-    cString name;             // Name of this instruction.
-    tHardwareMethod function; // Pointer to hardware method.
-    int redundancy;           // Weight in instruction set (not impl.)
-    int cost;                 // additional time spent to exectute inst.
-    int ft_cost;              // time spent first time exec (in add to cost)
-    double prob_fail;         // probability of failing to execute inst
-  };
-
-  tArray<cInstEntry> inst_array;  // The instructions indexed by ID
-  tArray<int> nop_mods;           // Modification table for nops
-  tArray<int> mutation_chart;     // ID's represented by redundancy values.
-#endif /* USE_INST_SET_CODE */
 
   // Static components...
   static const cInstruction inst_error;
@@ -88,13 +70,7 @@
   // Accessors
   const cString & GetName(int id) const
   { 
-#ifdef USE_INST_SET_CODE
-    ///* XXX start -- kgn */
     return m_inst_lib->GetName(m_lib_name_map[id].lib_fun_id);
-    ///* XXX end */
-#else /* USE_INST_SET_CODE */
-    return inst_array[id].name;
-#endif /* USE_INST_SET_CODE */
   }
   const cString & GetName(const cInstruction & inst) const
   {
@@ -102,116 +78,51 @@
   }
   int GetCost(const cInstruction & inst) const
   {
-#ifdef USE_INST_SET_CODE
-    ///* XXX start -- kgn */
     return m_lib_name_map[inst.GetOp()].cost;
-    ///* XXX end */
-#else /* USE_INST_SET_CODE */
-    return inst_array[inst.GetOp()].cost;
-#endif /* USE_INST_SET_CODE */
   }
   int GetFTCost(const cInstruction & inst) const
   {
-#ifdef USE_INST_SET_CODE
-    ///* XXX start -- kgn */
     return m_lib_name_map[inst.GetOp()].ft_cost;
-    ///* XXX end */
-#else /* USE_INST_SET_CODE */
-    return inst_array[inst.GetOp()].ft_cost;
-#endif /* USE_INST_SET_CODE */
   }
   double GetProbFail(const cInstruction & inst) const
   {
-#ifdef USE_INST_SET_CODE
-    ///* XXX start -- kgn */
     return m_lib_name_map[inst.GetOp()].prob_fail;
-    ///* XXX end */
-#else /* USE_INST_SET_CODE */
-    return inst_array[inst.GetOp()].prob_fail;
-#endif /* USE_INST_SET_CODE */
   }
   int GetRedundancy(const cInstruction & inst) const
   {
-#ifdef USE_INST_SET_CODE
-    ///* XXX start -- kgn */
     return m_lib_name_map[inst.GetOp()].redundancy;
-#else /* USE_INST_SET_CODE */
-    ///* XXX end */
-    return inst_array[inst.GetOp()].redundancy;
-#endif /* USE_INST_SET_CODE */
   }
 
-#ifdef USE_INST_SET_CODE
-  /* XXX start -- kgn */
   int GetLibFunctionIndex(const cInstruction & inst) const
   {
     return m_lib_name_map[inst.GetOp()].lib_fun_id;
   }
-  /* XXX end */
-#else /* USE_INST_SET_CODE */
-  tHardwareMethod GetFunction(const cInstruction & inst) const
-  {
-    return inst_array[inst.GetOp()].function;
-  }
-#endif /* USE_INST_SET_CODE */
 
   int GetNopMod(const cInstruction & inst) const
   {
-#ifdef USE_INST_SET_CODE
-    ///* XXX start -- kgn */
     return m_inst_lib->GetNopMod(m_lib_nopmod_map[inst.GetOp()]);
-    ///* XXX end */
-#else /* USE_INST_SET_CODE */
-    return nop_mods[inst.GetOp()];
-#endif /* USE_INST_SET_CODE */
   }
 
   cInstruction GetRandomInst() const;
-#ifdef USE_INST_SET_CODE
   int GetRandFunctionIndex() const
   {
     return m_lib_name_map[ GetRandomInst().GetOp() ].lib_fun_id;
   }
-#else /* USE_INST_SET_CODE */
-  tHardwareMethod GetRandFunction() const
-  {
-    return inst_array[ GetRandomInst().GetOp() ].function;
-  }
-#endif /* USE_INST_SET_CODE */
 
   int GetSize() const {
-#ifdef USE_INST_SET_CODE
-    ///* XXX start -- kgn */
     return m_lib_name_map.GetSize();
-    ///* XXX end */
-#else /* USE_INST_SET_CODE */
-    return inst_array.GetSize();
-#endif /* USE_INST_SET_CODE */
   }
   int GetNumNops() const {
-#ifdef USE_INST_SET_CODE
-    ///* XXX start -- kgn */
     return m_lib_nopmod_map.GetSize();
-#else /* USE_INST_SET_CODE */
-    ///* XXX end */
-    return nop_mods.GetSize();
-#endif /* USE_INST_SET_CODE */
   }
 
   // Instruction Analysis.
   int IsNop(const cInstruction & inst) const
   {
-#ifdef USE_INST_SET_CODE
-    ///* XXX start -- kgn */
     return (inst.GetOp() < m_lib_nopmod_map.GetSize());
-    ///* XXX end */
-#else /* USE_INST_SET_CODE */
-    return (inst.GetOp() < nop_mods.GetSize());
-#endif /* USE_INST_SET_CODE */
   }
 
   // Insertion of new instructions...
-#ifdef USE_INST_SET_CODE
   int Add2(
     const int lib_fun_id,
     const int redundancy=1,
@@ -226,16 +137,7 @@
     const int cost=0,
     const double prob_fail=0.0
   );
-#else /* USE_INST_SET_CODE */
-  int Add(const cString & _name, tHardwareMethod _fun, const int redundancy=1,
-	  const int ft_cost=0, const int cost=0, const double prob_fail=0.0);
-  int AddNop(const cString & _name, tHardwareMethod _fun, const int reg,
-	     const int redundancy=1, const int ft_cost=0, const int cost=0,
-	     const double prob_fail=0.0);
-#endif /* USE_INST_SET_CODE */
 
-#ifdef USE_INST_SET_CODE
-  /* XXX start -- kgn */
   // accessors for instruction library
   cInstLibBase *GetInstLib(){ return m_inst_lib; }
   void SetInstLib(cInstLibBase *inst_lib){
@@ -243,34 +145,16 @@
     inst_error2 = inst_lib->GetInstError();
     inst_default2 = inst_lib->GetInstDefault();
   }
-  /* XXX end */
-#endif /* USE_INST_SET_CODE */
 
   inline cInstruction GetInst(const cString & in_name) const;
   cString FindBestMatch(const cString & in_name) const;
 
   // Static methods..
   static const cInstruction & GetInstDefault() {
-#ifdef USE_INST_SET_CODE
-    /* XXX start --- kgn */
-    //if(inst_default != inst_default2)
-    //{ std::cout << "<cInstSet::GetInstDefault> mismatch!" << std::endl; }
     return inst_default2;
-    /* XXX end */
-#else /* USE_INST_SET_CODE */
-    return inst_default;
-#endif /* USE_INST_SET_CODE */
   }
   static const cInstruction & GetInstError()   {
-    /* XXX start --- kgn */
-    //if(inst_error != inst_error2)
-    //{ std::cout << "<cInstSet::GetInstError> mismatch!" << std::endl; }
-#ifdef USE_INST_SET_CODE
     return inst_error2;
-#else /* USE_INST_SET_CODE */
-    /* XXX end */
-    return inst_error;
-#endif /* USE_INST_SET_CODE */
   }
   // static const cInstruction & GetInstNone()    { return inst_none; }
 };
@@ -278,7 +162,6 @@
 
 inline cInstruction cInstSet::GetInst(const cString & in_name) const
 {
-#ifdef USE_INST_SET_CODE
   for (int i = 0; i < m_lib_name_map.GetSize(); i++) {
     if (m_inst_lib->GetName(m_lib_name_map[i].lib_fun_id) == in_name) {
       return cInstruction(i);
@@ -291,15 +174,6 @@
   -- kgn
   */
   return cInstruction(0);
-#else /* USE_INST_SET_CODE */
-  /* XXX start --- kgn */
-  for (int i = 0; i < inst_array.GetSize(); i++) {
-    if (inst_array[i].name == in_name) return cInstruction(i);
-  }
-  // assert(false); // Requesting ID for unknown inst.
-  return cInstSet::GetInstError();
-  /* XXX end */
-#endif /* USE_INST_SET_CODE */
 }
 
 
Index: avida/current/source/main/inst_util.cc
diff -u avida/current/source/main/inst_util.cc:1.7.2.2 avida/current/source/main/inst_util.cc:1.7.2.3
--- avida/current/source/main/inst_util.cc:1.7.2.2	Tue May 20 05:12:22 2003
+++ avida/current/source/main/inst_util.cc	Mon Aug 25 23:30:22 2003
@@ -21,7 +21,7 @@
 cGenome cInstUtil::LoadGenome(const cString & filename,
 			      const cInstSet & inst_set)
 {
-  cInitFile input_file(filename);
+    cInitFile input_file(filename);
   if (!input_file.IsOpen()) {
     cerr << "Cannot open file: " << filename << endl;
     return cGenome(1);
@@ -46,6 +46,9 @@
       exit(1);
     }
   }
+
+  if(new_genome.GetSize()==0)
+    cerr << "WARNING: Genome size is 0!" << endl;
 
   return new_genome;
 }
Index: avida/current/source/main/main_sub.pri
diff -u avida/current/source/main/main_sub.pri:1.1.2.4 avida/current/source/main/main_sub.pri:1.1.2.5
--- avida/current/source/main/main_sub.pri:1.1.2.4	Tue May 20 06:28:43 2003
+++ avida/current/source/main/main_sub.pri	Mon Aug 25 23:30:23 2003
@@ -12,6 +12,8 @@
              $$MAIN_HH/genome.hh \
              $$MAIN_HH/genome_util.hh \
              $$MAIN_HH/genotype.hh \
+             $$MAIN_HH/inject_genebank.hh \
+             $$MAIN_HH/inject_genotype.hh \
              $$MAIN_HH/inst.hh \
              $$MAIN_HH/inst_lib.hh \
              $$MAIN_HH/inst_set.hh \
@@ -45,6 +47,8 @@
              $$MAIN_CC/genome.cc \
              $$MAIN_CC/genome_util.cc \
              $$MAIN_CC/genotype.cc \
+             $$MAIN_CC/inject_genebank.cc \
+             $$MAIN_CC/inject_genotype.cc \
              $$MAIN_CC/inst.cc \
              $$MAIN_CC/inst_set.cc \
              $$MAIN_CC/inst_util.cc \
Index: avida/current/source/main/organism.cc
diff -u avida/current/source/main/organism.cc:1.18.2.3 avida/current/source/main/organism.cc:1.18.2.4
--- avida/current/source/main/organism.cc:1.18.2.3	Tue May 20 05:12:22 2003
+++ avida/current/source/main/organism.cc	Mon Aug 25 23:30:23 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);
@@ -94,10 +98,55 @@
 
   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
 }
 
+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.18.2.2 avida/current/source/main/organism.hh:1.18.2.3
--- avida/current/source/main/organism.hh:1.18.2.2	Thu May 15 05:35:13 2003
+++ avida/current/source/main/organism.hh	Mon Aug 25 23:30:23 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.27.2.3 avida/current/source/main/phenotype.cc:1.27.2.4
--- avida/current/source/main/phenotype.cc:1.27.2.3	Tue May 20 05:12:23 2003
+++ avida/current/source/main/phenotype.cc	Mon Aug 25 23:30:23 2003
@@ -25,6 +25,7 @@
   , last_task_count(environment.GetTaskLib().GetSize())
   , last_reaction_count(environment.GetReactionLib().GetSize())
   , last_inst_count(environment.GetInstSet().GetSize())
+  , sensed_resources(environment.GetResourceLib().GetSize())
 {
 }
 
@@ -52,7 +53,7 @@
   assert(time_used >= 0);
   assert(age >= 0);
   assert(child_copied_size >= 0);
-
+  assert(to_die == false);
   return true;
 }
 
@@ -91,6 +92,9 @@
   cur_task_count.SetAll(0);
   cur_reaction_count.SetAll(0);
   cur_inst_count.SetAll(0);
+  for (int j = 0; j < sensed_resources.GetSize(); j++)
+	      sensed_resources[j] =  parent_phenotype.sensed_resources[j];
+ 
 
   // Copy last values from parent
   last_merit_base     = parent_phenotype.last_merit_base;
@@ -120,6 +124,7 @@
   is_multi_thread = parent_phenotype.is_multi_thread;
   parent_true   = parent_phenotype.copy_true;
   parent_sex    = parent_phenotype.divide_sex;
+  to_die = false; 
 
   // Setup child info...
   copy_true          = false;
@@ -159,6 +164,7 @@
   cur_task_count.SetAll(0);
   cur_reaction_count.SetAll(0);
   cur_inst_count.SetAll(0);
+  sensed_resources.SetAll(0);
 
   // Copy last values from parent
   last_merit_base = _length;
@@ -186,6 +192,7 @@
   is_multi_thread = false;
   parent_true   = true;
   parent_sex    = false;
+  to_die = false;
 
   // Setup child info...
   copy_true         = false;
@@ -210,7 +217,7 @@
   // Update these values as needed...
   int cur_merit_base = CalcSizeMerit(genome_length,copied_size,executed_size);
   merit = cur_merit_base * cur_bonus;
-  assert(merit.GetDouble() != 0);
+  assert(merit.GetDouble() >= 0.0);
 
   genome_length   = _length;
   (void) copied_size;          // Unchanged
@@ -308,6 +315,7 @@
   cur_task_count.SetAll(0);
   cur_reaction_count.SetAll(0);
   cur_inst_count.SetAll(0);
+  sensed_resources.SetAll(-1.0);
 
   // Setup other miscellaneous values...
   num_divides++;
@@ -379,10 +387,21 @@
   cur_bonus *= result.GetMultBonus();
   cur_bonus += result.GetAddBonus();
 
+  // Bonus should never go negative...
+  if (cur_bonus < 0.0) cur_bonus = 0.0;
+
   // Denote consumed resources...
   for (int i = 0; i < res_in.GetSize(); i++) {
     res_change[i] = result.GetProduced(i) - result.GetConsumed(i);
   }
+
+  //Put in detected resources
+  for (int j = 0; j < res_in.GetSize(); j++)
+	  if(result.GetDetected(j) != -1.0)
+	      sensed_resources[j] = result.GetDetected(j);
+
+  //Kill any cells that did lethal reactions
+  //to_die = result.GetLethal();
 
   return true;
 }
Index: avida/current/source/main/phenotype.hh
diff -u avida/current/source/main/phenotype.hh:1.29.2.3 avida/current/source/main/phenotype.hh:1.29.2.4
--- avida/current/source/main/phenotype.hh:1.29.2.3	Tue May 20 05:12:23 2003
+++ avida/current/source/main/phenotype.hh	Mon Aug 25 23:30:23 2003
@@ -54,14 +54,16 @@
   int gestation_time;    // CPU cycles to produce offspring (or be produced)
   int gestation_start;   // Total instructions executed at last divide.
   double fitness;        // Relative efective replication rate...
-  double div_type;	 // Type of the divide command used
+  double div_type;	     // Type of the divide command used
 
   // 2. These are "in progress" variables, updated as the organism operates
   double cur_bonus;               // Current Bonus
+  bool to_die;					  // Has executed a fatal reaction
   int cur_num_errors;             // Total instructions executed illeagally.
   tArray<int> cur_task_count;     // Total times each task was performed
   tArray<int> cur_reaction_count; // Total times each reaction was triggered.
   tArray<int> cur_inst_count;	  // Intruction exection counter
+  tArray<double> sensed_resources; // Resources of which the organism is explictly aware
 
   // 3. These mark the status of "in progess" variables at the last divide.
   double last_merit_base;         // Either constant or based on genome length.
@@ -98,9 +100,6 @@
   bool last_child_fertile;  // Was the child being born to be fertile?
   int child_copied_size; // Instruction copied into child.
 
-private:
-  static int CalcSizeMerit(int full_size, int copied_size, int exe_size);
-
 public:
   cPhenotype(const cEnvironment & environment);
   ~cPhenotype();
@@ -129,6 +128,14 @@
   bool LoadState(std::ifstream & fp);
   void PrintStatus(std::ostream & fp);
 
+  // Some useful methods...
+  static int CalcSizeMerit(int full_size, int copied_size, int exe_size);
+  double CalcFitnessRatio() {
+    const int merit_base =
+      CalcSizeMerit(genome_length,copied_size,executed_size);
+    const double cur_fitness = merit_base * cur_bonus / time_used;
+    return cur_fitness / last_fitness;
+  }
 
   /////////////////////  Accessors -- Retrieving  ////////////////////
   const cEnvironment & GetEnvironment() const { return environment; };
@@ -152,6 +159,8 @@
 
   double GetCurBonus() const
     { assert(initialized == true); return cur_bonus; }
+  bool GetToDie() const
+    { assert(initialized == true); return to_die; }
   int GetCurNumErrors()const
     { assert(initialized == true); return cur_num_errors; }
   const tArray<int> & GetCurTaskCount() const
@@ -160,6 +169,9 @@
     { assert(initialized == true); return cur_reaction_count;}
   const tArray<int> & GetCurInstCount() const
     { assert(initialized == true); return cur_inst_count; }
+  
+  double GetSensedResource(int _in)
+  { assert(initialized == true); return sensed_resources[_in]; }
 
   double GetLastMeritBase() const
     { assert(initialized == true); return last_merit_base; }
Index: avida/current/source/main/pop_interface.cc
diff -u avida/current/source/main/pop_interface.cc:1.10.2.2 avida/current/source/main/pop_interface.cc:1.10.2.3
--- avida/current/source/main/pop_interface.cc:1.10.2.2	Thu May 15 05:35:13 2003
+++ avida/current/source/main/pop_interface.cc	Mon Aug 25 23:30:23 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.8.2.1 avida/current/source/main/pop_interface.hh:1.8.2.2
--- avida/current/source/main/pop_interface.hh:1.8.2.1	Thu May 15 05:35:13 2003
+++ avida/current/source/main/pop_interface.hh	Mon Aug 25 23:30:23 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.94.2.4 avida/current/source/main/population.cc:1.94.2.5
--- avida/current/source/main/population.cc:1.94.2.4	Tue May 20 19:14:36 2003
+++ avida/current/source/main/population.cc	Mon Aug 25 23:30:23 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.48.2.3 avida/current/source/main/population.hh:1.48.2.4
--- avida/current/source/main/population.hh:1.48.2.3	Tue May 20 05:12:23 2003
+++ avida/current/source/main/population.hh	Mon Aug 25 23:30:24 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.7.2.1 avida/current/source/main/population_cell.cc:1.7.2.2
--- avida/current/source/main/population_cell.cc:1.7.2.1	Mon May 12 10:22:47 2003
+++ avida/current/source/main/population_cell.cc	Mon Aug 25 23:30:24 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.6.2.1 avida/current/source/main/population_cell.hh:1.6.2.2
--- avida/current/source/main/population_cell.hh:1.6.2.1	Mon May 12 10:22:47 2003
+++ avida/current/source/main/population_cell.hh	Mon Aug 25 23:30:24 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.cc
diff -u avida/current/source/main/reaction.cc:1.4.2.1 avida/current/source/main/reaction.cc:1.4.2.2
--- avida/current/source/main/reaction.cc:1.4.2.1	Mon May 12 10:22:47 2003
+++ avida/current/source/main/reaction.cc	Mon Aug 25 23:30:24 2003
@@ -27,6 +27,10 @@
   , max_fraction(1.0)
   , product(NULL)
   , conversion(1.0)
+  , lethal(0)
+  , detect(NULL)
+  , detection_threshold(0.0)
+  , detection_error(0.0)
 {
 }
 
Index: avida/current/source/main/reaction.hh
diff -u avida/current/source/main/reaction.hh:1.3 avida/current/source/main/reaction.hh:1.3.2.1
--- avida/current/source/main/reaction.hh:1.3	Fri Oct 12 05:22:55 2001
+++ avida/current/source/main/reaction.hh	Mon Aug 25 23:30:24 2003
@@ -32,6 +32,10 @@
   double max_fraction;   // Max fraction of avaiable resources useable.
   cResource * product;   // Output resource.
   double conversion;     // Conversion factor.
+  bool lethal;			 // Lethality of reaction
+  cResource * detect; // Resource Measured
+  double detection_threshold;  //Minimum quantity of resource to register as present
+  double detection_error;  //Var of Detection Event (as % of resource present)
 public:
   cReactionProcess();
   ~cReactionProcess();
@@ -44,6 +48,10 @@
   double GetMaxFraction() const { return max_fraction; }
   cResource * GetProduct() const { return product; }
   double GetConversion() const { return conversion; }
+  bool GetLethal() const { return lethal; }
+  cResource * GetDetect() const { return detect; }
+  double GetDetectionThreshold() const { return detection_threshold; }
+  double GetDetectionError() const { return detection_error; }
 
   void SetResource(cResource * _in) { resource = _in; }
   void SetValue(double _in) { value = _in; }
@@ -53,6 +61,10 @@
   void SetMaxFraction(double _in) { max_fraction = _in; }
   void SetProduct(cResource * _in) { product = _in; }
   void SetConversion(double _in) { conversion = _in; }
+  void SetLethal(int _in) { lethal = _in; }
+  void SetDetect(cResource * _in) { detect = _in; }
+  void SetDetectionThreshold(double _in) { detection_threshold = _in; }
+  void SetDetectionError(double _in) { detection_error = _in; }
 };
 
 class cReactionRequisite {
Index: avida/current/source/main/reaction_result.cc
diff -u avida/current/source/main/reaction_result.cc:1.1.2.1 avida/current/source/main/reaction_result.cc:1.1.2.2
--- avida/current/source/main/reaction_result.cc:1.1.2.1	Mon May 12 10:22:47 2003
+++ avida/current/source/main/reaction_result.cc	Mon Aug 25 23:30:24 2003
@@ -13,10 +13,12 @@
 				 const int num_reactions)
   : resources_consumed(num_resources)
   , resources_produced(num_resources)
+  , resources_detected(num_resources)
   , tasks_done(num_tasks)
   , reactions_triggered(num_reactions)
   , bonus_add(0.0)
   , bonus_mult(1.0)
+  , lethal(false)
   , active_reaction(false)
 {
 }
@@ -43,8 +45,9 @@
   if (active_reaction == true) return;
 
   // To activate the reaction, we must initialize all counter settings.
-  resources_consumed.SetAll(0);
-  resources_produced.SetAll(0);
+  resources_consumed.SetAll(0.0);
+  resources_produced.SetAll(0.0);
+  resources_detected.SetAll(-1.0);
   tasks_done.SetAll(false);
   reactions_triggered.SetAll(false);
 
@@ -67,6 +70,18 @@
 }
 
 
+void cReactionResult::Detect(int id, double num)
+{
+  ActivateReaction();
+  resources_detected[id] += num;
+}
+
+void cReactionResult::Lethal(bool flag)
+{
+ ActivateReaction();
+ lethal = flag;
+}
+
 void cReactionResult::MarkTask(int id)
 {
   ActivateReaction();
@@ -106,6 +121,18 @@
 {
   if (GetActive() == false) return 0.0;
   return resources_produced[id];
+}
+
+double cReactionResult::GetDetected(int id)
+{
+  if (GetActive() == false) return 0.0;
+  return resources_detected[id];
+}
+
+bool cReactionResult::GetLethal()
+{
+  if (GetActive() == false) return false;
+  return lethal;
 }
 
 bool cReactionResult::ReactionTriggered(int id)
Index: avida/current/source/main/reaction_result.hh
diff -u avida/current/source/main/reaction_result.hh:1.1 avida/current/source/main/reaction_result.hh:1.1.2.1
--- avida/current/source/main/reaction_result.hh:1.1	Sat Oct 27 12:21:33 2001
+++ avida/current/source/main/reaction_result.hh	Mon Aug 25 23:30:24 2003
@@ -14,13 +14,13 @@
 private:
   tArray<double> resources_consumed;
   tArray<double> resources_produced;
+  tArray<double> resources_detected;  //Initialize to -1.0
   tArray<bool> tasks_done;
   tArray<bool> reactions_triggered;
   double bonus_add;
   double bonus_mult;
-
+  bool lethal;
   bool active_reaction;
-
   inline void ActivateReaction();
 public:
   cReactionResult(const int num_resources, const int num_tasks,
@@ -31,6 +31,8 @@
 
   void Consume(int id, double num);
   void Produce(int id, double num);
+  void Detect(int id, double num);
+  void Lethal(bool num);
   void MarkTask(int id);
   void MarkReaction(int id);
   void AddBonus(double value);
@@ -38,6 +40,8 @@
 
   double GetConsumed(int id);
   double GetProduced(int id);
+  double GetDetected(int id);
+  bool GetLethal();
   bool ReactionTriggered(int id);
   bool TaskDone(int id);
   double GetAddBonus();
Index: avida/current/source/main/tasks.cc
diff -u avida/current/source/main/tasks.cc:1.21.2.3 avida/current/source/main/tasks.cc:1.21.2.4
--- avida/current/source/main/tasks.cc:1.21.2.3	Tue May 20 00:43:50 2003
+++ avida/current/source/main/tasks.cc	Mon Aug 25 23:30:24 2003
@@ -294,20 +294,19 @@
     NewTask(name, "Math 3AB (sqrt(X)+sqrt(Y)+sqrt(Z))", &cTaskLib::Task_Math3in_AB);  
   else if (name == "math_3AC")
     NewTask(name, "Math 3AC (X+2Y+3Z)", &cTaskLib::Task_Math3in_AC);  
-  else if (name == "math_3AD")
-    NewTask(name, "Math 3AD (XY^2+Z^3)", &cTaskLib::Task_Math3in_AD);  
-  else if (name == "math_3AE")
-    NewTask(name, "Math 3AE ((X%Y)*Z)", &cTaskLib::Task_Math3in_AE);  
   /*
-  Visual Studio.net gives compiler error:
+  Visual Studio.net 2003 gives compiler error:
     fatal error C1061: compiler limit : blocks nested too deeply
-  Somebody in the lab, can't remember who, fixed this by removing
-  the 'else' in the next line.
+  Sherri fixed this by removing the 'else' in the next line.
   -- K
   */
-  //else if (name == "math_3AF")
-  //  NewTask(name, "Math 3AF ((X+Y)^2+sqrt(Y+Z))", &cTaskLib::Task_Math3in_AF);
-  if (name == "math_3AF")
+  //else if (name == "math_3AD")
+  //  NewTask(name, "Math 3AD (XY^2+Z^3)", &cTaskLib::Task_Math3in_AD); 
+  if (name == "math_3AD")
+    NewTask(name, "Math 3AD (XY^2+Z^3)", &cTaskLib::Task_Math3in_AD);  
+  else if (name == "math_3AE")
+    NewTask(name, "Math 3AE ((X%Y)*Z)", &cTaskLib::Task_Math3in_AE);  
+  else if (name == "math_3AF")
     NewTask(name, "Math 3AF ((X+Y)^2+sqrt(Y+Z))", &cTaskLib::Task_Math3in_AF);
   else if (name == "math_3AG")
     NewTask(name, "Math 3AG ((XY)%(YZ))", &cTaskLib::Task_Math3in_AG);  
@@ -325,6 +324,7 @@
     NewTask(name, "Math 3AM ((X+Y)^2+(Y+Z)^2)", &cTaskLib::Task_Math3in_AM);  
     
  // Make sure we have actuall found a task.
+
   if (task_array.GetSize() == start_size) {
     cerr << "Unknown task entry '" << name << "'." << endl;
     return NULL;
Index: avida/current/source/qt-viewer/avd_driver_controller.cc
diff -u avida/current/source/qt-viewer/avd_driver_controller.cc:1.1.2.3 avida/current/source/qt-viewer/avd_driver_controller.cc:1.1.2.4
--- avida/current/source/qt-viewer/avd_driver_controller.cc:1.1.2.3	Mon Aug 25 18:46:26 2003
+++ avida/current/source/qt-viewer/avd_driver_controller.cc	Mon Aug 25 23:30:24 2003
@@ -42,6 +42,8 @@
 avdMessageType Error_THRD_DRVR_avdMsg("ThreadHdlr", avdMCError);
 avdMessageType Fatal_THRD_DRVR_avdMsg("ThreadHdlr", avdMCFatal);
 
+using namespace std;
+
 
 void avdAvidaThreadCtrl::openAvidaSlot(){
   Debug << "got open sig.";
Index: avida/current/source/qt-viewer/map_view.cc
diff -u avida/current/source/qt-viewer/map_view.cc:1.9.2.2 avida/current/source/qt-viewer/map_view.cc:1.9.2.3
--- avida/current/source/qt-viewer/map_view.cc:1.9.2.2	Tue May 20 05:12:29 2003
+++ avida/current/source/qt-viewer/map_view.cc	Mon Aug 25 23:30:24 2003
@@ -11,6 +11,10 @@
 #include <qlayout.h>
 #include <qslider.h>
 #include <qcombobox.h>
+#include <qspinbox.h>
+
+
+using namespace std;
 
 
 using namespace std;
@@ -93,19 +97,21 @@
   m_mode_combo->setCurrentItem(3);
   setMapMode( 3 );
 
+  // add box for zoom value
   hlayout->addWidget( new QLabel( "Zoom: ", this ) );
-  m_zoom_slider = new QSlider( QSlider::Horizontal, this );
-  m_zoom_slider->setRange( 10, 500 );
-  //  m_zoom_slider->setTracking( false );
-  hlayout->addWidget( m_zoom_slider, 5 );
+  m_zoom_spinbox = new QSpinBox( this );
+  m_zoom_spinbox->setMinValue( 10 );
+  m_zoom_spinbox->setMaxValue( 500 );
+  m_zoom_spinbox->setLineStep( 10 );
+  hlayout->addWidget( m_zoom_spinbox);
 
   layout->addLayout( hlayout );
 
-  connect( m_zoom_slider, SIGNAL( valueChanged ( int ) ),
+  connect( m_zoom_spinbox, SIGNAL( valueChanged ( int ) ),
 	   this, SLOT( generateZoomValue( int ) ) );
   connect( this, SIGNAL( zoomValueChanged( double ) ),
 	   m_map_view_widget, SLOT( setZoomFactor( double ) ) );
-  m_zoom_slider->setValue( 50 );
+  m_zoom_spinbox->setValue( 50 );
   
   // activate the layout
   layout->activate();
@@ -125,7 +131,7 @@
 void
 MapView::repaintMap()
 {
-  m_map_view_widget->drawViewport();
+  m_map_view_widget->drawViewport(false);
 }
 
 void
Index: avida/current/source/qt-viewer/map_view.hh
diff -u avida/current/source/qt-viewer/map_view.hh:1.7.2.1 avida/current/source/qt-viewer/map_view.hh:1.7.2.2
--- avida/current/source/qt-viewer/map_view.hh:1.7.2.1	Mon May 12 10:22:48 2003
+++ avida/current/source/qt-viewer/map_view.hh	Mon Aug 25 23:30:24 2003
@@ -16,6 +16,7 @@
 
 class QSlider;
 class QComboBox;
+class QSpinBox;
 
 //class cPopulation;
 class avd_MissionControl;
@@ -28,7 +29,7 @@
   avd_MissionControl *m_mission_control;  // pointer to avida population
   MapViewWidget *m_map_view_widget; // the main widget
   ColorScaleWidget *m_color_scale_widget; // the color scale widget
-  QSlider *m_zoom_slider;
+  QSpinBox *m_zoom_spinbox;
   QSlider *m_center_x_slider;
   QSlider *m_center_y_slider;
   QComboBox *m_mode_combo;
Index: avida/current/source/qt-viewer/map_view_widget.cc
diff -u avida/current/source/qt-viewer/map_view_widget.cc:1.11.2.2 avida/current/source/qt-viewer/map_view_widget.cc:1.11.2.3
--- avida/current/source/qt-viewer/map_view_widget.cc:1.11.2.2	Tue May 20 05:12:29 2003
+++ avida/current/source/qt-viewer/map_view_widget.cc	Mon Aug 25 23:30:24 2003
@@ -79,7 +79,7 @@
 {
 // uncomment the following line if you want to play around
 // with the automatic centering after zoom.
-//#define __AUTO_CENTER_ON_ZOOM__
+#define __AUTO_CENTER_ON_ZOOM__
 
   if ( value > 0 ){
 #ifdef __AUTO_CENTER_ON_ZOOM__
@@ -87,6 +87,7 @@
 #endif
 
     m_zoom = value;
+    
 
     blockSignals( true ); // block all signals (we want to draw only once).
 
@@ -111,15 +112,34 @@
 
     // get the current center:
 #ifdef __AUTO_CENTER_ON_ZOOM__
-    int cx = contentsX() + visibleWidth()/2;
-    int cy = contentsY() + visibleHeight()/2;
+    
+    int width;
+    int height;
+
+    // use appropriate width to calculate new center, mapsize if it's 
+    // smaller than visible area, otherwise visible area
+    if( visibleWidth() < m_world_x*old_zoom*m_cell_width )
+      width = visibleWidth();
+    else
+      width = m_world_x*old_zoom*m_cell_width;
+    if( visibleHeight() < m_world_y*old_zoom*m_cell_height )
+      height = visibleHeight();
+    else
+      height = m_world_y*old_zoom*m_cell_height;
+    
     // recalculate the new center:
-    cx = (int) (cx*m_zoom/old_zoom);
-    cy = (int) (cy*m_zoom/old_zoom);
+    double dcx = contentsX() + width/2.;
+    double dcy = contentsY() + height/2.;
+    int cx = (int) (dcx*m_zoom/old_zoom);
+    int cy = (int) (dcy*m_zoom/old_zoom);
     center( cx, cy ); // make sure the center stays the same after zoom
 #endif
 
-    drawViewport();
+    //if zooming out so map is getting smaller, first erase then draw
+    bool redraw = false;            
+    if (old_zoom > m_zoom) redraw = true;
+
+    drawViewport(redraw);
     blockSignals( false ); // now we can allow signals again.
   }
 
@@ -135,7 +155,7 @@
     // reverse offset for better user experience
     m_x_offset = m_world_x - 1 - value;
     allChanged(); // mark all cells as changed
-    drawViewport();
+    drawViewport(false);
   }
 }
 
@@ -146,7 +166,7 @@
     // reverse offset for better user experience
     m_y_offset = m_world_y - 1 - value;
     allChanged(); // mark all cells as changed
-    drawViewport();
+    drawViewport(false);
   }
 }
 
@@ -154,7 +174,7 @@
 MapViewWidget::setMapMode( MapViewCellColorUtil::MapMode mode )
 {
   m_color_util->setMapMode( mode );
-  drawViewport();
+  drawViewport(false);
 }
 
 void
@@ -240,9 +260,9 @@
 
 
 void
-MapViewWidget::drawViewport()
+MapViewWidget::drawViewport(bool redraw)
 {
-  viewport()->repaint( false );
+  viewport()->repaint( redraw );
 }
 
 void
@@ -350,7 +370,7 @@
 
   emit cellSelected( m_x_selected
 		     + m_world_x * m_y_selected );
-  drawViewport();
+  drawViewport(false);
 }
 
 //#include "map_view_widget.moc"
Index: avida/current/source/qt-viewer/map_view_widget.hh
diff -u avida/current/source/qt-viewer/map_view_widget.hh:1.8.2.1 avida/current/source/qt-viewer/map_view_widget.hh:1.8.2.2
--- avida/current/source/qt-viewer/map_view_widget.hh:1.8.2.1	Mon May 12 10:22:48 2003
+++ avida/current/source/qt-viewer/map_view_widget.hh	Mon Aug 25 23:30:24 2003
@@ -152,7 +152,7 @@
   /**
    * Redraws everything.
    **/
-  void drawViewport();
+  void drawViewport(bool redraw);
 
 
   /**
Index: avida/current/source/qt-viewer/plot_widget.cc
diff -u avida/current/source/qt-viewer/plot_widget.cc:1.14.2.1 avida/current/source/qt-viewer/plot_widget.cc:1.14.2.2
--- avida/current/source/qt-viewer/plot_widget.cc:1.14.2.1	Mon May 12 10:22:48 2003
+++ avida/current/source/qt-viewer/plot_widget.cc	Mon Aug 25 23:30:24 2003
@@ -3,7 +3,7 @@
 #include "double_slider.hh"
 
 #include <float.h>           // for DBL_MIN, DBL_MAX (PointArray)
-#include <math.h>
+#include <cmath>
 #include <stdio.h>
 #include <iostream>
 
@@ -541,7 +541,7 @@
   double coeff = frexp( value, &exp_2 );
   double exp_10 = exp_2/3.3219280949;
   *exponent = (int) floor( exp_10 );
-  coeff *= pow( 10, exp_10 - *exponent );
+  coeff *= pow( double(10), exp_10 - (double)*exponent );
 
   if ( coeff < 1 ){
     coeff *= 10;
Index: avida/current/source/qt-viewer/qt-viewer.pro
diff -u avida/current/source/qt-viewer/qt-viewer.pro:1.1.2.6 avida/current/source/qt-viewer/qt-viewer.pro:1.1.2.7
--- avida/current/source/qt-viewer/qt-viewer.pro:1.1.2.6	Mon Aug 25 18:46:26 2003
+++ avida/current/source/qt-viewer/qt-viewer.pro	Mon Aug 25 23:30:24 2003
@@ -3,11 +3,19 @@
 
 TEMPLATE    = app
 TARGET      = qt-viewer
+DESTDIR = ../../work
 CONFIG      *= qt thread
 CONFIG      *= cpu event main trio tools
 
-# setting MOC_DIR should not be necessary:
-MOC_DIR = .
+# These must be conditional on platform type.  If they are active under
+# macx then the installation breaks.
+win32 {
+CONFIG  += console
+QMAKE_LFLAGS_CONSOLE += /FORCE:MULTIPLE
+}
+
+OBJECTS_DIR = objs
+MOC_DIR   = moc
 
 include($$AVIDA_SRC_DIR/modules.pri)
 
Index: avida/current/source/qt-viewer/setup_avida.cc
diff -u avida/current/source/qt-viewer/setup_avida.cc:1.15.2.5 avida/current/source/qt-viewer/setup_avida.cc:1.15.2.6
--- avida/current/source/qt-viewer/setup_avida.cc:1.15.2.5	Mon Aug 25 18:46:26 2003
+++ avida/current/source/qt-viewer/setup_avida.cc	Mon Aug 25 23:30:24 2003
@@ -80,16 +80,12 @@
   }
 
   if (cConfig::GetHardwareType() == HARDWARE_TYPE_CPU_ORIGINAL) {
-#ifdef USE_INST_SET_CODE
     environment.GetInstSet().SetInstLib(cHardwareCPU::GetInstLib());
-#endif /* USE_INST_SET_CODE */
     cHardwareUtil::LoadInstSet_CPUOriginal(cConfig::GetInstFilename(),
 					   environment.GetInstSet());
   }
   else if (cConfig::GetHardwareType() == HARDWARE_TYPE_CPU_4STACK) {
-#ifdef USE_INST_SET_CODE
     environment.GetInstSet().SetInstLib(cHardware4Stack::GetInstLib());
-#endif /* USE_INST_SET_CODE */
     cHardwareUtil::LoadInstSet_CPU4Stack(cConfig::GetInstFilename(),
 					   environment.GetInstSet());
   }
@@ -105,7 +101,6 @@
   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);
 
Index: avida/current/source/support/Makefile.am
diff -u avida/current/source/support/Makefile.am:1.9.2.6 avida/current/source/support/Makefile.am:1.9.2.7
--- avida/current/source/support/Makefile.am:1.9.2.6	Thu May 22 14:29:01 2003
+++ avida/current/source/support/Makefile.am	Mon Aug 25 23:30:24 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.34.2.3 avida/current/source/support/genesis:1.34.2.4
--- avida/current/source/support/genesis:1.34.2.3	Tue May 20 05:12:36 2003
+++ avida/current/source/support/genesis	Mon Aug 25 23:30:24 2003
@@ -3,7 +3,7 @@
 # For more information, see doc/genesis.html
 #############################################################################
 
-VERSION_ID 2.0b1		# Do not change this value!
+VERSION_ID 2.0b4		# Do not change this value!
 
 ### Architecture Variables ###
 MAX_UPDATES  -1         # Maximum updates to run simulation (-1 = no limit)
@@ -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.1.2.3 avida/current/source/support/preset_organisms/Makefile.am:1.1.2.4
--- avida/current/source/support/preset_organisms/Makefile.am:1.1.2.3	Thu May 22 14:29:01 2003
+++ avida/current/source/support/preset_organisms/Makefile.am	Mon Aug 25 23:30:25 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/third-party/Makefile.am
diff -u avida/current/source/third-party/Makefile.am:1.1.2.4 avida/current/source/third-party/Makefile.am:1.1.2.5
--- avida/current/source/third-party/Makefile.am:1.1.2.4	Mon Aug 25 18:46:26 2003
+++ avida/current/source/third-party/Makefile.am	Mon Aug 25 23:30:25 2003
@@ -1,3 +1,2 @@
 
-
 SUBDIRS = Loki trio-1.9
Index: avida/current/source/tools/datafile.cc
diff -u avida/current/source/tools/datafile.cc:1.8.2.2 avida/current/source/tools/datafile.cc:1.8.2.3
--- avida/current/source/tools/datafile.cc:1.8.2.2	Thu May 15 05:35:18 2003
+++ avida/current/source/tools/datafile.cc	Mon Aug 25 23:30:25 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.11.2.2 avida/current/source/tools/datafile.hh:1.11.2.3
--- avida/current/source/tools/datafile.hh:1.11.2.2	Thu May 15 05:35:19 2003
+++ avida/current/source/tools/datafile.hh	Mon Aug 25 23:30:25 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/tools/slice.cc
diff -u avida/current/source/tools/slice.cc:1.8.2.2 avida/current/source/tools/slice.cc:1.8.2.3
--- avida/current/source/tools/slice.cc:1.8.2.2	Thu May 15 05:35:20 2003
+++ avida/current/source/tools/slice.cc	Mon Aug 25 23:30:25 2003
@@ -32,9 +32,11 @@
 //  cConstSchedule
 ////////////////////
 
-cConstSchedule::cConstSchedule(int _item_count) : cSchedule(_item_count)
+cConstSchedule::cConstSchedule(int _item_count)
+  : cSchedule(_item_count), is_active(_item_count)
 {
   last_id = 0;
+  is_active.SetAll(false);
 }
 
 cConstSchedule::~cConstSchedule()
@@ -47,10 +49,22 @@
   return true;
 }
 
+void cConstSchedule::Adjust(int item_id, const cMerit & merit)
+{
+  if (merit == 0.0) is_active[item_id] = false;
+  else is_active[item_id] = true;
+}
+
+
 int cConstSchedule::GetNextID()
 {
-  last_id++;
-  if (last_id == item_count) last_id = 0;
+  // Grab the next ID...
+  if (++last_id == item_count) last_id = 0;
+
+  // Make sure we actually have an active ID...
+  while (is_active[last_id] == false) {
+    if (++last_id == item_count) last_id = 0;
+  }
   return last_id;
 }
 
Index: avida/current/source/tools/slice.hh
diff -u avida/current/source/tools/slice.hh:1.4.2.1 avida/current/source/tools/slice.hh:1.4.2.2
--- avida/current/source/tools/slice.hh:1.4.2.1	Tue May 20 05:12:38 2003
+++ avida/current/source/tools/slice.hh	Mon Aug 25 23:30:25 2003
@@ -43,12 +43,13 @@
 class cConstSchedule : public cSchedule {
 private:
   int last_id;
+  tArray<bool> is_active;
 public:
   cConstSchedule(int _item_count);
   ~cConstSchedule();
 
   bool OK();
-  void Adjust(int item_id, const cMerit & merit) { ; }
+  void Adjust(int item_id, const cMerit & merit);
 
   int GetNextID();
 };
Index: avida/current/source/utils/hist_map/hist_map.cc
diff -u avida/current/source/utils/hist_map/hist_map.cc:1.1.2.1 avida/current/source/utils/hist_map/hist_map.cc:1.1.2.2
--- avida/current/source/utils/hist_map/hist_map.cc:1.1.2.1	Mon May 12 10:22:49 2003
+++ avida/current/source/utils/hist_map/hist_map.cc	Mon Aug 25 23:30:25 2003
@@ -42,10 +42,8 @@
     
     int total_count = 0;
 
-    int line_num = 0;
-    while (file.GetNumLines() > 0) {
-      line_num++;
-      cString cur_line = file.RemoveLine();
+    for (int line_num = 0; line_num < file.GetNumLines(); line_num++) {
+      cString cur_line = file.GetLine(line_num);
       int value = -1;
       int count = -1;
       
@@ -60,7 +58,7 @@
       if (value < 0) {
 	cout << "Error in file '" << argv[i+3]
 	     << "': Only posive values allowed." << endl
-	     << "   (line = " << line_num
+	     << "   (line = " << line_num+1
 	     << ",  count = " << count
 	     << ",  value = '" << value << "')" << endl;
 	return 1;
Index: avida/current/source/viewers/Makefile.am
diff -u avida/current/source/viewers/Makefile.am:1.13.2.4 avida/current/source/viewers/Makefile.am:1.13.2.5
--- avida/current/source/viewers/Makefile.am:1.13.2.4	Thu May 22 14:29:02 2003
+++ avida/current/source/viewers/Makefile.am	Mon Aug 25 23:30:25 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.6.2.1 avida/current/source/viewers/bar_screen.cc:1.6.2.2
--- avida/current/source/viewers/bar_screen.cc:1.6.2.1	Mon May 12 10:22:49 2003
+++ avida/current/source/viewers/bar_screen.cc	Mon Aug 25 23:30:25 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.9.2.1 avida/current/source/viewers/map_screen.cc:1.9.2.2
--- avida/current/source/viewers/map_screen.cc:1.9.2.1	Mon May 12 10:22:49 2003
+++ avida/current/source/viewers/map_screen.cc	Mon Aug 25 23:30:25 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.2.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 25 23:30:25 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.3.2.1 avida/current/source/viewers/symbol_util.cc:1.3.2.2
--- avida/current/source/viewers/symbol_util.cc:1.3.2.1	Mon May 12 10:22:50 2003
+++ avida/current/source/viewers/symbol_util.cc	Mon Aug 25 23:30:25 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.10.2.2 avida/current/source/viewers/text_screen.cc:1.10.2.3
--- avida/current/source/viewers/text_screen.cc:1.10.2.2	Tue May 20 05:12:47 2003
+++ avida/current/source/viewers/text_screen.cc	Mon Aug 25 23:30:26 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.8.2.1 avida/current/source/viewers/text_screen.hh:1.8.2.2
--- avida/current/source/viewers/text_screen.hh:1.8.2.1	Tue May 20 05:12:47 2003
+++ avida/current/source/viewers/text_screen.hh	Mon Aug 25 23:30:26 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.9.2.2 avida/current/source/viewers/view.cc:1.9.2.3
--- avida/current/source/viewers/view.cc:1.9.2.2	Fri May 16 15:15:54 2003
+++ avida/current/source/viewers/view.cc	Mon Aug 25 23:30:26 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.2.1
--- avida/current/source/viewers/view.hh:1.9	Sun Nov 11 15:21:03 2001
+++ avida/current/source/viewers/view.hh	Mon Aug 25 23:30:26 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.22.2.2 avida/current/source/viewers/zoom_screen.cc:1.22.2.3
--- avida/current/source/viewers/zoom_screen.cc:1.22.2.2	Tue May 20 05:12:47 2003
+++ avida/current/source/viewers/zoom_screen.cc	Mon Aug 25 23:30:26 2003
@@ -18,6 +18,7 @@
 #include "../main/tasks.hh"
 
 #include "../cpu/hardware_cpu.hh"
+#include "../cpu/hardware_4stack.hh"
 
 #include "zoom_screen.hh"
 
@@ -39,12 +40,16 @@
   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;
+  //hardware_type = info.GetActiveCell()->GetOrganism()->GetHardware().GetType();
+  cur_stack=0;
+  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();
@@ -75,14 +80,20 @@
   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");
   }
 
   // Redirect to the proper Draw() method.
 
-  if (mode == ZOOM_MODE_CPU) DrawCPU();
+  if (mode == ZOOM_MODE_CPU)
+    {
+      if(cConfig::GetHardwareType()==HARDWARE_TYPE_CPU_ORIGINAL) 
+	DrawCPU_Original();
+      if(cConfig::GetHardwareType()==HARDWARE_TYPE_CPU_4STACK) 
+	DrawCPU_4Stack();
+    }
   else if (mode == ZOOM_MODE_STATS) DrawStats();
   else if (mode == ZOOM_MODE_GENOTYPE) DrawGenotype();
 
@@ -118,11 +129,23 @@
 
   Print(10, 27, "Thread:");
   Print(11, 27, "IP....:");
-  Print(12, 27, "AX....:");
-  Print(13, 27, "BX....:");
-  Print(14, 27, "CX....:");
-  Print(15, 27, "Stack.:");
-  Print(16, 27, "---- Memory ----");
+
+  if(cConfig::GetHardwareType() == HARDWARE_TYPE_CPU_ORIGINAL)
+    {
+      Print(12, 27, "AX....:");
+      Print(13, 27, "BX....:");
+      Print(14, 27, "CX....:");
+      Print(15, 27, "Stack.:");
+      Print(16, 27, "---- Memory ----");
+    }
+  else if(cConfig::GetHardwareType() == HARDWARE_TYPE_CPU_4STACK)
+    {
+      Print(12, 27, "Stack AX:");
+      Print(13, 27, "Stack BX:");
+      Print(14, 27, "Stack CX:");
+      Print(15, 27, "Stack DX:");
+      Print(16, 27, "---- Memory ----");
+    }
 
   Print(CPU_FLAGS_Y, CPU_FLAGS_X, "---- Flags ----");
 
@@ -159,11 +182,9 @@
     Print(Height()-1, Width() - 21, "<-");
     Print(Height()-1, Width() - 11, "->");
   }
-
-
 }
 
-void cZoomScreen::DrawCPU()
+void cZoomScreen::DrawCPU_Original()
 {
   SetColor(COLOR_WHITE);
 
@@ -211,9 +232,8 @@
 
   Print(OPTIONS_Y+6, OPTIONS_X+2, "[E]dit Component");
   Print(OPTIONS_Y+7, OPTIONS_X+2, "[V]iew Component");
-#ifdef THREADS
-  Print(OPTIONS_Y+8, OPTIONS_X+2, "[T]hread Options");
-#endif
+  if(cConfig::GetMaxCPUThreads() >1)
+    Print(OPTIONS_Y+8, OPTIONS_X+2, "Next [T]hread");
   Print(OPTIONS_Y+9, OPTIONS_X+2, "[TAB] Shift Active");
 
   if (info.GetPauseLevel()) {
@@ -226,9 +246,8 @@
   SetBoldColor(COLOR_CYAN);
   Print(OPTIONS_Y+6, OPTIONS_X+3, "E");
   Print(OPTIONS_Y+7, OPTIONS_X+3, "V");
-#ifdef THREADS
-  Print(OPTIONS_Y+8, OPTIONS_X+3, "T");
-#endif
+  if(cConfig::GetMaxCPUThreads() >1)
+    Print(OPTIONS_Y+8, OPTIONS_X+8, "T");
   Print(OPTIONS_Y+9, OPTIONS_X+3, "TAB");
 
   if (info.GetPauseLevel()) {
@@ -261,6 +280,109 @@
   Print(19, 52, "Thread.......:");
 }
 
+void cZoomScreen::DrawCPU_4Stack()
+{
+  SetColor(COLOR_WHITE);
+
+  // --== Registers ==--
+  Box(REG_X, REG_Y-1, 19, 8);
+  Print(REG_Y, REG_X + 2, "Stacks:");
+  HLine(REG_Y + 1, REG_X, 19);
+
+  SetBoldColor(COLOR_WHITE);
+  Print(REG_Y + 2, REG_X + 2, "AX:");
+  Print(REG_Y + 3, REG_X + 2, "BX:");
+  Print(REG_Y + 4, REG_X + 2, "CX:");
+  Print(REG_Y + 5, REG_X + 2, "DX:");
+  SetColor(COLOR_WHITE);
+
+  // --== Inputs ==--
+  Box(INPUT_X, INPUT_Y-1, 16, 8);
+  Print(INPUT_Y, INPUT_X + 2, "Inputs:");
+  HLine(INPUT_Y+1, INPUT_X, 16);
+
+  // --== Mini-Map ==--
+  Box(MINI_MAP_X, MINI_MAP_Y, 17, 3);
+  Print(MINI_MAP_Y + 1, MINI_MAP_X + 2, "Mini-Map");
+  //HLine(MINI_MAP_Y + 2, MINI_MAP_X, 19);
+
+  SetBoldColor(COLOR_WHITE);
+  Print(MINI_MAP_Y + 11, MINI_MAP_X,  "[ ]           [ ]");
+  SetBoldColor(COLOR_CYAN);
+  Print(MINI_MAP_Y + 11, MINI_MAP_X + 1,  '-');
+  Print(MINI_MAP_Y + 11, MINI_MAP_X + 15, '+');
+  SetColor(COLOR_WHITE);
+
+  // --== Memory ==--
+  Box(MEMORY_X, MEMORY_Y, 36, 5 + MEMORY_PRE_SIZE + MEMORY_POST_SIZE);
+  Print(MEMORY_Y + 1, MEMORY_X + 2,  "Memory Space");
+  HLine(MEMORY_Y + 2, MEMORY_X, 36);
+
+  // --== Stack ==--
+  Box(STACK_X, STACK_Y-1, 15, 8);
+  HLine(STACK_Y + 1, STACK_X, 15);
+
+  // --== Options ==--
+  SetBoldColor(COLOR_YELLOW);
+  Print(OPTIONS_Y, OPTIONS_X+4,    "Component Zoom");
+  SetBoldColor(COLOR_WHITE);
+
+  //Print(OPTIONS_Y+6, OPTIONS_X+2, "[E]dit Component");
+  //Print(OPTIONS_Y+7, OPTIONS_X+2, "[V]iew Component");
+  Print(OPTIONS_Y+5, OPTIONS_X+2, "Next Stac[K]");
+  if(cConfig::GetMaxCPUThreads() >1)
+  Print(OPTIONS_Y+6, OPTIONS_X+2, "Next [T]hread");
+  //Print(OPTIONS_Y+9, OPTIONS_X+2, "[TAB] Shift Active");
+
+  if (info.GetPauseLevel()) {
+    Print(OPTIONS_Y+7, OPTIONS_X+2, "[UP, DOWN]");
+    Print(OPTIONS_Y+8, OPTIONS_X+2, "Scroll Instruction");
+    Print(OPTIONS_Y+9, OPTIONS_X+2, "[LEFT, RIGHT]");
+    Print(OPTIONS_Y+10, OPTIONS_X+2, "Change Mem Space");
+  } else {
+    Print(OPTIONS_Y+7, OPTIONS_X+2, "               ");
+    Print(OPTIONS_Y+8, OPTIONS_X+2, "                  ");
+    Print(OPTIONS_Y+9, OPTIONS_X+2, "               ");
+    Print(OPTIONS_Y+10, OPTIONS_X+2, "                 ");
+  }
+
+
+  SetBoldColor(COLOR_CYAN);
+  Print(OPTIONS_Y+5, OPTIONS_X+12, "K");
+  if(cConfig::GetMaxCPUThreads() >1)
+  Print(OPTIONS_Y+6, OPTIONS_X+8, "T");
+
+  if (info.GetPauseLevel()) {
+    Print(OPTIONS_Y+7, OPTIONS_X+3, "UP, DOWN");
+    Print(OPTIONS_Y+9, OPTIONS_X+3, "LEFT, RIGHT");
+  }
+
+  // Highlight the active section...
+  SetActiveSection(active_section);
+
+  // Add on a bunch of special characters to smooth the view out...
+  Print(INPUT_Y - 1, INPUT_X, CHAR_TTEE);
+  Print(INPUT_Y + 1, INPUT_X, CHAR_PLUS);
+  Print(INPUT_Y + 6, INPUT_X, CHAR_BTEE);
+
+  Print(STACK_Y - 1, STACK_X, CHAR_TTEE);
+  Print(STACK_Y + 1, STACK_X, CHAR_PLUS);
+  Print(STACK_Y + 6, STACK_X, CHAR_BTEE);
+
+
+  // A few stats on this screen...
+
+  SetBoldColor(COLOR_WHITE);
+
+  Print(13, 52, "Location.....:");
+  Print(14, 52, "Genotype ID..:");
+  Print(15, 52, "Genotype Name:");
+
+  Print(17, 52, "Faults.......:");
+  Print(18, 52, "Offspring....:");
+  Print(19, 52, "Thread.......:");
+}
+
 void cZoomScreen::DrawGenotype()
 {
   SetBoldColor(COLOR_YELLOW);
@@ -306,16 +428,15 @@
 
 void cZoomScreen::Update()
 {
-  if (mode == ZOOM_MODE_CPU){
-    UpdateCPU();
-  }
-  else if (mode == ZOOM_MODE_STATS) UpdateStats();
+  cHardwareBase & hardware = info.GetActiveCell()->GetOrganism()->GetHardware();
+  if(mode == ZOOM_MODE_CPU) UpdateCPU(hardware);
+  else if (mode == ZOOM_MODE_STATS) UpdateStats(hardware);
   else if (mode == ZOOM_MODE_GENOTYPE) UpdateGenotype();
 
   Refresh();
 }
 
-void cZoomScreen::UpdateStats()
+void cZoomScreen::UpdateStats(cHardwareBase & hardware)
 {
   if (info.GetActiveCell() == NULL ||
       info.GetActiveCell()->IsOccupied() == false) return;
@@ -323,8 +444,8 @@
   cGenotype * genotype = info.GetActiveGenotype();
   cPhenotype & phenotype = info.GetActiveCell()->GetOrganism()->GetPhenotype();
 
-  cHardwareCPU & hardware =
-    (cHardwareCPU &) info.GetActiveCell()->GetOrganism()->GetHardware();
+  //cHardwareBase & hardware =
+  //  info.GetActiveCell()->GetOrganism()->GetHardware();
 
   SetBoldColor(COLOR_CYAN);
 
@@ -354,34 +475,14 @@
   Print(7, 39, "%9d ", phenotype.GetGestationStart());
   Print(8, 39, "%9d ", phenotype.GetNumDivides());
 
-
   if (info.GetThreadLock() != -1) Print(10, 36, "LOCKED");
   else Print(10, 36, "      ");
-  Print(10, 43, "%2d/%2d", hardware.GetCurThread() + 1,
-	hardware.GetNumThreads());
-  Print(12, 34, "%14d", hardware.Register(0));
-  Print(13, 34, "%14d", hardware.Register(1));
-  Print(14, 34, "%14d", hardware.Register(2));
-  Print(15, 34, "%14d", hardware.GetStack(0));
+  
+  if(cConfig::GetHardwareType() == HARDWARE_TYPE_CPU_ORIGINAL)
+    UpdateStats_CPU(hardware);
 
-  cCPUHead inst_ptr(hardware.IP());
-  const cInstSet & inst_set = hardware.GetInstSet();
-
-  for (int pos = 0; pos < 3; pos++) {
-    // Clear the line
-    Print(17+pos, 29, "                    ");
-    if (inst_ptr.InMemory() == false) continue;
-    if (pos == 1) SetColor(COLOR_CYAN);
-
-    // Draw the current instruction.
-      Print(17+pos, 29, "%s",	inst_set.GetName(inst_ptr.GetInst())());
-    inst_ptr.Advance();
-  }
-
-  // Flags...
-  if (hardware.GetMalActive()) SetBoldColor(COLOR_CYAN);
-  else SetColor(COLOR_CYAN);
-  Print(CPU_FLAGS_Y + 1, CPU_FLAGS_X + 1, "Mem Allocated");
+  if(cConfig::GetHardwareType() == HARDWARE_TYPE_CPU_4STACK)
+    UpdateStats_4Stack(hardware);
 
   if (phenotype.ParentTrue()) SetBoldColor(COLOR_CYAN);
   else SetColor(COLOR_CYAN);
@@ -450,27 +551,158 @@
   Print(2, 40, "[%2d, %2d] ",
 	id % population.GetWorldX(), id / population.GetWorldY());
 
-  // And print the IP.
+  
 
-  const cCPUHead & active_inst_ptr = hardware.IP();
+}
+
+void cZoomScreen::UpdateStats_CPU(cHardwareBase & hardware)
+{
+  cHardwareCPU & hardwareCPU = (cHardwareCPU &) hardware;
+
+  Print(10, 43, "%2d/%2d", hardwareCPU.GetCurThread() + 1,
+	hardwareCPU.GetNumThreads());
+
+  Print(12, 34, "%14d", hardwareCPU.Register(0));
+  Print(13, 34, "%14d", hardwareCPU.Register(1));
+  Print(14, 34, "%14d", hardwareCPU.Register(2));
+  Print(15, 34, "%14d", hardwareCPU.GetStack(0));
+
+  cCPUHead inst_ptr(hardwareCPU.IP());
+   const cInstSet & inst_set = hardwareCPU.GetInstSet();
+  
+  for (int pos = 0; pos < 3; pos++) {
+    // Clear the line
+    Print(17+pos, 29, "                    ");
+    if (inst_ptr.InMemory() == false) continue;
+    if (pos == 1) SetColor(COLOR_CYAN);
+
+    // Draw the current instruction.
+      Print(17+pos, 29, "%s",	inst_set.GetName(inst_ptr.GetInst())());
+    inst_ptr.Advance();
+  }
+
+  // Flags...
+  if (hardwareCPU.GetMalActive()) SetBoldColor(COLOR_CYAN);
+  else SetColor(COLOR_CYAN);
+  Print(CPU_FLAGS_Y + 1, CPU_FLAGS_X + 1, "Mem Allocated");
+ 
+  // And print the IP.
+  const cCPUHead & active_inst_ptr = hardwareCPU.IP();
   // @CAO assume no parasites for now.
   int cur_id = info.GetActiveCell()->GetID();
   //active_inst_ptr.GetCurHardware()->GetOrganism()->GetEnvironment()->GetID();
   Print(11, 36, "%12s", cStringUtil::Stringf("[%2d,%2d] : %2d",
 	cur_id % population.GetWorldX(), cur_id / population.GetWorldX(),
 	active_inst_ptr.GetPosition())() );
+}
+
+void cZoomScreen::UpdateStats_4Stack(cHardwareBase & hardware)
+{
+  cHardware4Stack & hardware4Stack = (cHardware4Stack &) hardware;
 
+  Print(10, 43, "%2d/%2d", hardware4Stack.GetCurThread() + 1,
+	hardware4Stack.GetNumThreads());
+
+  Print(12, 34, "%14d", hardware4Stack.Stack(0).Top());
+  Print(13, 34, "%14d", hardware4Stack.Stack(1).Top());
+  Print(14, 34, "%14d", hardware4Stack.Stack(2).Top());
+  Print(15, 34, "%14d", hardware4Stack.Stack(3).Top());
+
+  c4StackHead inst_ptr(hardware4Stack.IP());
+   const cInstSet & inst_set = hardware4Stack.GetInstSet();
+  
+  for (int pos = 0; pos < 3; pos++) {
+    // Clear the line
+    Print(17+pos, 29, "                    ");
+    if (inst_ptr.InMemory() == false) continue;
+    if (pos == 1) SetColor(COLOR_CYAN);
+
+    // Draw the current instruction.
+      Print(17+pos, 29, "%s",	inst_set.GetName(inst_ptr.GetInst())());
+    inst_ptr.Advance();
+  }
+
+  // Flags...
+  //if (hardwareCPU.GetMalActive()) SetBoldColor(COLOR_CYAN);
+  //else SetColor(COLOR_CYAN);
+  //Print(CPU_FLAGS_Y + 1, CPU_FLAGS_X + 1, "Mem Allocated");
+ 
+  // And print the IP.
+  const c4StackHead & active_inst_ptr = hardware4Stack.IP();
+  // @CAO assume no parasites for now.
+  //int cur_id = info.GetActiveCell()->GetID();
+  //active_inst_ptr.GetCurHardware()->GetOrganism()->GetEnvironment()->GetID();
+  Print(11, 36, "%12s", cStringUtil::Stringf("(%2d, %2d)",
+	active_inst_ptr.GetMemSpace(),
+	active_inst_ptr.GetPosition())() );
 }
 
-void cZoomScreen::UpdateCPU()
+void cZoomScreen::UpdateCPU(cHardwareBase & hardware)
 {
-  cHardwareCPU & hardware =
-    (cHardwareCPU &) info.GetActiveCell()->GetOrganism()->GetHardware();
+  // Place the visible section of the current memory onto the screen.
+
+  SetBoldColor(COLOR_WHITE);
+  if (info.GetPauseLevel() == PAUSE_OFF) {
+    // If not paused, then set user desired offset to zero AND always show
+    // the code that is executing (ie. do not show original Parasite code if
+    // host is executing)
+    memory_offset = 0;
+    parasite_zoom = false;
+  }
+
+  Print(14, 69, "%10d", info.GetActiveGenotypeID());
+  Print(15, 69, "%10s", info.GetActiveName()());
+
+  cPhenotype & phenotype = info.GetActiveCell()->GetOrganism()->GetPhenotype();
+  Print(17, 69, "%10d", phenotype.GetCurNumErrors());
+  Print(18, 69, "%10d", phenotype.GetNumDivides());
+  if (info.GetThreadLock() != -1) Print(19, 67, "LOCKED");
+  else Print(19, 67, "      ");
+
+  if(cConfig::GetHardwareType()==HARDWARE_TYPE_CPU_ORIGINAL)
+    UpdateCPU_Original(hardware);
+  else if(cConfig::GetHardwareType()==HARDWARE_TYPE_CPU_4STACK)
+    UpdateCPU_4Stack(hardware);
+
+  // Place the input buffer on the screen.
+
+  SetBoldColor(COLOR_CYAN);
+  Print(INPUT_Y+3, INPUT_X+2, "%12d", info.GetActiveCell()->GetInput(0));
+
+  SetColor(COLOR_CYAN);
+  for (int i = 1; i < IO_SIZE; i++) {
+    Print(INPUT_Y+3+i, INPUT_X+2, "%12d", info.GetActiveCell()->GetInput(i));
+  }
+
+  const cString & cur_fault = phenotype.GetFault();
+  if (cur_fault.GetSize() > 0) {
+    SetBoldColor(COLOR_RED);
+    Print(FAULT_Y, FAULT_X, "Fault:");
+    SetBoldColor(COLOR_CYAN);
+    Print(FAULT_Y, FAULT_X + 7, cur_fault());
+  } else {
+    Print(FAULT_Y, FAULT_X, "                                        ");
+  }
+
+  SetBoldColor(COLOR_WHITE);
+
+  Print(13, 70, "[%3d,%3d] ",
+	info.GetActiveID() % population.GetWorldX(),
+	info.GetActiveID() / population.GetWorldY());
+
+  SetBoldColor(COLOR_CYAN);
+  Refresh();
+}
+
+void cZoomScreen::UpdateCPU_Original(cHardwareBase & hardware)
+{
+  cHardwareCPU & hardwareCPU = (cHardwareCPU &) hardware;
+  //hardwareCPU.SetThread(cur_view_thread);
 
   // Place the registers onto the screen.
   SetBoldColor(COLOR_CYAN);
   for (int i = 0; i < NUM_REGISTERS; i++) {
-    Print(REG_Y+3 + i, REG_X+6, "%11d", hardware.Register(i));
+    Print(REG_Y+3 + i, REG_X+6, "%11d", hardwareCPU.Register(i));
   }
 
   // Place the active stack onto the screen.
@@ -478,14 +710,14 @@
   // Stack A
   // SetBoldColor(COLOR_CYAN);   // -Redundant
   SetColor(COLOR_WHITE);
-  char stack_letter = 'A' + hardware.GetActiveStackID();
+  char stack_letter = 'A' + hardwareCPU.GetActiveStackID();
   Print(STACK_Y + 1, STACK_X + 2, "Stack %c", stack_letter);
 
   SetBoldColor(COLOR_CYAN);
-  Print(STACK_Y+3, STACK_X + 2, "%11d", hardware.GetStack(0));
+  Print(STACK_Y+3, STACK_X + 2, "%11d", hardwareCPU.GetStack(0));
   SetColor(COLOR_CYAN);
   for (int i = 1; i <= 2; i++) {
-    Print(STACK_Y+3 + i, STACK_X+2, "%11d", hardware.GetStack(i));
+    Print(STACK_Y+3 + i, STACK_X+2, "%11d", hardwareCPU.GetStack(i));
   }
 
   // Place the input buffer on the screen.
@@ -498,38 +730,20 @@
     Print(INPUT_Y+3+i, INPUT_X+2, "%12d", info.GetActiveCell()->GetInput(i));
   }
 
-  // Place the visible section of the current memory onto the screen.
-
-  SetBoldColor(COLOR_WHITE);
-  if (info.GetPauseLevel() == PAUSE_OFF) {
-    // If not paused, then set user desired offset to zero AND always show
-    // the code that is executing (ie. do not show original Parasite code if
-    // host is executing)
-    memory_offset = 0;
-    parasite_zoom = false;
-  }
-
-  Print(14, 69, "%10d", info.GetActiveGenotypeID());
-  Print(15, 69, "%10s", info.GetActiveName()());
-
-  cPhenotype & phenotype = info.GetActiveCell()->GetOrganism()->GetPhenotype();
-  Print(17, 69, "%10d", phenotype.GetCurNumErrors());
-  Print(18, 69, "%10d", phenotype.GetNumDivides());
-  if (info.GetThreadLock() != -1) Print(19, 67, "LOCKED");
-  else Print(19, 67, "      ");
-  Print(19, 74, "%2d/%2d", hardware.GetCurThread() + 1,
-	hardware.GetNumThreads());
-
+  Print(19, 74, "%2d/%2d", hardwareCPU.GetCurThread() + 1,
+	hardwareCPU.GetNumThreads());
+  
   // This line gets the creature that is currently executing. Usually the
   // creature we are viewing, but can also be a different one (if this is a
   // parasite).
-
+  
   const cCPUMemory & memory = (parasite_zoom) ?
-    hardware.GetMemory() : hardware.IP().GetMemory();
+    hardware.GetMemory() : hardwareCPU.IP().GetMemory();
   SetColor(COLOR_WHITE);
   Print(MEMORY_Y + 1, MEMORY_X + 9, "%4d", memory.GetSize());
-
-
+  
+  
+  
   // Nothing past this point gets executed for empty creatures....
   if (memory.GetSize() == 0) {
     for (int i = -MEMORY_PRE_SIZE; i <= MEMORY_POST_SIZE; i++) {
@@ -537,12 +751,12 @@
     }
     return;
   }
-
+  
   int adj_inst_ptr = 0;
-  int base_inst_ptr = hardware.IP().GetPosition();
+  int base_inst_ptr = hardwareCPU.IP().GetPosition();
   if (base_inst_ptr < 0 || parasite_zoom == true) base_inst_ptr = 0;
 
-  const cInstSet & inst_set = hardware.GetInstSet();
+  const cInstSet & inst_set = hardwareCPU.GetInstSet();
 
   // Determine the center (must be between 0 and size - 1)
   int center_pos = (base_inst_ptr + memory_offset) % memory.GetSize();
@@ -601,40 +815,163 @@
 	Print(MEMORY_Y + MEMORY_PRE_SIZE + 3 + i, MEMORY_X + 27, "Bp");
       }
 
-      if (adj_inst_ptr == hardware.GetHead(HEAD_READ).GetPosition()) {
+      if (adj_inst_ptr == hardwareCPU.GetHead(HEAD_READ).GetPosition()) {
 	Print(MEMORY_Y + MEMORY_PRE_SIZE + 3 + i, MEMORY_X + 30, "R");
       }
-      if (adj_inst_ptr == hardware.GetHead(HEAD_WRITE).GetPosition()) {
+      if (adj_inst_ptr == hardwareCPU.GetHead(HEAD_WRITE).GetPosition()) {
 	Print(MEMORY_Y + MEMORY_PRE_SIZE + 3 + i, MEMORY_X + 31, "W");
       }
-      if (adj_inst_ptr == hardware.GetHead(HEAD_FLOW).GetPosition()) {
+      if (adj_inst_ptr == hardwareCPU.GetHead(HEAD_FLOW).GetPosition()) {
 	  Print(MEMORY_Y + MEMORY_PRE_SIZE + 3 + i, MEMORY_X + 32, "F");
       }
     }
-
     SetColor(COLOR_WHITE);
   }
 
   DrawMiniMap();
+}
 
-  const cString & cur_fault = phenotype.GetFault();
-  if (cur_fault.GetSize() > 0) {
-    SetBoldColor(COLOR_RED);
-    Print(FAULT_Y, FAULT_X, "Fault:");
-    SetBoldColor(COLOR_CYAN);
-    Print(FAULT_Y, FAULT_X + 7, cur_fault());
-  } else {
-    Print(FAULT_Y, FAULT_X, "                                        ");
+void cZoomScreen::UpdateCPU_4Stack(cHardwareBase & hardware)
+{
+  cHardware4Stack & hardware4Stack = (cHardware4Stack &) hardware;
+  
+  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 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, cur_view_thread).Top());
   }
 
-  SetBoldColor(COLOR_WHITE);
+  // Place the active stack onto the screen.
 
-  Print(13, 70, "[%3d,%3d] ",
-	info.GetActiveID() % population.GetWorldX(),
-	info.GetActiveID() / population.GetWorldY());
+  // Stack AX
+  //SetBoldColor(COLOR_CYAN);   // -Redundant
+  SetColor(COLOR_WHITE);
+  
+  Print(STACK_Y, STACK_X + 2, "Stack   :");
+  Print(STACK_Y, STACK_X + 8, "%s" , hardware4Stack.GetActiveStackID(cur_stack)());
 
-  SetBoldColor(COLOR_CYAN);
-  Refresh();
+  //SetBoldColor(COLOR_CYAN);
+  //Print(STACK_Y+2, STACK_X + 2, "%11d", hardware4Stack.GetStack(0, cur_stack));
+  SetColor(COLOR_CYAN);
+  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", cur_view_thread + 1,
+	hardware4Stack.GetNumThreads());
+  
+  // This line gets the creature that is currently executing. Usually the
+  // creature we are viewing, but can also be a different one (if this is a
+  // parasite).
+  
+  const cCPUMemory & memory = hardware4Stack.GetMemory(cur_mem_space);
+  SetBoldColor(COLOR_BLUE);
+  Print(MEMORY_Y + 1, MEMORY_X + 8, " Space ");	
+  SetColor(COLOR_WHITE);
+  Print(MEMORY_Y + 1, MEMORY_X + 15, "%2d", cur_mem_space);
+  
+  Print(MEMORY_Y + 1, MEMORY_X + 17, ":");	
+  Print(MEMORY_Y + 1, MEMORY_X + 18, "%4d", memory.GetSize());
+  
+  
+  
+  // Nothing past this point gets executed for empty creatures....
+  if (memory.GetSize() == 0) {
+    for (int i = -MEMORY_PRE_SIZE; i <= MEMORY_POST_SIZE; i++) {
+      HLine(MEMORY_Y + MEMORY_PRE_SIZE + 3 + i, MEMORY_X, 36);
+    }
+    return;
+  }
+  
+  int adj_inst_ptr = 0;
+  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();
+
+  // Determine the center (must be between 0 and size - 1)
+  int center_pos = (base_inst_ptr + memory_offset) % memory.GetSize();
+  if (center_pos < 0) center_pos += memory.GetSize();
+
+  for (int i = -MEMORY_PRE_SIZE; i <= MEMORY_POST_SIZE; i++) {
+    adj_inst_ptr = (center_pos + i) % (memory.GetSize() + 1);
+    if (adj_inst_ptr < 0) adj_inst_ptr += memory.GetSize() + 1;
+
+    if (adj_inst_ptr == memory.GetSize()) {
+      HLine(MEMORY_Y + MEMORY_PRE_SIZE + 3 + i, MEMORY_X, 36);
+    } else {
+      Print(MEMORY_Y + MEMORY_PRE_SIZE + 3 + i, MEMORY_X, CHAR_VLINE);
+      Print(MEMORY_Y + MEMORY_PRE_SIZE + 3 + i, MEMORY_X + 35, CHAR_VLINE);
+
+      // If we are on the instruction about to be executed by the CPU,
+      // hilight it...
+      if (adj_inst_ptr == base_inst_ptr && 
+	  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);
+	SetBoldColor(COLOR_CYAN);
+      } else {
+	if (i == 0) SetBoldColor(COLOR_YELLOW);
+	Print(MEMORY_Y + MEMORY_PRE_SIZE + 3 + i, MEMORY_X + 1, "%3d: ",
+		  adj_inst_ptr);
+	// If we are scrolling through memory, make the current position
+	// yellow.
+	if (i == 0) SetColor(COLOR_YELLOW);
+	else SetColor(COLOR_CYAN);
+      }
+
+      // Print the instruction...
+      Print(MEMORY_Y + MEMORY_PRE_SIZE + 3 + i, MEMORY_X + 6, "%8s ",
+	    inst_set.GetName( memory[adj_inst_ptr] )());
+
+      Print(MEMORY_Y + MEMORY_PRE_SIZE + 3 + i, MEMORY_X + 15,
+         "                    ");
+
+      // Only list the "Cpy" flag or the "Inj" flag...
+      if (memory.FlagCopied(adj_inst_ptr) == true) {
+	Print(MEMORY_Y + MEMORY_PRE_SIZE + 3 + i, MEMORY_X + 16, "Cpy");
+      }
+      if (memory.FlagInjected(adj_inst_ptr) == true) {
+	Print(MEMORY_Y + MEMORY_PRE_SIZE + 3 + i, MEMORY_X + 16, "Inj");
+      }
+
+      // Other flags we're interested in...
+      if (memory.FlagMutated(adj_inst_ptr) == true) {
+	Print(MEMORY_Y + MEMORY_PRE_SIZE + 3 + i, MEMORY_X + 20, "Mut");
+	}
+      if (memory.FlagExecuted(adj_inst_ptr) == true) {
+	  Print(MEMORY_Y + MEMORY_PRE_SIZE + 3 + i, MEMORY_X + 24, "Exe");
+      }
+      if (memory.FlagBreakpoint(adj_inst_ptr) == true) {
+	Print(MEMORY_Y + MEMORY_PRE_SIZE + 3 + i, MEMORY_X + 28, "Bp");
+      }
+
+      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, 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, 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");
+      }
+    }
+    SetColor(COLOR_WHITE);
+  }
+
+  DrawMiniMap();
 }
 
 void cZoomScreen::UpdateGenotype()
@@ -1064,15 +1401,40 @@
   case ZOOM_SECTION_MEMORY:
     return cCoords(MEMORY_X, MEMORY_Y);
     break;
+
   case ZOOM_SECTION_REGISTERS:
-    return cCoords(REG_X, REG_Y);
+    if(cConfig::GetHardwareType()==HARDWARE_TYPE_CPU_ORIGINAL)
+    {
+      return cCoords(REG_X, REG_Y);
+    }
+    else if(cConfig::GetHardwareType()==HARDWARE_TYPE_CPU_4STACK)
+      {
+	return cCoords(REG_X, REG_Y-1);
+      }
     break;
+    
   case ZOOM_SECTION_STACK:
-    return cCoords(STACK_X, STACK_Y);
+    if(cConfig::GetHardwareType()==HARDWARE_TYPE_CPU_ORIGINAL)
+      {
+	return cCoords(STACK_X, STACK_Y);
+      }
+    else if(cConfig::GetHardwareType()==HARDWARE_TYPE_CPU_4STACK)
+      {
+	return cCoords(STACK_X, STACK_Y-1);
+      }
     break;
+
   case ZOOM_SECTION_INPUTS:
-    return cCoords(INPUT_X, INPUT_Y);
+    if(cConfig::GetHardwareType()==HARDWARE_TYPE_CPU_ORIGINAL)
+      {
+	return cCoords(INPUT_X, INPUT_Y);
+      }
+    else if(cConfig::GetHardwareType()==HARDWARE_TYPE_CPU_4STACK)
+      {
+	return cCoords(INPUT_X, INPUT_Y-1);
+      }
     break;
+    
   case ZOOM_SECTION_MAP:
     return cCoords(MINI_MAP_X, MINI_MAP_Y);
     break;
@@ -1081,27 +1443,87 @@
   return cCoords(0,0);
 }
 
+/*
 cString cZoomScreen::GetSectionName(int in_section)
 {
   switch (in_section) {
   case ZOOM_SECTION_MEMORY:
-    return cString("Memory");
+    if(cConfig::GetHardwareType()==HARDWARE_TYPE_CPU_ORIGINAL)
+      {
+	 return cString("Memory");
+      }
+    else if(cConfig::GetHardwareType()==HARDWARE_TYPE_CPU_4STACK)
+      {
+	return cString("Memory Space");
+      }
     break;
+
   case ZOOM_SECTION_REGISTERS:
-    return cString("Registers");
+    if(cConfig::GetHardwareType()==HARDWARE_TYPE_CPU_ORIGINAL)
+      {
+	 return cString("Registers:");
+      }
+    else if(cConfig::GetHardwareType()==HARDWARE_TYPE_CPU_4STACK)
+      {
+	return cString("Stacks:");
+      }
     break;
+
   case ZOOM_SECTION_STACK:
-    return cString("Stack");
+    return cString("Stack ");
     break;
+
   case ZOOM_SECTION_INPUTS:
-    return cString("Inputs");
+    return cString("Inputs:");
     break;
+
   case ZOOM_SECTION_MAP:
     return cString("Mini-Map");
     break;
   }
 
   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)
@@ -1111,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);
 }
 
@@ -1132,12 +1554,36 @@
   if (mode == ZOOM_MODE_STATS    && DoInputStats(in_char)) return;
   if (mode == ZOOM_MODE_GENOTYPE && DoInputGenotype(in_char)) return;
 
+  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':
-    ThreadOptions();
+    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':
@@ -1187,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)));
@@ -1201,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;
@@ -1214,15 +1662,23 @@
     break;
   case '6':
   case KEY_RIGHT:
-    if (active_section == ZOOM_SECTION_MAP) {
-      mini_center_id++;
-      if (mini_center_id == population.GetSize()) mini_center_id = 0;
-      if (population.GetCell(mini_center_id).IsOccupied()) {
-	memory_offset = 0;
-	info.SetActiveCell( &(population.GetCell(mini_center_id)));
+    if (active_section == ZOOM_SECTION_MAP) 
+      {
+	mini_center_id++;
+	if (mini_center_id == population.GetSize()) mini_center_id = 0;
+	if (population.GetCell(mini_center_id).IsOccupied()) {
+	  memory_offset = 0;
+	  info.SetActiveCell( &(population.GetCell(mini_center_id)));
+	}
       }
-      Update();
-    }
+    else if (active_section == ZOOM_SECTION_MEMORY)
+      {
+	if(cConfig::GetHardwareType() == HARDWARE_TYPE_CPU_4STACK)
+	  {
+	    ++cur_mem_space%=4;
+	  }
+      }
+    Update(); 
     break;
   case '4':
   case KEY_LEFT:
@@ -1233,18 +1689,39 @@
 	memory_offset = 0;
 	info.SetActiveCell( &(population.GetCell(mini_center_id)));
       }
-      Update();
     }
+    else if (active_section == ZOOM_SECTION_MEMORY) {
+      if(cConfig::GetHardwareType()==HARDWARE_TYPE_CPU_4STACK)
+	{
+	  cur_mem_space+=3;
+	  cur_mem_space%=4;
+	}
+    }
+    Update();
+    break;
+  case 'K':
+  case 'k':
+    if(cConfig::GetHardwareType()==HARDWARE_TYPE_CPU_4STACK) {
+      ++cur_stack%=4;
+    }
+    Update();
     break;
+    //case '<':
+    // if(hardware_type==HARDWARE_TYPE_CPU_4STACK)
+    //  {
+    //cur_stack=(cur_stack-1);
+    //if(cur_stack<0) cur_stack=3;
+    //}
+    //Update();
+    //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':
@@ -1340,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.7 avida/current/source/viewers/zoom_screen.hh:1.7.2.1
--- avida/current/source/viewers/zoom_screen.hh:1.7	Sun Nov 11 15:21:03 2001
+++ avida/current/source/viewers/zoom_screen.hh	Mon Aug 25 23:30:26 2003
@@ -66,19 +66,28 @@
   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
   int active_section;
   int task_offset;
+  //int hardware_type;
+  int cur_stack;
+  int cur_mem_space;
+  int cur_view_thread;
 
 private:
-  void DrawCPU();
+  void DrawCPU_Original();
+  void DrawCPU_4Stack();
   void DrawStats();
   void DrawGenotype();
-  void UpdateCPU();
-  void UpdateStats();
+  void UpdateCPU(cHardwareBase & hardware);
+  void UpdateCPU_Original(cHardwareBase & hardware);
+  void UpdateCPU_4Stack(cHardwareBase & hardware);
+  void UpdateStats(cHardwareBase & hardware);
+  void UpdateStats_CPU(cHardwareBase & hardware);
+  void UpdateStats_4Stack(cHardwareBase & hardware);
   void UpdateGenotype();
 
   void EditMemory();
@@ -93,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();

Index: avida/current/source/event/cPopulation_construct_event_auto.ci
+++ avida/current/source/event/cPopulation_construct_event_auto.ci

Index: avida/current/source/event/cPopulation_descr.ci
+++ avida/current/source/event/cPopulation_descr.ci

Index: avida/current/source/event/cPopulation_descr.hi
+++ avida/current/source/event/cPopulation_descr.hi

Index: avida/current/source/event/cPopulation_enums_auto.ci
+++ avida/current/source/event/cPopulation_enums_auto.ci

Index: avida/current/source/event/cPopulation_name2enum_auto.ci
+++ avida/current/source/event/cPopulation_name2enum_auto.ci

Index: avida/current/source/event/cPopulation_process_auto.ci
+++ avida/current/source/event/cPopulation_process_auto.ci

Index: avida/current/source/main/inject_genebank.cc
+++ avida/current/source/main/inject_genebank.cc
//////////////////////////////////////////////////////////////////////////////
// Copyright (C) 1993 - 2003 California Institute of Technology             //
//                                                                          //
// Read the COPYING and README files, or contact 'avida at alife.org',         //
// before continuing.  SOME RESTRICTIONS MAY APPLY TO USE OF THIS FILE.     //
//////////////////////////////////////////////////////////////////////////////

#include <fstream>

#include "inject_genebank.hh"

#include "inject_genotype.hh"
#include "config.hh"
#include "stats.hh"

#include "../cpu/test_util.hh"

using namespace std;

/////////////////////
//  cInjectGenotypeQueue
/////////////////////

cInjectGenotypeQueue::cInjectGenotypeQueue()
{
  size = 0;
  root.SetNext(&root);
  root.SetPrev(&root);
}


cInjectGenotypeQueue::~cInjectGenotypeQueue()
{
  while (root.GetNext() != &root) {
    Remove(root.GetNext());
  }
}

bool cInjectGenotypeQueue::OK()
{
  bool result = true;
  int count = 0;

  for (cInjectGenotypeElement * temp_element = root.GetNext();
       temp_element != &root;
       temp_element = temp_element->GetNext()) {
    assert (temp_element->GetNext()->GetPrev() == temp_element);
    assert (temp_element->GetInjectGenotype()->GetID() >= 0);

    count++;
    assert (count <= size);
  }

  assert (count == size);

  return result;
}

void cInjectGenotypeQueue::Insert(cInjectGenotype & in_inject_genotype)
{
  cInjectGenotypeElement * new_element = new cInjectGenotypeElement(&in_inject_genotype);
  new_element->SetNext(root.GetNext());
  new_element->SetPrev(&root);
  root.GetNext()->SetPrev(new_element);
  root.SetNext(new_element);
  size++;
}

void cInjectGenotypeQueue::Remove(cInjectGenotype & in_inject_genotype)
{
  cInjectGenotypeElement * cur_element;

  for (cur_element = root.GetNext();
       cur_element != &root;
       cur_element = cur_element->GetNext()) {
    if (cur_element->GetInjectGenotype() == &in_inject_genotype) break;
  }

  assert (cur_element != &root);

  Remove(cur_element);
}

void cInjectGenotypeQueue::Remove(cInjectGenotypeElement * in_element)
{
  in_element->GetPrev()->SetNext(in_element->GetNext());
  in_element->GetNext()->SetPrev(in_element->GetPrev());
  in_element->SetNext(NULL);
  in_element->SetPrev(NULL);
  delete(in_element);

  size--;
}

cInjectGenotype * cInjectGenotypeQueue::Find(const cGenome & in_genome) const
{
  for (cInjectGenotypeElement * cur_element = root.GetNext();
       cur_element != &root;
       cur_element = cur_element->GetNext()) {
    if (cur_element->GetInjectGenotype()->GetGenome() == in_genome) {
      return cur_element->GetInjectGenotype();
    }
  }

  return NULL;
}


////////////////////////////
//  cInjectGenotypeControl
////////////////////////////

cInjectGenotypeControl::cInjectGenotypeControl(cInjectGenebank & in_gb) : genebank(in_gb)
{
  size = 0;
  best = NULL;
  coalescent = NULL;
  for (int i = 0; i < INJECTGENOTYPE_THREADS; i++) threads[i] = NULL;

  historic_list = NULL;
  historic_count = 0;
}

cInjectGenotypeControl::~cInjectGenotypeControl()
{
}

bool cInjectGenotypeControl::OK()
{
  int ret_value = true;

  // Cycle through the list, making sure all connections are proper, size
  // is correct, and all genotypes are OK().

  cInjectGenotype * cur_pos = best;
  for (int i = 0; i < size; i++) {
    if (!cur_pos->OK()) ret_value = false;
    assert (cur_pos->GetNext()->GetPrev() == cur_pos);
    cur_pos = cur_pos->GetNext();
  }

  assert (cur_pos == best);

  return ret_value;
}

void cInjectGenotypeControl::Insert(cInjectGenotype & in_inject_genotype, cInjectGenotype * prev_genotype)
{
  if (prev_genotype == NULL) {
    assert(size == 0); // Destroying a full genotype queue...

    best = &in_inject_genotype;
    best->SetNext(best);
    best->SetPrev(best);
  }
  else {
    in_inject_genotype.SetPrev(prev_genotype);
    in_inject_genotype.SetNext(prev_genotype->GetNext());
    prev_genotype->SetNext(&in_inject_genotype);
    in_inject_genotype.GetNext()->SetPrev(&in_inject_genotype);
  }

  size++;
}

void cInjectGenotypeControl::Remove(cInjectGenotype & in_inject_genotype)
{
  if (size == 1) {
    best = NULL;
  }
  if (&in_inject_genotype == best) {
    best = best->GetNext();
  }

  in_inject_genotype.GetNext()->SetPrev(in_inject_genotype.GetPrev());
  in_inject_genotype.GetPrev()->SetNext(in_inject_genotype.GetNext());
  in_inject_genotype.SetNext(NULL);
  in_inject_genotype.SetPrev(NULL);

  size--;
}

void cInjectGenotypeControl::RemoveHistoric(cInjectGenotype & in_inject_genotype)
{
  if (historic_count == 1) {
    historic_list = NULL;
  }
  if (&in_inject_genotype == historic_list) {
    historic_list = historic_list->GetNext();
  }

  in_inject_genotype.GetNext()->SetPrev(in_inject_genotype.GetPrev());
  in_inject_genotype.GetPrev()->SetNext(in_inject_genotype.GetNext());
  in_inject_genotype.SetNext(NULL);
  in_inject_genotype.SetPrev(NULL);

  historic_count--;
}

void cInjectGenotypeControl::InsertHistoric(cInjectGenotype & in_inject_genotype)
{
  if (historic_count == 0) {
    in_inject_genotype.SetNext(&in_inject_genotype);
    in_inject_genotype.SetPrev(&in_inject_genotype);
  }
  else {
    in_inject_genotype.SetPrev(historic_list->GetPrev());
    in_inject_genotype.SetNext(historic_list);
    historic_list->GetPrev()->SetNext(&in_inject_genotype);
    historic_list->SetPrev(&in_inject_genotype);
  }

  historic_list = &in_inject_genotype;
  historic_count++;
}

/*int cInjectGenotypeControl::UpdateCoalescent()
{
  // Test to see if any updating needs to be done...
  // Don't update active coalescent genotype, or if there is more than
  // one offspring.
  if (coalescent != NULL &&
      (coalescent->GetNumInjected() > 0) ||
      coalescent->GetNumOffspringGenotypes() > 1) ) {
    return coalescent->GetDepth();
  }

  // If there is no best, there is nothing to search through...
  if (best == NULL) return -1;

  // Find the new point...
  cInjectGenotype * test_gen = best;
  cInjectGenotype * found_gen = best;
  cInjectGenotype * parent_gen = best->GetParentGenotype();

  while (parent_gen != NULL) {
    // See if this genotype should be the new found genotype...
    if (test_gen->GetNumOrganisms() > 0 ||
	test_gen->GetNumOffspringGenotypes() > 1) {
      found_gen = test_gen;
    }

    // Move to the next genotype...
    test_gen = parent_gen;
    parent_gen = test_gen->GetParentGenotype();
  }

  coalescent = found_gen;

  return coalescent->GetDepth();
}*/


bool cInjectGenotypeControl::CheckPos(cInjectGenotype & in_inject_genotype)
{
  int next_OK = false;
  int prev_OK = false;

  if (in_inject_genotype.GetNumInjected() >= in_inject_genotype.GetNext()->GetNumInjected()) {
    next_OK =true;
  }
  if (in_inject_genotype.GetNumInjected() <= in_inject_genotype.GetPrev()->GetNumInjected()) {
    prev_OK =true;
  }

  if ((&in_inject_genotype == best && next_OK) ||
      (next_OK && prev_OK) ||
      (&in_inject_genotype == best->GetPrev() && prev_OK)) {
    return true;
  }

  return false;
}

void cInjectGenotypeControl::Insert(cInjectGenotype & new_genotype)
{
  // If there is nothing in the list, add this.

  if (size == 0) {
    Insert(new_genotype, NULL);
  }

  // Otherwise tack it on the end.

  else {
    Insert(new_genotype, best->GetPrev());
  }
}

bool cInjectGenotypeControl::Adjust(cInjectGenotype & in_inject_genotype)
{
  //if (in_inject_genotype.GetDeferAdjust() == true) return true;

  cInjectGenotype * cur_inject_genotype = in_inject_genotype.GetPrev();

  // Check to see if this genotype should be removed completely.

  if (in_inject_genotype.GetNumInjected() == 0) {
    genebank.RemoveInjectGenotype(in_inject_genotype);
    return false;
  }

  // Do not adjust if this was and still is the best genotype, or is
  // otherwise in the proper spot...

  if (CheckPos(in_inject_genotype)) {
    return true;
  }

  // Otherwise, remove it from the queue for just the moment.

  Remove(in_inject_genotype);

  // Also, if this genotype is the best, put it there.

  if (in_inject_genotype.GetNumInjected() > best->GetNumInjected()) {
    Insert(in_inject_genotype, best->GetPrev());
    best = &in_inject_genotype;
    return true;
  }

  // Finally, find out where this genotype *does* go.

  while (cur_inject_genotype->GetNumInjected() >= in_inject_genotype.GetNumInjected() &&
	 cur_inject_genotype != best->GetPrev()) {
    cur_inject_genotype = cur_inject_genotype->GetNext();
  }
  while (cur_inject_genotype->GetNumInjected() < in_inject_genotype.GetNumInjected() &&
	 cur_inject_genotype != best) {
    cur_inject_genotype = cur_inject_genotype->GetPrev();
  }

  Insert(in_inject_genotype, cur_inject_genotype);

  return true;
}


cInjectGenotype * cInjectGenotypeControl::Find(const cGenome & in_genome) const
{
  int i;
  cInjectGenotype * cur_inject_genotype = best;

  for (i = 0; i < size; i++) {
    if (in_genome == cur_inject_genotype->GetGenome()) {
      return cur_inject_genotype;
    }
    cur_inject_genotype = cur_inject_genotype->GetNext();
  }

  return NULL;
}

int cInjectGenotypeControl::FindPos(cInjectGenotype & in_inject_genotype, int max_depth)
{
  cInjectGenotype * temp_genotype = best;
  if (max_depth < 0 || max_depth > size) max_depth = size;

  for (int i = 0; i < max_depth; i++) {
    if (temp_genotype == &in_inject_genotype) return i;
    temp_genotype = temp_genotype->GetNext();
  }

  return -1;
}

cInjectGenotype * cInjectGenotypeControl::Next(int thread)
{
  return threads[thread] = threads[thread]->GetNext();
}

cInjectGenotype * cInjectGenotypeControl::Prev(int thread)
{
  return threads[thread] = threads[thread]->GetPrev();
}

////////////////////
//  cInjectGenebank
////////////////////

cInjectGenebank::cInjectGenebank(cStats & in_stats)
  : stats(in_stats)
{
  for (int i = 0; i < MAX_CREATURE_SIZE; i++) {
    inject_genotype_count[i] = 0;
  }

  inject_genotype_control = new cInjectGenotypeControl(*this);

}

cInjectGenebank::~cInjectGenebank()
{
  delete inject_genotype_control;
}

void cInjectGenebank::UpdateReset()
{
  static int genotype_dom_time = 0;
  static int prev_dom = -1;

  cInjectGenotype * best_inject_genotype = GetBestInjectGenotype();

  if (best_inject_genotype && best_inject_genotype->GetID() != prev_dom) {
    genotype_dom_time = 0;
    prev_dom = best_inject_genotype->GetID();
  }
  else {
    genotype_dom_time++;
    if (genotype_dom_time == cConfig::GetGenotypePrintDom()) {
      cString filename;
      filename.Set("genebank/%s", best_inject_genotype->GetName()());
      cTestUtil::PrintGenome(best_inject_genotype, best_inject_genotype->GetGenome(), 
			     filename, stats.GetUpdate());
    }
  }
}

cString cInjectGenebank::GetLabel(int in_size, int in_num)
{
  char alpha[6];
  char full_name[12];
  int i;

  for (i = 4; i >= 0; i--) {
    alpha[i] = (in_num % 26) + 'a';
    in_num /= 26;
  }
  alpha[5] = '\0';

  sprintf(full_name, "p%03d-%s", in_size, alpha);

  return full_name;
}

void cInjectGenebank::AddInjectGenotype(cInjectGenotype * in_inject_genotype, int in_list_num)
{
  assert( in_inject_genotype != 0 );
  
  if ( in_list_num < 0 )
    in_list_num = FindCRC(in_inject_genotype->GetGenome()) % INJECTGENOTYPE_HASH_SIZE;
  
  active_inject_genotypes[in_list_num].Insert(*in_inject_genotype);
  inject_genotype_control->Insert(*in_inject_genotype);
  //stats.AddGenotype(in_inject_genotype->GetID());
}


cInjectGenotype * cInjectGenebank::AddInjectGenotype(const cGenome & in_genome,
				   cInjectGenotype * parent_genotype)
{
  int list_num = FindCRC(in_genome) % INJECTGENOTYPE_HASH_SIZE;
  cInjectGenotype * found_genotype;

  found_genotype = active_inject_genotypes[list_num].Find(in_genome);

  if (!found_genotype) {
    found_genotype = new cInjectGenotype();
    found_genotype->SetGenome(in_genome);
    found_genotype->SetParent(parent_genotype);
    
    AddInjectGenotype( found_genotype, list_num );
  }

  return found_genotype;
}

cInjectGenotype * cInjectGenebank::FindInjectGenotype(const cGenome & in_genome) const
{
  int list_num = FindCRC(in_genome) % INJECTGENOTYPE_HASH_SIZE;
  return active_inject_genotypes[list_num].Find(in_genome);
}

void cInjectGenebank::RemoveInjectGenotype(cInjectGenotype & in_inject_genotype)
{
  // If this genotype is still active, mark it no longer active and
  // take it out of the hash table so it doesn't have any new organisms
  // assigned to it.

  if (in_inject_genotype.GetActive() == true) {
    int list_num = FindCRC(in_inject_genotype.GetGenome()) % INJECTGENOTYPE_HASH_SIZE;
    active_inject_genotypes[list_num].Remove(in_inject_genotype);
    inject_genotype_control->Remove(in_inject_genotype);
    //in_inject_genotype.Deactivate(stats.GetUpdate());
    if (cConfig::GetTrackMainLineage()) {
      inject_genotype_control->InsertHistoric(in_inject_genotype);
    }
  }

  // If we are tracking the main lineage, we only want to delete a
  // genotype when all of its decendents have also died out.

  /*if (cConfig::GetTrackMainLineage()) {
    // If  there are more offspring genotypes, hold off on deletion...
    if (in_inject_genotype.GetNumOffspringGenotypes() != 0) return;

    // If this is a dead end, delete it and recurse up...
    cInjectGenotype * parent = in_inject_genotype.GetParentGenotype();
    if (parent != NULL) {
      parent->RemoveOffspringGenotype();

      // Test to see if we need to update the coalescent genotype.
      const int new_coal = inject_genotype_control->UpdateCoalescent();
      stats.SetCoalescentGenotypeDepth(new_coal);
      // cout << "Set coalescent to " << found_gen->GetDepth() << endl;

      if (parent->GetNumInjected() == 0) {
	// Regardless, run RemoveGenotype on the parent.
	RemoveGenotype(*parent);
      }
    }

    inject_genotype_control->RemoveHistoric(in_inject_genotype);
  }

  // Handle the relevent statistics...
  stats.RemoveGenotype(in_inject_genotype.GetID(),
	      in_inject_genotype.GetParentID(), in_inject_genotype.GetParentDistance(),
	      in_inject_genotype.GetDepth(), in_inject_genotype.GetTotalOrganisms(),
              in_inject_genotype.GetTotalParasites(),
	      stats.GetUpdate() - in_inject_genotype.GetUpdateBorn(),
              in_inject_genotype.GetLength());
  if (in_inject_genotype.GetThreshold()) {
  stats.RemoveThreshold(in_inject_genotype.GetID());
  }*/

  delete &in_inject_genotype;
}

void cInjectGenebank::ThresholdInjectGenotype(cInjectGenotype & in_inject_genotype)
{
  in_inject_genotype.SetName( GetLabel(in_inject_genotype.GetLength(),
				inject_genotype_count[in_inject_genotype.GetLength()]++) );
  in_inject_genotype.SetThreshold();

  //stats.AddThreshold(in_inject_genotype.GetID(), in_inject_genotype.GetName()());
  
  // Print the genotype?

  if (cConfig::GetGenotypePrint()) {
    cString filename;
    filename.Set("genebank/%s", in_inject_genotype.GetName()());
    //cTestUtil::PrintGenome(in_inject_genotype.GetGenome(), filename,
    //			   &in_inject_genotype, stats.GetUpdate());
  }
}

bool cInjectGenebank::AdjustInjectGenotype(cInjectGenotype & in_inject_genotype)
{
  if (!inject_genotype_control->Adjust(in_inject_genotype)) return false;

  if ((in_inject_genotype.GetNumInjected() >= cConfig::GetThreshold() ||
       &in_inject_genotype == inject_genotype_control->GetBest()) &&
      !(in_inject_genotype.GetThreshold())) {
    ThresholdInjectGenotype(in_inject_genotype);
  }

  return true;
}

bool cInjectGenebank::SaveClone(ofstream & fp)
{
  // This method just save the counts at each size-class of genotypes.
  // The rest is reconstructable.

  // Save the numbers of organisms we're up to at each size.
  fp << MAX_CREATURE_SIZE << " ";
  for (int i = 0; i < MAX_CREATURE_SIZE; i++) {
    fp << inject_genotype_count[i] << " ";
  }

  return true;
}

bool cInjectGenebank::LoadClone(ifstream & fp)
{
  // This method just restores the counts at each size-class of genotypes.
  // The rest of the loading process should be handled elsewhere.

  // Load the numbers of organisms we're up to at each size.
  int max_size;
  fp >> max_size;
  assert (max_size <= MAX_CREATURE_SIZE); // MAX_CREATURE_SIZE too small
  for (int i = 0; i < max_size && i < MAX_CREATURE_SIZE; i++) {
    fp >> inject_genotype_count[i];
  }

  return true;
}

bool cInjectGenebank::DumpTextSummary(ofstream & fp)
{
  inject_genotype_control->Reset(0);
  for (int i = 0; i < inject_genotype_control->GetSize(); i++) {
    cInjectGenotype * genotype = inject_genotype_control->Get(0);
    fp << genotype->GetGenome().AsString() << " "
       << genotype->GetNumInjected() << " "
       << genotype->GetID() << endl;
    inject_genotype_control->Next(0);
  }

  return true;
}

bool cInjectGenebank::DumpDetailedSummary(const cString & file, int update)
{
  inject_genotype_control->Reset(0);
  for (int i = 0; i < inject_genotype_control->GetSize(); i++) {
    DumpDetailedEntry(inject_genotype_control->Get(0), file, update);
    inject_genotype_control->Next(0);
  }
  return true;
}

/*bool cInjectGenebank::DumpHistoricSummary(ofstream & fp)
{
  inject_genotype_control->ResetHistoric(0);
  for (int i = 0; i < inject_genotype_control->GetHistoricCount(); i++) {
    DumpDetailedEntry(inject_genotype_control->Get(0), fp);
    inject_genotype_control->Next(0);
  }

  return true;
}*/

void cInjectGenebank::DumpDetailedEntry(cInjectGenotype * genotype, const cString & filename, int update)
{
  /*fp << genotype->GetID() << " "                //  1
     << genotype->GetParentID() << " "          //  2
    //     << genotype->GetParentDistance() << " "    //  3
     << genotype->GetNumInjected() << " "      //  4
     << genotype->GetTotalInjected() << " "    //  5
     << genotype->GetLength() << " "            //  6
    // << genotype->GetMerit() << " "             //  7
    // << genotype->GetGestationTime() << " "     //  8
    // << genotype->GetFitness() << " "           //  9
     << genotype->GetUpdateBorn() << " "        // 10
     << genotype->GetUpdateDeactivated() << " " // 11
     << genotype->GetDepth() << " "             // 12
     << genotype->GetGenome().AsString() << " " // 13
     << endl;*/

  cDataFile & df = stats.GetDataFile(filename);

  df.WriteComment( "Avida parasite dump data" );
  df.WriteComment( "UPDATE " + update);
  df.WriteTimeStamp();

  //df.Write( update,                            "update");
  df.Write( genotype->GetID(),                 "parasite genotype ID");
  df.Write( genotype->GetName(),              "parasite genotype name");
  df.Write( genotype->GetParentID(),           "parasite parent ID");
  df.Write( genotype->GetNumInjected(),        "current number of injected creatures with this genotype");
  df.Write( genotype->GetTotalInjected(),      "total number of injected creatures with this genotype");
  df.Write( genotype->GetLength(),             "genotype length");
  df.Write( genotype->GetUpdateBorn(),         "update this genotype was born");
  df.Write( genotype->GetUpdateDeactivated(),  "update this genotype was deactivated");
  df.Write( genotype->GetDepth(),              "genotype depth");
  df.Write( genotype->GetGenome().AsString(),  "genome of this genotype");
  df.Endl();
}

bool cInjectGenebank::OK()
{
  bool ret_value = true;
  int i;

  // Check components...

  if (!inject_genotype_control->OK()) {
    ret_value = false;
  }

  // Loop through all of the reference lists for matching genotypes...

  for (i = 0; i < INJECTGENOTYPE_HASH_SIZE; i++) {
    assert (active_inject_genotypes[i].OK());
  }

  assert (ret_value == true);

  return ret_value;
}

int cInjectGenebank::CountNumCreatures()
{
  int i;
  int total = 0;

  inject_genotype_control->Reset(0);
  for (i = 0; i < inject_genotype_control->GetSize(); i++) {
    total += inject_genotype_control->Get(0)->GetNumInjected();
    inject_genotype_control->Next(0);
  }

  return total;
}


unsigned int cInjectGenebank::FindCRC(const cGenome & in_genome) const
{
  unsigned int total = 13;
  int i;

  for (i = 0; i < in_genome.GetSize(); i++) {
    total *= in_genome[i].GetOp() + 10 + i << 6;
    total += 3;
  }

  return total;
}


Index: avida/current/source/main/inject_genebank.hh
+++ avida/current/source/main/inject_genebank.hh
//////////////////////////////////////////////////////////////////////////////
// Copyright (C) 1993 - 2003 California Institute of Technology             //
//                                                                          //
// Read the COPYING and README files, or contact 'avida at alife.org',         //
// before continuing.  SOME RESTRICTIONS MAY APPLY TO USE OF THIS FILE.     //
//////////////////////////////////////////////////////////////////////////////

#ifndef INJECT_GENEBANK_HH
#define INJECT_GENEBANK_HH

#include "../tools/string.hh"
#include "../defs.hh"

// porting to gcc 3.1 -- k
//class std::ofstream;
//class std::ifstream;

class cInjectGenebank;
class cInjectGenotype;
class cGenome;
class cSpecies;
class cStats;

#define INJECTGENOTYPE_HASH_SIZE 307    // @CAO Is this an optimal number?
#define SPECIES_HASH_SIZE 101
#define INJECTGENOTYPE_THREADS 2

#define SPECIES_RECORD_OFF     0
#define SPECIES_RECORD_FULL    1
#define SPECIES_RECORD_LIMITED 2

class cInjectGenotypeElement {
private:
  cInjectGenotype * inject_genotype;
  cInjectGenotypeElement * next;
  cInjectGenotypeElement * prev;
public:
  inline cInjectGenotypeElement(cInjectGenotype * in_gen=NULL) : inject_genotype(in_gen) {
    next = NULL;  prev = NULL;
  }
  inline ~cInjectGenotypeElement() { ; }

  inline cInjectGenotype * GetInjectGenotype() const { return inject_genotype; }
  inline cInjectGenotypeElement * GetNext() const { return next; }
  inline cInjectGenotypeElement * GetPrev() const { return prev; }

  inline void SetNext(cInjectGenotypeElement * in_next) { next = in_next; }
  inline void SetPrev(cInjectGenotypeElement * in_prev) { prev = in_prev; }
};

class cInjectGenotypeQueue {
private:
  int size;
  cInjectGenotypeElement root;

  void Remove(cInjectGenotypeElement * in_element);
public:
  cInjectGenotypeQueue();
  ~cInjectGenotypeQueue();

  bool OK();

  void Insert(cInjectGenotype & in_inject_genotype);
  void Remove(cInjectGenotype & in_inject_genotype);
  cInjectGenotype * Find(const cGenome & in_genome) const;
};

class cInjectGenotypeControl {
private:
  int size;
  cInjectGenotype * best;
  cInjectGenotype * coalescent;
  cInjectGenotype * threads[INJECTGENOTYPE_THREADS];
  cInjectGenebank & genebank;

  cInjectGenotype * historic_list;
  int historic_count;

  void Insert(cInjectGenotype & in_inject_genotype, cInjectGenotype * prev_inject_genotype);
  bool CheckPos(cInjectGenotype & in_inject_genotype);
public:
  cInjectGenotypeControl(cInjectGenebank & in_gb);
  ~cInjectGenotypeControl();

  bool OK();
  void Remove(cInjectGenotype & in_inject_genotype);
  void Insert(cInjectGenotype & new_inject_genotype);
  bool Adjust(cInjectGenotype & in_inject_genotype);

  void RemoveHistoric(cInjectGenotype & in_inject_genotype);
  void InsertHistoric(cInjectGenotype & in_inject_genotype);
  int GetHistoricCount() { return historic_count; }

  int UpdateCoalescent();

  inline int GetSize() const { return size; }
  inline cInjectGenotype * GetBest() const { return best; }
  inline cInjectGenotype * GetCoalescent() const { return coalescent; }

  cInjectGenotype * Find(const cGenome & in_genome) const;
  int FindPos(cInjectGenotype & in_inject_genotype, int max_depth = -1);

  inline cInjectGenotype * Get(int thread) const { return threads[thread]; }
  inline cInjectGenotype * Reset(int thread)
    { return threads[thread] = best; }
  inline cInjectGenotype * ResetHistoric(int thread)
    { return threads[thread] = historic_list; }
  cInjectGenotype * Next(int thread);
  cInjectGenotype * Prev(int thread);
};

class cInjectGenebank {
private:
  unsigned int inject_genotype_count[MAX_CREATURE_SIZE];
  cInjectGenotypeQueue active_inject_genotypes[INJECTGENOTYPE_HASH_SIZE];
  cInjectGenotypeControl * inject_genotype_control;
  cStats & stats;

private:
  cString GetLabel(int in_size, int in_num);

public:
  cInjectGenebank(cStats & stats);
  ~cInjectGenebank();

  void UpdateReset();

  /** 
   * This function can be used to add a injectgenotype that was created
   * outside the genebank. In this case, the parameter in_list_num
   * should not be given. Normally, injectgenotypes are added through the 
   * function AddInjectGenotype(const cGenome & in_genome, 
   * cInjectGenotype * parent_injectgenotype = NULL), which then calls this one.
   **/
  void AddInjectGenotype(cInjectGenotype *in_inject_genotype, int in_list_num = -1 );
  cInjectGenotype * AddInjectGenotype(const cGenome & in_genome,
			  cInjectGenotype * parent_inject_genotype = NULL);
  cInjectGenotype * FindInjectGenotype(const cGenome & in_genome) const;
  void RemoveInjectGenotype(cInjectGenotype & in_inject_genotype);
  void ThresholdInjectGenotype(cInjectGenotype & in_inject_genotype);
  bool AdjustInjectGenotype(cInjectGenotype & in_inject_genotype);

  bool SaveClone(std::ofstream & fp);
  bool LoadClone(std::ifstream & fp);
  bool DumpTextSummary(std::ofstream & fp);
  //bool DumpDetailedSummary(std::ofstream & fp);
  bool DumpDetailedSummary(const cString & file, int update);
  bool DumpHistoricSummary(std::ofstream & fp);
  //void DumpDetailedEntry(cInjectGenotype * inject_genotype, std::ofstream & fp);
  void DumpDetailedEntry(cInjectGenotype * inject_genotype, const cString & file, int update);
  bool OK();

  inline int GetSize() const { return inject_genotype_control->GetSize(); }
  inline cInjectGenotype * GetBestInjectGenotype() const
    { return inject_genotype_control->GetBest(); }
  inline cInjectGenotype * GetCoalescentInjectGenotype() const
    { return inject_genotype_control->GetCoalescent(); }
  
  inline cInjectGenotype * GetInjectGenotype(int thread) const
    { return inject_genotype_control->Get(thread); }
  inline cInjectGenotype * NextInjectGenotype(int thread) {
    cInjectGenotype * next = inject_genotype_control->Next(thread);
    return (next == inject_genotype_control->GetBest()) ? (cInjectGenotype*)NULL : next;
  }
  inline cInjectGenotype * ResetThread(int thread)
    { return inject_genotype_control->Reset(thread); }

  int CountNumCreatures();
  inline int FindPos(cInjectGenotype & in_inject_genotype, int max_depth = -1)
    { return inject_genotype_control->FindPos(in_inject_genotype, max_depth); }
   unsigned int FindCRC(const cGenome & in_genome) const;
};

#endif

Index: avida/current/source/main/inject_genotype.cc
+++ avida/current/source/main/inject_genotype.cc
//////////////////////////////////////////////////////////////////////////////
// Copyright (C) 1993 - 2003 California Institute of Technology             //
//                                                                          //
// Read the COPYING and README files, or contact 'avida at alife.org',         //
// before continuing.  SOME RESTRICTIONS MAY APPLY TO USE OF THIS FILE.     //
//////////////////////////////////////////////////////////////////////////////

#include <fstream>

#include "inject_genotype.hh"

#include "../tools/tools.hh"
#include "../tools/merit.hh"

#include "stats.hh"
#include "config.hh"
#include "genome_util.hh"
#include "../cpu/hardware_method.hh"
#include "organism.hh"
#include "phenotype.hh"

#include "../cpu/test_cpu.hh"


using namespace std;

/////////////////////////
//  cInjectGenotype_BirthData
/////////////////////////

cInjectGenotype_BirthData::cInjectGenotype_BirthData(int in_update_born)
  : update_born(in_update_born)
  , parent_id(-1)
  , gene_depth(0)
  , update_deactivated(-1)
  , parent_genotype(NULL)
  , num_offspring_genotypes(0)
{
}

cInjectGenotype_BirthData::~cInjectGenotype_BirthData()
{
}


///////////////////////////
//  cInjectGenotype
///////////////////////////

cInjectGenotype::cInjectGenotype(int in_update_born, int in_id)
  : genome(1)
  , name("p001-no_name")
  , flag_threshold(false)
  , is_active(true)
  , defer_adjust(0)
  , symbol(0)
  , birth_data(in_update_born)
  , num_injected(0)
  , last_num_injected(0)
  , total_injected(0)
  , next(NULL)
  , prev(NULL)
{
  static int next_id = 1;
  
  if ( in_id >= 0 )
    next_id = in_id;
  
  id_num = next_id++;
}

cInjectGenotype::~cInjectGenotype()
{
  // Reset some of the variables to make sure program will crash if a deleted
  // cell is read!
  symbol = '!';

  num_injected = -1;
  total_injected = -1;

  next = NULL;
  prev = NULL;
}

bool cInjectGenotype::SaveClone(ofstream & fp)
{
  fp << id_num         << " ";
  fp << genome.GetSize() << " ";

  for (int i = 0; i < genome.GetSize(); i++) {
    fp << ((int) genome[i].GetOp()) << " ";
  }

  return true;
}

bool cInjectGenotype::LoadClone(ifstream & fp)
{
  int genome_size = 0;

  fp >> id_num;
  fp >> genome_size;

  genome = cGenome(genome_size);
  for (int i = 0; i < genome_size; i++) {
    cInstruction temp_inst;
    int inst_op;
    fp >> inst_op;
    temp_inst.SetOp((UCHAR) inst_op);
    genome[i] = temp_inst;
    // @CAO add something here to load arguments for instructions.
  }

  return true;
}

bool cInjectGenotype::OK()
{
  bool ret_value = true;

  // Check the components...

  if (!genome.OK()) ret_value = false;

  // And the statistics
  assert( id_num >= 0 && num_injected >= 0 && total_injected >= 0 );
  assert( birth_data.update_born >= -1);

  return ret_value;
};

void cInjectGenotype::SetParent(cInjectGenotype * parent)
{
  birth_data.parent_genotype = parent;

  // If we have a real parent genotype, collect other data about parent.
  if (parent == NULL) return;
  birth_data.parent_id = parent->GetID();
  birth_data.gene_depth = parent->GetDepth() + 1;
  parent->AddOffspringGenotype();
}

void cInjectGenotype::Mutate()  // Check each location to be mutated.
{
  int i;

  for (i = 0; i < genome.GetSize(); i++) {
      genome[i].SetOp(g_random.GetUInt(cConfig::GetNumInstructions()));
    }
  
}

void cInjectGenotype::UpdateReset()
{
  last_num_injected = num_injected;
  birth_data.birth_track.Next();
  birth_data.death_track.Next();
}

void cInjectGenotype::SetGenome(const cGenome & in_genome)
{
  genome = in_genome;

  name.Set("p%03d-no_name", genome.GetSize());
}

void cInjectGenotype::Deactivate(int update)
{
  is_active = false;
  birth_data.update_deactivated = update;
}

int cInjectGenotype::AddParasite()
{
  total_injected++;
  return num_injected++;
}

int cInjectGenotype::RemoveParasite()
{
  //birth_data.death_track.Inc();
  return num_injected--;
}


Index: avida/current/source/main/inject_genotype.hh
+++ avida/current/source/main/inject_genotype.hh
//////////////////////////////////////////////////////////////////////////////
// Copyright (C) 1993 - 2003 California Institute of Technology             //
//                                                                          //
// Read the COPYING and README files, or contact 'avida at alife.org',         //
// before continuing.  SOME RESTRICTIONS MAY APPLY TO USE OF THIS FILE.     //
//////////////////////////////////////////////////////////////////////////////

#ifndef INJECT_GENOTYPE_HH
#define INJECT_GENOTYPE_HH

#include "../tools/string.hh"
#include "../tools/stat.hh"

#include "genome.hh"

// porting to gcc 3.1 -- k
//class ofstream;
//class ifstream;

class cSpecies;
class cMerit;
class cInjectGenotype;

/*class cInjectGenotype_TestData {
public:
  cGenotype_TestData();
  ~cGenotype_TestData();

  bool is_viable;

  double fitness;
  double merit;
  int gestation_time;
  int executed_size;
  int copied_size;
  double colony_fitness;
  int generations;
  };*/

class cInjectGenotype_BirthData {
public:
  cInjectGenotype_BirthData(int in_update_born);
  ~cInjectGenotype_BirthData();

  cCountTracker birth_track;
  cCountTracker death_track;
  //cCountTracker breed_in_track;
  //cCountTracker breed_true_track;
  //cCountTracker breed_out_track;

  int update_born;      // Update genotype was first created
  int parent_id;        // ID of parent genotype
  //int parent_distance;  // Genetic distance from parent genotype
  int gene_depth;       // depth in the phylogenetic tree from ancestor

  int update_deactivated;      // If not, when did it get deactivated?
  cInjectGenotype * parent_genotype; // Pointer to parent genotype...
  //cSpecies * parent_species;
  int num_offspring_genotypes; // Num offspring genotypes still in memory.
};

class cInjectGenotype {
private:
  cGenome genome;
  cString name;
  bool flag_threshold;
  bool is_active;      // Is this genotype still alive?
  int defer_adjust;    // Don't adjust in the genebank until all are cleared.

  int id_num;
  char symbol;

  //mutable cGenotype_TestData test_data;
  cInjectGenotype_BirthData birth_data;

  // Statistical info

  int num_injected;
  int last_num_injected;
  int total_injected;
  //int total_parasites;

  //cSpecies * species;

  // Data Structure stuff...
  cInjectGenotype * next;
  cInjectGenotype * prev;


  ////// Statistical info //////

  // Collected on Divides
  //cDoubleSum sum_copied_size;
  //cDoubleSum sum_exe_size;

  //cDoubleSum sum_gestation_time;
  //cDoubleSum sum_repro_rate;  // should make gestation obsolete (not new)

  //cDoubleSum sum_merit;
  //cDoubleSum sum_fitness;

  // Temporary (Approx stats used before any divides done)
  // Set in "SetParent"
  //cDoubleSum tmp_sum_copied_size;
  //cDoubleSum tmp_sum_exe_size;

  //cDoubleSum tmp_sum_gestation_time;
  //cDoubleSum tmp_sum_repro_rate;

  //cDoubleSum tmp_sum_merit;
  //cDoubleSum tmp_sum_fitness;

  void CalcTestStats() const;
public:
  /**
   * Constructs an empty genotype. Normally, in_id should not specified as
   * parameter, because cGenotype keeps track of the last id given out, and
   * choses a new one based on that. However, in some cases it is necessary
   * to specify an id (e.g., when loading a history file from disk). Note 
   * that in this case, cGenotype does not check if the id has already been 
   * used before.
   **/
  cInjectGenotype(int in_update_born = 0, int in_id = -1);
  ~cInjectGenotype();

  bool SaveClone(std::ofstream & fp);
  bool LoadClone(std::ifstream & fp);
  bool OK();
  void Mutate();
  void UpdateReset();

  void SetGenome(const cGenome & in_genome);
  //void SetSpecies(cSpecies * in_species);

  // Test CPU info -- only used with limited options on.
  //bool GetTestViable() const;
  //double GetTestFitness() const;
  //double GetTestMerit() const;
  //int GetTestGestationTime() const;
  //int GetTestExecutedSize() const;
  //int GetTestCopiedSize() const;
  //double GetTestColonyFitness() const;
  //int GetTestGenerations() const;

  void SetParent(cInjectGenotype * parent);
  void SetName(cString in_name)     { name = in_name; }
  void SetNext(cInjectGenotype * in_next) { next = in_next; }
  void SetPrev(cInjectGenotype * in_prev) { prev = in_prev; }
  void SetSymbol(char in_symbol) { symbol = in_symbol; }
  inline void SetThreshold();
  void IncDeferAdjust() { defer_adjust++; }
  void DecDeferAdjust() { defer_adjust--; assert(defer_adjust >= 0); }

  // Setting New Stats
  //void AddCopiedSize      (int in)   { sum_copied_size.Add(in); }
  //void AddExecutedSize         (int in)   { sum_exe_size.Add(in); }
  //void AddGestationTime   (int in)   { sum_gestation_time.Add(in);
  //                            sum_repro_rate.Add(1/(double)in); }
//void AddMerit      (const cMerit & in);
//void RemoveMerit   (const cMerit & in);
//void AddFitness    (double in){
//  assert(in >= 0.0);
//  sum_fitness.Add(in);
//}
//void RemoveFitness (double in){
//  assert(in >= 0.0);
//  sum_fitness.Subtract(in);
//}

  //// Properties Native to Genotype ////
  cGenome & GetGenome()             { return genome; }
  const cGenome & GetGenome() const { return genome; }
  int GetLength()             const { return genome.GetSize(); }

//int GetBirths()    const { return birth_data.birth_track.GetTotal(); }
//int GetBreedOut()  const { return birth_data.breed_out_track.GetTotal(); }
//int GetBreedTrue() const { return birth_data.breed_true_track.GetTotal(); }
//int GetBreedIn()   const { return birth_data.breed_in_track.GetTotal(); }

//int GetThisBirths()    const { return birth_data.birth_track.GetCur(); }
//int GetThisBreedOut()  const { return birth_data.breed_out_track.GetCur(); }
//int GetThisBreedTrue() const { return birth_data.breed_true_track.GetCur(); }
//int GetThisBreedIn()   const { return birth_data.breed_in_track.GetCur(); }

//int GetThisDeaths() const { return birth_data.death_track.GetCur(); }

//int GetLastNumOrganisms() const { return last_num_organisms; }
//int GetLastBirths()    const { return birth_data.birth_track.GetLast(); }
//int GetLastBreedOut()  const { return birth_data.breed_out_track.GetLast(); }
//int GetLastBreedTrue() const { return birth_data.breed_true_track.GetLast();}
//int GetLastBreedIn()   const { return birth_data.breed_in_track.GetLast(); }

//inline void SetBreedStats(cGenotype & daughter); // called by ActivateChild

  //// Properties Averaged Over Creatues ////
  //double GetCopiedSize()    const { return (sum_copied_size.Count()>0) ?
//   sum_copied_size.Average() : tmp_sum_copied_size.Average(); }
//double GetExecutedSize()  const { return (sum_exe_size.Count()>0) ?
//   sum_exe_size.Average() : tmp_sum_exe_size.Average(); }
//double GetGestationTime() const { return (sum_gestation_time.Count()>0) ?
//   sum_gestation_time.Average() : tmp_sum_gestation_time.Average(); }
//double GetReproRate()     const { return (sum_repro_rate.Count()>0) ?
//   sum_repro_rate.Average() : tmp_sum_repro_rate.Average(); }
//double GetMerit()         const { return (sum_merit.Count()>0) ?
//   sum_merit.Average() : tmp_sum_merit.Average(); }
//double GetFitness()       const { return (sum_fitness.Count()>0) ?
//   sum_fitness.Average() : tmp_sum_fitness.Average(); }


  // For tracking the genotype line back to the ancestor...
  cInjectGenotype * GetParentGenotype() { return birth_data.parent_genotype; }
  int GetNumOffspringGenotypes() const
    { return birth_data.num_offspring_genotypes; }
  void AddOffspringGenotype() { birth_data.num_offspring_genotypes++; }
  void RemoveOffspringGenotype() { birth_data.num_offspring_genotypes--; }
  bool GetActive() const { return is_active; }
// bool GetDeferAdjust() const { return defer_adjust > 0; }
  int GetUpdateDeactivated() { return birth_data.update_deactivated; }
  void Deactivate(int update);

  int GetUpdateBorn()           { return birth_data.update_born; }
  int GetParentID()             { return birth_data.parent_id; }
//int GetParentDistance()       { return birth_data.parent_distance; }
  int GetDepth()                { return birth_data.gene_depth; }
  cString & GetName()           { return name; }
  cInjectGenotype * GetNext()         { return next; }
  cInjectGenotype * GetPrev()         { return prev; }
  bool GetThreshold() const     { return flag_threshold; }
  int GetID() const             { return id_num; }
  char GetSymbol() const        { return symbol; }

  int AddParasite();
  int RemoveParasite();
//int AddParasite()        { return ++total_parasites; }
//void SwapOrganism()      { total_organisms++; }
  int GetNumInjected()    { return num_injected; }
  int GetTotalInjected()  { return total_injected; }
//int GetTotalParasites()  { return total_parasites; }
};

// The genotype pointer template...



// All the inline stuff...

  ////////////////
 //  cGenotype //
////////////////

inline void cInjectGenotype::SetThreshold()
{
  flag_threshold = true;
  if (symbol == '.') symbol = '+';
}

/*
inline void cGenotype::SetBreedStats(cGenotype & daughter)
{
  birth_data.birth_track.Inc();
  if (daughter.id_num == id_num) {
    birth_data.breed_true_track.Inc();
  } else {
    birth_data.breed_out_track.Inc();
    daughter.birth_data.breed_in_track.Inc();
  }
}*/

#endif

Index: avida/current/source/main/org_message.cc
+++ avida/current/source/main/org_message.cc
#include "org_message.hh"
#include <string>
#include <sstream>

void cOrgMessage::SetData(int in_data)
{
  std::stringstream ss;
  ss << in_data;
  ss >> data;
}

void cOrgMessage::SetData(double in_data)
{
  std::stringstream ss;
  ss << in_data;
  ss >> data;
}

void cOrgMessage::GetData(int & in_data)
{
  in_data=atoi(data.c_str());
}

void cOrgMessage::GetData(double & in_data)
{
  in_data=atof(data.c_str());
}

Index: avida/current/source/main/org_message.hh
+++ avida/current/source/main/org_message.hh
#include <string>

class cOrgMessage {
private:
  int time;
  int sender_id;
  int recipient_id;
  std::string label;
  std::string data;

public:
  cOrgMessage() { time=sender_id=recipient_id=-1; label=data=""; }
  cOrgMessage(std::string in_label, std::string in_data) 
  { label = in_label; data = in_data; }
  
  void SetTime(int in_time) { time = in_time; }
  void SetSenderID(int in_id) { sender_id = in_id; }
  void SetRecipientID(int in_id) { recipient_id = in_id; }
  void SetLabel(int in_label) { label = in_label; }
  
  void SetData(std::string in_data) { data = in_data; }
  void SetData(int in_data);
  void SetData(double in_data);

  void GetData(std::string & in_data) { in_data=data; }
  void GetData(int & in_data);
  void GetData(double & in_data);
};

Index: avida/current/source/qt-viewer/event_chooser.cpp
+++ avida/current/source/qt-viewer/event_chooser.cpp

Index: avida/current/source/qt-viewer/event_chooser.h
+++ avida/current/source/qt-viewer/event_chooser.h

Index: avida/current/source/qt-viewer/event_list_editor.cpp
+++ avida/current/source/qt-viewer/event_list_editor.cpp

Index: avida/current/source/qt-viewer/event_list_editor.h
+++ avida/current/source/qt-viewer/event_list_editor.h

Index: avida/current/source/qt-viewer/godbox.cpp
+++ avida/current/source/qt-viewer/godbox.cpp

Index: avida/current/source/qt-viewer/godbox.h
+++ avida/current/source/qt-viewer/godbox.h

Index: avida/current/source/qt-viewer/plot_select_dia.cpp
+++ avida/current/source/qt-viewer/plot_select_dia.cpp

Index: avida/current/source/qt-viewer/plot_select_dia.h
+++ avida/current/source/qt-viewer/plot_select_dia.h

Index: avida/current/source/support/genesis.4stack
+++ avida/current/source/support/genesis.4stack
#############################################################################
# This file includes all the basic run-time defines for avida.
# For more information, see doc/genesis.html
#############################################################################

VERSION_ID 2.0b1		# Do not change this value!

### Architecture Variables ###
MAX_UPDATES  -1         # Maximum updates to run simulation (-1 = no limit)
MAX_GENERATIONS -1      # Maximum generations to run simulation (-1 = no limit)
END_CONDITION_MODE 0	# End run when ...
			# 0 = MAX_UPDATES _OR_ MAX_GENERATIONS is reached
			# 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.
RANDOM_SEED 0		# Random number seed. (0 for based on time)
HARDWARE_TYPE 1		# 0 = Original CPUs
			# 1 = New, Stack-based CPUs
MAX_CPU_THREADS 1	# Number of Threads CPUs can spawn

### Configuration Files ###
DEFAULT_DIR ../work/              # Directory in which config files are found
INST_SET inst_set.4stack          # File containing instruction set
EVENT_FILE events.cfg             # File containing list of events during run
ANALYZE_FILE analyze.cfg          # File used for analysis mode
ENVIRONMENT_FILE environment.cfg  # File that describes the environment
START_CREATURE organism.4stack    # Organism to seed the soup

### Reproduction ###
BIRTH_METHOD 4   # 0 = Replace random organism in neighborhood
		  # 1 = Replace oldest organism in neighborhood
		  # 2 = Replace largest Age/Merit in neighborhood
		  # 3 = Place only in empty cells in neighborhood
		  # 4 = Replace random from entire population (Mass Action)
		  # 5 = Replace oldest in entire population (like Tierra)
DEATH_METHOD 0    # 0 = Never die of old age.
		  # 1 = Die when inst executed = AGE_LIMIT (with deviation)
		  # 2 = Die when inst executed = length * AGE_LIMIT (+ dev.)
AGE_LIMIT 5000    # Modifies DEATH_METHOD
AGE_DEVIATION 0   # Modified DEATH_METHOD
ALLOC_METHOD 0    # 0 = Allocated space is set to default instruction.
                  # 1 = Set to section of dead genome (Necrophilia)
                  # 2 = Allocated space is set to random instruction.
DIVIDE_METHOD 2   # 0 = Divide leaves state of mother untouched.
                  # 1 = Divide resets state of mother
                  #     (after the divide, we have 2 children)
		  # 2 = Divide resets only the current thread of the mother
		  #     (useful in 4-stack CPU w/ parasites)

GENERATION_INC_METHOD 0 # 0 = Only the generation of the child is
                        #     increased on divide.
			# 1 = Both the generation of the mother and child are
			#     increased on divide (good with DIVIDE_METHOD 1).

### Divide Restrictions ####
CHILD_SIZE_RANGE 2.0	# Maximal differential between child and parent sizes.
MIN_COPIED_LINES 0.5    # Code fraction which must be copied before divide.
MIN_EXE_LINES    0.5    # Code fraction which must be executed before divide.
REQUIRE_ALLOCATE   1    # Is a an allocate required before a divide? (0/1)
REQUIRED_TASK -1  # Number of task required for successful divide.

### Mutations ###

# mutations that occur during execution..
POINT_MUT_PROB  0.0     # Mutation rate (per-location per update)
COPY_MUT_PROB   0.0075  # Mutation rate (per copy).

# mutations that occur on divide...
INS_MUT_PROB    0.0     # Insertion rate (per site, applied on divide).
DEL_MUT_PROB    0.0     # Deletion rate (per site, applied on divide).
DIV_MUT_PROB    0.0     # Mutation rate (per site, applied on divide).
DIVIDE_MUT_PROB 0.0     # Mutation rate (per divide).
DIVIDE_INS_PROB 0.05    # Insertion rate (per divide).
DIVIDE_DEL_PROB 0.05    # Deletion rate (per divide).
PARENT_MUT_PROB 0.0     # Per-site, in parent, on divide

# heads based mutations
# READ_SHIFT_PROB   0.0
# READ INS_PROB     0.0
# READ_DEL_PROB     0.0
# WRITE_SHIFT_PROB  0.0
# WRITE_INS_PROB    0.0
# WRITE_DEL_PROB    0.0


### Mutation reversions ###
# these slow down avida a lot, and should be set to 0 normally.
REVERT_FATAL       0.0  # Should any mutations be reverted on birth?
REVERT_DETRIMENTAL 0.0  #   0.0 to 1.0; Probability of reversion.
REVERT_NEUTRAL     0.0
REVERT_BENEFICIAL  0.0

STERILIZE_FATAL       0.0  # Should any mutations clear (kill) the organism?
STERILIZE_DETRIMENTAL 0.0  #   0.0 to 1.0; Probability of reset.
STERILIZE_NEUTRAL     0.0
STERILIZE_BENEFICIAL  0.0

FAIL_IMPLICIT     0	# Should copies that failed *not* due to mutations
			# be eliminated?

### Time Slicing ###
AVE_TIME_SLICE 30
SLICING_METHOD 2	# 0 = CONSTANT: all organisms get default...
			# 1 = PROBABILISTIC: Run _prob_ proportional to merit.
			# 2 = INTEGRATED: Perfectly integrated deterministic.
SIZE_MERIT_METHOD 4	# 0 = off (merit is independent of size)
			# 1 = Merit proportional to copied size
			# 2 = Merit prop. to executed size
			# 3 = Merit prop. to full size
			# 4 = Merit prop. to min of executed or copied size
			# 5 = Merit prop. to sqrt of the minimum size
TASK_MERIT_METHOD 1	# 0 = No task bonuses
			# 1 = Bonus just equals the task bonus
THREAD_SLICING_METHOD 1 # 0 = One thread executed per time slice.
			# 1 = All threads executed each time slice.
 			# Formula for an organism's thread slicing: 
			# 1 + (num_organism_threads-1) * THREAD_SLICING_METHOD

MAX_LABEL_EXE_SIZE 1	# Max nops marked as executed when labels are used
MERIT_TIME 1            # 0 = Merit Calculated when task completed
		        # 1 = Merit Calculated on Divide
MAX_NUM_TASKS_REWARDED -1  # -1 = Unlimited

### Genotype Info ###
THRESHOLD 3		# Number of organisms in a genotype needed for it
			#   to be considered viable.
GENOTYPE_PRINT 0	# 0/1 (off/on) Print out all threshold genotypes?
GENOTYPE_PRINT_DOM 0	# Print out a genotype if it stays dominant for
                        #   this many updates. (0 = off)
SPECIES_THRESHOLD 2     # max failure count for organisms to be same species
SPECIES_RECORDING 0	# 1 = full, 2 = limited search (parent only)
SPECIES_PRINT 0		# 0/1 (off/on) Print out all species?
TEST_CPU_TIME_MOD 20    # Time allocated in test CPUs (multiple of length)
TRACK_MAIN_LINEAGE 1    # Track primary lineage leading to final population?

### Log Files ###
LOG_CREATURES 0		# 0/1 (off/on) toggle to print file.
LOG_GENOTYPES 0		# 0 = off, 1 = print ALL, 2 = print threshold ONLY.
LOG_THRESHOLD 0		# 0/1 (off/on) toggle to print file.
LOG_SPECIES 0		# 0/1 (off/on) toggle to print file.
LOG_LANDSCAPE 0		# 0/1 (off/on) toggle to print file.

LOG_LINEAGES 0          # 0/1 (off/on) to log advantageous mutations
# This one can slow down avida a lot. It is used to get an idea of how
# often an advantageous mutation arises, and where it goes afterwards.
# See also LINEAGE_CREATION_METHOD.

LINEAGE_CREATION_METHOD 0
# Lineage creation options are.  Works only when LOG_LINEAGES is set to 1.
#   0 = manual creation (on inject, use successive integers as lineage labels).
#   1 = when a child's (potential) fitness is higher than that of its parent.
#   2 = when a child's (potential) fitness is higher than max in population.
#   3 = when a child's (potential) fitness is higher than max in dom. lineage
#	*and* the child is in the dominant lineage, or (2)
#   4 = when a child's (potential) fitness is higher than max in dom. lineage
#	(and that of its own lineage)
#   5 = same as child's (potential) fitness is higher than that of the
#       currently dominant organism, and also than that of any organism
#       currently in the same lineage.
#   6 = when a child's (potential) fitness is higher than any organism
#       currently in the same lineage.
#   7 = when a child's (potential) fitness is higher than that of any
#       organism in its line of descent

### END ###



Index: avida/current/source/support/inst_set.4stack
+++ avida/current/source/support/inst_set.4stack
Nop-A      	1	#1 	(a)	
Nop-B      	1  	#2	(b)
Nop-C      	1   	#3	(c)
Nop-D		1	#4	(d)
#Nop-X		1	#	
Val-Shift-R    	1	#5	(e)
Val-Shift-L    	1   	#6	(f)
Val-Nand      	1   	#7	(g)
Val-Add        	1   	#8	(h)
Val-Sub        	1   	#9	(i)
Val-Mult	1	#10	(j)
Val-Div		1	#11	(k)
SetMemory    	1   	#12	(l)
Divide   	1   	#13 	(m)
Inst-Read	1	#14	(n)
Inst-Write	1	#15	(o)
#Inst-Copy     	1   	     	()
If-Equal	1	#16	(p)
If-Not-Equal  	1	#17	(q)
If-Less    	1   	#18	(r)
If-Greater	1	#19	(s)
Head-Push	1	#20	(t)
Head-Pop	1	#21	(u)
Head-Move   	1   	#22   	(v)
Search   	1   	#23  	(w)
Push-Next	1	#24	(x)
Push-Prev	1	#25	(y)
Push-Comp	1	#26	(z)
Val-Delete	1	#27	(A)
Val-Copy	1	#28	(B)
#ThreadFork	1	#29	()
#if-label   	1   		()
Val-Inc		1	#30	(C)
Val-Dec		1	#31 	(D)
Val-Mod		1	#32	(E)
#ThreadKill	1	#33	()
IO		1	#34	(F)
Inject		1	#35	(G)
Index: avida/current/source/support/preset_organisms/organism.4stack
+++ avida/current/source/support/preset_organisms/organism.4stack
# SAMPLE ORGANISM:
#
Search       #  1:  Find organism end.
Nop-C        #  2:  - Match CD:AB
Nop-D
#ThreadFork   #  3:
#Nop-D	     #  4:
Push-Prev    #  5:  Move end position to Stack-A
SetMemory    #  6:  Place FLOW-head in memory space for offspring
Head-Move    #  7:  Move Write head to flow head position
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Nop-C        #  8:
Search       #  9:  Drop flow head at start of copy loop
Inst-Read    # 10:
Inst-Write   # 11: 
Head-Push    # 12:  Get current position of...
Nop-C        # 13:  - Read-Head
If-Equal     # 14:  Test if we are done copying...
Divide       # 15:  ...If so, divide.
Head-Move    # 16:  ...If not, continue with loop.
Nop-A        # 17:
Nop-B		
Index: avida/current/source/support/preset_organisms/organism.parasite
+++ avida/current/source/support/preset_organisms/organism.parasite
Search       #  1:  Find organism end.
Nop-D        #  2:  - Match A:A
Push-Prev    #  5:  Move end position to Stack-A
SetMemory    #  6:  Place FLOW-head in memory space for offspring
Head-Move    #  7:  Move Write head to flow head position
Nop-C        #  8:
Search       #  9:  Drop flow head at start of copy loop
Inst-Read    # 10:
Inst-Write   # 11: 
Head-Push    # 12:  Get current position of...
Nop-C        # 13:  - Read-Head
If-Equal     # 14:  Test if we are done copying...
Inject       # 15:  ...If so, inject.
Head-Move    # 16:  ...If not, continue with loop.
Nop-A        # 17:
Nop-B        # 18:

Index: avida/current/source/viewers/environment_screen.cc
+++ avida/current/source/viewers/environment_screen.cc
//////////////////////////////////////////////////////////////////////////////
// Copyright (C) 1993 - 2001 California Institute of Technology             //
//                                                                          //
// Read the COPYING and README files, or contact 'avida at alife.org',         //
// before continuing.  SOME RESTRICTIONS MAY APPLY TO USE OF THIS FILE.     //
//////////////////////////////////////////////////////////////////////////////

#include "../main/config.hh"
#include "../main/environment.hh"
#include "../main/genebank.hh"
#include "../main/genotype.hh"
#include "../main/population.hh"
#include "../main/species.hh"
#include "../main/stats.hh"
#include "../main/tasks.hh"
#include "../main/population_cell.hh"
#include "../main/organism.hh"

#include "environment_screen.hh"


using namespace std;


void cEnvironmentScreen::Draw()
{
  SetBoldColor(COLOR_WHITE);
  Print(1, 54, "[ ]               [ ]");
  if (info.GetPauseLevel()) {
    Print(3, 54, "Un-[ ]ause");
    Print(4, 54, "[ ]ext Update");
  } else {
    Print(3, 54, "[ ]ause   ");
    Print(4, 54, "             ");
  }
 
  SetBoldColor(COLOR_CYAN);
  Print(1, 55, "<");
  Print(1, 73, ">");
  Print(5, 54, "[        ]");
  if (info.GetPauseLevel()) {
    Print(3, 58, "P");
    Print(4, 55, "N");
  } else {
    Print(3, 55, "P");
  }
  Print(5, 55, "UP, DOWN");

  if(mode==ENVIRONMENT_MODE_RESOURCE)
    DrawResource();
  else
    DrawReaction();
  Update();
}

void cEnvironmentScreen::DrawResource()
{
  const cResourceLib & res_lib = population.GetEnvironment().GetResourceLib();

  SetBoldColor(COLOR_WHITE);
   
  Print(0, 0, " --Name-- ");
  Print(0, 12, "--Inflow--");
  Print(0, 24, "--Outflow--");
  Print(0, 37, "--Quantity--");
  
  Print(res_lib.GetSize()+3, 2, "Reactions associated with Resource ");
  Print(res_lib.GetSize()+4, 2, "--Name--  --Num Rxns (last update)--  --");
  
  Print(6, 54, "Next Resource");
  
  SetBoldColor(COLOR_CYAN);
  for(int i=0; i<res_lib.GetSize(); i++)
    {
      Print(i+1, 1, res_lib.GetResource(i)->GetName());
      Print(i+1, 12, "%7.2f", res_lib.GetResource(i)->GetInflow());
      Print(i+1, 24, "%7.2f", res_lib.GetResource(i)->GetOutflow());
    }
  if (info.GetPauseLevel()) {
    Print(3, 58, "P");
    Print(4, 55, "N");
  } else {
    Print(3, 55, "P");
  }
  Print(5, 55, "UP, DOWN");
  

  SetColor(COLOR_WHITE);
  Box(0, res_lib.GetSize()+2, Width(), Height()-res_lib.GetSize()-2);

  SetBoldColor(COLOR_YELLOW);
  Print(1, 58, "Resource View");
}

void cEnvironmentScreen::DrawReaction()
{
  const cReactionLib & rxn_lib = population.GetEnvironment().GetReactionLib();

  SetBoldColor(COLOR_WHITE);
   
  Print(0, 0, " --Name-- ");
  //Print(0, 12, "--Inflow--");
  //Print(0, 24, "--Outflow--");
  //Print(0, 37, "--Quantity--");
  
  Print(rxn_lib.GetSize()+3, 2, "Resources associated with Reaction ");
  Print(rxn_lib.GetSize()+4, 2, "--Name--  --Inflow--  --Outflow--  --Quantity--");
  
  Print(6, 54, "Next Reaction");
  
  SetBoldColor(COLOR_CYAN);
  for(int i=0; i<rxn_lib.GetSize(); i++)
    {
      Print(i+1, 1, rxn_lib.GetReaction(i)->GetName());
      //Print(i+1, 12, "%7.2f", res_lib.GetResource(i)->GetInflow());
      //Print(i+1, 24, "%7.2f", res_lib.GetResource(i)->GetOutflow());
    }  

  SetColor(COLOR_WHITE);
  Box(0, rxn_lib.GetSize()+2, Width(), Height()-rxn_lib.GetSize()-2);

  SetBoldColor(COLOR_YELLOW);
  Print(1, 58, "Reaction View");
}

void cEnvironmentScreen::Update()
{
  if(mode==ENVIRONMENT_MODE_RESOURCE)
    UpdateResource();
  else
    UpdateReaction();
  Refresh();
}

void cEnvironmentScreen::UpdateResource()
{
  const cResourceLib & res_lib = population.GetEnvironment().GetResourceLib();
  const cReactionLib & rxn_lib = population.GetEnvironment().GetReactionLib();

  SetBoldColor(COLOR_CYAN);
  //int j=0;
  //int last_count=0;
  for(int i=0; i<population.GetResources().GetSize(); i++)
    {
      Print(i+1, 40, "%7.2f", population.GetResources()[i]);
      //if(population.GetResources()[i]/last_count < population.GetResources()[i].
      //Print(i+2, 65, "%7.2f", population.GetResources()[i]/last_count);
    }
 
  SetBoldColor(COLOR_BLUE);
  Print(res_selection+1, 1, res_lib.GetResource(res_selection)->GetName());
  Print(res_selection+1, 12, "%7.2f", res_lib.GetResource(res_selection)->GetInflow());
  Print(res_selection+1, 24, "%7.2f", res_lib.GetResource(res_selection)->GetOutflow());
  Print(res_selection+1, 40, "%7.2f", population.GetResources()[res_selection]);
 
  int offset=0;

  SetBoldColor(COLOR_CYAN);
  for(int i=0; i<rxn_lib.GetSize(); i++)
    {
      for(int j=0; j<rxn_lib.GetReaction(i)->GetProcesses().GetSize(); j++)
	{
	  if(rxn_lib.GetReaction(i)->GetProcesses().GetPos(j)->GetResource()->GetName() == 
	     res_lib.GetResource(res_selection)->GetName())
	    {
	      Print(population.GetResources().GetSize()+5+offset, 2, 
		    rxn_lib.GetReaction(i)->GetName());
	      offset++;
	    }
	}
    }
  
  SetBoldColor(COLOR_WHITE);
  Print(res_lib.GetSize()+3, 37, "%s", res_lib.GetResource(res_selection)->GetName().GetData());
  Print(res_lib.GetSize()+3, res_lib.GetResource(res_selection)->GetName().GetSize()+37, ":");
  Print(res_lib.GetSize()+3, res_lib.GetResource(res_selection)->GetName().GetSize()+38, "        ");
    
}

void cEnvironmentScreen::UpdateReaction()
{
  const cReactionLib & rxn_lib = population.GetEnvironment().GetReactionLib();
  const cResourceLib & res_lib = population.GetEnvironment().GetResourceLib();

  SetBoldColor(COLOR_CYAN);
  //int j=0;
  //int last_count=0;
  for(int i=0; i<population.GetStats().GetReactions().GetSize(); i++)
    {
      Print(i+1, 40, "%7.2f", population.GetStats().GetReactions()[i]);
      //if(population.GetResources()[i]/last_count < population.GetResources()[i].
      //Print(i+2, 65, "%7.2f", population.GetResources()[i]/last_count);
    }
 
  SetBoldColor(COLOR_BLUE);
  Print(rxn_selection+1, 1, rxn_lib.GetReaction(rxn_selection)->GetName());
  Print(rxn_selection+1, 40, "%7.2f", population.GetStats().GetReactions()[rxn_selection]);
    

  int offset=0;

  SetBoldColor(COLOR_CYAN);
  for(int i=0; i<rxn_lib.GetReaction(rxn_selection)->GetProcesses().GetSize(); i++)
    {
      Print(population.GetStats().GetReactions().GetSize()+5+offset, 2, 
	    rxn_lib.GetReaction(rxn_selection)->GetProcesses().GetPos(i)->GetResource()->GetName());
      Print(population.GetStats().GetReactions().GetSize()+5+offset, 13, "%7.2f",
	    rxn_lib.GetReaction(rxn_selection)->GetProcesses().GetPos(i)->GetResource()->GetInflow());
      Print(population.GetStats().GetReactions().GetSize()+5+offset, 25, "%7.2f",
	    rxn_lib.GetReaction(rxn_selection)->GetProcesses().GetPos(i)->GetResource()->GetOutflow());
      for(int j=0; j<res_lib.GetSize(); j++)
	{
	  if(res_lib.GetResource(j)->GetName() ==
	     rxn_lib.GetReaction(rxn_selection)->GetProcesses().GetPos(i)->GetResource()->GetName())
	    Print(population.GetStats().GetReactions().GetSize()+5+offset, 40, "%7.2f", 
		  population.GetResources()[j]);
	}
      offset++;  
    }
  SetBoldColor(COLOR_WHITE);
  Print(rxn_lib.GetSize()+3, 37, "%s", rxn_lib.GetReaction(rxn_selection)->GetName().GetData());
  Print(rxn_lib.GetSize()+3, rxn_lib.GetReaction(rxn_selection)->GetName().GetSize()+37, ":");
  Print(rxn_lib.GetSize()+3, rxn_lib.GetReaction(rxn_selection)->GetName().GetSize()+38, "        ");
   
}

void cEnvironmentScreen::DoInput(int in_char)
{
  int last_selection;
  const cResourceLib & res_lib = population.GetEnvironment().GetResourceLib();
  const cReactionLib & rxn_lib = population.GetEnvironment().GetReactionLib();
  SetBoldColor(COLOR_CYAN);

  switch (in_char) {
  case KEY_DOWN:
    if(mode==ENVIRONMENT_MODE_RESOURCE ) {
      last_selection=res_selection;
      res_selection++;
      res_selection%=population.GetResources().GetSize();

      Print(last_selection+1, 1, res_lib.GetResource(last_selection)->GetName());
      Print(last_selection+1, 12, "%7.2f", res_lib.GetResource(last_selection)->GetInflow());
      Print(last_selection+1, 24, "%7.2f", res_lib.GetResource(last_selection)->GetOutflow());
    }
    else {
      last_selection=rxn_selection;
      rxn_selection++;
      rxn_selection%=population.GetStats().GetReactions().GetSize();

      Print(last_selection+1, 1, rxn_lib.GetReaction(last_selection)->GetName());
      //Print(last_selection+1, 12, "%7.2f", rxn_lib.GetReaction(last_selection)->GetInflow());
      //Print(last_selection+1, 24, "%7.2f", rxn_lib.GetReaction(last_selection)->GetOutflow());
    }

    Update();
    break;
  case KEY_UP:
    if(mode==ENVIRONMENT_MODE_RESOURCE) {
      last_selection=res_selection;
      res_selection--;
      if(res_selection < 0) res_selection=population.GetResources().GetSize()-1;
   
      Print(last_selection+1, 1, res_lib.GetResource(last_selection)->GetName());
      Print(last_selection+1, 12, "%7.2f", res_lib.GetResource(last_selection)->GetInflow());
      Print(last_selection+1, 24, "%7.2f", res_lib.GetResource(last_selection)->GetOutflow());
    }
    else {
      last_selection=rxn_selection;
      rxn_selection--;
      if(rxn_selection < 0) rxn_selection=population.GetStats().GetReactions().GetSize()-1;
   
      Print(last_selection+1, 1, rxn_lib.GetReaction(last_selection)->GetName());
      //Print(last_selection+1, 12, "%7.2f", rxn_lib.GetReaction(last_selection)->GetInflow());
      //Print(last_selection+1, 24, "%7.2f", rxn_lib.GetReaction(last_selection)->GetOutflow());
    }

    Update();
    break;
  case '>':
  case '<':
    if(mode==ENVIRONMENT_MODE_RESOURCE)
      mode=ENVIRONMENT_MODE_REACTION;
    else
      mode=ENVIRONMENT_MODE_RESOURCE;
    Clear();
    Draw();
    break;
    }
}


Index: avida/current/source/viewers/environment_screen.hh
+++ avida/current/source/viewers/environment_screen.hh
//////////////////////////////////////////////////////////////////////////////
// Copyright (C) 1993 - 2001 California Institute of Technology             //
//                                                                          //
// Read the COPYING and README files, or contact 'avida at alife.org',         //
// before continuing.  SOME RESTRICTIONS MAY APPLY TO USE OF THIS FILE.     //
//////////////////////////////////////////////////////////////////////////////

#ifndef VIEW_ENVIRONMENT_SCREEN_HH
#define VIEW_ENVIRONMENT_SCREEN_HH

#include "text_screen.hh"

class cEnvironmentScreen : public cScreen {
protected:
  cPopulation & population;
  int mode;
  int res_selection;
  int rxn_selection;
  //int task_offset;
  //int task_rows;
  //int task_cols;
  static const int ENVIRONMENT_MODE_RESOURCE = 0;
  static const int ENVIRONMENT_MODE_REACTION = 1;

public:
  cEnvironmentScreen(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),
    population(in_pop) { mode=ENVIRONMENT_MODE_RESOURCE; res_selection=rxn_selection=0; }
    //task_rows = Height() - 16;
    // task_cols = Width() / 20;
  //}
  virtual ~cEnvironmentScreen() { ; }

  // Virtual in base screen...
  void Draw();
  void Update();
  void DoInput(int in_char);

  void DrawResource();
  void DrawReaction();
  void UpdateResource();
  void UpdateReaction();
};

#endif


More information about the Avida-cvs mailing list