@Override
	public void executeMsg(final Environmental myHost, final CMMsg msg)
	{
		getArea().executeMsg(this,msg);

		if(msg.amITarget(this))
		{
			final MOB mob=msg.source();
			switch(msg.targetMinor())
			{
			case CMMsg.TYP_LEAVE:
			{
				if(!CMath.bset(msg.targetMajor(),CMMsg.MASK_OPTIMIZE))
					recoverRoomStats();
				break;
			}
			case CMMsg.TYP_FLEE:
			{
				if(!CMath.bset(msg.targetMajor(),CMMsg.MASK_OPTIMIZE))
					recoverRoomStats();
				break;
			}
			case CMMsg.TYP_ENTER:
			case CMMsg.TYP_RECALL:
			{
				if(!CMath.bset(msg.targetMajor(),CMMsg.MASK_OPTIMIZE))
					recoverRoomStats();
				if((msg.source().playerStats()!=null)&&(msg.source().soulMate()==null))
				{
					if(msg.source().playerStats().addRoomVisit(this))
						CMLib.players().bumpPrideStat(msg.source(),AccountStats.PrideStat.ROOMS_EXPLORED, 1);
				}
				break;
			}
			case CMMsg.TYP_LOOK_EXITS:
				if(msg.value()==CMMsg.MASK_OPTIMIZE)
					CMLib.commands().lookAtExitsShort(this, msg.source());
				else
					CMLib.commands().lookAtExits(this, msg.source());
				break;
			case CMMsg.TYP_LOOK:
			case CMMsg.TYP_EXAMINE:
				CMLib.commands().handleBeingLookedAt(msg);
				break;
			case CMMsg.TYP_SNIFF:
				CMLib.commands().handleBeingSniffed(msg);
				break;
			case CMMsg.TYP_READ:
				if(CMLib.flags().canBeSeenBy(this,mob))
					mob.tell(L("There is nothing written here."));
				else
					mob.tell(L("You can't see that!"));
				break;
			case CMMsg.TYP_AREAAFFECT:
				// obsolete with the area objects
				break;
			case CMMsg.TYP_DIG:
				if(findItem("HoleInTheGround")==null)
					addItem(CMClass.getBasicItem("HoleInTheGround"));
				break;
			default:
				break;
			}
		}
		if(numItems()>0)
		{
			eachItem(new EachApplicable<Item>()
			{ 
				@Override
				public final void apply(final Item I)
				{
					I.executeMsg(me, msg);
				} 
			});
		}

		for(int d=Directions.NUM_DIRECTIONS()-1;d>=0;d--)
		{
			final Exit E=getRawExit(d);
			if(E!=null)
				E.executeMsg(this,msg);
		}

		if(numBehaviors()>0)
		{
			eachBehavior(new EachApplicable<Behavior>()
			{
				@Override
				public final void apply(final Behavior B)
				{
					B.executeMsg(me, msg);
				} 
			});
		}
		if(numScripts()>0)
		{
			eachScript(new EachApplicable<ScriptingEngine>()
			{ 
				@Override
				public final void apply(final ScriptingEngine S)
				{
					S.executeMsg(me, msg);
				} 
			});
		}
		if(numEffects()>0)
		{
			eachEffect(new EachApplicable<Ability>()
			{ 
				@Override
				public final void apply(final Ability A)
				{
					A.executeMsg(me,msg);
				} 
			});
		}

		if(msg.sourceMinor()==CMMsg.TYP_SHUTDOWN)
		{
			try
			{
				if(CMSecurity.isSaveFlag(CMSecurity.SaveFlag.ROOMMOBS))
				{
					if(roomID().length()==0)
					{
						eachInhabitant(new EachApplicable<MOB>()
						{ 
							@Override
							public final void apply(final MOB M)
							{
								if((M.isSavable())
								&&(M.getStartRoom()!=me)
								&&(M.getStartRoom()!=null)
								&&(M.getStartRoom().roomID().length()>0))
									M.getStartRoom().bringMobHere(M,false);
							} 
						});
					}
				}
				else
				if(CMSecurity.isSaveFlag(CMSecurity.SaveFlag.ROOMSHOPS))
				{
					eachInhabitant(new EachApplicable<MOB>()
					{ 
						@Override
						public final void apply(final MOB M)
						{
							if((M instanceof ShopKeeper)
							&&(M.isSavable())
							&&(M.getStartRoom()!=me)
							&&(M.getStartRoom()!=null))
								M.getStartRoom().bringMobHere(M,false);
						} 
					});
				}
			}
			catch(final NoSuchElementException e)
			{
			}
		}

		if(msg.amITarget(this)&&(msg.targetMinor()==CMMsg.TYP_EXPIRE))
		{
			synchronized(("SYNC"+roomID()).intern())
			{
				final LinkedList<DeadBody> deadBodies=new LinkedList<DeadBody>();
				eachItem(new EachApplicable<Item>()
				{
					@Override public final void apply(final Item I)
					{
						if((I instanceof DeadBody)
						&&(((DeadBody)I).isPlayerCorpse()))
							deadBodies.add((DeadBody)I);
					} 
				});
				for(final DeadBody D : deadBodies)
				{
					MOB M=CMLib.players().getLoadPlayer(D.getMobName());
					if(M==null)
						M=D.getSavedMOB();
					if((M!=null)&&(M.getStartRoom()!=null))
					{
						final Room startRoom=CMLib.map().getRoom(M.getStartRoom());
						M.tell(L("Your corpse has been moved to @x1",startRoom.displayText()));
						startRoom.moveItemTo(D);
					}
				}
				if(gridParent!=null)
					gridParent.executeMsg(myHost,msg);
				else
				if((roomID().length()>0)
				&&((getArea()==null)||(!CMath.bset(getArea().flags(), Area.FLAG_INSTANCE_CHILD)))
				&&(CMSecurity.isSaveFlag(CMSecurity.SaveFlag.ROOMMOBS)
					||CMSecurity.isSaveFlag(CMSecurity.SaveFlag.ROOMITEMS)
					||CMSecurity.isSaveFlag(CMSecurity.SaveFlag.ROOMSHOPS)))
				{
					final ArrayList<MOB> shopmobs=new ArrayList<MOB>(1);
					final ArrayList<Item> bodies=new ArrayList<Item>(1);
					if(CMSecurity.isSaveFlag(CMSecurity.SaveFlag.ROOMMOBS))
					{
						eachInhabitant(new EachApplicable<MOB>()
						{ 
							@Override
							public final void apply(final MOB M)
							{
								if(M.isSavable())
								{
									M.setStartRoom(me);
									M.text(); // this permanizes his current state
								}
							} 
						});
						CMLib.database().DBUpdateMOBs(this);
					}
					else
					if(CMSecurity.isSaveFlag(CMSecurity.SaveFlag.ROOMSHOPS))
					{
						eachInhabitant(new EachApplicable<MOB>()
						{ 
							@Override
							public final void apply(final MOB M)
							{
								if((M.isSavable())
								&&(M instanceof ShopKeeper)
								&&(M.getStartRoom()==me))
									shopmobs.add(M);
							} 
						});
						if(!shopmobs.isEmpty())
							CMLib.database().DBUpdateTheseMOBs(this,shopmobs);
					}
					if(CMSecurity.isSaveFlag(CMSecurity.SaveFlag.ROOMITEMS))
					{
						eachItem(new EachApplicable<Item>()
						{ 
							@Override public final void apply(final Item I)
							{
								if(I instanceof DeadBody)
									bodies.add(I);
							}
						});
						for(int i=0;i<bodies.size();i++)
							bodies.get(i).destroy();
						CMLib.database().DBUpdateItems(this);
					}
				}
				final Area A=getArea();
				final String roomID=roomID();
				setGridParent(null);
				if(!CMProps.getBoolVar(CMProps.Bool.MUDSHUTTINGDOWN))
				{
					CMLib.map().emptyRoom(this,null,true);
					destroy();
					if(roomID.length()>0)
						A.addProperRoomnumber(roomID);
				}
			}
		}
	}