protected static MOB getMOB(String OfThisID,
								Room putInRoom,
								Session session,
								List mobData,
								List mobProgData,
								List specialData,
								List shopData,
								Map<String,MOB> areaMOBS,
								Map<String,MOB> doneMOBS,
								String areaFileName,
								boolean compileErrors,
								List<Object> commands)
	{
		if(OfThisID.startsWith("#"))
		{
			if(areaMOBS.containsKey(OfThisID.substring(1)))
			{
				final MOB M=(MOB)(areaMOBS.get(OfThisID.substring(1))).copyOf();
				M.setStartRoom(putInRoom);
				M.setLocation(putInRoom);
				return M;
			}
			if(doneMOBS.containsKey(OfThisID.substring(1)))
			{
				final MOB M=(MOB)(doneMOBS.get(OfThisID.substring(1))).copyOf();
				M.setStartRoom(putInRoom);
				M.setLocation(putInRoom);
				return M;
			}
		}
		else
		{
			if(areaMOBS.containsKey(OfThisID))
			{
				final MOB M=(MOB)(areaMOBS.get(OfThisID)).copyOf();
				M.setStartRoom(putInRoom);
				M.setLocation(putInRoom);
				return M;
			}
			if(doneMOBS.containsKey(OfThisID))
			{
				final MOB M=(MOB)(doneMOBS.get(OfThisID)).copyOf();
				M.setStartRoom(putInRoom);
				M.setLocation(putInRoom);
				return M;
			}
		}


		for(int m=0;m<mobData.size();m++)
		{
			List<String> objV=null;
			if(mobData.get(m) instanceof List)
				objV=(List)mobData.get(m);
			else
			if(mobData.get(m) instanceof String)
			{
				final String s=(String)mobData.get(m);
				if((!s.toUpperCase().trim().startsWith("#MOB"))&&(s.length()>0))
					returnAnError(session,"Eating mob immaterial line: "+mobData.get(m),compileErrors,commands);
				continue;
			}
			else
				continue;

			final String mobID=eatNextLine(objV);

			if(isBadID(mobID))
			{
				Log.errOut("IMPORT","Eating bad mob id "+mobID);
				mobData.remove(m);
				m--;
				continue;
			}

			if(!mobID.equals(OfThisID))
				continue;

			final String simpleName=CMLib.coffeeFilter().safetyFilter(eatLineSquiggle(objV));
			String mobName=CMLib.coffeeFilter().safetyFilter(eatLineSquiggle(objV));
			final String mobDisplay=CMLib.coffeeFilter().safetyFilter(eatLineSquiggle(objV));
			final String mobDescription=CMLib.coffeeFilter().safetyFilter(eatLineSquiggle(objV));
			Race R=null;
			boolean circleFormat=false;
			if(nextLine(objV).endsWith("~"))
			{
				final String raceName=eatLineSquiggle(objV);
				R=CMClass.getRace(raceName);
				if(R==null)
					R=CMClass.findRace(raceName);
				final String lowerRaceName=raceName.toUpperCase();
				if(R==null)
				{
					for(final Enumeration<Race> r=CMClass.races();r.hasMoreElements();)
					{
						final Race R2=r.nextElement();
						if(R2.name().toLowerCase().startsWith(lowerRaceName))
						{
							R=R2;
							break;
						}
					}
				}
				if(R==null)
				{
					for(final Enumeration<Race> r=CMClass.races();r.hasMoreElements();)
					{
						final Race R2=r.nextElement();
						if(R2.name().toLowerCase().endsWith(lowerRaceName))
						{
							R=R2;
							break;
						}
					}
				}
				if(R==null)
				{
					for(final Enumeration<Race> r=CMClass.races();r.hasMoreElements();)
					{
						final Race R2=r.nextElement();
						if(R2.name().toLowerCase().indexOf(lowerRaceName)>=0)
						{
							R=R2;
							break;
						}
					}
				}
				circleFormat=true;
			}
			if(R==null)
				R=CMClass.getRace("StdRace");

			final String codeStr1=eatNextLine(objV);
			final String codeStr2=eatNextLine(objV);
			String codeStr3=eatNextLine(objV);
			String codeStr4=eatNextLine(objV);
			String codeStr5="";
			if(circleFormat)
			{
				codeStr3=codeStr4;
				codeStr4=eatNextLine(objV);
				codeStr5=eatNextLine(objV);
			}


			if((!mobID.startsWith("#"))
			||((mobName.length()==0)
				&&((CMParms.numBits(codeStr1)<3)
					||(CMParms.numBits(codeStr1)>4)
					||(CMParms.numBits(codeStr2)<2)
					||(CMParms.numBits(codeStr3)<2))))
			{
				returnAnError(session,"Malformed mob! Aborting this mob "+mobID+", display="+mobDisplay+", simple="+simpleName+", name="+mobName+", codeStr1="+codeStr1+", codeStr2="+codeStr2+", codeStr3="+codeStr3+"!",compileErrors,commands);
				continue;
			}
			if(mobName.length()==0)
				mobName="Unknown";
			final long actFlag=getBitMask(codeStr1,0);
			final long affFlag=getBitMask(codeStr1,1);
			int aliFlag=CMath.s_int(CMParms.getBit(codeStr1,2));
			MOB M=CMClass.getMOB("GenMob");
			final String checkName=mobName.trim().toUpperCase();
			if(CMath.isSet(actFlag,14)
			||(checkName.indexOf("GHOUL")>=0)
			||(checkName.indexOf("GHAST")>=0)
			||(checkName.indexOf("SKELETON")>=0)
			||(checkName.indexOf("ZOMBIE")>=0)
			||(checkName.indexOf("VAMPIRE")>=0)
			||(checkName.indexOf("LICH")>=0)
			||(checkName.indexOf("MUMMY")>=0)
			||(checkName.indexOf("GHOST")>=0)
			||(checkName.indexOf("GEIST")>=0))
				M=CMClass.getMOB("GenUndead");
			else
			if(simpleName.toUpperCase().indexOf("HORSE")>=0)
				M=CMClass.getMOB("GenRideable");
			for(int i=0;i<shopData.size();i++)
			{
				final String s=((String)shopData.get(i)).trim();
				if(("#"+s).startsWith(OfThisID+" ")||("#"+s).startsWith(OfThisID+"\t")||("#"+s).startsWith(OfThisID+"	"))
				{
					M=CMClass.getMOB("GenShopkeeper");
					final int i1=CMath.s_int(CMParms.getBit(s,1));
					final int i2=CMath.s_int(CMParms.getBit(s,2));
					final int i3=CMath.s_int(CMParms.getBit(s,3));
					//int i4=CMath.s_int(CMParms.getBit(s,4));
					int whatIsell=ShopKeeper.DEAL_INVENTORYONLY;
					if((i1>4)&&(i1<8)&&(i2>4)&&(i2<8)&&(i3>4)&&(i3<8))
						whatIsell=ShopKeeper.DEAL_WEAPONS;
					else
					if((((i1>1)&&(i1<5))||(i1==10)||(i1==26))
					&&(((i2>1)&&(i2<5))||(i2==10)||(i2==26))
					&&(((i3>1)&&(i3<5))||(i3==10)||(i3==26)))
						whatIsell=ShopKeeper.DEAL_MAGIC;
					else
					if(((i1==9)||(i1==0))&&((i2==9)||(i2==0))&&((i3==9)||(i3==0)))
						whatIsell=ShopKeeper.DEAL_ARMOR;
					else
					if(mobName.toUpperCase().indexOf("LEATHER")>=0)
						whatIsell=ShopKeeper.DEAL_LEATHER;
					else
					if((mobName.toUpperCase().indexOf("PET ")>=0)||(mobName.toUpperCase().indexOf("PETS ")>=0))
						whatIsell=ShopKeeper.DEAL_PETS;
					((ShopKeeper)M).setWhatIsSoldMask(0);
					((ShopKeeper)M).addSoldType(whatIsell);
					break;
				}
			}
			M.setName(mobName);
			M.setDisplayText(mobDisplay);
			if(!mobDescription.trim().equalsIgnoreCase("OLDSTYLE"))
				M.setDescription(mobDescription);
			aliFlag=(int)Math.round(CMath.div(aliFlag,2));
			CMLib.factions().setAlignmentOldRange(M,500+aliFlag);
			M.setStartRoom(putInRoom);
			M.setLocation(putInRoom);
			M.baseCharStats().setMyRace(R);

			Behavior behavior=CMClass.getBehavior("Mobile");
			if(CMath.isSet(actFlag,5))
				behavior=CMClass.getBehavior("MobileAggressive");
			//if(!CMath.isSet(actFlag,6))
			//	behavior.setParms("WANDER");
			if(!CMath.isSet(actFlag,1))
				M.addBehavior(behavior);
			if(CMath.isSet(actFlag,2))
				M.addBehavior(CMClass.getBehavior("Scavenger"));
			if(CMath.isSet(actFlag,4))
				M.addNonUninvokableEffect(CMClass.getAbility("Prop_Invisibility"));
			if(CMath.isSet(actFlag,5)&&CMath.isSet(actFlag,1))
				M.addBehavior(CMClass.getBehavior("Aggressive"));
			M.setWimpHitPoint(0);
			if(CMath.isSet(actFlag,7)) // this needs to be adjusted further down!
				M.setWimpHitPoint(2);
			//if(CMath.isSet(actFlag,8)) // not really supported properly
			//	M.addNonUninvokableEffect(CMClass.getAbility("Prop_SafePet"));

			if(CMath.isSet(actFlag,9))
				M.addNonUninvokableEffect(CMClass.getAbility("Prop_StatTrainer"));
			if(CMath.isSet(actFlag,10))
				M.addBehavior(CMClass.getBehavior("MOBTeacher"));

			if(CMath.isSet(actFlag,11))
				M.addBehavior(CMClass.getBehavior("Fighterness"));
			if(CMath.isSet(actFlag,12))
				M.addBehavior(CMClass.getBehavior("Mageness"));
			if(CMath.isSet(actFlag,13))
				M.addBehavior(CMClass.getBehavior("Mageness"));

			if(CMath.isSet(actFlag,14))
			{
				R=M.baseCharStats().getMyRace();
				if(R.ID().equals("Human")||R.ID().equals("StdRace"))
				{
					R=CMClass.getRace("Undead");
					M.baseCharStats().setMyRace(R);
				}
			}

			if(CMath.isSet(actFlag,16))
				M.addBehavior(CMClass.getBehavior("Clericness"));
			if(CMath.isSet(actFlag,17))
				M.addBehavior(CMClass.getBehavior("Mageness"));
			if(CMath.isSet(actFlag,18))
				M.addBehavior(CMClass.getBehavior("Thiefness"));
			if(CMath.isSet(actFlag,19))
				M.addBehavior(CMClass.getBehavior("Fighterness"));
			if(CMath.isSet(actFlag,26))
				M.addBehavior(CMClass.getBehavior("Healer"));
			if(CMath.isSet(actFlag,27))
				M.addBehavior(CMClass.getBehavior("MOBTeacher"));

			if(CMath.isSet(affFlag,0))
				M.basePhyStats().setSensesMask(M.basePhyStats().sensesMask()|PhyStats.CAN_NOT_SEE);
			if(CMath.isSet(affFlag,1))
				M.basePhyStats().setDisposition(M.basePhyStats().disposition()|PhyStats.IS_INVISIBLE);
			if(CMath.isSet(affFlag,2))
				M.basePhyStats().setSensesMask(M.basePhyStats().sensesMask()|PhyStats.CAN_SEE_EVIL);
			if(CMath.isSet(affFlag,3))
				M.basePhyStats().setSensesMask(M.basePhyStats().sensesMask()|PhyStats.CAN_SEE_INVISIBLE);
			if(CMath.isSet(affFlag,4))
				M.basePhyStats().setSensesMask(M.basePhyStats().sensesMask()|PhyStats.CAN_SEE_BONUS);
			if(CMath.isSet(affFlag,5))
			{
				M.basePhyStats().setSensesMask(M.basePhyStats().sensesMask()|PhyStats.CAN_SEE_HIDDEN);
				M.basePhyStats().setSensesMask(M.basePhyStats().sensesMask()|PhyStats.CAN_SEE_SNEAKERS);
			}
			if(CMath.isSet(affFlag,6))
			{
				if(CMLib.flags().isEvil(M))
				   M.addNonUninvokableEffect(CMClass.getAbility("Prayer_UnholyWord"));
				else
				   M.addNonUninvokableEffect(CMClass.getAbility("Prayer_HolyWord"));
				M.addNonUninvokableEffect(CMClass.getAbility("Prayer_Sanctuary"));
			}
			else
			if(CMath.isSet(affFlag,7))
				M.addNonUninvokableEffect(CMClass.getAbility("Prayer_Sanctuary"));

			if(CMath.isSet(affFlag,8))
				M.addNonUninvokableEffect(CMClass.getAbility("Spell_FaerieFire"));
			if(CMath.isSet(affFlag,9))
				M.basePhyStats().setSensesMask(M.basePhyStats().sensesMask()|PhyStats.CAN_SEE_INFRARED);
			if(CMath.isSet(affFlag,10))
				M.addNonUninvokableEffect(CMClass.getAbility("Prayer_Curse"));
			if(CMath.isSet(affFlag,11))
			{
				for(final Enumeration<Ability> a=CMClass.abilities();a.hasMoreElements();)
				{
					final Ability A=a.nextElement();
					if(A.ID().startsWith("Specialization"))
						M.addNonUninvokableEffect((Ability)A.newInstance());
				}
			}

			//if(CMath.isSet(affFlag,12)) really dumb
			//  M.addNonUninvokableEffect(new Poison());

			if(CMath.isSet(affFlag,13))
				M.addNonUninvokableEffect(CMClass.getAbility("Prayer_ProtEvil"));

			if(CMath.isSet(affFlag,14))
				M.addNonUninvokableEffect(CMClass.getAbility("Prayer_ProtGood"));

			if(CMath.isSet(affFlag,15))
			{
				final Ability A=(Ability)CMClass.getAbility("Thief_Sneak").copyOf();
				A.setProficiency(100);
				M.addAbility(A);
			}

			if(CMath.isSet(affFlag,16))
				M.addNonUninvokableEffect(CMClass.getAbility("Prop_Hidden"));

			if(CMath.isSet(affFlag,17))
				M.addNonUninvokableEffect(CMClass.getAbility("Spell_Sleep"));

			if(CMath.isSet(affFlag,18))
				M.addNonUninvokableEffect(CMClass.getAbility("Spell_Charm"));

			if(CMath.isSet(affFlag,20))
				M.addNonUninvokableEffect(CMClass.getAbility("Spell_PassDoor"));

			if(CMath.isSet(affFlag,21))
				M.addNonUninvokableEffect(CMClass.getAbility("Spell_Haste"));

			//if(CMath.isSet(affFlag,22)) no effect anyway
			//	M.addNonUninvokableEffect(new Prayer_Calm());

			if(CMath.isSet(affFlag,23))
				M.addNonUninvokableEffect(CMClass.getAbility("Prayer_Plague"));

			if(CMath.isSet(affFlag,24))
				M.addNonUninvokableEffect(CMClass.getAbility("Spell_Weaken"));

			if(CMath.isSet(affFlag,25))
				M.basePhyStats().setSensesMask(M.basePhyStats().sensesMask()|PhyStats.CAN_SEE_DARK);

			if(CMath.isSet(affFlag,26))
				M.addNonUninvokableEffect(CMClass.getAbility("Fighter_Berzerk"));

			if(CMath.isSet(affFlag,27))
				M.addAbility(CMClass.getAbility("Skill_Swim"));

			if(CMath.isSet(affFlag,28))
				M.addNonUninvokableEffect(CMClass.getAbility("Regeneration"));

			if(CMath.isSet(affFlag,29))
			{
				M.addNonUninvokableEffect(CMClass.getAbility("Regeneration"));
				M.addNonUninvokableEffect(CMClass.getAbility("Spell_Slow"));
			}

			// start ROM type
			int positionCode=8;
			int sexCode=1;
			if(CMParms.numBits(codeStr2)>=4)
			{
				M.basePhyStats().setLevel(CMath.s_int(CMParms.getCleanBit(codeStr2,0).trim()));
				if(M.basePhyStats().level()==0)
					M.basePhyStats().setLevel(1);
				int baseHP=11;
				if(circleFormat)
					baseHP=getDRoll(CMParms.getCleanBit(codeStr2,2));
				else
					baseHP=getDRoll(CMParms.getCleanBit(codeStr2,3));
				baseHP=baseHP-3;
				baseHP=(baseHP/M.basePhyStats().level())-1;
				M.basePhyStats().setAbility(baseHP);

				if(circleFormat)
				{
					if(CMath.isNumber(CMParms.getCleanBit(codeStr4,2).trim()))
						sexCode=CMath.s_int(CMParms.getCleanBit(codeStr4,2).trim());
					else
					if(CMParms.getCleanBit(codeStr4,2).trim().toUpperCase().equals("MALE"))
						sexCode=1;
					else
					if(CMParms.getCleanBit(codeStr4,2).trim().toUpperCase().equals("FEMALE"))
						sexCode=2;
					else
					if(CMParms.getCleanBit(codeStr4,2).trim().toUpperCase().equals("EITHER"))
						sexCode=(CMLib.dice().rollPercentage()>50)?1:2;
					else
						sexCode=3;

					if(CMath.isNumber(CMParms.getCleanBit(codeStr4,0).trim()))
						positionCode=CMath.s_int(CMParms.getCleanBit(codeStr4,2).trim());
					else
					if(CMParms.getCleanBit(codeStr4,0).trim().startsWith("STAND"))
						positionCode=8;
					else
					if(CMParms.getCleanBit(codeStr4,0).trim().startsWith("SIT"))
						positionCode=5;
					else
					if(CMParms.getCleanBit(codeStr4,0).trim().startsWith("SLEEP"))
						positionCode=1;

				}
				else
				{
					positionCode=CMath.s_int(CMParms.getCleanBit(codeStr4,0).trim());
					sexCode=CMath.s_int(CMParms.getCleanBit(codeStr4,2).trim());
				}
				if(CMLib.dice().rollPercentage()>75)
					M.addBehavior(CMClass.getBehavior("MudChat"));
			}
			else
			{
				M.basePhyStats().setAbility(11);
				int baseLevel=CMath.s_int(CMParms.getCleanBit(codeStr2,0).trim());
				while(baseLevel>25)
					baseLevel=(int)Math.round(CMath.div(baseLevel,2.0));
			}

			if(M.basePhyStats().level()==0)
				M.basePhyStats().setLevel(1);
			if(M.getWimpHitPoint()==2)
				M.setWimpHitPoint(((int)Math.round(CMath.div(M.basePhyStats().level()*(11+M.basePhyStats().ability()),8.0)))+1);

			M.basePhyStats().setArmor(CMLib.leveler().getLevelMOBArmor(M));
			M.basePhyStats().setAttackAdjustment(CMLib.leveler().getLevelAttack(M));
			M.basePhyStats().setDamage(CMLib.leveler().getLevelMOBDamage(M));
			if(circleFormat)
				M.setMoney(CMath.s_int(CMParms.getCleanBit(codeStr4,3).trim()));
			else
				M.setMoney(CMLib.dice().roll(1,M.basePhyStats().level(),0)+CMLib.dice().roll(1,10,0));
			M.basePhyStats().setWeight(50);

			switch(positionCode)
			{
			case 1:
			case 2:
			case 3:
			case 4:
				M.basePhyStats().setDisposition(M.basePhyStats().disposition()|PhyStats.IS_SLEEPING);
				break;
			case 5:
				M.basePhyStats().setDisposition(M.basePhyStats().disposition()|PhyStats.IS_SITTING);
				break;
			case 6:
				M.basePhyStats().setDisposition(M.basePhyStats().disposition()|PhyStats.IS_SITTING);
				break;
			}

			M.baseCharStats().setStat(CharStats.STAT_GENDER,'M');
			switch(sexCode)
			{
			case 2:
				M.baseCharStats().setStat(CharStats.STAT_GENDER, 'F');
				break;
			case 3:
				M.baseCharStats().setStat(CharStats.STAT_GENDER, 'N');
				break;
			}

			if(circleFormat)
			{
				final long off=getBitMask(codeStr3,0);
				final long imm=getBitMask(codeStr3,1);
				final long res=getBitMask(codeStr3,2);
				final int size=CMath.s_int(CMParms.getCleanBit(codeStr5,2).trim());
				switch(size)
				{
				case 0:
					M.basePhyStats().setWeight(1);
					break;
				case 1:
					M.basePhyStats().setWeight(15);
					break;
				case 2:
					M.basePhyStats().setWeight(150);
					break;
				case 3:
					M.basePhyStats().setWeight(350);
					break;
				case 4:
					M.basePhyStats().setWeight(850);
					break;
				case 5:
					M.basePhyStats().setWeight(2000);
					break;
				}
				// ignore the above, coffeemud does it better!
				final int numAbiles=M.numAbilities();
				M.baseCharStats().getMyRace().startRacing(M,false);
				//if(CMath.isSet(off,0)) // no area killers in coffeemud
				//if(CMath.isSet(off,1)) // no circling in coffeemud

				if(CMath.isSet(off,2)) // bash them off their feet?
					M.addAbility(CMClass.getAbility("Skill_Trip"));
				if(CMath.isSet(off,3))
					M.addAbility(CMClass.getAbility("Fighter_Berzerk"));
				if(CMath.isSet(off,4))
					M.addAbility(CMClass.getAbility("Skill_Disarm"));
				if(CMath.isSet(off,5))
					M.addAbility(CMClass.getAbility("Skill_Dodge"));
				//if(CMath.isSet(off,6)) is missing
				if(CMath.isSet(off,7))
					M.basePhyStats().setSpeed(M.basePhyStats().speed()+1);
				if(CMath.isSet(off,8))
					M.addAbility(CMClass.getAbility("Fighter_Kick"));
				if(CMath.isSet(off,9))
					M.addAbility(CMClass.getAbility("Skill_Dirt"));
				if(CMath.isSet(off,10))
					M.addAbility(CMClass.getAbility("Skill_Parry"));
				//if(CMath.isSet(off,11)) rescue is irrelevant
				//if(CMath.isSet(off,12)) is missing
				if(CMath.isSet(off,13))
					M.addAbility(CMClass.getAbility("Skill_Trip"));
				if(CMath.isSet(off,14))
					M.addAbility(CMClass.getAbility("Fighter_Whomp"));
				if(CMath.isSet(off,15))
					M.addBehavior(CMClass.getBehavior("MOBHelper"));
				if(CMath.isSet(off,16))
					M.addBehavior(CMClass.getBehavior("AlignHelper"));
				if(CMath.isSet(off,17))
					M.addBehavior(CMClass.getBehavior("RaceHelper"));
				if(CMath.isSet(off,18))
					M.addBehavior(CMClass.getBehavior("PlayerHelper"));
				if(CMath.isSet(off,19))
				{
					Behavior guardian=CMClass.getBehavior("GoodGuardian");
					for(int b=M.numBehaviors()-1;b>=0;b--)
					{
						final Behavior B=M.fetchBehavior(b);
						if((B!=null)&&(CMath.bset(B.flags(),Behavior.FLAG_MOBILITY)))
						{
							if(guardian.ID().equals("GoodGuardian"))
								guardian=CMClass.getBehavior("MobileGoodGuardian");
							if(B.getParms().length()>0)
								guardian.setParms(B.getParms());
							M.delBehavior(B);
						}
					}
					M.addBehavior(guardian);
					M.addBehavior(CMClass.getBehavior("AntiVagrant"));
				}
				if(CMath.isSet(off,20))
					M.addBehavior(CMClass.getBehavior("BrotherHelper"));
				//if(CMath.isSet(off,21)) is missing
				if(CMath.isSet(off,22))
					M.addAbility(CMClass.getAbility("Fighter_Sweep"));

				if((M.numAllAbilities())>numAbiles)
					M.addBehavior(CMClass.getBehavior("CombatAbilities"));

				final Ability resist=CMClass.getAbility("Prop_Resistance");
				if((CMath.isSet(res,0))||(CMath.isSet(imm,0)))
					resist.setMiscText(resist.text()+" teleport");
				if((CMath.isSet(res,1))||(CMath.isSet(imm,1)))
					resist.setMiscText(resist.text()+" mind");
				if((CMath.isSet(res,2))||(CMath.isSet(imm,2)))
					resist.setMiscText(resist.text()+" magic");
				if((CMath.isSet(res,3))||(CMath.isSet(imm,3)))
					resist.setMiscText(resist.text()+" weapons");
				if((CMath.isSet(res,4))||(CMath.isSet(imm,4)))
					resist.setMiscText(resist.text()+" blunt");
				if((CMath.isSet(res,5))||(CMath.isSet(imm,5)))
					resist.setMiscText(resist.text()+" pierce");
				if((CMath.isSet(res,6))||(CMath.isSet(imm,6)))
					resist.setMiscText(resist.text()+" slash");
				if((CMath.isSet(res,7))||(CMath.isSet(imm,7)))
					resist.setMiscText(resist.text()+" fire");
				if((CMath.isSet(res,8))||(CMath.isSet(imm,8)))
					resist.setMiscText(resist.text()+" cold");
				if((CMath.isSet(res,9))||(CMath.isSet(imm,9)))
					resist.setMiscText(resist.text()+" elec");
				if((CMath.isSet(res,10))||(CMath.isSet(imm,10)))
					resist.setMiscText(resist.text()+" acid");
				if((CMath.isSet(res,11))||(CMath.isSet(imm,11)))
					resist.setMiscText(resist.text()+" poison");
				if((CMath.isSet(res,12))||(CMath.isSet(imm,12)))
					resist.setMiscText(resist.text()+" evil");
				if((CMath.isSet(res,13))||(CMath.isSet(imm,13)))
					resist.setMiscText(resist.text()+" holy");
				if(CMath.isSet(res,14))
					M.addNonUninvokableEffect(CMClass.getAbility("Spell_ResistMagicMissiles"));
				if((CMath.isSet(res,15))||(CMath.isSet(imm,15)))
					resist.setMiscText(resist.text()+" mind");
				if((CMath.isSet(res,16))||(CMath.isSet(imm,16)))
					resist.setMiscText(resist.text()+" disease");
				if((CMath.isSet(res,17))||(CMath.isSet(imm,17)))
					resist.setMiscText(resist.text()+" water gas");
				//if(CMath.isSet(res,18)) no light resistance
				//if(CMath.isSet(res,18)) no sound resistance
				if(resist.text().length()>0)
				{
					resist.setMiscText(resist.text()+" "+(10+M.basePhyStats().level())+"%");
					M.addNonUninvokableEffect(resist);
				}
			}

			String scriptStuff="";
			while(objV.size()>0)
			{
				String s=nextLine(objV);
				if(s.startsWith(">"))
				{
					s=eatLineSquiggle(objV);
					if(!s.substring(1).trim().toUpperCase().startsWith("IN_FILE_PROG"))
					{
						scriptStuff+=s.substring(1).trim()+";";
						s=nextLine(objV);
						while(s.indexOf('~')<0)
						{
							scriptStuff+=s.trim()+";";
							eatLine(objV);
							s=nextLine(objV);
						}
						s=eatLineSquiggle(objV).trim();
						scriptStuff+=s+"~";
					}
				}
				else
				if(s.startsWith("X "))
				{
					final String codeLine=eatLineSquiggle(objV);
					Behavior B=M.fetchBehavior("Sounder");
					if(B==null)
					{
						B=CMClass.getBehavior("Sounder");
						if(B!=null)
							M.addBehavior(B);
					}
					// no else please
					if(B!=null)
					{
						if(B.getParms().length()==0)
							B.setParms(codeLine.substring(1).trim());
						else
							B.setParms(B.getParms()+";"+codeLine.substring(1).trim());
					}
				}
				else
				if(s.startsWith("|"))
				{
					eatNextLine(objV);
					// just eat and go.. its an end of mob marker probably
				}
				else
					eatNextLine(objV);
			}
			for(int mp=0;mp<mobProgData.size();mp++)
			{
				String s=(String)mobProgData.get(mp);
				String rest=null;
				if(s.startsWith("#")&&(s.length()>1)&&(CMath.isNumber(""+s.charAt(1))))
				{
					final String newS="M "+s.substring(1);
					final StringBuilder b=new StringBuilder("");
					while(s.indexOf('~')<=0)
					{
						mp++;
						if(mp<mobProgData.size())
						{
							final String s1=(String)mobProgData.get(mp);
							//s1=CMStrings.replaceAll(s1, ";", "\\;");
							b.append(s1);
							//b.append(";");
							s=(String)mobProgData.get(mp);
						}
						else
							break;
					}
					rest=b.toString();
					s=newS;
				}
				if(s.startsWith("M "))
				{
					final String MOBID=CMParms.getBit(s,1);
					if(!("#"+MOBID).equals(OfThisID))
						continue;

					final String mobprg=CMParms.getBit(s,2).toUpperCase().trim();
					if(mobprg.equals("JANITOR.PRG"))
						M.addBehavior(CMClass.getBehavior("Scavenger"));
					else
					if(mobprg.equals("VAGABOND.PRG"))
						M.addBehavior(CMClass.getBehavior("Vagrant"));
					else
					if(mobprg.equals("DRUNK.PRG"))
					{
						if(M.fetchEffect("Inebriation")==null)
							M.addNonUninvokableEffect(CMClass.getAbility("Inebriation"));
					}
					else
					if(mobprg.equals("MID_CIT.PRG"))
					{
						//
					}
					else
					if(mobprg.equals("BEGGAR.PRG"))
						M.addBehavior(CMClass.getBehavior("Beggar"));
					else
					if(mobprg.equals("GATEGRD.PRG"))
						M.addBehavior(CMClass.getBehavior("GateGuard"));
					else
					if(mobprg.equals("GATEGRD2.PRG"))
						M.addBehavior(CMClass.getBehavior("GateGuard"));
					else
					if(mobprg.equals("CRIER.PRG"))
					{
					}
					else
					if(rest!=null)
						continue;
					else
					{
						try
						{
							final CMFile F2=new CMFile(areaFileName,M,CMFile.FLAG_LOGERRORS);
							if((F2.exists())&&(!F2.isDirectory()))
							{
								final int x=F2.getAbsolutePath().lastIndexOf('/');
								final String path=F2.getAbsolutePath().substring(0,x)+"/"+mobprg;
								StringBuffer buf=new CMFile(path,M,CMFile.FLAG_LOGERRORS).text();
								if((buf==null)||(buf.length()==0))
									returnAnError(session,"Unknown MobPrg: "+mobprg,compileErrors,commands);
								else
								{
									if(buf.indexOf("\n")>0)
										buf=new StringBuffer(CMStrings.replaceAll(buf.toString(),"\r",""));
									else
									if(buf.indexOf("\r")>0)
										buf=new StringBuffer(CMStrings.replaceAll(buf.toString(),"\n",""));
									final List<String> V=Resources.getFileLineVector(buf);
									while(V.size()>0)
									{
										s=nextLine(V);
										if(s.startsWith(">"))
										{
											s=eatLineSquiggle(V).substring(1).trim();
											scriptStuff+=s+";";
											s=nextLine(V);
											while(s.indexOf('~')<0)
											{
												scriptStuff+=s+";";
												eatLine(V);
												s=nextLine(V);
											}
											s=eatLineSquiggle(V).trim();
											scriptStuff+=s+"~";
										}
										else
											eatLine(V);
									}
								}
							}
						}catch(final Exception e)
						{
							returnAnError(session,"Unknown MobPrg: "+mobprg,compileErrors,commands);
						}
					}
				}
				else
				if(s.startsWith("O "))
				{
					// also unsupported
				}
				else
				if((s.startsWith("#M"))||(s.startsWith("S")))
				{
				}
				else
				if(s.trim().length()>0)
					returnAnError(session,"MobPrg line: "+s,compileErrors,commands);
			}
			if(scriptStuff.length()>0)
			{
				final Behavior S=CMClass.getBehavior("Scriptable");
				S.setParms(scriptStuff);
				M.addBehavior(S);
			}

			for(int mp=0;mp<specialData.size();mp++)
			{
				final String s=(String)specialData.get(mp);
				if(s.startsWith("M "))
				{
					final String MOBID=CMParms.getBit(s,1);
					if(!("#"+MOBID).equals(OfThisID))
						continue;

					final String special=CMParms.getBit(s,2).toUpperCase().trim();
					if((special.equals("SPEC_CAST_MAGE"))
					||(special.equals("SPEC_WANDERER")))
						M.addBehavior(CMClass.getBehavior("Mageness"));
					else
					if(special.equals("SPEC_CAST_SENESCHAL"))
					{
						M.addBehavior(CMClass.getBehavior("CombatAbilities"));
						M.addAbility(CMClass.getAbility("Spell_Blindness"));
						M.addAbility(CMClass.getAbility("Spell_DispelMagic"));
						M.addAbility(CMClass.getAbility("Spell_Weaken"));
						M.addAbility(CMClass.getAbility("Spell_AcidArrow"));
						M.addAbility(CMClass.getAbility("Spell_Fireball"));
						M.addAbility(CMClass.getAbility("Spell_AcidFog"));
						M.addAbility(CMClass.getAbility("Spell_Lightning"));
						M.addAbility(CMClass.getAbility("Undead_WeakEnergyDrain"));
						M.addAbility(CMClass.getAbility("Prayer_Plague"));
					}
					else
					if(special.equals("SPEC_CAST_BEHOLDER"))
					{
						M.addBehavior(CMClass.getBehavior("CombatAbilities"));
						M.addAbility(CMClass.getAbility("Spell_Spook"));
						M.addAbility(CMClass.getAbility("Spell_Slow"));
						M.addAbility(CMClass.getAbility("Prayer_Harm"));
						M.addAbility(CMClass.getAbility("Prayer_CauseCritical"));
						M.addAbility(CMClass.getAbility("Prayer_CauseSerious"));
						M.addAbility(CMClass.getAbility("Spell_DispelMagic"));

					}
					else
					if(special.equals("SPEC_CAST_PSIONICIST"))
					{
						M.addBehavior(CMClass.getBehavior("CombatAbilities"));
						M.addAbility(CMClass.getAbility("Spell_Spook"));
						M.addAbility(CMClass.getAbility("Spell_Slow"));
						M.addAbility(CMClass.getAbility("Spell_DispelMagic"));
						M.addAbility(CMClass.getAbility("Undead_WeakEnergyDrain"));
						M.addAbility(CMClass.getAbility("WeakParalysis"));
					}
					else
					if((special.equals("SPEC_CAST_GHOST"))
					||(special.equals("SPEC_UNDEAD")))
					{
						M.addBehavior(CMClass.getBehavior("CombatAbilities"));
						M.addAbility(CMClass.getAbility("Spell_Spook"));
						M.addAbility(CMClass.getAbility("Prayer_Curse"));
						M.addAbility(CMClass.getAbility("Prayer_Blindness"));
						M.addAbility(CMClass.getAbility("Prayer_Harm"));
						M.addAbility(CMClass.getAbility("Prayer_Poison"));
						M.addAbility(CMClass.getAbility("WeakParalysis"));
					}
					else
					if(special.equals("SPEC_THIEF"))
						M.addBehavior(CMClass.getBehavior("Thiefness"));
					else
					if(special.equals("SPEC_SNAKE_CHARM"))
					{
						// ends combat, and makes people give him their weapons
						Log.errOut("IMPORT","Unsupported spec: "+special);
					}
					else
					if(special.equals("SPEC_KUNGFU_POISON"))
					{
						Log.errOut("IMPORT","Unsupported spec: "+special);
					}
					else
					if(special.equals("SPEC_TAXIDERMIST"))
					{
						Log.errOut("IMPORT","Unsupported spec: "+special);
					}
					else
					if(special.equals("SPEC_TEACHER"))
					{
						M.addBehavior(CMClass.getBehavior("MOBTeacher"));
					}
					else
					if(special.equals("SPEC_BUDDHA"))
					{
						M.addBehavior(CMClass.getBehavior("Clericness"));
						M.addAbility(CMClass.getAbility("Dragonbreath"));
					}
					else
					if(special.equals("SPEC_DEATH_RAIN"))
					{
						Log.errOut("IMPORT","Unsupported spec: "+special);
					}
					else
					if(special.equals("SPEC_HEALER"))
						M.addBehavior(CMClass.getBehavior("Healer"));
					else
					if(special.equals("SPEC_REPAIRMAN"))
						M.addBehavior(CMClass.getBehavior("ItemMender"));
					else
					if((special.equals("SPEC_SUMMON_LIGHT"))
					||(special.equals("SPEC_SUMMON_DEMON")))
					{
						M.addBehavior(CMClass.getBehavior("CombatAbilities"));
						M.addAbility(CMClass.getAbility("Prayer_SummonElemental"));
					}
					else
					if(special.equals("SPEC_EXECUTIONER"))
						M.addBehavior(CMClass.getBehavior("GoodExecutioner"));
					else
					if(special.startsWith("SPEC_ASSASSIN"))
					{
						Behavior B=M.fetchBehavior("Aggressive");
						if(B==null)
							B=M.fetchBehavior("MobileAggressive");
						if(B==null)
							B=M.fetchBehavior("VeryAggressive");
						if(B==null)
							B=CMClass.getBehavior("Aggressive");
						B.setParms(B.getParms()+" MOBKILLER ");
						M.addBehavior(B);
					}
					else
					if(special.equals("SPEC_CAST_ADEPT"))
						M.addBehavior(CMClass.getBehavior("Healer"));
					else
					if(special.equals("SPEC_CAST_CLERIC"))
						M.addBehavior(CMClass.getBehavior("Clericness"));
					else
					if(special.equals("SPEC_NASTY"))
						M.addBehavior(CMClass.getBehavior("FightFlee"));
					else
					if(special.equals("SPEC_DARK_MAGIC"))
					{
						M.addNonUninvokableEffect(CMClass.getAbility("Spell_SpellTurning"));
						M.addAbility(CMClass.getAbility("Prayer_Heal"));
					}
					else
					if(special.equals("SPEC_SMART"))
						M.addBehavior(CMClass.getBehavior("Scavenger"));
					else
					if(special.equals("SPEC_CAST_UNDEAD"))
					{
						M.basePhyStats().setDisposition(M.basePhyStats().disposition()|PhyStats.IS_GOLEM);
						M.addBehavior(CMClass.getBehavior("CombatAbilities"));
						M.addAbility(CMClass.getAbility("Undead_ColdTouch"));
						M.addAbility(CMClass.getAbility("Undead_LifeDrain"));
						M.baseCharStats().setMyRace(CMClass.getRace("Undead"));
						M.baseCharStats().getMyRace().startRacing(M,false);
					}
					else
					if((special.equals("SPEC_GUARD"))
					||(special.equals("SPEC_GUARD_WHITE"))
					||(special.equals("SPEC_POLICEMAN"))
					||(special.equals("SPEC_SPECIAL_GUARD")))
						M.addBehavior(CMClass.getBehavior("GoodGuardian"));
					else
					if(special.equals("SPEC_FIDO"))
						M.addBehavior(CMClass.getBehavior("CorpseEater"));
					else
					if((special.equals("SPEC_MAYOR"))
					||(special.equals("SPEC_CAPTAIN")))
						M.addBehavior(CMClass.getBehavior("MudChat"));
					else
					if(special.equals("SPEC_JANITOR"))
						M.addBehavior(CMClass.getBehavior("Scavenger"));
					else
					if(special.equals("SPEC_BREATH_ANY"))
					{
						M.addBehavior(CMClass.getBehavior("CombatAbilities"));
						M.addAbility(CMClass.getAbility("Dragonbreath"));
					}
					else
					if(special.equals("SPEC_CAST_CADAVER"))
					{
						M.addBehavior(CMClass.getBehavior("CombatAbilities"));
						M.addAbility(CMClass.getAbility("Prayer_Bury"));
					}
					else
					if((special.equals("SPEC_REWIELD"))
					||(special.equals("SPEC_WIZARDOFOZ"))
					||(special.equals("SPEC_VAMP_HUNTER"))
					||(special.equals("SPEC_MINO_GUARD")))
					{
						// who knows?
					}
					else
					if(special.equals("SPEC_TAX_MAN"))
					{
						M.addBehavior(CMClass.getBehavior("RandomTeleporter"));
						M.addBehavior(CMClass.getBehavior("Thiefness"));
					}
					else
					if(special.equals("SPEC_STEPHEN"))
					{
						M.addBehavior(CMClass.getBehavior("RandomTeleporter"));
						M.addBehavior(CMClass.getBehavior("Healer"));
					}
					else
					if(special.equals("SPEC_CAST_BIGTIME"))
					{
						// In CoffeeMud, they all cast bigtime
					}
					else
					if(special.equals("SPEC_BREATH_ACID"))
					{
						M.addBehavior(CMClass.getBehavior("CombatAbilities"));
						M.addAbility(CMClass.getAbility("Acidbreath"));
					}
					else
					if(special.equals("SPEC_CAST_JUDGE"))
					{
						M.addBehavior(CMClass.getBehavior("CombatAbilities"));
						M.addAbility(CMClass.getAbility("Skill_Explosive"));
					}
					else
					if(special.equals("SPEC_BREATH_FIRE"))
					{
						M.addBehavior(CMClass.getBehavior("CombatAbilities"));
						M.addAbility(CMClass.getAbility("Firebreath"));
					}
					else
					if(special.equals("SPEC_BREATH_FROST"))
					{
						M.addBehavior(CMClass.getBehavior("CombatAbilities"));
						M.addAbility(CMClass.getAbility("Frostbreath"));
					}
					else
					if(special.equals("SPEC_BREATH_GAS"))
					{
						M.addBehavior(CMClass.getBehavior("CombatAbilities"));
						M.addAbility(CMClass.getAbility("Gasbreath"));
					}
					else
					if(special.equals("SPEC_BREATH_LIGHTNING"))
					{
						M.addBehavior(CMClass.getBehavior("CombatAbilities"));
						M.addAbility(CMClass.getAbility("Lighteningbreath"));
					}
					else
					if(special.equals("SPEC_POISON"))
					{
						M.addBehavior(CMClass.getBehavior("CombatAbilities"));
						M.addAbility(CMClass.getAbility("Poison"));
					}
					else
					if(special.equals("SPEC_OGRE_MEMBER"))
					{
						final Behavior B=CMClass.getBehavior("ROMGangMember");
						B.setParms("Ogre");
						M.addBehavior(B);
					}
					else
					if(special.equals("SPEC_TROLL_MEMBER"))
					{
						final Behavior B=CMClass.getBehavior("ROMGangMember");
						B.setParms("Troll");
						M.addBehavior(B);
					}
					else
					if(special.equals("SPEC_PATROLMAN"))
						M.addBehavior(CMClass.getBehavior("ROMPatrolman"));
					else
						returnAnError(session,"Unknown mob special: "+special,compileErrors,commands);
				}
				else
				if((s.startsWith("#SPE"))||(s.startsWith("S"))||(s.startsWith("*")||(s.startsWith("#$"))||(s.startsWith("R "))))
				{
				}
				else
				if(s.trim().length()>0)
					returnAnError(session,"Unknown mob special line: "+s,compileErrors,commands);
			}
			for(int a=0;a<M.numAbilities();a++)
			{
				final Ability A=M.fetchAbility(a);
				if(A!=null)
					A.autoInvocation(M, false);
			}
			long rejuv=CMProps.getTicksPerMinute()+CMProps.getTicksPerMinute()+(CMProps.getTicksPerMinute()*M.basePhyStats().level()/2);
			if(rejuv>(30*CMProps.getTicksPerMinute()))
				rejuv=(30*CMProps.getTicksPerMinute());
			M.basePhyStats().setRejuv((int)rejuv);
			if(M.displayText().toUpperCase().indexOf("MONEY CHANGER")>=0)
				M.addBehavior(CMClass.getBehavior("MoneyChanger"));
			Behavior B=M.fetchBehavior("CombatAbilities");
			if(B!=null)
			{
				final Behavior BB=B;
				for(final Enumeration<Behavior> e=M.behaviors();e.hasMoreElements();)
				{
					B=e.nextElement();
					if((B!=null)&&(B.getClass().getSuperclass().getName().endsWith("CombatAbilities")))
					{
						M.delBehavior(BB);
						M.recoverPhyStats();
						break;
					}
				}
			}
			M.recoverCharStats();
			M.recoverPhyStats();
			M.recoverMaxState();
			M.resetToMaxState();
			M.text();
			if(OfThisID.startsWith("#"))
				doneMOBS.put(OfThisID.substring(1),(MOB)M.copyOf());
			else
				doneMOBS.put(OfThisID,(MOB)M.copyOf());
			return M;
		}
		return null;
	}