Add security controls to all plugins, get plugins build for all tier-1
platforms.

Patch by: jat
Review by: amitmanjhi, jaimeyap


git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@6085 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/plugins/MissingBrowserPlugin.html b/plugins/MissingBrowserPlugin.html
index 553c27b..22ecac4 100644
--- a/plugins/MissingBrowserPlugin.html
+++ b/plugins/MissingBrowserPlugin.html
@@ -6,7 +6,7 @@
 <body>
 <h1>No GWT Browser Plugin Detected</h1>
 <!-- TODO: alter language for final naming decisions -->
-GWT Debug Mode needs a browser plugin to operate.  Please install the
+GWT Development Mode needs a browser plugin to operate.  Please install the
 appropriate one for your browser.
 
 <ul>
@@ -14,10 +14,10 @@
   <br>Install the appropriate Firefox plugin via the normal plugin install
   process.
  <ul>
-  <li><a href="http://google-web-toolkit.googlecode.com/svn/trunk/plugins/xpcom/prebuilt/oophm-xpcom-ff2.xpi">Version 1.5-2.0</a>
-  <li><a href="http://google-web-toolkit.googlecode.com/svn/trunk/plugins/xpcom/prebuilt/oophm-xpcom-ff3.xpi">Version 3.0</a> (see below if you have problems)
-  <li><a href="http://google-web-toolkit.googlecode.com/svn/trunk/plugins/xpcom/prebuilt/oophm-xpcom-ff3+.xpi">Version 3.0.11</a> (some platforms will use the one above)
-  <li><a href="http://google-web-toolkit.googlecode.com/svn/trunk/plugins/xpcom/prebuilt/oophm-xpcom-ff35.xpi">Version 3.5+</a>
+  <li><a href="http://google-web-toolkit.googlecode.com/svn/trunk/plugins/xpcom/prebuilt/gwt-dmp-ff2.xpi">Version 1.5-2.0</a>
+  <li><a href="http://google-web-toolkit.googlecode.com/svn/trunk/plugins/xpcom/prebuilt/gwt-dmp-ff3.xpi">Version 3.0</a>
+  <li><a href="http://google-web-toolkit.googlecode.com/svn/trunk/plugins/xpcom/prebuilt/gwt-dmp-ff3+.xpi">Version 3.0 alternate libraries</a> (try this if the one above doesn't work on Linux, known to be needed on Fedora Core 10))
+  <li><a href="http://google-web-toolkit.googlecode.com/svn/trunk/plugins/xpcom/prebuilt/gwt-dmp-ff35.xpi">Version 3.5+</a>
  </ul>
  <br>
  <li><b><font size="+1">Safari 3/4 on Mac/OSX</font></b>
diff --git a/plugins/common/AllowedConnections.cpp b/plugins/common/AllowedConnections.cpp
index 39b8a0e..dd14441 100644
--- a/plugins/common/AllowedConnections.cpp
+++ b/plugins/common/AllowedConnections.cpp
@@ -17,20 +17,94 @@
 #include "Debug.h"
 #include <string>
 #include <cstring>
+#include <vector>
 
 #include "AllowedConnections.h"
 
-void AllowedConnections::init() {
+
+// TODO(jat): do we need to protect against parallel access to static state?
+//    current browsers only use one thread, but Chrome is multithreaded, though
+//    it isn't clear if plugins see parallel execution.  For now, we will
+//    assume the caller takes responsibility for making sure there are no
+//    concurrent calls into AllowedConnections.
+std::vector<AllowedConnections::Rule> AllowedConnections::rules;
+
+/**
+ * Get the host portion of the URL, not including the port.
+ *
+ * @return the host portion of the URL, or the unmodified URL if it does not appear
+ *     to be valid
+ */
+std::string AllowedConnections::getHostFromUrl(const std::string& url) {
+  int protoEnd = url.find("://");
+  if (protoEnd == std::string::npos) {
+    Debug::log(Debug::Debugging) << "getHostFromUrl(" << url
+        << ") - no :// in URL" << Debug::flush;
+    return url;
+  }
+  protoEnd += 3; // skip over "://"
+  int hostEnd = url.find('/', protoEnd);
+  if (hostEnd == std::string::npos) {
+    hostEnd = url.length();
+  }
+  int colon = url.find(':', protoEnd);
+  if (colon == std::string::npos || colon > hostEnd) {
+    colon = hostEnd;
+  }
+  std::string host = url.substr(protoEnd, colon - protoEnd);
+  return host;
 }
 
-bool AllowedConnections::isAllowed(const char* host, int port) {
-  // always allow localhost
-  if (!strcmp(host, "localhost") || !strcmp(host, "127.0.0.1")) {
+bool AllowedConnections::matchesRule(const std::string& url,
+    bool* allowed) {
+  std::string host = getHostFromUrl(url);
+  // always allow localhost, localhost.* or 127.0.0.1 for the host
+  // TODO(jat): try and get IP addresses of local interfaces?
+  if (host == "localhost" || host.find("localhost.") == 0
+      || host == "127.0.0.1") {
+    *allowed = true;
     return true;
   }
-  // TODO(jat): allow specified IP addresses that are actually on this machine
-  return true;
+  Debug::log(Debug::Spam) << "Checking host " << host << Debug::flush;
+  for (std::vector<AllowedConnections::Rule>::const_iterator it = rules.begin();
+       it != rules.end(); ++it) {
+    Debug::log(Debug::Spam) << "  comparing to " << it->getPattern()
+        << Debug::flush;
+    // TODO(jat): add support for regexes
+    if (host == it->getPattern()) {
+      *allowed = !it->isExcluded();
+      return true;
+    }
+  }
+  Debug::log(Debug::Info)
+      << "GWT Development Mode connection requested by unknown web server "
+      << host << Debug::flush;
+  return false;
 }
 
-void AllowedConnections::parseRule(const std::string& rule) {
-};
+void AllowedConnections::addRule(const std::string& pattern,
+    bool exclude) {
+  Debug::log(Debug::Spam) << "AllowedConnections::addRule(pattern=" << pattern
+      << ", excl=" << exclude << ")" << Debug::flush;
+  rules.push_back(AllowedConnections::Rule(pattern, exclude));
+}
+
+void AllowedConnections::clearRules() {
+  rules.clear();
+}
+
+void AllowedConnections::initFromAccessList(const std::string& accessList) {
+  clearRules();
+  int n = accessList.length();
+  for (int i = 0; i < n; ) {
+    bool exclude = false;
+    if (accessList[i] == '!') {
+      exclude = true;
+      ++i;
+    }
+    int comma = i - 1; // for pre-increment below
+    while (++comma < n && accessList[comma] != ','); // empty
+    addRule(accessList.substr(i, comma - i), exclude);
+    i = comma + 1;
+  }
+}
diff --git a/plugins/common/AllowedConnections.h b/plugins/common/AllowedConnections.h
index ff48693..46c74e0 100644
--- a/plugins/common/AllowedConnections.h
+++ b/plugins/common/AllowedConnections.h
@@ -17,6 +17,8 @@
  */
 
 #include <string>
+#include <vector>
+#include <utility>
 
 /**
  * Manages rules to control access to other sites from the plugin.  This is
@@ -26,26 +28,75 @@
  */
 class AllowedConnections {
 public:
-  AllowedConnections() {
-    init();
-  }
+  /**
+   * Add a rule to match new requests against.
+   *
+   * @param pattern pattern to match
+   * @param exclude true if matches should be excluded instead of included
+   */
+  static void addRule(const std::string& pattern, bool exclude = false);
 
-  AllowedConnections(const std::string& rule) {
-    init();
-    parseRule(rule);
+  /**
+   * Clear all rules.
+   */
+  static void clearRules();
+
+  /**
+   * Get the host portion of the URL, not including the port.
+   *
+   * @return the host portion of the URL, or the unmodified URL if it does not
+   *     appear to be valid
+   */
+  static std::string getHostFromUrl(const std::string& url);
+
+  /**
+   * Clear any existing rules and reinitialize from the supplied access list.
+   *
+   * This access list is of the form:
+   *    [!]pattern,[!]pattern...
+   * where the optional exclamation indicates the following pattern is to be
+   * excluded, and an arbitrary number of patterns may be supplied with the
+   * first match being used.  Each pattern currently is only an exact literal
+   * match against the host name, but will be extended to support simple
+   * wildcard patterns.
+   */
+  static void initFromAccessList(const std::string& accessList);
+
+  /**
+   * Returns true if the server for the requested URL matched any rule in
+   * our access list, and sets a flag based on whether that rule permits or
+   * denies the request.  A host name of localhost or 127.0.0.1 is always
+   * allowed.
+   *
+   * @param url url of page initiating connection
+   * @param allowed pointer to return value indiciating that this URL should
+   *     be allowed to initiate GWT development mode connections
+   * @return true if url matched a rule
+   */
+  static bool matchesRule(const std::string& url, bool* allowed);
+
+private:
+  AllowedConnections() {
   }
 
   /**
-   * Returns true if a connection to the requested target is allowed.
-   *
-   * @param host name or address to connect to
-   * @param port TCP port to connect to
+   * Internal class used for representing a rule.
    */
-  bool isAllowed(const char* host, int port);
+  class Rule : std::pair<std::string, bool> {
+  public:
+    Rule(const std::string& pattern, bool exclude)
+        : std::pair<std::string, bool>(pattern, exclude) {}
 
-private:
-  void init();
-  void parseRule(const std::string& rule);
+    const std::string& getPattern() const {
+      return first;
+    }
+
+    bool isExcluded() const {
+      return second;
+    }
+  };
+
+  static std::vector<Rule> rules;
 };
 
 #endif
diff --git a/plugins/common/HostChannel.cpp b/plugins/common/HostChannel.cpp
index 53272da..90552a4 100644
--- a/plugins/common/HostChannel.cpp
+++ b/plugins/common/HostChannel.cpp
@@ -57,23 +57,20 @@
 ByteOrder HostChannel::byteOrder;
 
 bool HostChannel::connectToHost(const char* host, unsigned port) {
-  Debug::log(Debug::Info) << "Initiating GWT hosted mode connection to host "
-      << host << ", port " << port << Debug::flush;
   if (!port) {
     port = 9997;
   }
-  if (!whitelist.isAllowed(host, port)) {
-    Debug::log(Debug::Error) << "Permission to connect to " << host << ":" << port
-        << " denied" << Debug::flush;
-    return false;
-  }
+  Debug::log(Debug::Info)
+      << "Initiating GWT Development Mode connection to host " << host
+      << ", port " << port << Debug::flush;
   return sock.connect(host, port);
 }
 
 bool HostChannel::init(SessionHandler* handler, int minProtoVers,
     int maxProtoVers, const std::string& hostedHtmlVers) {
-  Debug::log(Debug::Info) << "initializing connection: proto=" << minProtoVers
-      << "-" << maxProtoVers << ", hostedHtmlVersion=" << hostedHtmlVers
+  Debug::log(Debug::Debugging)
+      << "  negotiating versions - we support protocol " << minProtoVers
+      << " through " << maxProtoVers << ", hostedHtmlVersion=" << hostedHtmlVers
       << Debug::flush;
   // TODO(jat): support transport selection
   CheckVersionsMessage::send(*this, minProtoVers, maxProtoVers, hostedHtmlVers);
diff --git a/plugins/common/HostChannel.h b/plugins/common/HostChannel.h
index 8facabe..f104d63 100644
--- a/plugins/common/HostChannel.h
+++ b/plugins/common/HostChannel.h
@@ -24,7 +24,6 @@
 
 #include "ByteOrder.h"
 #include "Socket.h"
-#include "AllowedConnections.h"
 #include "Platform.h"
 #include "Message.h"
 #include "ReturnMessage.h"
@@ -33,7 +32,6 @@
 
 class HostChannel {
   Socket sock;
-  AllowedConnections whitelist;
   static ByteOrder byteOrder;
 
 public:
diff --git a/plugins/common/Makefile b/plugins/common/Makefile
index abfd933..4003274 100644
--- a/plugins/common/Makefile
+++ b/plugins/common/Makefile
@@ -42,7 +42,9 @@
 	$(AR) $(ARFLAGS) $@ $(OBJS)
 
 $(OBJDIR)/%.o: %.cpp
-	$(CXX) $(CXXFLAGS) -c $< -o $@
+	$(CXX) $(BASECFLAGS) $(ALLARCHCFLAGS) -c $< -o $@
+
+$(OBJDIR)/%.o: DebugLevel.h
 
 .PHONY: clean depend testdebug
 
diff --git a/plugins/config.mk b/plugins/config.mk
index 5e4ff14..f07dfd5 100644
--- a/plugins/config.mk
+++ b/plugins/config.mk
@@ -69,16 +69,24 @@
 MARCH=$(ARCH)
 ifeq ($(ARCH),x86)
 MARCH=i386
+OMARCH=ppc
+endif
+ifeq ($(ARCH),ppc)
+OMARCH=i386
 endif
 
 # Set OS as well as CFLAGS, CXX, and other common make variables
 ifeq ($(shell uname),Linux)
 OS=linux
-CFLAGS= -g -O2 -fPIC $(INC) -rdynamic -m$(FLAG32BIT)
+BASECFLAGS= -g -O2 -fPIC $(INC) -rdynamic
+ARCHCFLAGS=-m$(FLAG32BIT)
+ALLARCHCFLAGS=$(ARCHCFLAGS)
 endif
 ifeq ($(shell uname),Darwin)
 OS=mac
-CFLAGS= -g -O2 -fPIC $(INC) -D__mac -arch $(MARCH)
+BASECFLAGS= -g -O2 -fPIC $(INC) -D__mac
+ARCHCFLAGS=-arch $(MARCH)
+ALLARCHCFLAGS=-arch i386 -arch ppc
 AR=libtool
 ARFLAGS=-static -o
 endif
@@ -88,7 +96,10 @@
 # SunC appears to miscompile Socket::writeByte by not incrementing the
 # buffer pointer, so no optimization for now
 #CFLAGS=-g -Kpic $(INC) -Bdynamic -noex
-CFLAGS= -g0 -Kpic -noex -xO1 -xlibmil -xlibmopt -features=tmplife -xbuiltin=%all -mt $(INC)
+BASECFLAGS= -g0 -Kpic -noex -xO1 -xlibmil -xlibmopt -features=tmplife -xbuiltin=%all -mt $(INC)
+ARCHCFLAGS=
+ALLARCHCFLAGS=
 CXX= CC
 endif
-CXXFLAGS = $(CFLAGS)
+CFLAGS=$(BASECFLAGS) $(ARCHCFLAGS)
+CXXFLAGS = $(CFLAGS) 
diff --git a/plugins/ie/oophm/oophm.sln b/plugins/ie/oophm/oophm.sln
index e5d9fea..6bb8d36 100644
--- a/plugins/ie/oophm/oophm.sln
+++ b/plugins/ie/oophm/oophm.sln
@@ -1,6 +1,6 @@
 

-Microsoft Visual Studio Solution File, Format Version 10.00

-# Visual Studio 2008

+Microsoft Visual Studio Solution File, Format Version 9.00

+# Visual Studio 2005

 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "oophm", "oophm\oophm.vcproj", "{EB69BDFE-9380-4C51-99E8-C3EB25AE36A2}"

 EndProject

 Global

diff --git a/plugins/ie/oophm/oophm/AllowDialog.cpp b/plugins/ie/oophm/oophm/AllowDialog.cpp
new file mode 100644
index 0000000..6e5672b
--- /dev/null
+++ b/plugins/ie/oophm/oophm/AllowDialog.cpp
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2009 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 "AllowDialog.h"
+#include "Debug.h"
+#include "resource.h"
+
+HINSTANCE AllowDialog::hInstance;
+
+static BOOL CALLBACK allowDialogProc(HWND hwndDlg, UINT message, WPARAM wParam, LPARAM lParam) {
+  if (message != WM_COMMAND) {
+    return false;
+  }
+  bool allowed;
+  switch (LOWORD(wParam)) {
+    case IDCANCEL:
+      allowed = false;
+      break;
+    case IDC_ALLOW_BUTTON:
+      allowed = true;
+      break;
+    default:
+      // ignore anything but buttons which close the dialog
+      return false;
+  }
+  bool remember = IsDlgButtonChecked(hwndDlg, IDC_REMEMBER_CHECKBOX) == BST_CHECKED;
+  int returnVal = (allowed ? 1 : 0) + (remember ? 2 : 0);
+  EndDialog(hwndDlg, (INT_PTR) returnVal);
+  return true;
+}
+
+void AllowDialog::setHInstance(HINSTANCE hInstance) {
+  AllowDialog::hInstance = hInstance;
+}
+
+bool AllowDialog::askUserToAllow(bool* remember) {
+  int result = (int) DialogBox(hInstance, MAKEINTRESOURCE(IDD_ALLOW_DIALOG),
+      NULL, (DLGPROC) allowDialogProc);
+  *remember = (result & 2) != 0;
+  return (result & 1) != 0;
+}
diff --git a/plugins/ie/oophm/oophm/AllowDialog.h b/plugins/ie/oophm/oophm/AllowDialog.h
new file mode 100644
index 0000000..b8d14c8
--- /dev/null
+++ b/plugins/ie/oophm/oophm/AllowDialog.h
@@ -0,0 +1,38 @@
+#ifndef _H_AllowDialog
+#define _H_AllowDialog
+/*
+ * Copyright 2009 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 "stdafx.h"
+
+class AllowDialog {
+public:
+  static void setHInstance(HINSTANCE hInstance);
+
+  /**
+   * Ask the user if a connection should be allowed.
+   *
+   * @param remember *remember is set to true if the user asked us to remember this decision,
+   *     false otherwise
+   * @return return true if this connection should be allowed
+   */
+  static bool askUserToAllow(bool* remember);
+
+private:
+  static HINSTANCE hInstance;
+};
+
+#endif
diff --git a/plugins/ie/oophm/oophm/IESessionHandler.cpp b/plugins/ie/oophm/oophm/IESessionHandler.cpp
index cd0ec68..43c9c90 100644
--- a/plugins/ie/oophm/oophm/IESessionHandler.cpp
+++ b/plugins/ie/oophm/oophm/IESessionHandler.cpp
@@ -46,7 +46,7 @@
 }
 
 void IESessionHandler::fatalError(HostChannel& channel,
-    const std::string& messsage) {
+    const std::string& message) {
   // TODO: better way of reporting error?
   Debug::log(Debug::Error) << "Fatal error: " << message << Debug::flush;
 }
@@ -59,7 +59,7 @@
   javaObjectsToFree.insert(objId);
 }
 
-void IESessionHandler::freeJavaObjects() {
+void IESessionHandler::sendFreeValues(HostChannel& channel) {
   int idCount = javaObjectsToFree.size();
   if (idCount == 0) {
     return;
@@ -73,7 +73,7 @@
     ids[i++] = *it;
   }
 
-  if (!ServerMethods::freeJava(*channel, this, idCount, ids.get())) {
+  if (!ServerMethods::freeJava(channel, this, idCount, ids.get())) {
     Debug::log(Debug::Error) << "Unable to free Java ids on server" << Debug::flush;
   }
   javaObjectsToFree.clear();
@@ -179,9 +179,6 @@
     // Success
     makeValue(*returnValue, retVal);
   }
-
-  // Free previously-collected Java ids on the server to enable re-use
-  freeJavaObjects();
   return exceptionFlag != 0;
 }
 
diff --git a/plugins/ie/oophm/oophm/IESessionHandler.h b/plugins/ie/oophm/oophm/IESessionHandler.h
index 8c035ba..2db361a 100644
--- a/plugins/ie/oophm/oophm/IESessionHandler.h
+++ b/plugins/ie/oophm/oophm/IESessionHandler.h
@@ -43,6 +43,8 @@
       int numArgs, const Value* const args, Value* returnValue);
   virtual bool invokeSpecial(HostChannel& channel, SpecialMethodId method, int numArgs,
       const Value* const args, Value* returnValue);
+  virtual void sendFreeValues(HostChannel& channel);
+
 
 private:
   int jsObjectId;
@@ -64,17 +66,12 @@
   std::map<IUnknown*, int> jsIdsByObject;
 
   /*
-  * Send freed Java ids back to the server.
-  */
-  void IESessionHandler::freeJavaObjects();
-
-  /*
-  * Create a JavaScript Error object with the given message.
-  */
+   * Create a JavaScript Error object with the given message.
+   */
   void makeException(_variant_t& value, const char* message);
 
   /*
-  * Create a exception Value that contains the given message.
-  */
+   * Create a exception Value that contains the given message.
+   */
   void makeExceptionValue(Value& value, const char* message);
 };
diff --git a/plugins/ie/oophm/oophm/Preferences.cpp b/plugins/ie/oophm/oophm/Preferences.cpp
new file mode 100644
index 0000000..c16940f
--- /dev/null
+++ b/plugins/ie/oophm/oophm/Preferences.cpp
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2009 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 "stdafx.cpp"
+#include <winnt.h>
+#include <winreg.h>
+#include "Debug.h"
+#include "Preferences.h"
+#include "AllowedConnections.h"
+
+#define REG_ACCESS_LIST "SOFTWARE\\Google\\Google Web Toolkit\\gwt-dmp.accessList"
+
+/**
+ * Return a null-terminated string containing the access list.
+ *
+ * @param HKEY registry key for the access list value
+ * @return null-terminated string containing the access list (an empty string
+ *     if the value does not exist) -- caller is responsible for freeing with
+ *     delete[]
+ */
+static char* getAccessList(HKEY keyHandle) {
+  char *buf;
+  DWORD len = 512;
+  while(true) {
+    buf = new char[len];
+    int cc = RegQueryValueExA(keyHandle, NULL, 0, NULL, (LPBYTE) buf, &len);
+    if (cc == ERROR_SUCCESS) {
+      break;
+    } else if (cc == ERROR_FILE_NOT_FOUND) {
+      // special handling if the value doesn't exist
+      len = 0;
+      break;
+    } else if (cc != ERROR_MORE_DATA) {
+      // log unexpected errors
+      Debug::log(Debug::Error) << "Unable to load access list from registry: "
+          << cc << Debug::flush;
+      len = 0;
+      break;
+    }
+    // Buffer wasn't big enough, so make it bigger and try again
+    delete [] buf;
+    len *= 2;
+  }
+  buf[len] = 0;
+  return buf;
+}
+
+void Preferences::addNewRule(const std::string& pattern, bool exclude) {
+  HKEY keyHandle;
+  if (RegCreateKeyExA(HKEY_CURRENT_USER, REG_ACCESS_LIST, 0, 0,
+      REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &keyHandle, NULL)
+      != ERROR_SUCCESS) {
+    return;
+  }
+  char *buf = getAccessList(keyHandle);
+  std::string pref(buf);
+  delete [] buf;
+  if (pref.length() > 0) {
+    pref += ',';
+  }
+  if (exclude) {
+    pref += '!';
+  }
+  pref += pattern;
+  int cc = RegSetValueExA(keyHandle, NULL, 0, REG_SZ, (LPBYTE) pref.c_str(),
+      pref.length() + 1);
+  if (cc != ERROR_SUCCESS) {
+      Debug::log(Debug::Error) << "Unable to store access list in registry: "
+          << cc << Debug::flush;
+  }
+  RegCloseKey(keyHandle);
+}
+
+void Preferences::loadAccessList() {
+  // TODO(jat): can Reg* routines throw exceptions?  If so, we need to make
+  // this exception safe about closing the key hendle and freeing the buffer.
+  HKEY keyHandle;
+  if (RegCreateKeyExA(HKEY_CURRENT_USER, REG_ACCESS_LIST, 0, 0,
+      REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &keyHandle, NULL)
+      != ERROR_SUCCESS) {
+    return;
+  }
+  char *buf = getAccessList(keyHandle);
+  AllowedConnections::initFromAccessList(buf);
+  delete [] buf;
+  RegCloseKey(keyHandle);
+}
diff --git a/plugins/ie/oophm/oophm/Preferences.h b/plugins/ie/oophm/oophm/Preferences.h
new file mode 100644
index 0000000..f4fc49b
--- /dev/null
+++ b/plugins/ie/oophm/oophm/Preferences.h
@@ -0,0 +1,34 @@
+#ifndef _H_Preferences
+#define _H_Preferences
+/*
+ * Copyright 2009 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 <string>
+
+/**
+ * Deal with getting/storing/updating preferences in the Windows registry.
+ */
+class Preferences {
+private:
+  // prevent instantiation
+  Preferences() {}
+
+public:
+  static void loadAccessList();
+  static void addNewRule(const std::string& pattern, bool exclude);
+};
+
+#endif
diff --git a/plugins/ie/oophm/oophm/Resource.h b/plugins/ie/oophm/oophm/Resource.h
deleted file mode 100644
index d53c63f..0000000
--- a/plugins/ie/oophm/oophm/Resource.h
+++ /dev/null
@@ -1,38 +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.
- */
-
-//{{NO_DEPENDENCIES}}
-// Microsoft Visual C++ generated include file.
-// Used by oophm.rc
-//
-#define IDS_PROJNAME                    100
-#define IDR_OOPHM                       101
-#define IDB_PLUGIN                      102
-#define IDR_PLUGIN                      103
-#define IDH_PLUGIN                      104
-#define IDR_JAVAOBJECT                  105
-#define IDR_EXCEPTIONCATCHER            106
-
-// Next default values for new objects
-// 
-#ifdef APSTUDIO_INVOKED
-#ifndef APSTUDIO_READONLY_SYMBOLS
-#define _APS_NEXT_RESOURCE_VALUE        201
-#define _APS_NEXT_COMMAND_VALUE         32768
-#define _APS_NEXT_CONTROL_VALUE         201
-#define _APS_NEXT_SYMED_VALUE           107
-#endif
-#endif
diff --git a/plugins/ie/oophm/oophm/dlldata.c b/plugins/ie/oophm/oophm/dlldata.c
index 7b86f60..5b71905 100644
--- a/plugins/ie/oophm/oophm/dlldata.c
+++ b/plugins/ie/oophm/oophm/dlldata.c
@@ -1,38 +1,38 @@
-/*********************************************************
-   DllData file -- generated by MIDL compiler 
-
-        DO NOT ALTER THIS FILE
-
-   This file is regenerated by MIDL on every IDL file compile.
-
-   To completely reconstruct this file, delete it and rerun MIDL
-   on all the IDL files in this DLL, specifying this file for the
-   /dlldata command line option
-
-*********************************************************/
-
-#define PROXY_DELEGATION
-
-#include <rpcproxy.h>
-
-#ifdef __cplusplus
-extern "C"   {
-#endif
-
-EXTERN_PROXY_FILE( oophm )
-
-
-PROXYFILE_LIST_START
-/* Start of list */
-  REFERENCE_PROXY_FILE( oophm ),
-/* End of list */
-PROXYFILE_LIST_END
-
-
-DLLDATA_ROUTINES( aProxyFileList, GET_DLL_CLSID )
-
-#ifdef __cplusplus
-}  /*extern "C" */
-#endif
-
-/* end of generated dlldata file */
+/*********************************************************

+   DllData file -- generated by MIDL compiler 

+

+        DO NOT ALTER THIS FILE

+

+   This file is regenerated by MIDL on every IDL file compile.

+

+   To completely reconstruct this file, delete it and rerun MIDL

+   on all the IDL files in this DLL, specifying this file for the

+   /dlldata command line option

+

+*********************************************************/

+

+#define PROXY_DELEGATION

+

+#include <rpcproxy.h>

+

+#ifdef __cplusplus

+extern "C"   {

+#endif

+

+EXTERN_PROXY_FILE( oophm )

+

+

+PROXYFILE_LIST_START

+/* Start of list */

+  REFERENCE_PROXY_FILE( oophm ),

+/* End of list */

+PROXYFILE_LIST_END

+

+

+DLLDATA_ROUTINES( aProxyFileList, GET_DLL_CLSID )

+

+#ifdef __cplusplus

+}  /*extern "C" */

+#endif

+

+/* end of generated dlldata file */

diff --git a/plugins/ie/oophm/oophm/dllmain.cpp b/plugins/ie/oophm/oophm/dllmain.cpp
index 57790ba..e7c6ada 100644
--- a/plugins/ie/oophm/oophm/dllmain.cpp
+++ b/plugins/ie/oophm/oophm/dllmain.cpp
@@ -21,6 +21,7 @@
 #include "oophm_i.h"
 #include "dllmain.h"
 #include "dlldatax.h"
+#include "AllowDialog.h"
 
 CoophmModule _AtlModule;
 
@@ -31,6 +32,6 @@
 	if (!PrxDllMain(hInstance, dwReason, lpReserved))
 		return FALSE;
 #endif
-	hInstance;
+        AllowDialog::setHInstance(hInstance);
 	return _AtlModule.DllMain(dwReason, lpReserved); 
 }
diff --git a/plugins/ie/oophm/oophm/oophm.aps b/plugins/ie/oophm/oophm/oophm.aps
index 74623ca..4b22157 100644
--- a/plugins/ie/oophm/oophm/oophm.aps
+++ b/plugins/ie/oophm/oophm/oophm.aps
Binary files differ
diff --git a/plugins/ie/oophm/oophm/oophm.cpp b/plugins/ie/oophm/oophm/oophm.cpp
index 5435c62..b94b12e 100644
--- a/plugins/ie/oophm/oophm/oophm.cpp
+++ b/plugins/ie/oophm/oophm/oophm.cpp
@@ -56,7 +56,7 @@
         return hr;
     hr = PrxDllRegisterServer();
 #endif
-	return hr;
+    return hr;
 }
 
 
@@ -72,7 +72,7 @@
         return hr;
     hr = PrxDllUnregisterServer();
 #endif
-	return hr;
+    return hr;
 }
 
 // DllInstall - Adds/Removes entries to the system registry per user
@@ -80,6 +80,8 @@
 STDAPI DllInstall(BOOL bInstall, LPCWSTR pszCmdLine)
 {
     HRESULT hr = E_FAIL;
+#if 0
+    // TODO(jat): consider adding this back
     static const wchar_t szUserSwitch[] = _T("user");
 
     if (pszCmdLine != NULL)
@@ -89,6 +91,7 @@
     		AtlSetPerUserRegistration(true);
     	}
     }
+#endif
 
     if (bInstall)
     {	
diff --git a/plugins/ie/oophm/oophm/oophm.rc b/plugins/ie/oophm/oophm/oophm.rc
index 92a62dc..de5890c 100644
--- a/plugins/ie/oophm/oophm/oophm.rc
+++ b/plugins/ie/oophm/oophm/oophm.rc
@@ -1,143 +1,174 @@
-// Microsoft Visual C++ generated resource script.

-//

-#include "resource.h"

-

-#define APSTUDIO_READONLY_SYMBOLS

-/////////////////////////////////////////////////////////////////////////////

-//

-// Generated from the TEXTINCLUDE 2 resource.

-//

-#ifndef APSTUDIO_INVOKED

-#include "targetver.h"

-#endif

-#include "winres.h"

-

-/////////////////////////////////////////////////////////////////////////////

-#undef APSTUDIO_READONLY_SYMBOLS

-

-/////////////////////////////////////////////////////////////////////////////

-// English (U.S.) resources

-

-#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)

-#ifdef _WIN32

-LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US

-#pragma code_page(1252)

-#endif //_WIN32

-

-#ifdef APSTUDIO_INVOKED

-/////////////////////////////////////////////////////////////////////////////

-//

-// TEXTINCLUDE

-//

-

-1 TEXTINCLUDE 

-BEGIN

-    "resource.h\0"

-END

-

-2 TEXTINCLUDE 

-BEGIN

-    "#ifndef APSTUDIO_INVOKED\r\n"

-    "#include ""targetver.h""\r\n"

-    "#endif\r\n"

-    "#include ""winres.h""\r\n"

-    "\0"

-END

-

-3 TEXTINCLUDE 

-BEGIN

-    "1 TYPELIB ""oophm.tlb""\r\n"

-    "\0"

-END

-

-#endif    // APSTUDIO_INVOKED

-

-

-/////////////////////////////////////////////////////////////////////////////

-//

-// Version

-//

-

-VS_VERSION_INFO VERSIONINFO

- FILEVERSION 1,0,0,1

- PRODUCTVERSION 1,0,0,1

- FILEFLAGSMASK 0x3fL

-#ifdef _DEBUG

- FILEFLAGS 0x1L

-#else

- FILEFLAGS 0x0L

-#endif

- FILEOS 0x4L

- FILETYPE 0x2L

- FILESUBTYPE 0x0L

-BEGIN

-    BLOCK "StringFileInfo"

-    BEGIN

-        BLOCK "040904e4"

-        BEGIN

-            VALUE "CompanyName", "Google Inc."

-            VALUE "FileDescription", "Google Web Toolkit Out-of-Process Hosted Mode Plugin"

-            VALUE "FileVersion", "1.0.0.1"

-            VALUE "InternalName", "oophm.dll"

-            VALUE "LegalCopyright", "Copyright 2008 Google Inc. Licensed under the Apache 2.0 license."

-            VALUE "OriginalFilename", "oophm.dll"

-            VALUE "ProductName", "Google Web Toolkit"

-            VALUE "ProductVersion", "1.0.0.1"

-        END

-    END

-    BLOCK "VarFileInfo"

-    BEGIN

-        VALUE "Translation", 0x409, 1252

-    END

-END

-

-

-/////////////////////////////////////////////////////////////////////////////

-//

-// REGISTRY

-//

-

-IDR_OOPHM               REGISTRY                "oophm.rgs"

-IDR_PLUGIN              REGISTRY                "plugin.rgs"

-IDR_JAVAOBJECT          REGISTRY                "JavaObject.rgs"

-IDR_EXCEPTIONCATCHER    REGISTRY                "ExceptionCatcher.rgs"

-

-/////////////////////////////////////////////////////////////////////////////

-//

-// Bitmap

-//

-

-IDB_PLUGIN              BITMAP                  "plugin.bmp"

-

-/////////////////////////////////////////////////////////////////////////////

-//

-// HTML

-//

-

-IDH_PLUGIN              HTML                    "pluginUI.htm"

-

-/////////////////////////////////////////////////////////////////////////////

-//

-// String Table

-//

-

-STRINGTABLE 

-BEGIN

-    IDS_PROJNAME            "oophm"

-END

-

-#endif    // English (U.S.) resources

-/////////////////////////////////////////////////////////////////////////////

-

-

-

-#ifndef APSTUDIO_INVOKED

-/////////////////////////////////////////////////////////////////////////////

-//

-// Generated from the TEXTINCLUDE 3 resource.

-//

-1 TYPELIB "oophm.tlb"

-

-/////////////////////////////////////////////////////////////////////////////

-#endif    // not APSTUDIO_INVOKED

-

+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#ifndef APSTUDIO_INVOKED
+#include "targetver.h"
+#endif
+#include "winres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE 
+BEGIN
+    "resource.h\0"
+END
+
+2 TEXTINCLUDE 
+BEGIN
+    "#ifndef APSTUDIO_INVOKED\r\n"
+    "#include ""targetver.h""\r\n"
+    "#endif\r\n"
+    "#include ""winres.h""\r\n"
+    "\0"
+END
+
+3 TEXTINCLUDE 
+BEGIN
+    "1 TYPELIB ""oophm.tlb""\r\n"
+    "\0"
+END
+
+#endif    // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 1,0,0,1
+ PRODUCTVERSION 1,0,0,1
+ FILEFLAGSMASK 0x3fL
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+    BLOCK "StringFileInfo"
+    BEGIN
+        BLOCK "040904e4"
+        BEGIN
+            VALUE "CompanyName", "Google Inc."
+            VALUE "FileDescription", "Google Web Toolkit Out-of-Process Hosted Mode Plugin"
+            VALUE "FileVersion", "1.0.0.1"
+            VALUE "InternalName", "oophm.dll"
+            VALUE "LegalCopyright", "Copyright 2008 Google Inc. Licensed under the Apache 2.0 license."
+            VALUE "OriginalFilename", "oophm.dll"
+            VALUE "ProductName", "Google Web Toolkit"
+            VALUE "ProductVersion", "1.0.0.1"
+        END
+    END
+    BLOCK "VarFileInfo"
+    BEGIN
+        VALUE "Translation", 0x409, 1252
+    END
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// REGISTRY
+//
+
+IDR_OOPHM               REGISTRY                "oophm.rgs"
+IDR_PLUGIN              REGISTRY                "plugin.rgs"
+IDR_JAVAOBJECT          REGISTRY                "JavaObject.rgs"
+IDR_EXCEPTIONCATCHER    REGISTRY                "ExceptionCatcher.rgs"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Dialog
+//
+
+IDD_ALLOW_DIALOG DIALOGEX 0, 0, 188, 73
+STYLE DS_SYSMODAL | DS_SETFONT | DS_MODALFRAME | DS_3DLOOK | DS_CENTER | WS_POPUP | WS_CAPTION
+EXSTYLE WS_EX_TOPMOST
+CAPTION "GWT Plugin Security Alert"
+FONT 10, "Microsoft Sans Serif", 400, 0, 0x0
+BEGIN
+    CONTROL         "Remember this decision for this server",IDC_REMEMBER_CHECKBOX,
+                    "Button",BS_AUTOCHECKBOX | WS_TABSTOP,30,31,129,10
+    LTEXT           "This web server is trying to initiate a GWT Development\r\nMode Conncetion -- should it be allowed?",IDC_STATIC,10,7,167,19
+    PUSHBUTTON      "Allow",IDC_ALLOW_BUTTON,37,50,50,14
+    DEFPUSHBUTTON   "Deny",IDCANCEL,100,50,50,14
+END
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// DESIGNINFO
+//
+
+#ifdef APSTUDIO_INVOKED
+GUIDELINES DESIGNINFO 
+BEGIN
+    IDD_ALLOW_DIALOG, DIALOG
+    BEGIN
+        LEFTMARGIN, 7
+        RIGHTMARGIN, 181
+        TOPMARGIN, 7
+        BOTTOMMARGIN, 66
+    END
+END
+#endif    // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// HTML
+//
+
+IDH_PLUGIN              HTML                    "pluginUI.htm"
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// String Table
+//
+
+STRINGTABLE 
+BEGIN
+    IDS_PROJNAME            "oophm"
+END
+
+#endif    // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+1 TYPELIB "oophm.tlb"
+
+/////////////////////////////////////////////////////////////////////////////
+#endif    // not APSTUDIO_INVOKED
+
diff --git a/plugins/ie/oophm/oophm/oophm.vcproj b/plugins/ie/oophm/oophm/oophm.vcproj
index 33e662b..2ccde1a 100644
--- a/plugins/ie/oophm/oophm/oophm.vcproj
+++ b/plugins/ie/oophm/oophm/oophm.vcproj
@@ -1,12 +1,11 @@
 <?xml version="1.0" encoding="Windows-1252"?>

 <VisualStudioProject

 	ProjectType="Visual C++"

-	Version="9.00"

+	Version="8.00"

 	Name="oophm"

 	ProjectGUID="{EB69BDFE-9380-4C51-99E8-C3EB25AE36A2}"

 	RootNamespace="oophm"

 	Keyword="AtlProj"

-	TargetFrameworkVersion="196613"

 	>

 	<Platforms>

 		<Platform

@@ -80,6 +79,7 @@
 				RegisterOutput="true"

 				IgnoreImportLibrary="true"

 				AdditionalDependencies="comsuppw.lib ws2_32.lib"

+				OutputFile="..\..\prebuilt\$(ProjectName).dll"

 				LinkIncremental="2"

 				ModuleDefinitionFile=".\oophm.def"

 				GenerateDebugInformation="true"

@@ -105,6 +105,9 @@
 				Name="VCAppVerifierTool"

 			/>

 			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

 				Name="VCPostBuildEventTool"

 			/>

 		</Configuration>

@@ -197,6 +200,9 @@
 				Name="VCAppVerifierTool"

 			/>

 			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

 				Name="VCPostBuildEventTool"

 			/>

 		</Configuration>

@@ -210,6 +216,10 @@
 			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"

 			>

 			<File

+				RelativePath=".\AllowDialog.cpp"

+				>

+			</File>

+			<File

 				RelativePath=".\dlldatax.c"

 				>

 				<FileConfiguration

@@ -282,6 +292,10 @@
 				>

 			</File>

 			<File

+				RelativePath=".\Preferences.cpp"

+				>

+			</File>

+			<File

 				RelativePath=".\stdafx.cpp"

 				>

 				<FileConfiguration

@@ -309,10 +323,22 @@
 					>

 				</File>

 				<File

+					RelativePath="..\..\..\common\CheckVersionsMessage.cpp"

+					>

+				</File>

+				<File

+					RelativePath="..\..\..\common\ChooseTransportMessage.cpp"

+					>

+				</File>

+				<File

 					RelativePath="..\..\..\common\Debug.cpp"

 					>

 				</File>

 				<File

+					RelativePath="..\..\..\common\FatalErrorMessage.cpp"

+					>

+				</File>

+				<File

 					RelativePath="..\..\..\common\FreeValueMessage.cpp"

 					>

 				</File>

@@ -337,6 +363,10 @@
 					>

 				</File>

 				<File

+					RelativePath="..\..\..\common\ProtocolVersionMessage.cpp"

+					>

+				</File>

+				<File

 					RelativePath="..\..\..\common\ReturnMessage.cpp"

 					>

 				</File>

@@ -348,6 +378,10 @@
 					RelativePath="..\..\..\common\Socket.cpp"

 					>

 				</File>

+				<File

+					RelativePath="..\..\..\common\SwitchTransportMessage.cpp"

+					>

+				</File>

 			</Filter>

 		</Filter>

 		<Filter

@@ -356,6 +390,10 @@
 			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"

 			>

 			<File

+				RelativePath=".\AllowDialog.h"

+				>

+			</File>

+			<File

 				RelativePath=".\dlldatax.h"

 				>

 			</File>

@@ -368,6 +406,10 @@
 				>

 			</File>

 			<File

+				RelativePath="..\..\..\common\FatalErrorMessage.h"

+				>

+			</File>

+			<File

 				RelativePath=".\IESessionHandler.h"

 				>

 			</File>

@@ -380,6 +422,10 @@
 				>

 			</File>

 			<File

+				RelativePath=".\Preferences.h"

+				>

+			</File>

+			<File

 				RelativePath=".\Resource.h"

 				>

 			</File>

@@ -407,6 +453,14 @@
 					>

 				</File>

 				<File

+					RelativePath="..\..\..\common\CheckVersionsMessage.h"

+					>

+				</File>

+				<File

+					RelativePath="..\..\..\common\ChooseTransportMessage.h"

+					>

+				</File>

+				<File

 					RelativePath="..\..\..\common\Debug.h"

 					>

 				</File>

@@ -451,6 +505,10 @@
 					>

 				</File>

 				<File

+					RelativePath="..\..\..\common\ProtocolVersionMessage.h"

+					>

+				</File>

+				<File

 					RelativePath="..\..\..\common\QuitMessage.h"

 					>

 				</File>

@@ -471,6 +529,10 @@
 					>

 				</File>

 				<File

+					RelativePath="..\..\..\common\SwitchTransportMessage.h"

+					>

+				</File>

+				<File

 					RelativePath="..\..\..\common\Value.h"

 					>

 				</File>

diff --git a/plugins/ie/oophm/oophm/plugin.cpp b/plugins/ie/oophm/oophm/plugin.cpp
index 5132421..a372cdf 100644
--- a/plugins/ie/oophm/oophm/plugin.cpp
+++ b/plugins/ie/oophm/oophm/plugin.cpp
@@ -24,13 +24,15 @@
 #include "IESessionHandler.h"
 #include "LoadModuleMessage.h"
 #include "ServerMethods.h"
+#include "AllowedConnections.h"
+#include "Preferences.h"
+#include "AllowDialog.h"
 
 // Cplugin
 
-STDMETHODIMP Cplugin::connect(BSTR burl, BSTR sessionKey, BSTR bhostedServer,
+STDMETHODIMP Cplugin::connect(BSTR burl, BSTR bsessionKey, BSTR bhostedServer,
     BSTR bmoduleName, BSTR bhostedHtmlVersion, VARIANT_BOOL* ret)
 {
-  // TODO: Add your implementation code here
   LPOLECLIENTSITE site;
   IOleContainer* container = NULL;
   IHTMLDocument2* doc = NULL;
@@ -44,6 +46,23 @@
   doc->get_parentWindow(&window);
   doc->Release();
 
+  std::string url = BSTRToUTF8(burl);
+  Debug::log(Debug::Debugging) << "OOPHM connect(url=" << url << ")" << Debug::flush;
+  Preferences::loadAccessList();
+  bool allowed = false;
+  if (!AllowedConnections::matchesRule(url, &allowed)) {
+    bool remember;
+    allowed = AllowDialog::askUserToAllow(&remember);
+    if (remember) {
+      std::string host = AllowedConnections::getHostFromUrl(url);
+      Preferences::addNewRule(host, !allowed);
+    }
+  }
+  if (!allowed) {
+    *ret = false;
+    return S_OK;
+  }
+
   std::string hostedServer = BSTRToUTF8(bhostedServer);
   size_t index = hostedServer.find(':');
   if (index == std::string::npos) {
@@ -73,7 +92,6 @@
     return S_OK;
   }
 
-  std::string url = BSTRToUTF8(burl);
   std::string tabKey = ""; // TODO(jat): add support for tab identity
   std::string sessionKey = BSTRToUTF8(bsessionKey);
   std::string moduleName = BSTRToUTF8(bmoduleName);
@@ -92,7 +110,8 @@
   return S_OK;
 }
 
-STDMETHODIMP CPlugin::init(IDispatch* jsniContext, VARIANT_BOOL* ret) {
+STDMETHODIMP Cplugin::init(IDispatch* jsniContext, VARIANT_BOOL* ret) {
+  Debug::log(Debug::Debugging) << "OOPHM init called" << Debug::flush;
   *ret = true;
   return S_OK;
 }
diff --git a/plugins/ie/oophm/oophm/resource.h b/plugins/ie/oophm/oophm/resource.h
new file mode 100644
index 0000000..e0ef5a4
--- /dev/null
+++ b/plugins/ie/oophm/oophm/resource.h
@@ -0,0 +1,24 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by oophm.rc
+//
+#define IDS_PROJNAME                    100
+#define IDR_OOPHM                       101
+#define IDR_PLUGIN                      103
+#define IDD_ALLOW_DIALOG                103
+#define IDH_PLUGIN                      103
+#define IDR_JAVAOBJECT                  105
+#define IDR_EXCEPTIONCATCHER            106
+#define IDC_REMEMBER_CHECKBOX           201
+#define IDC_ALLOW_BUTTON                202
+
+// Next default values for new objects
+// 
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE        202
+#define _APS_NEXT_COMMAND_VALUE         32768
+#define _APS_NEXT_CONTROL_VALUE         204
+#define _APS_NEXT_SYMED_VALUE           107
+#endif
+#endif
diff --git a/plugins/ie/prebuilt/oophm.dll b/plugins/ie/prebuilt/oophm.dll
index 1ae8067..a0fc36f 100644
--- a/plugins/ie/prebuilt/oophm.dll
+++ b/plugins/ie/prebuilt/oophm.dll
Binary files differ
diff --git a/plugins/webkit/Core/WebScriptSessionHandler.cpp b/plugins/webkit/Core/WebScriptSessionHandler.cpp
index 82fb820..2cc288b 100644
--- a/plugins/webkit/Core/WebScriptSessionHandler.cpp
+++ b/plugins/webkit/Core/WebScriptSessionHandler.cpp
@@ -92,12 +92,12 @@
 }
 
 void WebScriptSessionHandler::fatalError(HostChannel& channel,
-    const std::string& messsage) {
+    const std::string& message) {
   // TODO: better way of reporting error?
   Debug::log(Debug::Error) << "Fatal error: " << message << Debug::flush;
 }
 
-void WebScriptSessionHandler::freeJavaObjects() {
+void WebScriptSessionHandler::sendFreeValues(HostChannel& channel) {
   pthread_mutex_lock(&javaObjectsLock);
   int idCount = javaObjectsToFree.size();
   if (idCount == 0) {
@@ -110,7 +110,7 @@
   for (int i = 0; i < idCount; it++) {
     ids[i++] = *it;
   }
-  if (!ServerMethods::freeJava(*channel, this, idCount, ids)) {
+  if (!ServerMethods::freeJava(channel, this, idCount, ids)) {
     Debug::log(Debug::Error) << "Unable to free Java ids" << Debug::flush;
   } else {
     Debug::log(Debug::Debugging) << "Freed " << idCount << " Java ids" << Debug::flush;
@@ -189,9 +189,6 @@
                                              thisObjJs, numArgs, argsJS,
                                              &localException);
 
-  // It's safe to free remote objects before sending an Invoke or a Return message
-  freeJavaObjects();
-
   if (localException) {
     Debug::log(Debug::Spam) << "Returning exception to server" << Debug::flush;
     makeValue(*returnValue, localException);
diff --git a/plugins/webkit/Core/WebScriptSessionHandler.h b/plugins/webkit/Core/WebScriptSessionHandler.h
index ba6a9c6..486f523 100644
--- a/plugins/webkit/Core/WebScriptSessionHandler.h
+++ b/plugins/webkit/Core/WebScriptSessionHandler.h
@@ -88,13 +88,14 @@
   JSValueRef makeException(const char* message);
 
 protected:
-  virtual void fatalError(HostChannel& channel, const std::string& messsage);
+  virtual void fatalError(HostChannel& channel, const std::string& message);
   virtual void freeValue(HostChannel& channel, int idCount, const int* ids);
   virtual void loadJsni(HostChannel& channel, const std::string& js);
   virtual bool invoke(HostChannel& channel, const Value& thisObj, const std::string& methodName,
                       int numArgs, const Value* const args, Value* returnValue);
   virtual bool invokeSpecial(HostChannel& channel, SpecialMethodId method, int numArgs,
                              const Value* const args, Value* returnValue);
+  virtual void sendFreeValues(HostChannel& channel);
 
 private:
   CrashHandlerRef const crashHandler;
diff --git a/plugins/webkit/Info.plist b/plugins/webkit/Info.plist
index 7b8e8a0..cb71921 100644
--- a/plugins/webkit/Info.plist
+++ b/plugins/webkit/Info.plist
@@ -23,16 +23,16 @@
 	<key>NSPrincipalClass</key>
 	<string>OophmPlugin</string>
 	<key>WebPluginDescription</key>
-	<string>Google Web Toolkit Out-Of-Process Hosted Mode plugin</string>
+	<string>Google Web Toolkit Development Mode plugin</string>
 	<key>WebPluginMIMETypes</key>
 	<dict>
 		<key>application/x-gwt-hosted-mode</key>
 		<dict>
 			<key>WebPluginTypeDescription</key>
-			<string>Google Web Toolkit Out-of-Process hosted mode.</string>
+			<string>Google Web Toolkit Development Mode</string>
 		</dict>
 	</dict>
 	<key>WebPluginName</key>
-	<string>GWT OOPHM</string>
+	<string>GWT DMP</string>
 </dict>
 </plist>
diff --git a/plugins/webkit/Plugin/OophmWebScriptObject.mm b/plugins/webkit/Plugin/OophmWebScriptObject.mm
index d5c452f..0b0b288 100644
--- a/plugins/webkit/Plugin/OophmWebScriptObject.mm
+++ b/plugins/webkit/Plugin/OophmWebScriptObject.mm
@@ -25,6 +25,7 @@
 #import "LoadModuleMessage.h"
 #import "OophmWebScriptObject.h"
 #import "SessionHandler.h"
+#import "AllowedConnections.h"
 
 /*
  * This is a helper shim to bridge crash events from the core cpp code to the
@@ -50,8 +51,12 @@
 - (void)connectAlertDidEnd: (NSAlert*)alert
                 returnCode: (int)returnCode
                contextInfo: (void*)contextInfo;
-- (BOOL)doConnectWithHost: (NSString*) host
-               withModule: (NSString*) moduleName;
+- (BOOL)doConnectWithUrl: (NSString*) url
+          withSessionKey: (NSString*) sessionKey
+                withHost: (NSString*) host
+              withModule: (NSString*) moduleName
+   withHostedHtmlVersion: (NSString*) hostedHtmlVersion;
+	
 @end
 
 @implementation OophmWebScriptObject
@@ -106,30 +111,48 @@
               withHost: (NSString*) host
         withModuleName: (NSString*) moduleName
  withHostedHtmlVersion: (NSString*) hostedHtmlVersion {
-  
-  // TODO remove this for production builds
-  Debug::log(Debug::Warning) << "ACLs are currently disabled" << Debug::flush;
-  return [self doConnectWithUrl:url withSessonKey: withHost:host
-       withModule:moduleName withHostedHtmlVersion];
 
   NSUserDefaults* defaults = [NSUserDefaults standardUserDefaults];
 
   // See if authentication has been bypassed
   if ([defaults boolForKey:@"allowAll"]) {
-    return [self doConnectWithUrl:url withSessonKey: withHost:host
-        withModule:moduleName withHostedHtmlVersion];
+    return [self doConnectWithUrl:url withSessionKey:sessionKey withHost:host
+        withModule:moduleName withHostedHtmlVersion:hostedHtmlVersion];
   }
   
-  // Otherwise, check for an explicit entry
+  // TODO(jat): do this only once, refactor to a separate method
   NSArray* allowedHosts = [defaults arrayForKey:@"allowedHosts"];
   if (allowedHosts != nil) {
-    NSArray* hostParts = [host componentsSeparatedByString:@":"];
-    if ([allowedHosts containsObject:[hostParts objectAtIndex:0]]) {
-      return [self doConnectWithHost:host withModule:moduleName];
+    AllowedConnections::clearRules();
+    int n = [allowedHosts count];
+    for (int i = 0; i < n; ++i) {
+      NSString* entry = [allowedHosts objectAtIndex:i];
+      std::string hostName = [entry UTF8String];
+      int len = hostName.length();
+      bool exclude = false;
+      if (len > 0) {
+        if (len > 1 && hostName[0] == '!') {
+          exclude = true;
+          hostName = hostName.substr(1);
+        }
+        AllowedConnections::addRule(hostName, exclude);
+      }
     }
   }
-  
+
+  const std::string urlStr = [url UTF8String];
+  bool allowed = false;
+  if (AllowedConnections::matchesRule(urlStr, &allowed)) {
+    if (allowed) {
+      return [self doConnectWithUrl:url withSessionKey:sessionKey withHost:host
+          withModule:moduleName withHostedHtmlVersion:hostedHtmlVersion];
+    } else {
+      return YES;
+    }
+  }
+
   // Otherwise, bring up an alert dialog
+  // TODO(jat): add an include/exclude option, currently treat as only include
   NSAlert* alert = [NSAlert alertWithMessageText:@"Initiate hosted-mode session"
                                    defaultButton:@"Deny"
                                  alternateButton:nil
@@ -138,14 +161,15 @@
   
   if ([alert respondsToSelector:@selector(setShowsSuppressionButton:)]) {
     [alert setShowsSuppressionButton:YES];
-    [[alert suppressionButton] setTitle:@"Always allow connections to this host"];
+    [[alert suppressionButton] setTitle:@"Remember this decision for this server"];
   } else {
     [[alert addButtonWithTitle:@"Always allow"] setTag:NSAlertAlternateReturn];
   }
   
   NSBundle* bundle = [NSBundle bundleForClass:[OophmWebScriptObject class]];
-  NSArray* contextArray = [[NSArray arrayWithObjects:[host retain],
-                            [moduleName retain], nil] retain];
+	NSArray* contextArray = [[NSArray arrayWithObjects:[url retain],
+      [sessionKey retain], [host retain], [moduleName retain],
+      [hostedHtmlVersion retain], nil] retain];
   NSString* imagePath = [bundle pathForImageResource:@"gwtlogo"];
   if (imagePath != nil) {
     NSImage* img = [[[NSImage alloc] initByReferencingFile:imagePath] autorelease];
@@ -245,20 +269,28 @@
                 returnCode:(int)returnCode
                contextInfo:(void *)contextInfo {
   NSArray* contextArray = (NSArray*) contextInfo;
-  NSString* host = [[contextArray objectAtIndex:0] autorelease];
-  NSString* moduleName = [[contextArray objectAtIndex:1] autorelease];
+  NSString* url = [[contextArray objectAtIndex:0] autorelease];
+  NSString* sessionKey = [[contextArray objectAtIndex:1] autorelease];
+  NSString* host = [[contextArray objectAtIndex:2] autorelease];
+  NSString* moduleName = [[contextArray objectAtIndex:3] autorelease];
+  NSString* hostedHtmlVersion = [[contextArray objectAtIndex:4] autorelease];
   [contextArray release];
   
   if (returnCode == NSAlertDefaultReturn) {
     return;
   } else if (returnCode == NSAlertAlternateReturn ||
-             [alert respondsToSelector:@selector(suppressionButton)] &&
-             [[alert suppressionButton] state] == NSOnState) {
-    NSArray* hostParts = [host componentsSeparatedByString:@":"];
-    [self addAllowedHost:[hostParts objectAtIndex:0]];
+      [alert respondsToSelector:@selector(suppressionButton)] &&
+      [[alert suppressionButton] state] == NSOnState) {
+    // TODO(jat): simplify, handle errors
+    // Get the host part of the URL and store that
+    NSString* server = [[[[[[url componentsSeparatedByString:@"://"]
+        objectAtIndex:1] componentsSeparatedByString:@"/"] objectAtIndex:0]
+        componentsSeparatedByString:@":"] objectAtIndex:0];
+    [self addAllowedHost:server];
   }
 
-  [self doConnectWithHost:host withModule:moduleName];
+  [self doConnectWithUrl:url withSessionKey:sessionKey withHost:host
+      withModule:moduleName withHostedHtmlVersion:hostedHtmlVersion];
 }
 
 - (BOOL)doConnectWithUrl: (NSString*) url
@@ -321,7 +353,7 @@
     
   if (!LoadModuleMessage::send(*_hostChannel, urlStr, tabKeyStr, 
                                sessionKeyStr, moduleNameStr,
-                               "Safari OOPHM", _sessionHandler)) {
+                               "Safari DMP", _sessionHandler)) {
     _hostChannel->disconnectFromHost();
     delete _hostChannel;
     _hostChannel = NULL;
diff --git a/plugins/webkit/oophm.pmdoc/01oophm-contents.xml b/plugins/webkit/oophm.pmdoc/01oophm-contents.xml
index 5c9517c..b0631b2 100644
--- a/plugins/webkit/oophm.pmdoc/01oophm-contents.xml
+++ b/plugins/webkit/oophm.pmdoc/01oophm-contents.xml
@@ -1 +1 @@
-<pkg-contents spec="1.12"><f n="oophm.webplugin" o="root" g="admin" p="16893" pt="/Users/robertvawter/gwt/oophm/plugins/webkit/build/Release/oophm.webplugin" m="true" t="file"><f n="Contents" o="root" g="admin" p="16893"><f n="Info.plist" o="root" g="admin" p="33204"><mod>mode</mod></f><f n="MacOS" o="root" g="admin" p="16893"><f n="oophm" o="root" g="admin" p="33277"><mod>mode</mod></f><mod>mode</mod></f><f n="Resources" o="root" g="admin" p="16893"><f n="English.lproj" o="root" g="admin" p="16893"><f n="crash.html" o="root" g="admin" p="33204"><mod>mode</mod></f><f n="InfoPlist.strings" o="root" g="admin" p="33204"><mod>mode</mod></f><mod>mode</mod></f><f n="gwtlogo.icns" o="root" g="admin" p="33204"><mod>mode</mod></f><f n="README.google" o="root" g="admin" p="33204"><mod>mode</mod></f><mod>mode</mod></f><mod>mode</mod></f><mod>mode</mod></f></pkg-contents>
\ No newline at end of file
+<pkg-contents spec="1.12"><f n="oophm.webplugin" o="root" g="admin" p="16893" pt="/Users/jat/s/gwt-trunk/plugins/webkit/build/Release/oophm.webplugin" m="true" t="file"><f n="Contents" o="root" g="admin" p="16893"><f n="Info.plist" o="root" g="admin" p="33204"><mod>mode</mod></f><f n="MacOS" o="root" g="admin" p="16893"><f n="oophm" o="root" g="admin" p="33277"><mod>mode</mod></f><mod>mode</mod></f><f n="Resources" o="root" g="admin" p="16893"><f n="English.lproj" o="root" g="admin" p="16893"><f n="crash.html" o="root" g="admin" p="33204"><mod>mode</mod></f><f n="InfoPlist.strings" o="root" g="admin" p="33204"><mod>mode</mod></f><mod>mode</mod></f><f n="gwtlogo.icns" o="root" g="admin" p="33204"><mod>mode</mod></f><f n="README.google" o="root" g="admin" p="33204"><mod>mode</mod></f><mod>mode</mod></f><mod>mode</mod></f><mod>mode</mod></f></pkg-contents>
diff --git a/plugins/webkit/oophm.pmdoc/01oophm.xml b/plugins/webkit/oophm.pmdoc/01oophm.xml
index ca52096..1e3122c 100644
--- a/plugins/webkit/oophm.pmdoc/01oophm.xml
+++ b/plugins/webkit/oophm.pmdoc/01oophm.xml
@@ -1 +1 @@
-<pkgref spec="1.12" uuid="417BF300-1147-478E-9359-100836B507EE"><config><identifier>com.google.gwt.oophm.pkg</identifier><version>1</version><description></description><post-install type="none"/><requireAuthorization/><installFrom relative="true" mod="true" includeRoot="true">build/Release/oophm.webplugin</installFrom><installTo mod="true">/Library/Internet Plug-Ins</installTo><flags><followSymbolicLinks/><mod>overwriteDirectoryPermissions</mod></flags><packageStore type="internal"></packageStore><mod>parent</mod><mod>installTo</mod><mod>requireAuthorization</mod><mod>installFrom.isRelativeType</mod><mod>installTo.path</mod><mod>installFrom.path</mod><mod>identifier</mod><mod>includeRoot</mod></config><contents><file-list>01oophm-contents.xml</file-list><component id="com.google.gwt.oophm" path="/Users/robertvawter/gwt/oophm/plugins/webkit/build/Release/oophm.webplugin" version="0.1"/><filter>/CVS$</filter><filter>/\.svn$</filter><filter>/\.cvsignore$</filter><filter>/\.cvspass$</filter><filter>/\.DS_Store$</filter></contents></pkgref>
\ No newline at end of file
+<pkgref spec="1.12" uuid="417BF300-1147-478E-9359-100836B507EE"><config><identifier>com.google.gwt.oophm.pkg</identifier><version>1</version><description></description><post-install type="none"/><requireAuthorization/><installFrom relative="true" mod="true" includeRoot="true">build/Release/oophm.webplugin</installFrom><installTo mod="true">/Library/Internet Plug-Ins</installTo><flags><followSymbolicLinks/><mod>overwriteDirectoryPermissions</mod></flags><packageStore type="internal"></packageStore><mod>parent</mod><mod>installTo</mod><mod>requireAuthorization</mod><mod>installFrom.isRelativeType</mod><mod>installTo.path</mod><mod>installFrom.path</mod><mod>identifier</mod><mod>includeRoot</mod></config><contents><file-list>01oophm-contents.xml</file-list><component id="com.google.gwt.oophm" path="/Users/jat/s/gwt-trunk/plugins/webkit/build/Release/oophm.webplugin" version="0.1"/><filter>/CVS$</filter><filter>/\.svn$</filter><filter>/\.cvsignore$</filter><filter>/\.cvspass$</filter><filter>/\.DS_Store$</filter></contents></pkgref>
diff --git a/plugins/webkit/oophm.pmdoc/index.xml b/plugins/webkit/oophm.pmdoc/index.xml
index 872d10b..99f981a 100644
--- a/plugins/webkit/oophm.pmdoc/index.xml
+++ b/plugins/webkit/oophm.pmdoc/index.xml
@@ -1,4 +1,4 @@
-<pkmkdoc spec="1.12"><properties><title>GWT Out-of-Process Hosted Mode Plugins</title><build>/Users/robertvawter/Desktop/GWT Out-of-Process Hosted Mode Plugin.mpkg</build><organization>com.google.gwt</organization><userSees ui="custom"/><min-target os="2"/><domain system="true"/></properties><distribution><versions min-spec="1.000000"/><scripts></scripts></distribution><contents><choice title="WebKit Plugin" id="webkit" description="This plugin support WebKit-based browsers, such as Safari and Shiira.  Any other application that makes use of WebKit will also be able to load this plugin." starts_selected="true" starts_enabled="true" starts_hidden="false"><pkgref id="com.google.gwt.oophm.pkg"/></choice></contents><resources bg-scale="none" bg-align="bottomleft"><locale lang="en"><resource relative="true" mod="true" type="background">gwtlogo.icns</resource><resource relative="true" mod="true" type="license">../../distro-source/core/src/COPYING.html</resource><resource relative="true" mod="true" type="readme">../../distro-source/core/src/index.html</resource><resource mime-type="text/rtf" kind="embedded" type="welcome"><![CDATA[{\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf270
+<pkmkdoc spec="1.12"><properties><title>GWT Out-of-Process Hosted Mode Plugins</title><build>/Users/jat/Desktop/GWT Out-of-Process Hosted Mode Plugin.mpkg</build><organization>com.google.gwt</organization><userSees ui="custom"/><min-target os="2"/><domain system="true"/></properties><distribution><versions min-spec="1.000000"/><scripts></scripts></distribution><contents><choice title="WebKit Plugin" id="webkit" description="This plugin support WebKit-based browsers, such as Safari and Shiira.  Any other application that makes use of WebKit will also be able to load this plugin." starts_selected="true" starts_enabled="true" starts_hidden="false"><pkgref id="com.google.gwt.oophm.pkg"/></choice></contents><resources bg-scale="none" bg-align="bottomleft"><locale lang="en"><resource relative="true" mod="true" type="background">gwtlogo.icns</resource><resource relative="true" mod="true" type="license">../../distro-source/core/src/COPYING.html</resource><resource relative="true" mod="true" type="readme">../../distro-source/core/src/index.html</resource><resource mime-type="text/rtf" kind="embedded" type="welcome"><![CDATA[{\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf270
 {\fonttbl\f0\fnil\fcharset0 LucidaGrande;}
 {\colortbl;\red255\green255\blue255;}
 \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural\pardirnatural
@@ -12,4 +12,4 @@
 {\colortbl;\red255\green255\blue255;}
 \pard\tx560\tx1120\tx1680\tx2240\tx2800\tx3360\tx3920\tx4480\tx5040\tx5600\tx6160\tx6720\ql\qnatural\pardirnatural
 
-\f0\fs26 \cf0 Restart any WebKit-based browsers in order to use the plugin.}]]></resource></locale></resources><flags/><item type="file">01oophm.xml</item><mod>properties.customizeOption</mod><mod>properties.userDomain</mod><mod>properties.title</mod><mod>description</mod><mod>properties.systemDomain</mod><mod>properties.anywhereDomain</mod></pkmkdoc>
\ No newline at end of file
+\f0\fs26 \cf0 Restart any WebKit-based browsers in order to use the plugin.}]]></resource></locale></resources><flags/><item type="file">01oophm.xml</item><mod>properties.customizeOption</mod><mod>properties.userDomain</mod><mod>properties.title</mod><mod>description</mod><mod>properties.systemDomain</mod><mod>properties.anywhereDomain</mod></pkmkdoc>
diff --git a/plugins/webkit/oophm.xcodeproj/project.pbxproj b/plugins/webkit/oophm.xcodeproj/project.pbxproj
index d788230..1981698 100644
--- a/plugins/webkit/oophm.xcodeproj/project.pbxproj
+++ b/plugins/webkit/oophm.xcodeproj/project.pbxproj
@@ -35,6 +35,11 @@
 /* End PBXAggregateTarget section */
 
 /* Begin PBXBuildFile section */
+		45283765103BCCB100153ABF /* CheckVersionsMessage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 45283764103BCCB100153ABF /* CheckVersionsMessage.cpp */; };
+		4528376F103BCCDF00153ABF /* ChooseTransportMessage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 45283767103BCCDF00153ABF /* ChooseTransportMessage.cpp */; };
+		45283770103BCCDF00153ABF /* FatalErrorMessage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 45283769103BCCDF00153ABF /* FatalErrorMessage.cpp */; };
+		45283771103BCCDF00153ABF /* ProtocolVersionMessage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4528376B103BCCDF00153ABF /* ProtocolVersionMessage.cpp */; };
+		45283772103BCCDF00153ABF /* SwitchTransportMessage.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4528376D103BCCDF00153ABF /* SwitchTransportMessage.cpp */; };
 		480DDCAA0E381E22000711F4 /* AppController.m in Sources */ = {isa = PBXBuildFile; fileRef = 48A23BB50DD0E688004EF5CA /* AppController.m */; };
 		480DDCAB0E381E23000711F4 /* BrowserWindow.m in Sources */ = {isa = PBXBuildFile; fileRef = 48A23C770DD0F545004EF5CA /* BrowserWindow.m */; };
 		480DDCAC0E381E28000711F4 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 48A23BB60DD0E688004EF5CA /* main.m */; };
@@ -105,6 +110,16 @@
 		089C167FFE841241C02AAC07 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = "<absolute>"; };
 		1058C7ADFEA557BF11CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
 		32DBCF630370AF2F00C91783 /* oophm_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = oophm_Prefix.pch; sourceTree = "<group>"; };
+		45283764103BCCB100153ABF /* CheckVersionsMessage.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = CheckVersionsMessage.cpp; sourceTree = "<group>"; };
+		45283766103BCCDF00153ABF /* CheckVersionsMessage.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = CheckVersionsMessage.h; sourceTree = "<group>"; };
+		45283767103BCCDF00153ABF /* ChooseTransportMessage.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ChooseTransportMessage.cpp; sourceTree = "<group>"; };
+		45283768103BCCDF00153ABF /* ChooseTransportMessage.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ChooseTransportMessage.h; sourceTree = "<group>"; };
+		45283769103BCCDF00153ABF /* FatalErrorMessage.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = FatalErrorMessage.cpp; sourceTree = "<group>"; };
+		4528376A103BCCDF00153ABF /* FatalErrorMessage.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = FatalErrorMessage.h; sourceTree = "<group>"; };
+		4528376B103BCCDF00153ABF /* ProtocolVersionMessage.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = ProtocolVersionMessage.cpp; sourceTree = "<group>"; };
+		4528376C103BCCDF00153ABF /* ProtocolVersionMessage.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = ProtocolVersionMessage.h; sourceTree = "<group>"; };
+		4528376D103BCCDF00153ABF /* SwitchTransportMessage.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = SwitchTransportMessage.cpp; sourceTree = "<group>"; };
+		4528376E103BCCDF00153ABF /* SwitchTransportMessage.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = SwitchTransportMessage.h; sourceTree = "<group>"; };
 		48108DDB0E2C15BD007FA76C /* AllowedConnections.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AllowedConnections.cpp; sourceTree = "<group>"; };
 		48108DDC0E2C15BD007FA76C /* AllowedConnections.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AllowedConnections.h; sourceTree = "<group>"; };
 		48108DDD0E2C15BD007FA76C /* Socket.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Socket.cpp; sourceTree = "<group>"; };
@@ -174,7 +189,7 @@
 		48FD99530DC6349F00E011A2 /* OophmWebScriptObject.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = OophmWebScriptObject.mm; sourceTree = "<group>"; };
 		48FFCFC80DD35DA900805659 /* Platform.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Platform.h; sourceTree = "<group>"; };
 		8D5B49B6048680CD000E48DA /* oophm.webplugin */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = oophm.webplugin; sourceTree = BUILT_PRODUCTS_DIR; };
-		8D5B49B7048680CD000E48DA /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = Info.plist; sourceTree = "<group>"; };
+		8D5B49B7048680CD000E48DA /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
 		D2F7E65807B2D6F200F64583 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = /System/Library/Frameworks/CoreData.framework; sourceTree = "<absolute>"; };
 /* End PBXFileReference section */
 
@@ -305,6 +320,15 @@
 		4856DF730DCF95B8000BF47C /* common */ = {
 			isa = PBXGroup;
 			children = (
+				45283766103BCCDF00153ABF /* CheckVersionsMessage.h */,
+				45283767103BCCDF00153ABF /* ChooseTransportMessage.cpp */,
+				45283768103BCCDF00153ABF /* ChooseTransportMessage.h */,
+				45283769103BCCDF00153ABF /* FatalErrorMessage.cpp */,
+				4528376A103BCCDF00153ABF /* FatalErrorMessage.h */,
+				4528376B103BCCDF00153ABF /* ProtocolVersionMessage.cpp */,
+				4528376C103BCCDF00153ABF /* ProtocolVersionMessage.h */,
+				4528376D103BCCDF00153ABF /* SwitchTransportMessage.cpp */,
+				4528376E103BCCDF00153ABF /* SwitchTransportMessage.h */,
 				48C9EA440E37863700E691C6 /* FreeValueMessage.cpp */,
 				48C9EA450E37863700E691C6 /* FreeValueMessage.h */,
 				48C9EA460E37863700E691C6 /* InvokeSpecialMessage.cpp */,
@@ -335,6 +359,7 @@
 				4856DF850DCF95B8000BF47C /* ServerMethods.h */,
 				4856DF860DCF95B8000BF47C /* SessionHandler.h */,
 				4856DF880DCF95B8000BF47C /* Value.h */,
+				45283764103BCCB100153ABF /* CheckVersionsMessage.cpp */,
 			);
 			name = common;
 			path = ../common;
@@ -370,8 +395,8 @@
 				48FD988E0DC62E7400E011A2 /* OophmPlugin.h */,
 				48FD988F0DC62E7400E011A2 /* OophmPlugin.mm */,
 				48FD99520DC6349F00E011A2 /* OophmWebScriptObject.h */,
-				48FD99530DC6349F00E011A2 /* OophmWebScriptObject.mm */,
 				485505EB0DCD475C0009536F /* SlowScriptProxy.h */,
+				48FD99530DC6349F00E011A2 /* OophmWebScriptObject.mm */,
 				485505EC0DCD475C0009536F /* SlowScriptProxy.m */,
 				48FD989B0DC62F8800E011A2 /* WebFrameNonTigerHeaders.h */,
 				48547F490DD88D110047AC8A /* NSMutableString+HtmlReplacement.h */,
@@ -492,8 +517,7 @@
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			shellPath = /bin/sh;
-			shellScript = "set -x\n# This is because the PackageMaker definition has \"Release\" hard-coded into it\nif [ \"${CONFIGURATION}\" != \"Release\" ]; then\n  echo error: Must be in Release configuration to build disk image\n  exit 1\nfi\n\n/Developer/Applications/Utilities/PackageMaker.app/Contents/MacOS/PackageMaker --doc \"${PROJECT_DIR}/oophm.pmdoc\" --out \"${TEMP_FILES_DIR}/oophm.mpkg\"\n\nhdiutil create -ov -srcfolder \"${TEMP_FILES_DIR}/oophm.mpkg\" -format UDBZ \"${BUILT_PRODUCTS_DIR}/oophm.dmg\"\nhdiutil internet-enable \"${BUILT_PRODUCTS_DIR}/oophm.dmg\"";
-			showEnvVarsInLog = 0;
+			shellScript = "#set -x\n## This is because the PackageMaker definition has \"Release\" hard-coded into it\n#if [ \"${CONFIGURATION}\" != \"Release\" ]; then\n#  echo error: Must be in Release configuration to build disk image\n#  exit 1\n#fi\n#\n#/Developer/Applications/Utilities/PackageMaker.app/Contents/MacOS/PackageMaker --doc \"${PROJECT_DIR}/oophm.pmdoc\" --out \"${TEMP_FILES_DIR}/oophm.mpkg\"\n#\n#hdiutil create -ov -srcfolder \"${TEMP_FILES_DIR}/oophm.mpkg\" -format UDBZ \"${BUILT_PRODUCTS_DIR}/oophm.dmg\"\n#hdiutil internet-enable \"${BUILT_PRODUCTS_DIR}/oophm.dmg\"";
 		};
 		48547E020DD882170047AC8A /* Make symlink */ = {
 			isa = PBXShellScriptBuildPhase;
@@ -509,8 +533,7 @@
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 			shellPath = /bin/sh;
-			shellScript = "set -x\nln -sf \"${BUILT_PRODUCTS_DIR}/oophm.webplugin\" \"${USER_LIBRARY_DIR}/Internet Plug-Ins/.\"";
-			showEnvVarsInLog = 0;
+			shellScript = "#set -x\n#ln -sf \"${BUILT_PRODUCTS_DIR}/oophm.webplugin\" \"${USER_LIBRARY_DIR}/Internet Plug-Ins/.\"";
 		};
 /* End PBXShellScriptBuildPhase section */
 
@@ -549,6 +572,11 @@
 				48C9EA4A0E37863700E691C6 /* FreeValueMessage.cpp in Sources */,
 				48C9EA4B0E37863700E691C6 /* InvokeSpecialMessage.cpp in Sources */,
 				48C9EA4C0E37863700E691C6 /* LoadJsniMessage.cpp in Sources */,
+				45283765103BCCB100153ABF /* CheckVersionsMessage.cpp in Sources */,
+				4528376F103BCCDF00153ABF /* ChooseTransportMessage.cpp in Sources */,
+				45283770103BCCDF00153ABF /* FatalErrorMessage.cpp in Sources */,
+				45283771103BCCDF00153ABF /* ProtocolVersionMessage.cpp in Sources */,
+				45283772103BCCDF00153ABF /* SwitchTransportMessage.cpp in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
diff --git a/plugins/webkit/prebuilt/oophm.dmg b/plugins/webkit/prebuilt/oophm.dmg
index 54fd2d9..7931c00 100644
--- a/plugins/webkit/prebuilt/oophm.dmg
+++ b/plugins/webkit/prebuilt/oophm.dmg
Binary files differ
diff --git a/plugins/xpcom/ExternalWrapper.cpp b/plugins/xpcom/ExternalWrapper.cpp
index 1d54747..afb7040 100644
--- a/plugins/xpcom/ExternalWrapper.cpp
+++ b/plugins/xpcom/ExternalWrapper.cpp
@@ -22,6 +22,7 @@
 #include "nsCOMPtr.h"
 #include "nsMemory.h"
 #include "nsServiceManagerUtils.h"
+#include "nsIPromptService.h"
 
 #ifndef NS_IMPL_ISUPPORTS2_CI
 #include "nsIClassInfoImpl.h" // 1.9 only
@@ -30,11 +31,20 @@
 #include "LoadModuleMessage.h"
 #include "ServerMethods.h"
 #include "BrowserChannel.h"
+#include "AllowedConnections.h"
 
 NS_IMPL_ISUPPORTS2_CI(ExternalWrapper, IOOPHM, nsISecurityCheckedComponent)
 
 ExternalWrapper::ExternalWrapper() {
-  Debug::log(Debug::Spam) << "ExternalWrapper::ExternalWrapper()" << Debug::flush;
+  Debug::log(Debug::Spam) << "ExternalWrapper::ExternalWrapper()"
+      << Debug::flush;
+  preferences = new Preferences();
+  windowWatcher = do_GetService(NS_WINDOWWATCHER_CONTRACTID);
+  if (!windowWatcher) {
+    Debug::log(Debug::Warning) << "Can't get WindowWatcher service"
+        << Debug::flush;
+    return;
+  }
 }
 
 ExternalWrapper::~ExternalWrapper() {
@@ -59,13 +69,60 @@
   return NS_OK;
 }
 
-// TODO: handle context object passed in (currently nsIDOMWindow below)
-NS_IMETHODIMP ExternalWrapper::Init(nsIDOMWindow* domWindow, PRBool *_retval) {
+std::string ExternalWrapper::computeTabIdentity() {
+  std::string returnVal;
+  if (!windowWatcher) {
+    return returnVal;
+  }
+  nsCOMPtr<nsIDOMWindow> topWindow(domWindow);
+  if (topWindow->GetTop(getter_AddRefs(topWindow)) != NS_OK) {
+    Debug::log(Debug::Warning) << "Unable to get top window" << Debug::flush;
+    return returnVal;
+  }
+  nsCOMPtr<nsIWebBrowserChrome> chrome;
+  if (windowWatcher->GetChromeForWindow(topWindow.get(),
+      getter_AddRefs(chrome)) != NS_OK) {
+    Debug::log(Debug::Warning) << "Unable to get browser chrome for window"
+        << Debug::flush;
+    return returnVal;
+  }
+  Debug::log(Debug::Debugging) << "computeTabIdentity: browserChrome = "
+      << (void*) chrome.get() << Debug::flush;
+  // TODO(jat): find a way to get the tab from the chrome window
+  return returnVal;
+}
+
+NS_IMETHODIMP ExternalWrapper::Init(nsIDOMWindow* domWindow,
+    PRBool *_retval) {
   Debug::log(Debug::Spam) << "Init" << Debug::flush;
+  this->domWindow = domWindow;
   *_retval = true;
   return NS_OK;
 }
 
+bool ExternalWrapper::askUserToAllow(const std::string& url) {
+  nsCOMPtr<nsIPromptService> promptService = do_GetService(
+      "@mozilla.org/embedcomp/prompt-service;1");
+  if (!promptService) {
+    return false;
+  }
+  NS_ConvertASCIItoUTF16 title("Allow GWT Development Mode Connection");
+  NS_ConvertASCIItoUTF16 text("This web server is requesting a GWT "
+      "development mode connection -- do you want to allow it?");
+  NS_ConvertASCIItoUTF16 checkMsg("Remember this decision for this server "
+      "(change in GWT plugin preferences)");
+  PRBool remember = false;
+  PRBool include = true;
+  if (promptService->ConfirmCheck(domWindow.get(), title.get(), text.get(),
+      checkMsg.get(), &remember, &include) != NS_OK) {
+    return false;
+  }
+  if (remember) {
+    preferences->addNewRule(AllowedConnections::getHostFromUrl(url), !include);
+  }
+  return include;
+}
+
 NS_IMETHODIMP ExternalWrapper::Connect(const nsACString& url,
 		const nsACString& sessionKey, const nsACString& aAddr,
 		const nsACString& aModuleName, const nsACString& hostedHtmlVersion,
@@ -81,6 +138,17 @@
   nsCString moduleAutoStr(aModuleName);
   nsCString hostedHtmlVersionAutoStr(hostedHtmlVersion);
   std::string hostedUrl(addrAutoStr.get());
+  std::string urlStr(urlAutoStr.get());
+
+  bool allowed = false;
+  if (!AllowedConnections::matchesRule(urlStr, &allowed)) {
+    // If we didn't match an existing rule, prompt the user
+    allowed = askUserToAllow(urlStr);
+  }
+  if (!allowed) {
+    *_retval = false;
+    return NS_OK;
+  }
 
   size_t index = hostedUrl.find(':');
   if (index == std::string::npos) {
@@ -120,8 +188,7 @@
     return res;
   }
 
-  std::string urlStr(urlAutoStr.get());
-  std::string tabKeyStr(""); // TODO(jat): add support for tab identity
+  std::string tabKeyStr = computeTabIdentity();
   std::string sessionKeyStr(sessionKeyAutoStr.get());
 
   LoadModuleMessage::send(*channel, urlStr, tabKeyStr, sessionKeyStr,
diff --git a/plugins/xpcom/ExternalWrapper.h b/plugins/xpcom/ExternalWrapper.h
index a21204c..d840827 100755
--- a/plugins/xpcom/ExternalWrapper.h
+++ b/plugins/xpcom/ExternalWrapper.h
@@ -2,13 +2,13 @@
 #define _H_ExternalWrapper
 /*
  * 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
@@ -22,11 +22,16 @@
 
 #include "IOOPHM.h"
 
+#include "Preferences.h"
 #include "FFSessionHandler.h"
 #include "Debug.h"
 #include "scoped_ptr/scoped_ptr.h"
+
+#include "nsCOMPtr.h"
 #include "nsISecurityCheckedComponent.h"
 #include "nsStringAPI.h"
+#include "nsIWindowWatcher.h"
+#include "nsIDOMWindow.h"
 
 class nsIDOMWindow;
 
@@ -45,9 +50,28 @@
   NS_DECL_NSISECURITYCHECKEDCOMPONENT
 
   ExternalWrapper();
-  virtual ~ExternalWrapper(); 
+  virtual ~ExternalWrapper();
+
 private:
+  nsCOMPtr<nsIDOMWindow> domWindow;
+  nsCOMPtr<Preferences> preferences;
   scoped_ptr<FFSessionHandler> sessionHandler;
+  nsCOMPtr<nsIWindowWatcher> windowWatcher;
+
+  /**
+   * Prompt the user whether a connection should be allowed, and optionally
+   * update the preferences.
+   */
+  bool askUserToAllow(const std::string& url);
+
+  /**
+   * Compute a stable tab identity value for the DOM window.
+   *
+   * @return a unique tab identifier which is stable across reloads, or an
+   *     empty string if it cannot be computed
+   */
+  std::string computeTabIdentity();
+
 };
 
 inline Debug::DebugStream& operator<<(Debug::DebugStream& dbg, const nsACString& str) {
diff --git a/plugins/xpcom/FFSessionHandler.cpp b/plugins/xpcom/FFSessionHandler.cpp
index 2d74fbe..06a4534 100755
--- a/plugins/xpcom/FFSessionHandler.cpp
+++ b/plugins/xpcom/FFSessionHandler.cpp
@@ -24,9 +24,11 @@
 #include "RootedObject.h"
 #include "InvokeMessage.h"
 #include "ServerMethods.h"
+#include "AllowedConnections.h"
 
 #include "jsapi.h"
 #include "nsCOMPtr.h"
+#include "nsStringAPI.h"
 #include "nsIJSContextStack.h"
 #include "nsIPrincipal.h"
 #include "nsServiceManagerUtils.h"
@@ -45,8 +47,9 @@
   }
 
   if (cx == nsnull) {
-    Debug::log(Debug::Error) << "Null context" << Debug::flush;
-  }  
+    // TODO(jat): figure out why this can be null at plugin unload time
+    Debug::log(Debug::Error) << "GWT DMP: Null JS context" << Debug::flush;
+  }
 
   return cx;
 }
diff --git a/plugins/xpcom/FFSessionHandler.h b/plugins/xpcom/FFSessionHandler.h
index b456dcd..f7fec2b 100755
--- a/plugins/xpcom/FFSessionHandler.h
+++ b/plugins/xpcom/FFSessionHandler.h
@@ -21,6 +21,7 @@
 
 #include "mozincludes.h"
 #include "SessionData.h"
+#include "Preferences.h"
 
 #include "jsapi.h"
 
diff --git a/plugins/xpcom/Makefile b/plugins/xpcom/Makefile
index a1e8186..f36f9dc 100644
--- a/plugins/xpcom/Makefile
+++ b/plugins/xpcom/Makefile
@@ -14,7 +14,7 @@
 
 include ../config.mk
 
-# Make variables intended to be settable fromthe command line:
+# Make variables intended to be settable from the command line:
 #   DEFAULT_FIREFOX_LIBS	points to /usr/lib/firefox or equivalent
 #   PLUGIN_SDKS			points to GWT /plugin-sdks directory
 #   GECKO_PLATFORM		XPCOM ABI (ie, Linux_x86_64-gcc3)
@@ -24,8 +24,8 @@
 DEFAULT_FIREFOX_LIBS ?= /Applications/Firefox.app/Contents/MacOS
 RUN_PATH_FLAG = -executable_path
 DLL_SUFFIX = .dylib
-DLLFLAGS = -bundle -arch i386 -arch ppc
-TARGET_PLATFORM = Darwin_x86-gcc3
+DLLFLAGS = -bundle -arch $(MARCH)
+TARGET_PLATFORM = Darwin_$(ARCH)-gcc3
 # Mac puts multiple architectures into the same files
 GECKO_PLATFORM = Darwin-gcc3
 else
@@ -47,7 +47,7 @@
 export FLAG32BIT
 
 ifeq ($(BROWSER),)
-$(warning Defaulting to FF3 build)
+$(warning Defaulting to FF3 build [set with BROWSER=ff2, ff3, ff3+, or ff35])
 BROWSER=ff3
 endif
 
@@ -89,8 +89,8 @@
 EXTENSION_OUTDIR  = prebuilt/extension-$(BROWSER)
 FF_PLATFORM_DIR   = $(EXTENSION_OUTDIR)/platform/$(TARGET_PLATFORM)
 
-INSTALLER_XPI     = prebuilt/oophm-xpcom-$(BROWSER).xpi
-FF_DLL            = $(OBJ_OUTDIR)/liboophm_$(BROWSER)$(DLL_SUFFIX)
+INSTALLER_XPI     = prebuilt/gwt-dmp-$(BROWSER).xpi
+FF_DLL            = $(OBJ_OUTDIR)/libgwt_dmp_$(BROWSER)$(DLL_SUFFIX)
 #FF_TYPELIB        = build/IOOPHM.xpt
 #FF_HEADER         = $(OBJ_OUTDIR)/IOOPHM.h
 FF_TYPELIB        = prebuilt/extension/components/IOOPHM.xpt
@@ -158,6 +158,7 @@
 		FFSessionHandler.cpp \
 		JavaObject.cpp \
 		JSRunner.cpp \
+		Preferences.cpp \
 		XpcomDebug.cpp
 
 FF_OBJS = $(patsubst %.cpp,$(OBJ_OUTDIR)/%.o,$(SRCS))
@@ -183,10 +184,10 @@
 	$(CXX) -m$(FLAG32BIT) -o $@ $(FF_OBJS) $(COMMON) $(DLLFLAGS) 
 	@mkdir -p $(FF_PLATFORM_DIR)/components
 	cp $(FF_DLL) $(FF_PLATFORM_DIR)/components/
-ifeq ($(OS),mac)
-	@mkdir -p $(subst x86,ppc,$(FF_PLATFORM_DIR))/components
-	cp $(FF_DLL) $(subst x86,ppc,$(FF_PLATFORM_DIR))/components/
-endif
+#ifeq ($(OS),mac)
+#	@mkdir -p $(subst x86,ppc,$(FF_PLATFORM_DIR))/components
+#	cp $(FF_DLL) $(subst x86,ppc,$(FF_PLATFORM_DIR))/components/
+#endif
 
 $(OBJ_OUTDIR)/%.o: %.cpp $(FF_HEADER)
 	$(CXX) $(CXXFLAGS) -c -o $@ -I. -I../common $<
diff --git a/plugins/xpcom/ModuleOOPHM.cpp b/plugins/xpcom/ModuleOOPHM.cpp
index 919d2b3..6fda93c 100644
--- a/plugins/xpcom/ModuleOOPHM.cpp
+++ b/plugins/xpcom/ModuleOOPHM.cpp
@@ -51,7 +51,8 @@
     const char *aLoaderStr, const char *aType,
     const nsModuleComponentInfo *aInfo) {
 
-  Debug::log(Debug::Info) << "Registered GWT hosted mode plugin"
+  Debug::log(Debug::Info)
+      << "  successfully registered GWT Development Mode plugin"
       << Debug::flush;
   nsresult rv;
   nsCOMPtr<nsICategoryManager> categoryManager =
@@ -78,7 +79,7 @@
 static NS_IMETHODIMP unregisterSelf(nsIComponentManager *aCompMgr,
     nsIFile *aPath, const char *aLoaderStr,
     const nsModuleComponentInfo *aInfo) {
-  Debug::log(Debug::Debugging) << "ModuleOOPHM unRegisterSelf()"
+  Debug::log(Debug::Info) << "Unregistered GWT Development Mode plugin"
       << Debug::flush;
   return NS_OK;
 }
@@ -111,7 +112,7 @@
 
 NSGETMODULE_ENTRY_POINT(ExternalWrapperModule) (nsIComponentManager *servMgr,
     nsIFile* location, nsIModule** result) {
-  Debug::log(Debug::Debugging) << "OOPHM ExternalWrapperModule entry point"
+  Debug::log(Debug::Debugging) << "GWT DMP ExternalWrapperModule entry point"
       << Debug::flush;
 
   // CURRENTLY BUILT AS SEPARATE PLUGINS FOR FF1.5/2 and FF3, so the below
@@ -129,7 +130,8 @@
 
   nsCString gecko_version;
   app_info->GetPlatformVersion(gecko_version);
-  Debug::log(Debug::Info) << "  gecko version = "
+  Debug::log(Debug::Info)
+      << "Initializing GWT Development Mode Plugin - gecko version = "
       << gecko_version.BeginReading() << Debug::flush;
 #if defined(BROWSER_FF2)
   if (strncmp(gecko_version.BeginReading(), "1.8", 3) != 0) {
diff --git a/plugins/xpcom/Preferences.cpp b/plugins/xpcom/Preferences.cpp
new file mode 100644
index 0000000..0951711
--- /dev/null
+++ b/plugins/xpcom/Preferences.cpp
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2009 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 "Preferences.h"
+#include "Debug.h"
+#include "AllowedConnections.h"
+
+#include "nsCOMPtr.h"
+#include "nsStringAPI.h"
+#include "nsISupportsImpl.h"
+#include "nsIObserver.h"
+#include "nsIPrefService.h"
+#include "nsIPrefBranch.h"
+#include "nsIPrefBranch2.h"
+#include "nsServiceManagerUtils.h"
+
+#define DMP_PREFS_PREFIX "gwt-dmp."
+#define DMP_ACCESS_LIST "accessList"
+
+NS_IMPL_ADDREF(Preferences)
+NS_IMPL_RELEASE(Preferences)
+NS_IMPL_QUERY_INTERFACE1(Preferences, nsIObserver)
+
+Preferences::Preferences() {
+  nsCOMPtr<nsIPrefService> prefService = do_GetService(
+      NS_PREFSERVICE_CONTRACTID);
+  if (!prefService) {
+    Debug::log(Debug::Error) << "Unable to get preference service" << Debug::flush;
+    return;
+  }
+  nsCOMPtr<nsIPrefBranch> branch;
+  prefService->GetBranch(DMP_PREFS_PREFIX, getter_AddRefs(branch));
+  if (!branch) {
+    Debug::log(Debug::Error) << "Unable to get gwt-dmp. preference branch"
+        << Debug::flush;
+    return;
+  }
+  prefs = do_QueryInterface(branch);
+  if (!prefs) {
+    Debug::log(Debug::Error) << "Unable to get nsIPrefBranch2" << Debug::flush;
+    return;
+  }
+  prefs->AddObserver(DMP_ACCESS_LIST, this, PR_FALSE);
+  nsCString prefValue;
+  if (branch->GetCharPref(DMP_ACCESS_LIST, getter_Copies(prefValue)) == NS_OK) {
+    loadAccessList(prefValue.get());
+  }
+}
+
+// implements nsIObserver
+NS_IMETHODIMP
+Preferences::Observe(nsISupports *aSubject, const char* aTopic,
+    const PRUnichar *aData) {
+  nsresult rv = NS_OK;
+  Debug::log(Debug::Spam) << "Preferences::Observe(subject="
+      << aSubject << ", topic=" << aTopic << ", data=" << aData << Debug::flush;
+  if (strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID)) {
+    return NS_ERROR_UNEXPECTED;
+  }
+  // TODO(jat): check preference name in aData if we ever add another one
+  nsCOMPtr<nsIPrefBranch> prefs(do_QueryInterface(aSubject, &rv));
+  NS_ENSURE_SUCCESS(rv, rv);
+  nsCString prefValue;
+  if (prefs->GetCharPref(DMP_ACCESS_LIST, getter_Copies(prefValue)) == NS_OK) {
+    loadAccessList(prefValue.get());
+  }
+  return NS_OK;
+}
+
+void Preferences::addNewRule(const std::string& pattern, bool exclude) {
+  nsCString prefValue;
+  if (prefs->GetCharPref(DMP_ACCESS_LIST, getter_Copies(prefValue)) != NS_OK) {
+    Debug::log(Debug::Error) << "Unable to retrieve access list preference"
+        << Debug::flush;
+    return;
+  }
+  // TODO(jat): see if the same rule already exists
+  std::string pref(prefValue.get());
+  if (pref.length() > 0) {
+    pref += ',';
+  }
+  if (exclude) {
+    pref += '!';
+  }
+  pref += pattern;
+  if (prefs->SetCharPref(DMP_ACCESS_LIST, pref.c_str()) != NS_OK) {
+    Debug::log(Debug::Error) << "Unable to save modified access list preference"
+        << Debug::flush;
+    return;
+  }
+}
+
+void Preferences::loadAccessList(const char* prefValue) {
+  if (!prefValue) {
+    return;
+  }
+  Debug::log(Debug::Spam) << "loadFromAccessList(prefValue=" << prefValue << ")"
+      << Debug::flush;
+  AllowedConnections::initFromAccessList(prefValue);
+}
+
+Preferences::~Preferences() {
+  if (prefs) {
+    prefs->RemoveObserver(DMP_ACCESS_LIST, this);
+  }
+}
diff --git a/plugins/xpcom/Preferences.h b/plugins/xpcom/Preferences.h
new file mode 100644
index 0000000..bf9a25c
--- /dev/null
+++ b/plugins/xpcom/Preferences.h
@@ -0,0 +1,53 @@
+#ifndef _H_Preferences
+#define _H_Preferences
+/*
+ * Copyright 2009 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 <string>
+
+#include "mozincludes.h"
+
+#include "nsCOMPtr.h"
+#include "nsISupports.h"
+#include "nsIObserver.h"
+#include "nsIPrefBranch2.h"
+
+class HostChannel;
+class Value;
+
+class Preferences : public nsIObserver {
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIOBSERVER
+public:
+  Preferences();
+  virtual ~Preferences();
+
+  /**
+   * Add a new rule to the access list preference.
+   *
+   * @param pattern pattern to add (currently only an exact-match literal)
+   * @param exclude true if the pattern should be excluded from matches,
+   *     otherwise included
+   */
+  void addNewRule(const std::string& pattern, bool exclude);
+
+private:
+  static void loadAccessList(const char*);
+
+  nsCOMPtr<nsIPrefBranch2> prefs;
+};
+
+#endif
diff --git a/plugins/xpcom/UserAgents.txt b/plugins/xpcom/UserAgents.txt
new file mode 100644
index 0000000..28d70ae
--- /dev/null
+++ b/plugins/xpcom/UserAgents.txt
@@ -0,0 +1,8 @@
+User agents that work with ff3 XPI:
+===================================
+Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.13) Gecko/2009080315 Ubuntu/9.04 (jaunty) Firefox/3.08
+
+User agents that work with ff3+ XPI:
+====================================
+Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.0.12) Gecko/2009072110 Fedora/3.0.12-1.fc10 Firefox/3.0.12
+
diff --git a/plugins/xpcom/VisualStudio/ff2-xpcom.vcproj b/plugins/xpcom/VisualStudio/ff2-xpcom.vcproj
index 6d71ac0..50674b5 100755
--- a/plugins/xpcom/VisualStudio/ff2-xpcom.vcproj
+++ b/plugins/xpcom/VisualStudio/ff2-xpcom.vcproj
@@ -1,12 +1,11 @@
 <?xml version="1.0" encoding="UTF-8"?>

 <VisualStudioProject

 	ProjectType="Visual C++"

-	Version="9.00"

+	Version="8.00"

 	Name="ff2-xpcom"

 	ProjectGUID="{6BF0C2CE-CB0C-421B-A67C-1E448371D24B}"

 	RootNamespace="ff2-xpcom"

 	Keyword="Win32Proj"

-	TargetFrameworkVersion="131072"

 	>

 	<Platforms>

 		<Platform

@@ -72,8 +71,6 @@
 				GenerateDebugInformation="true"

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

 				SubSystem="2"

-				RandomizedBaseAddress="1"

-				DataExecutionPrevention="0"

 				ImportLibrary="$(IntDir)\$(TargetName).lib"

 				TargetMachine="1"

 			/>

@@ -155,8 +152,6 @@
 				SubSystem="2"

 				OptimizeReferences="2"

 				EnableCOMDATFolding="2"

-				RandomizedBaseAddress="1"

-				DataExecutionPrevention="0"

 				ImportLibrary="$(IntDir)\$(TargetName).lib"

 				TargetMachine="1"

 			/>

diff --git a/plugins/xpcom/VisualStudio/ff3-xpcom.vcproj b/plugins/xpcom/VisualStudio/ff3-xpcom.vcproj
index 25b9737..37d0f43 100755
--- a/plugins/xpcom/VisualStudio/ff3-xpcom.vcproj
+++ b/plugins/xpcom/VisualStudio/ff3-xpcom.vcproj
@@ -1,12 +1,11 @@
 <?xml version="1.0" encoding="UTF-8"?>

 <VisualStudioProject

 	ProjectType="Visual C++"

-	Version="9.00"

+	Version="8.00"

 	Name="ff3-xpcom"

 	ProjectGUID="{6BF0C2CE-CB0C-421B-A67C-1E448371D24C}"

 	RootNamespace="ff3-xpcom"

 	Keyword="Win32Proj"

-	TargetFrameworkVersion="131072"

 	>

 	<Platforms>

 		<Platform

@@ -18,8 +17,8 @@
 	<Configurations>

 		<Configuration

 			Name="Debug|Win32"

-			OutputDirectory="Debug"

-			IntermediateDirectory="Debug"

+			OutputDirectory="Debug3"

+			IntermediateDirectory="Debug3"

 			ConfigurationType="2"

 			UseOfMFC="1"

 			>

@@ -46,6 +45,7 @@
 				MinimalRebuild="true"

 				BasicRuntimeChecks="3"

 				RuntimeLibrary="1"

+				TreatWChar_tAsBuiltInType="false"

 				UsePrecompiledHeader="0"

 				WarningLevel="3"

 				Detect64BitPortabilityProblems="true"

@@ -72,8 +72,6 @@
 				GenerateDebugInformation="true"

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

 				SubSystem="2"

-				RandomizedBaseAddress="1"

-				DataExecutionPrevention="0"

 				ImportLibrary="$(IntDir)\$(TargetName).lib"

 				TargetMachine="1"

 			/>

@@ -96,13 +94,16 @@
 				Name="VCAppVerifierTool"

 			/>

 			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

 				Name="VCPostBuildEventTool"

 			/>

 		</Configuration>

 		<Configuration

 			Name="Release|Win32"

-			OutputDirectory="Release"

-			IntermediateDirectory="Release"

+			OutputDirectory="Release3"

+			IntermediateDirectory="Release3"

 			ConfigurationType="2"

 			>

 			<Tool

@@ -124,10 +125,11 @@
 				Name="VCCLCompilerTool"

 				Optimization="3"

 				EnableIntrinsicFunctions="true"

-				AdditionalIncludeDirectories="&quot;..\..\common&quot;"

+				AdditionalIncludeDirectories="&quot;$(ProjectDir)\..\..\common&quot;;&quot;..\prebuilt\ff3\include&quot;;&quot;..\..\..\..\plugin-sdks\gecko-sdks\gecko-1.9.0\WINNT_x86-msvc\include&quot;;&quot;..\..\..\..\plugin-sdks\gecko-sdks\gecko-1.9.0\include&quot;;&quot;..\..\..\..\plugin-sdks\gecko-sdks\gecko-1.9.0\include\caps&quot;;&quot;..\..\..\..\plugin-sdks\gecko-sdks\gecko-1.9.0\include\dom&quot;;&quot;..\..\..\..\plugin-sdks\gecko-sdks\gecko-1.9.0\include\js&quot;;&quot;..\..\..\..\plugin-sdks\gecko-sdks\gecko-1.9.0\include\necko&quot;;&quot;..\..\..\..\plugin-sdks\gecko-sdks\gecko-1.9.0\include\string&quot;;&quot;..\..\..\..\plugin-sdks\gecko-sdks\gecko-1.9.0\include\widget&quot;;&quot;..\..\..\..\plugin-sdks\gecko-sdks\gecko-1.9.0\include\xpcom&quot;;&quot;..\..\..\..\plugin-sdks\gecko-sdks\gecko-1.9.0\include\xpconnect&quot;;&quot;..\..\..\..\plugin-sdks\gecko-sdks\gecko-1.9.0\include&quot;"

 				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;FIREFOXPLUGIN_EXPORTS;GWT_DEBUGLEVEL=Warning;XPCOM_GLUE;XPCOM_GLUE_USE_NSPR;MOZILLA_STRICT_API;BROWSER_FF3"

 				ExceptionHandling="1"

 				RuntimeLibrary="2"

+				TreatWChar_tAsBuiltInType="false"

 				UsePrecompiledHeader="0"

 				WarningLevel="3"

 				Detect64BitPortabilityProblems="false"

@@ -155,8 +157,6 @@
 				SubSystem="2"

 				OptimizeReferences="2"

 				EnableCOMDATFolding="2"

-				RandomizedBaseAddress="1"

-				DataExecutionPrevention="0"

 				ImportLibrary="$(IntDir)\$(TargetName).lib"

 				TargetMachine="1"

 			/>

@@ -179,6 +179,9 @@
 				Name="VCAppVerifierTool"

 			/>

 			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

 				Name="VCPostBuildEventTool"

 			/>

 		</Configuration>

@@ -792,6 +795,14 @@
 				</FileConfiguration>

 			</File>

 			<File

+				RelativePath="..\Preferences.cpp"

+				>

+			</File>

+			<File

+				RelativePath="..\Preferences.h"

+				>

+			</File>

+			<File

 				RelativePath="..\..\common\ProtocolVersionMessage.cpp"

 				>

 			</File>

diff --git a/plugins/xpcom/VisualStudio/ff35-xpcom.vcproj b/plugins/xpcom/VisualStudio/ff35-xpcom.vcproj
index 37a6085..3be29b9 100755
--- a/plugins/xpcom/VisualStudio/ff35-xpcom.vcproj
+++ b/plugins/xpcom/VisualStudio/ff35-xpcom.vcproj
@@ -1,12 +1,11 @@
 <?xml version="1.0" encoding="UTF-8"?>

 <VisualStudioProject

 	ProjectType="Visual C++"

-	Version="9.00"

+	Version="8.00"

 	Name="ff35-xpcom"

 	ProjectGUID="{6BF0C2CE-CB0C-421B-A67C-1E448371D24D}"

 	RootNamespace="ff35-xpcom"

 	Keyword="Win32Proj"

-	TargetFrameworkVersion="131072"

 	>

 	<Platforms>

 		<Platform

@@ -18,8 +17,8 @@
 	<Configurations>

 		<Configuration

 			Name="Debug|Win32"

-			OutputDirectory="Debug"

-			IntermediateDirectory="Debug"

+			OutputDirectory="Debug35"

+			IntermediateDirectory="Debug35"

 			ConfigurationType="2"

 			UseOfMFC="1"

 			>

@@ -41,11 +40,12 @@
 			<Tool

 				Name="VCCLCompilerTool"

 				Optimization="0"

-				AdditionalIncludeDirectories="&quot;$(ProjectDir)\..\..\common&quot;;&quot;..\prebuilt\ff3\include&quot;;&quot;..\..\..\..\plugin-sdks\gecko-sdks\gecko-1.9.1\WINNT_x86-msvc\include&quot;;&quot;..\..\..\..\plugin-sdks\gecko-sdks\gecko-1.9.1\include&quot;;&quot;..\..\..\..\plugin-sdks\gecko-sdks\gecko-1.9.1\include\caps&quot;;&quot;..\..\..\..\plugin-sdks\gecko-sdks\gecko-1.9.1\include\dom&quot;;&quot;..\..\..\..\plugin-sdks\gecko-sdks\gecko-1.9.1\include\js&quot;;&quot;..\..\..\..\plugin-sdks\gecko-sdks\gecko-1.9.1\include\necko&quot;;&quot;..\..\..\..\plugin-sdks\gecko-sdks\gecko-1.9.1\include\string&quot;;&quot;..\..\..\..\plugin-sdks\gecko-sdks\gecko-1.9.1\include\widget&quot;;&quot;..\..\..\..\plugin-sdks\gecko-sdks\gecko-1.9.1\include\xpcom&quot;;&quot;..\..\..\..\plugin-sdks\gecko-sdks\gecko-1.9.1\include\xpconnect&quot;;&quot;..\..\..\..\plugin-sdks\gecko-sdks\gecko-1.9.1\include&quot;"

+				AdditionalIncludeDirectories="&quot;$(ProjectDir)\..\..\common&quot;;..\prebuilt\ff3\include;&quot;..\..\..\..\plugin-sdks\gecko-sdks\gecko-1.9.1\WINNT_x86-msvc\include&quot;;&quot;..\..\..\..\plugin-sdks\gecko-sdks\gecko-1.9.1\include&quot;;&quot;..\..\..\..\plugin-sdks\gecko-sdks\gecko-1.9.1\include\caps&quot;;&quot;..\..\..\..\plugin-sdks\gecko-sdks\gecko-1.9.1\include\dom&quot;;&quot;..\..\..\..\plugin-sdks\gecko-sdks\gecko-1.9.1\include\js&quot;;&quot;..\..\..\..\plugin-sdks\gecko-sdks\gecko-1.9.1\include\necko&quot;;&quot;..\..\..\..\plugin-sdks\gecko-sdks\gecko-1.9.1\include\string&quot;;&quot;..\..\..\..\plugin-sdks\gecko-sdks\gecko-1.9.1\include\widget&quot;;&quot;..\..\..\..\plugin-sdks\gecko-sdks\gecko-1.9.1\include\xpcom&quot;;&quot;..\..\..\..\plugin-sdks\gecko-sdks\gecko-1.9.1\include\xpconnect&quot;"

 				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;FIREFOXPLUGIN_EXPORTS;GWT_DEBUGLEVEL=Warning;XPCOM_GLUE;XPCOM_GLUE_USE_NSPR;MOZILLA_STRICT_API;BROWSER_FF3"

 				MinimalRebuild="true"

 				BasicRuntimeChecks="3"

 				RuntimeLibrary="1"

+				TreatWChar_tAsBuiltInType="false"

 				UsePrecompiledHeader="0"

 				WarningLevel="3"

 				Detect64BitPortabilityProblems="true"

@@ -72,8 +72,6 @@
 				GenerateDebugInformation="true"

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

 				SubSystem="2"

-				RandomizedBaseAddress="1"

-				DataExecutionPrevention="0"

 				ImportLibrary="$(IntDir)\$(TargetName).lib"

 				TargetMachine="1"

 			/>

@@ -96,13 +94,16 @@
 				Name="VCAppVerifierTool"

 			/>

 			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

 				Name="VCPostBuildEventTool"

 			/>

 		</Configuration>

 		<Configuration

 			Name="Release|Win32"

-			OutputDirectory="Release"

-			IntermediateDirectory="Release"

+			OutputDirectory="Release35"

+			IntermediateDirectory="Release35"

 			ConfigurationType="2"

 			>

 			<Tool

@@ -124,10 +125,11 @@
 				Name="VCCLCompilerTool"

 				Optimization="3"

 				EnableIntrinsicFunctions="true"

-				AdditionalIncludeDirectories="&quot;..\..\common&quot;"

+				AdditionalIncludeDirectories="&quot;$(ProjectDir)\..\..\common&quot;;..\prebuilt\ff3\include;&quot;..\..\..\..\plugin-sdks\gecko-sdks\gecko-1.9.1\WINNT_x86-msvc\include&quot;;&quot;..\..\..\..\plugin-sdks\gecko-sdks\gecko-1.9.1\include&quot;;&quot;..\..\..\..\plugin-sdks\gecko-sdks\gecko-1.9.1\include\caps&quot;;&quot;..\..\..\..\plugin-sdks\gecko-sdks\gecko-1.9.1\include\dom&quot;;&quot;..\..\..\..\plugin-sdks\gecko-sdks\gecko-1.9.1\include\js&quot;;&quot;..\..\..\..\plugin-sdks\gecko-sdks\gecko-1.9.1\include\necko&quot;;&quot;..\..\..\..\plugin-sdks\gecko-sdks\gecko-1.9.1\include\string&quot;;&quot;..\..\..\..\plugin-sdks\gecko-sdks\gecko-1.9.1\include\widget&quot;;&quot;..\..\..\..\plugin-sdks\gecko-sdks\gecko-1.9.1\include\xpcom&quot;;&quot;..\..\..\..\plugin-sdks\gecko-sdks\gecko-1.9.1\include\xpconnect&quot;"

 				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;FIREFOXPLUGIN_EXPORTS;GWT_DEBUGLEVEL=Warning;XPCOM_GLUE;XPCOM_GLUE_USE_NSPR;MOZILLA_STRICT_API;BROWSER_FF3"

 				ExceptionHandling="1"

 				RuntimeLibrary="2"

+				TreatWChar_tAsBuiltInType="false"

 				UsePrecompiledHeader="0"

 				WarningLevel="3"

 				Detect64BitPortabilityProblems="false"

@@ -155,8 +157,6 @@
 				SubSystem="2"

 				OptimizeReferences="2"

 				EnableCOMDATFolding="2"

-				RandomizedBaseAddress="1"

-				DataExecutionPrevention="0"

 				ImportLibrary="$(IntDir)\$(TargetName).lib"

 				TargetMachine="1"

 			/>

@@ -179,6 +179,9 @@
 				Name="VCAppVerifierTool"

 			/>

 			<Tool

+				Name="VCWebDeploymentTool"

+			/>

+			<Tool

 				Name="VCPostBuildEventTool"

 			/>

 		</Configuration>

@@ -596,6 +599,10 @@
 				>

 			</File>

 			<File

+				RelativePath="..\Preferences.h"

+				>

+			</File>

+			<File

 				RelativePath="..\..\..\..\plugin-sdks\gecko-sdks\gecko-1.9.1\include\prinrval.h"

 				>

 			</File>

@@ -792,6 +799,10 @@
 				</FileConfiguration>

 			</File>

 			<File

+				RelativePath="..\Preferences.cpp"

+				>

+			</File>

+			<File

 				RelativePath="..\..\common\ProtocolVersionMessage.cpp"

 				>

 			</File>

diff --git a/plugins/xpcom/install-template-ff2.rdf b/plugins/xpcom/install-template-ff2.rdf
index 031924c..29b66d0 100644
--- a/plugins/xpcom/install-template-ff2.rdf
+++ b/plugins/xpcom/install-template-ff2.rdf
@@ -3,7 +3,7 @@
      xmlns:em="http://www.mozilla.org/2004/em-rdf#">
 
   <Description about="urn:mozilla:install-manifest">
-    <em:id>oophm-xpcom-ff2@gwt.google.com</em:id>
+    <em:id>gwt-dmp-ff2@gwt.google.com</em:id>
     <em:name>GWT Development Mode Plugin (XPCOM) for FF v1.5-2.x</em:name>
     <em:version>GWT_OOPHM_VERSION</em:version>
     <em:type>2</em:type>
@@ -16,20 +16,22 @@
     </em:targetApplication>
 
     <!-- Front End MetaData -->
-    <em:description>A plugin to support development-mode development of GWT applications</em:description>
+    <em:description>A plugin to support GWT development-mode in XPCOM-based browsers</em:description>
     <em:creator>Google, Inc.</em:creator>
     <em:homepageURL>http://code.google.com/webtoolkit/</em:homepageURL>
-    <em:iconURL>chrome://gwt-oophm/skin/icon.png</em:iconURL>
+    <em:iconURL>chrome://gwt-dmp/skin/icon.png</em:iconURL>
 
     <em:targetPlatform>Linux_x86-gcc3</em:targetPlatform>
     <em:targetPlatform>Linux_x86_64-gcc3</em:targetPlatform>
     <em:targetPlatform>Darwin_x86-gcc3</em:targetPlatform>
+    <em:targetPlatform>Darwin_ppc-gcc3</em:targetPlatform>
+
+    <em:optionsURL>chrome://gwt-dmp/content/options.xul</em:optionsURL>
 
     <!-- TODO
-    # prefs dialog
 
     # replace default about dialog
-    <em:aboutURL>chrome://gwt-oophm/content/about.xul</em:aboutURL>
+    <em:aboutURL>chrome://gwt-dmp/content/about.xul</em:aboutURL>
 
     # updates, see http://developer.mozilla.org/en/docs/Extension_Versioning%2C_Update_and_Compatibility#Update_RDF_Format
     <em:updateURL>https://xxx.google.com/.../update.rdf</em:updateURL>
@@ -37,7 +39,6 @@
 
     # platforms - any others?
     <em:targetPlatform>WINNT_x86-msvc</em:targetPlatform>
-    <em:targetPlatform>Darwin_ppc-gcc3</em:targetPlatform>
     <em:targetPlatform>SunOS_sparc-sunc</em:targetPlatform>
     <em:targetPlatform>SunOS_x86-sunc</em:targetPlatform>
     -->
diff --git a/plugins/xpcom/install-template-ff3+.rdf b/plugins/xpcom/install-template-ff3+.rdf
index 84a16f9..6cb592b 100644
--- a/plugins/xpcom/install-template-ff3+.rdf
+++ b/plugins/xpcom/install-template-ff3+.rdf
@@ -3,7 +3,7 @@
      xmlns:em="http://www.mozilla.org/2004/em-rdf#">
 
   <Description about="urn:mozilla:install-manifest">
-    <em:id>oophm-xpcom-ff3p@gwt.google.com</em:id>
+    <em:id>gwt-dmp-ff3p@gwt.google.com</em:id>
     <em:name>GWT Development Mode Plugin (XPCOM) for FF v3.x (alt libraries)</em:name>
     <em:version>GWT_OOPHM_VERSION</em:version>
     <em:type>2</em:type>
@@ -16,30 +16,32 @@
     </em:targetApplication>
 
     <!-- Front End MetaData -->
-    <em:description>A plugin to support development-mode development of GWT applications</em:description>
+    <em:description>A plugin to support GWT development-mode in XPCOM-based browsers</em:description>
     <em:creator>Google, Inc.</em:creator>
     <em:homepageURL>http://code.google.com/webtoolkit/</em:homepageURL>
-    <em:iconURL>chrome://gwt-oophm/skin/icon.png</em:iconURL>
+    <em:iconURL>chrome://gwt-dmp/skin/icon.png</em:iconURL>
 
     <em:targetPlatform>Linux_x86-gcc3</em:targetPlatform>
     <em:targetPlatform>Linux_x86_64-gcc3</em:targetPlatform>
-    <em:targetPlatform>WINNT_x86-msvc</em:targetPlatform>
-    <em:targetPlatform>Darwin_x86-gcc3</em:targetPlatform>
+
+    <em:optionsURL>chrome://gwt-dmp/content/options.xul</em:optionsURL>
 
     <!-- TODO
     # prefs dialog
 
     # replace default about dialog
-    <em:aboutURL>chrome://gwt-oophm/content/about.xul</em:aboutURL>
+    <em:aboutURL>chrome://gwt-dmp/content/about.xul</em:aboutURL>
 
     # updates, see http://developer.mozilla.org/en/docs/Extension_Versioning%2C_Update_and_Compatibility#Update_RDF_Format
     <em:updateURL>https://xxx.google.com/.../update.rdf</em:updateURL>
     <em:updateURL>http://google-web-toolkit.googlecode.com/svn/trunk/plugins/xpcom/prebuilt/update.rdf</em:updateURL>
 
     # platforms - any others?
-    <em:targetPlatform>Darwin_ppc-gcc3</em:targetPlatform>
     <em:targetPlatform>SunOS_sparc-sunc</em:targetPlatform>
     <em:targetPlatform>SunOS_x86-sunc</em:targetPlatform>
+    <em:targetPlatform>WINNT_x86-msvc</em:targetPlatform>
+    <em:targetPlatform>Darwin_x86-gcc3</em:targetPlatform>
+    <em:targetPlatform>Darwin_ppc-gcc3</em:targetPlatform>
     -->
 
   </Description>
diff --git a/plugins/xpcom/install-template-ff3.rdf b/plugins/xpcom/install-template-ff3.rdf
index 9082d32..7653ccb 100644
--- a/plugins/xpcom/install-template-ff3.rdf
+++ b/plugins/xpcom/install-template-ff3.rdf
@@ -3,7 +3,7 @@
      xmlns:em="http://www.mozilla.org/2004/em-rdf#">
 
   <Description about="urn:mozilla:install-manifest">
-    <em:id>oophm-xpcom-ff3@gwt.google.com</em:id>
+    <em:id>gwt-dmp-ff3@gwt.google.com</em:id>
     <em:name>GWT Development Mode Plugin (XPCOM) for FF v3.x</em:name>
     <em:version>GWT_OOPHM_VERSION</em:version>
     <em:type>2</em:type>
@@ -16,28 +16,29 @@
     </em:targetApplication>
 
     <!-- Front End MetaData -->
-    <em:description>A plugin to support development-mode development of GWT applications</em:description>
+    <em:description>A plugin to support GWT development-mode in XPCOM-based browsers</em:description>
     <em:creator>Google, Inc.</em:creator>
     <em:homepageURL>http://code.google.com/webtoolkit/</em:homepageURL>
-    <em:iconURL>chrome://gwt-oophm/skin/icon.png</em:iconURL>
+    <em:iconURL>chrome://gwt-dmp/skin/icon.png</em:iconURL>
 
     <em:targetPlatform>Linux_x86-gcc3</em:targetPlatform>
     <em:targetPlatform>Linux_x86_64-gcc3</em:targetPlatform>
     <em:targetPlatform>WINNT_x86-msvc</em:targetPlatform>
     <em:targetPlatform>Darwin_x86-gcc3</em:targetPlatform>
+    <em:targetPlatform>Darwin_ppc-gcc3</em:targetPlatform>
+
+    <em:optionsURL>chrome://gwt-dmp/content/options.xul</em:optionsURL>
 
     <!-- TODO
-    # prefs dialog
 
     # replace default about dialog
-    <em:aboutURL>chrome://gwt-oophm/content/about.xul</em:aboutURL>
+    <em:aboutURL>chrome://gwt-dmp/content/about.xul</em:aboutURL>
 
     # updates, see http://developer.mozilla.org/en/docs/Extension_Versioning%2C_Update_and_Compatibility#Update_RDF_Format
     <em:updateURL>https://xxx.google.com/.../update.rdf</em:updateURL>
     <em:updateURL>http://google-web-toolkit.googlecode.com/svn/trunk/plugins/xpcom/prebuilt/update.rdf</em:updateURL>
 
     # platforms - any others?
-    <em:targetPlatform>Darwin_ppc-gcc3</em:targetPlatform>
     <em:targetPlatform>SunOS_sparc-sunc</em:targetPlatform>
     <em:targetPlatform>SunOS_x86-sunc</em:targetPlatform>
     -->
diff --git a/plugins/xpcom/install-template-ff35.rdf b/plugins/xpcom/install-template-ff35.rdf
index deec1e8..faeb80e 100644
--- a/plugins/xpcom/install-template-ff35.rdf
+++ b/plugins/xpcom/install-template-ff35.rdf
@@ -3,7 +3,7 @@
      xmlns:em="http://www.mozilla.org/2004/em-rdf#">
 
   <Description about="urn:mozilla:install-manifest">
-    <em:id>oophm-xpcom-ff35@gwt.google.com</em:id>
+    <em:id>gwt-dmp-ff35@gwt.google.com</em:id>
     <em:name>GWT Development Mode Plugin (XPCOM) for FF v3.5+</em:name>
     <em:version>GWT_OOPHM_VERSION</em:version>
     <em:type>2</em:type>
@@ -16,28 +16,29 @@
     </em:targetApplication>
 
     <!-- Front End MetaData -->
-    <em:description>A plugin to support development-mode development of GWT applications</em:description>
+    <em:description>A plugin to support GWT development-mode in XPCOM-based browsers</em:description>
     <em:creator>Google, Inc.</em:creator>
     <em:homepageURL>http://code.google.com/webtoolkit/</em:homepageURL>
-    <em:iconURL>chrome://gwt-oophm/skin/icon.png</em:iconURL>
+    <em:iconURL>chrome://gwt-dmp/skin/icon.png</em:iconURL>
 
     <em:targetPlatform>Linux_x86-gcc3</em:targetPlatform>
     <em:targetPlatform>Linux_x86_64-gcc3</em:targetPlatform>
     <em:targetPlatform>WINNT_x86-msvc</em:targetPlatform>
     <em:targetPlatform>Darwin_x86-gcc3</em:targetPlatform>
+    <em:targetPlatform>Darwin_ppc-gcc3</em:targetPlatform>
+
+    <em:optionsURL>chrome://gwt-dmp/content/options.xul</em:optionsURL>
 
     <!-- TODO
-    # prefs dialog
 
     # replace default about dialog
-    <em:aboutURL>chrome://gwt-oophm/content/about.xul</em:aboutURL>
+    <em:aboutURL>chrome://gwt-dmp/content/about.xul</em:aboutURL>
 
     # updates, see http://developer.mozilla.org/en/docs/Extension_Versioning%2C_Update_and_Compatibility#Update_RDF_Format
     <em:updateURL>https://xxx.google.com/.../update.rdf</em:updateURL>
     <em:updateURL>http://google-web-toolkit.googlecode.com/svn/trunk/plugins/xpcom/prebuilt/update.rdf</em:updateURL>
 
     # platforms - any others?
-    <em:targetPlatform>Darwin_ppc-gcc3</em:targetPlatform>
     <em:targetPlatform>SunOS_sparc-sunc</em:targetPlatform>
     <em:targetPlatform>SunOS_x86-sunc</em:targetPlatform>
     -->
diff --git a/plugins/xpcom/prebuilt/extension-ff2/chrome.manifest b/plugins/xpcom/prebuilt/extension-ff2/chrome.manifest
deleted file mode 100644
index 38a0fdd..0000000
--- a/plugins/xpcom/prebuilt/extension-ff2/chrome.manifest
+++ /dev/null
@@ -1,2 +0,0 @@
-content gwt-oophm content/
-skin gwt-oophm classic/1.0 skin/
diff --git a/plugins/xpcom/prebuilt/extension-ff2/install.rdf b/plugins/xpcom/prebuilt/extension-ff2/install.rdf
deleted file mode 100644
index 7feda0c..0000000
--- a/plugins/xpcom/prebuilt/extension-ff2/install.rdf
+++ /dev/null
@@ -1,46 +0,0 @@
-<?xml version="1.0"?>
-<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-     xmlns:em="http://www.mozilla.org/2004/em-rdf#">
-
-  <Description about="urn:mozilla:install-manifest">
-    <em:id>oophm-xpcom-ff2@gwt.google.com</em:id>
-    <em:name>GWT Hosted Mode Plugin (XPCOM) for FF v1.5-2.x</em:name>
-    <em:version>0.0.-1M.20090803104826</em:version>
-    <em:type>2</em:type>
-    <em:targetApplication>
-      <Description>
-        <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
-        <em:minVersion>1.5</em:minVersion>
-        <em:maxVersion>2.*</em:maxVersion>
-      </Description>
-    </em:targetApplication>
-
-    <!-- Front End MetaData -->
-    <em:description>A plugin to support hosted-mode development of GWT applications</em:description>
-    <em:creator>Google, Inc.</em:creator>
-    <em:homepageURL>http://code.google.com/webtoolkit/</em:homepageURL>
-    <em:iconURL>chrome://gwt-oophm/skin/icon.png</em:iconURL>
-
-    <em:targetPlatform>Linux_x86-gcc3</em:targetPlatform>
-    <em:targetPlatform>Linux_x86_64-gcc3</em:targetPlatform>
-    <em:targetPlatform>Darwin_x86-gcc3</em:targetPlatform>
-
-    <!-- TODO
-    # prefs dialog
-
-    # replace default about dialog
-    <em:aboutURL>chrome://gwt-oophm/content/about.xul</em:aboutURL>
-
-    # updates, see http://developer.mozilla.org/en/docs/Extension_Versioning%2C_Update_and_Compatibility#Update_RDF_Format
-    <em:updateURL>https://xxx.google.com/.../update.rdf</em:updateURL>
-    <em:updateURL>http://google-web-toolkit.googlecode.com/svn/trunk/plugins/xpcom/prebuilt/update.rdf</em:updateURL>
-
-    # platforms - any others?
-    <em:targetPlatform>WINNT_x86-msvc</em:targetPlatform>
-    <em:targetPlatform>Darwin_ppc-gcc3</em:targetPlatform>
-    <em:targetPlatform>SunOS_sparc-sunc</em:targetPlatform>
-    <em:targetPlatform>SunOS_x86-sunc</em:targetPlatform>
-    -->
-
-  </Description>
-</RDF>
diff --git a/plugins/xpcom/prebuilt/extension-ff2/platform/Darwin_ppc-gcc3/components/libgwt_dmp_ff2.dylib b/plugins/xpcom/prebuilt/extension-ff2/platform/Darwin_ppc-gcc3/components/libgwt_dmp_ff2.dylib
new file mode 100755
index 0000000..9e224cd
--- /dev/null
+++ b/plugins/xpcom/prebuilt/extension-ff2/platform/Darwin_ppc-gcc3/components/libgwt_dmp_ff2.dylib
Binary files differ
diff --git a/plugins/xpcom/prebuilt/extension-ff2/platform/Darwin_x86-gcc3/components/libgwt_dmp_ff2.dylib b/plugins/xpcom/prebuilt/extension-ff2/platform/Darwin_x86-gcc3/components/libgwt_dmp_ff2.dylib
new file mode 100755
index 0000000..f9ad6ad
--- /dev/null
+++ b/plugins/xpcom/prebuilt/extension-ff2/platform/Darwin_x86-gcc3/components/libgwt_dmp_ff2.dylib
Binary files differ
diff --git a/plugins/xpcom/prebuilt/extension-ff2/platform/Linux_x86-gcc3/components/libgwt_dmp_ff2.so b/plugins/xpcom/prebuilt/extension-ff2/platform/Linux_x86-gcc3/components/libgwt_dmp_ff2.so
new file mode 100755
index 0000000..eecc748
--- /dev/null
+++ b/plugins/xpcom/prebuilt/extension-ff2/platform/Linux_x86-gcc3/components/libgwt_dmp_ff2.so
Binary files differ
diff --git a/plugins/xpcom/prebuilt/extension-ff2/platform/Linux_x86-gcc3/components/liboophm_ff2.so b/plugins/xpcom/prebuilt/extension-ff2/platform/Linux_x86-gcc3/components/liboophm_ff2.so
deleted file mode 100755
index eedbabb..0000000
--- a/plugins/xpcom/prebuilt/extension-ff2/platform/Linux_x86-gcc3/components/liboophm_ff2.so
+++ /dev/null
Binary files differ
diff --git a/plugins/xpcom/prebuilt/extension-ff2/platform/Linux_x86_64-gcc3/components/libgwt_dmp_ff2.so b/plugins/xpcom/prebuilt/extension-ff2/platform/Linux_x86_64-gcc3/components/libgwt_dmp_ff2.so
new file mode 100755
index 0000000..46bd8fc
--- /dev/null
+++ b/plugins/xpcom/prebuilt/extension-ff2/platform/Linux_x86_64-gcc3/components/libgwt_dmp_ff2.so
Binary files differ
diff --git a/plugins/xpcom/prebuilt/extension-ff2/platform/Linux_x86_64-gcc3/components/liboophm_ff2.so b/plugins/xpcom/prebuilt/extension-ff2/platform/Linux_x86_64-gcc3/components/liboophm_ff2.so
deleted file mode 100755
index cf54702..0000000
--- a/plugins/xpcom/prebuilt/extension-ff2/platform/Linux_x86_64-gcc3/components/liboophm_ff2.so
+++ /dev/null
Binary files differ
diff --git a/plugins/xpcom/prebuilt/extension-ff3+/chrome.manifest b/plugins/xpcom/prebuilt/extension-ff3+/chrome.manifest
deleted file mode 100644
index 38a0fdd..0000000
--- a/plugins/xpcom/prebuilt/extension-ff3+/chrome.manifest
+++ /dev/null
@@ -1,2 +0,0 @@
-content gwt-oophm content/
-skin gwt-oophm classic/1.0 skin/
diff --git a/plugins/xpcom/prebuilt/extension-ff3+/install.rdf b/plugins/xpcom/prebuilt/extension-ff3+/install.rdf
deleted file mode 100644
index 31f4673..0000000
--- a/plugins/xpcom/prebuilt/extension-ff3+/install.rdf
+++ /dev/null
@@ -1,46 +0,0 @@
-<?xml version="1.0"?>
-<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-     xmlns:em="http://www.mozilla.org/2004/em-rdf#">
-
-  <Description about="urn:mozilla:install-manifest">
-    <em:id>oophm-xpcom-ff3@gwt.google.com</em:id>
-    <em:name>GWT Hosted Mode Plugin (XPCOM) for FF v3.x</em:name>
-    <em:version>0.0.-1M.20090803104811</em:version>
-    <em:type>2</em:type>
-    <em:targetApplication>
-      <Description>
-        <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
-        <em:minVersion>3</em:minVersion>
-        <em:maxVersion>3.*</em:maxVersion>
-      </Description>
-    </em:targetApplication>
-
-    <!-- Front End MetaData -->
-    <em:description>A plugin to support hosted-mode development of GWT applications</em:description>
-    <em:creator>Google, Inc.</em:creator>
-    <em:homepageURL>http://code.google.com/webtoolkit/</em:homepageURL>
-    <em:iconURL>chrome://gwt-oophm/skin/icon.png</em:iconURL>
-
-    <em:targetPlatform>Linux_x86-gcc3</em:targetPlatform>
-    <em:targetPlatform>Linux_x86_64-gcc3</em:targetPlatform>
-    <em:targetPlatform>WINNT_x86-msvc</em:targetPlatform>
-    <em:targetPlatform>Darwin_x86-gcc3</em:targetPlatform>
-
-    <!-- TODO
-    # prefs dialog
-
-    # replace default about dialog
-    <em:aboutURL>chrome://gwt-oophm/content/about.xul</em:aboutURL>
-
-    # updates, see http://developer.mozilla.org/en/docs/Extension_Versioning%2C_Update_and_Compatibility#Update_RDF_Format
-    <em:updateURL>https://xxx.google.com/.../update.rdf</em:updateURL>
-    <em:updateURL>http://google-web-toolkit.googlecode.com/svn/trunk/plugins/xpcom/prebuilt/update.rdf</em:updateURL>
-
-    # platforms - any others?
-    <em:targetPlatform>Darwin_ppc-gcc3</em:targetPlatform>
-    <em:targetPlatform>SunOS_sparc-sunc</em:targetPlatform>
-    <em:targetPlatform>SunOS_x86-sunc</em:targetPlatform>
-    -->
-
-  </Description>
-</RDF>
diff --git a/plugins/xpcom/prebuilt/extension-ff3+/platform/Linux_x86_64-gcc3/components/libgwt_dmp_ff3+.so b/plugins/xpcom/prebuilt/extension-ff3+/platform/Linux_x86_64-gcc3/components/libgwt_dmp_ff3+.so
new file mode 100755
index 0000000..4517d2a
--- /dev/null
+++ b/plugins/xpcom/prebuilt/extension-ff3+/platform/Linux_x86_64-gcc3/components/libgwt_dmp_ff3+.so
Binary files differ
diff --git a/plugins/xpcom/prebuilt/extension-ff3+/platform/Linux_x86_64-gcc3/components/liboophm_ff3+.so b/plugins/xpcom/prebuilt/extension-ff3+/platform/Linux_x86_64-gcc3/components/liboophm_ff3+.so
deleted file mode 100755
index e1f5935..0000000
--- a/plugins/xpcom/prebuilt/extension-ff3+/platform/Linux_x86_64-gcc3/components/liboophm_ff3+.so
+++ /dev/null
Binary files differ
diff --git a/plugins/xpcom/prebuilt/extension-ff3/chrome.manifest b/plugins/xpcom/prebuilt/extension-ff3/chrome.manifest
deleted file mode 100644
index 38a0fdd..0000000
--- a/plugins/xpcom/prebuilt/extension-ff3/chrome.manifest
+++ /dev/null
@@ -1,2 +0,0 @@
-content gwt-oophm content/
-skin gwt-oophm classic/1.0 skin/
diff --git a/plugins/xpcom/prebuilt/extension-ff3/install.rdf b/plugins/xpcom/prebuilt/extension-ff3/install.rdf
deleted file mode 100644
index a782f87..0000000
--- a/plugins/xpcom/prebuilt/extension-ff3/install.rdf
+++ /dev/null
@@ -1,46 +0,0 @@
-<?xml version="1.0"?>
-<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-     xmlns:em="http://www.mozilla.org/2004/em-rdf#">
-
-  <Description about="urn:mozilla:install-manifest">
-    <em:id>oophm-xpcom-ff3@gwt.google.com</em:id>
-    <em:name>GWT Hosted Mode Plugin (XPCOM) for FF v3.x</em:name>
-    <em:version>0.0.-1M.20090803104821</em:version>
-    <em:type>2</em:type>
-    <em:targetApplication>
-      <Description>
-        <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
-        <em:minVersion>3</em:minVersion>
-        <em:maxVersion>3.*</em:maxVersion>
-      </Description>
-    </em:targetApplication>
-
-    <!-- Front End MetaData -->
-    <em:description>A plugin to support hosted-mode development of GWT applications</em:description>
-    <em:creator>Google, Inc.</em:creator>
-    <em:homepageURL>http://code.google.com/webtoolkit/</em:homepageURL>
-    <em:iconURL>chrome://gwt-oophm/skin/icon.png</em:iconURL>
-
-    <em:targetPlatform>Linux_x86-gcc3</em:targetPlatform>
-    <em:targetPlatform>Linux_x86_64-gcc3</em:targetPlatform>
-    <em:targetPlatform>WINNT_x86-msvc</em:targetPlatform>
-    <em:targetPlatform>Darwin_x86-gcc3</em:targetPlatform>
-
-    <!-- TODO
-    # prefs dialog
-
-    # replace default about dialog
-    <em:aboutURL>chrome://gwt-oophm/content/about.xul</em:aboutURL>
-
-    # updates, see http://developer.mozilla.org/en/docs/Extension_Versioning%2C_Update_and_Compatibility#Update_RDF_Format
-    <em:updateURL>https://xxx.google.com/.../update.rdf</em:updateURL>
-    <em:updateURL>http://google-web-toolkit.googlecode.com/svn/trunk/plugins/xpcom/prebuilt/update.rdf</em:updateURL>
-
-    # platforms - any others?
-    <em:targetPlatform>Darwin_ppc-gcc3</em:targetPlatform>
-    <em:targetPlatform>SunOS_sparc-sunc</em:targetPlatform>
-    <em:targetPlatform>SunOS_x86-sunc</em:targetPlatform>
-    -->
-
-  </Description>
-</RDF>
diff --git a/plugins/xpcom/prebuilt/extension-ff3/platform/Darwin_ppc-gcc3/components/libgwt_dmp_ff3.dylib b/plugins/xpcom/prebuilt/extension-ff3/platform/Darwin_ppc-gcc3/components/libgwt_dmp_ff3.dylib
new file mode 100755
index 0000000..81df2bf
--- /dev/null
+++ b/plugins/xpcom/prebuilt/extension-ff3/platform/Darwin_ppc-gcc3/components/libgwt_dmp_ff3.dylib
Binary files differ
diff --git a/plugins/xpcom/prebuilt/extension-ff3/platform/Darwin_x86-gcc3/components/libgwt_dmp_ff3.dylib b/plugins/xpcom/prebuilt/extension-ff3/platform/Darwin_x86-gcc3/components/libgwt_dmp_ff3.dylib
new file mode 100755
index 0000000..a23866a
--- /dev/null
+++ b/plugins/xpcom/prebuilt/extension-ff3/platform/Darwin_x86-gcc3/components/libgwt_dmp_ff3.dylib
Binary files differ
diff --git a/plugins/xpcom/prebuilt/extension-ff3/platform/Darwin_x86-gcc3/components/liboophm.dylib b/plugins/xpcom/prebuilt/extension-ff3/platform/Darwin_x86-gcc3/components/liboophm.dylib
deleted file mode 100755
index eb3864d..0000000
--- a/plugins/xpcom/prebuilt/extension-ff3/platform/Darwin_x86-gcc3/components/liboophm.dylib
+++ /dev/null
Binary files differ
diff --git a/plugins/xpcom/prebuilt/extension-ff3/platform/Linux_x86-gcc3/components/libgwt_dmp_ff3.so b/plugins/xpcom/prebuilt/extension-ff3/platform/Linux_x86-gcc3/components/libgwt_dmp_ff3.so
new file mode 100755
index 0000000..637dc24
--- /dev/null
+++ b/plugins/xpcom/prebuilt/extension-ff3/platform/Linux_x86-gcc3/components/libgwt_dmp_ff3.so
Binary files differ
diff --git a/plugins/xpcom/prebuilt/extension-ff3/platform/Linux_x86-gcc3/components/liboophm_ff3.so b/plugins/xpcom/prebuilt/extension-ff3/platform/Linux_x86-gcc3/components/liboophm_ff3.so
deleted file mode 100755
index 76ace0d..0000000
--- a/plugins/xpcom/prebuilt/extension-ff3/platform/Linux_x86-gcc3/components/liboophm_ff3.so
+++ /dev/null
Binary files differ
diff --git a/plugins/xpcom/prebuilt/extension-ff3/platform/Linux_x86_64-gcc3/components/libgwt_dmp_ff3.so b/plugins/xpcom/prebuilt/extension-ff3/platform/Linux_x86_64-gcc3/components/libgwt_dmp_ff3.so
new file mode 100755
index 0000000..3fd64cc
--- /dev/null
+++ b/plugins/xpcom/prebuilt/extension-ff3/platform/Linux_x86_64-gcc3/components/libgwt_dmp_ff3.so
Binary files differ
diff --git a/plugins/xpcom/prebuilt/extension-ff3/platform/Linux_x86_64-gcc3/components/liboophm_ff3.so b/plugins/xpcom/prebuilt/extension-ff3/platform/Linux_x86_64-gcc3/components/liboophm_ff3.so
deleted file mode 100755
index 99db367..0000000
--- a/plugins/xpcom/prebuilt/extension-ff3/platform/Linux_x86_64-gcc3/components/liboophm_ff3.so
+++ /dev/null
Binary files differ
diff --git a/plugins/xpcom/prebuilt/extension-ff3/platform/WINNT_x86-msvc/components/xpOOPHM.dll b/plugins/xpcom/prebuilt/extension-ff3/platform/WINNT_x86-msvc/components/xpOOPHM.dll
index 6c8ec68..09a0119 100755
--- a/plugins/xpcom/prebuilt/extension-ff3/platform/WINNT_x86-msvc/components/xpOOPHM.dll
+++ b/plugins/xpcom/prebuilt/extension-ff3/platform/WINNT_x86-msvc/components/xpOOPHM.dll
Binary files differ
diff --git a/plugins/xpcom/prebuilt/extension-ff35/chrome.manifest b/plugins/xpcom/prebuilt/extension-ff35/chrome.manifest
deleted file mode 100644
index 38a0fdd..0000000
--- a/plugins/xpcom/prebuilt/extension-ff35/chrome.manifest
+++ /dev/null
@@ -1,2 +0,0 @@
-content gwt-oophm content/
-skin gwt-oophm classic/1.0 skin/
diff --git a/plugins/xpcom/prebuilt/extension-ff35/install.rdf b/plugins/xpcom/prebuilt/extension-ff35/install.rdf
deleted file mode 100644
index 6148662..0000000
--- a/plugins/xpcom/prebuilt/extension-ff35/install.rdf
+++ /dev/null
@@ -1,46 +0,0 @@
-<?xml version="1.0"?>
-<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
-     xmlns:em="http://www.mozilla.org/2004/em-rdf#">
-
-  <Description about="urn:mozilla:install-manifest">
-    <em:id>oophm-xpcom-ff35@gwt.google.com</em:id>
-    <em:name>GWT Hosted Mode Plugin (XPCOM) for FF v3.5+</em:name>
-    <em:version>0.0.-1M.20090803104256</em:version>
-    <em:type>2</em:type>
-    <em:targetApplication>
-      <Description>
-        <em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
-        <em:minVersion>3.4</em:minVersion>
-        <em:maxVersion>3.*</em:maxVersion>
-      </Description>
-    </em:targetApplication>
-
-    <!-- Front End MetaData -->
-    <em:description>A plugin to support hosted-mode development of GWT applications</em:description>
-    <em:creator>Google, Inc.</em:creator>
-    <em:homepageURL>http://code.google.com/webtoolkit/</em:homepageURL>
-    <em:iconURL>chrome://gwt-oophm/skin/icon.png</em:iconURL>
-
-    <em:targetPlatform>Linux_x86-gcc3</em:targetPlatform>
-    <em:targetPlatform>Linux_x86_64-gcc3</em:targetPlatform>
-    <em:targetPlatform>WINNT_x86-msvc</em:targetPlatform>
-    <em:targetPlatform>Darwin_x86-gcc3</em:targetPlatform>
-
-    <!-- TODO
-    # prefs dialog
-
-    # replace default about dialog
-    <em:aboutURL>chrome://gwt-oophm/content/about.xul</em:aboutURL>
-
-    # updates, see http://developer.mozilla.org/en/docs/Extension_Versioning%2C_Update_and_Compatibility#Update_RDF_Format
-    <em:updateURL>https://xxx.google.com/.../update.rdf</em:updateURL>
-    <em:updateURL>http://google-web-toolkit.googlecode.com/svn/trunk/plugins/xpcom/prebuilt/update.rdf</em:updateURL>
-
-    # platforms - any others?
-    <em:targetPlatform>Darwin_ppc-gcc3</em:targetPlatform>
-    <em:targetPlatform>SunOS_sparc-sunc</em:targetPlatform>
-    <em:targetPlatform>SunOS_x86-sunc</em:targetPlatform>
-    -->
-
-  </Description>
-</RDF>
diff --git a/plugins/xpcom/prebuilt/extension-ff35/platform/Darwin_ppc-gcc3/components/libgwt_dmp_ff35.dylib b/plugins/xpcom/prebuilt/extension-ff35/platform/Darwin_ppc-gcc3/components/libgwt_dmp_ff35.dylib
new file mode 100755
index 0000000..e483be4
--- /dev/null
+++ b/plugins/xpcom/prebuilt/extension-ff35/platform/Darwin_ppc-gcc3/components/libgwt_dmp_ff35.dylib
Binary files differ
diff --git a/plugins/xpcom/prebuilt/extension-ff35/platform/Darwin_x86-gcc3/components/libgwt_dmp_ff35.dylib b/plugins/xpcom/prebuilt/extension-ff35/platform/Darwin_x86-gcc3/components/libgwt_dmp_ff35.dylib
new file mode 100755
index 0000000..74c9132
--- /dev/null
+++ b/plugins/xpcom/prebuilt/extension-ff35/platform/Darwin_x86-gcc3/components/libgwt_dmp_ff35.dylib
Binary files differ
diff --git a/plugins/xpcom/prebuilt/extension-ff35/platform/Linux_x86-gcc3/components/libgwt_dmp_ff35.so b/plugins/xpcom/prebuilt/extension-ff35/platform/Linux_x86-gcc3/components/libgwt_dmp_ff35.so
new file mode 100755
index 0000000..8844bc7
--- /dev/null
+++ b/plugins/xpcom/prebuilt/extension-ff35/platform/Linux_x86-gcc3/components/libgwt_dmp_ff35.so
Binary files differ
diff --git a/plugins/xpcom/prebuilt/extension-ff35/platform/Linux_x86_64-gcc3/components/libgwt_dmp_ff35.so b/plugins/xpcom/prebuilt/extension-ff35/platform/Linux_x86_64-gcc3/components/libgwt_dmp_ff35.so
new file mode 100755
index 0000000..ef27b46
--- /dev/null
+++ b/plugins/xpcom/prebuilt/extension-ff35/platform/Linux_x86_64-gcc3/components/libgwt_dmp_ff35.so
Binary files differ
diff --git a/plugins/xpcom/prebuilt/extension-ff35/platform/Linux_x86_64-gcc3/components/liboophm_ff35.so b/plugins/xpcom/prebuilt/extension-ff35/platform/Linux_x86_64-gcc3/components/liboophm_ff35.so
deleted file mode 100755
index a65b4e6..0000000
--- a/plugins/xpcom/prebuilt/extension-ff35/platform/Linux_x86_64-gcc3/components/liboophm_ff35.so
+++ /dev/null
Binary files differ
diff --git a/plugins/xpcom/prebuilt/extension-ff35/platform/WINNT_x86-msvc/components/xpOOPHM.dll b/plugins/xpcom/prebuilt/extension-ff35/platform/WINNT_x86-msvc/components/xpOOPHM.dll
new file mode 100755
index 0000000..5b20eca
--- /dev/null
+++ b/plugins/xpcom/prebuilt/extension-ff35/platform/WINNT_x86-msvc/components/xpOOPHM.dll
Binary files differ
diff --git a/plugins/xpcom/prebuilt/extension/chrome.manifest b/plugins/xpcom/prebuilt/extension/chrome.manifest
index 38a0fdd..aaa29b3 100644
--- a/plugins/xpcom/prebuilt/extension/chrome.manifest
+++ b/plugins/xpcom/prebuilt/extension/chrome.manifest
@@ -1,2 +1,2 @@
-content gwt-oophm content/
-skin gwt-oophm classic/1.0 skin/
+content gwt-dmp content/
+skin gwt-dmp classic/1.0 skin/
diff --git a/plugins/xpcom/prebuilt/extension/content/options.xul b/plugins/xpcom/prebuilt/extension/content/options.xul
new file mode 100644
index 0000000..5aebd48
--- /dev/null
+++ b/plugins/xpcom/prebuilt/extension/content/options.xul
@@ -0,0 +1,64 @@
+<?xml version="1.0"?>
+<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
+
+<dialog buttons="accept"
+     id="gwt-dmp-prefs"
+     title="GWT Development Mode Plugin Options"
+     onload="GwtDevelopmentModePlugin.onload()"
+     ondialogaccept="return true;"
+     xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+
+<script type="application/x-javascript"
+    src="chrome://gwt-dmp/content/prefScript.js"/>
+
+<vbox flex="1">
+
+  <groupbox flex="1">
+    <caption>
+      <hbox>
+        <image src="chrome://gwt-dmp/skin/warning.png"/>
+        <label value="Security Restrictions" style="font-weight: bold"/>
+      </hbox>
+    </caption>
+    <description width="55em">
+      The GWT Development Mode Plugin will open a TCP/IP connection to an
+      arbitrary host/port at the request of a web page.  To minimize security
+      risks, by default it will only connect to the local machine.  To allow
+      cross-machine debugging, you can add exceptions here -- include the exact
+      host name of the web servers you will use for debugging, but do not
+      include any you do not trust.
+    </description>
+  </groupbox>
+
+  <hbox align="top" flex="1">
+    <hbox align="center" flex="1">
+      <label control="hostname" value="Host name: "/>
+      <textbox id="hostname" maxlength="40" flex="1"/>
+    </hbox>
+    <radiogroup id="incexc">
+      <radio id="include" label="Include" selected="true"/>
+      <radio id="exclude" label="Exclude"/>
+    </radiogroup>
+    <button id="addButton" label="Add Entry" oncommand="GwtDevelopmentModePlugin.addEntry()"/>
+  </hbox>
+
+  <listbox id="accessListListbox" rows="5">
+    <listhead>
+      <listheader label="Inc/Exc"/>
+      <listheader label="Host Name"/>
+    </listhead>
+    <listcols>
+      <listcol/>
+      <listcol flex="1"/>
+    </listcols>
+  </listbox>
+
+  <hbox>
+    <button id="removeButton" label="Remove Selected"
+        oncommand="GwtDevelopmentModePlugin.removeEntry()"/>
+    <!-- TODO(jat): add move up/down buttons -->
+  </hbox>
+
+</vbox>
+
+</dialog>
diff --git a/plugins/xpcom/prebuilt/extension/content/prefScript.js b/plugins/xpcom/prebuilt/extension/content/prefScript.js
new file mode 100644
index 0000000..9b3e052
--- /dev/null
+++ b/plugins/xpcom/prebuilt/extension/content/prefScript.js
@@ -0,0 +1,94 @@
+var GwtDevelopmentModePlugin = {
+
+// Add a new entry when the Add Entry button is clicked.
+addEntry: function() {
+  var prefs = this.getAccessList();
+  var hostname = document.getElementById("hostname").value;
+  if (!hostname || hostname.length == 0) {
+    alert("No host name provided");
+    return;
+  }
+  if (hostname.indexOf(",") >=0 || hostname.indexOf("!") >= 0) {
+    alert("Host name must not contain ',' or '!'");
+    return;
+  }
+  var exclude = document.getElementById("exclude");
+  var incText;
+  var prefix = "";
+  if (exclude.selected) {
+    incText = "Exclude";
+    prefix = "!";
+  } else {
+    incText = "Include";
+  }
+  var listboxEntry = this.makeLBE(incText, hostname);
+  var prefsEntry = prefix + hostname;
+  var listbox = document.getElementById("accessListListbox");
+  listbox.appendChild(listboxEntry);
+  prefs.push(prefsEntry.toString());
+  this.saveAccessList(prefs);
+},
+
+// Remove the selected entry when the Remove Entry button is clicked.
+removeEntry: function() {
+  var listbox = document.getElementById("accessListListbox");
+  var idx = listbox.selectedIndex;
+  if (idx >= 0) {
+    listbox.removeItemAt(idx);
+    var prefs = this.getAccessList();
+    prefs.splice(idx, 1);
+    this.saveAccessList(prefs);
+  }
+},
+
+// Populate the listbox when the dialog window is loaded
+onload: function() {
+  var listbox = document.getElementById("accessListListbox");
+  var prefs = this.getAccessList();
+  for (var i = 0 ; i < prefs.length; ++i) {
+    var pref = prefs[i];
+    var hostname = pref;
+    var incexc = "Include";
+    if (pref.length > 0 && pref.charAt(0) == "!") {
+      hostname = hostname.substr(1);
+      incexc = "Exclude";
+    }
+    var listboxEntry = this.makeLBE(incexc, hostname);
+    listbox.appendChild(listboxEntry);
+  }
+},
+
+// Internal - create a entry for the list box
+makeLBE: function(inc, hostname) {
+  var listboxEntry = document.createElement("listitem");
+  var lbeInc = document.createElement("listcell");
+  lbeInc.setAttribute("label", inc);
+  listboxEntry.appendChild(lbeInc);
+  var lbeHost = document.createElement("listcell");
+  lbeHost.setAttribute("label", hostname);
+  listboxEntry.appendChild(lbeHost);
+  return listboxEntry;
+},
+
+// Internal - load the access list from the gwt-dmp.accessList preference
+getAccessList: function() {
+  var prefServ = Components.classes["@mozilla.org/preferences-service;1"]
+                  .getService(Components.interfaces.nsIPrefService);
+  var prefs = prefServ.getBranch("gwt-dmp.");
+  var pref = prefs.getCharPref("accessList");
+  if (!pref) {
+    return [];
+  }
+  return pref.split(",");
+},
+
+// Internal - save the access list to the gwt-dmp.accessList preference
+saveAccessList: function(list) {
+  var prefServ = Components.classes["@mozilla.org/preferences-service;1"]
+                  .getService(Components.interfaces.nsIPrefService);
+  var prefs = prefServ.getBranch("gwt-dmp.");
+  prefs.setCharPref("accessList", list.join(","));
+  prefServ.savePrefFile(null);
+}
+
+};
diff --git a/plugins/xpcom/prebuilt/extension/defaults/preferences/defaults.js b/plugins/xpcom/prebuilt/extension/defaults/preferences/defaults.js
new file mode 100644
index 0000000..8b6558b
--- /dev/null
+++ b/plugins/xpcom/prebuilt/extension/defaults/preferences/defaults.js
@@ -0,0 +1 @@
+pref("gwt-dmp.accessList", "");
diff --git a/plugins/xpcom/prebuilt/extension/skin/README.txt b/plugins/xpcom/prebuilt/extension/skin/README.txt
new file mode 100644
index 0000000..7d212f0
--- /dev/null
+++ b/plugins/xpcom/prebuilt/extension/skin/README.txt
@@ -0,0 +1,2 @@
+warning.png generated from public domain SVG file found at
+  http://www.wowwiki.com/File:Icon-warning.svg
diff --git a/plugins/xpcom/prebuilt/extension/skin/warning.png b/plugins/xpcom/prebuilt/extension/skin/warning.png
new file mode 100644
index 0000000..55a203b
--- /dev/null
+++ b/plugins/xpcom/prebuilt/extension/skin/warning.png
Binary files differ
diff --git a/plugins/xpcom/prebuilt/gwt-dmp-ff2.xpi b/plugins/xpcom/prebuilt/gwt-dmp-ff2.xpi
new file mode 100644
index 0000000..098e7d7
--- /dev/null
+++ b/plugins/xpcom/prebuilt/gwt-dmp-ff2.xpi
Binary files differ
diff --git a/plugins/xpcom/prebuilt/gwt-dmp-ff3.xpi b/plugins/xpcom/prebuilt/gwt-dmp-ff3.xpi
new file mode 100644
index 0000000..658c12e
--- /dev/null
+++ b/plugins/xpcom/prebuilt/gwt-dmp-ff3.xpi
Binary files differ
diff --git a/plugins/xpcom/prebuilt/gwt-dmp-ff35.xpi b/plugins/xpcom/prebuilt/gwt-dmp-ff35.xpi
new file mode 100644
index 0000000..ffe6afc
--- /dev/null
+++ b/plugins/xpcom/prebuilt/gwt-dmp-ff35.xpi
Binary files differ
diff --git a/plugins/xpcom/prebuilt/oophm-xpcom-ff2.xpi b/plugins/xpcom/prebuilt/oophm-xpcom-ff2.xpi
deleted file mode 100644
index 96ae80f..0000000
--- a/plugins/xpcom/prebuilt/oophm-xpcom-ff2.xpi
+++ /dev/null
Binary files differ
diff --git a/plugins/xpcom/prebuilt/oophm-xpcom-ff3+.xpi b/plugins/xpcom/prebuilt/oophm-xpcom-ff3+.xpi
deleted file mode 100644
index 9e5cabc..0000000
--- a/plugins/xpcom/prebuilt/oophm-xpcom-ff3+.xpi
+++ /dev/null
Binary files differ
diff --git a/plugins/xpcom/prebuilt/oophm-xpcom-ff3.xpi b/plugins/xpcom/prebuilt/oophm-xpcom-ff3.xpi
deleted file mode 100644
index d7fd35a..0000000
--- a/plugins/xpcom/prebuilt/oophm-xpcom-ff3.xpi
+++ /dev/null
Binary files differ
diff --git a/plugins/xpcom/prebuilt/oophm-xpcom-ff35.xpi b/plugins/xpcom/prebuilt/oophm-xpcom-ff35.xpi
deleted file mode 100644
index 3bf14d8..0000000
--- a/plugins/xpcom/prebuilt/oophm-xpcom-ff35.xpi
+++ /dev/null
Binary files differ