protected override void LoadParametersForGene(IEvolutionState state, int index, IParameter paramBase, IParameter def, String postfix)
        {
            base.LoadParametersForGene(state, index, paramBase, def, postfix);

            bool minValExists = state.Parameters.ParameterExists(paramBase.Push(P_MINGENE).Push(postfix), def.Push(P_MINGENE).Push(postfix));
            bool maxValExists = state.Parameters.ParameterExists(paramBase.Push(P_MAXGENE).Push(postfix), def.Push(P_MAXGENE).Push(postfix));

            if ((maxValExists && !minValExists))
            {
                state.Output.Warning("Max Gene specified but not Min Gene", paramBase.Push(P_MINGENE).Push(postfix), def.Push(P_MINGENE).Push(postfix));
            }

            if (minValExists && !maxValExists)
            {
                state.Output.Warning("Min Gene specified but not Max Gene", paramBase.Push(P_MAXGENE).Push(postfix), def.Push(P_MINGENE).Push(postfix));
            }

            if (minValExists)
            {
                long minVal = state.Parameters.GetLongWithDefault(paramBase.Push(P_MINGENE).Push(postfix), def.Push(P_MINGENE).Push(postfix), 0);

                //check if the value is in range
                if (!InNumericalTypeRange(minVal))
                {
                    state.Output.Error("Min Gene Value out of range for data type " + I_Prototype.GetType().Name,
                                       paramBase.Push(P_MINGENE).Push(postfix),
                                       paramBase.Push(P_MINGENE).Push(postfix));
                }
                else
                {
                    MinGenes[index] = minVal;
                }

                if (DynamicInitialSize)
                {
                    state.Output.WarnOnce("Using dynamic initial sizing, but per-gene or per-segment min-gene declarations.  This is probably wrong.  You probably want to use global min/max declarations.",
                                          paramBase.Push(P_MINGENE).Push(postfix),
                                          paramBase.Push(P_MINGENE).Push(postfix));
                }
            }

            if (minValExists)
            {
                long maxVal = state.Parameters.GetLongWithDefault(paramBase.Push(P_MAXGENE).Push(postfix), def.Push(P_MAXGENE).Push(postfix), 0);

                //check if the value is in range
                if (!InNumericalTypeRange(maxVal))
                {
                    state.Output.Error("Max Gene Value out of range for data type " + I_Prototype.GetType().Name,
                                       paramBase.Push(P_MAXGENE).Push(postfix),
                                       paramBase.Push(P_MAXGENE).Push(postfix));
                }
                else
                {
                    MaxGenes[index] = maxVal;
                }

                if (DynamicInitialSize)
                {
                    state.Output.WarnOnce("Using dynamic initial sizing, but per-gene or per-segment max-gene declarations.  This is probably wrong.  You probably want to use global min/max declarations.",
                                          paramBase.Push(P_MAXGENE).Push(postfix),
                                          paramBase.Push(P_MAXGENE).Push(postfix));
                }
            }

            // MUTATION

            String mtype   = state.Parameters.GetStringWithDefault(paramBase.Push(P_MUTATIONTYPE).Push(postfix), def.Push(P_MUTATIONTYPE).Push(postfix), null);
            int    mutType = -1;

            if (mtype == null)
            {
            }                       // we're cool
            else if (mtype.Equals(V_RESET_MUTATION, StringComparison.InvariantCultureIgnoreCase))
            {
                mutType = MutationType[index] = C_RESET_MUTATION;
            }
            else if (mtype.Equals(V_RANDOM_WALK_MUTATION, StringComparison.InvariantCultureIgnoreCase))
            {
                mutType = MutationType[index] = C_RANDOM_WALK_MUTATION;
                state.Output.WarnOnce("Integer Random Walk Mutation used in IntegerVectorSpecies.  Be advised that during initialization these genes will only be set to integer values.");
            }
            else
            {
                state.Output.Error("IntegerVectorSpecies given a bad mutation type: " + mtype,
                                   paramBase.Push(P_MUTATIONTYPE).Push(postfix), def.Push(P_MUTATIONTYPE).Push(postfix));
            }


            if (mutType == C_RANDOM_WALK_MUTATION)
            {
                if (state.Parameters.ParameterExists(paramBase.Push(P_RANDOM_WALK_PROBABILITY).Push(postfix), def.Push(P_RANDOM_WALK_PROBABILITY).Push(postfix)))
                {
                    RandomWalkProbability[index] = state.Parameters.GetDoubleWithMax(paramBase.Push(P_RANDOM_WALK_PROBABILITY).Push(postfix), def.Push(P_RANDOM_WALK_PROBABILITY).Push(postfix), 0.0, 1.0);
                    if (RandomWalkProbability[index] <= 0)
                    {
                        state.Output.Error("If it's going to use random walk mutation as a per-gene or per-segment type, IntegerVectorSpecies must a random walk mutation probability between 0.0 and 1.0.",
                                           paramBase.Push(P_RANDOM_WALK_PROBABILITY).Push(postfix), def.Push(P_RANDOM_WALK_PROBABILITY).Push(postfix));
                    }
                }
                else
                {
                    state.Output.Error("If IntegerVectorSpecies is going to use polynomial mutation as a per-gene or per-segment type, either the global or per-gene/per-segment random walk mutation probability must be defined.",
                                       paramBase.Push(P_RANDOM_WALK_PROBABILITY).Push(postfix), def.Push(P_RANDOM_WALK_PROBABILITY).Push(postfix));
                }

                if (state.Parameters.ParameterExists(paramBase.Push(P_MUTATION_BOUNDED).Push(postfix), def.Push(P_MUTATION_BOUNDED).Push(postfix)))
                {
                    MutationIsBounded[index] = state.Parameters.GetBoolean(paramBase.Push(P_MUTATION_BOUNDED).Push(postfix), def.Push(P_MUTATION_BOUNDED).Push(postfix), true);
                }
                else if (!_mutationIsBoundedDefined)
                {
                    state.Output.Fatal("If IntegerVectorSpecies is going to use gaussian, polynomial, or integer random walk mutation as a per-gene or per-segment type, the mutation bounding must be defined.",
                                       paramBase.Push(P_MUTATION_BOUNDED).Push(postfix), def.Push(P_MUTATION_BOUNDED).Push(postfix));
                }
            }
        }
        public override void Setup(IEvolutionState state, IParameter paramBase)
        {
            IParameter def = DefaultBase;

            SetupGenome(state, paramBase);

            // create the arrays
            MinGenes              = new long[GenomeSize + 1];
            MaxGenes              = new long[GenomeSize + 1];
            MutationType          = Fill(new int[GenomeSize + 1], -1);
            MutationIsBounded     = new bool[GenomeSize + 1];
            RandomWalkProbability = new double[GenomeSize + 1];


            // LOADING GLOBAL MIN/MAX GENES
            long minGene = state.Parameters.GetLongWithDefault(paramBase.Push(P_MINGENE), def.Push(P_MINGENE), 0);
            long maxGene = state.Parameters.GetLong(paramBase.Push(P_MAXGENE), def.Push(P_MAXGENE), minGene);

            if (maxGene < minGene)
            {
                state.Output.Fatal("IntegerVectorSpecies must have a default min-gene which is <= the default max-gene",
                                   paramBase.Push(P_MAXGENE), def.Push(P_MAXGENE));
            }
            Fill(MinGenes, minGene);
            Fill(MaxGenes, maxGene);


            /// MUTATION


            String mtype   = state.Parameters.GetStringWithDefault(paramBase.Push(P_MUTATIONTYPE), def.Push(P_MUTATIONTYPE), null);
            int    mutType = C_RESET_MUTATION;

            if (mtype == null)
            {
                state.Output.Warning("No global mutation type given for IntegerVectorSpecies, assuming 'reset' mutation",
                                     paramBase.Push(P_MUTATIONTYPE), def.Push(P_MUTATIONTYPE));
            }
            else if (mtype.Equals(V_RESET_MUTATION, StringComparison.InvariantCultureIgnoreCase))
            {
                mutType = C_RESET_MUTATION; // redundant
            }
            else if (mtype.Equals(V_RANDOM_WALK_MUTATION, StringComparison.InvariantCultureIgnoreCase))
            {
                mutType = C_RANDOM_WALK_MUTATION;
            }
            else
            {
                state.Output.Fatal("IntegerVectorSpecies given a bad mutation type: "
                                   + mtype, paramBase.Push(P_MUTATIONTYPE), def.Push(P_MUTATIONTYPE));
            }
            Fill(MutationType, mutType);

            if (mutType == C_RANDOM_WALK_MUTATION)
            {
                double randWalkProb = state.Parameters.GetDoubleWithMax(paramBase.Push(P_RANDOM_WALK_PROBABILITY), def.Push(P_RANDOM_WALK_PROBABILITY), 0.0, 1.0);
                if (randWalkProb <= 0)
                {
                    state.Output.Fatal("If it's going to use random walk mutation as its global mutation type, IntegerVectorSpecies must a random walk mutation probability between 0.0 and 1.0.",
                                       paramBase.Push(P_RANDOM_WALK_PROBABILITY), def.Push(P_RANDOM_WALK_PROBABILITY));
                }
                Fill(RandomWalkProbability, randWalkProb);

                if (!state.Parameters.ParameterExists(paramBase.Push(P_MUTATION_BOUNDED), def.Push(P_MUTATION_BOUNDED)))
                {
                    state.Output.Warning("IntegerVectorSpecies is using gaussian, polynomial, or integer randomwalk mutation as its global mutation type, but " + P_MUTATION_BOUNDED + " is not defined.  Assuming 'true'");
                }
                bool mutIsBounded = state.Parameters.GetBoolean(paramBase.Push(P_MUTATION_BOUNDED), def.Push(P_MUTATION_BOUNDED), true);
                Fill(MutationIsBounded, mutIsBounded);
                _mutationIsBoundedDefined = true;
            }


            base.Setup(state, paramBase);

            // VERIFY
            for (var x = 0; x < GenomeSize; x++)
            {
                if (MaxGenes[x] < MinGenes[x])
                {
                    state.Output.Fatal("IntegerVectorSpecies must have a min-gene[" + x + "] which is <= the max-gene[" + x + "]");
                }

                // check to see if these longs are within the data type of the particular individual
                if (!InNumericalTypeRange(MinGenes[x]))
                {
                    state.Output.Fatal("This IntegerVectorSpecies has a prototype of the kind: "
                                       + I_Prototype.GetType().FullName + ", but doesn't have a min-gene[" + x
                                       + "] value within the range of this prototype's genome's data types");
                }

                if (!InNumericalTypeRange(MaxGenes[x]))
                {
                    state.Output.Fatal("This IntegerVectorSpecies has a prototype of the kind: "
                                       + I_Prototype.GetType().FullName + ", but doesn't have a max-gene[" + x
                                       + "] value within the range of this prototype's genome's data types");
                }
            }

            /*
             * //Debugging
             * for(int i = 0; i < minGenes.length; i++)
             * System.out.PrintLn("Min: " + minGenes[i] + ", Max: " + maxGenes[i]);
             */
        }