 								subCall = call.compiledMethod as CompiledFunctionCall;
 							else
 								subCall = compiledParams[call.evalIndex] as CompiledFunctionCall;
-							
+							
 							if (subCall != null)
 							{
+								// special case for for-in and for-each
+								// implemented as "for (each|in)(\in(list), item=undefined, stmt)
+								if (LOOP_LOOKUP[method] && call.evalIndex == INDEX_FOR_ITEM && (method == operators[ST_FOR_IN] || method == operators[ST_FOR_EACH]))
+								{
+									if ((call.evaluatedParams[INDEX_FOR_LIST] as Array).length > 0)
+									{
+										// next item
+										result = (call.evaluatedParams[INDEX_FOR_LIST] as Array).shift(); // property name
+										if (method == operators[ST_FOR_EACH])
+										{
+											// get property value from property name
+											var _in:CompiledFunctionCall = call.compiledParams[INDEX_FOR_LIST] as CompiledFunctionCall;
+											result = _in.evaluatedParams[0][result]; // property value
+										}
+										// set item value
+										subCall.evaluatedParams[subCall.evaluatedParams.length - 1] = result;
+									}
+									else
+									{
+										// break out of loop
+										method = operators[ST_BREAK];
+										break;
+									}
+								}
+								
 								// initialize subCall and push onto stack
 								subCall.evalIndex = INDEX_METHOD;
 								stack.push(subCall);

			}
		}
	}
}

									break;
							result = allSymbolTables[i][symbolName];
						}
						else if (JUMP_LOOKUP[method])
						{
							if (method == operators[ST_RETURN])
							{
								return compiledParams.length ? call.evaluatedParams[0] : undefined;
							}
							else if (method == operators[ST_CONTINUE])
							{
								stack.pop();
								while (stack.length > 0)
								{
									call = stack[stack.length - 1] as CompiledFunctionCall;
									method = call.evaluatedMethod;
									if (LOOP_LOOKUP[method] && LOOP_LOOKUP[method] != ST_BREAK)
									{
										// continue loop
										call.evalIndex = INDEX_METHOD + 1;
										continue stackLoop;
									}
									stack.pop();
								}
								return result; // continue at top level
							}
							else if (method == operators[ST_BREAK])
							{
								while (stack.length > 1)
								{
									call = stack.pop() as CompiledFunctionCall;
									method = call.evaluatedMethod;
									if (LOOP_LOOKUP[method] && LOOP_LOOKUP[method] != ST_CONTINUE)
									{
										method = operators[ST_BREAK];
										continue stackLoop;
									}
								}
								return result; // break at top level
							}
						}
						else if (ASSIGN_OP_LOOKUP[method] && compiledParams.length == 2) // two params means local assignment
						{
							// local assignment
							symbolName = call.evaluatedParams[0];
							if (builtInSymbolTable.hasOwnProperty(symbolName))
								throw new Error("Cannot assign built-in symbol: " + symbolName);
							
							// assignment operator expects parameters like (host, ...chain, value)
							// if there is no matching local variable and 'this' has a matching one, assign the property of 'this'
							if (useThisScope && this && this.hasOwnProperty(symbolName) && !localSymbolTable.hasOwnProperty(symbolName))
								result = method(this, symbolName, call.evaluatedParams[1]);
							else // otherwise, assign local variable
								result = method(localSymbolTable, symbolName, call.evaluatedParams[1]);
						}
						else if (method is Class)
						{
							// type casting
							if (method == Array) // special case for Array
								result = call.evaluatedParams.concat();
							else if (call.evaluatedParams.length != 1)
							{
								// special case for Object('prop1', value1, ...)
								if (method === Object)
								{
									var params:Array = call.evaluatedParams;
									result = {}
									for (i = 0; i < params.length - 1; i += 2)
										result[params[i]] = params[i + 1];
								}
								else
									throw new Error("Incorrect number of arguments for type casting.  Expected 1.");
							}
							// special case for Class('some.qualified.ClassName')
							else if (method === Class && call.evaluatedParams[0] is String)
								result = getDefinitionByName(call.evaluatedParams[0]);
							else // all other single-parameter type casting operations
								result = method(call.evaluatedParams[0]);
						}
						else
						{
							// function call
							result = method.apply(null, call.evaluatedParams);
						}
					}
					catch (e:Error)
					{
