v8::Handle<v8::Value> V8InjectedScriptHost::getInternalPropertiesMethodCustom(const v8::Arguments& args)
{
    if (args.Length() < 1)
        return v8::Undefined();

    v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(args[0]);

    InjectedScriptHost* host = V8InjectedScriptHost::toNative(args.Holder());
    ScriptDebugServer& debugServer = host->scriptDebugServer();
    return debugServer.getInternalProperties(object);
}
v8::Handle<v8::Value> V8InjectedScriptHost::setFunctionVariableValueMethodCustom(const v8::Arguments& args)
{
    v8::Handle<v8::Value> functionValue = args[0];
    int scopeIndex = args[1]->Int32Value();
    String variableName = toWebCoreStringWithUndefinedOrNullCheck(args[2]);
    v8::Handle<v8::Value> newValue = args[3];

    InjectedScriptHost* host = V8InjectedScriptHost::toNative(args.Holder());
    ScriptDebugServer& debugServer = host->scriptDebugServer();
    return debugServer.setFunctionVariableValue(functionValue, scopeIndex, variableName, newValue);
}
void V8InjectedScriptHost::setFunctionVariableValueMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    v8::Handle<v8::Value> functionValue = info[0];
    int scopeIndex = info[1]->Int32Value();
    String variableName = toWebCoreStringWithUndefinedOrNullCheck(info[2]);
    v8::Handle<v8::Value> newValue = info[3];

    InjectedScriptHost* host = V8InjectedScriptHost::toNative(info.Holder());
    ScriptDebugServer& debugServer = host->scriptDebugServer();
    v8SetReturnValue(info, debugServer.setFunctionVariableValue(functionValue, scopeIndex, variableName, newValue));
}
void V8InjectedScriptHost::getInternalPropertiesMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    if (info.Length() < 1)
        return;

    v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(info[0]);

    InjectedScriptHost* host = V8InjectedScriptHost::toNative(info.Holder());
    ScriptDebugServer& debugServer = host->scriptDebugServer();
    v8SetReturnValue(info, debugServer.getInternalProperties(object));
}
v8::Handle<v8::Value> V8InjectedScriptHost::getInternalPropertiesCallback(const v8::Arguments& args)
{
    INC_STATS("InjectedScriptHost.getInternalProperties()");
    if (args.Length() < 1)
        return v8::Undefined();

    v8::HandleScope handleScope;

    v8::Handle<v8::Object> object = v8::Handle<v8::Object>::Cast(args[0]);

    InjectedScriptHost* host = V8InjectedScriptHost::toNative(args.Holder());
    ScriptDebugServer& debugServer = host->scriptDebugServer();
    return debugServer.getInternalProperties(object);
}
v8::Handle<v8::Value> V8InjectedScriptHost::functionDetailsCallback(const v8::Arguments& args)
{
    INC_STATS("InjectedScriptHost.functionDetailsCallback()");
    if (args.Length() < 1)
        return v8::Undefined();

    v8::HandleScope handleScope;

    v8::Handle<v8::Value> value = args[0];
    if (!value->IsFunction())
        return v8::Undefined();
    v8::Handle<v8::Function> function = v8::Handle<v8::Function>::Cast(value);
    int lineNumber = function->GetScriptLineNumber();
    int columnNumber = function->GetScriptColumnNumber();

    v8::Local<v8::Object> location = v8::Object::New();
    location->Set(v8::String::NewSymbol("lineNumber"), v8Integer(lineNumber, args.GetIsolate()));
    location->Set(v8::String::NewSymbol("columnNumber"), v8Integer(columnNumber, args.GetIsolate()));
    location->Set(v8::String::NewSymbol("scriptId"), function->GetScriptId()->ToString());

    v8::Local<v8::Object> result = v8::Object::New();
    result->Set(v8::String::NewSymbol("location"), location);

    v8::Handle<v8::Value> name = function->GetName();
    if (name->IsString() && v8::Handle<v8::String>::Cast(name)->Length())
        result->Set(v8::String::NewSymbol("name"), name);

    v8::Handle<v8::Value> inferredName = function->GetInferredName();
    if (inferredName->IsString() && v8::Handle<v8::String>::Cast(inferredName)->Length())
        result->Set(v8::String::NewSymbol("inferredName"), inferredName);

    InjectedScriptHost* host = V8InjectedScriptHost::toNative(args.Holder());
    ScriptDebugServer& debugServer = host->scriptDebugServer();
    v8::Handle<v8::Value> scopes = debugServer.functionScopes(function);
    if (!scopes.IsEmpty() && scopes->IsArray())
        result->Set(v8::String::NewSymbol("rawScopes"), scopes);

    return result;
}
void V8InjectedScriptHost::functionDetailsMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& info)
{
    if (info.Length() < 1)
        return;

    v8::Handle<v8::Value> value = info[0];
    if (!value->IsFunction())
        return;
    v8::Handle<v8::Function> function = v8::Handle<v8::Function>::Cast(value);
    int lineNumber = function->GetScriptLineNumber();
    int columnNumber = function->GetScriptColumnNumber();

    v8::Local<v8::Object> location = v8::Object::New();
    location->Set(v8::String::NewSymbol("lineNumber"), v8::Integer::New(lineNumber, info.GetIsolate()));
    location->Set(v8::String::NewSymbol("columnNumber"), v8::Integer::New(columnNumber, info.GetIsolate()));
    location->Set(v8::String::NewSymbol("scriptId"), function->GetScriptId()->ToString());

    v8::Local<v8::Object> result = v8::Object::New();
    result->Set(v8::String::NewSymbol("location"), location);

    v8::Handle<v8::Value> name = function->GetName();
    if (name->IsString() && v8::Handle<v8::String>::Cast(name)->Length())
        result->Set(v8::String::NewSymbol("name"), name);

    v8::Handle<v8::Value> inferredName = function->GetInferredName();
    if (inferredName->IsString() && v8::Handle<v8::String>::Cast(inferredName)->Length())
        result->Set(v8::String::NewSymbol("inferredName"), inferredName);

    // FIXME: pass function displayName from V8 (crbug.com/17356).

    InjectedScriptHost* host = V8InjectedScriptHost::toNative(info.Holder());
    ScriptDebugServer& debugServer = host->scriptDebugServer();
    v8::Handle<v8::Value> scopes = debugServer.functionScopes(function);
    if (!scopes.IsEmpty() && scopes->IsArray())
        result->Set(v8::String::NewSymbol("rawScopes"), scopes);

    v8SetReturnValue(info, result);
}