/**
  * Constructs the list of Proposal Abstract Types. Each entry in the list is a <key, value>
  * pair, where the "key" is the unique type code and the "value" is the textual description that
  * is viewed by a user. The list is obtained from the Abstract Type database table via the
  * "keyValuesService". The intent of this method is to provide a list which is viewed in a GUI. As
  * such, the first entry in the list is the generic <"", "select:"> option.
  *
  * <p>The list is also filtered based upon the abstracts currently in the proposal development
  * document. Users are not allowed to create two or more abstracts with the same abstract type.
  * Therefore, if an abstract type is already being used, it is removed from the list. If the
  * document cannot be found, the entire list is returned (it is not filtered).
  *
  * @return the list of &lt;key, value&gt; pairs of abstract types. The first entry is always
  *     &lt;"", "select:"&gt;.
  * @see org.kuali.rice.krad.keyvalues.KeyValuesFinder#getKeyValues()
  */
 @Override
 public List<KeyValue> getKeyValues() {
   ProposalDevelopmentDocument doc = (ProposalDevelopmentDocument) getDocument();
   KeyValuesService keyValuesService =
       (KeyValuesService) KraServiceLocator.getService("keyValuesService");
   Collection<AbstractType> abstractTypes = keyValuesService.findAll(AbstractType.class);
   List<KeyValue> keyValues = new ArrayList<KeyValue>();
   keyValues.add(new ConcreteKeyValue("", "select"));
   for (AbstractType abstractType : abstractTypes) {
     if (!hasAbstract(doc, abstractType)) {
       keyValues.add(
           new ConcreteKeyValue(
               abstractType.getAbstractTypeCode(), abstractType.getDescription()));
     }
   }
   return keyValues;
 }
 /**
  * Does the document already have an abstract using the given abstract type?
  *
  * @param doc the Proposal Development Document.
  * @param abstractType the abstract type to look for.
  * @return true if the abstract type is found; otherwise false.
  */
 private boolean hasAbstract(ProposalDevelopmentDocument doc, AbstractType abstractType) {
   if (doc != null) {
     List<ProposalAbstract> proposalAbstracts =
         doc.getDevelopmentProposal().getProposalAbstracts();
     for (ProposalAbstract proposalAbstract : proposalAbstracts) {
       if (proposalAbstract.getAbstractTypeCode().equals(abstractType.getAbstractTypeCode())) {
         return true;
       }
     }
   }
   return false;
 }