Update Chrome plugin naming, cleanup leftover garbage, commit object
freeing code that was never committed.

This was originally committed to the changes/jat/single-xpi branch by
mistake.

Patch by: jat
Review by: rice (TBR)


git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@6779 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/plugins/npapi/LocalObjectTable.h b/plugins/npapi/LocalObjectTable.h
index 9ff809d..7d95509 100644
--- a/plugins/npapi/LocalObjectTable.h
+++ b/plugins/npapi/LocalObjectTable.h
@@ -16,8 +16,7 @@
  * the License.
  */
 
-#include <vector>
-#include <algorithm>
+#include <map>
 
 #include "Debug.h"
 
@@ -25,27 +24,21 @@
 
 class LocalObjectTable {
 private:
-  static const int INITIAL_OBJECT_TABLE_SIZE = 300;
+  typedef std::map<int, NPObject*> ObjectMap;
 
-  int nextFree;
-  std::vector<NPObject*> objects;
+  int nextId;
+  ObjectMap objects;
   bool dontFree;
 
-  bool isFree(int id) {
-    // low bit is set for free pointers, object pointers can't be odd
-    NPObject* obj = objects[id];
-    return !obj || (reinterpret_cast<long long>(obj) & 1);
-  }
-
   void setFree(int id) {
-    objects[id] = reinterpret_cast<NPObject*>((nextFree << 1) | 1LL);
-    nextFree = id;
+    if (objects.erase(id) != 1) {
+      Debug::log(Debug::Error) << "setFree(id=" << id << "): object not in table"
+        << Debug::flush;
+    }
   }
 
 public:
   LocalObjectTable() {
-    nextFree = -1;
-    objects.reserve(INITIAL_OBJECT_TABLE_SIZE);
     dontFree = false;
   }
 
@@ -55,64 +48,51 @@
    * Add a new object, which must not be in the table, and return a new id for it.
    */
   int add(NPObject* obj) {
-    int id;
-    if (nextFree >= 0) {
-      id = nextFree;
-      nextFree = int(reinterpret_cast<long long>(objects[nextFree])) >> 1;
-      objects[id] = obj;
-    } else {
-      id = static_cast<int>(objects.size());
-      objects.push_back(obj);
-    }
-    Debug::log(Debug::Spam) << "LocalObjectTable::add(obj=" << obj << "): id=" << id
-        << Debug::flush;
-    // keep track that we hold a reference in the table
-    NPN_RetainObject(obj);
+    int id = nextId++;
+    set(id, obj);
     return id;
   }
 
+  void set(int id, NPObject* obj) {
+    Debug::log(Debug::Info) << "LocalObjectTable::set(id=" << id << ",obj=" << (void*)obj
+        << ")" << Debug::flush;
+    objects[id] = obj;
+    // keep track that we hold a reference in the table
+    NPN_RetainObject(obj);
+  }
+
   void free(int id) {
-    Debug::log(Debug::Spam) << "LocalObjectTable::free(id=" << id << ")" << Debug::flush;
-    if (unsigned(id) >= objects.size()) {
-      Debug::log(Debug::Error) << "LocalObjectTable::free(id=" << id << "): invalid index (size="
-          << objects.size() << Debug::flush;
-      return;
-    }
-    if (isFree(id)) {
+    Debug::log(Debug::Info) << "LocalObjectTable::free(id=" << id << ")" << Debug::flush;
+    ObjectMap::iterator it = objects.find(id);
+    if (it == objects.end()) {
       Debug::log(Debug::Error) << "Freeing freed object slot " << id << Debug::flush;
       return;
     }
-    NPObject* obj = objects[id];
     setFree(id);
     if (!dontFree) {
+      NPObject* obj = it->second;
       NPN_ReleaseObject(obj);
     }
   }
 
   void freeAll() {
-    Debug::log(Debug::Spam) << "LocalObjectTable::freeAll()" << Debug::flush;
-    for (unsigned i = 0; i < objects.size(); ++i) {
-      if (!isFree(i)) {
-        NPObject* obj = objects[i];
-        setFree(i);
-        if (!dontFree) {
-          NPN_ReleaseObject(obj);
-        }
+    Debug::log(Debug::Info) << "LocalObjectTable::freeAll()" << Debug::flush;
+    for (ObjectMap::const_iterator it = objects.begin(); it != objects.end(); ++it) {
+      NPObject* obj = it->second;
+      if (!dontFree) {
+        NPN_ReleaseObject(obj);
       }
     }
+    objects.clear();
   }
 
   NPObject* get(int id) {
-    if (unsigned(id) >= objects.size()) {
-      Debug::log(Debug::Error) << "LocalObjectTable::get(id=" << id << "): invalid index (size="
-          << objects.size() << Debug::flush;
-      return 0;
+    ObjectMap::iterator it = objects.find(id);
+    if (it == objects.end()) {
+      Debug::log(Debug::Error) << "LocalObjectTable::get(id=" << id
+          << "): no object found" << Debug::flush;
     }
-    if (isFree(id)) {
-      Debug::log(Debug::Error) << "Getting freed object slot " << id << Debug::flush;
-      return 0;
-    }
-    return objects[id];
+    return it->second;
   }
 
   void setDontFree(bool dontFree) {
diff --git a/plugins/npapi/ScriptableInstance.cpp b/plugins/npapi/ScriptableInstance.cpp
index 6a137bd..6149ffc 100644
--- a/plugins/npapi/ScriptableInstance.cpp
+++ b/plugins/npapi/ScriptableInstance.cpp
@@ -1,276 +1,276 @@
-/*
- * 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);
-
+/*

+ * 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)) {

@@ -281,387 +281,388 @@
       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();
-  } 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();
-    }
-  }
-}
-
+  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();

+    }

+  }

+}

+

diff --git a/plugins/npapi/VisualStudio/npapi-plugin.vcproj b/plugins/npapi/VisualStudio/npapi-plugin.vcproj
index d338c7f..5826c32 100755
--- a/plugins/npapi/VisualStudio/npapi-plugin.vcproj
+++ b/plugins/npapi/VisualStudio/npapi-plugin.vcproj
@@ -63,9 +63,9 @@
 				Name="VCLinkerTool"

 				AdditionalDependencies="ws2_32.lib"

 				ShowProgress="2"

-				OutputFile="$(ProjectDir)\..\prebuilt\gwtdmp\WINNT_x86-msvc\npOOPHM.dll"

+				OutputFile="$(ProjectDir)\..\prebuilt\gwt-dev-plugin\WINNT_x86-msvc\npGwtDevPlugin.dll"

 				LinkIncremental="1"

-				ModuleDefinitionFile="$(ProjectDir)\..\npOOPHM.def"

+				ModuleDefinitionFile="$(ProjectDir)\..\npGwtDevPlugin.def"

 				GenerateDebugInformation="true"

 				ProgramDatabaseFile="$(IntDir)\$(TargetName).pdb"

 				SubSystem="2"

@@ -144,10 +144,10 @@
 				Name="VCLinkerTool"

 				AdditionalDependencies="ws2_32.lib"

 				ShowProgress="2"

-				OutputFile="$(ProjectDir)\..\prebuilt\gwtdmp\WINNT_x86-msvc\npOOPHM.dll"

+				OutputFile="$(ProjectDir)\..\prebuilt\gwt-dev-plugin\WINNT_x86-msvc\npGwtDevPlugin.dll"

 				LinkIncremental="0"

 				AdditionalLibraryDirectories=""

-				ModuleDefinitionFile="..\npOOPHM.def"

+				ModuleDefinitionFile="..\npGwtDevPlugin.def"

 				GenerateDebugInformation="true"

 				ProgramDatabaseFile="$(IntDir)\$(TargetName).pdb"

 				SubSystem="2"

@@ -349,7 +349,7 @@
 			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"

 			>

 			<File

-				RelativePath="..\npOOPHM.rc"

+				RelativePath="..\npGwtDevPlugin.rc"

 				>

 			</File>

 		</Filter>

@@ -423,7 +423,7 @@
 				>

 			</File>

 			<File

-				RelativePath="..\npOOPHM.def"

+				RelativePath="..\npGwtDevPlugin.def"

 				>

 			</File>

 			<File

diff --git a/plugins/npapi/liboophm.r b/plugins/npapi/liboophm.r
deleted file mode 100644
index 251d5f4..0000000
--- a/plugins/npapi/liboophm.r
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * 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 <Carbon/Carbon.r>
-
-// To compile run:
-//  Rez liboophm.r -o liboophm.rsrc -useDF
-//  mv liboophm.rsrc prebuilt/extension/platform/Darwin_x86-gcc3/plugins/oophm.plugin/Contents/Resources/liboophm.rsrc
-
-resource 'STR#' (126) {
- { "GWT Hosted-mode plugin", "GWT Hosted-mode plugin" }
-};
diff --git a/plugins/npapi/npOOPHM.def b/plugins/npapi/npGwtDevPlugin.def
similarity index 100%
rename from plugins/npapi/npOOPHM.def
rename to plugins/npapi/npGwtDevPlugin.def
diff --git a/plugins/npapi/npOOPHM.rc b/plugins/npapi/npGwtDevPlugin.rc
similarity index 100%
rename from plugins/npapi/npOOPHM.rc
rename to plugins/npapi/npGwtDevPlugin.rc
diff --git a/plugins/npapi/oophm.xpi b/plugins/npapi/oophm.xpi
deleted file mode 100644
index 425cdba..0000000
--- a/plugins/npapi/oophm.xpi
+++ /dev/null
Binary files differ
diff --git a/plugins/npapi/prebuilt/gwtdmp/background.html b/plugins/npapi/prebuilt/gwt-dev-plugin/background.html
similarity index 100%
rename from plugins/npapi/prebuilt/gwtdmp/background.html
rename to plugins/npapi/prebuilt/gwt-dev-plugin/background.html
diff --git a/plugins/npapi/prebuilt/gwtdmp/gwt128.png b/plugins/npapi/prebuilt/gwt-dev-plugin/gwt128.png
similarity index 100%
rename from plugins/npapi/prebuilt/gwtdmp/gwt128.png
rename to plugins/npapi/prebuilt/gwt-dev-plugin/gwt128.png
Binary files differ
diff --git a/plugins/npapi/prebuilt/gwtdmp/gwt16.png b/plugins/npapi/prebuilt/gwt-dev-plugin/gwt16.png
similarity index 100%
rename from plugins/npapi/prebuilt/gwtdmp/gwt16.png
rename to plugins/npapi/prebuilt/gwt-dev-plugin/gwt16.png
Binary files differ
diff --git a/plugins/npapi/prebuilt/gwtdmp/gwt32.png b/plugins/npapi/prebuilt/gwt-dev-plugin/gwt32.png
similarity index 100%
rename from plugins/npapi/prebuilt/gwtdmp/gwt32.png
rename to plugins/npapi/prebuilt/gwt-dev-plugin/gwt32.png
Binary files differ
diff --git a/plugins/npapi/prebuilt/gwtdmp/gwt48.png b/plugins/npapi/prebuilt/gwt-dev-plugin/gwt48.png
similarity index 100%
rename from plugins/npapi/prebuilt/gwtdmp/gwt48.png
rename to plugins/npapi/prebuilt/gwt-dev-plugin/gwt48.png
Binary files differ
diff --git a/plugins/npapi/prebuilt/gwtdmp/gwt64.png b/plugins/npapi/prebuilt/gwt-dev-plugin/gwt64.png
similarity index 100%
rename from plugins/npapi/prebuilt/gwtdmp/gwt64.png
rename to plugins/npapi/prebuilt/gwt-dev-plugin/gwt64.png
Binary files differ
diff --git a/plugins/npapi/prebuilt/gwtdmp/manifest.json b/plugins/npapi/prebuilt/gwt-dev-plugin/manifest.json
similarity index 70%
rename from plugins/npapi/prebuilt/gwtdmp/manifest.json
rename to plugins/npapi/prebuilt/gwt-dev-plugin/manifest.json
index 4dfc66a..fc73f5f 100644
--- a/plugins/npapi/prebuilt/gwtdmp/manifest.json
+++ b/plugins/npapi/prebuilt/gwt-dev-plugin/manifest.json
@@ -1,7 +1,8 @@
 {
-  "name": "GWT Development Mode Plugin",
+  "name": "GWT Developer Plugin",
   "version": "0.9.0",
   "description": "A plugin to enable debugging with GWT's Development Mode",
+  "update_url": "https://dl-ssl.google.com/gwt/plugins/chrome/updates.xml",
   "icons": {
     "16": "gwt16.png",
     "32": "gwt32.png",
@@ -17,6 +18,6 @@
     }
   ],
   "plugins": [
-    { "path": "WINNT_x86-msvc/npOOPHM.dll", "public": true }
+    { "path": "WINNT_x86-msvc/npGwtDevPlugin.dll", "public": true }
   ]
 }
diff --git a/plugins/npapi/prebuilt/gwtdmp/record_tab_id.js b/plugins/npapi/prebuilt/gwt-dev-plugin/record_tab_id.js
similarity index 100%
rename from plugins/npapi/prebuilt/gwtdmp/record_tab_id.js
rename to plugins/npapi/prebuilt/gwt-dev-plugin/record_tab_id.js
diff --git a/plugins/npapi/prebuilt/gwtdmp.crx b/plugins/npapi/prebuilt/gwtdmp.crx
deleted file mode 100644
index 1538642..0000000
--- a/plugins/npapi/prebuilt/gwtdmp.crx
+++ /dev/null
Binary files differ
diff --git a/plugins/npapi/prebuilt/gwtdmp/WINNT_x86-msvc/npOOPHM.dll b/plugins/npapi/prebuilt/gwtdmp/WINNT_x86-msvc/npOOPHM.dll
deleted file mode 100644
index a1dcaa9..0000000
--- a/plugins/npapi/prebuilt/gwtdmp/WINNT_x86-msvc/npOOPHM.dll
+++ /dev/null
Binary files differ