/// <summary>
        /// Creates a new ProjectServiceValidationEntity.
        /// </summary>
        /// <param name="updatedProject">The updated project.</param>
        /// <param name="projectToUpdate">The project to be updated.</param>
        /// <param name="locationsExist">The boolean value indicating whether all locations exist in the system.</param>
        /// <param name="categoriesExist">The boolean value indicating whether all categories exist in the system.</param>
        /// <param name="objectivesExist">The boolean value indicating whether all objectives exist in the system.</param>
        /// <param name="newInactiveLocations">The ids of locations that are inactive and were not previously set on the project.</param>
        /// <param name="goalsExist">The boolean value indicating whether all goals exist in the system.</param>
        /// <param name="themesExist">The boolean value indicating whether all themes exist in the system.</param>
        /// <param name="pointsOfContactExist">the boolean valud indicating whether all points of contact in the system.</param>
        /// <param name="numberOfCategories">The number of categories.</param>
        /// <param name="numberOfObjectives">The number of objectives.</param>
        /// <param name="officeSettings">The office settings.</param>
        /// <param name="allowedCategoryIds">The category ids the project can be assigned as deteremined by the parent program.</param>
        /// <param name="allowedObjectiveIds">The objective ids the project can be assigned as determined by the parent program.</param>
        /// <param name="regionLocationTypeIds">The location type ids for the given project regions.</param>
        public ProjectServiceUpdateValidationEntity(
            PublishedProject updatedProject,
            Project projectToUpdate,
            List <int> newInactiveLocations,
            bool goalsExist,
            bool themesExist,
            bool pointsOfContactExist,
            bool categoriesExist,
            bool objectivesExist,
            bool locationsExist,
            int numberOfObjectives,
            int numberOfCategories,
            IEnumerable <int> allowedCategoryIds,
            IEnumerable <int> allowedObjectiveIds,
            IEnumerable <int> regionLocationTypeIds,
            OfficeSettings officeSettings,
            IEnumerable <int> allowedThemeIds,
            IEnumerable <int> allowedGoalIds)
        {
            Contract.Requires(updatedProject != null, "The updated project must not be null.");
            Contract.Requires(projectToUpdate != null, "The project to update must not be null.");

            var updatedProjectStatus = ProjectStatus.GetStaticLookup(updatedProject.ProjectStatusId);

            if (updatedProjectStatus == null)
            {
                throw new UnknownStaticLookupException(String.Format("The project status with id [{0}] is not recognized.", updatedProject.ProjectStatusId));
            }
            Contract.Assert(ProjectStatus.GetStaticLookup(projectToUpdate.ProjectStatusId) != null, "The project to update should have a valid project status.");
            this.Name                    = updatedProject.Name;
            this.Description             = updatedProject.Description;
            this.GoalsExist              = goalsExist;
            this.ThemesExist             = themesExist;
            this.LocationsExist          = locationsExist;
            this.PointsOfContactExist    = pointsOfContactExist;
            this.CategoriesExist         = categoriesExist;
            this.ObjectivesExist         = objectivesExist;
            this.UpdatedProjectStatusId  = updatedProject.ProjectStatusId;
            this.SevisOrgId              = updatedProject.SevisOrgId;
            this.OriginalProjectStatusId = projectToUpdate.ProjectStatusId;
            this.StartDate               = updatedProject.StartDate;
            this.EndDate                 = updatedProject.EndDate;
            this.NumberOfCategories      = numberOfCategories;
            this.NumberOfObjectives      = numberOfObjectives;
            this.OfficeSettings          = officeSettings;
            this.CategoryIds             = updatedProject.CategoryIds;
            this.ObjectiveIds            = updatedProject.ObjectiveIds;
            this.AllowedCategoryIds      = allowedCategoryIds == null ? new List <int>() : allowedCategoryIds.Distinct();
            this.AllowedObjectiveIds     = allowedObjectiveIds == null ? new List <int>() : allowedObjectiveIds.Distinct();
            this.NewInactiveLocationIds  = newInactiveLocations == null ? new List <int>() : newInactiveLocations.Distinct();
            this.RegionLocationTypeIds   = regionLocationTypeIds == null ? new List <int>() : regionLocationTypeIds.Distinct();
            this.ThemeIds                = updatedProject.ThemeIds;
            this.GoalIds                 = updatedProject.GoalIds;
            this.AllowedThemeIds         = allowedThemeIds == null ? new List <int>() : allowedThemeIds.Distinct();
            this.AllowedGoalIds          = allowedGoalIds == null ? new List <int>() : allowedGoalIds.Distinct();
        }
        /// <summary>
        /// Returns enumerated validation results for a project update.
        /// </summary>
        /// <param name="validationEntity">The update entity.</param>
        /// <returns>The enumerated errors.</returns>

        public override IEnumerable <BusinessValidationResult> DoValidateUpdate(ProjectServiceUpdateValidationEntity validationEntity)
        {
            Contract.Requires(validationEntity.OfficeSettings != null, "The office settings must not be null.");
            if (!validationEntity.LocationsExist)
            {
                yield return(new BusinessValidationResult <PublishedProject>(x => x.LocationIds, LOCATIONS_DO_NOT_EXIST_ERROR_MESSAGE));
            }
            if (!validationEntity.ThemesExist)
            {
                yield return(new BusinessValidationResult <PublishedProject>(x => x.ThemeIds, THEMES_DO_NOT_EXIST_ERROR_MESSAGE));
            }
            if (!validationEntity.GoalsExist)
            {
                yield return(new BusinessValidationResult <PublishedProject>(x => x.GoalIds, GOALS_DO_NOT_EXIST_ERROR_MESSAGE));
            }
            if (!validationEntity.PointsOfContactExist)
            {
                yield return(new BusinessValidationResult <PublishedProject>(x => x.PointsOfContactIds, CONTACTS_DO_NOT_EXIST_ERROR_MESSAGE));
            }
            if (!validationEntity.ObjectivesExist)
            {
                yield return(new BusinessValidationResult <PublishedProject>(x => x.ObjectiveIds, OBJECTIVES_DO_NOT_EXIST_ERROR_MESSAGE));
            }
            if (!validationEntity.CategoriesExist)
            {
                yield return(new BusinessValidationResult <PublishedProject>(x => x.CategoryIds, CATEGORIES_DO_NOT_EXIST_ERROR_MESSAGE));
            }
            if (validationEntity.OfficeSettings.IsObjectiveRequired && validationEntity.NumberOfObjectives < 1)
            {
                yield return(new BusinessValidationResult <PublishedProject>(x => x.ObjectiveIds, OBJECTIVES_REQUIRED_ERROR_MESSAGE));
            }
            if (validationEntity.OfficeSettings.IsCategoryRequired && validationEntity.NumberOfCategories > validationEntity.OfficeSettings.MaximumRequiredFoci)
            {
                yield return(new BusinessValidationResult <PublishedProject>(x => x.CategoryIds,
                                                                             String.Format(MAX_CATEGORIES_REQUIRED_ERROR_MESSAGE, validationEntity.OfficeSettings.MaximumRequiredFoci)));
            }
            if (validationEntity.OfficeSettings.IsCategoryRequired && validationEntity.NumberOfCategories < validationEntity.OfficeSettings.MinimumRequiredFoci)
            {
                yield return(new BusinessValidationResult <PublishedProject>(x => x.CategoryIds,
                                                                             String.Format(MIN_CATEGORIES_REQUIRED_ERROR_MESSAGE, validationEntity.OfficeSettings.MinimumRequiredFoci)));
            }
            if (String.IsNullOrWhiteSpace(validationEntity.Name))
            {
                yield return(new BusinessValidationResult <PublishedProject>(x => x.Name, INVALID_NAME_ERROR_MESSAGE));
            }
            if (String.IsNullOrWhiteSpace(validationEntity.Description))
            {
                yield return(new BusinessValidationResult <PublishedProject>(x => x.Description, INVALID_DESCRIPTION_ERROR_MESSAGE));
            }
            if (validationEntity.StartDate >= validationEntity.EndDate)
            {
                yield return(new BusinessValidationResult <PublishedProject>(x => x.StartDate, INVALID_START_AND_END_DATE_MESSAGE));
            }
            var oldProjectStatus = ProjectStatus.GetStaticLookup(validationEntity.OriginalProjectStatusId);
            var newProjectStatus = ProjectStatus.GetStaticLookup(validationEntity.UpdatedProjectStatusId);

            Contract.Assert(oldProjectStatus != null, "The old project status must not be null.");
            Contract.Assert(newProjectStatus != null, "The new project status must not be null.");
            if (oldProjectStatus != ProjectStatus.Draft && newProjectStatus == ProjectStatus.Draft)
            {
                yield return(new BusinessValidationResult <PublishedProject>(x => x.ProjectStatusId, CAN_NOT_SET_PROJECT_BACK_TO_DRAFT_ERROR_MESSAGE));
            }

            var invalidCategoryIds = validationEntity.CategoryIds.Where(x => !validationEntity.AllowedCategoryIds.Contains(x)).ToList();

            if (invalidCategoryIds.Count > 0)
            {
                yield return(new BusinessValidationResult <PublishedProject>(x => x.CategoryIds, INVALID_CATEGORIES_ERROR_MESSAGE));
            }

            var invalidObjectiveIds = validationEntity.ObjectiveIds.Where(x => !validationEntity.AllowedObjectiveIds.Contains(x)).ToList();

            if (invalidObjectiveIds.Count > 0)
            {
                yield return(new BusinessValidationResult <PublishedProject>(x => x.ObjectiveIds, INVALID_OBJECTIVES_ERROR_MESSAGE));
            }

            if (validationEntity.NewInactiveLocationIds.Count() > 0)
            {
                yield return(new BusinessValidationResult <PublishedProject>(x => x.LocationIds, INACTIVE_LOCATIONS_ERROR_MESSAGE));
            }
            if (validationEntity.RegionLocationTypeIds.Count() > 1)
            {
                yield return(new BusinessValidationResult <PublishedProject>(x => x.RegionIds, REGION_IS_NOT_A_REGION_LOCATION_TYPE_ERROR_MESSAGE));
            }

            var invalidThemeIds = validationEntity.ThemeIds.Where(x => !validationEntity.AllowedThemeIds.Contains(x)).ToList();

            if (invalidThemeIds.Count > 0)
            {
                yield return(new BusinessValidationResult <PublishedProject>(x => x.ThemeIds, INACTIVE_THEMES_ERROR_MESSAGE));
            }
            var invalidGoalIds = validationEntity.GoalIds.Where(x => !validationEntity.AllowedGoalIds.Contains(x)).ToList();

            if (invalidGoalIds.Count > 0)
            {
                yield return(new BusinessValidationResult <PublishedProject>(x => x.GoalIds, INACTIVE_GOALS_ERROR_MESSAGE));
            }
        }