StringConstructor(ObjectValue* string) :
        string(string),
        arguments(new FormalParameterList),
        prototype(new ObjectValue)
    {
        ObjectValue* function = static_cast<ObjectValue*>(getGlobal()->get("Function"));

        arguments->add(new Identifier("value"));
        prototype->put("constructor", string);
        prototype->setPrototype(function->getPrototype()->getPrototype());

        for (int i = 0; i < StringMethod::methodCount(); ++i)
        {
            ObjectValue* function = new ObjectValue;
            StringMethod* method = new StringMethod(function, i);
            function->setCode(method);
            prototype->put(method->name(), function);
        }

        string->setParameterList(arguments);
        string->setScope(getGlobal());
        string->put("prototype", prototype);
        string->setPrototype(function->getPrototype());

        for (int i = 0; i < StringConstructorMethod::methodCount(); ++i)
        {
            ObjectValue* function = new ObjectValue;
            StringConstructorMethod* method = new StringConstructorMethod(function, i);
            function->setCode(method);
            string->put(method->name(), function);
        }
    }
    InterfaceMethodCode(ObjectValue* object, const char* iid, int number) :
        arguments(new FormalParameterList),
        prototype(new ObjectValue),
        iid(iid),
        number(number)
    {
        Reflect::Interface interface = es::getInterface(iid);
        Reflect::Method method(interface.getMethod(number));

#if 0
        // Add as many arguments as required.
        for (int i = 0; i < method.getParameterCount(); ++i)
        {
            Reflect::Parameter param(method.getParameter(i));
            if (param.isInput())
            {
                // Note the name "arguments" is reserved in a ECMAScript function.
                ASSERT(strcmp(param.getName(), "arguments") != 0);
                arguments->add(new Identifier(param.getName()));
            }
        }
#endif

        object->setParameterList(arguments);
        object->setScope(getGlobal());

        // Create Interface.prototype
        prototype->put("constructor", object);
        object->put("prototype", prototype);

    }
    InterfaceStoreConstructor(ObjectValue* object) :
        arguments(new FormalParameterList),
        prototype(new ObjectValue)
    {
        ObjectValue* function = static_cast<ObjectValue*>(getGlobal()->get("Function"));

        arguments->add(new Identifier("iid"));

        object->setParameterList(arguments);
        object->setScope(getGlobal());

        // Create Interface.prototype
        prototype->setPrototype(function->getPrototype()->getPrototype());
        prototype->put("constructor", object);
        object->put("prototype", prototype);
        object->setPrototype(function->getPrototype());
    }
    CompletionType evaluate()
    {
        Register<Value> value = getScopeChain()->get("value");
        Register<StringValue> result = new StringValue(value->isUndefined() ? "" : value->toString());

        if (string->hasInstance(getThis()))
        {
            // Constructor
            ObjectValue* object = static_cast<ObjectValue*>(getThis());
            object->setValueProperty(result);
            Register<NumberValue> length = new NumberValue(result->length());
            object->put("length", length,
                        ObjectValue::DontEnum | ObjectValue::DontDelete | ObjectValue::ReadOnly);
        }

        return CompletionType(CompletionType::Return, result, "");
    }