@Override
	public String maskDesc(final String text, final boolean skipFirstWord)
	{
		if(text.trim().length()==0)
			return L("Anyone");
		StringBuilder buf=new StringBuilder("");
		final Map<String,ZapperKey> zapCodes=getMaskCodes();
		final List<String> V=CMParms.parse(text.toUpperCase());
		int val=-1;
		for(int v=0;v<V.size();v++)
		{
			final String str=V.get(v);
			val=-1;
			if(zapCodes.containsKey(str))
			{
				switch(zapCodes.get(str))
				{
				case CLASS: // +class
					{
						buf.append(L("Disallows the following class"+(multipleQuals(V,v,"-")?"es":"")+": "));
						for(final SavedClass C : charClasses())
						{
							final String cstr=C.minusNameStart;
							for(int v2=v+1;v2<V.size();v2++)
							{
								final String str2=V.get(v2);
								if(str2.length()==0)
									continue;
								if(zapCodes.containsKey(str2))
									break;
								if(str2.startsWith(cstr))
									buf.append(C.name+", ");
							}
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case _CLASS: // -class
					{
						buf.append(L(skipFirstWord?"Only ":"Allows only "));
						for(final SavedClass C : charClasses())
						{
							final String cstr=C.plusNameStart;
							for(int v2=v+1;v2<V.size();v2++)
							{
								final String str2=V.get(v2);
								if(str2.length()==0)
									continue;
								if(zapCodes.containsKey(str2))
									break;
								if(str2.startsWith(cstr))
									buf.append(C.name+", ");
							}
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case BASECLASS: // +baseclass
					{
						buf.append(L("Disallows the following types"+(multipleQuals(V,v,"-")?"s":"")+": "));
						final HashSet<String> seenBase=new HashSet<String>();
						for(final SavedClass C : charClasses())
						{
							if(!seenBase.contains(C.baseClass))
							{
								seenBase.add(C.baseClass);
								if(fromHereStartsWith(V,'-',v+1,C.baseClassStart))
									buf.append(C.baseClass+" types, ");
							}
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case _BASECLASS: // -baseclass
					{
						buf.append(L(skipFirstWord?"Only ":"Allows only "));
						final HashSet<String> seenBase=new HashSet<String>();
						for(final SavedClass C : charClasses())
						{
							final String cstr=C.plusBaseClassStart;
							if(!seenBase.contains(C.baseClass))
							{
								seenBase.add(C.baseClass);
								for(int v2=v+1;v2<V.size();v2++)
								{
									final String str2=V.get(v2);
									if(str2.length()==0)
										continue;
									if(zapCodes.containsKey(str2))
										break;
									if(str2.startsWith(cstr))
										buf.append(L("@x1 types, ",C.baseClass));
								}
							}
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case _RACE: // -Race
					{
						buf.append(L(skipFirstWord?"Only ":"Allows only "));
						final LinkedList<String> cats=new LinkedList<String>();
						for(final SavedRace R : races())
						{
							if((!cats.contains(R.name)
							&&(fromHereStartsWith(V,'+',v+1,R.nameStart))))
								cats.add(R.name);
						}
						for(final String s : cats)
							buf.append(s+", ");
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case _RACECAT: // -Racecats
					{
						buf.append(L(skipFirstWord?"Only these racial categor"+(multipleQuals(V,v,"+")?"ies":"y")+" ":"Allows only these racial categor"+(multipleQuals(V,v,"+")?"ies":"y")+" "));
						final LinkedList<String> cats=new LinkedList<String>();
						for(final SavedRace R : races())
						{
							if((!cats.contains(R.racialCategory)
							&&(fromHereStartsWith(V,'+',v+1,R.upperCatName))))
								cats.add(R.racialCategory);
						}
						for(final String s : cats)
							buf.append(s+", ");
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case ALIGNMENT: // Alignment
					{
						buf.append(L("Disallows the following alignment"+(multipleQuals(V,v,"-")?"s":"")+": "));
						if(fromHereStartsWith(V,'-',v+1,Faction.Align.EVIL.toString().substring(0,3)))
							buf.append(L(Faction.Align.EVIL.toString().toLowerCase()+", "));
						if(fromHereStartsWith(V,'-',v+1,Faction.Align.GOOD.toString().substring(0,3)))
							buf.append(L(Faction.Align.GOOD.toString().toLowerCase()+", "));
						if(fromHereStartsWith(V,'-',v+1,Faction.Align.NEUTRAL.toString().substring(0,3)))
							buf.append(L(Faction.Align.NEUTRAL.toString().toLowerCase()+", "));
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case _ALIGNMENT: // -Alignment
					{
						buf.append(L(skipFirstWord?"Only ":"Allows only "));
						if(fromHereStartsWith(V,'+',v+1,Faction.Align.EVIL.toString().substring(0,3)))
							buf.append(L(Faction.Align.EVIL.toString().toLowerCase()+", "));
						if(fromHereStartsWith(V,'+',v+1,Faction.Align.GOOD.toString().substring(0,3)))
							buf.append(L(Faction.Align.GOOD.toString().toLowerCase()+", "));
						if(fromHereStartsWith(V,'+',v+1,Faction.Align.NEUTRAL.toString().substring(0,3)))
							buf.append(L(Faction.Align.NEUTRAL.toString().toLowerCase()+", "));
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case GENDER:
					{
						buf.append(L("Disallows the following gender"+(multipleQuals(V,v,"-")?"s":"")+": "));
						if(fromHereStartsWith(V,'-',v+1,"MALE"))
							buf.append(L("Male, "));
						if(fromHereStartsWith(V,'-',v+1,"FEMALE"))
							buf.append(L("Female, "));
						if(fromHereStartsWith(V,'-',v+1,"NEUTER"))
							buf.append(L("Neuter"));
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case _GENDER: // -Gender
					{
						buf.append(L(skipFirstWord?"Only ":"Allows only "));
						if(fromHereStartsWith(V,'+',v+1,"MALE"))
							buf.append(L("Male, "));
						if(fromHereStartsWith(V,'+',v+1,"FEMALE"))
							buf.append(L("Female, "));
						if(fromHereStartsWith(V,'+',v+1,"NEUTER"))
							buf.append(L("Neuter"));
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case _LEVEL: // -Levels
					{
						for(int v2=v+1;v2<V.size();v2++)
							buf.append(levelHelp(V.get(v2),'+',L(skipFirstWord?"Only ":"Allows only ")));
					}
					break;
				case _CLASSLEVEL: // -ClassLevels
					{
						for(int v2=v+1;v2<V.size();v2++)
							buf.append(levelHelp(V.get(v2),'+',L(skipFirstWord?"Only class ":"Allows only class ")));
					}
					break;
				case _MAXCLASSLEVEL: // -MaxclassLevels
					{
						for(int v2=v+1;v2<V.size();v2++)
							buf.append(levelHelp(V.get(v2),'+',L(skipFirstWord?"Only highest class ":"Allows only highest class ")));
					}
					break;
				case _TATTOO: // -Tattoos
					{
						buf.append(L((skipFirstWord?"The":"Requires")+" the following tattoo"+(multipleQuals(V,v,"+")?"s":"")+": "));
						for(int v2=v+1;v2<V.size();v2++)
						{
							final String str2=V.get(v2);
							if(zapCodes.containsKey(str2))
								break;
							if(str2.startsWith("+"))
								buf.append(str2.substring(1)+", ");
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case TATTOO: // +Tattoos
					{
						buf.append(L("Disallows the following tattoo"+(multipleQuals(V,v,"-")?"s":"")+": "));
						for(int v2=v+1;v2<V.size();v2++)
						{
							final String str2=V.get(v2);
							if(zapCodes.containsKey(str2))
								break;
							if(str2.startsWith("-"))
								buf.append(str2.substring(1)+", ");
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case _MOOD: // -Mood
					{
						buf.append(L((skipFirstWord?"The":"Requires")+" the following mood"+(multipleQuals(V,v,"+")?"s":"")+": "));
						for(int v2=v+1;v2<V.size();v2++)
						{
							final String str2=V.get(v2);
							if(zapCodes.containsKey(str2))
								break;
							if(str2.startsWith("+"))
								buf.append(str2.substring(1)+", ");
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case MOOD: // +Mood
					{
						buf.append(L("Disallows the following mood"+(multipleQuals(V,v,"-")?"s":"")+": "));
						for(int v2=v+1;v2<V.size();v2++)
						{
							final String str2=V.get(v2);
							if(zapCodes.containsKey(str2))
								break;
							if(str2.startsWith("-"))
								buf.append(str2.substring(1)+", ");
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case _ACCCHIEVE: // -accchieves
					{
						buf.append(L((skipFirstWord?"The":"Requires")+" the following account achievement"+(multipleQuals(V,v,"+")?"s":"")+": "));
						for(int v2=v+1;v2<V.size();v2++)
						{
							final String str2=V.get(v2);
							if(zapCodes.containsKey(str2))
								break;
							if(str2.startsWith("+"))
							{
								final AchievementLibrary.Achievement A=CMLib.achievements().getAchievement(str2.substring(1));
								if(A!=null)
									buf.append(A.getDisplayStr()+", ");
								else
									buf.append(str2.substring(1)+", ");
							}
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case ACCCHIEVE: // +accchieves
					{
						buf.append(L("Disallows the following account achievement"+(multipleQuals(V,v,"-")?"s":"")+": "));
						for(int v2=v+1;v2<V.size();v2++)
						{
							final String str2=V.get(v2);
							if(zapCodes.containsKey(str2))
								break;
							if(str2.startsWith("-"))
							{
								final AchievementLibrary.Achievement A=CMLib.achievements().getAchievement(str2.substring(1));
								if(A!=null)
									buf.append(A.getDisplayStr()+", ");
								else
									buf.append(str2.substring(1)+", ");
							}
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case _SECURITY: // -Security
					{
						buf.append(L((skipFirstWord?"The":"Requires")+" following security flag"+(multipleQuals(V,v,"+")?"s":"")+": "));
						for(int v2=v+1;v2<V.size();v2++)
						{
							final String str2=V.get(v2);
							if(zapCodes.containsKey(str2))
								break;
							if(str2.startsWith("+"))
								buf.append(str2.substring(1)+", ");
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case SECURITY: // +security
					{
						buf.append(L("Disallows the following security flag"+(multipleQuals(V,v,"-")?"s":"")+": "));
						for(int v2=v+1;v2<V.size();v2++)
						{
							final String str2=V.get(v2);
							if(zapCodes.containsKey(str2))
								break;
							if(str2.startsWith("-"))
								buf.append(str2.substring(1)+", ");
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case _EXPERTISE: // -expertises
					{
						buf.append(L((skipFirstWord?"The":"Requires")+" following expertise"+(multipleQuals(V,v,"+")?"s":"")+": "));
						for(int v2=v+1;v2<V.size();v2++)
						{
							final String str2=V.get(v2);
							if(zapCodes.containsKey(str2))
								break;
							if(str2.startsWith("+"))
							{
								final ExpertiseLibrary.ExpertiseDefinition E=CMLib.expertises().getDefinition(str2.substring(1).toUpperCase().trim());
								if(E!=null)
									buf.append(E.name()+", ");
							}
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case EXPERTISE: // +expertises
					{
						buf.append(L("Disallows the following expertise"+(multipleQuals(V,v,"-")?"s":"")+": "));
						for(int v2=v+1;v2<V.size();v2++)
						{
							final String str2=V.get(v2);
							if(zapCodes.containsKey(str2))
								break;
							if(str2.startsWith("-"))
							{
								final ExpertiseLibrary.ExpertiseDefinition E=CMLib.expertises().getDefinition(str2.substring(1).toUpperCase().trim());
								if(E!=null)
									buf.append(E.name()+", ");
							}
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case _SKILLFLAG: // -skillflags
					{
						buf.append(L((skipFirstWord?"A":"Requires a")+" skill of type: "));
						for(int v2=v+1;v2<V.size();v2++)
						{
							final String str2=V.get(v2);
							if(zapCodes.containsKey(str2))
								break;
							if(str2.startsWith("+"))
							{
								final List<String> V3=CMParms.parseAny(str2.substring(1),'&',true);
								String str3=null;
								for(int v3=0;v3<V3.size();v3++)
								{
									str3=CMStrings.replaceAll(CMStrings.capitalizeAndLower(V3.get(v3)),"_"," ");
									if(str3.startsWith("!"))
										buf.append("not "+str3.substring(1));
									else
										buf.append(str3);
									if(v3<(V3.size()-1))
										buf.append(" and ");
									else
										buf.append(", ");
								}
							}
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case _SKILL: // -skills
					{
						buf.append(L((skipFirstWord?"O":"Requires o")+"ne of the following skills: "));
						for(int v2=v+1;v2<V.size();v2++)
						{
							String str2=V.get(v2);
							if(zapCodes.containsKey(str2))
								break;
							if(str2.startsWith("+"))
							{
								int prof=0;
								str2=str2.substring(1);
								final int x=str2.indexOf('(');
								if(x>0)
								{
									if(str2.endsWith(")"))
										prof=CMath.s_int(str2.substring(x+1,str2.length()-1));
									str2=str2.substring(0,x);
								}
								final Ability A=CMClass.getAbility(str2);
								if(A!=null)
								{
									if(prof<=0)
										buf.append(A.name()+", ");
									else
										buf.append(L("@x1 at @x2% proficiency, ",A.name(),""+prof));
								}
							}
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case SKILL: // +skills
					{
						buf.append(L("Disallows the following skill"+(multipleQuals(V,v,"-")?"s":"")+": "));
						for(int v2=v+1;v2<V.size();v2++)
						{
							String str2=V.get(v2);
							if(zapCodes.containsKey(str2))
								break;
							if(str2.startsWith("-"))
							{
								int prof=0;
								str2=str2.substring(1);
								final int x=str2.indexOf('(');
								if(x>0)
								{
									if(str2.endsWith(")"))
										prof=CMath.s_int(str2.substring(x+1,str2.length()-1));
									str2=str2.substring(0,x);
								}
								final Ability A=CMClass.getAbility(str2);
								if(A!=null)
								{
									if(prof<=0)
										buf.append(A.name()+", ");
									else
										buf.append(L("@x1 at more than @x2% proficiency, ",A.name(),""+prof));
								}
							}
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case SKILLFLAG: // +skillflag
					{
						buf.append(L("Disallows the skill of type: "));
						for(int v2=v+1;v2<V.size();v2++)
						{
							final String str2=V.get(v2);
							if(zapCodes.containsKey(str2))
								break;
							if(str2.startsWith("-"))
							{
								final List<String> V3=CMParms.parseAny(str2.substring(1),'&',true);
								String str3=null;
								for(int v3=0;v3<V3.size();v3++)
								{
									str3=CMStrings.replaceAll(CMStrings.capitalizeAndLower(V3.get(v3)),"_"," ");
									if(str3.startsWith("!"))
										buf.append("not "+str3.substring(1));
									else
										buf.append(str3);
									if(v3<(V3.size()-1))
										buf.append(" and ");
									else
										buf.append(", ");
								}
							}
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case _CLAN: // -Clan
					{
						buf.append(L((skipFirstWord?"M":"Requires m")+"embership in the following clan"+(multipleQuals(V,v,"+")?"s":"")+": "));
						for(int v2=v+1;v2<V.size();v2++)
						{
							final String str2=V.get(v2);
							if(zapCodes.containsKey(str2))
								break;
							if(str2.startsWith("+"))
								buf.append(str2.substring(1)+", ");
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case CLAN: // +Clan
					{
						buf.append(L("Disallows the following clan"+(multipleQuals(V,v,"-")?"s":"")+": "));
						for(int v2=v+1;v2<V.size();v2++)
						{
							final String str2=V.get(v2);
							if(zapCodes.containsKey(str2))
								break;
							if(str2.startsWith("-"))
								buf.append(str2.substring(1)+", ");
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case _MATERIAL: // -Material
					{
						buf.append(L((skipFirstWord?"C":"Requires c")+"onstruction from the following material"+(multipleQuals(V,v,"+")?"s":"")+": "));
						for(int v2=v+1;v2<V.size();v2++)
						{
							final String str2=V.get(v2);
							if(zapCodes.containsKey(str2))
								break;
							if(str2.startsWith("+"))
							{
								final int code=CMLib.materials().getMaterialCode(str2.substring(1),false);
								if(code>=0)
									buf.append(RawMaterial.Material.findByMask(code).noun()+", ");
							}
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case MATERIAL: // +Material
					{
						buf.append(L("Disallows items of the following material"+(multipleQuals(V,v,"-")?"s":"")+": "));
						for(int v2=v+1;v2<V.size();v2++)
						{
							final String str2=V.get(v2);
							if(zapCodes.containsKey(str2))
								break;
							if(str2.startsWith("-"))
							{
								final int code=CMLib.materials().getMaterialCode(str2.substring(1),false);
								if(code>=0)
									buf.append(RawMaterial.Material.findByMask(code).noun()+", ");
							}
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case _WORNON: // -wornon
					{
						buf.append(L((skipFirstWord?"A":"Requires a")+"bility to be worn: "));
						for(int v2=v+1;v2<V.size();v2++)
						{
							final String str2=V.get(v2);
							if(zapCodes.containsKey(str2))
								break;
							if(str2.startsWith("+"))
							{
								final long code=Wearable.CODES.FIND_endsWith(str2.substring(1));
								if(code>=0)
									buf.append(Wearable.CODES.NAME(code)+", ");
							}
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case WORNON: // +wornon
					{
						buf.append(L("Disallows items capable of being worn: "));
						for(int v2=v+1;v2<V.size();v2++)
						{
							final String str2=V.get(v2);
							if(zapCodes.containsKey(str2))
								break;
							if(str2.startsWith("-"))
							{
								final long code=Wearable.CODES.FIND_endsWith(str2.substring(1));
								if(code>=0)
									buf.append(Wearable.CODES.NAME(code)+", ");
							}
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case _SENSES: // -senses
					{
						buf.append(L((skipFirstWord?"The":"Requires")+" following sense"+(multipleQuals(V,v,"+")?"s":"")+": "));
						for(int v2=v+1;v2<V.size();v2++)
						{
							final String str2=V.get(v2);
							if(zapCodes.containsKey(str2))
								break;
							if(str2.startsWith("+"))
							{
								final int code=CMLib.flags().getSensesIndex(str2.substring(1));
								if(code>=0)
									buf.append(PhyStats.CAN_SEE_DESCS[code]+", ");
							}
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case SENSES: // +senses
					{
						buf.append(L("Disallows the following sense"+(multipleQuals(V,v,"-")?"s":"")+": "));
						for(int v2=v+1;v2<V.size();v2++)
						{
							final String str2=V.get(v2);
							if(zapCodes.containsKey(str2))
								break;
							if(str2.startsWith("-"))
							{
								final int code=CMLib.flags().getSensesIndex(str2.substring(1));
								if(code>=0)
									buf.append(PhyStats.CAN_SEE_DESCS[code]+", ");
							}
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case HOUR: // +HOUR
					{
						buf.append(L("Disallowed during the following time"+(multipleQuals(V,v,"-")?"s":"")+" of the day: "));
						for(int v2=v+1;v2<V.size();v2++)
						{
							final String str2=V.get(v2);
							if(zapCodes.containsKey(str2))
								break;
							if(str2.startsWith("-"))
								buf.append(CMath.s_int(str2.substring(1).trim())+", ");
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case _HOUR: // -HOUR
					{
						buf.append(L((skipFirstWord?"Only ":"Allowed only ")+"during the following time"+(multipleQuals(V,v,"+")?"s":"")+" of the day: "));
						for(int v2=v+1;v2<V.size();v2++)
						{
							final String str2=V.get(v2);
							if(zapCodes.containsKey(str2))
								break;
							if(str2.startsWith("+"))
								buf.append(CMath.s_int(str2.substring(1).trim())+", ");
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case SEASON: // +season
					{
						buf.append(L("Disallowed during the following season"+(multipleQuals(V,v,"-")?"s":"")+": "));
						for(int v2=v+1;v2<V.size();v2++)
						{
							final String str2=V.get(v2);
							if(zapCodes.containsKey(str2))
								break;
							if(str2.startsWith("-"))
							{
								if(CMath.isInteger(str2.substring(1).trim()))
								{
									final int season=CMath.s_int(str2.substring(1).trim());
									if((season>=0)&&(season<TimeClock.Season.values().length))
										buf.append(TimeClock.Season.values()[season].toString()+", ");
								}
								else
								{
									final int season=determineSeasonCode(str2.substring(1).trim());
									if((season>=0)&&(season<TimeClock.Season.values().length))
										buf.append(TimeClock.Season.values()[season].toString()+", ");
								}
							}
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case _SEASON: // -season
					{
						buf.append(L((skipFirstWord?"Only ":"Allowed only ")+"during the following season"+(multipleQuals(V,v,"+")?"s":"")+": "));
						for(int v2=v+1;v2<V.size();v2++)
						{
							final String str2=V.get(v2);
							if(zapCodes.containsKey(str2))
								break;
							if(str2.startsWith("+"))
							{
								if(CMath.isInteger(str2.substring(1).trim()))
								{
									final int season=CMath.s_int(str2.substring(1).trim());
									if((season>=0)&&(season<TimeClock.Season.values().length))
										buf.append(TimeClock.Season.values()[season].toString()+", ");
								}
								else
								{
									final int season=determineSeasonCode(str2.substring(1).trim());
									if((season>=0)&&(season<TimeClock.Season.values().length))
										buf.append(TimeClock.Season.values()[season].toString()+", ");
								}
							}
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case WEATHER: // +weather
					{
						buf.append(L("Disallowed during the following weather condition"+(multipleQuals(V,v,"-")?"s":"")+": "));
						for(int v2=v+1;v2<V.size();v2++)
						{
							final String str2=V.get(v2);
							if(zapCodes.containsKey(str2))
								break;
							if(str2.startsWith("-"))
							{
								if(CMath.isInteger(str2.substring(1).trim()))
								{
									final int weather=CMath.s_int(str2.substring(1).trim());
									if((weather>=0)&&(weather<Climate.WEATHER_DESCS.length))
										buf.append(CMStrings.capitalizeAndLower(Climate.WEATHER_DESCS[weather])+", ");
								}
								else
								{
									final int weather=CMParms.indexOf(Climate.WEATHER_DESCS,str2.substring(1).toUpperCase().trim());
									if((weather>=0)&&(weather<Climate.WEATHER_DESCS.length))
										buf.append(CMStrings.capitalizeAndLower(Climate.WEATHER_DESCS[weather])+", ");
								}
							}
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case _WEATHER: // -weather
					{
						buf.append(L((skipFirstWord?"Only ":"Allowed only ")+"during the following weather condition"+(multipleQuals(V,v,"+")?"s":"")+": "));
						for(int v2=v+1;v2<V.size();v2++)
						{
							final String str2=V.get(v2);
							if(zapCodes.containsKey(str2))
								break;
							if(str2.startsWith("+"))
							{
								if(CMath.isInteger(str2.substring(1).trim()))
								{
									final int weather=CMath.s_int(str2.substring(1).trim());
									if((weather>=0)&&(weather<Climate.WEATHER_DESCS.length))
										buf.append(CMStrings.capitalizeAndLower(Climate.WEATHER_DESCS[weather])+", ");
								}
								else
								{
									final int weather=CMParms.indexOf(Climate.WEATHER_DESCS,str2.substring(1).toUpperCase().trim());
									if((weather>=0)&&(weather<Climate.WEATHER_DESCS.length))
										buf.append(CMStrings.capitalizeAndLower(Climate.WEATHER_DESCS[weather])+", ");
								}
							}
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case MONTH: // +month
					{
						buf.append(L("Disallowed during the following month"+(multipleQuals(V,v,"-")?"s":"")+": "));
						for(int v2=v+1;v2<V.size();v2++)
						{
							final String str2=V.get(v2);
							if(zapCodes.containsKey(str2))
								break;
							if(str2.startsWith("-"))
								buf.append(CMath.s_int(str2.substring(1).trim())+", ");
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case _MONTH: // -month
					{
						buf.append(L((skipFirstWord?"Only ":"Allowed only ")+"during the following month"+(multipleQuals(V,v,"+")?"s":"")+": "));
						for(int v2=v+1;v2<V.size();v2++)
						{
							final String str2=V.get(v2);
							if(zapCodes.containsKey(str2))
								break;
							if(str2.startsWith("+"))
								buf.append(CMath.s_int(str2.substring(1).trim())+", ");
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case DAY: // +day
					{
						buf.append(L("Disallowed during the following day"+(multipleQuals(V,v,"-")?"s":"")+" of the month: "));
						for(int v2=v+1;v2<V.size();v2++)
						{
							final String str2=V.get(v2);
							if(zapCodes.containsKey(str2))
								break;
							if(str2.startsWith("-"))
								buf.append(CMath.s_int(str2.substring(1).trim())+", ");
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case _DAY: // -day
					{
						buf.append(L((skipFirstWord?"Only ":"Allowed only ")+"on the following day"+(multipleQuals(V,v,"+")?"s":"")+" of the month: "));
						for(int v2=v+1;v2<V.size();v2++)
						{
							final String str2=V.get(v2);
							if(zapCodes.containsKey(str2))
								break;
							if(str2.startsWith("+"))
								buf.append(CMath.s_int(str2.substring(1).trim())+", ");
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;

				case QUALLVL: // +quallvl
					if((v+1)<V.size())
					{
						final Ability A=CMClass.getAbility(V.get(v+1));
						if(A!=null)
						{
							int adjustment=0;
							if(((v+2)<V.size())&&(CMath.isInteger(V.get(v+2))))
								adjustment=CMath.s_int(V.get(v+2));
							buf.append(A.Name());
							if(adjustment!=0)
								buf.append(L("Qualifies for @x1",A.Name()));
							else
							if(adjustment<0)
								buf.append(L("@x1 levels before qualifying for @x2",""+(-adjustment),A.Name()));
							else
								buf.append(L("@x1 levels after qualifying for @x2",""+adjustment,A.Name()));
							buf.append(".  ");
						}
					}
					break;
				case _QUALLVL: // -quallvl
					if((v+1)<V.size())
					{
						final Ability A=CMClass.getAbility(V.get(v+1));
						if(A!=null)
						{
							int adjustment=0;
							if(((v+2)<V.size())&&(CMath.isInteger(V.get(v+2))))
								adjustment=CMath.s_int(V.get(v+2));
							buf.append(A.Name());
							if(adjustment!=0)
								buf.append(L("Does not qualify for @x1",A.Name()));
							else
							if(adjustment<0)
								buf.append(L("Still prior to @x1 levels before qualifying for @x2",""+(-adjustment),A.Name()));
							else
								buf.append(L("Still prior to @x1 levels after qualifying for @x2",""+adjustment,A.Name()));
							buf.append(".  ");
						}
					}
					break;
				case _DISPOSITION: // -disposition
					{
						buf.append(L((skipFirstWord?"The":"Requires")+" following disposition"+(multipleQuals(V,v,"+")?"s":"")+": "));
						for(int v2=v+1;v2<V.size();v2++)
						{
							final String str2=V.get(v2);
							if(zapCodes.containsKey(str2))
								break;
							if(str2.startsWith("+"))
							{
								final int code=CMLib.flags().getDispositionIndex(str2.substring(1));
								if(code>=0)
									buf.append(PhyStats.IS_DESCS[code]+", ");
							}
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case DISPOSITION: // +disposition
					{
						buf.append(L("Disallows the following disposition"+(multipleQuals(V,v,"-")?"s":"")+": "));
						for(int v2=v+1;v2<V.size();v2++)
						{
							final String str2=V.get(v2);
							if(zapCodes.containsKey(str2))
								break;
							if(str2.startsWith("-"))
							{
								final int code=CMLib.flags().getDispositionIndex(str2.substring(1));
								if(code>=0)
									buf.append(PhyStats.IS_DESCS[code]+", ");
							}
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case _RESOURCE: // -Resource
					{
						buf.append(L((skipFirstWord?"C":"Requires c")+"onstruction from the following material"+(multipleQuals(V,v,"+")?"s":"")+": "));
						for(int v2=v+1;v2<V.size();v2++)
						{
							final String str2=V.get(v2);
							if(zapCodes.containsKey(str2))
								break;
							if(str2.startsWith("+"))
							{
								final int code=CMLib.materials().getResourceCode(str2.substring(1),false);
								if(code>=0)
									buf.append(CMStrings.capitalizeAndLower(RawMaterial.CODES.NAME(code))+", ");
							}
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case RESOURCE: // +Resource
					{
						buf.append(L("Disallows items of the following material"+(multipleQuals(V,v,"-")?"s":"")+": "));
						for(int v2=v+1;v2<V.size();v2++)
						{
							final String str2=V.get(v2);
							if(zapCodes.containsKey(str2))
								break;
							if(str2.startsWith("-"))
							{
								final int code=CMLib.materials().getResourceCode(str2.substring(1),false);
								if(code>=0)
									buf.append(CMStrings.capitalizeAndLower(RawMaterial.CODES.NAME(code))+", ");
							}
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case _JAVACLASS: // -JavaClass
					{
						buf.append(L((skipFirstWord?"B":"Requires b")+"eing of the following type"+(multipleQuals(V,v,"+")?"s":"")+": "));
						for(int v2=v+1;v2<V.size();v2++)
						{
							final String str2=V.get(v2);
							if(zapCodes.containsKey(str2))
								break;
							if(str2.startsWith("+"))
								buf.append(str2.substring(1)+", ");
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case JAVACLASS: // +JavaClass
					{
						buf.append(L("Disallows being of the following type"+(multipleQuals(V,v,"-")?"s":"")+": "));
						for(int v2=v+1;v2<V.size();v2++)
						{
							final String str2=V.get(v2);
							if(zapCodes.containsKey(str2))
								break;
							if(str2.startsWith("-"))
								buf.append(str2.substring(1)+", ");
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case _DEITY: // -Deity
					{
						buf.append(L((skipFirstWord?"W":"Requires w")+"orshipping the following deity"+(multipleQuals(V,v,"+")?"s":"")+": "));
						for(int v2=v+1;v2<V.size();v2++)
						{
							final String str2=V.get(v2);
							if(zapCodes.containsKey(str2))
								break;
							if(str2.startsWith("+"))
								buf.append(str2.substring(1)+", ");
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case DEITY: // +Deity
					{
						buf.append(L("Disallows the worshippers of: "));
						for(int v2=v+1;v2<V.size();v2++)
						{
							final String str2=V.get(v2);
							if(zapCodes.containsKey(str2))
								break;
							if(str2.startsWith("-"))
								buf.append(str2.substring(1)+", ");
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case NAME: // +Names
					{
						buf.append(L("Disallows the following mob/player name"+(multipleQuals(V,v,"-")?"s":"")+": "));
						for(int v2=v+1;v2<V.size();v2++)
						{
							final String str2=V.get(v2);
							if(zapCodes.containsKey(str2))
								break;
							if(str2.startsWith("-"))
								buf.append(str2.substring(1)+", ");
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case _NAME: // -Names
					{
						buf.append(L((skipFirstWord?"The":"Requires")+" following name"+(multipleQuals(V,v,"+")?"s":"")+": "));
						for(int v2=v+1;v2<V.size();v2++)
						{
							final String str2=V.get(v2);
							if(zapCodes.containsKey(str2))
								break;
							if(str2.startsWith("+"))
								buf.append(str2.substring(1)+", ");
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case _QUESTWIN: // -Questwin
					{
						buf.append(L((skipFirstWord?"Completing":"Requires completing")+" the following quest"+(multipleQuals(V,v,"+")?"s":"")+": "));
						for(int v2=v+1;v2<V.size();v2++)
						{
							final String str2=V.get(v2);
							if(zapCodes.containsKey(str2))
								break;
							if(str2.startsWith("+"))
							{
								final Quest Q=CMLib.quests().fetchQuest(str2.substring(1));
								if(Q==null)
									buf.append(str2.substring(1)+", ");
								else
								if((Q.displayName()!=null)&&(Q.displayName().trim().length()>0))
									buf.append(Q.displayName()+", ");
								else
									buf.append(Q.name()+", ");
							}
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case QUESTWIN: // +Questwin
					{
						buf.append(L("Disallows those who`ve won the following quest"+(multipleQuals(V,v,"-")?"s":"")+": "));
						for(int v2=v+1;v2<V.size();v2++)
						{
							final String str2=V.get(v2);
							if(zapCodes.containsKey(str2))
								break;
							if(str2.startsWith("-"))
							{
								final Quest Q=CMLib.quests().fetchQuest(str2.substring(1));
								if(Q==null)
									buf.append(str2.substring(1)+", ");
								else
								if((Q.displayName()!=null)&&(Q.displayName().trim().length()>0))
									buf.append(Q.displayName()+", ");
								else
									buf.append(Q.name()+", ");
							}
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case _PLAYER: // -Player
					buf.append(L("Disallows players.  "));
					break;
				case _NPC: // -MOB
					buf.append(L("Disallows mobs/npcs.  "));
					break;
				case RACE: // +races
					{
						buf.append(L("Disallows the following race"+(multipleQuals(V,v,"-")?"s":"")+": "));
						for(int v2=v+1;v2<V.size();v2++)
						{
							final String str2=V.get(v2);
							if(zapCodes.containsKey(str2))
								break;
							if(str2.startsWith("-"))
								buf.append(str2.substring(1)+", ");
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case RACECAT: // +racecats
					{
						buf.append(L("Disallows the following racial category"+(multipleQuals(V,v,"-")?"s":"")+": "));
						for(int v2=v+1;v2<V.size();v2++)
						{
							final String str2=V.get(v2);
							if(zapCodes.containsKey(str2))
								break;
							if(str2.startsWith("-"))
								buf.append(str2.substring(1)+", ");
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case _ANYCLASSLEVEL: // -anyclasslevel
					{
						String className = "";
						for(int v2=v+1;v2<V.size();v2++)
						{
							final String s = V.get(v2);
							if(getMaskCodes().containsKey(s))
								break;
							boolean checkForClass = true;
							boolean found=false;
							if(className.length()>0)
							{
								StringBuilder lvlHelp = levelHelp(V.get(v2),'+',L(skipFirstWord?"Only "+className+" ":"Allows only "+className+" "));
								if(lvlHelp.length()>0)
								{
									buf.append(lvlHelp);
									checkForClass = false;
									found=true;
								}
							}
							if(checkForClass)
							{
								for(final SavedClass C : charClasses())
								{
									if(s.startsWith('+'+C.nameStart))
									{
										className = C.name;
										found=true;
										break;
									}
								}
							}
							if(!found)
								break;
						}
					}
					break;
				case ANYCLASSLEVEL: // +anyclasslevel
					{
						String className = "";
						for(int v2=v+1;v2<V.size();v2++)
						{
							final String s = V.get(v2);
							if(getMaskCodes().containsKey(s))
							{
								v=v2-1;
								break;
							}
							boolean checkForClass = true;
							boolean found=false;
							if(className.length()>0)
							{
								StringBuilder lvlHelp = levelHelp(V.get(v2),'-',"Disallows "+className+" ");
								if(lvlHelp.length()>0)
								{
									buf.append(lvlHelp);
									checkForClass = false;
									found = true;
								}
							}
							if(checkForClass)
							{
								for(final SavedClass C : charClasses())
								{
									if(s.startsWith('-'+C.nameStart))
									{
										className = C.name;
										found = true;
										break;
									}
								}
							}
							if(!found)
							{
								v=v2-1;
								break;
							}
							else
							if(v2==V.size()-1)
							{
								v=v2;
								break;
							}
						}
					}
					break;
				case _ANYCLASS: // -anyclass
					{
						buf.append(L((skipFirstWord?"L":"Requires l")+"evels in one of the following:  "));
						for(final SavedClass C : charClasses())
						{
							if(fromHereStartsWith(V,'+',v+1,C.nameStart))
								buf.append(C.name+", ");
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case ANYCLASS: // +anyclass
					{
						buf.append(L("Disallows any levels in any of the following:  "));
						for(final SavedClass C : charClasses())
						{
							if(fromHereStartsWith(V,'-',v+1,C.nameStart))
								buf.append(C.name+", ");
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case ADJSTRENGTH: // +adjstr
					val=((++v)<V.size())?CMath.s_int(V.get(v)):0;
					buf.append(L((skipFirstWord?"A":"Requires a")+" strength of at least @x1.  ",""+val));
					break;
				case ADJINTELLIGENCE: // +adjint
					val=((++v)<V.size())?CMath.s_int(V.get(v)):0;
					buf.append(L((skipFirstWord?"An":"Requires an")+" intelligence of at least @x1.  ",""+val));
					break;
				case ADJWISDOM: // +adjwis
					val=((++v)<V.size())?CMath.s_int(V.get(v)):0;
					buf.append(L((skipFirstWord?"A":"Requires a")+" wisdom of at least @x1.  ",""+val));
					break;
				case ADJDEXTERITY: // +adjdex
					val=((++v)<V.size())?CMath.s_int(V.get(v)):0;
					buf.append(L((skipFirstWord?"A":"Requires a")+" dexterity of at least @x1.  ",""+val));
					break;
				case ADJCONSTITUTION: // -adjcha
					val=((++v)<V.size())?CMath.s_int(V.get(v)):0;
					buf.append(L((skipFirstWord?"A":"Requires a")+" constitution of at least @x1.  ",""+val));
					break;
				case ADJCHARISMA: // +adjcha
					val=((++v)<V.size())?CMath.s_int(V.get(v)):0;
					buf.append(L((skipFirstWord?"A":"Requires a")+" charisma of at least @x1.  ",""+val));
					break;
				case _ADJSTRENGTH: // -adjstr
					val=((++v)<V.size())?CMath.s_int(V.get(v)):0;
					buf.append(L((skipFirstWord?"A":"Requires a")+" strength of at most @x1.  ",""+val));
					break;
				case _ADJINTELLIGENCE: // -adjint
					val=((++v)<V.size())?CMath.s_int(V.get(v)):0;
					buf.append(L((skipFirstWord?"An":"Requires an")+" intelligence of at most @x1.  ",""+val));
					break;
				case _ADJWISDOM: // -adjwis
					val=((++v)<V.size())?CMath.s_int(V.get(v)):0;
					buf.append(L((skipFirstWord?"A":"Requires a")+" wisdom of at most @x1.  ",""+val));
					break;
				case _ADJDEXTERITY: // -adjdex
					val=((++v)<V.size())?CMath.s_int(V.get(v)):0;
					buf.append(L((skipFirstWord?"A":"Requires a")+" dexterity of at most @x1.  ",""+val));
					break;
				case _ADJCONSTITUTION: // -adjcon
					val=((++v)<V.size())?CMath.s_int(V.get(v)):0;
					buf.append(L((skipFirstWord?"A":"Requires a")+" constitution of at most @x1.  ",""+val));
					break;
				case _ADJCHARISMA: // -adjcha
					val=((++v)<V.size())?CMath.s_int(V.get(v)):0;
					buf.append(L((skipFirstWord?"A":"Requires a")+" charisma of at most @x1.  ",""+val));
					break;
				case STRENGTH: // +str
					val=((++v)<V.size())?CMath.s_int(V.get(v)):0;
					buf.append(L((skipFirstWord?"A":"Requires a")+" base strength of at least @x1.  ",""+val));
					break;
				case INTELLIGENCE: // +int
					val=((++v)<V.size())?CMath.s_int(V.get(v)):0;
					buf.append(L((skipFirstWord?"A":"Requires a")+" base intelligence of at least @x1.  ",""+val));
					break;
				case WISDOM: // +wis
					val=((++v)<V.size())?CMath.s_int(V.get(v)):0;
					buf.append(L((skipFirstWord?"A":"Requires a")+" base wisdom of at least @x1.  ",""+val));
					break;
				case DEXTERITY: // +dex
					val=((++v)<V.size())?CMath.s_int(V.get(v)):0;
					buf.append(L((skipFirstWord?"A":"Requires a")+" base dexterity of at least @x1.  ",""+val));
					break;
				case CONSTITUTION: // +con
					val=((++v)<V.size())?CMath.s_int(V.get(v)):0;
					buf.append(L((skipFirstWord?"A":"Requires a")+" base constitution of at least @x1.  ",""+val));
					break;
				case CHARISMA: // +cha
					val=((++v)<V.size())?CMath.s_int(V.get(v)):0;
					buf.append(L((skipFirstWord?"A":"Requires a")+" base charisma of at least @x1.  ",""+val));
					break;
				case _STRENGTH: // -str
					val=((++v)<V.size())?CMath.s_int(V.get(v)):0;
					buf.append(L((skipFirstWord?"A":"Requires a")+" base strength of at most @x1.  ",""+val));
					break;
				case _INTELLIGENCE: // -int
					val=((++v)<V.size())?CMath.s_int(V.get(v)):0;
					buf.append(L((skipFirstWord?"A":"Requires a")+" base intelligence of at most @x1.  ",""+val));
					break;
				case _WISDOM: // -wis
					val=((++v)<V.size())?CMath.s_int(V.get(v)):0;
					buf.append(L((skipFirstWord?"A":"Requires a")+" base wisdom of at most @x1.  ",""+val));
					break;
				case _DEXTERITY: // -dex
					val=((++v)<V.size())?CMath.s_int(V.get(v)):0;
					buf.append(L((skipFirstWord?"A":"Requires a")+" base dexterity of at most @x1.  ",""+val));
					break;
				case _CONSTITUTION: // -con
					val=((++v)<V.size())?CMath.s_int(V.get(v)):0;
					buf.append(L((skipFirstWord?"A":"Requires a")+" base constitution of at most @x1.  ",""+val));
					break;
				case _CHARISMA: // -cha
					val=((++v)<V.size())?CMath.s_int(V.get(v)):0;
					buf.append(L((skipFirstWord?"A":"Requires a")+" base charisma of at most @x1.  ",""+val));
					break;
				case _CHANCE: // -chance
					val=((++v)<V.size())?CMath.s_int(V.get(v)):0;
					buf.append(L((skipFirstWord?"":"Allowed ")+" "+(100-val)+"% of the time.  "));
					break;
				case ABILITY: // +ability
					val=((++v)<V.size())?CMath.s_int(V.get(v)):0;
					buf.append(L((skipFirstWord?"A":"Requires a")+" magic/ability of at most @x1.  ",""+val));
					break;
				case _ABILITY: // -ability
					val=((++v)<V.size())?CMath.s_int(V.get(v)):0;
					buf.append(L((skipFirstWord?"A":"Requires a")+" magic/ability of at least @x1.  ",""+val));
					break;
				case VALUE: // +value
					val=((++v)<V.size())?CMath.s_int(V.get(v)):0;
					buf.append(L((skipFirstWord?"A":"Requires a")+" value of at most @x1.  ",""+val));
					break;
				case _VALUE: // -value
					val=((++v)<V.size())?CMath.s_int(V.get(v)):0;
					buf.append(L((skipFirstWord?"A":"Requires a")+" value of at least @x1.  ",""+val));
					break;
				case WEIGHT: // +weight
					val=((++v)<V.size())?CMath.s_int(V.get(v)):0;
					buf.append(L((skipFirstWord?"A":"Requires a")+" weight/encumbrance of at most @x1.  ",""+val));
					break;
				case _WEIGHT: // -weight
					val=((++v)<V.size())?CMath.s_int(V.get(v)):0;
					buf.append(L((skipFirstWord?"A":"Requires a")+" weight/encumbrance of at least @x1.  ",""+val));
					break;
				case ARMOR: // +armor
					val=((++v)<V.size())?CMath.s_int(V.get(v)):0;
					buf.append(L((skipFirstWord?"A":"Requires a")+" armor rating of at most @x1.  ",""+val));
					break;
				case _ARMOR: // -armor
					val=((++v)<V.size())?CMath.s_int(V.get(v)):0;
					buf.append(L((skipFirstWord?"A":"Requires a")+" armor rating of at least @x1.  ",""+val));
					break;
				case DAMAGE: // +damage
					val=((++v)<V.size())?CMath.s_int(V.get(v)):0;
					buf.append(L((skipFirstWord?"A":"Requires a")+" damage ability of at most @x1.  ",""+val));
					break;
				case _DAMAGE: // -damage
					val=((++v)<V.size())?CMath.s_int(V.get(v)):0;
					buf.append(L((skipFirstWord?"A":"Requires a")+" damage ability of at least @x1.  ",""+val));
					break;
				case ATTACK: // +attack
					val=((++v)<V.size())?CMath.s_int(V.get(v)):0;
					buf.append(L((skipFirstWord?"An":"Requires an")+" attack bonus of at most @x1.  ",""+val));
					break;
				case _ATTACK: // -attack
					val=((++v)<V.size())?CMath.s_int(V.get(v)):0;
					buf.append(L((skipFirstWord?"An":"Requires an")+" attack bonus of at least @x1.  ",""+val));
					break;
				case AREA: // +Area
					{
						buf.append(L("Disallows the following area"+(multipleQuals(V,v,"-")?"s":"")+": "));
						for(int v2=v+1;v2<V.size();v2++)
						{
							final String str2=V.get(v2);
							if(zapCodes.containsKey(str2))
								break;
							if(str2.startsWith("-"))
								buf.append(str2.substring(1)+", ");
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case _AREA: // -Area
					{
						buf.append(L((skipFirstWord?"The":"Requires the")+" following area"+(multipleQuals(V,v,"+")?"s":"")+": "));
						for(int v2=v+1;v2<V.size();v2++)
						{
							final String str2=V.get(v2);
							if(zapCodes.containsKey(str2))
								break;
							if(str2.startsWith("+"))
								buf.append(str2.substring(1)+", ");
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case ISHOME: // +isHome
					buf.append(L("Disallows those who are not in their home area.  "));
					break;
				case _ISHOME: // -isHome
					buf.append(L("Disallows those who are in their home area.  "));
					break;
				case HOME: // +Home
					{
						buf.append(L("Disallows those whose home is the following area"+(multipleQuals(V,v,"-")?"s":"")+": "));
						for(int v2=v+1;v2<V.size();v2++)
						{
							final String str2=V.get(v2);
							if(zapCodes.containsKey(str2))
								break;
							if(str2.startsWith("-"))
								buf.append(str2.substring(1)+", ");
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case _HOME: // -Home
					{
						buf.append(L((skipFirstWord?"From the":"Requires being from the")+" following area"+(multipleQuals(V,v,"+")?"s":"")+": "));
						for(int v2=v+1;v2<V.size();v2++)
						{
							final String str2=V.get(v2);
							if(zapCodes.containsKey(str2))
								break;
							if(str2.startsWith("+"))
								buf.append(str2.substring(1)+", ");
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case ITEM: // +Item
					{
						buf.append(L("Disallows those with the following item"+(multipleQuals(V,v,"-")?"s":"")+": "));
						for(int v2=v+1;v2<V.size();v2++)
						{
							final String str2=V.get(v2);
							if(zapCodes.containsKey(str2))
								break;
							if(str2.startsWith("-"))
								buf.append(str2.substring(1)+", ");
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case WORN:
					{
						buf.append(L((skipFirstWord?"The":"Requires the")+" following worn item"+(multipleQuals(V,v,"-")?"s":"")+": "));
						for(int v2=v+1;v2<V.size();v2++)
						{
							final String str2=V.get(v2);
							if(zapCodes.containsKey(str2))
								break;
							if(str2.startsWith("-"))
								buf.append(str2.substring(1)+", ");
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case _ITEM:
					{
						buf.append(L((skipFirstWord?"H":"Requires h")+"aving the following item"+(multipleQuals(V,v,"+")?"s":"")+": "));
						for(int v2=v+1;v2<V.size();v2++)
						{
							final String str2=V.get(v2);
							if(zapCodes.containsKey(str2))
								break;
							if((str2.startsWith("+"))||(str2.startsWith("-")))
								buf.append(str2.substring(1)+", ");
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case _WORN: // -Worn
					{
						buf.append(L((skipFirstWord?"W":"Requires w")+"earing the following item"+(multipleQuals(V,v,"+")?"s":"")+": "));
						for(int v2=v+1;v2<V.size();v2++)
						{
							final String str2=V.get(v2);
							if(zapCodes.containsKey(str2))
								break;
							if((str2.startsWith("+"))||(str2.startsWith("-")))
								buf.append(str2.substring(1)+", ");
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case EFFECT: // +Effects
					{
						buf.append(L("Disallows the following activities/effect"+(multipleQuals(V,v,"-")?"s":"")+": "));
						for(int v2=v+1;v2<V.size();v2++)
						{
							final String str2=V.get(v2);
							if(zapCodes.containsKey(str2))
								break;
							if(str2.startsWith("-"))
							{
								final Ability A=CMClass.getAbility(str2.substring(1));
								if(A!=null)
									buf.append(A.name()+", ");
								else
									buf.append(str2.substring(1)+", ");
							}
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case _EFFECT: // -Effects
					{
						buf.append(L((skipFirstWord?"P":"Requires p")+"articipation in the following activities/effect"+(multipleQuals(V,v,"+")?"s":"")+": "));
						for(int v2=v+1;v2<V.size();v2++)
						{
							final String str2=V.get(v2);
							if(zapCodes.containsKey(str2))
								break;
							if(str2.startsWith("+"))
							{
								final Ability A=CMClass.getAbility(str2.substring(1));
								if(A!=null)
									buf.append(A.name()+", ");
								else
									buf.append(str2.substring(1)+", ");
							}
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case FACTION: // +faction
					{
						buf.append(L("Disallows the following: "));
						for(int v2=v+1;v2<V.size();v2++)
						{
							final String str2=V.get(v2);
							if(zapCodes.containsKey(str2))
								break;
							if(str2.startsWith("-"))
							{
								final Faction.FRange FR=getRange(str2.substring(1).toUpperCase().trim());
								if(FR!=null)
								{
									final String desc=CMLib.factions().rangeDescription(FR,"or ");
									if(desc.length()>0)
										buf.append(desc+"; ");
								}
							}
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						if(buf.toString().endsWith("; "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case _FACTION: // -faction
					{
						buf.append(L((skipFirstWord?"The":"Requires the")+" following: "));
						for(int v2=v+1;v2<V.size();v2++)
						{
							final String str2=V.get(v2);
							if(zapCodes.containsKey(str2))
								break;
							if(str2.startsWith("+"))
							{
								final Faction.FRange FR=getRange(str2.substring(1).toUpperCase().trim());
								if(FR!=null)
								{
									final String desc=CMLib.factions().rangeDescription(FR,"or ");
									if(desc.length()>0)
										buf.append(desc+"; ");
								}
							}
						}
						if(buf.toString().endsWith(", "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						if(buf.toString().endsWith("; "))
							buf=new StringBuilder(buf.substring(0,buf.length()-2));
						buf.append(".  ");
					}
					break;
				case _GROUPSIZE: // -groupsize
					val=((++v)<V.size())?CMath.s_int(V.get(v)):0;
					buf.append(L((skipFirstWord?"A":"Requires a")+" group size of at most @x1.  ",""+val));
					break;
				case GROUPSIZE: // +groupsize
					val=((++v)<V.size())?CMath.s_int(V.get(v)):0;
					buf.append(L((skipFirstWord?"A":"Requires a")+" group size of at least @x1.  ",""+val));
					break;
				case _IF: // -if
					buf.append(L((skipFirstWord?"n":"Requires n")+"ot meeting the following condition(s):"));
					for(int v2=v+1;v2<V.size();v2++)
					{
						final String str2=V.get(v2);
						if(zapCodes.containsKey(str2))
							break;
						buf.append(str2).append(" ");
					}
					break;
				case IF: // +if
					buf.append(L((skipFirstWord?"m":"Requires m")+"meets the following condition(s):"));
					for(int v2=v+1;v2<V.size();v2++)
					{
						final String str2=V.get(v2);
						if(zapCodes.containsKey(str2))
							break;
						buf.append(str2).append(" ");
					}
					break;
				case SUBOP:
					// this line intentionally left blank
					break;
				case SYSOP:
					// this line intentionally left blank
					break;
				case _SUBOP:
					// this line intentionally left blank
					break;
				case _SYSOP:
					// this line intentionally left blank
					break;
				case LVLEQ:
					// this line intentionally left blank
					break;
				case LVLGE:
					// this line intentionally left blank
					break;
				case LVLGR:
					// this line intentionally left blank
					break;
				case LVLLE:
					// this line intentionally left blank
					break;
				case LVLLT:
					// this line intentionally left blank
					break;
				}
			}
			else
			{
				for(final SavedClass C : charClasses())
				{
					if(str.startsWith("-"+C.nameStart))
						buf.append(L("Disallows @x1.  ",C.name));
				}
				final LinkedList<String> cats=new LinkedList<String>();
				for(final SavedRace R : races())
				{
					if((str.startsWith(R.minusCatNameStart))&&(!cats.contains(R.racialCategory)))
					{
						cats.add(R.racialCategory);
						buf.append(L("Disallows @x1.  ",R.racialCategory));
					}
				}
				if(str.startsWith("-"+Faction.Align.EVIL.toString().substring(0,3)))
					buf.append(L("Disallows "+Faction.Align.EVIL.toString().toLowerCase()+".  "));
				if(str.startsWith("-"+Faction.Align.GOOD.toString().substring(0,3)))
					buf.append(L("Disallows "+Faction.Align.GOOD.toString().toLowerCase()+".  "));
				if(str.startsWith("-"+Faction.Align.NEUTRAL.toString().substring(0,3)))
					buf.append(L("Disallows "+Faction.Align.NEUTRAL.toString().toLowerCase()+".  "));
				if(str.startsWith("-MALE"))
					buf.append(L("Disallows Males.  "));
				if(str.startsWith("-FEMALE"))
					buf.append(L("Disallows Females.  "));
				if(str.startsWith("-NEUTER"))
					buf.append(L((skipFirstWord?"Only ":"Allows only ")+"Males and Females.  "));
				buf.append(levelHelp(str,'-',L("Disallows ")));
				if(str.startsWith("-"))
				{
					final Faction.FRange FR=getRange(str.substring(1));
					final String desc=CMLib.factions().rangeDescription(FR,"and ");
					if(desc.length()>0)
						buf.append(L("Disallows ")+desc);
				}
			}
		}

		if(buf.length()==0)
			buf.append(L("Anyone."));
		return buf.toString();
	}