@Override
 public IGenericTrait getTrait(final ITraitType type) {
   IGenericTrait attribute;
   IBeastformAttribute beastformattribute = beastmanCollection.getDeadlyBeastmanAttribute(type);
   if (beastformattribute == null) {
     attribute = collection.getTrait(type);
   } else {
     attribute = beastformattribute.getTrait();
   }
   final int[] value = new int[1];
   value[0] = attribute.getCurrentValue();
   for (IQualitySelection<?> selection : model.getSelectedQualities()) {
     ((IMutation) selection.getQuality())
         .accept(
             new MutationVisitorAdapter() {
               @Override
               public void visitAttributeEnhancingMutation(AttributeEnhancingMutation mutation) {
                 if (mutation.getAttributeType() == type) {
                   value[0] += mutation.getBonus();
                 }
               }
             });
   }
   return new ValuedTraitType(type, value[0]);
 }
 private int getBackgroundValue(IGenericTraitCollection traitCollection) {
   IGenericTrait background = traitCollection.getTrait(template);
   if (background == null) {
     return 0;
   }
   return background.getCurrentValue();
 }
 @Test
 public void testChangePrimaryPrerequisiteType() throws Exception {
   IGenericTrait unwanted = new ValuedTraitType(AbilityType.Athletics, 4);
   IGenericTrait expected = new ValuedTraitType(AbilityType.Awareness, 4);
   data.setPrimaryPrerequisite(unwanted);
   data.setPrimaryPrerequisite(expected);
   assertEquals(1, data.getPrerequisites().length);
   assertTrue(ArrayUtilities.containsValue(data.getPrerequisites(), expected));
   assertFalse(ArrayUtilities.containsValue(data.getPrerequisites(), unwanted));
   assertEquals(expected.getType(), data.getPrimaryTraitType());
 }
 // TODO: Available dots limit max. value
 public SpiritFormAttribute(IGenericTrait baseTrait, final ICharacterModelContext charContext) {
   ITraitContext context = charContext.getTraitContext();
   ITraitTemplate template = SimpleTraitTemplate.createStaticLimitedTemplate(1, 12);
   TraitRules traitRules =
       new TraitRules(baseTrait.getType(), template, context.getLimitationContext());
   IValueChangeChecker incrementChecker =
       new IValueChangeChecker() {
         @Override
         public boolean isValidNewValue(int value) {
           return value != spiritTrait.getCurrentValue()
               && !charContext.getBasicCharacterContext().isExperienced();
         }
       };
   spiritTrait = new DefaultTrait(traitRules, context, incrementChecker);
   spiritTrait.addCurrentValueListener(
       new IIntValueChangedListener() {
         @Override
         public void valueChanged(int newValue) {
           SpiritFormAttribute.this.newValue = newValue;
         }
       });
 }
  public final boolean isLearnable(ICharm charm) {
    if (isAlienCharm(charm)) {
      ICasteType casteType = context.getBasicCharacterContext().getCasteType();
      if (!getCharmTemplate(getNativeCharacterType()).isAllowedAlienCharms(casteType)) {
        return false;
      }
      if (charm.hasAttribute(ICharmData.NOT_ALIEN_LEARNABLE)) {
        return false;
      }
    }
    if (charm.isBlockedByAlternative(context.getMagicCollection())) {
      return false;
    }
    if (MartialArtsUtilities.isMartialArtsCharm(charm)) {
      boolean isSiderealFormCharm =
          MartialArtsUtilities.isFormCharm(charm)
              && MartialArtsUtilities.hasLevel(MartialArtsLevel.Sidereal, charm);
      if (isSiderealFormCharm
          && !arbitrator.isCelestialMartialArtsGroupCompleted(getMartialArtsGroups())) {
        return false;
      }
      if (!getCharmTemplate(getNativeCharacterType())
          .getMartialArtsRules()
          .isCharmAllowed(
              charm,
              context.getCharmContext().getCharmConfiguration(),
              context.getBasicCharacterContext().isExperienced())) {
        return false;
      }
    }
    for (ICharmAttributeRequirement requirement : charm.getAttributeRequirements()) {
      if (!requirement.isFulfilled(getLearnedCharms(true))) {
        return false;
      }
    }
    for (IGenericTrait prerequisite : charm.getPrerequisites()) {
      IGenericTrait prerequisiteTrait =
          context.getTraitCollection().getTrait(prerequisite.getType());
      int prereq = prerequisite.getCurrentValue();
      for (ISpecialCharm specialCharm : getPrerequisiteModifyingCharms())
        if (specialCharm instanceof IPrerequisiteModifyingCharm
            && isLearned(specialCharm.getCharmId()))
          prereq =
              ((IPrerequisiteModifyingCharm) specialCharm)
                  .getTraitModifier(charm, prerequisiteTrait.getType(), prereq);

      if (prerequisiteTrait == null || prereq > prerequisiteTrait.getCurrentValue()) {
        return false;
      }
    }
    IGenericTrait essenceTrait = context.getTraitCollection().getTrait(OtherTraitType.Essence);
    int essencePrereq = charm.getEssence().getCurrentValue();
    for (ISpecialCharm specialCharm : getPrerequisiteModifyingCharms())
      if (specialCharm instanceof IPrerequisiteModifyingCharm
          && isLearned(specialCharm.getCharmId()))
        essencePrereq =
            ((IPrerequisiteModifyingCharm) specialCharm)
                .getTraitModifier(charm, OtherTraitType.Essence, essencePrereq);
    if (essencePrereq > essenceTrait.getCurrentValue()) {
      return false;
    }
    for (ICharm parentCharm : charm.getLearnPrerequisitesCharms(this)) {
      if (!isLearnable(parentCharm)) {
        return false;
      }
    }
    return true;
  }