/// <summary>
        /// Method to Mutate the specified child in derived classes. The method would not normally
        /// be called directly. It will be called by the framework as required.
        /// </summary>
        /// <param name="child"></param>
        protected override void Mutate(Chromosome child)
        {
            // this method calls the base class later which handles elites
            // duplicates are handled here

            Chromosome childToMutate = null;

            if (AllowDuplicates)
            {
                childToMutate = child;
            }
            else
            {
                //We have to clone the chromosome before we mutate it as it may
                //not be usable i.e. if it is a duplicate if we didn't clone it
                //and we created a duplicate through mutation we would have to
                //undo the mutation. This way is easier.
                childToMutate = child.DeepClone();
            }

            //call the default mutation behaviour, this will inturn call the abstract
            //class 'MutateGene' implemented in this class below.
            base.Mutate(childToMutate);

            //only add the mutated chromosome if it does not exist otherwise do nothing
            if (!AllowDuplicates && !NewPopulation.SolutionExists(childToMutate))
            {
                //swap existing genes for the mutated onese
                child.Genes = childToMutate.Genes;
            }
        }
        /// <summary>
        /// Adds a child to the new population depending upon the criteria set in relation to replacement
        /// method and duplicate handling. The method updates the evaluation count and returns true if a
        /// child was added to the new population.
        /// </summary>
        /// <param name="child"></param>
        /// <returns></returns>
        private bool AddChild(Chromosome child)
        {
            var result = false;

            if (_replacementMethodS == ReplacementMethod.DeleteLast)
            {
                child.Evaluate(FitnessFunction);
                _evaluations++;

                if (child.Genes != null && child.Fitness > CurrentPopulation.MinimumFitness)
                {
                    //add the child if there is still space
                    if (AllowDuplicates || !NewPopulation.SolutionExists(child))
                    {
                        //add the new child and remove the last
                        NewPopulation.Solutions.Add(child);
                        if (NewPopulation.Solutions.Count > _currentPopulationSize)
                        {
                            NewPopulation.Solutions.Sort();
                            NewPopulation.Solutions.RemoveAt(_currentPopulationSize - 1);
                            result = true;
                        }
                        else
                        {
                            //we return true whether we actually added or not what we are effectively
                            //doing here is adding the original child from the current solution
                            result = true;
                        }
                    }
                }
            }
            else
            {
                //we need to cater for the user switching from delete last to Generational Replacement
                //in this scenrio we will have a full population but with still some children to generate
                if (NewPopulation.Solutions.Count + _numberOfChildrenToGenerate > _currentPopulationSize)
                {
                    //assume all done for this generation
                    _numberOfChildrenToGenerate = 0;
                    return(false);
                }

                if (child.Genes != null)
                {
                    //add the child if there is still space
                    if (this.AllowDuplicates || !NewPopulation.SolutionExists(child))
                    {
                        NewPopulation.Solutions.Add(child);
                        result = true;
                    }
                }
            }
            return(result);
        }