/**
  * Acts as a hash for producing the contents of this model.
  *
  * <p>Four items are supported: category, nature, ability and selection.
  *
  * @see freemarker.template.TemplateHashModel#get(java.lang.String)
  */
 @Override
 public TemplateModel get(String key) throws TemplateModelException {
   Object towrap;
   if ("category".equals(key)) {
     towrap = cnas.getCNAbility().getAbilityCategory();
   } else if ("nature".equals(key)) {
     towrap = cnas.getCNAbility().getNature();
   } else if ("ability".equals(key)) {
     towrap = cnas.getCNAbility().getAbility();
   } else if ("selection".equals(key)) {
     towrap = cnas.getSelection();
   } else {
     throw new TemplateModelException("CNAbilitySelection did not have output of type " + key);
   }
   return WRAPPER_FACET.wrap(id, towrap);
 }
 @Override
 protected boolean containsExpected(Ability granted) {
   Collection<CNAbilitySelection> casSet = getTargetFacet().getSet(id);
   for (CNAbilitySelection cnas : casSet) {
     CNAbility cas = cnas.getCNAbility();
     boolean featExpected = cas.getAbilityCategory() == AbilityCategory.FEAT;
     boolean abilityExpected =
         cas.getAbility()
             .equals(
                 context
                     .getReferenceContext()
                     .silentlyGetConstructedCDOMObject(
                         Ability.class, AbilityCategory.FEAT, "Granted"));
     boolean natureExpected = cas.getNature() == Nature.VIRTUAL;
     boolean selectionExpected = cnas.getSelection() == null;
     if (featExpected && abilityExpected && natureExpected && selectionExpected) {
       return true;
     }
   }
   return false;
 }
 public boolean check(CNAbilitySelection cas) {
   return cas.getSelection() == null;
 }