/// <summary>
        /// Changes the given genome by mutating the gene corresponding to the given <see cref="IParameterNode" />.
        /// </summary>
        /// <param name="genome">The genome to mutate. Will be modified.</param>
        /// <param name="parameterNode">Specification of the parameter / gene to mutate.</param>
        protected void MutateParameter(Genome genome, IParameterNode parameterNode)
        {
            var currentValue = genome.GetGeneValue(parameterNode.Identifier);
            var mutatedValue = parameterNode.Domain.MutateGeneValue(
                currentValue,
                this._mutationVariancePercentage);

            genome.SetGene(parameterNode.Identifier, mutatedValue);
        }
        /// <summary>
        /// Checks whether the given genome matches the <see cref="_parameterTree" />.
        /// </summary>
        /// <param name="genome">The genome to check.</param>
        /// <returns>Whether or not the genome matches the parameter tree.</returns>
        private bool CheckAgainstParameterTree(Genome genome)
        {
            // For each parameter:
            foreach (var parameterNode in this._parameterNodes)
            {
                // Check that fitting gene's value is legal.
                var value = genome.GetGeneValue(parameterNode.Identifier);
                if (!parameterNode.Domain.ContainsGeneValue(value))
                {
                    return(false);
                }
            }

            // All parameters exist in genome and their values are legal.
            return(true);
        }
        /// <summary>
        /// Sets the value for the specified gene on the given child,
        /// respecting its parents and the latest parameter origin.
        /// </summary>
        /// <param name="node">
        /// Specifies the gene to set the value for.
        /// Is allowed to be an <see cref="AndNode" />. In this case, nothing happens.
        /// </param>
        /// <param name="parent1">The first parent.</param>
        /// <param name="parent2">The second parent.</param>
        /// <param name="child">The child. Genome will be modified.</param>
        /// <param name="lastParameterOrigin">
        /// The latest parameter origin.
        /// Influences the probability which parent's gene the child inherits.
        /// </param>
        /// <returns>
        /// The origin of the inherited gene value.
        /// For an <see cref="AndNode" />, returns the given parameter origin.
        /// </returns>
        private ParameterOrigin SetGeneValue(
            IParameterTreeNode node,
            Genome parent1,
            Genome parent2,
            Genome child,
            ParameterOrigin lastParameterOrigin = ParameterOrigin.Open)
        {
            // If the node is not a parameter node, we do not have to set a value.
            // The parameter origin does not change.
            var nodeAsParameter = node as IParameterNode;

            if (nodeAsParameter == null)
            {
                return(lastParameterOrigin);
            }

            // If it is a parameter node, find the parents' gene values.
            var parameterName    = nodeAsParameter.Identifier;
            var parent1GeneValue = parent1.GetGeneValue(parameterName);
            var parent2GeneValue = parent2.GetGeneValue(parameterName);

            // If they are equal and the last parameter's origin is open, set child's parameter value to it
            // and keep the origin.
            if (lastParameterOrigin == ParameterOrigin.Open && object.Equals(parent1GeneValue, parent2GeneValue))
            {
                child.SetGene(parameterName, parent1GeneValue);
                return(lastParameterOrigin);
            }

            // Otherwise, randomly decide on one of the two parents.
            // The probability for the parents is dependent on the last parameter's origin.
            double probabilityForFirstParent;

            switch (lastParameterOrigin)
            {
            case ParameterOrigin.FirstParent:
                probabilityForFirstParent = 1 - this._crossoverSwitchProbability;
                break;

            case ParameterOrigin.SecondParent:
                probabilityForFirstParent = this._crossoverSwitchProbability;
                break;

            case ParameterOrigin.Open:
                probabilityForFirstParent = 0.5;
                break;

            default:
                throw new ArgumentException($"Parameter origin {lastParameterOrigin} is unknown.");
            }

            // Throw a (biased) coin and decide on one parent to inherit the gene value from.
            var useFirstParent = Randomizer.Instance.Decide(probabilityForFirstParent);

            if (useFirstParent)
            {
                child.SetGene(parameterName, parent1GeneValue);
                return(ParameterOrigin.FirstParent);
            }

            child.SetGene(parameterName, parent2GeneValue);
            return(ParameterOrigin.SecondParent);
        }