/// <summary>
        /// Validates CA for usage submittal. Assumes current reporting year.
        /// </summary>
        /// <param name="ca"></param>
        /// <param name="errors"></param>
        /// <returns></returns>
        protected bool ValidateContiguousAcres(JsonContiguousAcres ca, out List<string> errors)
        {
            errors = new List<string>();
            /* MWinckler.20130202: This set of validation is written as CA-specific, but it is
             * attempting to validate meter-specific conditions. This validation needs to be
             * rewritten to validate meter readings, and also not rely on calculated boolean
             * values sent from the (untrustworthy) client. Rely on the actual submitted meter
             * readings and user inputs - we have them all here.

            if (ca.isFakingValidReadings)
            {
                if(!ca.userRevisedVolume)
                    errors.Add("The end reading for one of the meters is not in the valid reporting range of December 15 to January 15.");
            }
            if (ca.notEnoughReadingsForAllMeters) // This also allows user override
            {
                if (!ca.userRevisedVolume)
                    errors.Add("One of the meters does not have enough valid readings for volume calculation.");
            }
            if (!ca.hasValidBeginReadings) // This also allows user override
            {
                if (!ca.userRevisedVolume)
                    errors.Add("One of the meters does not have valid begin readings for volume calculation.");
            }
             */
            foreach (var mr in ca.meterReadings)
            {

                // If this is an annual reading or if the user supplied a revised volume, this validation doesn't matter.
                if (!mr.Value.readings.Any(x => x.isAnnualTotalReading)
                    && mr.Value.userRevisedVolume.GetValueOrDefault(0) <= 0)
                {
                    if (mr.Value.readings.Length < 2)
                    {
                        // Too few readings.
                        errors.Add("One of the meters does not have enough valid readings for volume calculation.");
                    } else if (!mr.Value.readings.Any(x => x.isValidBeginReading)) {
                        // Need both a valid begin and a valid end reading.
                        // Note that the above check is not good - it depends on a value
                        // sent by the client.
                        // TODO: Refactor this to not rely on .isValidBeginReading; get
                        // the values needed to validate meter reading against the database
                        // using the methods in ReportingDalc.
                        errors.Add("One of the meters does not have valid begin readings for volume calculation.");
                    } else if (!mr.Value.readings.Any(x => x.isValidEndReading)) {
                        // TODO: See above comment regarding trusting vlient values.
                        errors.Add("One of the meters does not have valid ending readings for volume calculation.");
                    }
                }
            }

            // Ensure the CA actually exists in the database.
            if (!new GisDalc().ContiguousAcresExists(ca.number)) {
                errors.Add("The specified contiguous area (ID: " + ca.number + ") does not exist.");
            } else {
                // (the remainder of validation is only useful if the CA actually exists)

                // Verify that the user is actually associated with the CA
                if (!new GisDalc().OwnsContiguousAcres(ActualUser, ca.number)) {
                    errors.Add("Records show that you do not own the specified contiguous acres. You may not record banked water for this area.");
                    return false;
                }

                // Ensure the CA is for the current reporting year.
                if (ca.year != CurrentReportingYear) {
                    errors.Add("You cannot submit usage reports for previous operating years.");
                }

                // Check to see if the CA has already been submitted.
                if (new ReportingDalc().IsSubmitted(ca.number, CurrentReportingYear)) {
                    errors.Add("The usage report has already been submitted for this contiguous area in this reporting year.");
                }

                if (ca.annualUsageSummary.contiguousArea <= 0) {
                    errors.Add("The contiguous area has no acreage defined!");
                }

                foreach (var mr in ca.meterReadings) {
                    if (mr.Value.acceptCalculation) {
                        if (mr.Value.calculatedVolumeGallons < 0) {
                            errors.Add("Meter ID " + mr.Key.ToString() + " has an invalid volume.");
                        }
                    } else {
                        if (mr.Value.userRevisedVolume <= 0) {
                            errors.Add("Meter ID " + mr.Key.ToString() + " has an invalid user-revised volume.");
                        }
                    }
                }

                if (ca.annualUsageSummary.desiredBankInches < 0) {
                    errors.Add("Desired water bank value cannot be negative.");
                }

                // Retrieve allowable application rate for this year
                // It's also on the submitted CA JSON, but we cannot
                // trust the client here!
                var rdalc = new ReportingDalc();
                var allowableRate = rdalc.GetAllowableProductionRate(CurrentReportingYear);
                if (ca.annualUsageSummary.desiredBankInches > allowableRate) {
                    errors.Add(string.Format("You cannot bank more than {0} inches for this reporting year.", allowableRate));
                }

                // Check all associated wells
                foreach (var well in ca.wells) {
                    if (well.meterInstallationIds.Length == 0) {
                        // Check to see if there's already been a user error response
                        if (!rdalc.IsWellErrorResponseRecorded(well.id, ActualUser.ActingAsUserId ?? ActualUser.Id)) {
                            errors.Add("Well #" + well.permitNumber + " has no associated meters.");
                        }
                    }
                }

                // Retrieve previous banked water values for the CA.
                // (These are on the ca object, but we can't trust the client.)
                var bankHistory = new ReportingDalc().GetHistoricalBankedWater(ca.number);
                double prevBank = bankHistory.Where(x => x.year == CurrentReportingYear - 1).Select(x => x.bankedInches).DefaultIfEmpty(0).First();//mjia: round banked water to the 10ths.
                int avgAppRate = (int)(ca.annualUsageSummary.annualVolume / ca.annualUsageSummary.contiguousArea);
                int surplusSubtotal = ca.annualUsageSummary.allowableApplicationRate - avgAppRate;
                var surplusTotal = prevBank + surplusSubtotal;
                if (ca.annualUsageSummary.desiredBankInches > 0 && ca.annualUsageSummary.desiredBankInches > surplusTotal) {
                    errors.Add("You cannot bank more water than your cumulative available total (previous year's banked inches plus this year's surplus/deficit).");
                }

            }

            return errors.Count == 0;
        }