public Object getStat(String statName)
		{
			final int x=statName.indexOf('#');
			String whichStr=null;
			int whichNum=-1;
			if(x>=0)
			{
				whichStr=statName.substring(x+1);
				if(whichStr.length()>0)
					whichNum=CMath.s_parseIntExpression(whichStr);
				statName=statName.substring(0,x);
			}
			Object O=null;
			int code=-1;
			for(int i=0;i<QOBJS.length;i++)
			{
				if(statName.equalsIgnoreCase(QOBJS[i]))
				{
					code=i;
					break;
				}
			}
			switch(code)
			{
			case 0:
				O = loadedMobs;
				break;
			case 1:
				O = loadedItems;
				break;
			case 2:
				O = area;
				break;
			case 3:
				O = room;
				break;
			case 4:
				O = mobGroup;
				break;
			case 5:
				O = itemGroup;
				break;
			case 6:
				O = roomGroup;
				break;
			case 7:
				O = item;
				break;
			case 8:
				O = envObject;
				break;
			case 9:
				O = new ConvertingList<PreservedQuestObject, PhysicalAgent>(worldObjects, PreservedQuestObject.converter);
				break;
			case 10:
				O = mob;
				break;
			default:
				if(mysteryData!=null)
					O=mysteryData.getStat(statName);
				break;
			}
			if(O instanceof List)
			{
				final List V=(List)O;
				if((whichStr!=null)&&((whichNum<=0)||(whichNum>V.size())))
					return ""+V.size();
				if(whichStr!=null)
					return V.get(whichNum-1);
			}
			return O;
		}
	}

	/**
	 * MysteryData is a helper class for QuestState that stores quest
	 * state variables for the parsing of quests that make use of the
	 * "mystery" variables (mystery as in Sherlock Holmes, not as in
	 * unknown).
	 * @author Bo Zimmermanimmerman
	 */
	public static class MysteryData implements Cloneable
	{
		public List<Faction>		factionGroup;
		public Faction				faction;
		public MOB					agent;
		public List<MOB>			agentGroup;
		public Environmental		target;
		public List<Environmental>	targetGroup;
		public Environmental		tool;
		public List<Environmental>	toolGroup;
		public Room					whereHappened;
		public List<Room>			whereHappenedGroup;
		public Room					whereAt;
		public List<Room>			whereAtGroup;
		public String				action;
		public List<String>			actionGroup;
		public String				motive;
		public List<String>			motiveGroup;
		public TimeClock			whenHappened;
		public List<TimeClock>		whenHappenedGroup;
		public TimeClock			whenAt;
		public List<TimeClock>		whenAtGroup;

		public boolean isStat(String statName)
		{
			for (final String element : MYSTERY_QCODES)
			{
				if(statName.equalsIgnoreCase(element))
					return true;
			}
			return false;
		}

		public Object getStat(String statName)
		{
			int code=-1;
			for(int i=0;i<MYSTERY_QCODES.length;i++)
			{
				if(statName.equalsIgnoreCase(MYSTERY_QCODES[i]))
				{
					code = i;
					break;
				}
			}
			switch(code)
			{
			case 0:
				return faction;
			case 1:
				return factionGroup;
			case 2:
				return agent;
			case 3:
				return agentGroup;
			case 4:
				return action;
			case 5:
				return actionGroup;
			case 6:
				return target;
			case 7:
				return targetGroup;
			case 8:
				return motive;
			case 9:
				return motiveGroup;
			case 10:
				return whereHappened;
			case 11:
				return whereHappenedGroup;
			case 12:
				return whereAt;
			case 13:
				return whereAtGroup;
			case 14:
				return whenHappened;
			case 15:
				return whenHappenedGroup;
			case 16:
				return whenAt;
			case 17:
				return whenAtGroup;
			case 18:
				return tool;
			case 19:
				return toolGroup;
			}
			return null;
		}
	}

	protected static class JScriptQuest extends ScriptableObject
	{
		@Override
		public String getClassName()
		{
			return "JScriptQuest";
		}

		static final long	serialVersionUID	= 44;
		Quest				quest				= null;
		QuestState			state				= null;

		public Quest quest()
		{
			return quest;
		}

		public QuestState setupState()
		{
			return state;
		}

		public JScriptQuest(Quest Q, QuestState S)
		{
			quest = Q;
			state = S;
		}

		public static String[]	functions	= { "quest", "setupState", "toJavaString" };

		public String toJavaString(Object O)
		{
			return Context.toString(O);
		}