/*
 * Copyright 2008 Google Inc.
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

#include <cstring>

#include "ScriptableInstance.h"
#include "InvokeMessage.h"
#include "ReturnMessage.h"
#include "ServerMethods.h"
#include "AllowedConnections.h"
#include "Preferences.h"
#include "AllowDialog.h"

#include "mozincludes.h"
#include "scoped_ptr/scoped_ptr.h"
#include "NPVariantWrapper.h"

using std::string;
using std::endl;

static inline string convertToString(const NPString& str) {
  return string(GetNPStringUTF8Characters(str), GetNPStringUTF8Length(str));
}

string ScriptableInstance::computeTabIdentity() {
  return "";
}

void ScriptableInstance::dumpObjectBytes(NPObject* obj) {
  char buf[20];
  Debug::log(Debug::Debugging) << "   object bytes:\n";
  const unsigned char* ptr = reinterpret_cast<const unsigned char*>(obj);
  for (int i = 0; i < 24; ++i) {
    snprintf(buf, sizeof(buf), " %02x", ptr[i]);
    Debug::log(Debug::Debugging) << buf;
  }
  NPVariant objVar;
  OBJECT_TO_NPVARIANT(obj, objVar);
  Debug::log(Debug::Debugging) << " obj.toString()="
      << NPVariantProxy::toString(objVar) << Debug::flush;
}

ScriptableInstance::ScriptableInstance(NPP npp) : NPObjectWrapper<ScriptableInstance>(npp),
    plugin(*reinterpret_cast<Plugin*>(npp->pdata)),
    _channel(new HostChannel()),
    localObjects(),
    _connectId(NPN_GetStringIdentifier("connect")),
    initID(NPN_GetStringIdentifier("init")),
    toStringID(NPN_GetStringIdentifier("toString")),
    connectedID(NPN_GetStringIdentifier("connected")),
    statsID(NPN_GetStringIdentifier("stats")),
    gwtId(NPN_GetStringIdentifier("__gwt_ObjectId")),
    jsInvokeID(NPN_GetStringIdentifier("__gwt_jsInvoke")),
    jsResultID(NPN_GetStringIdentifier("__gwt_makeResult")),
    jsTearOffID(NPN_GetStringIdentifier("__gwt_makeTearOff")),
    jsValueOfID(NPN_GetStringIdentifier("valueOf")),
    idx0(NPN_GetIntIdentifier(0)),
    idx1(NPN_GetIntIdentifier(1)) {
  savedValueIdx = -1;
  if (NPN_GetValue(npp, NPNVWindowNPObject, &window) != NPERR_NO_ERROR) {
    Debug::log(Debug::Error) << "Error getting window object" << Debug::flush;
  }
}

ScriptableInstance::~ScriptableInstance() {
  // TODO(jat): free any remaining Java objects held by JS, then make
  // the JS wrapper handle that situation gracefully
  if (window) {
    NPN_ReleaseObject(window);
  }
  for (hash_map<int, JavaObject*>::iterator it = javaObjects.begin(); it != javaObjects.end();
      ++it) {
    Debug::log(Debug::Spam) << "  disconnecting Java wrapper " << it->first << Debug::flush;
    it->second->disconnectPlugin();
  }
  if (_channel) {
    _channel->disconnectFromHost();
    delete _channel;
  }
}

void ScriptableInstance::dumpJSresult(const char* js) {
  NPString npScript;
  dupString(js, npScript);
  NPVariantWrapper wrappedRetVal(*this);
  if (!NPN_Evaluate(getNPP(), window, &npScript, wrappedRetVal.addressForReturn())) {
    Debug::log(Debug::Error) << "   *** dumpJSresult failed" << Debug::flush;
    return;
  }
  Debug::log(Debug::Info) << "dumpWindow=" << wrappedRetVal.toString() << Debug::flush;
}

bool ScriptableInstance::tryGetStringPrimitive(NPObject* obj, NPVariant& result) {
  if (NPN_HasMethod(getNPP(), obj, jsValueOfID)) {
    if (NPN_Invoke(getNPP(), obj, jsValueOfID, 0, 0, &result)
        && NPVariantProxy::isString(result)) {
      return true;
    }
    NPVariantProxy::release(result);
  }
  return false;
}

bool ScriptableInstance::makeResult(bool isException, const Value& value, NPVariant* result) {
  Debug::log(Debug::Debugging) << "makeResult(" << isException << ", " << value << ")"
      << Debug::flush;
  Value temp;
  if (value.getType() == Value::JAVA_OBJECT) {
    int javaId = value.getJavaObjectId();
    // We may have previously released the proxy for the same object id,
    // but have not yet sent a free message back to the server.
    javaObjectsToFree.erase(javaId);
  }
  NPVariantArray varArgs(*this, 3);
  varArgs[0] = isException ? 1 : 0;
  varArgs[1] = value;
  NPVariantWrapper retVal(*this);
  return NPN_Invoke(getNPP(), window, jsResultID, varArgs.getArray(), varArgs.getSize(), result);
}

//=============================================================================
// NPObject methods
//=============================================================================

bool ScriptableInstance::hasProperty(NPIdentifier name) {
  if (!NPN_IdentifierIsString(name)) {
    // all numeric properties are ok, as we assume only JSNI code is making
    // the field access via dispatchID
    return true;
  }
  // TODO: special-case toString tear-offs
  return name == statsID || name == connectedID;
}

bool ScriptableInstance::getProperty(NPIdentifier name, NPVariant* variant) {
  Debug::log(Debug::Debugging) << "ScriptableInstance::getProperty(name="
      << NPN_UTF8FromIdentifier(name) << ")" << Debug::flush;
  bool retVal = false;
  VOID_TO_NPVARIANT(*variant);
  if (name == connectedID) {
    BOOLEAN_TO_NPVARIANT(_channel->isConnected(), *variant);
    retVal = true;
  } else if (name == statsID) {
    NPVariantProxy::assignFrom(*variant, "<stats data>");
    retVal = true;
  }
  if (retVal) {
    // TODO: testing
    Debug::log(Debug::Debugging) << " return value " << *variant
        << Debug::flush;
  }
  return retVal;
}

bool ScriptableInstance::setProperty(NPIdentifier name, const NPVariant* variant) {
  Debug::log(Debug::Debugging) << "ScriptableInstance::setProperty(name="
      << NPN_UTF8FromIdentifier(name) << ", value=" << *variant << ")"
      << Debug::flush; 
  return false;
}

bool ScriptableInstance::hasMethod(NPIdentifier name) {
  Debug::log(Debug::Debugging) << "ScriptableInstance::hasMethod(name=" << NPN_UTF8FromIdentifier(name) << ")"
      << Debug::flush; 
  if (name == _connectId || name == initID || name == toStringID) {
    return true;
  }
  return false;
}

bool ScriptableInstance::invoke(NPIdentifier name, const NPVariant* args, unsigned argCount,
    NPVariant* result) {
  NPUTF8* uname = NPN_UTF8FromIdentifier(name);
  Debug::log(Debug::Debugging) << "ScriptableInstance::invoke(name=" << uname << ",#args=" << argCount << ")"
      << Debug::flush;
  VOID_TO_NPVARIANT(*result);
  if (name == _connectId) {
    connect(args, argCount, result);
  } else if (name == initID) {
    init(args, argCount, result);
  } else if (name == toStringID) {
    // TODO(jat): figure out why this doesn't show in Firebug
    string val("[GWT OOPHM Plugin: connected=");
    val += _channel->isConnected() ? 'Y' : 'N';
    val += ']';
    NPVariantProxy::assignFrom(*result, val);
  }
  return true;
}

bool ScriptableInstance::invokeDefault(const NPVariant* args, unsigned argCount,
      NPVariant* result) {
  Debug::log(Debug::Debugging) << "ScriptableInstance::invokeDefault(#args=" << argCount << ")"
      << Debug::flush;
  VOID_TO_NPVARIANT(*result);
  return true;
}

bool ScriptableInstance::enumeration(NPIdentifier** propReturn, uint32_t* count) {
  Debug::log(Debug::Debugging) << "ScriptableInstance::enumeration()" << Debug::flush;
  int n = 2;
  NPIdentifier* props = static_cast<NPIdentifier*>(NPN_MemAlloc(sizeof(NPIdentifier) * n));
  props[0] = connectedID;
  props[1] = statsID;
  *propReturn = props;
  *count = n;
  return true;
}

//=============================================================================
// internal methods
//=============================================================================

void ScriptableInstance::init(const NPVariant* args, unsigned argCount, NPVariant* result) {
  if (argCount != 1 || !NPVariantProxy::isObject(args[0])) {
    // TODO: better failure?
    Debug::log(Debug::Error) << "ScriptableInstance::init called with incorrect arguments:\n";
    for (unsigned i = 0; i < argCount; ++i) {
      Debug::log(Debug::Error) << " " << i << " " << NPVariantProxy::toString(args[i]) << "\n";
    }
    Debug::log(Debug::Error) << Debug::flush;
    result->type = NPVariantType_Void;
    return;
  }
  if (window) {
    NPN_ReleaseObject(window);
  }
  // replace our window object with that passed by the caller
  window = NPVariantProxy::getAsObject(args[0]);
  NPN_RetainObject(window);
  BOOLEAN_TO_NPVARIANT(true, *result);
  result->type = NPVariantType_Bool;
}

void ScriptableInstance::connect(const NPVariant* args, unsigned argCount, NPVariant* result) {
  if (argCount != 5 || !NPVariantProxy::isString(args[0])
      || !NPVariantProxy::isString(args[1])
      || !NPVariantProxy::isString(args[2])
      || !NPVariantProxy::isString(args[3])
      || !NPVariantProxy::isString(args[4])) {
    // TODO: better failure?
    Debug::log(Debug::Error) << "ScriptableInstance::connect called with incorrect arguments:\n";
    for (unsigned i = 0; i < argCount; ++i) {
      Debug::log(Debug::Error) << " " << i << " " << NPVariantProxy::toString(args[i]) << "\n";
    }
    Debug::log(Debug::Error) << Debug::flush;
    result->type = NPVariantType_Void;
    return;
  }
  const NPString url = args[0].value.stringValue;
  const NPString sessionKey = args[1].value.stringValue;
  const NPString hostAddr = args[2].value.stringValue;
  const NPString moduleName = args[3].value.stringValue;
  const NPString hostedHtmlVersion = args[4].value.stringValue;
  Debug::log(Debug::Info) << "ScriptableInstance::connect(url=" << NPVariantProxy::toString(args[0])
      << ",sessionKey=" << NPVariantProxy::toString(args[1]) << ",host=" << NPVariantProxy::toString(args[2])
      << ",module=" << NPVariantProxy::toString(args[3]) << ",hostedHtmlVers=" << NPVariantProxy::toString(args[4])
      << ")" << Debug::flush;
  const std::string urlStr = convertToString(url);

  Preferences::loadAccessList();
  bool allowed = false;
  if (!AllowedConnections::matchesRule(urlStr, &allowed)) {
    bool remember = false;
    allowed = AllowDialog::askUserToAllow(&remember);
    if (remember) {
      std::string host = AllowedConnections::getHostFromUrl(urlStr);
      Preferences::addNewRule(host, !allowed);
    }
  }
  if (!allowed) {
    BOOLEAN_TO_NPVARIANT(false, *result);
    result->type = NPVariantType_Bool;
    return;
  }

  bool connected = false;
  unsigned port = 9997;  // TODO(jat): should there be a default?
  int n = GetNPStringUTF8Length(hostAddr);
  scoped_ptr<char> host(new char[n + 1]);
  const char* s = GetNPStringUTF8Characters(hostAddr);
  char* d = host.get();
  while (n > 0 && *s != ':') {
    n--;
    *d++ = *s++;
  }
  *d = 0;
  if (n > 0) {
    port = atoi(s + 1);
  }
  Debug::log(Debug::Info) << "  host=" << host.get() << ",port=" << port << Debug::flush;


  if (!_channel->connectToHost(host.get(), port)) {
    BOOLEAN_TO_NPVARIANT(false, *result);
    result->type = NPVariantType_Bool;
  }

  string hostedHtmlVersionStr = convertToString(hostedHtmlVersion);
  if (!_channel->init(this, BROWSERCHANNEL_PROTOCOL_VERSION,
      BROWSERCHANNEL_PROTOCOL_VERSION, hostedHtmlVersionStr)) {
    BOOLEAN_TO_NPVARIANT(false, *result);
    result->type = NPVariantType_Bool;
  }

  string moduleNameStr = convertToString(moduleName);
  string userAgent(NPN_UserAgent(getNPP()));
  string tabKeyStr = computeTabIdentity();
  string sessionKeyStr = convertToString(sessionKey);
  Debug::log(Debug::Debugging) << "  connected, sending loadModule" << Debug::flush;
  connected = LoadModuleMessage::send(*_channel, urlStr, tabKeyStr, sessionKeyStr,
      moduleNameStr, userAgent, this);
  BOOLEAN_TO_NPVARIANT(connected, *result);
  result->type = NPVariantType_Bool;
}

int ScriptableInstance::getLocalObjectRef(NPObject* obj) {
  NPVariantWrapper wrappedRetVal(*this);
  int id;
  if (NPN_GetProperty(getNPP(), obj, gwtId, wrappedRetVal.addressForReturn())
      && wrappedRetVal.isInt()) {
    id = wrappedRetVal.getAsInt();
    localObjects.set(id, obj);
  } else {
    id = localObjects.add(obj);
    wrappedRetVal = id;
    if (!NPN_SetProperty(getNPP(), obj, gwtId, wrappedRetVal.address())) {
      Debug::log(Debug::Error) << "Setting GWT id on object failed" << Debug::flush;
    }
  }
  return id;
}

void ScriptableInstance::fatalError(HostChannel& channel, const std::string& message) {
  // TODO(jat): better error handling
  Debug::log(Debug::Error) << "Fatal error: " << message << Debug::flush;
}

void ScriptableInstance::dupString(const char* str, NPString& npString) {
  npString.UTF8Length = static_cast<uint32_t>(strlen(str));
  NPUTF8* chars = static_cast<NPUTF8*>(NPN_MemAlloc(npString.UTF8Length));
  memcpy(chars, str, npString.UTF8Length);
  npString.UTF8Characters = chars;
}

// SessionHandler methods
void ScriptableInstance::freeValue(HostChannel& channel, int idCount, const int* const ids) {
  Debug::log(Debug::Debugging) << "freeValue(#ids=" << idCount << ")" << Debug::flush;
  for (int i = 0; i < idCount; ++i) {
	  Debug::log(Debug::Spam) << " id=" << ids[i] << Debug::flush;
    NPObject* obj = localObjects.get(ids[i]);
    if (!NPN_RemoveProperty(getNPP(), obj, gwtId)) {
      Debug::log(Debug::Error) << "Unable to remove GWT ID from object " << ids[i] << Debug::flush;
    } else {
      localObjects.free(ids[i]);
    }
  }
}

void ScriptableInstance::loadJsni(HostChannel& channel, const std::string& js) {
  NPString npScript;
  dupString(js.c_str(), npScript);
  NPVariantWrapper npResult(*this);
  Debug::log(Debug::Spam) << "loadJsni - \n" << js << Debug::flush;
  if (!NPN_Evaluate(getNPP(), window, &npScript, npResult.addressForReturn())) {
    Debug::log(Debug::Error) << "loadJsni failed\n" << js << Debug::flush;
  }
}

Value ScriptableInstance::clientMethod_getProperty(HostChannel& channel, int numArgs, const Value* const args) {
  if (numArgs != 2 || !args[0].isInt() || (!args[1].isString() && !args[1].isInt())) {
    Debug::log(Debug::Error) << "Incorrect invocation of getProperty: #args=" << numArgs << ":";
    for (int i = 0; i < numArgs; ++i) {
      Debug::log(Debug::Error) << " " << i << "=" << args[i].toString();
    }
    Debug::log(Debug::Error) << Debug::flush;
    return Value();
  }
  int id = args[0].getInt();
  NPObject* obj = localObjects.get(id);
  NPIdentifier propID;
  if (args[1].isString()) {
    std::string propName = args[1].getString();
    propID = NPN_GetStringIdentifier(propName.c_str());
  } else {
    int propNum = args[1].getInt();
    propID = NPN_GetIntIdentifier(propNum);
  }
  NPVariantWrapper npResult(*this);
  if (!NPN_GetProperty(getNPP(), obj, propID, npResult.addressForReturn())) {
    Debug::log(Debug::Warning) << "getProperty(id=" << id << ", prop="
        << NPN_UTF8FromIdentifier(propID) << ") failed" << Debug::flush;
    return Value();
  }
  return npResult.getAsValue(*this);
}

Value ScriptableInstance::clientMethod_setProperty(HostChannel& channel, int numArgs, const Value* const args) {
  if (numArgs != 2 || !args[0].isInt() || (!args[1].isString() && !args[1].isInt())) {
    Debug::log(Debug::Error) << "Incorrect invocation of setProperty: #args="
        << numArgs << ":";
    for (int i = 0; i < numArgs; ++i) {
      Debug::log(Debug::Error) << " " << i << "=" << args[i].toString();
    }
    Debug::log(Debug::Error) << Debug::flush;
    return Value();
  }
  int id = args[0].getInt();
  NPObject* obj = localObjects.get(id);
  NPIdentifier propID;
  if (args[1].isString()) {
    std::string propName = args[1].getString();
    propID = NPN_GetStringIdentifier(propName.c_str());
  } else {
    int propNum = args[1].getInt();
    propID = NPN_GetIntIdentifier(propNum);
  }
  NPVariantWrapper npValue(*this);
  npValue.operator=(args[2]);
  if (!NPN_SetProperty(getNPP(), obj, propID, npValue.address())) {
    Debug::log(Debug::Warning) << "setProperty(id=" << id << ", prop="
        << NPN_UTF8FromIdentifier(propID) << ", val=" << args[2].toString()
        << ") failed" << Debug::flush;
    return Value();
  }
  return Value();
}

/**
 * SessionHandler.invoke - used by LoadModule and reactToMessages* to process server-side
 * requests to invoke methods in Javascript or the plugin.
 */
bool ScriptableInstance::invokeSpecial(HostChannel& channel, SpecialMethodId dispatchId,
    int numArgs, const Value* const args, Value* returnValue) {
  switch (dispatchId) {
  case SessionHandler::HasMethod:
  case SessionHandler::HasProperty:
    break;
  case SessionHandler::SetProperty:
    *returnValue = clientMethod_setProperty(channel, numArgs, args);
    return false;
  case SessionHandler::GetProperty:
    *returnValue = clientMethod_getProperty(channel, numArgs, args);
    return false;
  default:
    break;
  }
  Debug::log(Debug::Error) << "Unexpected special method " << dispatchId
      << " called on plugin; #args=" << numArgs << ":";
  for (int i = 0; i < numArgs; ++i) {
    Debug::log(Debug::Error) << " " << i << "=" << args[i].toString();
  }
  Debug::log(Debug::Error) << Debug::flush;
  // TODO(jat): should we create a real exception object?
  std::string buf("unexpected invokeSpecial(");
  buf += static_cast<int>(dispatchId);
  buf += ")";
  returnValue->setString(buf);
  return true;
}

bool ScriptableInstance::invoke(HostChannel& channel, const Value& thisRef,
    const std::string& methodName, int numArgs, const Value* const args,
    Value* returnValue) {
  Debug::log(Debug::Debugging) << "invokeJS(" << methodName << ", this=" 
      << thisRef.toString() << ", numArgs=" << numArgs << ")" << Debug::flush;
  NPVariantArray varArgs(*this, numArgs + 2);
  varArgs[0] = thisRef;
  varArgs[1] = methodName;
  for (int i = 0; i < numArgs; ++i) {
    varArgs[i + 2] = args[i];
  }
  const NPVariant* argArray = varArgs.getArray();
  if (Debug::level(Debug::Spam)) {
    for (int i = 0; i < varArgs.getSize(); ++i) {
      Debug::log(Debug::Spam) << "  arg " << i << " is "
          << NPVariantProxy::toString(argArray[i]) << Debug::flush;
    }
  }
  NPVariantWrapper wrappedRetVal(*this);
  if (!NPN_Invoke(getNPP(), window, jsInvokeID, argArray, varArgs.getSize(),
      wrappedRetVal.addressForReturn())) {
    Debug::log(Debug::Error) << "*** invokeJS(" << methodName << ", this="
        << thisRef.toString() << ", numArgs=" << numArgs << ") failed"
        << Debug::flush;
    // TODO(jat): should we create a real exception object?
    returnValue->setString("invoke of " + methodName + " failed");
    return true;
  }
  Debug::log(Debug::Spam) << "  wrapped return is " << wrappedRetVal.toString() << Debug::flush;
  NPVariantWrapper exceptFlag(*this);
  NPVariantWrapper retval(*this);
  NPObject* wrappedArray = wrappedRetVal.getAsObject();
  if (!NPN_GetProperty(getNPP(), wrappedArray, idx0, exceptFlag.addressForReturn())) {
    Debug::log(Debug::Error) << " Error getting element 0 of wrapped return value ("
        << wrappedRetVal << ") on call to " << methodName << Debug::flush;
  }
  if (!NPN_GetProperty(getNPP(), wrappedArray, idx1, retval.addressForReturn())) {
    Debug::log(Debug::Error) << " Error getting element 1 of wrapped return value ("
        << wrappedRetVal << ") on call to " << methodName << Debug::flush;
  }
  Debug::log(Debug::Debugging) << "  return value " << retval.toString() << Debug::flush;
  *returnValue = retval.getAsValue(*this);
  if (exceptFlag.isInt() && exceptFlag.getAsInt() != 0) {
    Debug::log(Debug::Debugging) << "  exception: " << retval << Debug::flush;
    return true;
  }
  return false;
}

bool ScriptableInstance::JavaObject_invoke(int objectId, int dispId,
    const NPVariant* args, uint32_t numArgs, NPVariant* result) {
  Debug::log(Debug::Debugging) << "JavaObject_invoke(dispId= " << dispId << ", numArgs=" << numArgs << ")" << Debug::flush;
  if (Debug::level(Debug::Spam)) {
    for (uint32_t i = 0; i < numArgs; ++i) {
      Debug::log(Debug::Spam) << "  " << i << " = " << args[i] << Debug::flush;
    }
  }

  bool isRawToString = false;
  if (dispId == -1) {
    dispId = 0;
    isRawToString = true;
  }

  Value javaThis;
  javaThis.setJavaObject(objectId);
  scoped_array<Value> vargs(new Value[numArgs]);
  for (unsigned i = 0; i < numArgs; ++i) {
    vargs[i] = NPVariantProxy::getAsValue(args[i], *this);
  }
  if (!InvokeMessage::send(*_channel, javaThis, dispId, numArgs, vargs.get())) {
    Debug::log(Debug::Error) << "JavaObject_invoke: failed to send invoke message" << Debug::flush;
    // TODO(jat): returning false here spams the browser console
    return true;
  }
  Debug::log(Debug::Debugging) << " return from invoke" << Debug::flush;
  scoped_ptr<ReturnMessage> retMsg(_channel->reactToMessagesWhileWaitingForReturn(this));
  if (!retMsg.get()) {
    Debug::log(Debug::Error) << "JavaObject_invoke: failed to get return value" << Debug::flush;
    return false;
  }
  if (isRawToString) {
    // toString() needs the raw value
    NPVariantProxy::assignFrom(*this, *result, retMsg->getReturnValue());
    return !retMsg->isException();
  }
  // Wrap the result
  return makeResult(retMsg->isException(), retMsg->getReturnValue(), result);
}

bool ScriptableInstance::JavaObject_getProperty(int objectId, int dispId,
    NPVariant* result) {
  Debug::log(Debug::Debugging) << "JavaObject_getProperty(objectid="
      << objectId << ", dispId=" << dispId << ")" << Debug::flush;
  VOID_TO_NPVARIANT(*result);
  Value propertyValue = ServerMethods::getProperty(*_channel, this, objectId, dispId);
  if (propertyValue.isJsObject()) {
    // TODO(jat): special-case for testing
    NPObject* npObj = localObjects.get(propertyValue.getJsObjectId());
    OBJECT_TO_NPVARIANT(npObj, *result);
    NPN_RetainObject(npObj);
  } else {
    NPVariantProxy::assignFrom(*this, *result, propertyValue);
  }
  Debug::log(Debug::Debugging) << " return val=" << propertyValue
      << ", NPVariant=" << *result << Debug::flush;
  if (NPVariantProxy::isObject(*result)) {
    dumpObjectBytes(NPVariantProxy::getAsObject(*result));
  }
  if (NPVariantProxy::isObject(*result)) {
    Debug::log(Debug::Debugging) << "  final return refcount = "
        << NPVariantProxy::getAsObject(*result)->referenceCount << Debug::flush; 
  }
  return true;
}

bool ScriptableInstance::JavaObject_setProperty(int objectId, int dispId,
    const NPVariant* npValue) {
  Debug::log(Debug::Debugging) << "JavaObject_setProperty(objectid="
      << objectId << ", dispId=" << dispId << ", value=" << *npValue << ")" << Debug::flush;
  if (NPVariantProxy::isObject(*npValue)) {
    Debug::log(Debug::Debugging) << "  before localObj: refcount = "
        << NPVariantProxy::getAsObject(*npValue)->referenceCount << Debug::flush; 
  }
  Value value = NPVariantProxy::getAsValue(*npValue, *this, true);
  if (NPVariantProxy::isObject(*npValue)) {
    Debug::log(Debug::Debugging) << "  after localObj: refcount = "
        << NPVariantProxy::getAsObject(*npValue)->referenceCount << Debug::flush; 
  }
  if (NPVariantProxy::isObject(*npValue)) {
    dumpObjectBytes(NPVariantProxy::getAsObject(*npValue));
  }
  Debug::log(Debug::Debugging) << "  as value: " << value << Debug::flush;
  // TODO: no way to set an actual exception object! (Could ClassCastException on server.)
  return ServerMethods::setProperty(*_channel, this, objectId, dispId, value);
}

bool ScriptableInstance::JavaObject_getToStringTearOff(NPVariant* result) {
  Debug::log(Debug::Debugging) << "JavaObject_getToStringTearOff()" << Debug::flush;
  VOID_TO_NPVARIANT(*result);

  Value temp;
  NPVariantArray varArgs(*this, 3);
  temp.setNull();  varArgs[0] = temp; // proxy: no proxy needed
  temp.setInt(0);  varArgs[1] = temp; // dispId: always 0 for toString()
  temp.setInt(0);  varArgs[2] = temp; // argCount: always 0 for toString()

  if (!NPN_Invoke(getNPP(), window, jsTearOffID, varArgs.getArray(), 3, result)) {
    Debug::log(Debug::Error) << "*** JavaObject_getToStringTearOff() failed"
        << Debug::flush;
    return true;
  }
  return true;
}

JavaObject* ScriptableInstance::createJavaWrapper(int objectId) {
  Debug::log(Debug::Debugging) << "createJavaWrapper(objectId=" << objectId <<  ")" << Debug::flush;
  JavaObject* jObj;
  hash_map<int, JavaObject*>::iterator it = javaObjects.find(objectId);
  if (it != javaObjects.end()) {
    jObj = it->second;
    NPN_RetainObject(jObj);
    return jObj;
  }
  jObj = JavaObject::create(this, objectId);
  javaObjects[objectId] = jObj;
  return jObj;
}

void ScriptableInstance::destroyJavaWrapper(JavaObject* jObj) {
  int objectId = jObj->getObjectId();
  if (!javaObjects.erase(objectId)) {
    Debug::log(Debug::Error) << "destroyJavaWrapper(id=" << objectId
        << "): trying to free unknown JavaObject" << Debug::flush;
  }
  Debug::log(Debug::Debugging) << "destroyJavaWrapper(id=" << objectId << ")" << Debug::flush;
  javaObjectsToFree.insert(objectId);
}

void ScriptableInstance::sendFreeValues(HostChannel& channel) {
  unsigned n = javaObjectsToFree.size();
  if (n) {
    scoped_array<int> ids(new int[n]);
    int i = 0;
    for (std::set<int>::iterator it = javaObjectsToFree.begin();
        it != javaObjectsToFree.end(); ++it) {
      ids[i++] = *it;
    }
    if (ServerMethods::freeJava(channel, this, n, ids.get())) {
      javaObjectsToFree.clear();
    }
  }
}

