protected List<AbilityMapping> findRaceAbles(final Modifiable E, String tagName, final String prefix, final XMLTag piece, Map<String,Object> defined) throws CMException
	{
		try
		{
			final List<AbilityMapping> V = new Vector<AbilityMapping>();
			final List<XMLLibrary.XMLTag> choices = getAllChoices(E,null,prefix,tagName, piece, defined,true);
			if((choices==null)||(choices.size()==0))
				return V;
			for(int c=0;c<choices.size();c++)
			{
				final XMLTag valPiece = choices.get(c);
				if(valPiece.parms().containsKey("VALIDATE") && !testCondition(E,null,prefix,CMLib.xml().restoreAngleBrackets(valPiece.getParmValue("VALIDATE")),valPiece, defined))
					continue;
				defineReward(E,null,prefix,valPiece.getParmValue("DEFINE"),valPiece,null,defined,true);
				final Set<String> definedSet=getPrevouslyDefined(defined,tagName+"_");
				final String classID = findStringNow("CLASS",valPiece,defined);
				Ability A=CMClass.getAbility(classID);
				if(A == null)
					A=CMClass.findAbility(classID);
				if(A == null)
					throw new CMException("Unable to build ability on classID '"+classID+"', Data: "+CMParms.toKeyValueSlashListString(piece.parms())+":"+CMStrings.limit(piece.value(),100));
				defined.put(prefix+"CLASS", classID);
				final AbilityMapping mapA=CMLib.ableMapper().newAbilityMapping().ID(classID);
				String value;
				value=findOptionalStringNow(E, null, prefix, "PARMS", valPiece, defined, false);
				if(value != null)
				{
					mapA.defaultParm(value);
					defined.put(prefix+"PARMS", value);
				}
				value=findOptionalStringNow(E, null, prefix, "PROFF", valPiece, defined, false);
				if(value != null)
				{
					mapA.defaultProficiency(CMath.parseIntExpression(value));
					defined.put(prefix+"PROFF", Integer.valueOf(mapA.defaultProficiency()));
				}
				value=findOptionalStringNow(E, null, prefix, "LEVEL", valPiece, defined, false);
				if(value != null)
				{
					mapA.qualLevel(CMath.parseIntExpression(value));
					defined.put(prefix+"LEVEL", Integer.valueOf(mapA.qualLevel()));
				}
				value=findOptionalStringNow(E, null, prefix, "QUALIFY", valPiece, defined, false);
				if(value != null)
				{
					mapA.autoGain(!CMath.s_bool(value));
					defined.put(prefix+"QUALIFY", value);
				}
				V.add(mapA);
				clearNewlyDefined(defined, definedSet, tagName+"_");
			}
			return V;
		}
		catch(PostProcessException pe)
		{
			throw new CMException("Unable to post process this object type: "+pe.getMessage(),pe);
		}
	}