protected override IAgent DoAsexualReproduction(IAgent parent, ILocation location)
        {
            if (parent == null) throw new ArgumentNullException("parent");
            if (location == null) throw new ArgumentNullException("location");

            if (parent.IsMultiAgent())
            {
                return DoMulticellularAsexualReproduction(parent, location);
            }

            // Reproduce assuming this agent has a single cell
            var childCell = asexualReproductionInteraction.Interact(parent.Cells[0], null);
            var childAgent = new GridAgent();
            childAgent.Cells.Add(childCell);
            this.RegisterBirth(childAgent, new BirthEvent(location, CurrentGeneration, asexualReproductionInteraction.GetType(), parent.Species));

            this.AddEventToAgent(parent, new ReproductionEvent(location, CurrentGeneration, asexualReproductionInteraction.GetType(), null, childAgent.Species));

            return childAgent;
        }
        private IList<IAgent> DoSexualReproduction(IAgent parent1, IAgent parent2, IInteraction<ICell, ICell, IList<ICell>> interaction, ILocation location)
        {
            if (parent1 == null) throw new ArgumentNullException("parent1");
            if (parent1.Cells.Count == 0) throw new ArgumentException("Agent must have at least one cell", "parent1");
            if (parent2 == null) throw new ArgumentNullException("parent2");
            if (parent2.Cells.Count == 0) throw new ArgumentException("Agent must have at least one cell", "parent2");
            if (interaction == null) throw new ArgumentNullException("interaction");
            if (location == null) throw new ArgumentNullException("location");

            if (parent1.IsMultiAgent() || parent2.IsMultiAgent())
            {
                return DoMulticellularSexualReproduction(parent1, parent2, interaction, location);
            }

            // Reproduce assuming both agents have a single cell
            var childCells = interaction.Interact(parent1.Cells[0], parent2.Cells[0]);

            var child1 = new GridAgent();
            child1.Cells.Add(childCells[0]);
            this.RegisterBirth(child1, new BirthEvent(location, CurrentGeneration, interaction.GetType(), parent1.Species, parent2.Species));

            var child2 = new GridAgent();
            child2.Cells.Add(childCells[1]);
            this.RegisterBirth(child2, new BirthEvent(location, CurrentGeneration, interaction.GetType(), parent1.Species, parent2.Species));

            // Events
            this.AddEventToAgent(parent1, new ReproductionEvent(location, CurrentGeneration, interaction.GetType(), parent2.Species, child1.Species, child2.Species));
            this.AddEventToAgent(parent2, new ReproductionEvent(location, CurrentGeneration, interaction.GetType(), parent1.Species, child1.Species, child2.Species));

            return new[] {child1, child2};
        }