Inheritance: Jint.Parser.Ast.Statement
        /// <summary>
        /// http://www.ecma-international.org/ecma-262/5.1/#sec-12.6.4
        /// </summary>
        /// <param name="forInStatement"></param>
        /// <returns></returns>
        public Completion ExecuteForInStatement(ForInStatement forInStatement)
        {
            Identifier identifier = forInStatement.Left.Type == SyntaxNodes.VariableDeclaration
                                        ? forInStatement.Left.As<VariableDeclaration>().Declarations.First().Id
                                        : forInStatement.Left.As<Identifier>();

            var varRef = _engine.EvaluateExpression(identifier) as Reference;
            var exprRef = _engine.EvaluateExpression(forInStatement.Right);
            var experValue = _engine.GetValue(exprRef);
            if (experValue == Undefined.Instance || experValue == Null.Instance)
            {
                return new Completion(Completion.Normal, null, null);
            }


            var obj = TypeConverter.ToObject(_engine, experValue);
            JsValue v = Null.Instance;

            // keys are constructed using the prototype chain
            var cursor = obj;
            var processedKeys = new HashSet<string>();

            while (cursor != null)
            {
                var keys = cursor.GetOwnProperties().Select(x => x.Key).ToArray();
                foreach (var p in keys)
                {
                    if (processedKeys.Contains(p))
                    {
                        continue;
                    }

                    processedKeys.Add(p);

                    // collection might be modified by inner statement
                    if (!cursor.HasOwnProperty(p))
                    {
                        continue;
                    }

                    var value = cursor.GetOwnProperty(p);
                    if (!value.Enumerable.HasValue || !value.Enumerable.Value)
                    {
                        continue;
                    }

                    _engine.PutValue(varRef, p);

                    var stmt = ExecuteStatement(forInStatement.Body);
                    if (stmt.Value != null)
                    {
                        v = stmt.Value;
                    }
                    if (stmt.Type == Completion.Break)
                    {
                        return new Completion(Completion.Normal, v, null);
                    }
                    if (stmt.Type != Completion.Continue)
                    {
                        if (stmt.Type != Completion.Normal)
                        {
                            return stmt;
                        }
                    }
                }

                cursor = cursor.Prototype;
            }

            return new Completion(Completion.Normal, v, null);
        }
        private void EmitForInStatement(ForInStatement s)
        {
            if (s.Each)
            {
                throw new NotImplementedException();
            }
            else
            {
                Write("for (");
                if (s.Left is VariableDeclaration)
                {
                    var decl = s.Left as VariableDeclaration;
                    Emit(decl.Declarations.First());
                }
                else
                {
                    Emit(s.Left);
                }
                Write(" in ");
                Emit(s.Right);
                Write(") ");
            }

            Emit(s.Body);
        }