protected DeadBody justDie(final MOB source, final MOB target)
	{
		if(target==null)
			return null;
		final Room deathRoom=target.location();
		if(deathRoom == null)
			return null;

		//TODO: this creates too many loops.  The right thing is to loop once
		// and call  a boolean function to populate all these lists.
		final CharClass combatCharClass=getCombatDominantClass(source,target);
		final Set<MOB> beneficiaries=getCombatBeneficiaries(source,target,combatCharClass);
		final Set<MOB> hisGroupH=target.getGroupMembers(new HashSet<MOB>());
		for(final Enumeration<MOB> m=deathRoom.inhabitants();m.hasMoreElements();)
		{
			final MOB M=m.nextElement();
			if((M!=null)&&(M.getVictim()==target))
				pickNextVictim(M, target, hisGroupH);
		}
		final Set<MOB> dividers=getCombatDividers(source,target,combatCharClass);

		dispenseExperience(beneficiaries,dividers,target);

		final String currency=CMLib.beanCounter().getCurrency(target);
		final double deadMoney=CMLib.beanCounter().getTotalAbsoluteValue(target,currency);
		double myAmountOfDeadMoney=0.0;
		final Vector<MOB> goldLooters=new Vector<MOB>();
		for (final MOB M : beneficiaries)
		{
			if(((M.isAttributeSet(MOB.Attrib.AUTOGOLD))
			&&(!goldLooters.contains(M)))
			&&(M!=target)
			&&(M.location()==deathRoom)
			&&(deathRoom.isInhabitant(M)))
				goldLooters.addElement(M);
		}
		if((goldLooters.size()>0)&&(deadMoney>0))
		{
			myAmountOfDeadMoney=CMath.div(deadMoney,goldLooters.size());
			CMLib.beanCounter().subtractMoney(target,deadMoney);
		}

		final int[] expLost={100*target.phyStats().level()};
		if(expLost[0]<100)
			expLost[0]=100;
		String[] cmds=null;
		if((target.isMonster())||(target.soulMate()!=null))
			cmds=CMParms.toStringArray(CMParms.parseCommas(CMProps.getVar(CMProps.Str.MOBDEATH),true));
		else
			cmds=CMParms.toStringArray(CMParms.parseCommas(CMProps.getVar(CMProps.Str.PLAYERDEATH),true));

		DeadBody body=null; //must be done before consequences because consequences could be purging
		if((!CMParms.containsIgnoreCase(cmds,"RECALL"))
		&&(!isKnockedOutUponDeath(target,source)))
			body=target.killMeDead(true);

		handleCombatLossConsequences(target,source,cmds,expLost,"^*You lose @x1 experience points.^?^.");

		if(!isKnockedOutUponDeath(target,source))
		{
			Room bodyRoom=deathRoom;
			if((body!=null)&&(body.owner() instanceof Room)&&(((Room)body.owner()).isContent(body)))
				bodyRoom=(Room)body.owner();
			if((source!=null)&&(body!=null))
			{
				body.setKillerName(source.Name());
				body.setIsKillerPlayer(!source.isMonster());
				body.setKillerTool(source.fetchWieldedItem());
				if(body.getKillerTool()==null)
					body.setKillerTool(source.getNaturalWeapon());
			}

			if((!target.isMonster())
			&&(CMLib.dice().rollPercentage()==1)
			&&(!CMSecurity.isDisabled(CMSecurity.DisFlag.AUTODISEASE)))
			{
				final Ability A=CMClass.getAbility("Disease_Amnesia");
				if((A!=null)&&(target.fetchEffect(A.ID())==null)&&(!CMSecurity.isAbilityDisabled(A.ID())))
					A.invoke(target,target,true,0);
			}

			if(target.soulMate()!=null)
			{
				final Session s=target.session();
				s.setMob(target.soulMate());
				target.soulMate().setSession(s);
				target.setSession(null);
				target.soulMate().tell(L("^HYour spirit has returned to your body...\n\r\n\r^N"));
				CMLib.commands().postLook(target.soulMate(),true);
				target.setSoulMate(null);
			}

			if((source!=null)
			&&(bodyRoom!=null)
			&&(body!=null)
			&&(source.location()==bodyRoom)
			&&(bodyRoom.isInhabitant(source))
			&&(source.isAttributeSet(MOB.Attrib.AUTOLOOT)))
			{
				if((source.riding()!=null)&&(source.riding() instanceof MOB))
					source.tell(L("You'll need to dismount to loot the body."));
				else
				if((source.riding()!=null)&&(source.riding() instanceof MOB))
					source.tell(L("You'll need to disembark to loot the body."));
				else
				for(int i=bodyRoom.numItems()-1;i>=0;i--)
				{
					final Item item=bodyRoom.getItem(i);
					if((item!=null)
					&&(item.container()==body)
					&&(CMLib.flags().canBeSeenBy(body,source))
					&&((!body.isDestroyedAfterLooting())||(!(item instanceof RawMaterial)))
					&&(CMLib.flags().canBeSeenBy(item,source)))
						CMLib.commands().postGet(source,body,item,false);
				}
				if(body.isDestroyedAfterLooting())
					bodyRoom.recoverRoomStats();
			}

			Coins C=null;
			if((deadMoney>0)&&(myAmountOfDeadMoney>0)&&(body!=null)&&(bodyRoom!=null))
			for(int g=0;g<goldLooters.size();g++)
			{
				C=CMLib.beanCounter().makeBestCurrency(currency,myAmountOfDeadMoney,null,body);
				if(C!=null)
				{
					C.recoverPhyStats();
					bodyRoom.addItem(C,ItemPossessor.Expire.Monster_EQ);
					bodyRoom.recoverRoomStats();
					final MOB mob=goldLooters.elementAt(g);
					if(mob.location()==bodyRoom)
					{
						if((mob.riding()!=null)&&(mob.riding() instanceof MOB))
							mob.tell(L("You'll need to dismount to get @x1 off the body.",C.name()));
						else
						if((mob.riding()!=null)&&(mob.riding() instanceof Item))
							mob.tell(L("You'll need to disembark to get @x1 off the body.",C.name()));
						else
						if(CMLib.flags().canBeSeenBy(body,mob))
							CMLib.commands().postGet(mob,body,C,false);
					}
				}
			}

			if((source != null)&&(source.getVictim()==target))
				source.setVictim(null);
			target.setVictim(null);
			if((body!=null)&&(bodyRoom!=null)&&(body.isDestroyedAfterLooting()))
			{
				for(int i=bodyRoom.numItems()-1;i>=0;i--)
				{
					final Item item=bodyRoom.getItem(i);
					if((item!=null)&&(item.container()==body))
						item.setContainer(null);
				}
				body.destroy();
				bodyRoom.recoverPhyStats();
				return null;
			}
			return body;
		}
		return null;
	}