// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

/*
 * Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
 * Copyright (C) 2009 Holger Hans Peter Freyther
 * Copyright (C) 2010 Collabora Ltd.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "PluginObject.h"

#include <assert.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "PluginTest.h"
#include "base/strings/string_util.h"
#include "content/shell/tools/plugin/test_object.h"

// Helper function which takes in the plugin window object for logging to the
// console object.
static void pluginLogWithWindowObject(NPObject* windowObject,
                                      NPP instance,
                                      const char* message) {
    NPVariant consoleVariant;
    if (!browser->getproperty(instance,
                              windowObject,
                              browser->getstringidentifier("console"),
                              &consoleVariant)) {
      fprintf(stderr,
              "Failed to retrieve console object while logging: %s\n",
              message);
        return;
    }

    NPObject* consoleObject = NPVARIANT_TO_OBJECT(consoleVariant);

    NPVariant messageVariant;
    STRINGZ_TO_NPVARIANT(message, messageVariant);

    NPVariant result;
    if (!browser->invoke(instance,
                         consoleObject,
                         browser->getstringidentifier("log"),
                         &messageVariant,
                         1,
                         &result)) {
      fprintf(
          stderr, "Failed to invoke console.log while logging: %s\n", message);
        browser->releaseobject(consoleObject);
        return;
    }

    browser->releasevariantvalue(&result);
    browser->releaseobject(consoleObject);
}

void pluginLogWithArguments(NPP instance, const char* format, va_list args) {
  const size_t messageBufferSize = 2048;
  char message[messageBufferSize] = "PLUGIN: ";
  int messageLength = sizeof("PLUGIN: ") - 1;
  messageLength += vsnprintf(message + messageLength,
                             messageBufferSize - 1 - messageLength,
                             format,
                             args);
  message[messageLength] = '\0';

  NPObject* windowObject = 0;
  NPError error =
      browser->getvalue(instance, NPNVWindowNPObject, &windowObject);
  if (error != NPERR_NO_ERROR) {
    fprintf(stderr,
            "Failed to retrieve window object while logging: %s\n",
            message);
    return;
  }

  pluginLogWithWindowObject(windowObject, instance, message);
  browser->releaseobject(windowObject);
}

// Helper function to log to the console object.
void pluginLog(NPP instance, const char* format, ...) {
  va_list args;
  va_start(args, format);
  pluginLogWithArguments(instance, format, args);
  va_end(args);
}

static void pluginInvalidate(NPObject*);
static bool pluginHasProperty(NPObject*, NPIdentifier name);
static bool pluginHasMethod(NPObject*, NPIdentifier name);
static bool pluginGetProperty(NPObject*, NPIdentifier name, NPVariant*);
static bool pluginSetProperty(NPObject*, NPIdentifier name, const NPVariant*);
static bool pluginInvoke(NPObject*,
                         NPIdentifier name,
                         const NPVariant* args,
                         uint32_t argCount,
                         NPVariant* result);
static NPObject* pluginAllocate(NPP npp, NPClass*);
static void pluginDeallocate(NPObject*);

NPNetscapeFuncs* browser;
NPPluginFuncs* pluginFunctions;

static NPClass pluginClass_ = {
    NP_CLASS_STRUCT_VERSION, pluginAllocate,    pluginDeallocate,
    pluginInvalidate,        pluginHasMethod,   pluginInvoke,
    0,  // NPClass::invokeDefault,
    pluginHasProperty,       pluginGetProperty, pluginSetProperty,
    0,  // NPClass::removeProperty
    0,  // NPClass::enumerate
    0,  // NPClass::construct
};

NPClass* createPluginClass(void) {
  NPClass* pluginClass = new NPClass;
  *pluginClass = pluginClass_;
  return pluginClass;
}

static bool identifiersInitialized = false;

enum {
  ID_PROPERTY_PROPERTY = 0,
  ID_PROPERTY_EVENT_LOGGING,
  ID_PROPERTY_HAS_STREAM,
  ID_PROPERTY_TEST_OBJECT,
  ID_PROPERTY_LOG_DESTROY,
  ID_PROPERTY_RETURN_ERROR_FROM_NEWSTREAM,
  ID_PROPERTY_RETURN_NEGATIVE_ONE_FROM_WRITE,
  ID_PROPERTY_THROW_EXCEPTION_PROPERTY,
  ID_LAST_SET_WINDOW_ARGUMENTS,
  ID_PROPERTY_TEST_OBJECT_COUNT,
  ID_PROPERTY_DELETE_IN_GET_PROPERTY,
  ID_PROPERTY_DELETE_IN_HAS_PROPERTY_RETURN_TRUE,
  ID_PROPERTY_DELETE_IN_SET_PROPERTY,
  NUM_PROPERTY_IDENTIFIERS
};

static NPIdentifier pluginPropertyIdentifiers[NUM_PROPERTY_IDENTIFIERS];
static const NPUTF8* pluginPropertyIdentifierNames[NUM_PROPERTY_IDENTIFIERS] = {
    "property",
    "eventLoggingEnabled",
    "hasStream",
    "testObject",
    "logDestroy",
    "returnErrorFromNewStream",
    "returnNegativeOneFromWrite",
    "testThrowExceptionProperty",
    "lastSetWindowArguments",
    "testObjectCount",
    "deletePluginInGetProperty",
    "deletePluginInHasPropertyReturnTrue",
    "deletePluginInSetProperty"};

enum {
  ID_TEST_CALLBACK_METHOD = 0,
  ID_TEST_CALLBACK_METHOD_RETURN,
  ID_TEST_GETURL,
  ID_TEST_DOM_ACCESS,
  ID_TEST_GET_URL_NOTIFY,
  ID_TEST_INVOKE_DEFAULT,
  ID_DESTROY_STREAM,
  ID_TEST_ENUMERATE,
  ID_TEST_GETINTIDENTIFIER,
  ID_TEST_GET_PROPERTY,
  ID_TEST_HAS_PROPERTY,
  ID_TEST_HAS_METHOD,
  ID_TEST_EVALUATE,
  ID_TEST_GET_PROPERTY_RETURN_VALUE,
  ID_TEST_IDENTIFIER_TO_STRING,
  ID_TEST_IDENTIFIER_TO_INT,
  ID_TEST_PASS_TEST_OBJECT,
  ID_TEST_POSTURL_FILE,
  ID_TEST_CONSTRUCT,
  ID_TEST_THROW_EXCEPTION_METHOD,
  ID_TEST_FAIL_METHOD,
  ID_TEST_CLONE_OBJECT,
  ID_TEST_SCRIPT_OBJECT_INVOKE,
  ID_TEST_CREATE_TEST_OBJECT,
  ID_DESTROY_NULL_STREAM,
  ID_TEST_RELOAD_PLUGINS_NO_PAGES,
  ID_TEST_RELOAD_PLUGINS_AND_PAGES,
  ID_TEST_GET_BROWSER_PROPERTY,
  ID_TEST_SET_BROWSER_PROPERTY,
  ID_REMEMBER,
  ID_GET_REMEMBERED_OBJECT,
  ID_GET_AND_FORGET_REMEMBERED_OBJECT,
  ID_REF_COUNT,
  ID_SET_STATUS,
  ID_RESIZE_TO,
  ID_NORMALIZE,
  ID_INVALIDATE_RECT,
  ID_OBJECTS_ARE_SAME,
  ID_TEST_DELETE_WITHIN_INVOKE,
  NUM_METHOD_IDENTIFIERS
};

static NPIdentifier pluginMethodIdentifiers[NUM_METHOD_IDENTIFIERS];
static const NPUTF8* pluginMethodIdentifierNames[NUM_METHOD_IDENTIFIERS] = {
    "testCallback",           "testCallbackReturn",
    "getURL",                 "testDOMAccess",
    "getURLNotify",           "testInvokeDefault",
    "destroyStream",          "testEnumerate",
    "testGetIntIdentifier",   "testGetProperty",
    "testHasProperty",        "testHasMethod",
    "testEvaluate",           "testGetPropertyReturnValue",
    "testIdentifierToString", "testIdentifierToInt",
    "testPassTestObject",     "testPostURLFile",
    "testConstruct",          "testThrowException",
    "testFail",               "testCloneObject",
    "testScriptObjectInvoke", "testCreateTestObject",
    "destroyNullStream",      "reloadPluginsNoPages",
    "reloadPluginsAndPages",  "testGetBrowserProperty",
    "testSetBrowserProperty", "remember",
    "getRememberedObject",    "getAndForgetRememberedObject",
    "refCount",               "setStatus",
    "resizeTo",               "normalize",
    "invalidateRect",         "objectsAreSame",
    "testDeleteWithinInvoke"};

static NPUTF8* createCStringFromNPVariant(const NPVariant* variant) {
  size_t length = NPVARIANT_TO_STRING(*variant).UTF8Length;
  NPUTF8* result = (NPUTF8*)malloc(length + 1);
  memcpy(result, NPVARIANT_TO_STRING(*variant).UTF8Characters, length);
  result[length] = '\0';
  return result;
}

static void initializeIdentifiers(void) {
  browser->getstringidentifiers(pluginPropertyIdentifierNames,
                                NUM_PROPERTY_IDENTIFIERS,
                                pluginPropertyIdentifiers);
  browser->getstringidentifiers(pluginMethodIdentifierNames,
                                NUM_METHOD_IDENTIFIERS,
                                pluginMethodIdentifiers);
}

static bool callDeletePlugin(NPObject* obj,
                             NPIdentifier name,
                             NPIdentifier identifierToMatch) {
  if (name != identifierToMatch)
    return false;

  PluginObject* plugin = reinterpret_cast<PluginObject*>(obj);
  NPObject* windowScriptObject;
  browser->getvalue(plugin->npp, NPNVWindowNPObject, &windowScriptObject);

  NPIdentifier callbackIdentifier =
      browser->getstringidentifier("deletePlugin");
  NPVariant browserResult;
  if (browser->invoke(plugin->npp,
                      windowScriptObject,
                      callbackIdentifier,
                      0,
                      0,
                      &browserResult))
    browser->releasevariantvalue(&browserResult);
  return true;
}

static bool pluginHasProperty(NPObject* obj, NPIdentifier name) {
  if (callDeletePlugin(
          obj,
          name,
          browser->getstringidentifier("deletePluginInHasPropertyReturnFalse")))
    return false;

  callDeletePlugin(obj,
                   name,
                   pluginPropertyIdentifiers
                       [ID_PROPERTY_DELETE_IN_HAS_PROPERTY_RETURN_TRUE]);

  for (int i = 0; i < NUM_PROPERTY_IDENTIFIERS; i++)
    if (name == pluginPropertyIdentifiers[i])
      return true;
  return false;
}

static bool pluginHasMethod(NPObject* obj, NPIdentifier name) {
  if (callDeletePlugin(
          obj, name, browser->getstringidentifier("deletePluginInHasMethod")))
    return true;

  for (int i = 0; i < NUM_METHOD_IDENTIFIERS; i++)
    if (name == pluginMethodIdentifiers[i])
      return true;
  return false;
}

static bool pluginGetProperty(NPObject* obj,
                              NPIdentifier name,
                              NPVariant* result) {
  PluginObject* plugin = reinterpret_cast<PluginObject*>(obj);
  if (name == pluginPropertyIdentifiers[ID_PROPERTY_PROPERTY]) {
    static const char* originalString = "property";
    char* buf =
        static_cast<char*>(browser->memalloc(strlen(originalString) + 1));
    strcpy(buf, originalString);
    STRINGZ_TO_NPVARIANT(buf, *result);
    return true;
  }
  if (name == pluginPropertyIdentifiers[ID_PROPERTY_EVENT_LOGGING]) {
    BOOLEAN_TO_NPVARIANT(plugin->eventLogging, *result);
    return true;
  }
  if (name == pluginPropertyIdentifiers[ID_PROPERTY_LOG_DESTROY]) {
    BOOLEAN_TO_NPVARIANT(plugin->logDestroy, *result);
    return true;
  }
  if (name == pluginPropertyIdentifiers[ID_PROPERTY_HAS_STREAM]) {
    BOOLEAN_TO_NPVARIANT(plugin->stream, *result);
    return true;
  }
  if (name == pluginPropertyIdentifiers[ID_PROPERTY_TEST_OBJECT]) {
    NPObject* testObject = plugin->testObject;
    browser->retainobject(testObject);
    OBJECT_TO_NPVARIANT(testObject, *result);
    return true;
  }
  if (name ==
      pluginPropertyIdentifiers[ID_PROPERTY_RETURN_ERROR_FROM_NEWSTREAM]) {
    BOOLEAN_TO_NPVARIANT(plugin->returnErrorFromNewStream, *result);
    return true;
  }
  if (name ==
      pluginPropertyIdentifiers[ID_PROPERTY_RETURN_NEGATIVE_ONE_FROM_WRITE]) {
    BOOLEAN_TO_NPVARIANT(plugin->returnNegativeOneFromWrite, *result);
    return true;
  }
  if (name == pluginPropertyIdentifiers[ID_PROPERTY_THROW_EXCEPTION_PROPERTY]) {
    browser->setexception(obj,
                          "plugin object testThrowExceptionProperty SUCCESS");
    return true;
  }
  if (name == pluginPropertyIdentifiers[ID_LAST_SET_WINDOW_ARGUMENTS]) {
    char* buf = static_cast<char*>(browser->memalloc(256));
    snprintf(
        buf,
        256,
        "x: %d, y: %d, width: %u, height: %u, clipRect: (%u, %u, %u, %u)",
        (int)plugin->lastWindow.x,
        (int)plugin->lastWindow.y,
        (unsigned)plugin->lastWindow.width,
        (unsigned)plugin->lastWindow.height,
        plugin->lastWindow.clipRect.left,
        plugin->lastWindow.clipRect.top,
        plugin->lastWindow.clipRect.right - plugin->lastWindow.clipRect.left,
        plugin->lastWindow.clipRect.bottom - plugin->lastWindow.clipRect.top);

    STRINGZ_TO_NPVARIANT(buf, *result);
    return true;
  }
  if (name == pluginPropertyIdentifiers[ID_PROPERTY_TEST_OBJECT_COUNT]) {
    INT32_TO_NPVARIANT(content::GetTestObjectCount(), *result);
    return true;
  }

  if (name == pluginPropertyIdentifiers[ID_PROPERTY_DELETE_IN_GET_PROPERTY]) {
    browser->retainobject(obj);
    callDeletePlugin(
        obj,
        name,
        pluginPropertyIdentifiers[ID_PROPERTY_DELETE_IN_GET_PROPERTY]);
    NPObject* testObject = plugin->testObject;
    browser->retainobject(testObject);
    OBJECT_TO_NPVARIANT(testObject, *result);
    browser->releaseobject(obj);
    return true;
  }

  return false;
}

static bool pluginSetProperty(NPObject* obj,
                              NPIdentifier name,
                              const NPVariant* variant) {
  PluginObject* plugin = reinterpret_cast<PluginObject*>(obj);
  if (callDeletePlugin(
          obj,
          name,
          pluginPropertyIdentifiers[ID_PROPERTY_DELETE_IN_SET_PROPERTY]))
    return true;

  if (name == pluginPropertyIdentifiers[ID_PROPERTY_EVENT_LOGGING]) {
    plugin->eventLogging = NPVARIANT_TO_BOOLEAN(*variant);
    return true;
  }
  if (name == pluginPropertyIdentifiers[ID_PROPERTY_LOG_DESTROY]) {
    plugin->logDestroy = NPVARIANT_TO_BOOLEAN(*variant);
    return true;
  }
  if (name ==
      pluginPropertyIdentifiers[ID_PROPERTY_RETURN_ERROR_FROM_NEWSTREAM]) {
    plugin->returnErrorFromNewStream = NPVARIANT_TO_BOOLEAN(*variant);
    return true;
  }
  if (name ==
      pluginPropertyIdentifiers[ID_PROPERTY_RETURN_NEGATIVE_ONE_FROM_WRITE]) {
    plugin->returnNegativeOneFromWrite = NPVARIANT_TO_BOOLEAN(*variant);
    return true;
  }
  if (name == pluginPropertyIdentifiers[ID_PROPERTY_THROW_EXCEPTION_PROPERTY]) {
    browser->setexception(obj,
                          "plugin object testThrowExceptionProperty SUCCESS");
    return true;
  }

  return false;
}

static bool testDOMAccess(PluginObject* obj,
                          const NPVariant*,
                          uint32_t,
                          NPVariant* result) {
  // Get plugin's DOM element
  NPObject* elementObject;
  if (browser->getvalue(obj->npp, NPNVPluginElementNPObject, &elementObject) ==
      NPERR_NO_ERROR) {
    // Get style
    NPVariant styleVariant;
    NPIdentifier styleIdentifier = browser->getstringidentifier("style");
    if (browser->getproperty(
            obj->npp, elementObject, styleIdentifier, &styleVariant) &&
        NPVARIANT_IS_OBJECT(styleVariant)) {
      // Set style.border
      NPIdentifier borderIdentifier = browser->getstringidentifier("border");
      NPVariant borderVariant;
      STRINGZ_TO_NPVARIANT("3px solid red", borderVariant);
      browser->setproperty(obj->npp,
                           NPVARIANT_TO_OBJECT(styleVariant),
                           borderIdentifier,
                           &borderVariant);
      browser->releasevariantvalue(&styleVariant);
    }

    browser->releaseobject(elementObject);
  }
  VOID_TO_NPVARIANT(*result);
  return true;
}

static NPIdentifier stringVariantToIdentifier(NPVariant variant) {
  assert(NPVARIANT_IS_STRING(variant));
  NPUTF8* utf8String = createCStringFromNPVariant(&variant);
  NPIdentifier identifier = browser->getstringidentifier(utf8String);
  free(utf8String);
  return identifier;
}

static NPIdentifier int32VariantToIdentifier(NPVariant variant) {
  assert(NPVARIANT_IS_INT32(variant));
  int32_t integer = NPVARIANT_TO_INT32(variant);
  return browser->getintidentifier(integer);
}

static NPIdentifier doubleVariantToIdentifier(NPVariant variant) {
  assert(NPVARIANT_IS_DOUBLE(variant));
  double value = NPVARIANT_TO_DOUBLE(variant);
  // Sadly there is no "getdoubleidentifier"
  int32_t integer = static_cast<int32_t>(value);
  return browser->getintidentifier(integer);
}

static NPIdentifier variantToIdentifier(NPVariant variant) {
  if (NPVARIANT_IS_STRING(variant))
    return stringVariantToIdentifier(variant);
  if (NPVARIANT_IS_INT32(variant))
    return int32VariantToIdentifier(variant);
  if (NPVARIANT_IS_DOUBLE(variant))
    return doubleVariantToIdentifier(variant);
  return 0;
}

static bool testIdentifierToString(PluginObject*,
                                   const NPVariant* args,
                                   uint32_t argCount,
                                   NPVariant* result) {
  if (argCount != 1)
    return true;
  NPIdentifier identifier = variantToIdentifier(args[0]);
  if (!identifier)
    return true;
  NPUTF8* utf8String = browser->utf8fromidentifier(identifier);
  if (!utf8String)
    return true;
  STRINGZ_TO_NPVARIANT(utf8String, *result);
  return true;
}

static bool testIdentifierToInt(PluginObject*,
                                const NPVariant* args,
                                uint32_t argCount,
                                NPVariant* result) {
  if (argCount != 1)
    return false;
  NPIdentifier identifier = variantToIdentifier(args[0]);
  if (!identifier)
    return false;
  int32_t integer = browser->intfromidentifier(identifier);
  INT32_TO_NPVARIANT(integer, *result);
  return true;
}

static bool testPassTestObject(PluginObject* obj,
                               const NPVariant* args,
                               uint32_t argCount,
                               NPVariant* result) {
  if (argCount != 2 || !NPVARIANT_IS_STRING(args[0]))
    return false;

  NPObject* windowScriptObject;
  browser->getvalue(obj->npp, NPNVWindowNPObject, &windowScriptObject);

  NPUTF8* callbackString = createCStringFromNPVariant(&args[0]);
  NPIdentifier callbackIdentifier =
      browser->getstringidentifier(callbackString);
  free(callbackString);

  NPVariant browserResult;
  browser->invoke(obj->npp,
                  windowScriptObject,
                  callbackIdentifier,
                  &args[1],
                  1,
                  &browserResult);
  browser->releasevariantvalue(&browserResult);

  VOID_TO_NPVARIANT(*result);
  return true;
}

static bool testCallback(PluginObject* obj,
                         const NPVariant* args,
                         uint32_t argCount,
                         NPVariant* result) {
  if (!argCount || !NPVARIANT_IS_STRING(args[0]))
    return false;

  NPObject* windowScriptObject;
  browser->getvalue(obj->npp, NPNVWindowNPObject, &windowScriptObject);

  NPUTF8* callbackString = createCStringFromNPVariant(&args[0]);
  NPIdentifier callbackIdentifier =
      browser->getstringidentifier(callbackString);
  free(callbackString);

  NPVariant browserResult;
  if (browser->invoke(obj->npp,
                      windowScriptObject,
                      callbackIdentifier,
                      0,
                      0,
                      &browserResult))
    browser->releasevariantvalue(&browserResult);

  browser->releaseobject(windowScriptObject);

  VOID_TO_NPVARIANT(*result);
  return true;
}

static bool testCallbackReturn(PluginObject* obj,
                               const NPVariant* args,
                               uint32_t argCount,
                               NPVariant* result) {
  if (argCount != 1 || !NPVARIANT_IS_STRING(args[0]))
    return false;

  NPObject* windowScriptObject;
  browser->getvalue(obj->npp, NPNVWindowNPObject, &windowScriptObject);

  NPUTF8* callbackString = createCStringFromNPVariant(&args[0]);
  NPIdentifier callbackIdentifier =
      browser->getstringidentifier(callbackString);
  free(callbackString);

  NPVariant callbackArgs[1];
  OBJECT_TO_NPVARIANT(windowScriptObject, callbackArgs[0]);

  NPVariant browserResult;
  browser->invoke(obj->npp,
                  windowScriptObject,
                  callbackIdentifier,
                  callbackArgs,
                  1,
                  &browserResult);

  if (NPVARIANT_IS_OBJECT(browserResult))
    OBJECT_TO_NPVARIANT(NPVARIANT_TO_OBJECT(browserResult), *result);
  else {
    browser->releasevariantvalue(&browserResult);
    VOID_TO_NPVARIANT(*result);
  }

  return true;
}

static bool getURL(PluginObject* obj,
                   const NPVariant* args,
                   uint32_t argCount,
                   NPVariant* result) {
  if (argCount == 2 && NPVARIANT_IS_STRING(args[0]) &&
      NPVARIANT_IS_STRING(args[1])) {
    NPUTF8* urlString = createCStringFromNPVariant(&args[0]);
    NPUTF8* targetString = createCStringFromNPVariant(&args[1]);
    NPError npErr = browser->geturl(obj->npp, urlString, targetString);
    free(urlString);
    free(targetString);

    INT32_TO_NPVARIANT(npErr, *result);
    return true;
  }
  if (argCount == 1 && NPVARIANT_IS_STRING(args[0])) {
    NPUTF8* urlString = createCStringFromNPVariant(&args[0]);
    NPError npErr = browser->geturl(obj->npp, urlString, 0);
    free(urlString);

    INT32_TO_NPVARIANT(npErr, *result);
    return true;
  }
  return false;
}

static bool getURLNotify(PluginObject* obj,
                         const NPVariant* args,
                         uint32_t argCount,
                         NPVariant* result) {
  if (argCount != 3 || !NPVARIANT_IS_STRING(args[0]) ||
      (!NPVARIANT_IS_STRING(args[1]) && !NPVARIANT_IS_NULL(args[1])) ||
      !NPVARIANT_IS_STRING(args[2]))
    return false;

  NPUTF8* urlString = createCStringFromNPVariant(&args[0]);
  NPUTF8* targetString =
      (NPVARIANT_IS_STRING(args[1]) ? createCStringFromNPVariant(&args[1]) : 0);
  NPUTF8* callbackString = createCStringFromNPVariant(&args[2]);

  NPIdentifier callbackIdentifier =
      browser->getstringidentifier(callbackString);
  browser->geturlnotify(obj->npp, urlString, targetString, callbackIdentifier);

  free(urlString);
  free(targetString);
  free(callbackString);

  VOID_TO_NPVARIANT(*result);
  return true;
}

static bool testInvokeDefault(PluginObject* obj,
                              const NPVariant* args,
                              uint32_t argCount,
                              NPVariant* result) {
  if (!NPVARIANT_IS_OBJECT(args[0]))
    return false;

  NPObject* callback = NPVARIANT_TO_OBJECT(args[0]);

  NPVariant invokeArgs[1];
  NPVariant browserResult;

  STRINGZ_TO_NPVARIANT("test", invokeArgs[0]);
  bool retval =
      browser->invokeDefault(obj->npp, callback, invokeArgs, 1, &browserResult);

  if (retval)
    browser->releasevariantvalue(&browserResult);

  BOOLEAN_TO_NPVARIANT(retval, *result);
  return true;
}

static bool destroyStream(PluginObject* obj,
                          const NPVariant* args,
                          uint32_t argCount,
                          NPVariant* result) {
  NPError npError =
      browser->destroystream(obj->npp, obj->stream, NPRES_USER_BREAK);
  INT32_TO_NPVARIANT(npError, *result);
  return true;
}

static bool destroyNullStream(PluginObject* obj,
                              const NPVariant* args,
                              uint32_t argCount,
                              NPVariant* result) {
  NPError npError = browser->destroystream(obj->npp, 0, NPRES_USER_BREAK);
  INT32_TO_NPVARIANT(npError, *result);
  return true;
}

static bool testEnumerate(PluginObject* obj,
                          const NPVariant* args,
                          uint32_t argCount,
                          NPVariant* result) {
  if (argCount != 2 || !NPVARIANT_IS_OBJECT(args[0]) ||
      !NPVARIANT_IS_OBJECT(args[1]))
    return false;

  uint32_t count;
  NPIdentifier* identifiers;
  if (browser->enumerate(
          obj->npp, NPVARIANT_TO_OBJECT(args[0]), &identifiers, &count)) {
    NPObject* outArray = NPVARIANT_TO_OBJECT(args[1]);
    NPIdentifier pushIdentifier = browser->getstringidentifier("push");

    for (uint32_t i = 0; i < count; i++) {
      NPUTF8* string = browser->utf8fromidentifier(identifiers[i]);

      if (!string)
        continue;

      NPVariant args[1];
      STRINGZ_TO_NPVARIANT(string, args[0]);
      NPVariant browserResult;
      if (browser->invoke(
              obj->npp, outArray, pushIdentifier, args, 1, &browserResult))
        browser->releasevariantvalue(&browserResult);
      browser->memfree(string);
    }

    browser->memfree(identifiers);
  }

  VOID_TO_NPVARIANT(*result);
  return true;
}

static bool testGetIntIdentifier(PluginObject*,
                                 const NPVariant* args,
                                 uint32_t argCount,
                                 NPVariant* result) {
  if (argCount != 1 || !NPVARIANT_IS_DOUBLE(args[0]))
    return false;

  NPIdentifier identifier =
      browser->getintidentifier((int)NPVARIANT_TO_DOUBLE(args[0]));
  INT32_TO_NPVARIANT((int32_t)(long long)identifier, *result);
  return true;
}

static bool testGetProperty(PluginObject* obj,
                            const NPVariant* args,
                            uint32_t argCount,
                            NPVariant* result) {
  if (!argCount)
    return false;

  NPObject* object;
  browser->getvalue(obj->npp, NPNVWindowNPObject, &object);

  for (uint32_t i = 0; i < argCount; i++) {
    assert(NPVARIANT_IS_STRING(args[i]));
    NPUTF8* propertyString = createCStringFromNPVariant(&args[i]);
    NPIdentifier propertyIdentifier =
        browser->getstringidentifier(propertyString);
    free(propertyString);

    NPVariant variant;
    bool retval =
        browser->getproperty(obj->npp, object, propertyIdentifier, &variant);
    browser->releaseobject(object);

    if (!retval)
      break;

    if (i + 1 < argCount) {
      assert(NPVARIANT_IS_OBJECT(variant));
      object = NPVARIANT_TO_OBJECT(variant);
    } else {
      *result = variant;
      return true;
    }
  }

  VOID_TO_NPVARIANT(*result);
  return false;
}

static bool testHasProperty(PluginObject* obj,
                            const NPVariant* args,
                            uint32_t argCount,
                            NPVariant* result) {
  if (argCount != 2 || !NPVARIANT_IS_OBJECT(args[0]) ||
      !NPVARIANT_IS_STRING(args[1]))
    return false;

  NPUTF8* propertyString = createCStringFromNPVariant(&args[1]);
  NPIdentifier propertyIdentifier =
      browser->getstringidentifier(propertyString);
  free(propertyString);

  bool retval = browser->hasproperty(
      obj->npp, NPVARIANT_TO_OBJECT(args[0]), propertyIdentifier);

  BOOLEAN_TO_NPVARIANT(retval, *result);
  return true;
}

static bool testHasMethod(PluginObject* obj,
                          const NPVariant* args,
                          uint32_t argCount,
                          NPVariant* result) {
  if (argCount != 2 || !NPVARIANT_IS_OBJECT(args[0]) ||
      !NPVARIANT_IS_STRING(args[1]))
    return false;

  NPUTF8* propertyString = createCStringFromNPVariant(&args[1]);
  NPIdentifier propertyIdentifier =
      browser->getstringidentifier(propertyString);
  free(propertyString);

  bool retval = browser->hasmethod(
      obj->npp, NPVARIANT_TO_OBJECT(args[0]), propertyIdentifier);

  BOOLEAN_TO_NPVARIANT(retval, *result);
  return true;
}

static bool testEvaluate(PluginObject* obj,
                         const NPVariant* args,
                         uint32_t argCount,
                         NPVariant* result) {
  if (argCount != 1 || !NPVARIANT_IS_STRING(args[0]))
    return false;
  NPObject* windowScriptObject;
  browser->getvalue(obj->npp, NPNVWindowNPObject, &windowScriptObject);

  NPString s = NPVARIANT_TO_STRING(args[0]);

  bool retval = browser->evaluate(obj->npp, windowScriptObject, &s, result);
  browser->releaseobject(windowScriptObject);
  return retval;
}

static bool testGetPropertyReturnValue(PluginObject* obj,
                                       const NPVariant* args,
                                       uint32_t argCount,
                                       NPVariant* result) {
  if (argCount != 2 || !NPVARIANT_IS_OBJECT(args[0]) ||
      !NPVARIANT_IS_STRING(args[1]))
    return false;

  NPUTF8* propertyString = createCStringFromNPVariant(&args[1]);
  NPIdentifier propertyIdentifier =
      browser->getstringidentifier(propertyString);
  free(propertyString);

  NPVariant variant;
  bool retval = browser->getproperty(
      obj->npp, NPVARIANT_TO_OBJECT(args[0]), propertyIdentifier, &variant);
  if (retval)
    browser->releasevariantvalue(&variant);

  BOOLEAN_TO_NPVARIANT(retval, *result);
  return true;
}

static char* toCString(const NPString& string) {
  char* result = static_cast<char*>(malloc(string.UTF8Length + 1));
  memcpy(result, string.UTF8Characters, string.UTF8Length);
  result[string.UTF8Length] = '\0';

  return result;
}

static bool testPostURLFile(PluginObject* obj,
                            const NPVariant* args,
                            uint32_t argCount,
                            NPVariant* result) {
  if (argCount != 4 || !NPVARIANT_IS_STRING(args[0]) ||
      !NPVARIANT_IS_STRING(args[1]) || !NPVARIANT_IS_STRING(args[2]) ||
      !NPVARIANT_IS_STRING(args[3]))
    return false;

  NPString urlString = NPVARIANT_TO_STRING(args[0]);
  char* url = toCString(urlString);

  NPString targetString = NPVARIANT_TO_STRING(args[1]);
  char* target = toCString(targetString);

  NPString pathString = NPVARIANT_TO_STRING(args[2]);
  char* path = toCString(pathString);

  NPString contentsString = NPVARIANT_TO_STRING(args[3]);

  FILE* tempFile = fopen(path, "w");
  if (!tempFile)
    return false;

  size_t written = fwrite(
      contentsString.UTF8Characters, contentsString.UTF8Length, 1, tempFile);
  fclose(tempFile);
  if (!written)
    return false;

  NPError error = browser->posturl(
      obj->npp, url, target, pathString.UTF8Length, path, true);

  free(path);
  free(target);
  free(url);

  BOOLEAN_TO_NPVARIANT(error == NPERR_NO_ERROR, *result);
  return true;
}

static bool testConstruct(PluginObject* obj,
                          const NPVariant* args,
                          uint32_t argCount,
                          NPVariant* result) {
  if (!argCount || !NPVARIANT_IS_OBJECT(args[0]))
    return false;

  return browser->construct(
      obj->npp, NPVARIANT_TO_OBJECT(args[0]), args + 1, argCount - 1, result);
}

// Invoke a script callback to get a script NPObject. Then call a method on the
// script NPObject passing it a freshly created NPObject.
static bool testScriptObjectInvoke(PluginObject* obj,
                                   const NPVariant* args,
                                   uint32_t argCount,
                                   NPVariant* result) {
  if (argCount != 2 || !NPVARIANT_IS_STRING(args[0]) ||
      !NPVARIANT_IS_STRING(args[1]))
    return false;
  NPObject* windowScriptObject;
  browser->getvalue(obj->npp, NPNVWindowNPObject, &windowScriptObject);

  // Arg1 is the name of the callback
  NPUTF8* callbackString = createCStringFromNPVariant(&args[0]);
  NPIdentifier callbackIdentifier =
      browser->getstringidentifier(callbackString);
  free(callbackString);

  // Invoke a callback that returns a script object
  NPVariant object_result;
  browser->invoke(obj->npp,
                  windowScriptObject,
                  callbackIdentifier,
                  &args[1],
                  1,
                  &object_result);

  // Script object returned
  if (!NPVARIANT_IS_OBJECT(object_result)) {
    browser->releasevariantvalue(&object_result);
    return false;
  }
  NPObject* script_object = NPVARIANT_TO_OBJECT(object_result);

  // Arg2 is the name of the method to be called on the script object
  NPUTF8* object_method_string = createCStringFromNPVariant(&args[1]);
  NPIdentifier object_method =
      browser->getstringidentifier(object_method_string);
  free(object_method_string);

  // Create a fresh NPObject to be passed as an argument
  NPObject* object_arg = browser->createobject(obj->npp, obj->header._class);

  NPVariant invoke_args[1];
  OBJECT_TO_NPVARIANT(object_arg, invoke_args[0]);

  // Invoke the script method
  NPVariant object_method_result;
  browser->invoke(obj->npp,
                  script_object,
                  object_method,
                  invoke_args,
                  1,
                  &object_method_result);

  browser->releasevariantvalue(&object_result);
  VOID_TO_NPVARIANT(*result);
  if (NPVARIANT_IS_OBJECT(object_method_result)) {
    // Now return the callbacks return value back to our caller.
    // BUG 897451: This should be the same as the
    // windowScriptObject, but its not (in Chrome) - or at least, it
    // has a different refcount. This means Chrome will delete the
    // object before returning it and the calling JS gets a garbage
    // value.  Firefox handles it fine.
    OBJECT_TO_NPVARIANT(NPVARIANT_TO_OBJECT(object_method_result), *result);
  } else {
    browser->releasevariantvalue(&object_method_result);
    VOID_TO_NPVARIANT(*result);
  }

  browser->releaseobject(object_arg);

  return true;
}

// Helper function to notify the layout test controller that the test completed.
void notifyTestCompletion(NPP npp, NPObject* object) {
  NPVariant result;
  NPString script;
  script.UTF8Characters = "javascript:window.testRunner.notifyDone();";
  script.UTF8Length = strlen("javascript:window.testRunner.notifyDone();");
  browser->evaluate(npp, object, &script, &result);
  browser->releasevariantvalue(&result);
}

bool testDocumentOpen(NPP npp) {
  NPIdentifier documentId = browser->getstringidentifier("document");
  NPIdentifier openId = browser->getstringidentifier("open");

  NPObject* windowObject = 0;
  browser->getvalue(npp, NPNVWindowNPObject, &windowObject);
  if (!windowObject)
    return false;

  NPVariant docVariant;
  browser->getproperty(npp, windowObject, documentId, &docVariant);
  if (docVariant.type != NPVariantType_Object) {
    browser->releaseobject(windowObject);
    return false;
  }

  NPObject* documentObject = NPVARIANT_TO_OBJECT(docVariant);

  NPVariant openArgs[2];
  STRINGZ_TO_NPVARIANT("text/html", openArgs[0]);
  STRINGZ_TO_NPVARIANT("_blank", openArgs[1]);

  NPVariant result;
  if (!browser->invoke(npp, documentObject, openId, openArgs, 2, &result)) {
    browser->releaseobject(windowObject);
    browser->releaseobject(documentObject);
    return false;
  }

  browser->releaseobject(documentObject);

  if (result.type != NPVariantType_Object) {
    browser->releaseobject(windowObject);
    browser->releasevariantvalue(&result);
    return false;
  }

  pluginLogWithWindowObject(windowObject, npp, "PLUGIN: DOCUMENT OPEN SUCCESS");
  notifyTestCompletion(npp, result.value.objectValue);
  browser->releaseobject(result.value.objectValue);
  browser->releaseobject(windowObject);
  return true;
}

bool testWindowOpen(NPP npp) {
  NPIdentifier openId = browser->getstringidentifier("open");

  NPObject* windowObject = 0;
  browser->getvalue(npp, NPNVWindowNPObject, &windowObject);
  if (!windowObject)
    return false;

  NPVariant openArgs[2];
  STRINGZ_TO_NPVARIANT("about:blank", openArgs[0]);
  STRINGZ_TO_NPVARIANT("_blank", openArgs[1]);

  NPVariant result;
  if (!browser->invoke(npp, windowObject, openId, openArgs, 2, &result)) {
    browser->releaseobject(windowObject);
    return false;
  }

  if (result.type != NPVariantType_Object) {
    browser->releaseobject(windowObject);
    browser->releasevariantvalue(&result);
    return false;
  }

  pluginLogWithWindowObject(windowObject, npp, "PLUGIN: WINDOW OPEN SUCCESS");
  notifyTestCompletion(npp, result.value.objectValue);
  browser->releaseobject(result.value.objectValue);
  browser->releaseobject(windowObject);
  return true;
}

static bool testSetStatus(PluginObject* obj,
                          const NPVariant* args,
                          uint32_t argCount,
                          NPVariant* result) {
  char* message = 0;
  if (argCount && NPVARIANT_IS_STRING(args[0])) {
    NPString statusString = NPVARIANT_TO_STRING(args[0]);
    message = toCString(statusString);
  }

  browser->status(obj->npp, message);

  free(message);
  return true;
}

static bool testResizeTo(PluginObject* obj,
                         const NPVariant* args,
                         uint32_t argCount,
                         NPVariant* result) {
  VOID_TO_NPVARIANT(*result);

  NPObject* windowObject;
  if (NPERR_NO_ERROR !=
      browser->getvalue(obj->npp, NPNVWindowNPObject, &windowObject))
    return false;

  NPVariant callResult;
  if (browser->invoke(obj->npp,
                      windowObject,
                      browser->getstringidentifier("resizePlugin"),
                      args,
                      argCount,
                      &callResult))
    browser->releasevariantvalue(&callResult);

  // Force layout.
  if (browser->getproperty(obj->npp,
                           windowObject,
                           browser->getstringidentifier("pageYOffset"),
                           &callResult))
    browser->releasevariantvalue(&callResult);

  return true;
}

static bool normalizeOverride(PluginObject* obj,
                              const NPVariant* args,
                              uint32_t argCount,
                              NPVariant* result) {
  VOID_TO_NPVARIANT(*result);

  NPObject* windowObject;
  if (NPERR_NO_ERROR !=
      browser->getvalue(obj->npp, NPNVWindowNPObject, &windowObject))
    return false;

  NPVariant callResult;
  if (browser->invoke(obj->npp,
                      windowObject,
                      browser->getstringidentifier("pluginCallback"),
                      args,
                      argCount,
                      &callResult))
    browser->releasevariantvalue(&callResult);

  return true;
}

static bool invalidateRect(PluginObject* obj,
                           const NPVariant* args,
                           uint32_t argCount,
                           NPVariant* result) {
  if (argCount != 4)
    return false;

  NPRect rect;
  rect.left = static_cast<uint16_t>(NPVARIANT_TO_DOUBLE(args[0]));
  rect.top = static_cast<uint16_t>(NPVARIANT_TO_DOUBLE(args[1]));
  rect.right = static_cast<uint16_t>(NPVARIANT_TO_DOUBLE(args[2]));
  rect.bottom = static_cast<uint16_t>(NPVARIANT_TO_DOUBLE(args[3]));

  browser->invalidaterect(obj->npp, &rect);
  return true;
}

static bool objectsAreSame(PluginObject* obj,
                           const NPVariant* args,
                           uint32_t argCount,
                           NPVariant* result) {
  if (argCount != 2 || !NPVARIANT_IS_OBJECT(args[0]) ||
      !NPVARIANT_IS_OBJECT(args[1]))
    return false;

  BOOLEAN_TO_NPVARIANT(
      NPVARIANT_TO_OBJECT(args[0]) == NPVARIANT_TO_OBJECT(args[1]), *result);
  return true;
}

static bool pluginInvoke(NPObject* header,
                         NPIdentifier name,
                         const NPVariant* args,
                         uint32_t argCount,
                         NPVariant* result) {
  PluginObject* plugin = reinterpret_cast<PluginObject*>(header);
  if (name == pluginMethodIdentifiers[ID_TEST_CALLBACK_METHOD])
    return testCallback(plugin, args, argCount, result);
  if (name == pluginMethodIdentifiers[ID_TEST_CALLBACK_METHOD_RETURN])
    return testCallbackReturn(plugin, args, argCount, result);
  if (name == pluginMethodIdentifiers[ID_TEST_GETURL])
    return getURL(plugin, args, argCount, result);
  if (name == pluginMethodIdentifiers[ID_TEST_DOM_ACCESS])
    return testDOMAccess(plugin, args, argCount, result);
  if (name == pluginMethodIdentifiers[ID_TEST_GET_URL_NOTIFY])
    return getURLNotify(plugin, args, argCount, result);
  if (name == pluginMethodIdentifiers[ID_TEST_INVOKE_DEFAULT])
    return testInvokeDefault(plugin, args, argCount, result);
  if (name == pluginMethodIdentifiers[ID_TEST_ENUMERATE])
    return testEnumerate(plugin, args, argCount, result);
  if (name == pluginMethodIdentifiers[ID_DESTROY_STREAM])
    return destroyStream(plugin, args, argCount, result);
  if (name == pluginMethodIdentifiers[ID_TEST_GETINTIDENTIFIER])
    return testGetIntIdentifier(plugin, args, argCount, result);
  if (name == pluginMethodIdentifiers[ID_TEST_EVALUATE])
    return testEvaluate(plugin, args, argCount, result);
  if (name == pluginMethodIdentifiers[ID_TEST_GET_PROPERTY])
    return testGetProperty(plugin, args, argCount, result);
  if (name == pluginMethodIdentifiers[ID_TEST_GET_PROPERTY_RETURN_VALUE])
    return testGetPropertyReturnValue(plugin, args, argCount, result);
  if (name == pluginMethodIdentifiers[ID_TEST_HAS_PROPERTY])
    return testHasProperty(plugin, args, argCount, result);
  if (name == pluginMethodIdentifiers[ID_TEST_HAS_METHOD])
    return testHasMethod(plugin, args, argCount, result);
  if (name == pluginMethodIdentifiers[ID_TEST_IDENTIFIER_TO_STRING])
    return testIdentifierToString(plugin, args, argCount, result);
  if (name == pluginMethodIdentifiers[ID_TEST_IDENTIFIER_TO_INT])
    return testIdentifierToInt(plugin, args, argCount, result);
  if (name == pluginMethodIdentifiers[ID_TEST_PASS_TEST_OBJECT])
    return testPassTestObject(plugin, args, argCount, result);
  if (name == pluginMethodIdentifiers[ID_TEST_POSTURL_FILE])
    return testPostURLFile(plugin, args, argCount, result);
  if (name == pluginMethodIdentifiers[ID_TEST_CONSTRUCT])
    return testConstruct(plugin, args, argCount, result);
  if (name == pluginMethodIdentifiers[ID_TEST_SCRIPT_OBJECT_INVOKE])
    return testScriptObjectInvoke(plugin, args, argCount, result);
  if (name == pluginMethodIdentifiers[ID_TEST_THROW_EXCEPTION_METHOD]) {
    browser->setexception(header, "plugin object testThrowException SUCCESS");
    return true;
  }
  if (name == pluginMethodIdentifiers[ID_TEST_FAIL_METHOD]) {
    NPObject* windowScriptObject;
    browser->getvalue(plugin->npp, NPNVWindowNPObject, &windowScriptObject);
    browser->invoke(
        plugin->npp, windowScriptObject, name, args, argCount, result);
    return false;
  }
  if (name == pluginMethodIdentifiers[ID_TEST_CLONE_OBJECT]) {
    NPObject* new_object =
        browser->createobject(plugin->npp, plugin->header._class);
    assert(new_object->referenceCount == 1);
    OBJECT_TO_NPVARIANT(new_object, *result);
    return true;
  }
  if (name == pluginMethodIdentifiers[ID_TEST_CREATE_TEST_OBJECT]) {
    NPObject* testObject =
        browser->createobject(plugin->npp, content::GetTestClass());
    assert(testObject->referenceCount == 1);
    OBJECT_TO_NPVARIANT(testObject, *result);
    return true;
  }
  if (name == pluginMethodIdentifiers[ID_DESTROY_NULL_STREAM])
    return destroyNullStream(plugin, args, argCount, result);
  if (name == pluginMethodIdentifiers[ID_TEST_RELOAD_PLUGINS_NO_PAGES]) {
    browser->reloadplugins(false);
    return true;
  }
  if (name == pluginMethodIdentifiers[ID_TEST_RELOAD_PLUGINS_AND_PAGES]) {
    browser->reloadplugins(true);
    return true;
  }
  if (name == pluginMethodIdentifiers[ID_TEST_GET_BROWSER_PROPERTY]) {
    browser->getproperty(plugin->npp,
                         NPVARIANT_TO_OBJECT(args[0]),
                         stringVariantToIdentifier(args[1]),
                         result);
    return true;
  }
  if (name == pluginMethodIdentifiers[ID_TEST_SET_BROWSER_PROPERTY]) {
    browser->setproperty(plugin->npp,
                         NPVARIANT_TO_OBJECT(args[0]),
                         stringVariantToIdentifier(args[1]),
                         &args[2]);
    return true;
  }
  if (name == pluginMethodIdentifiers[ID_REMEMBER]) {
    if (plugin->rememberedObject)
      browser->releaseobject(plugin->rememberedObject);
    plugin->rememberedObject = NPVARIANT_TO_OBJECT(args[0]);
    browser->retainobject(plugin->rememberedObject);
    VOID_TO_NPVARIANT(*result);
    return true;
  }
  if (name == pluginMethodIdentifiers[ID_GET_REMEMBERED_OBJECT]) {
    assert(plugin->rememberedObject);
    browser->retainobject(plugin->rememberedObject);
    OBJECT_TO_NPVARIANT(plugin->rememberedObject, *result);
    return true;
  }
  if (name == pluginMethodIdentifiers[ID_GET_AND_FORGET_REMEMBERED_OBJECT]) {
    assert(plugin->rememberedObject);
    OBJECT_TO_NPVARIANT(plugin->rememberedObject, *result);
    plugin->rememberedObject = 0;
    return true;
  }
  if (name == pluginMethodIdentifiers[ID_REF_COUNT]) {
    uint32_t refCount = NPVARIANT_TO_OBJECT(args[0])->referenceCount;
    INT32_TO_NPVARIANT(refCount, *result);
    return true;
  }
  if (name == pluginMethodIdentifiers[ID_SET_STATUS])
    return testSetStatus(plugin, args, argCount, result);
  if (name == pluginMethodIdentifiers[ID_RESIZE_TO])
    return testResizeTo(plugin, args, argCount, result);
  if (name == pluginMethodIdentifiers[ID_NORMALIZE])
    return normalizeOverride(plugin, args, argCount, result);
  if (name == pluginMethodIdentifiers[ID_INVALIDATE_RECT])
    return invalidateRect(plugin, args, argCount, result);
  if (name == pluginMethodIdentifiers[ID_OBJECTS_ARE_SAME])
    return objectsAreSame(plugin, args, argCount, result);
  if (name == pluginMethodIdentifiers[ID_TEST_DELETE_WITHIN_INVOKE]) {
    NPObject* newObject =
        browser->createobject(plugin->npp, plugin->header._class);
    OBJECT_TO_NPVARIANT(newObject, *result);
    callDeletePlugin(
        header, name, pluginMethodIdentifiers[ID_TEST_DELETE_WITHIN_INVOKE]);
    return true;
  }
  return false;
}

static void pluginInvalidate(NPObject* header) {
  PluginObject* plugin = reinterpret_cast<PluginObject*>(header);
  plugin->testObject = 0;
  plugin->rememberedObject = 0;
}

static NPObject* pluginAllocate(NPP npp, NPClass* theClass) {
  PluginObject* newInstance = (PluginObject*)malloc(sizeof(PluginObject));

  if (!identifiersInitialized) {
    identifiersInitialized = true;
    initializeIdentifiers();
  }

  newInstance->pluginTest = 0;
  newInstance->npp = npp;
  newInstance->testObject = browser->createobject(npp, content::GetTestClass());
  newInstance->rememberedObject = 0;
  newInstance->eventLogging = false;
  newInstance->onStreamLoad = 0;
  newInstance->onStreamDestroy = 0;
  newInstance->onDestroy = 0;
  newInstance->onURLNotify = 0;
  newInstance->onSetWindow = 0;
  newInstance->onPaintEvent = 0;
  newInstance->logDestroy = false;
  newInstance->logSetWindow = false;
  newInstance->returnErrorFromNewStream = false;
  newInstance->returnNegativeOneFromWrite = false;
  newInstance->stream = 0;

  newInstance->firstUrl = 0;
  newInstance->firstHeaders = 0;
  newInstance->lastUrl = 0;
  newInstance->lastHeaders = 0;

  newInstance->testGetURLOnDestroy = false;
  newInstance->testWindowOpen = false;
  newInstance->testKeyboardFocusForPlugins = false;

  newInstance->mouseDownForEvaluateScript = false;
  newInstance->evaluateScriptOnMouseDownOrKeyDown = 0;

  return (NPObject*)newInstance;
}

static void pluginDeallocate(NPObject* header) {
  PluginObject* plugin = reinterpret_cast<PluginObject*>(header);
  delete plugin->pluginTest;
  if (plugin->testObject)
    browser->releaseobject(plugin->testObject);
  if (plugin->rememberedObject)
    browser->releaseobject(plugin->rememberedObject);

  free(plugin->firstUrl);
  free(plugin->firstHeaders);
  free(plugin->lastUrl);
  free(plugin->lastHeaders);
  free(plugin);
}

void handleCallback(PluginObject* object,
                    const char* url,
                    NPReason reason,
                    void* notifyData) {
  assert(object);

  NPVariant args[2];

  NPObject* windowScriptObject;
  browser->getvalue(object->npp, NPNVWindowNPObject, &windowScriptObject);

  NPIdentifier callbackIdentifier = notifyData;

  INT32_TO_NPVARIANT(reason, args[0]);

  char* strHdr = 0;
  if (object->firstUrl && object->firstHeaders && object->lastUrl &&
      object->lastHeaders) {
    // Format expected by JavaScript validator: four fields separated by \n\n:
    // First URL; first header block; last URL; last header block.
    // Note that header blocks already end with \n due to how NPStream::headers
    // works.
    int len = strlen(object->firstUrl) + 2 + strlen(object->firstHeaders) + 1 +
              strlen(object->lastUrl) + 2 + strlen(object->lastHeaders) + 1;
    strHdr = (char*)malloc(len + 1);
    snprintf(strHdr,
             len + 1,
             "%s\n\n%s\n%s\n\n%s\n",
             object->firstUrl,
             object->firstHeaders,
             object->lastUrl,
             object->lastHeaders);
    STRINGN_TO_NPVARIANT(strHdr, len, args[1]);
  } else
    NULL_TO_NPVARIANT(args[1]);

  NPVariant browserResult;
  if (browser->invoke(object->npp,
                      windowScriptObject,
                      callbackIdentifier,
                      args,
                      2,
                      &browserResult))
    browser->releasevariantvalue(&browserResult);

  free(strHdr);
}

void notifyStream(PluginObject* object, const char* url, const char* headers) {
  if (!object->firstUrl) {
    if (url)
      object->firstUrl = base::strdup(url);
    if (headers)
      object->firstHeaders = base::strdup(headers);
  } else {
    free(object->lastUrl);
    free(object->lastHeaders);
    object->lastUrl = (url ? base::strdup(url) : 0);
    object->lastHeaders = (headers ? base::strdup(headers) : 0);
  }
}

void testNPRuntime(NPP npp) {
  NPObject* windowScriptObject;
  browser->getvalue(npp, NPNVWindowNPObject, &windowScriptObject);

  // Invoke
  NPIdentifier testNPInvoke = browser->getstringidentifier("testNPInvoke");
  NPVariant args[7];

  VOID_TO_NPVARIANT(args[0]);
  NULL_TO_NPVARIANT(args[1]);
  BOOLEAN_TO_NPVARIANT(true, args[2]);
  INT32_TO_NPVARIANT(242, args[3]);
  DOUBLE_TO_NPVARIANT(242.242, args[4]);
  STRINGZ_TO_NPVARIANT("Hello, World", args[5]);
  OBJECT_TO_NPVARIANT(windowScriptObject, args[6]);

  NPVariant result;
  if (browser->invoke(npp, windowScriptObject, testNPInvoke, args, 7, &result))
    browser->releasevariantvalue(&result);

  browser->releaseobject(windowScriptObject);
}
