/*****************************************************************************************
 * Copyright © 2006 VHA. All rights reserved
 ****************************************************************************************/

/*
 * Created on Mar 6, 2006
 */
package gov.va.med.esr.common.model.report;

// Java classes
import java.math.BigDecimal;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
// Library classes
import org.apache.commons.lang.Validate;
import org.apache.commons.lang.builder.ToStringBuilder;

// Framework classes
import gov.va.med.fw.model.AbstractEntity;
import gov.va.med.fw.model.AbstractKeyedEntity;
import gov.va.med.fw.model.EntityKey;
import gov.va.med.fw.report.ReportExportedType;

// EDB Classes
import gov.va.med.esr.common.model.lookup.EnrollmentProcessStatus;
import gov.va.med.esr.common.model.lookup.ReportDetailBy;
import gov.va.med.esr.common.model.lookup.ReportDetailFor;
import gov.va.med.esr.common.model.lookup.ReportDivision;
import gov.va.med.esr.common.model.lookup.ReportExceptionType;
import gov.va.med.esr.common.model.lookup.ReportFacilityDisplayBy;
import gov.va.med.esr.common.model.lookup.ReportFormat;
import gov.va.med.esr.common.model.lookup.ReportWorkItemStatus;
import gov.va.med.esr.common.model.lookup.VAFacility;
import gov.va.med.esr.common.model.lookup.VISN;

/**
 * @author Yi He
 * @version 1.0 This class contains the set of parameters for a report.
 */
public class ReportParameterSet extends AbstractEntity {
   private static final long serialVersionUID = -235896269896551241L;

   public ReportSetup getReportSetup() {
      return this.reportSetup;
   }

   public void setReportSetup(ReportSetup reportSetup) {
      this.reportSetup = reportSetup;
   }

   public Date getFromDate() {
      return this.fromDate;
   }

   public void setFromDate(Date fromDate) {
      this.fromDate = fromDate;
   }

   public Date getToDate() {
      return this.toDate;
   }

   public void setToDate(Date toDate) {
      this.toDate = toDate;
   }

   public Date getAsOfDate() {
      return asOfDate;
   }

   public void setAsOfDate(Date asOfDate) {
      this.asOfDate = asOfDate;
   }

   public Integer getBeginIncomeYear() {
      return this.beginIncomeYear;
   }

   public void setBeginIncomeYear(Integer incomeYear) {
      this.beginIncomeYear = incomeYear;
   }

   public Integer getEndIncomeYear() {
      return endIncomeYear;
   }

   public void setEndIncomeYear(Integer endIncomeYear) {
      this.endIncomeYear = endIncomeYear;
   }

   public ReportDivision getDivision() {
      return this.division;
   }

   public void setDivision(ReportDivision division) {
      this.division = division;
   }

   public ReportWorkItemStatus getWorkItemStatus() {
      return this.workItemStatus;
   }

   public void setWorkItemStatus(ReportWorkItemStatus workItemStatus) {
      this.workItemStatus = workItemStatus;
   }

   public boolean getRunReportByUser() {
      return this.runReportByUser;
   }

   public void setRunReportByUser(boolean runReportByUser) {
      this.runReportByUser = runReportByUser;
   }

   public Integer getBatchNumber() {
      return this.batchNumber;
   }

   public void setBatchNumber(Integer batchNumber) {
      this.batchNumber = batchNumber;
   }

   public ReportExceptionType getExceptionType() {
      return this.exceptionType;
   }

   public void setExceptionType(ReportExceptionType exceptionType) {
      this.exceptionType = exceptionType;
   }

   public boolean getIncludeUsers() {
      return this.includeUsers;
   }

   public void setIncludeUsers(boolean includeUsers) {
      this.includeUsers = includeUsers;
   }

   public Date getEnrollmentEffectiveDateOfChange() {
      return this.enrollmentEffectiveDateOfChange;
   }

   public void setEnrollmentEffectiveDateOfChange(Date date) {
      this.enrollmentEffectiveDateOfChange = date;
   }

   public Integer getDaysBetweenUpdates() {
      return daysBetweenUpdates;
   }

   public void setDaysBetweenUpdates(Integer daysBetweenUpdates) {
      this.daysBetweenUpdates = daysBetweenUpdates;
   }

   public Integer getNumberOfRecordsPerEnrollmentStatus() {
      return this.numberOfRecordsPerEnrollmentStatus;
   }

   public void setNumberOfRecordsPerEnrollmentStatus(Integer number) {
      this.numberOfRecordsPerEnrollmentStatus = number;
   }

   public ReportFormat getReportFormat() {
      return this.reportFormat;
   }

   public void setReportFormat(ReportFormat reportFormat) {
      this.reportFormat = reportFormat;
   }

   public ReportDetailBy getDetailBy() {
      return this.detailBy;
   }

   public void setDetailBy(ReportDetailBy detailBy) {
      this.detailBy = detailBy;
   }

   public ReportDetailFor getDetailFor() {
      return this.detailFor;
   }

   public void setDetailFor(ReportDetailFor detailFor) {
      this.detailFor = detailFor;
   }

   public ReportPeriod getReportPeriod() {
      return this.reportPeriod;
   }

   public void setReportPeriod(ReportPeriod reportPeriod) {
      this.reportPeriod = reportPeriod;
   }

   public Integer getAddressUpdateDays() {
      return this.addressUpdateDays;
   }

   public void setAddressUpdateDays(Integer days) {
      this.addressUpdateDays = days;
   }

   public Integer getPhUnconfirmedDays() {
      return this.phUnconfirmedDays;
   }

   public void setPhUnconfirmedDays(Integer days) {
      this.phUnconfirmedDays = days;
   }

   public Date getLetterFileReceivedDate() {
      return this.letterFileReceivedDate;
   }

   public void setLetterFileReceivedDate(Date date) {
      this.letterFileReceivedDate = date;
   }

   public ReportFacilityDisplayBy getFacilityDisplayBy() {
      return this.facilityDisplayBy;
   }

   public void setFacilityDisplayBy(ReportFacilityDisplayBy facilityDisplayBy) {
      this.facilityDisplayBy = facilityDisplayBy;
   }

   public ReportExportedType getFileType() {
      return this.fileType;
   }

   public void setFileType(ReportExportedType fileType) {
      this.fileType = fileType;
   }

   public Integer getOutlierDays() {
      return outlierDays;
   }

   public void setOutlierDays(Integer outlierDays) {
      this.outlierDays = outlierDays;
   }

   public Integer getRandomNumberOfRecords() {
      return this.randomNumberOfRecords;
   }

   public void setRandomNumberOfRecords(Integer randomNumberOfRecords) {
      this.randomNumberOfRecords = randomNumberOfRecords;
   }

   /**
    * @return A collection of ReportUser object
    */
   public Set getUsers() {
      return Collections.unmodifiableSet(getInternalUsers());
   }

   public ReportUser getUserByEntityKey(EntityKey identifier) {
      return (ReportUser)AbstractKeyedEntity.getEntityByEntityKey(getUsers(), identifier);
   }

   public ReportUser removeUserByEntityKey(EntityKey identifier) {
      return (ReportUser)AbstractKeyedEntity.removeEntityByEntityKey(getInternalUsers(),
            identifier);
   }

   /**
    * Getter - for hibernate use only.
    *
    * @return
    */
   private Set getInternalUsers() {
      if( this.internalUsers == null ) {
         this.internalUsers = new HashSet();
      }
      return this.internalUsers;
   }

   /**
    * Setter - for hibernate use only.
    *
    * @param users
    */
   private void setInternalUsers(Set users) {
      this.internalUsers = users;
   }

   /**
    * Add a ReportUser for this report setup. This method takes care of Bidirectional
    * setting of ReportUser's report setup.
    *
    * @param user
    */
   public void addUser(ReportUser user) {
      Validate.notNull(user, "Null user specified.");
      user.setReportSetup(reportSetup);
      getInternalUsers().add(user);
   }

   /**
    * Add a collection of Users to this report setup. This method takes care of
    * Bidirectional setting of ReportUser's report setup.
    *
    * @param users
    */
   public void addAllUsers(Set users) {
      Validate.notNull(users, "Null set of users specified.");
      this.setParameterOwner(users);
      Set internal = this.getInternalUsers();
      internal.addAll(users);
   }

   /**
    * Remove an ReportUser for this report setup. This method takes care of Bidirectional
    * setting of ReportUser's report setup.
    *
    * @param user
    */
   public void removeUser(ReportUser user) {
      Validate.notNull(user, "Null user specified.");
      getInternalUsers().remove(user);
      user.setReportSetup(null);
   }

   public void removeAllUsers() {
      this.getInternalUsers().clear();
   }

   /**
    * @return A collection of ReportMessageType object
    */
   public Set getMessageTypes() {
      return Collections.unmodifiableSet(getInternalMessageTypes());
   }

   public ReportMessageType getMessageTypeByEntityKey(EntityKey identifier) {
      return (ReportMessageType)AbstractKeyedEntity.getEntityByEntityKey(
            getMessageTypes(), identifier);
   }

   public ReportMessageType removeMessageTypeByEntityKey(EntityKey identifier) {
      return (ReportMessageType)AbstractKeyedEntity.removeEntityByEntityKey(
            getInternalMessageTypes(), identifier);
   }

   /**
    * Getter - for hibernate use only.
    *
    * @return
    */
   private Set getInternalMessageTypes() {
      if( this.internalMessageTypes == null ) {
         this.internalMessageTypes = new HashSet();
      }
      return this.internalMessageTypes;
   }

   /**
    * Setter - for hibernate use only.
    *
    * @param messageTypes
    */
   private void setInternalMessageTypes(Set messageTypes) {
      this.internalMessageTypes = messageTypes;
   }

   /**
    * Add a ReportMessageType for this report setup. This method takes care of
    * Bidirectional setting of ReportMessageType's report setup.
    *
    * @param messageType
    */
   public void addMessageType(ReportMessageType messageType) {
      Validate.notNull(messageType, "Null messageType specified.");
      messageType.setReportSetup(reportSetup);
      getInternalMessageTypes().add(messageType);
   }

   /**
    * Add a collection of MessageTypes to this report setup. This method takes care of
    * Bidirectional setting of ReportMessageType's report setup.
    *
    * @param messageTypes
    */
   public void addAllMessageTypes(Set messageTypes) {
      Validate.notNull(messageTypes, "Null set of messageTypes specified.");
      this.setParameterOwner(messageTypes);
      Set internal = this.getInternalMessageTypes();
      internal.addAll(messageTypes);
   }

   /**
    * Remove an ReportMessageType for this report setup. This method takes care of
    * Bidirectional setting of ReportMessageType's report setup.
    *
    * @param messageType
    */
   public void removeMessageType(ReportMessageType messageType) {
      Validate.notNull(messageType, "Null messageType specified.");
      getInternalMessageTypes().remove(messageType);
      messageType.setReportSetup(null);
   }

   public void removeAllMessageTypes() {
      this.getInternalMessageTypes().clear();
   }

   public boolean getAllLetterRejectReasons() {
      return this.allLetterRejectReasons;
   }

   public void setAllLetterRejectReasons(boolean val) {
      this.allLetterRejectReasons = val;
   }

   public Set getLetterRejectReasons() {
      if( this.letterRejectReasons == null ) {
         this.letterRejectReasons = new HashSet();
      }
      return Collections.unmodifiableSet(this.letterRejectReasons);
   }

   public void addAllLetterRejectReasons(Set letterRejectReasons) {
      Validate.notNull(letterRejectReasons, "Null set of letterRejectReasons specified.");
      this.setParameterOwner(letterRejectReasons);
      if( this.letterRejectReasons == null ) {
         this.letterRejectReasons = new HashSet();
      }
      Set internal = this.letterRejectReasons;
      internal.addAll(letterRejectReasons);
   }

   public void removeAllLetterRejectReasons() {
      if( this.letterRejectReasons != null ) {
         this.letterRejectReasons.clear();
      }
   }

   public boolean getAllLetterErrorTypes() {
      return this.allLetterErrorTypes;
   }

   public void setAllLetterErrorTypes(boolean val) {
      this.allLetterErrorTypes = val;
   }

   public Set getLetterErrorTypes() {
      if( this.letterErrorTypes == null ) {
         this.letterErrorTypes = new HashSet();
      }
      return Collections.unmodifiableSet(this.letterErrorTypes);
   }

   public void addAllLetterErrorTypes(Set letterErrorTypes) {
      Validate.notNull(letterErrorTypes, "Null set of letterErrorTypes specified.");
      this.setParameterOwner(letterErrorTypes);
      if( this.letterErrorTypes == null ) {
         this.letterErrorTypes = new HashSet();
      }
      Set internal = this.letterErrorTypes;
      internal.addAll(letterErrorTypes);
   }

   public void removeAllLetterErrorTypes() {
      if( this.letterErrorTypes != null ) {
         this.letterErrorTypes.clear();
      }
   }

   public Set getReportLetterFileCodes() {
      Set linkLetterFiles = getReportLinkLetterFiles();
      Set letterFiles = new HashSet();
      Iterator iter = linkLetterFiles.iterator();
      while( iter.hasNext() ) {
         ReportLinkLetterFile linkLetterFile = (ReportLinkLetterFile)iter.next();
         letterFiles.add(linkLetterFile.getReportLetterFile().getCode());
      }

      return letterFiles;
   }

   public Set getReportLinkLetterFiles() {
      if( this.letterFiles == null ) {
         this.letterFiles = new HashSet();
      }
      return Collections.unmodifiableSet(this.letterFiles);
   }

   public void addReportLinkLetterFile(ReportLinkLetterFile letterFile) {
      if( letterFile != null ) {
         letterFile.setReportSetup(reportSetup);
         if( this.letterFiles == null ) {
            this.letterFiles = new HashSet();
         }
         Set internal = this.letterFiles;
         internal.add(letterFile);
      }
   }

   public void addAllReportLinkLetterFiles(Set letterFiles) {
      Validate.notNull(letterFiles, "Null set of letterFiles specified.");
      this.setParameterOwner(letterFiles);
      if( this.letterFiles == null ) {
         this.letterFiles = new HashSet();
      }
      Set internal = this.letterFiles;
      internal.addAll(letterFiles);
   }

   public void removeAllReportLinkLetterFiles() {
      if( this.letterFiles != null ) {
         this.letterFiles.clear();
      }
   }

   /**
    * @return A collection of ReportBadAddressReason object
    */
   public Set getBadAddressReasons() {
      return Collections.unmodifiableSet(getInternalBadAddressReasons());
   }

   public ReportBadAddressReason getBadAddressReasonByEntityKey(EntityKey identifier) {
      return (ReportBadAddressReason)AbstractKeyedEntity.getEntityByEntityKey(
            getBadAddressReasons(), identifier);
   }

   public ReportBadAddressReason removeBadAddressReasonByEntityKey(EntityKey identifier) {
      return (ReportBadAddressReason)AbstractKeyedEntity.removeEntityByEntityKey(
            getInternalBadAddressReasons(), identifier);
   }

   /**
    * Getter - for hibernate use only.
    *
    * @return
    */
   private Set getInternalBadAddressReasons() {
      if( this.internalBadAddressReasons == null ) {
         this.internalBadAddressReasons = new HashSet();
      }
      return this.internalBadAddressReasons;
   }

   /**
    * Setter - for hibernate use only.
    *
    * @param badAddressReasons
    */
   private void setInternalBadAddressReasons(Set badAddressReasons) {
      this.internalBadAddressReasons = badAddressReasons;
   }

   /**
    * Add a ReportBadAddressReason for this report setup. This method takes care of
    * Bidirectional setting of ReportBadAddressReason's report setup.
    *
    * @param badAddressReason
    */
   public void addBadAddressReason(ReportBadAddressReason badAddressReason) {
      Validate.notNull(badAddressReason, "Null badAddressReason specified.");
      badAddressReason.setReportSetup(reportSetup);
      getInternalBadAddressReasons().add(badAddressReason);
   }

   /**
    * Add a collection of BadAddressReasons to this report setup. This method takes care
    * of Bidirectional setting of ReportBadAddressReason's report setup.
    *
    * @param badAddressReasons
    */
   public void addAllBadAddressReasons(Set badAddressReasons) {
      Validate.notNull(badAddressReasons, "Null set of badAddressReasons specified.");
      this.setParameterOwner(badAddressReasons);
      Set internal = this.getInternalBadAddressReasons();
      internal.addAll(badAddressReasons);
   }

   /**
    * Remove an ReportBadAddressReason for this report setup. This method takes care of
    * Bidirectional setting of ReportBadAddressReason's report setup.
    *
    * @param badAddressReason
    */
   public void removeBadAddressReason(ReportBadAddressReason badAddressReason) {
      Validate.notNull(badAddressReason, "Null badAddressReason specified.");
      getInternalBadAddressReasons().remove(badAddressReason);
      badAddressReason.setReportSetup(null);
   }

   public void removeAllBadAddressReasons() {
      this.getInternalBadAddressReasons().clear();
   }

   /**
    * @return A collection of ReportCancelDeclineReason object
    */
   public Set getCancelDeclineReasons() {
      return Collections.unmodifiableSet(getInternalCancelDeclineReasons());
   }

   public ReportCancelDeclineReason getCancelDeclineReasonByEntityKey(EntityKey identifier) {
      return (ReportCancelDeclineReason)AbstractKeyedEntity.getEntityByEntityKey(
            getCancelDeclineReasons(), identifier);
   }

   public ReportCancelDeclineReason removeCancelDeclineReasonByEntityKey(
         EntityKey identifier) {
      return (ReportCancelDeclineReason)AbstractKeyedEntity.removeEntityByEntityKey(
            getInternalCancelDeclineReasons(), identifier);
   }

   /**
    * Getter - for hibernate use only.
    *
    * @return
    */
   private Set getInternalCancelDeclineReasons() {
      if( this.internalCancelDeclineReasons == null ) {
         this.internalCancelDeclineReasons = new HashSet();
      }
      return this.internalCancelDeclineReasons;
   }

   /**
    * Setter - for hibernate use only.
    *
    * @param cancelDeclineReasons
    */
   private void setInternalCancelDeclineReasons(Set cancelDeclineReasons) {
      this.internalCancelDeclineReasons = cancelDeclineReasons;
   }

   /**
    * Add a ReportCancelDeclineReason for this report setup. This method takes care of
    * Bidirectional setting of ReportCancelDeclineReason's report setup.
    *
    * @param cancelDeclineReason
    */
   public void addCancelDeclineReason(ReportCancelDeclineReason cancelDeclineReason) {
      Validate.notNull(cancelDeclineReason, "Null cancelDeclineReason specified.");
      cancelDeclineReason.setReportSetup(reportSetup);
      getInternalCancelDeclineReasons().add(cancelDeclineReason);
   }

   /**
    * Add a collection of CancelDeclineReasons to this report setup. This method takes
    * care of Bidirectional setting of ReportCancelDeclineReason's report setup.
    *
    * @param cancelDeclineReasons
    */
   public void addAllCancelDeclineReasons(Set cancelDeclineReasons) {
      Validate.notNull(cancelDeclineReasons,
            "Null set of cancelDeclineReasons specified.");
      this.setParameterOwner(cancelDeclineReasons);
      Set internal = this.getInternalCancelDeclineReasons();
      internal.addAll(cancelDeclineReasons);
   }

   /**
    * Remove an ReportCancelDeclineReason for this report setup. This method takes care of
    * Bidirectional setting of ReportCancelDeclineReason's report setup.
    *
    * @param cancelDeclineReason
    */
   public void removeCancelDeclineReason(ReportCancelDeclineReason cancelDeclineReason) {
      Validate.notNull(cancelDeclineReason, "Null cancelDeclineReason specified.");
      getInternalCancelDeclineReasons().remove(cancelDeclineReason);
      cancelDeclineReason.setReportSetup(null);
   }

   public void removeAllCancelDeclineReasons() {
      this.getInternalCancelDeclineReasons().clear();
   }

   /**
    * @return A collection of ReportPHRejectionRemark object
    */
   public Set getPHRejectionRemarks() {
      return Collections.unmodifiableSet(getInternalPHRejectionRemarks());
   }

   public ReportPHRejectionRemark getPHRejectionRemarkByEntityKey(EntityKey identifier) {
      return (ReportPHRejectionRemark)AbstractKeyedEntity.getEntityByEntityKey(
            getPHRejectionRemarks(), identifier);
   }

   public ReportPHRejectionRemark removePHRejectionRemarkByEntityKey(EntityKey identifier) {
      return (ReportPHRejectionRemark)AbstractKeyedEntity.removeEntityByEntityKey(
            getInternalPHRejectionRemarks(), identifier);
   }

   /**
    * Getter - for hibernate use only.
    *
    * @return
    */
   private Set getInternalPHRejectionRemarks() {
      if( this.internalPHRejectionRemarks == null ) {
         this.internalPHRejectionRemarks = new HashSet();
      }
      return this.internalPHRejectionRemarks;
   }

   /**
    * Setter - for hibernate use only.
    *
    * @param pHRejectionRemarks
    */
   private void setInternalPHRejectionRemarks(Set pHRejectionRemarks) {
      this.internalPHRejectionRemarks = pHRejectionRemarks;
   }

   /**
    * Add a ReportPHRejectionRemark for this report setup. This method takes care of
    * Bidirectional setting of ReportPHRejectionRemark's report setup.
    *
    * @param pHRejectionRemark
    */
   public void addPHRejectionRemark(ReportPHRejectionRemark pHRejectionRemark) {
      Validate.notNull(pHRejectionRemark, "Null pHRejectionRemark specified.");
      pHRejectionRemark.setReportSetup(reportSetup);
      getInternalPHRejectionRemarks().add(pHRejectionRemark);
   }

   /**
    * Add a collection of PHRejectionRemarks to this report setup. This method takes care
    * of Bidirectional setting of ReportPHRejectionRemark's report setup.
    *
    * @param pHRejectionRemarks
    */
   public void addAllPHRejectionRemarks(Set pHRejectionRemarks) {
      Validate.notNull(pHRejectionRemarks, "Null set of pHRejectionRemarks specified.");
      this.setParameterOwner(pHRejectionRemarks);
      Set internal = this.getInternalPHRejectionRemarks();
      internal.addAll(pHRejectionRemarks);
   }

   /**
    * Remove an ReportPHRejectionRemark for this report setup. This method takes care of
    * Bidirectional setting of ReportPHRejectionRemark's report setup.
    *
    * @param pHRejectionRemark
    */
   public void removePHRejectionRemark(ReportPHRejectionRemark pHRejectionRemark) {
      Validate.notNull(pHRejectionRemark, "Null pHRejectionRemark specified.");
      getInternalPHRejectionRemarks().remove(pHRejectionRemark);
      pHRejectionRemark.setReportSetup(null);
   }

   public void removeAllPHRejectionRemarks() {
      this.getInternalPHRejectionRemarks().clear();
   }

   /**
    * @return A collection of ReportEnrollmentPriorityGroup object
    */
   public Set getReportEnrollmentPriorityGroups() {
      return Collections.unmodifiableSet(getInternalReportEnrollmentPriorityGroups());
   }

   public ReportEnrollmentPriorityGroup getReportEnrollmentPriorityGroupByEntityKey(
         EntityKey identifier) {
      return (ReportEnrollmentPriorityGroup)AbstractKeyedEntity.getEntityByEntityKey(
            getReportEnrollmentPriorityGroups(), identifier);
   }

   public ReportEnrollmentPriorityGroup removeReportEnrollmentPriorityGroupByEntityKey(
         EntityKey identifier) {
      return (ReportEnrollmentPriorityGroup)AbstractKeyedEntity.removeEntityByEntityKey(
            getInternalReportEnrollmentPriorityGroups(), identifier);
   }

   /**
    * Getter - for hibernate use only.
    *
    * @return
    */
   private Set getInternalReportEnrollmentPriorityGroups() {
      if( this.internalReportEnrollmentPriorityGroups == null ) {
         this.internalReportEnrollmentPriorityGroups = new HashSet();
      }
      return this.internalReportEnrollmentPriorityGroups;
   }

   /**
    * Setter - for hibernate use only.
    *
    * @param enrollmentPriorityGroups
    */
   private void setInternalReportEnrollmentPriorityGroups(Set enrollmentPriorityGroups) {
      this.internalReportEnrollmentPriorityGroups = enrollmentPriorityGroups;
   }

   /**
    * Add a ReportEnrollmentPriorityGroup for this report setup. This method takes care of
    * Bidirectional setting of ReportEnrollmentPriorityGroup's report setup.
    *
    * @param enrollmentPriorityGroup
    */
   public void addReportEnrollmentPriorityGroup(
         ReportEnrollmentPriorityGroup enrollmentPriorityGroup) {
      Validate
            .notNull(enrollmentPriorityGroup, "Null enrollmentPriorityGroup specified.");
      enrollmentPriorityGroup.setReportSetup(reportSetup);
      getInternalReportEnrollmentPriorityGroups().add(enrollmentPriorityGroup);
   }

   /**
    * Add a collection of ReportEnrollmentPriorityGroups to this report setup. This method
    * takes care of Bidirectional setting of ReportEnrollmentPriorityGroup's report setup.
    *
    * @param enrollmentPriorityGroups
    */
   public void addAllReportEnrollmentPriorityGroups(Set enrollmentPriorityGroups) {
      Validate.notNull(enrollmentPriorityGroups,
            "Null set of enrollmentPriorityGroups specified.");
      this.setParameterOwner(enrollmentPriorityGroups);
      Set internal = this.getInternalReportEnrollmentPriorityGroups();
      internal.addAll(enrollmentPriorityGroups);
   }

   /**
    * Remove an ReportEnrollmentPriorityGroup for this report setup. This method takes
    * care of Bidirectional setting of ReportEnrollmentPriorityGroup's report setup.
    *
    * @param enrollmentPriorityGroup
    */
   public void removeReportEnrollmentPriorityGroup(
         ReportEnrollmentPriorityGroup enrollmentPriorityGroup) {
      Validate
            .notNull(enrollmentPriorityGroup, "Null enrollmentPriorityGroup specified.");
      getInternalReportEnrollmentPriorityGroups().remove(enrollmentPriorityGroup);
      enrollmentPriorityGroup.setReportSetup(null);
   }

   public void removeAllReportEnrollmentPriorityGroups() {
      this.getInternalReportEnrollmentPriorityGroups().clear();
   }

   /**
    * @return A collection of ReportEnrollmentCategory object
    */
   public Set getEnrollmentCategories() {
      return Collections.unmodifiableSet(getInternalEnrollmentCategories());
   }

   public ReportEnrollmentCategory getEnrollmentCategoryByEntityKey(EntityKey identifier) {
      return (ReportEnrollmentCategory)AbstractKeyedEntity.getEntityByEntityKey(
            getEnrollmentCategories(), identifier);
   }

   public ReportEnrollmentCategory removeEnrollmentCategoryByEntityKey(
         EntityKey identifier) {
      return (ReportEnrollmentCategory)AbstractKeyedEntity.removeEntityByEntityKey(
            getInternalEnrollmentCategories(), identifier);
   }

   /**
    * Getter - for hibernate use only.
    *
    * @return
    */
   private Set getInternalEnrollmentCategories() {
      if( this.internalEnrollmentCategories == null ) {
         this.internalEnrollmentCategories = new HashSet();
      }
      return this.internalEnrollmentCategories;
   }

   /**
    * Setter - for hibernate use only.
    *
    * @param enrollmentCategories
    */
   private void setInternalEnrollmentCategories(Set enrollmentCategories) {
      this.internalEnrollmentCategories = enrollmentCategories;
   }

   /**
    * Add a ReportEnrollmentCategory for this report setup. This method takes care of
    * Bidirectional setting of ReportEnrollmentCategory's report setup.
    *
    * @param enrollmentCategory
    */
   public void addEnrollmentCategory(ReportEnrollmentCategory enrollmentCategory) {
      Validate.notNull(enrollmentCategory, "Null enrollmentCategory specified.");
      enrollmentCategory.setReportSetup(reportSetup);
      getInternalEnrollmentCategories().add(enrollmentCategory);
   }

   /**
    * Add a collection of EnrollmentCategories to this report setup. This method takes
    * care of Bidirectional setting of ReportEnrollmentCategory's report setup.
    *
    * @param enrollmentCategories
    */
   public void addAllEnrollmentCategories(Set enrollmentCategories) {
      Validate.notNull(enrollmentCategories,
            "Null set of enrollmentCategories specified.");
      this.setParameterOwner(enrollmentCategories);
      Set internal = this.getInternalEnrollmentCategories();
      internal.addAll(enrollmentCategories);
   }

   /**
    * Remove an ReportEnrollmentCategory for this report setup. This method takes care of
    * Bidirectional setting of ReportEnrollmentCategory's report setup.
    *
    * @param enrollmentCategory
    */
   public void removeEnrollmentCategory(ReportEnrollmentCategory enrollmentCategory) {
      Validate.notNull(enrollmentCategory, "Null enrollmentCategory specified.");
      getInternalEnrollmentCategories().remove(enrollmentCategory);
      enrollmentCategory.setReportSetup(null);
   }

   public void removeAllEnrollmentCategories() {
      this.getInternalEnrollmentCategories().clear();
   }

   /**
    * @return A collection of ReportEnrollmentStatus object
    */
   public Set getEnrollmentStatuses() {
      return Collections.unmodifiableSet(getInternalEnrollmentStatuses());
   }

   public ReportEnrollmentStatus getEnrollmentStatusByEntityKey(EntityKey identifier) {
      return (ReportEnrollmentStatus)AbstractKeyedEntity.getEntityByEntityKey(
            getEnrollmentStatuses(), identifier);
   }

   public ReportEnrollmentStatus removeEnrollmentStatusByEntityKey(EntityKey identifier) {
      return (ReportEnrollmentStatus)AbstractKeyedEntity.removeEntityByEntityKey(
            getInternalEnrollmentStatuses(), identifier);
   }

   /**
    * Getter - for hibernate use only.
    *
    * @return
    */
   private Set getInternalEnrollmentStatuses() {
      if( this.internalEnrollmentStatuses == null ) {
         this.internalEnrollmentStatuses = new HashSet();
      }
      return this.internalEnrollmentStatuses;
   }

   /**
    * Setter - for hibernate use only.
    *
    * @param enrollmentStatuses
    */
   private void setInternalEnrollmentStatuses(Set enrollmentStatuses) {
      this.internalEnrollmentStatuses = enrollmentStatuses;
   }

   /**
    * Add a ReportEnrollmentStatus for this report setup. This method takes care of
    * Bidirectional setting of ReportEnrollmentStatus's report setup.
    *
    * @param enrollmentStatus
    */
   public void addEnrollmentStatus(ReportEnrollmentStatus enrollmentStatus) {
      Validate.notNull(enrollmentStatus, "Null enrollmentStatus specified.");
      enrollmentStatus.setReportSetup(reportSetup);
      getInternalEnrollmentStatuses().add(enrollmentStatus);
   }

   /**
    * Add a collection of EnrollmentStatuses to this report setup. This method takes care
    * of Bidirectional setting of ReportEnrollmentStatus's report setup.
    *
    * @param enrollmentStatuses
    */
   public void addAllEnrollmentStatuses(Set enrollmentStatuses) {
      Validate.notNull(enrollmentStatuses, "Null set of enrollmentStatuses specified.");
      this.setParameterOwner(enrollmentStatuses);
      Set internal = this.getInternalEnrollmentStatuses();
      internal.addAll(enrollmentStatuses);
   }

   /**
    * Remove an ReportEnrollmentStatus for this report setup. This method takes care of
    * Bidirectional setting of ReportEnrollmentStatus's report setup.
    *
    * @param enrollmentStatus
    */
   public void removeEnrollmentStatus(ReportEnrollmentStatus enrollmentStatus) {
      Validate.notNull(enrollmentStatus, "Null enrollmentStatus specified.");
      getInternalEnrollmentStatuses().remove(enrollmentStatus);
      enrollmentStatus.setReportSetup(null);
   }

   public void removeAllEnrollmentStatuses() {
      this.getInternalEnrollmentStatuses().clear();
   }

   /**
    * @return A collection of ReportQueryToSite object
    */
   public Set getQueryToSites() {
      return Collections.unmodifiableSet(getInternalQueryToSites());
   }

   public ReportQueryToSite getQueryToSiteByEntityKey(EntityKey identifier) {
      return (ReportQueryToSite)AbstractKeyedEntity.getEntityByEntityKey(
            getQueryToSites(), identifier);
   }

   public ReportQueryToSite removeQueryToSiteByEntityKey(EntityKey identifier) {
      return (ReportQueryToSite)AbstractKeyedEntity.removeEntityByEntityKey(
            getInternalQueryToSites(), identifier);
   }

   /**
    * Getter - for hibernate use only.
    *
    * @return
    */
   private Set getInternalQueryToSites() {
      if( this.internalQueryToSites == null ) {
         this.internalQueryToSites = new HashSet();
      }
      return this.internalQueryToSites;
   }

   /**
    * Setter - for hibernate use only.
    *
    * @param queryToSites
    */
   private void setInternalQueryToSites(Set queryToSites) {
      this.internalQueryToSites = queryToSites;
   }

   /**
    * Add a ReportQueryToSite for this report setup. This method takes care of
    * Bidirectional setting of ReportQueryToSite's report setup.
    *
    * @param queryToSite
    */
   public void addQueryToSite(ReportQueryToSite queryToSite) {
      Validate.notNull(queryToSite, "Null queryToSite specified.");
      queryToSite.setReportSetup(reportSetup);
      getInternalQueryToSites().add(queryToSite);
   }

   /**
    * Add a collection of QueryToSites to this report setup. This method takes care of
    * Bidirectional setting of ReportQueryToSite's report setup.
    *
    * @param queryToSites
    */
   public void addAllQueryToSites(Set queryToSites) {
      Validate.notNull(queryToSites, "Null set of queryToSites specified.");
      this.setParameterOwner(queryToSites);
      Set internal = this.getInternalQueryToSites();
      internal.addAll(queryToSites);
   }

   /**
    * Remove an ReportQueryToSite for this report setup. This method takes care of
    * Bidirectional setting of ReportQueryToSite's report setup.
    *
    * @param queryToSite
    */
   public void removeQueryToSite(ReportQueryToSite queryToSite) {
      Validate.notNull(queryToSite, "Null queryToSite specified.");
      getInternalQueryToSites().remove(queryToSite);
      queryToSite.setReportSetup(null);
   }

   public void removeAllQueryToSites() {
      this.getInternalQueryToSites().clear();
   }

   /**
    * @return A collection of ReportMessageType object
    */
   public Set getVBAQueryStatuses() {
      return Collections.unmodifiableSet(getInternalVBAQueryStatuses());
   }

   public ReportVBAQueryStatus getVBAQueryStatusByEntityKey(EntityKey identifier) {
      return (ReportVBAQueryStatus)AbstractKeyedEntity.getEntityByEntityKey(
            getVBAQueryStatuses(), identifier);
   }

   public ReportVBAQueryStatus removeVBAQueryStatusByEntityKey(EntityKey identifier) {
      return (ReportVBAQueryStatus)AbstractKeyedEntity.removeEntityByEntityKey(
            getInternalVBAQueryStatuses(), identifier);
   }

   /**
    * Getter - for hibernate use only.
    *
    * @return
    */
   private Set getInternalVBAQueryStatuses() {
      if( this.internalVBAQueryStatuses == null ) {
         this.internalVBAQueryStatuses = new HashSet();
      }
      return this.internalVBAQueryStatuses;
   }

   /**
    * Setter - for hibernate use only.
    *
    * @param messageTypes
    */
   private void setInternalVBAQueryStatuses(Set messageTypes) {
      this.internalVBAQueryStatuses = messageTypes;
   }

   /**
    * Add a ReportVBAQueryStatus for this report setup. This method takes care of
    * Bidirectional setting of ReportVBAQueryStatus's report setup.
    *
    * @param messageType
    */
   public void addVBAQueryStatus(ReportVBAQueryStatus messageType) {
      Validate.notNull(messageType, "Null messageType specified.");
      messageType.setReportSetup(reportSetup);
      getInternalVBAQueryStatuses().add(messageType);
   }

   /**
    * Add a collection of VBAQueryStatuses to this report setup. This method takes care of
    * Bidirectional setting of ReportVBAQueryStatus's report setup.
    *
    * @param messageTypes
    */
   public void addAllVBAQueryStatuses(Set messageTypes) {
      Validate.notNull(messageTypes, "Null set of messageTypes specified.");
      this.setParameterOwner(messageTypes);
      Set internal = this.getInternalVBAQueryStatuses();
      internal.addAll(messageTypes);
   }

   /**
    * Remove an ReportVBAQueryStatus for this report setup. This method takes care of
    * Bidirectional setting of ReportVBAQueryStatus's report setup.
    *
    * @param messageType
    */
   public void removeVBAQueryStatus(ReportVBAQueryStatus messageType) {
      Validate.notNull(messageType, "Null messageType specified.");
      getInternalVBAQueryStatuses().remove(messageType);
      messageType.setReportSetup(null);
   }

   public void removeAllVBAQueryStatuses() {
      this.getInternalVBAQueryStatuses().clear();
   }

   /**
    * @return A collection of ReportMessageType object
    */
   public Set getReportEEDWeeklyReportTypes() {
      return Collections.unmodifiableSet(getInternalReportEEDWeeklyReportTypes());
   }

   public ReportEEDWeeklyReportType getReportEEDWeeklyReportTypeByEntityKey(
         EntityKey identifier) {
      return (ReportEEDWeeklyReportType)AbstractKeyedEntity.getEntityByEntityKey(
            getReportEEDWeeklyReportTypes(), identifier);
   }

   public ReportEEDWeeklyReportType removeReportEEDWeeklyReportTypeByEntityKey(
         EntityKey identifier) {
      return (ReportEEDWeeklyReportType)AbstractKeyedEntity.removeEntityByEntityKey(
            getInternalReportEEDWeeklyReportTypes(), identifier);
   }

   /**
    * Getter - for hibernate use only.
    *
    * @return
    */
   private Set getInternalReportEEDWeeklyReportTypes() {
      if( this.internalReportEEDWeeklyReportTypes == null ) {
         this.internalReportEEDWeeklyReportTypes = new HashSet();
      }
      return this.internalReportEEDWeeklyReportTypes;
   }

   /**
    * Setter - for hibernate use only.
    *
    * @param reportEEDWeeklyReportTypes
    */
   private void setInternalReportEEDWeeklyReportTypes(Set reportEEDWeeklyReportTypes) {
      this.internalReportEEDWeeklyReportTypes = reportEEDWeeklyReportTypes;
   }

   /**
    * Add a ReportReportEEDWeeklyReportType for this report setup. This method takes care
    * of Bidirectional setting of ReportReportEEDWeeklyReportType's report setup.
    *
    * @param reportEEDWeeklyReportType
    */
   public void addReportEEDWeeklyReportType(
         ReportEEDWeeklyReportType reportEEDWeeklyReportType) {
      Validate.notNull(reportEEDWeeklyReportType,
            "Null reportEEDWeeklyReportType specified.");
      reportEEDWeeklyReportType.setReportSetup(reportSetup);
      getInternalReportEEDWeeklyReportTypes().add(reportEEDWeeklyReportType);
   }

   /**
    * Add a collection of ReportEEDWeeklyReportTypes to this report setup. This method
    * takes care of Bidirectional setting of ReportReportEEDWeeklyReportType's report
    * setup.
    *
    * @param reportEEDWeeklyReportTypes
    */
   public void addAllReportEEDWeeklyReportTypes(Set reportEEDWeeklyReportTypes) {
      Validate.notNull(reportEEDWeeklyReportTypes,
            "Null set of reportEEDWeeklyReportTypes specified.");
      this.setParameterOwner(reportEEDWeeklyReportTypes);
      Set internal = this.getInternalReportEEDWeeklyReportTypes();
      internal.addAll(reportEEDWeeklyReportTypes);
   }

   /**
    * Remove an ReportReportEEDWeeklyReportType for this report setup. This method takes
    * care of Bidirectional setting of ReportReportEEDWeeklyReportType's report setup.
    *
    * @param reportEEDWeeklyReportType
    */
   public void removeReportEEDWeeklyReportType(
         ReportEEDWeeklyReportType reportEEDWeeklyReportType) {
      Validate.notNull(reportEEDWeeklyReportType,
            "Null reportEEDWeeklyReportType specified.");
      getInternalReportEEDWeeklyReportTypes().remove(reportEEDWeeklyReportType);
      reportEEDWeeklyReportType.setReportSetup(null);
   }

   public void removeAllReportEEDWeeklyReportTypes() {
      this.getInternalReportEEDWeeklyReportTypes().clear();
   }

   /**
    * @return A collection of ReportFacility object
    */
   public Set getFacilities() {
      return Collections.unmodifiableSet(getInternalFacilities());
   }

   public ReportFacility getFacilityByEntityKey(EntityKey identifier) {
      return (ReportFacility)AbstractKeyedEntity.getEntityByEntityKey(getFacilities(),
            identifier);
   }

   public ReportFacility removeFacilityByEntityKey(EntityKey identifier) {
      return (ReportFacility)AbstractKeyedEntity.removeEntityByEntityKey(
            getInternalFacilities(), identifier);
   }

   /**
    * Getter - for hibernate use only.
    *
    * @return
    */
   private Set getInternalFacilities() {
      if( this.internalFacilities == null ) {
         this.internalFacilities = new HashSet();
      }
      return this.internalFacilities;
   }

   /**
    * Setter - for hibernate use only.
    *
    * @param messageTypes
    */
   private void setInternalFacilities(Set messageTypes) {
      this.internalFacilities = messageTypes;
   }

   /**
    * Add a ReportFacility for this report setup. This method takes care of Bidirectional
    * setting of ReportFacility's report setup.
    *
    * @param messageType
    */
   public void addFacility(ReportFacility messageType) {
      Validate.notNull(messageType, "Null messageType specified.");      

      VAFacility vaFacility = (VAFacility)messageType.getLookup();
      
      //Because there is a database constraint on the facility while scheduling reports, we cannot set
      //the facilty to the dummy No VISN Id. So set it to the batch number.
      //TODO Store this logic in a better place if we get a database change. 
      if(vaFacility != null && VISN.CODE_NO_VISN_IDENTIFIER.equals(vaFacility.getVisnId()))
      {
    	  setBatchNumber(new Integer(vaFacility.getVisnId().intValue()));
      }
      else {
	      messageType.setReportSetup(reportSetup);      
	      getInternalFacilities().add(messageType);
      }
   }

   /**
    * Add a collection of Facilities to this report setup. This method takes care of
    * Bidirectional setting of ReportFacility's report setup.
    *
    * @param messageTypes
    */
   public void addAllFacilities(Set messageTypes) {
      Validate.notNull(messageTypes, "Null set of messageTypes specified.");
      this.setParameterOwner(messageTypes);
      Set internal = this.getInternalFacilities();
      internal.addAll(messageTypes);
   }

   /**
    * Remove an ReportFacility for this report setup. This method takes care of
    * Bidirectional setting of ReportFacility's report setup.
    *
    * @param messageType
    */
   public void removeFacility(ReportFacility messageType) {
      Validate.notNull(messageType, "Null messageType specified.");
      getInternalFacilities().remove(messageType);
      messageType.setReportSetup(null);
   }

   public void removeAllFacilities() {
      this.getInternalFacilities().clear();
   }

   /**
    * @return A collection of ReportFunctionalGroup object
    */
   public Set getFunctionalGroups() {
      return Collections.unmodifiableSet(getInternalFunctionalGroups());
   }

   public ReportFunctionalGroup getFunctionalGroupByEntityKey(EntityKey identifier) {
      return (ReportFunctionalGroup)AbstractKeyedEntity.getEntityByEntityKey(
            getFunctionalGroups(), identifier);
   }

   public ReportFunctionalGroup removeFunctionalGroupByEntityKey(EntityKey identifier) {
      return (ReportFunctionalGroup)AbstractKeyedEntity.removeEntityByEntityKey(
            getInternalFunctionalGroups(), identifier);
   }
   
   public boolean isNoVISNPresent()
   {
	   return getBatchNumber() != null;
   }
   
   /**
    * Getter - for hibernate use only.
    *
    * @return
    */
   private Set getInternalFunctionalGroups() {
      if( this.internalFunctionalGroups == null ) {
         this.internalFunctionalGroups = new HashSet();
      }
      return this.internalFunctionalGroups;
   }

   /**
    * Setter - for hibernate use only.
    *
    * @param functionalGroups
    */
   private void setInternalFunctionalGroups(Set functionalGroups) {
      this.internalFunctionalGroups = functionalGroups;
   }

   /**
    * Add a ReportFunctionalGroup for this report setup. This method takes care of
    * Bidirectional setting of ReportFunctionalGroup's report setup.
    *
    * @param functionalGroup
    */
   public void addFunctionalGroup(ReportFunctionalGroup functionalGroup) {
      Validate.notNull(functionalGroup, "Null functionalGroup specified.");
      functionalGroup.setReportSetup(reportSetup);
      getInternalFunctionalGroups().add(functionalGroup);
   }

   /**
    * Add a collection of FunctionalGroups to this report setup. This method takes care of
    * Bidirectional setting of ReportFunctionalGroup's report setup.
    *
    * @param functionalGroups
    */
   public void addAllFunctionalGroups(Set functionalGroups) {
      Validate.notNull(functionalGroups, "Null set of functionalGroups specified.");
      this.setParameterOwner(functionalGroups);
      Set internal = this.getInternalFunctionalGroups();
      internal.addAll(functionalGroups);
   }

   /**
    * Remove an ReportFunctionalGroup for this report setup. This method takes care of
    * Bidirectional setting of ReportFunctionalGroup's report setup.
    *
    * @param functionalGroup
    */
   public void removeFunctionalGroup(ReportFunctionalGroup functionalGroup) {
      Validate.notNull(functionalGroup, "Null functionalGroup specified.");
      getInternalFunctionalGroups().remove(functionalGroup);
      functionalGroup.setReportSetup(null);
   }

   public void removeAllFunctionalGroups() {
      this.getInternalFunctionalGroups().clear();
   }

   /**
    * @return A collection of ReportWkfCaseType object internalWkfCaseTypes
    */
   public Set getWkfCaseTypes() {
      return Collections.unmodifiableSet(getInternalWkfCaseTypes());
   }

   public ReportWkfCaseType getWkfCaseTypeByEntityKey(EntityKey identifier) {
      return (ReportWkfCaseType)AbstractKeyedEntity.getEntityByEntityKey(
            getWkfCaseTypes(), identifier);
   }

   public ReportWkfCaseType removeWkfCaseTypeByEntityKey(EntityKey identifier) {
      return (ReportWkfCaseType)AbstractKeyedEntity.removeEntityByEntityKey(
            getInternalWkfCaseTypes(), identifier);
   }

   private Set getInternalWkfCaseTypes() {
      if( this.internalWkfCaseTypes == null ) {
         this.internalWkfCaseTypes = new HashSet();
      }
      return this.internalWkfCaseTypes;
   }

   private void setInternalWkfCaseTypes(Set wkfCaseTypes) {
      this.internalWkfCaseTypes = wkfCaseTypes;
   }

   public void addWkfCaseType(ReportWkfCaseType wkfCaseType) {
      Validate.notNull(wkfCaseType, "Null wkfCaseType specified.");
      wkfCaseType.setReportSetup(reportSetup);
      getInternalWkfCaseTypes().add(wkfCaseType);
   }

   public void addAllWkfCaseTypes(Set wkfCaseTypes) {
      Validate.notNull(wkfCaseTypes, "Null set of wkfCaseTypes specified.");
      this.setParameterOwner(wkfCaseTypes);
      Set internal = this.getInternalWkfCaseTypes();
      internal.addAll(wkfCaseTypes);
   }

   public void removeWkfCaseType(ReportWkfCaseType wkfCaseType) {
      Validate.notNull(wkfCaseType, "Null wkfCaseType specified.");
      getInternalWkfCaseTypes().remove(wkfCaseType);
      wkfCaseType.setReportSetup(null);
   }

   public void removeAllWkfCaseTypes() {
      this.getInternalWkfCaseTypes().clear();
   }

   /**
    * @return A collection of ReportWkfCaseStatusType object internalWkfCaseStatusTypes
    */
   public Set getWkfCaseStatusTypes() {
      return Collections.unmodifiableSet(getInternalWkfCaseStatusTypes());
   }

   public ReportWkfCaseStatusType getWkfCaseStatusTypeByEntityKey(EntityKey identifier) {
      return (ReportWkfCaseStatusType)AbstractKeyedEntity.getEntityByEntityKey(
            getWkfCaseStatusTypes(), identifier);
   }

   public ReportWkfCaseStatusType removeWkfCaseStatusTypeByEntityKey(EntityKey identifier) {
      return (ReportWkfCaseStatusType)AbstractKeyedEntity.removeEntityByEntityKey(
            getInternalWkfCaseStatusTypes(), identifier);
   }

   private Set getInternalWkfCaseStatusTypes() {
      if( this.internalWkfCaseStatusTypes == null ) {
         this.internalWkfCaseStatusTypes = new HashSet();
      }
      return this.internalWkfCaseStatusTypes;
   }

   private void setInternalWkfCaseStatusTypes(Set wkfCaseStatuses) {
      this.internalWkfCaseStatusTypes = wkfCaseStatuses;
   }

   public void addWkfCaseStatusType(ReportWkfCaseStatusType wkfCaseStatusType) {
      Validate.notNull(wkfCaseStatusType, "Null functionalGroup specified.");
      wkfCaseStatusType.setReportSetup(reportSetup);
      getInternalWkfCaseStatusTypes().add(wkfCaseStatusType);
   }

   public void addAllWkfCaseStatusTypes(Set wkfCaseStatusTypes) {
      Validate.notNull(wkfCaseStatusTypes, "Null set of functionalGroups specified.");
      this.setParameterOwner(wkfCaseStatusTypes);
      Set internal = this.getInternalWkfCaseStatusTypes();
      internal.addAll(wkfCaseStatusTypes);
   }

   public void removeWkfCaseStatusType(ReportWkfCaseStatusType wkfCaseStatusType) {
      Validate.notNull(wkfCaseStatusType, "Null functionalGroup specified.");
      getInternalWkfCaseStatusTypes().remove(wkfCaseStatusType);
      wkfCaseStatusType.setReportSetup(null);
   }

   public void removeAllWkfCaseStatusTypes() {
      this.getInternalWkfCaseStatusTypes().clear();
   }

   /**
    * @return A collection of ReportMessageError object
    */
   public Set getMessageErrors() {
      return Collections.unmodifiableSet(getInternalMessageErrors());
   }

   public ReportMessageError getMessageErrorByEntityKey(EntityKey identifier) {
      return (ReportMessageError)AbstractKeyedEntity.getEntityByEntityKey(
            getMessageErrors(), identifier);
   }

   public ReportMessageError removeMessageErrorByEntityKey(EntityKey identifier) {
      return (ReportMessageError)AbstractKeyedEntity.removeEntityByEntityKey(
            getInternalMessageErrors(), identifier);
   }

   /**
    * Getter - for hibernate use only.
    *
    * @return
    */
   private Set getInternalMessageErrors() {
      if( this.internalMessageErrors == null ) {
         this.internalMessageErrors = new HashSet();
      }
      return this.internalMessageErrors;
   }

   /**
    * Setter - for hibernate use only.
    *
    * @param messageErrors
    */
   private void setInternalMessageErrors(Set messageErrors) {
      this.internalMessageErrors = messageErrors;
   }

   /**
    * Add a ReportMessageError for this report setup. This method takes care of
    * Bidirectional setting of ReportMessageError's report setup.
    *
    * @param messageError
    */
   public void addMessageError(ReportMessageError messageError) {
      Validate.notNull(messageError, "Null messageError specified.");
      messageError.setReportSetup(reportSetup);
      getInternalMessageErrors().add(messageError);
   }

   /**
    * Add a collection of MessageErrors to this report setup. This method takes care of
    * Bidirectional setting of ReportMessageError's report setup.
    *
    * @param messageErrors
    */
   public void addAllMessageErrors(Set messageErrors) {
      Validate.notNull(messageErrors, "Null set of messageErrors specified.");
      this.setParameterOwner(messageErrors);
      Set internal = this.getInternalMessageErrors();
      internal.addAll(messageErrors);
   }

   /**
    * Remove an ReportMessageError for this report setup. This method takes care of
    * Bidirectional setting of ReportMessageError's report setup.
    *
    * @param messageError
    */
   public void removeMessageError(ReportMessageError messageError) {
      Validate.notNull(messageError, "Null messageError specified.");
      getInternalMessageErrors().remove(messageError);
      messageError.setReportSetup(null);
   }

   public void removeAllMessageErrors() {
      this.getInternalMessageErrors().clear();
   }

   /**
    * @return A collection of ReportRegistryType object
    */
   public Set getRegistryTypes() {
      return Collections.unmodifiableSet(getInternalRegistryTypes());
   }

   public ReportRegistryType getRegistryTypeByEntityKey(EntityKey identifier) {
      return (ReportRegistryType)AbstractKeyedEntity.getEntityByEntityKey(
            getRegistryTypes(), identifier);
   }

   public ReportRegistryType removeRegistryTypeByEntityKey(EntityKey identifier) {
      return (ReportRegistryType)AbstractKeyedEntity.removeEntityByEntityKey(
            getInternalRegistryTypes(), identifier);
   }

   /**
    * Getter - for hibernate use only.
    *
    * @return
    */
   private Set getInternalRegistryTypes() {
      if( this.internalRegistryTypes == null ) {
         this.internalRegistryTypes = new HashSet();
      }
      return this.internalRegistryTypes;
   }

   /**
    * Setter - for hibernate use only.
    *
    * @param registryTypes
    */
   private void setInternalRegistryTypes(Set registryTypes) {
      this.internalRegistryTypes = registryTypes;
   }

   /**
    * Add a ReportRegistryType for this report setup. This method takes care of
    * Bidirectional setting of ReportRegistryType's report setup.
    *
    * @param registryType
    */
   public void addRegistryType(ReportRegistryType registryType) {
      Validate.notNull(registryType, "Null registryType specified.");
      registryType.setReportSetup(reportSetup);
      getInternalRegistryTypes().add(registryType);
   }

   /**
    * Add a collection of RegistryTypes to this report setup. This method takes care of
    * Bidirectional setting of ReportRegistryType's report setup.
    *
    * @param registryTypes
    */
   public void addAllRegistryTypes(Set registryTypes) {
      Validate.notNull(registryTypes, "Null set of registryTypes specified.");
      this.setParameterOwner(registryTypes);
      Set internal = this.getInternalRegistryTypes();
      internal.addAll(registryTypes);
   }

   /**
    * Remove an ReportRegistryType for this report setup. This method takes care of
    * Bidirectional setting of ReportRegistryType's report setup.
    *
    * @param registryType
    */
   public void removeRegistryType(ReportRegistryType registryType) {
      Validate.notNull(registryType, "Null registryType specified.");
      getInternalRegistryTypes().remove(registryType);
      registryType.setReportSetup(null);
   }

   public void removeAllRegistryTypes() {
      this.getInternalRegistryTypes().clear();
   }

   private Set getInternalEnrollmentOverrideReasons() {
      if( this.internalEnrollmentOverrideReasons == null ) {
         this.internalEnrollmentOverrideReasons = new HashSet();
      }
      return internalEnrollmentOverrideReasons;
   }

   public Set getEnrollmentOverrideReasons() {
      return Collections.unmodifiableSet(getInternalEnrollmentOverrideReasons());
   }

   private void setInternalEnrollmentOverrideReasons(Set internalEnrollmentOverrideReasons) {
      this.internalEnrollmentOverrideReasons = internalEnrollmentOverrideReasons;
   }

   public void addAllEnrollmentOverrideReasons(Set enrollmentOverrideReasons) {
      Validate.notNull(enrollmentOverrideReasons,
            "Null set of enrollmentOverrideReasons specified.");
      this.setParameterOwner(enrollmentOverrideReasons);
      Set internal = this.getInternalEnrollmentOverrideReasons();
      internal.addAll(enrollmentOverrideReasons);
   }

   public void removeAllEnrollmentOverrideReasons() {
      this.getInternalEnrollmentOverrideReasons().clear();
   }

   public void addEnrollmentOverrideReason(ReportEnrollmentOverrideReason reason) {
      Validate.notNull(reason, "Null reason specified.");
      reason.setReportSetup(reportSetup);
      getInternalEnrollmentOverrideReasons().add(reason);
   }

   /**
    * @return A collection of getInternalEnrollmentStatusComponents object
    */
   public Set getEnrollmentStatusComponents() {
      return Collections.unmodifiableSet(getInternalEnrollmentStatusComponents());
   }

   public ReportEnrollmentStatusComponent getEnrollmentStatusComponentByEntityKey(
         EntityKey identifier) {
      return (ReportEnrollmentStatusComponent)AbstractKeyedEntity.getEntityByEntityKey(
            getEnrollmentStatusComponents(), identifier);
   }

   public ReportEnrollmentStatusComponent removeEnrollmentStatusComponentByEntityKey(
         EntityKey identifier) {
      return (ReportEnrollmentStatusComponent)AbstractKeyedEntity
            .removeEntityByEntityKey(getInternalEnrollmentStatusComponents(), identifier);
   }

   /**
    * Getter - for hibernate use only.
    */
   private Set getInternalEnrollmentStatusComponents() {
      if( this.internalEnrollmentStatusComponents == null ) {
         this.internalEnrollmentStatusComponents = new HashSet();
      }
      return this.internalEnrollmentStatusComponents;
   }

   /**
    * Setter - for hibernate use only.
    *
    * @param enrollmentStatusComponents
    */
   private void setInternalEnrollmentStatusComponents(Set enrollmentStatusComponents) {
      this.internalEnrollmentStatusComponents = enrollmentStatusComponents;
   }

   /**
    * Add a ReportEnrollmentStatus for this report setup. This method takes care of
    * Bidirectional setting of ReportEnrollmentStatus's report setup.
    *
    * @param enrollmentStatus
    */
   public void addEnrollmentStatusComponent(ReportEnrollmentStatus enrollmentStatus) {
      Validate.notNull(enrollmentStatus, "Null enrollmentStatus specified.");
      enrollmentStatus.setReportSetup(reportSetup);
      getInternalEnrollmentStatusComponents().add(enrollmentStatus);
   }

   /**
    * Add a collection of ReportEnrollmentStatus to this report setup. This method takes
    * care of Bidirectional setting of ReportEnrollmentStatus's report setup.
    *
    * @param enrollmentStatusComponents
    */
   public void addAllEnrollmentStatusComponents(Set enrollmentStatusComponents) {
      Validate.notNull(enrollmentStatusComponents,
            "Null set of enrollmentStatusComponents specified.");
      this.setParameterOwner(enrollmentStatusComponents);
      Set internal = this.getInternalEnrollmentStatusComponents();
      internal.addAll(enrollmentStatusComponents);
   }

   /**
    * Remove an ReportEnrollmentStatus for this report setup. This method takes care of
    * Bidirectional setting of ReportEnrollmentStatus's report setup.
    *
    * @param enrollmentStatus
    */
   public void removeEnrollmentStatusComponent(ReportEnrollmentStatus enrollmentStatus) {
      Validate.notNull(enrollmentStatus, "Null enrollmentStatus specified.");
      getInternalEnrollmentStatusComponents().remove(enrollmentStatus);
      enrollmentStatus.setReportSetup(null);
   }

   public void removeAllEnrollmentStatusComponents() {
      this.getInternalEnrollmentStatusComponents().clear();
   }

   /**
    * @return A collection of getInternalEligibilityFactors object
    */
   public Set getEligibilityFactors() {
      return Collections.unmodifiableSet(getInternalEligibilityFactors());
   }

   public ReportEligibilityFactor getEligibilityFactorByEntityKey(
         EntityKey identifier) {
      return (ReportEligibilityFactor)AbstractKeyedEntity.getEntityByEntityKey(
            getEligibilityFactors(), identifier);
   }

   public ReportEligibilityFactor removeEligibilityFactorByEntityKey(
         EntityKey identifier) {
      return (ReportEligibilityFactor)AbstractKeyedEntity
            .removeEntityByEntityKey(getInternalEligibilityFactors(), identifier);
   }

   /**
    * Getter - for hibernate use only.
    */
   private Set getInternalEligibilityFactors() {
      if( this.internalEligibilityFactors == null ) {
         this.internalEligibilityFactors = new HashSet();
      }
      return this.internalEligibilityFactors;
   }

   /**
    * Setter - for hibernate use only.
    *
    * @param EligibilityFactors
    */
   private void setInternalEligibilityFactors(Set EligibilityFactors) {
      this.internalEligibilityFactors = EligibilityFactors;
   }

   /**
    * Add a ReportEnrollmentStatus for this report setup. This method takes care of
    * Bidirectional setting of ReportEnrollmentStatus's report setup.
    *
    * @param enrollmentStatus
    */
   public void addEligibilityFactor(ReportEnrollmentStatus enrollmentStatus) {
      Validate.notNull(enrollmentStatus, "Null enrollmentStatus specified.");
      enrollmentStatus.setReportSetup(reportSetup);
      getInternalEligibilityFactors().add(enrollmentStatus);
   }

   /**
    * Add a collection of ReportEnrollmentStatus to this report setup. This method takes
    * care of Bidirectional setting of ReportEnrollmentStatus's report setup.
    *
    * @param EligibilityFactors
    */
   public void addAllEligibilityFactors(Set EligibilityFactors) {
      Validate.notNull(EligibilityFactors,
            "Null set of EligibilityFactors specified.");
      this.setParameterOwner(EligibilityFactors);
      Set internal = this.getInternalEligibilityFactors();
      internal.addAll(EligibilityFactors);
   }

   /**
    * Remove an ReportEnrollmentStatus for this report setup. This method takes care of
    * Bidirectional setting of ReportEnrollmentStatus's report setup.
    *
    * @param enrollmentStatus
    */
   public void removeEligibilityFactor(ReportEnrollmentStatus enrollmentStatus) {
      Validate.notNull(enrollmentStatus, "Null enrollmentStatus specified.");
      getInternalEligibilityFactors().remove(enrollmentStatus);
      enrollmentStatus.setReportSetup(null);
   }

   public void removeAllEligibilityFactors() {
      this.getInternalEligibilityFactors().clear();
   }

   /**
    * @return A collection of getInternalPersonMergeStatuses object
    */
   public Set getPersonMergeStatuses() {
      return Collections.unmodifiableSet(getInternalPersonMergeStatuses());
   }

   public ReportPersonMergeStatus getPersonMergeStatusByEntityKey(
         EntityKey identifier) {
      return (ReportPersonMergeStatus)AbstractKeyedEntity.getEntityByEntityKey(
            getPersonMergeStatuses(), identifier);
   }

   public ReportPersonMergeStatus removePersonMergeStatusByEntityKey(
         EntityKey identifier) {
      return (ReportPersonMergeStatus)AbstractKeyedEntity
            .removeEntityByEntityKey(getInternalPersonMergeStatuses(), identifier);
   }

   /**
    * Getter - for hibernate use only.
    */
   private Set getInternalPersonMergeStatuses() {
      if( this.internalPersonMergeStatuses == null ) {
         this.internalPersonMergeStatuses = new HashSet();
      }
      return this.internalPersonMergeStatuses;
   }

   /**
    * Setter - for hibernate use only.
    *
    * @param PersonMergeStatuses
    */
   private void setInternalPersonMergeStatuses(Set PersonMergeStatuses) {
      this.internalPersonMergeStatuses = PersonMergeStatuses;
   }

   /**
    * Add a ReportEnrollmentStatus for this report setup. This method takes care of
    * Bidirectional setting of ReportEnrollmentStatus's report setup.
    *
    * @param enrollmentStatus
    */
   public void addPersonMergeStatus(ReportEnrollmentStatus enrollmentStatus) {
      Validate.notNull(enrollmentStatus, "Null enrollmentStatus specified.");
      enrollmentStatus.setReportSetup(reportSetup);
      getInternalPersonMergeStatuses().add(enrollmentStatus);
   }

   /**
    * Add a collection of ReportEnrollmentStatus to this report setup. This method takes
    * care of Bidirectional setting of ReportEnrollmentStatus's report setup.
    *
    * @param PersonMergeStatuses
    */
   public void addAllPersonMergeStatuses(Set PersonMergeStatuses) {
      Validate.notNull(PersonMergeStatuses,
            "Null set of PersonMergeStatuses specified.");
      this.setParameterOwner(PersonMergeStatuses);
      Set internal = this.getInternalPersonMergeStatuses();
      internal.addAll(PersonMergeStatuses);
   }

   /**
    * Remove an ReportEnrollmentStatus for this report setup. This method takes care of
    * Bidirectional setting of ReportEnrollmentStatus's report setup.
    *
    * @param enrollmentStatus
    */
   public void removePersonMergeStatus(ReportEnrollmentStatus enrollmentStatus) {
      Validate.notNull(enrollmentStatus, "Null enrollmentStatus specified.");
      getInternalPersonMergeStatuses().remove(enrollmentStatus);
      enrollmentStatus.setReportSetup(null);
   }

   public void removeAllPersonMergeStatuses() {
      this.getInternalPersonMergeStatuses().clear();
   }

   /**
    * @return A collection of ReportEnrollmentProcessStatus object
    */
   public EnrollmentProcessStatus getEnrollmentProcessStatus() {
      return enrollmentProcessStatus;
   }

   /**
    * @param enrollmentProcessStatus
    */
   public void setEnrollmentProcessStatus(EnrollmentProcessStatus enrollmentProcessStatus) {
      this.enrollmentProcessStatus = enrollmentProcessStatus;
   }

   /**
    * @return A collection of ReportFormType object
    */
   public Set getFormTypes() {
      return Collections.unmodifiableSet(getInternalFormTypes());
   }

   public ReportFormType getFormTypeByEntityKey(EntityKey identifier) {
      return (ReportFormType)AbstractKeyedEntity.getEntityByEntityKey(
            getFormTypes(), identifier);
   }

   public ReportFormType removeFormTypeByEntityKey(EntityKey identifier) {
      return (ReportFormType)AbstractKeyedEntity.removeEntityByEntityKey(
            getInternalFormTypes(), identifier);
   }

   /**
    * Getter - for hibernate use only.
    *
    * @return
    */
   private Set getInternalFormTypes() {
      if( this.internalFormTypes == null ) {
         this.internalFormTypes = new HashSet();
      }
      return this.internalFormTypes;
   }

   /**
    * Setter - for hibernate use only.
    *
    * @param FormTypes
    */
   private void setInternalFormTypes(Set formTypes) {
      this.internalFormTypes = formTypes;
   }

   /**
    * Add a ReportFormType for this report setup. This method takes care of
    * Bidirectional setting of ReportFormType's report setup.
    *
    * @param formType
    */
   public void addFormType(ReportFormType formType) {
      Validate.notNull(formType, "Null formType specified.");
      formType.setReportSetup(reportSetup);
      getInternalFormTypes().add(formType);
   }

   /**
    * Add a collection of FormTypes to this report setup. This method takes care
    * of Bidirectional setting of ReportEnrollmentStatus's report setup.
    *
    * @param formTypes
    */
   public void addAllFormTypes(Set formTypes) {
      Validate.notNull(formTypes, "Null set of formTypes specified.");
      this.setParameterOwner(formTypes);
      Set internal = this.getInternalFormTypes();
      internal.addAll(formTypes);
   }

   /**
    * Remove an ReportFormType for this report setup. This method takes care of
    * Bidirectional setting of ReportEnrollmentStatus's report setup.
    *
    * @param formType
    */
   public void removeFormType(ReportFormType formType) {
      Validate.notNull(formType, "Null formType specified.");
      getInternalFormTypes().remove(formType);
      formType.setReportSetup(null);
   }

   public void removeAllFormTypes() {
      this.getInternalFormTypes().clear();
   }

   
   
   /**
    * @param p
    *           A collection of ReportParameter
    */
   private void setParameterOwner(Collection p) {
      Iterator iter = p.iterator();
      while( iter.hasNext() ) {
         ( (ReportParameter)iter.next() ).setReportSetup(reportSetup);
      }
   }

   protected void buildToString(ToStringBuilder builder) {
      // TODO Auto-generated method stub

   }

   private ReportSetup reportSetup;

   private Date fromDate;

   private Date toDate;

   private Date asOfDate;

   private Integer beginIncomeYear;

   private Integer endIncomeYear;

   private ReportDivision division;

   private ReportWorkItemStatus workItemStatus;

   private boolean runReportByUser;

   private Integer batchNumber;

   private ReportExceptionType exceptionType;

   private boolean includeUsers;

   private Date enrollmentEffectiveDateOfChange;

   private Integer daysBetweenUpdates;

   private Integer numberOfRecordsPerEnrollmentStatus; // Number of records to include
                                                         // per enrollment status

   private ReportFormat reportFormat;

   private ReportDetailBy detailBy;

   private ReportDetailFor detailFor;

   private ReportPeriod reportPeriod;

   private boolean allLetterRejectReasons;

   private boolean allLetterErrorTypes;

   private Integer addressUpdateDays; // address update within number of days.

   private Integer phUnconfirmedDays; // ph unconformed more than xxx number of days

   private Date letterFileReceivedDate;

   private ReportFacilityDisplayBy facilityDisplayBy;

   private ReportExportedType fileType;

   private EnrollmentProcessStatus enrollmentProcessStatus;

   private Integer outlierDays;

   private Integer randomNumberOfRecords;

   private Set letterFiles;

   private Set letterRejectReasons;

   private Set letterErrorTypes;

   private Set internalUsers; // the users used as parameters

   private Set internalMessageTypes;

   private Set internalBadAddressReasons;

   private Set internalCancelDeclineReasons;

   private Set internalEnrollmentOverrideReasons;

   private Set internalPHRejectionRemarks;

   private Set internalReportEnrollmentPriorityGroups;

   private Set internalEnrollmentCategories;

   private Set internalEnrollmentStatuses;

   private Set internalQueryToSites;

   private Set internalVBAQueryStatuses;

   private Set internalReportEEDWeeklyReportTypes;

   private Set internalFacilities;

   private Set internalFunctionalGroups;

   private Set internalMessageErrors;

   private Set internalRegistryTypes;

   private Set internalEnrollmentStatusComponents;

   private Set internalPersonMergeStatuses;

   private Set internalEligibilityFactors;

   private Set internalWkfCaseTypes;

   private Set internalWkfCaseStatusTypes;
   
   private Set internalFormTypes;

   protected void finalize() throws Throwable {
      super.finalize();
      setInternalUsers(null);
      setInternalEnrollmentStatusComponents(null);
       setInternalPersonMergeStatuses(null);
       setInternalEligibilityFactors(null);
      setInternalEnrollmentOverrideReasons(null);
      setInternalRegistryTypes(null);
      setInternalMessageErrors(null);
      setInternalWkfCaseStatusTypes(null);
      setInternalWkfCaseTypes(null);
      setInternalFunctionalGroups(null);
      setInternalFacilities(null);
      setInternalReportEEDWeeklyReportTypes(null);
      setInternalVBAQueryStatuses( null );
      setInternalQueryToSites( null );
      setInternalEnrollmentStatuses( null );
      setInternalEnrollmentCategories( null );
      setInternalReportEnrollmentPriorityGroups( null );
      setInternalPHRejectionRemarks( null );
      setInternalCancelDeclineReasons( null );
      setInternalBadAddressReasons( null );
      setInternalMessageTypes( null );
      setInternalFormTypes( null );
   }
}