/*
 * 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")),
    jsDisconnectedID(NPN_GetStringIdentifier("__gwt_disconnected")),
    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);
  }
  bool isException = false;
  Value returnValue;
  if (!InvokeMessage::send(*_channel, javaThis, dispId, numArgs, vargs.get())) {
    Debug::log(Debug::Error) << "JavaObject_invoke: failed to send invoke message" << Debug::flush;
  } else {
    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;
    } else {
      if (isRawToString) {
        // toString() needs the raw value
        NPVariantProxy::assignFrom(*this, *result, retMsg->getReturnValue());
        return !retMsg->isException();
      }
      isException = retMsg->isException();
      returnValue = retMsg->getReturnValue();
    }
  }
  // Wrap the result
  return makeResult(isException, returnValue, 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::disconnectDetectedImpl() {
  NPVariantWrapper result(*this);
  NPN_Invoke(getNPP(), window, jsDisconnectedID, 0, 0, result.addressForReturn());
}

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();
    }
  }
}

