///-------------------------------------------------------------------------------------------------
        /// <summary> Limit and reallocate growth. </summary>
        ///
        /// <remarks> This is a standard routine to limit growth for some providers and reallocate lost growth potential to other providers.
        ///           Tries to keep total regional reallocated numbers the same as the total regional projected regional population numbers.
        ///           The Being managed array
        ///           and the trigger array need to be set before call to this routine.  After the call the users code must set the population parameters.  The following code provides and example.
        ///           <code>
        ///                     ProviderIntArray IsTriggered = new ProviderIntArray(0);
        ///                     for (int i = 0; i < YearForZero.Length; i++)
        ///                        if (TestUnassured(YearForZero[i], WSim))
        ///                        {
        ///                            ConsecutiveUnassuredYears[i]++;
        ///                            if (ConsecutiveUnassuredYears[i]>FMaxUnassuredYears)
        ///                            {
        ///                                // mark as triggered
        ///                                 IsTriggered[i]=0;
        ///                                // Once triggered always being managed
        ///                                BeingManaged[i] = 1;
        ///                        }
        ///                        else
        ///                        {
        ///                            ConsecutiveUnassuredYears[i] = 0;
        ///                        }
        ///
        ///                    PopulationClass.LimitAndReallocateGrowth(WSim, year, BeingManaged, IsTriggered, ref NewPopOn, ref NewPopOff);
        ///
        ///                }
        ///                // Ok Set PopOverride Values
        ///                for (int i = 0; i < NewPopOn.Length; i++)
        ///                {
        ///                    WSim.Population_Override_On[i] = NewPopOn[i];
        ///                }
        ///                for (int i = 0; i < NewPopOff.Length; i++)
        ///                {
        ///                    WSim.Population_Override_Other[i] = NewPopOff[i];
        ///                }
        ///   </code>
        ///                    </remarks>
        ///
        /// <param name="WSim">         The WaterSimManager for simulation. </param>
        /// <param name="year">         The year of simulation. </param>
        /// <param name="BeingManaged"> A ProviderIntArray indicating providers being managed, 1 = use projected growth rate, 0= use projected pop numbers . </param>
        /// <param name="TriggerCnt">  A ProviderIntArray indicating providers being limited (ie no growth) >0=Limit,  0 = Do not limit. </param>

        /// <param name="NewPopOn">     [in,out] The new Onproject POP numbers. </param>
        /// <param name="NewPopOff">    [in,out] The new Other (off project) POP numbers. </param>
        ///
        ///-------------------------------------------------------------------------------------------------

        static public void LimitAndReallocateGrowth(WaterSimManager WSim, int year, ProviderIntArray BeingManaged, ProviderIntArray Triggered, ref ProviderIntArray NewPopOn, ref ProviderIntArray NewPopOff)
        {
            ProviderIntArray LastYearOnPop  = WSim.Population_On_Project.getvalues();
            ProviderIntArray LastYearOffPop = WSim.Population_Other.getvalues();

            ProviderIntArray PulledPopOn   = WSim.Projected_OnProject_Pop.getvalues();
            ProviderIntArray PulledPopOff  = WSim.Projected_Other_Pop.getvalues();
            bool             ReallocatePop = false;


            for (int i = 0; i < NewPopOn.Length; i++)
            {
                if (Triggered[i] > 0)
                {
                    ReallocatePop = true;
                    NewPopOn[i]   = LastYearOnPop[i];
                    NewPopOff[i]  = LastYearOffPop[i];
                }
                else
                if (BeingManaged[i] > 0)
                {
                    ReallocatePop = true;
                    double LastOn  = Convert.ToDouble(LastYearOnPop[i]);
                    double RateOn  = WSim.PopData.GetYearRatePopOnData(year).Values[i];
                    double LastOff = Convert.ToDouble(LastYearOffPop[i]);
                    double RateOff = WSim.PopData.GetYearRatePopOffData(year).Values[i];
                    int    Addon   = Convert.ToInt32(LastOn * RateOn);
                    int    Addoff  = Convert.ToInt32(LastOff * RateOff);
                    NewPopOff[i] = Addoff;
                    NewPopOn[i]  = Addon;
                }
                else
                {
                    // Check and see if on trajectory for higher
                    if (PulledPopOn[i] > LastYearOnPop[i])
                    {
                        NewPopOn[i] = PulledPopOn[i];
                    }
                    else
                    {
                        NewPopOn[i] = LastYearOnPop[i];
                    }
                    // Check and see if on trajectory for higher
                    if (PulledPopOff[i] > LastYearOffPop[i])
                    {
                        NewPopOff[i] = PulledPopOff[i];
                    }
                    else
                    {
                        NewPopOff[i] = LastYearOffPop[i];
                    }
                }
            }  // For newPop
            // OK Now reallocate unused growth

            if (ReallocatePop)
            // Only reason not doing this is if no one has been ever been triggered to stop growth
            {
                // Calc Total Potential growth and Modified Growth
                // On Possible Total
                int TotalPossibleOnGrowth = 0;

                foreach (int value in PulledPopOn.Values)
                {
                    TotalPossibleOnGrowth += value;
                }
                // off Possible Total
                int TotalPossibleOffGrowth = 0;
                foreach (int value in PulledPopOff.Values)
                {
                    TotalPossibleOffGrowth += value;
                }
                // on Actual Modified
                int TotalModifiedOnGrowth = 0;
                foreach (int value in NewPopOn.Values)
                {
                    TotalModifiedOnGrowth += value;
                }
                // off Possible Total
                int TotalModifiedOffGrowth = 0;
                foreach (int value in NewPopOff.Values)
                {
                    TotalModifiedOffGrowth += value;
                }
                // Calculate Difference

                double PopDifferenceOn  = Convert.ToDouble(TotalPossibleOnGrowth - TotalModifiedOnGrowth);
                double PopDifferenceOff = Convert.ToDouble(TotalPossibleOffGrowth - TotalModifiedOffGrowth);

                // Calculate Totals of NonDeficit People
                double TotalNotLimitedOn  = 0;
                double TotalNotLimitedOff = 0;
                for (int i = 0; i < NewPopOff.Length; i++)
                {
                    if (Triggered[i] > 0)
                    {
                        TotalNotLimitedOff += NewPopOff[i];
                    }
                }
                for (int i = 0; i < NewPopOn.Length; i++)
                {
                    if (Triggered[i] > 0)
                    {
                        TotalNotLimitedOn += NewPopOn[i];
                    }
                }
                // Calculate Ratios for those not in deficit
                ProviderDoubleArray ShareOn  = new ProviderDoubleArray(0);
                ProviderDoubleArray ShareOff = new ProviderDoubleArray(0);
                for (int i = 0; i < NewPopOn.Length; i++)
                {
                    if ((TotalNotLimitedOn > 0) && (Triggered[i] == 0))
                    {
                        ShareOn[i] = Convert.ToDouble(NewPopOn[i]) / TotalNotLimitedOn;
                    }
                }
                for (int i = 0; i < NewPopOff.Length; i++)
                {
                    if ((TotalNotLimitedOff > 0) && (Triggered[i] == 0))
                    {
                        ShareOff[i] = Convert.ToDouble(NewPopOff[i]) / TotalNotLimitedOff;
                    }
                }
                // Now allocate Extra growth based on ratio
                for (int i = 0; i < NewPopOff.Length; i++)
                {
                    if (Triggered[i] == 0)
                    {
                        // Calculate how much to add this year
                        int addmore = Convert.ToInt32(PopDifferenceOff * ShareOff[i]);
                        // Re add this added amount.
                        NewPopOff[i] += addmore;
                    }
                }
                for (int i = 0; i < NewPopOn.Length; i++)
                {
                    if (Triggered[i] == 0)
                    {
                        // Calculate how much to add this year
                        int addmore = Convert.ToInt32(PopDifferenceOn * ShareOn[i]);
                        // Re add this added amount.
                        NewPopOn[i] += addmore;
                    }
                }
            }
        }
        bool LoadAllPopData(string DataPathName, ref string errString)
        {
            bool test = false;

            // Clear the OnPop list
            PopOnByYearList.Clear();
            // Build Pathname
            string filename = AddFileName(DataPathName, FortranPopOnFilename);

            // Load the OnPop data
            test = LoadPopDataFile(filename, ref errString, ref PopOnByYearList);
            // Continue if no error
            if (test)
            {
                // Clear the off pop list
                PopOffByYearList.Clear();
                // Build Filename
                filename = AddFileName(DataPathName, FortranPopOffFilename);
                // load OffPop data
                test = LoadPopDataFile(filename, ref errString, ref PopOffByYearList);
                // continue if no error
                if (test)
                {
                    // Calculate Total Pop
                    PopTotalByYearList.Clear();
                    // Cycle through each year's provider array for pop list
                    for (int i = 0; i < PopOnByYearList.Count; i++)
                    {
                        ProviderIntArray Tot = new ProviderIntArray(0);
                        // Add on and off for each provider
                        for (int j = 0; j < Tot.Length; j++)
                        {
                            Tot.Values[j] = PopOnByYearList[i].Values[j] + PopOffByYearList[i].Values[j];
                        }
                        // add total to the pop year list
                        PopTotalByYearList.Add(Tot);
                    }
                    // Calculate Growth Rate
                    // Calculate Total Pop
                    PopOnRateByYearList.Clear();
                    PopOffRateByYearList.Clear();
                    // Cycle through each year's provider array for pop list
                    for (int i = 1; i < PopTotalByYearList.Count; i++)
                    {
                        ProviderDoubleArray Rate = new ProviderDoubleArray(0.0);
                        // Add on for each provider
                        for (int j = 0; j < Rate.Length; j++)
                        {
                            double LastYearOn = Convert.ToDouble(PopOnByYearList[i - 1].Values[j]);
                            double ThisYearOn = Convert.ToDouble(PopOnByYearList[i].Values[j]);
                            if (LastYearOn > 0.0)
                            {
                                double pctchange = (ThisYearOn - LastYearOn) / LastYearOn;
                                Rate[j] = 1 + pctchange;
                                //if (pctchange > .05)
                                //    pctchange = .05;
                            }
                            else
                            {
                                Rate[j] = 1.0;
                            }
                        }
                        // add total to the pop On year list
                        PopOnRateByYearList.Add(Rate);

                        // Add off and off for each provider
                        for (int j = 0; j < Rate.Length; j++)
                        {
                            double LastYearOff = Convert.ToDouble(PopOffByYearList[i - 1].Values[j]);
                            double ThisYearOff = Convert.ToDouble(PopOffByYearList[i].Values[j]);
                            if (LastYearOff > 0.0)
                            {
                                double pctchange = (ThisYearOff - LastYearOff) / LastYearOff;
                                Rate[j] = 1 + pctchange;
                                //if (pctchange > .05)
                                //    pctchange = .05;
                            }
                            else
                            {
                                Rate[j] = 1.0;
                            }
                        }
                        // add total to the pop Off year list
                        PopOffRateByYearList.Add(Rate);
                    }
                }
            }
            if (test == false)
            {
                PopOffByYearList.Clear();
                PopOnByYearList.Clear();
                PopTotalByYearList.Clear();
                PopOnRateByYearList.Clear();
                PopOffRateByYearList.Clear();
            }
            return(test);
        }