public void roomMaintSweep()
	{
		final boolean corpsesOnly=CMSecurity.isSaveFlag(CMSecurity.SaveFlag.ROOMITEMS);
		final boolean noMobs=CMSecurity.isSaveFlag(CMSecurity.SaveFlag.ROOMMOBS);
		setThreadStatus(serviceClient,"expiration sweep");
		final long currentTime=System.currentTimeMillis();
		final boolean debug=CMSecurity.isDebugging(CMSecurity.DbgFlag.VACUUM);
		final MOB expireM=getFactoryMOB(null);
		try
		{
			final List<Environmental> stuffToGo=new ArrayList<Environmental>();
			Item I=null;
			MOB M=null;
			Room R=null;
			final List<Room> roomsToGo=new ArrayList<Room>();
			final CMMsg expireMsg=CMClass.getMsg(expireM,R,null,CMMsg.MSG_EXPIRE,null);
			for(final Enumeration<Room> r=roomsFilled();r.hasMoreElements();)
			{
				R=r.nextElement();
				expireM.setLocation(R);
				expireMsg.setTarget(R);
				if((R.expirationDate()!=0)
				&&(currentTime>R.expirationDate())
				&&(R.okMessage(R,expireMsg)))
					roomsToGo.add(R);
				else
				if(!R.amDestroyed())
				{
					stuffToGo.clear();
					for(int i=0;i<R.numItems();i++)
					{
						I=R.getItem(i);
						if((I!=null)
						&&((!corpsesOnly)||(I instanceof DeadBody))
						&&(I.expirationDate()!=0)
						&&(I.owner()==R)
						&&(currentTime>I.expirationDate()))
							stuffToGo.add(I);
					}
					for(int i=0;i<R.numInhabitants();i++)
					{
						M=R.fetchInhabitant(i);
						if((M!=null)
						&&(!noMobs)
						&&(M.expirationDate()!=0)
						&&(currentTime>M.expirationDate()))
							stuffToGo.add(M);
					}
				}
				if(stuffToGo.size()>0)
				{
					boolean success=true;
					for(int s=0;s<stuffToGo.size();s++)
					{
						final Environmental E=stuffToGo.get(s);
						setThreadStatus(serviceClient,"expiring "+E.Name());
						expireMsg.setTarget(E);
						if(R.okMessage(expireM,expireMsg))
							R.sendOthers(expireM,expireMsg);
						else
							success=false;
						if(debug)
							Log.sysOut("UTILITHREAD","Expired "+E.Name()+" in "+getExtendedRoomID(R)+": "+success);
					}
					stuffToGo.clear();
				}
			}
			for(int r=0;r<roomsToGo.size();r++)
			{
				R=roomsToGo.get(r);
				expireM.setLocation(R);
				expireMsg.setTarget(R);
				setThreadStatus(serviceClient,"expirating room "+getExtendedRoomID(R));
				if(debug)
				{
					String roomID=getExtendedRoomID(R);
					if(roomID.length()==0)
						roomID="(unassigned grid room, probably in the air)";
					if(debug)
						Log.sysOut("UTILITHREAD","Expired "+roomID+".");
				}
				R.sendOthers(expireM,expireMsg);
			}

		}
		catch(final java.util.NoSuchElementException e)
		{
		}
		setThreadStatus(serviceClient,"title sweeping");
		final List<String> playerList=CMLib.database().getUserList();
		try
		{
			for(final Enumeration<Room> r=rooms();r.hasMoreElements();)
			{
				final Room R=r.nextElement();
				final LandTitle T=CMLib.law().getLandTitle(R);
				if(T!=null)
				{
					setThreadStatus(serviceClient,"checking title in "+R.roomID()+": "+Runtime.getRuntime().freeMemory());
					T.updateLot(playerList);
					setThreadStatus(serviceClient,"title sweeping");
				}
			}
		}
		catch(final NoSuchElementException nse)
		{
		}

		setThreadStatus(serviceClient,"cleaning scripts");
		for(final String areaKey : scriptHostMap.keySet())
			cleanScriptHosts(scriptHostMap.get(areaKey), null, true);

		final long lastDateTime=System.currentTimeMillis()-(5*TimeManager.MILI_MINUTE);
		setThreadStatus(serviceClient,"checking");
		try
		{
			for(final Enumeration<Room> r=roomsFilled();r.hasMoreElements();)
			{
				final Room R=r.nextElement();
				for(int m=0;m<R.numInhabitants();m++)
				{
					final MOB mob=R.fetchInhabitant(m);
					if(mob == null)
						continue;
					if(mob.amDestroyed())
					{
						R.delInhabitant(mob);
						continue;
					}
					if((mob.lastTickedDateTime()>0)&&(mob.lastTickedDateTime()<lastDateTime))
					{
						final boolean ticked=CMLib.threads().isTicking(mob,Tickable.TICKID_MOB);
						final boolean isDead=mob.amDead();
						final Room startR=mob.getStartRoom();
						final String wasFrom=(startR!=null)?startR.roomID():"NULL";
						if(!ticked)
						{
							if(!mob.isPlayer())
							{
								if(ticked)
								{
									// we have a dead group.. let the group handler deal with it.
									Log.errOut(serviceClient.getName(),mob.name()+" in room "+CMLib.map().getDescriptiveExtendedRoomID(R)
											+" unticked in dead group (Home="+wasFrom+") since: "+CMLib.time().date2String(mob.lastTickedDateTime())+".");
									continue;
								}
								else
								{
									Log.errOut(serviceClient.getName(),mob.name()+" in room "+CMLib.map().getDescriptiveExtendedRoomID(R)
											+" unticked (is ticking="+(ticked)+", dead="+isDead+", Home="+wasFrom+") since: "+CMLib.time().date2String(mob.lastTickedDateTime())+"."+(ticked?"":"  This mob has been destroyed. May he rest in peace."));
									mob.destroy();
								}
							}
							else
							{
								Log.errOut(serviceClient.getName(),"Player "+mob.name()+" in room "+CMLib.map().getDescriptiveExtendedRoomID(R)
										+" unticked (is ticking="+(ticked)+", dead="+isDead+", Home="+wasFrom+") since: "+CMLib.time().date2String(mob.lastTickedDateTime())+"."+(ticked?"":"  This mob has been put aside."));
							}
							R.delInhabitant(mob);//keeps it from happening again.
							setThreadStatus(serviceClient,"checking");
						}
					}
				}
			}
		}
		catch(final java.util.NoSuchElementException e)
		{
		}
		finally
		{
			if(expireM!=null)
				expireM.destroy();
		}
	}