private boolean beMobile(final MOB mob,
							 boolean dooropen,
							 final boolean wander,
							 final boolean roomprefer,
							 final boolean roomobject,
							 final boolean sneakIfAble,
							 final int[] status,
							 final Set<Room> rooms)
	{
		if(status!=null)
			status[0]=Tickable.STATUS_MISC7+0;

		// ridden and following things aren't mobile!
		if(((mob instanceof Rideable)&&(((Rideable)mob).numRiders()>0))
		||((mob.amFollowing()!=null)&&(mob.location()==mob.amFollowing().location())))
		{
			if(status!=null)
				status[0]=Tickable.STATUS_NOT;
			return false;
		}

		Room oldRoom=mob.location();

		if(isAnAdminHere(oldRoom, true))
		{
			if(status!=null)
				status[0]=Tickable.STATUS_NOT;
			return false;
		}

		if(oldRoom instanceof GridLocale)
		{
			final Room R=((GridLocale)oldRoom).getRandomGridChild();
			if(R!=null)
				R.bringMobHere(mob,true);
			oldRoom=mob.location();
		}

		if(oldRoom == null)
		{
			if((!mob.amDead())&&(!mob.amDestroyed()))
			{
				if(mob.isPlayer() && (mob.getStartRoom()!=null))
					mob.getStartRoom().bringMobHere(mob, true);
				else
					mob.killMeDead(false);
				Log.errOut("MUDTracker","Inexplicable lost room for '"+mob.Name()+"'.  Killing dead.");
			}
			return false;
		}

		if(status!=null)
			status[0]=Tickable.STATUS_MISC7+3;
		int tries=0;
		int direction=-1;
		final CMFlagLibrary flags=CMLib.flags();
		while(((tries++)<10)&&(direction<0))
		{
			direction=CMLib.dice().roll(1,Directions.NUM_DIRECTIONS(),-1);
			final Room nextRoom=oldRoom.getRoomInDir(direction);
			final Exit nextExit=oldRoom.getExitInDir(direction);
			if((nextRoom!=null)&&(nextExit!=null))
			{
				if(isAnAdminHere(nextRoom, true))
				{
					direction=-1;
					continue;
				}

				final Exit opExit=nextRoom.getExitInDir(Directions.getOpDirectionCode(direction));
				if(flags.isTrapped(nextExit)
				||(flags.isHidden(nextExit)&&(!flags.canSeeHidden(mob))&&(!flags.canSeeHiddenItems(mob)))
				||(flags.isInvisible(nextExit)&&(!flags.canSeeInvisible(mob))))
					direction=-1;
				else
				if((opExit!=null)&&(flags.isTrapped(opExit)))
					direction=-1;
				else
				if((oldRoom.domainType()!=nextRoom.domainType())
				&&(!flags.isInFlight(mob))
				&&((nextRoom.domainType()==Room.DOMAIN_INDOORS_AIR)
				||(nextRoom.domainType()==Room.DOMAIN_OUTDOORS_AIR)))
					direction=-1;
				else
				if((oldRoom.domainType()!=nextRoom.domainType())
				&&(!flags.isSwimming(mob))
				&&(flags.isUnderWateryRoom(nextRoom)))
					direction=-1;
				else
				if((!wander)&&(!oldRoom.getArea().Name().equals(nextRoom.getArea().Name())))
					direction=-1;
				else
				if((roomobject)&&(rooms!=null)&&(rooms.contains(nextRoom)))
					direction=-1;
				else
				if((roomprefer)&&(rooms!=null)&&(!rooms.contains(nextRoom)))
					direction=-1;
				else
					break;
			}
			else
				direction=-1;
		}

		if(status!=null)
			status[0]=Tickable.STATUS_MISC7+10;

		if(direction<0)
		{
			if(status!=null)
				status[0]=Tickable.STATUS_NOT;
			return false;
		}

		final Room nextRoom=oldRoom.getRoomInDir(direction);
		final Exit nextExit=oldRoom.getExitInDir(direction);
		final int opDirection=Directions.getOpDirectionCode(direction);

		if((nextRoom==null)||(nextExit==null))
		{
			if(status!=null)
				status[0]=Tickable.STATUS_NOT;
			return false;
		}

		if(dooropen)
		{
			final LandTitle landTitle=CMLib.law().getLandTitle(nextRoom);
			if((landTitle!=null)&&(landTitle.getOwnerName().length()>0))
				dooropen=false;
		}

		boolean reclose=false;
		boolean relock=false;
		// handle doors!
		if(nextExit.hasADoor()&&(!nextExit.isOpen())&&(dooropen))
		{
			if((nextExit.hasALock())&&(nextExit.isLocked()))
			{
				CMMsg msg=CMClass.getMsg(mob,nextExit,null,CMMsg.MSG_OK_VISUAL,CMMsg.MSG_OK_VISUAL,CMMsg.MSG_OK_VISUAL,null);
				if(oldRoom.okMessage(mob,msg))
				{
					relock=true;
					msg=CMClass.getMsg(mob,nextExit,null,CMMsg.MSG_OK_VISUAL,CMMsg.MSG_UNLOCK,CMMsg.MSG_OK_VISUAL,L("<S-NAME> unlock(s) <T-NAMESELF>."));
					if(oldRoom.okMessage(mob,msg))
						CMLib.utensils().roomAffectFully(msg,oldRoom,direction);
				}
			}
			if(!nextExit.isOpen())
			{
				mob.doCommand(getOpenCommandSet(direction),MUDCmdProcessor.METAFLAG_FORCED);
				if(nextExit.isOpen())
					reclose=true;
			}
		}
		if(!nextExit.isOpen())
		{
			if(status!=null)
				status[0]=Tickable.STATUS_NOT;
			return false;
		}

		if(((flags.isWaterySurfaceRoom(nextRoom)))
		   &&(!flags.isWaterWorthy(mob))
		   &&(!flags.isInFlight(mob))
		   &&(mob.fetchAbility("Skill_Swim")!=null))
		{
			final Ability A=mob.fetchAbility("Skill_Swim");
			final List<String> V=getDirectionCommandSet(direction);
			if(A.proficiency()<50)
				A.setProficiency(CMLib.dice().roll(1,50,A.adjustedLevel(mob,0)*15));
			final CharState oldState=(CharState)mob.curState().copyOf();
			A.invoke(mob,V,null,false,0);
			mob.curState().setMana(oldState.getMana());
			mob.curState().setMovement(oldState.getMovement());
		}
		else
		if(((nextRoom.ID().indexOf("Surface")>0)||(flags.isClimbing(nextExit))||(flags.isClimbing(nextRoom)))
		&&(!flags.isClimbing(mob))
		&&(!flags.isInFlight(mob))
		&&((mob.fetchAbility("Skill_Climb")!=null)||(mob.fetchAbility("Power_SuperClimb")!=null)))
		{
			Ability A=mob.fetchAbility("Skill_Climb");
			if(A==null )
				A=mob.fetchAbility("Power_SuperClimb");
			final List<String> V=getDirectionCommandSet(direction);
			if(A.proficiency()<50)
				A.setProficiency(CMLib.dice().roll(1,50,A.adjustedLevel(mob,0)*15));
			final CharState oldState=(CharState)mob.curState().copyOf();
			A.invoke(mob,V,null,false,0);
			mob.curState().setMana(oldState.getMana());
			mob.curState().setMovement(oldState.getMovement());
		}
		else
		if((mob.fetchAbility("Thief_Sneak")!=null)&&(sneakIfAble))
		{
			final Ability A=mob.fetchAbility("Thief_Sneak");
			final List<String> V=getDirectionCommandSet(direction);
			if(A.proficiency()<50)
			{
				A.setProficiency(CMLib.dice().roll(1,50,A.adjustedLevel(mob,0)*15));
				final Ability A2=mob.fetchAbility("Thief_Hide");
				if(A2!=null)
					A2.setProficiency(CMLib.dice().roll(1,50,A.adjustedLevel(mob,0)*15));
			}
			final int oldMana=mob.curState().getMana();
			final int oldMove=mob.curState().getMovement();
			A.invoke(mob,V,null,false,0);
			mob.curState().setMana(oldMana);
			mob.curState().setMovement(oldMove);
		}
		else
		{
			walk(mob,direction,false,false);
		}
		if(status!=null)
			status[0]=Tickable.STATUS_MISC7+21;

		if((reclose)&&(mob.location()==nextRoom)&&(dooropen))
		{
			final Exit opExit=nextRoom.getExitInDir(opDirection);
			if((opExit!=null)
			&&(opExit.hasADoor())
			&&(opExit.isOpen()))
			{
				mob.doCommand(getCloseCommandSet(opDirection),MUDCmdProcessor.METAFLAG_FORCED);
				if((opExit.hasALock())&&(relock))
				{
					CMMsg msg=CMClass.getMsg(mob,opExit,null,CMMsg.MSG_OK_VISUAL,CMMsg.MSG_OK_VISUAL,CMMsg.MSG_OK_VISUAL,null);
					if(nextRoom.okMessage(mob,msg))
					{
						msg=CMClass.getMsg(mob,opExit,null,CMMsg.MSG_OK_VISUAL,CMMsg.MSG_LOCK,CMMsg.MSG_OK_VISUAL,L("<S-NAME> lock(s) <T-NAMESELF>."));
						if(nextRoom.okMessage(mob,msg))
							CMLib.utensils().roomAffectFully(msg,nextRoom,opDirection);
					}
				}
			}
		}
		if(status!=null)
			status[0]=Tickable.STATUS_NOT;
		return mob.location()!=oldRoom;
	}