public StringBuilder listCharClasses(Session viewerS, Enumeration<CharClass> these, List<String> commands)
	{
		boolean shortList=false;
		WikiFlag wiki=this.getWikiFlagRemoved(commands);
		for(String c : commands)
		{
			if(c.equalsIgnoreCase("SHORT"))
				shortList=true;
		}
		final StringBuilder lines=new StringBuilder("");
		if(!these.hasMoreElements())
			return lines;
		int column=0;
		final int COL_LEN=CMLib.lister().fixColWidth(25.0,viewerS);
		if(shortList)
		{
			final Vector<String> classNames=new Vector<String>();
			for(final Enumeration<CharClass> e=these;e.hasMoreElements();)
				classNames.add(e.nextElement().ID());
			lines.append(CMParms.toListString(classNames));
		}
		else
		for(final Enumeration<CharClass> e=these;e.hasMoreElements();)
		{
			final CharClass C=e.nextElement();
			if(wiki==WikiFlag.WIKILIST)
			{
				lines.append("[["+C.name()+"("+C.baseClass()+")|"+C.name()+"]]\n\r");
			}
			else
			if(wiki==WikiFlag.WIKIHELP)
			{
				final Set<Integer> types=new STreeSet<Integer>(new Integer[]{
					Integer.valueOf(Ability.ACODE_CHANT),
					Integer.valueOf(Ability.ACODE_COMMON_SKILL),
					Integer.valueOf(Ability.ACODE_PRAYER),
					Integer.valueOf(Ability.ACODE_SKILL),
					Integer.valueOf(Ability.ACODE_SONG),
					Integer.valueOf(Ability.ACODE_SPELL),
					Integer.valueOf(Ability.ACODE_THIEF_SKILL),
					Integer.valueOf(Ability.ACODE_TECH),
					Integer.valueOf(Ability.ACODE_SUPERPOWER)
				});
				StringBuilder help=CMLib.help().getHelpText(C.ID(),null,false,true);
				if(help==null)
					help=CMLib.help().getHelpText(C.name(),null,false,true);
				if((help!=null)&&(help.toString().startsWith("<CHARCLASS>")))
					help=new StringBuilder(help.toString().substring(11));
				else
					help=new StringBuilder("");
				final List<Item> items=C.outfit(null);
				StringBuilder outfit=new StringBuilder("");
				if(items !=null)
				{
					for(final Item I : items)
					{
						if(I!=null)
							outfit.append(((outfit.length()>0)?", ":"")+I.name());
					}
				}
				StringBuilder raceStr=new StringBuilder("");
				for(Enumeration<Race> r=CMClass.races();r.hasMoreElements();)
				{
					final Race R=r.nextElement();
					if((CMProps.isTheme(R.availabilityCode()))
					&&(((R.availabilityCode()&Area.THEME_SKILLONLYMASK)==0))
					&&(C.isAllowedRace(R)))
					{
						raceStr.append("[["+R.name()+"|"+R.name()+"]] ");
					}
				}
				StringBuilder langStr=new StringBuilder("");
				for(Enumeration<Ability> a=CMClass.abilities();a.hasMoreElements();)
				{
					final Ability A=a.nextElement();
					if(((A.classificationCode()&Ability.ALL_ACODES)==Ability.ACODE_LANGUAGE)
					&&(CMLib.ableMapper().getQualifyingLevel(C.ID(),true,A.ID())>=0)
					&&(CMLib.ableMapper().getSecretSkill(C.ID(),false,A.ID())))
							langStr.append("[["+A.ID()+"|"+A.name()+"]] ");
				}
				lines.append("{{ClassTemplate"
						+ "|Name="+C.name()
						+ "|Description="+help.toString()
						+ "|PrimeStat="+C.getPrimeStatDesc()
						+ "|Qualifications="+C.getStatQualDesc()
						+ "|Practices="+C.getPracticeDesc()
						+ "|Trains="+C.getTrainDesc()
						+ "|Hitpoints="+C.getHitPointDesc()
						+ "|Mana="+C.getManaDesc()
						+ "|Movement="+C.getMovementDesc()
						+ "|Attack="+C.getAttackDesc()
						+ "|Damage="+C.getDamageDesc()
						+ "|MaxStat="+C.getMaxStatDesc()
						+ "|Bonuses="+C.getOtherBonusDesc()
						+ "|Weapons="+C.getWeaponLimitDesc()
						+ "|Armor="+C.getArmorLimitDesc()
						+ "|Limitations="+C.getOtherLimitsDesc()
						+ "|StartingEq="+outfit.toString()
						+ "|Races="+raceStr.toString()
						+ "|Languages="+langStr.toString());
				for(int l=1;l<=CMProps.getIntVar(CMProps.Int.LASTPLAYERLEVEL);l++)
				{
					final StringBuilder levelList=new StringBuilder("");
					final List<Ability> autoGains=new ArrayList<Ability>(3);
					final List<Ability> qualifies=new ArrayList<Ability>(3);
					for (final Enumeration<AbilityMapper.AbilityMapping> a = CMLib.ableMapper().getClassAbles(C.ID(),true); a.hasMoreElements(); )
					{
						final AbilityMapper.AbilityMapping cimable=a.nextElement();
						if((cimable.qualLevel() ==l)&&(!cimable.isSecret()))
						{
							final Ability A=CMClass.getAbility(cimable.abilityID());
							if((A!=null)
							&&(types.contains(Integer.valueOf(A.classificationCode()&Ability.ALL_ACODES))))
							{
								if(cimable.autoGain())
									autoGains.add(A);
								else
									qualifies.add(A);
							}
						}
					}
					for(Ability A : autoGains)
						levelList.append("[["+A.ID()+"|"+A.name()+"]]&nbsp;&nbsp;&nbsp;&nbsp;");
					for(Ability A : qualifies)
						levelList.append("([["+A.ID()+"|"+A.name()+"]])&nbsp;&nbsp;&nbsp;&nbsp;");
					
					lines.append("|level"+l+"="+levelList.toString());
				}
				lines.append("}}");
			}
			else
			{
				if(++column>2)
				{
					lines.append("\n\r");
					column=1;
				}
				lines.append(CMStrings.padRight(C.ID()
							+(C.isGeneric()?"*":"")
							+" ("+C.baseClass()+")",COL_LEN));
			}
		}
		lines.append("\n\r");
		return lines;
	}