diff --git a/dev/oophm/src/com/google/gwt/dev/shell/BrowserChannel.java b/dev/oophm/src/com/google/gwt/dev/shell/BrowserChannel.java
index e76ea89..99629c7 100644
--- a/dev/oophm/src/com/google/gwt/dev/shell/BrowserChannel.java
+++ b/dev/oophm/src/com/google/gwt/dev/shell/BrowserChannel.java
@@ -69,11 +69,16 @@
    * Class representing a reference to a JS object.
    */
   public static class JsObjectRef {
-    private int refId;
-
-    public JsObjectRef(int refId) {
+    
+    // TODO: refactor and remove this method.
+    public static void checkIdMap(int refId) {
       assert !JSOBJECT_ID_MAP.get().containsKey(refId)
-          || (JSOBJECT_ID_MAP.get().get(refId).get() == null);
+      || (JSOBJECT_ID_MAP.get().get(refId).get() == null);
+    }
+
+    private int refId;
+    
+    public JsObjectRef(int refId) {
       this.refId = refId;
     }
 
@@ -1325,6 +1330,7 @@
       }
     }
 
+    JsObjectRef.checkIdMap(refId);
     JsObjectRef toReturn = new JsObjectRef(refId);
     Reference<JsObjectRef> ref = new WeakReference<JsObjectRef>(toReturn,
         JSOBJECT_REF_QUEUE.get());
diff --git a/dev/oophm/src/com/google/gwt/dev/shell/BrowserChannelClient.java b/dev/oophm/src/com/google/gwt/dev/shell/BrowserChannelClient.java
new file mode 100644
index 0000000..4713e95
--- /dev/null
+++ b/dev/oophm/src/com/google/gwt/dev/shell/BrowserChannelClient.java
@@ -0,0 +1,201 @@
+/*
+ * 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.
+ */
+package com.google.gwt.dev.shell;
+
+import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.dev.shell.BrowserChannel.SessionHandler.ExceptionOrReturnValue;
+import com.google.gwt.dev.util.log.PrintWriterTreeLogger;
+
+import java.io.IOException;
+import java.net.Socket;
+
+/**
+ * Implementation of the BrowserChannel for the client side.
+ * 
+ */
+public class BrowserChannelClient extends BrowserChannel {
+
+  private static final int PROTOCOL_VERSION = 2;
+  private final HtmlUnitSessionHandler htmlUnitSessionHandler;
+  private final PrintWriterTreeLogger logger = new PrintWriterTreeLogger();
+  private final String moduleName;
+  private final String tabKey;
+  private final String sessionKey;
+  private final String url;
+  private final String versionString;
+  private boolean connected = false;
+
+  public BrowserChannelClient(String addressParts[], String url,
+      String sessionKey, String moduleName, String versionString,
+      HtmlUnitSessionHandler htmlUnitSessionHandler) throws IOException {
+    super(new Socket(addressParts[0], Integer.parseInt(addressParts[1])));
+    connected = true;
+    this.url = url;
+    this.sessionKey = sessionKey;
+    this.moduleName = moduleName;
+    this.tabKey = ""; // TODO(jat): update when tab support is added.
+    this.versionString = versionString;
+    logger.setMaxDetail(TreeLogger.WARN);
+    logger.log(TreeLogger.SPAM, "BrowserChannelClient, versionString: "
+        + versionString);
+    this.htmlUnitSessionHandler = htmlUnitSessionHandler;
+  }
+
+  public boolean disconnectFromHost() throws IOException {
+    logger.log(TreeLogger.DEBUG, "disconnecting channel " + this);
+    if (!isConnected()) {
+      logger.log(TreeLogger.DEBUG,
+          "Disconnecting already disconnected channel " + this);
+      return false;
+    }
+    new QuitMessage(this).send();
+    endSession();
+    connected = false;
+    return true;
+  }
+
+  public boolean isConnected() {
+    return connected;
+  }
+
+  // TODO (amitmanjhi): refer the state (message?) transition diagram
+  /**
+   * returns true iff execution completes normally.
+   */
+  public boolean process() throws IOException, BrowserChannelException {
+    if (!init()) {
+      disconnectFromHost();
+      return false;
+    }
+    logger.log(TreeLogger.DEBUG, "sending " + MessageType.LOAD_MODULE
+        + " message, userAgent: " + htmlUnitSessionHandler.getUserAgent());
+    ReturnMessage returnMessage = null;
+    synchronized (htmlUnitSessionHandler.getHtmlPage()) {
+      new LoadModuleMessage(this, url, tabKey, sessionKey, moduleName,
+          htmlUnitSessionHandler.getUserAgent()).send();
+      returnMessage = reactToMessages(htmlUnitSessionHandler, true);
+    }
+    logger.log(TreeLogger.DEBUG, "loaded module, returnValue: "
+        + returnMessage.getReturnValue() + ", isException: "
+        + returnMessage.isException());
+    return !returnMessage.isException();
+  }
+
+  public ReturnMessage reactToMessagesWhileWaitingForReturn(
+      HtmlUnitSessionHandler handler) throws IOException,
+      BrowserChannelException {
+    return reactToMessages(handler, true);
+  }
+
+  /*
+   * Perform the initial interaction. Return true if interaction succeeds, false
+   * if it fails. Do a check protocol versions, expected with 2.0+ oophm
+   * protocol.
+   */
+  private boolean init() throws IOException, BrowserChannelException {
+    logger.log(TreeLogger.DEBUG, "sending " + MessageType.CHECK_VERSIONS
+        + " message");
+    new CheckVersionsMessage(this, PROTOCOL_VERSION, PROTOCOL_VERSION,
+        versionString).send();
+    MessageType type = Message.readMessageType(getStreamFromOtherSide());
+    switch (type) {
+      case PROTOCOL_VERSION:
+        ProtocolVersionMessage protocolMessage = ProtocolVersionMessage.receive(this);
+        logger.log(TreeLogger.DEBUG, MessageType.PROTOCOL_VERSION
+            + ": protocol version = " + protocolMessage.getProtocolVersion());
+        // TODO(jat) : save selected protocol version when a range is supported.
+        break;
+      case FATAL_ERROR:
+        FatalErrorMessage errorMessage = FatalErrorMessage.receive(this);
+        logger.log(TreeLogger.ERROR, "Received FATAL_ERROR message "
+            + errorMessage.getError());
+        return false;
+      default:
+        return false;
+    }
+
+    return true;
+  }
+
+  private ReturnMessage reactToMessages(
+      HtmlUnitSessionHandler htmlUnitSessionHandler, boolean expectReturn)
+      throws IOException, BrowserChannelException {
+    while (true) {
+      ExceptionOrReturnValue returnValue;
+      MessageType type = Message.readMessageType(getStreamFromOtherSide());
+      logger.log(TreeLogger.INFO, "client: received " + type + ", thread: "
+          + Thread.currentThread().getName());
+      try {
+        switch (type) {
+          case INVOKE:
+            InvokeOnClientMessage invokeMessage = InvokeOnClientMessage.receive(this);
+            returnValue = htmlUnitSessionHandler.invoke(this,
+                invokeMessage.getThis(), invokeMessage.getMethodName(),
+                invokeMessage.getArgs());
+            htmlUnitSessionHandler.sendFreeValues(this);
+            new ReturnMessage(this, returnValue.isException(),
+                returnValue.getReturnValue()).send();
+            break;
+          case INVOKE_SPECIAL:
+            InvokeSpecialMessage invokeSpecialMessage = InvokeSpecialMessage.receive(this);
+            logger.log(TreeLogger.DEBUG, type + " message " + ", thisRef: "
+                + invokeSpecialMessage.getArgs());
+            returnValue = htmlUnitSessionHandler.invokeSpecial(this,
+                invokeSpecialMessage.getDispatchId(),
+                invokeSpecialMessage.getArgs());
+            htmlUnitSessionHandler.sendFreeValues(this);
+            new ReturnMessage(this, returnValue.isException(),
+                returnValue.getReturnValue()).send();
+            break;
+          case FREE_VALUE:
+            FreeMessage freeMessage = FreeMessage.receive(this);
+            logger.log(TreeLogger.DEBUG, type + " message "
+                + freeMessage.getIds());
+            htmlUnitSessionHandler.freeValue(this, freeMessage.getIds());
+            // no response
+            break;
+          case LOAD_JSNI:
+            LoadJsniMessage loadJsniMessage = LoadJsniMessage.receive(this);
+            String jsniString = loadJsniMessage.getJsni();
+            htmlUnitSessionHandler.loadJsni(this, jsniString);
+            // no response
+            break;
+          case RETURN:
+            if (!expectReturn) {
+              logger.log(TreeLogger.ERROR, "Received unexpected "
+                  + MessageType.RETURN);
+            }
+            return ReturnMessage.receive(this);
+          case QUIT:
+            if (expectReturn) {
+              logger.log(TreeLogger.ERROR, "Received " + MessageType.QUIT
+                  + " while waiting for return");
+            }
+            disconnectFromHost();
+            return null;
+          default:
+            logger.log(TreeLogger.ERROR, "Unkown messageType: " + type
+                + ", expectReturn: " + expectReturn);
+            disconnectFromHost();
+            return null;
+        }
+      } catch (Exception ex) {
+        logger.log(TreeLogger.ERROR, "Unknown exception" + ex);
+        ex.printStackTrace();
+      }
+    }
+  }
+}
diff --git a/dev/oophm/src/com/google/gwt/dev/shell/HostedModePluginObject.java b/dev/oophm/src/com/google/gwt/dev/shell/HostedModePluginObject.java
new file mode 100644
index 0000000..702d408
--- /dev/null
+++ b/dev/oophm/src/com/google/gwt/dev/shell/HostedModePluginObject.java
@@ -0,0 +1,188 @@
+/*
+ * 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.
+ */
+package com.google.gwt.dev.shell;
+
+import com.gargoylesoftware.htmlunit.javascript.host.Window;
+
+import net.sourceforge.htmlunit.corejs.javascript.Context;
+import net.sourceforge.htmlunit.corejs.javascript.Function;
+import net.sourceforge.htmlunit.corejs.javascript.Scriptable;
+import net.sourceforge.htmlunit.corejs.javascript.ScriptableObject;
+
+import java.io.IOException;
+
+/**
+ * HTMLUnit object that represents the hosted-mode plugin.
+ */
+public class HostedModePluginObject extends ScriptableObject {
+
+  /**
+   * Function object which implements the connect method on the hosted-mode
+   * plugin.
+   */
+  private class ConnectMethod extends ScriptableObject implements Function {
+
+    private static final long serialVersionUID = -8799481412144205779L;
+    private static final int EXPECTED_NUM_ARGS = 5;
+
+    public Object call(Context context, Scriptable scope, Scriptable thisObj,
+        Object[] args) {
+      // Allow extra arguments for forward compatibility
+      if (args.length < EXPECTED_NUM_ARGS) {
+        throw Context.reportRuntimeError("Bad number of parameters for function"
+            + " connect: expected "
+            + EXPECTED_NUM_ARGS
+            + ", got "
+            + args.length);
+      }
+      try {
+        /*
+         * connect arguments: url, sessionKey, ipAddress:port, moduleName,
+         * hostedHtmlVersion
+         */
+        return connect((String) args[0], (String) args[1], (String) args[2],
+            (String) args[3], (String) args[4]);
+      } catch (ClassCastException e) {
+        throw Context.reportRuntimeError("Incorrect parameter types for "
+            + " connect: expected String/String/String/String/String");
+      }
+    }
+
+    public Scriptable construct(Context context, Scriptable scope, Object[] args) {
+      throw Context.reportRuntimeError("Function connect can't be used as a "
+          + "constructor");
+    }
+
+    @Override
+    public String getClassName() {
+      return "function HostedModePluginObject.connect";
+    }
+  }
+
+  /**
+   * Function object which implements the init method on the hosted-mode plugin.
+   */
+  private class InitMethod extends ScriptableObject implements Function {
+
+    private static final long serialVersionUID = -8799481412144205779L;
+    private static final String VERSION = "2.0";
+
+    public Object call(Context context, Scriptable scope, Scriptable thisObj,
+        Object[] args) {
+      // Allow extra arguments for forward compatibility
+      if (args.length < 1) {
+        throw Context.reportRuntimeError("Bad number of parameters for function"
+            + " init: expected 1, got " + args.length);
+      }
+      try {
+        window = (Window) args[0];
+        // TODO (amitmanjhi): what checking needs to be done here for window?
+        return init(VERSION);
+      } catch (ClassCastException e) {
+        throw Context.reportRuntimeError("Incorrect parameter types for "
+            + " initt: expected String");
+      }
+    }
+
+    public Scriptable construct(Context context, Scriptable scope, Object[] args) {
+      throw Context.reportRuntimeError("Function init can't be used as a "
+          + "constructor");
+    }
+
+    @Override
+    public String getClassName() {
+      return "function HostedModePluginObject.init";
+    }
+  }
+
+  private static final long serialVersionUID = -1815031145376726799L;
+
+  private Scriptable connectMethod;
+  private Scriptable initMethod;
+  private Window window;
+
+  /**
+   * Initiate a hosted mode connection to the requested port and load the
+   * requested module.
+   * 
+   * @param url the complete url
+   * @param sessionKey a length 16 string to identify a "session"
+   * @param address "host:port" or "ipAddress:port" to use for the OOPHM server
+   * @param module module name to load
+   * @param version version string
+   * @return true if the connection succeeds
+   */
+  public boolean connect(String url, String sessionKey, String address,
+      String module, String version) {
+    String addressParts[] = address.split(":");
+    if (addressParts.length < 2) {
+      return false;
+    }
+    // TODO: add whitelist and default-port support?
+    System.out.println("connect(url=" + url + ", sessionKey=" + sessionKey
+        + ", address=" + address + ", module=" + module + ", version="
+        + version + "), window=" + System.identityHashCode(window) + ")");
+
+    try {
+      HtmlUnitSessionHandler htmlUnitSessionHandler = new HtmlUnitSessionHandler(window);
+      BrowserChannelClient browserChannelClient = new BrowserChannelClient(
+          addressParts, url, sessionKey, module, version,
+          htmlUnitSessionHandler);
+      htmlUnitSessionHandler.setSessionData(new SessionData(
+          htmlUnitSessionHandler, browserChannelClient));
+      return browserChannelClient.process();
+    } catch (BrowserChannelException e) {
+      e.printStackTrace();
+      return false;
+    } catch (IOException e) {
+      e.printStackTrace();
+      return false;
+    }
+  }
+
+  @Override
+  public Object get(String name, Scriptable start) {
+    if ("connect".equals(name)) {
+      if (connectMethod == null) {
+        connectMethod = new ConnectMethod();
+      }
+      return connectMethod;
+    } else if ("init".equals(name)) {
+      if (initMethod == null) {
+        initMethod = new InitMethod();
+      }
+      return initMethod;
+    }
+    return NOT_FOUND;
+  }
+
+  @Override
+  public String getClassName() {
+    return "HostedModePluginObject";
+  }
+
+  /**
+   * Verify that the plugin can be initialized properly and supports the
+   * requested version.
+   * 
+   * @param version hosted mode protocol version
+   * @return true if initialization succeeds, otherwise false
+   */
+  public boolean init(String version) {
+    // TODO: what needs to be done here?
+    return true;
+  }
+}
diff --git a/dev/oophm/src/com/google/gwt/dev/shell/HtmlUnitSessionHandler.java b/dev/oophm/src/com/google/gwt/dev/shell/HtmlUnitSessionHandler.java
new file mode 100644
index 0000000..201dafb
--- /dev/null
+++ b/dev/oophm/src/com/google/gwt/dev/shell/HtmlUnitSessionHandler.java
@@ -0,0 +1,290 @@
+/*
+ * 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.
+ */
+package com.google.gwt.dev.shell;
+
+import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.dev.shell.BrowserChannel.JavaObjectRef;
+import com.google.gwt.dev.shell.BrowserChannel.JsObjectRef;
+import com.google.gwt.dev.shell.BrowserChannel.SessionHandler;
+import com.google.gwt.dev.shell.BrowserChannel.Value;
+import com.google.gwt.dev.shell.BrowserChannel.Value.ValueType;
+import com.google.gwt.dev.util.log.PrintWriterTreeLogger;
+
+import com.gargoylesoftware.htmlunit.ScriptResult;
+import com.gargoylesoftware.htmlunit.html.HtmlPage;
+import com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine;
+import com.gargoylesoftware.htmlunit.javascript.host.Window;
+
+import net.sourceforge.htmlunit.corejs.javascript.Context;
+import net.sourceforge.htmlunit.corejs.javascript.Function;
+import net.sourceforge.htmlunit.corejs.javascript.Scriptable;
+import net.sourceforge.htmlunit.corejs.javascript.ScriptableObject;
+import net.sourceforge.htmlunit.corejs.javascript.Undefined;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.IdentityHashMap;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * Handle session tasks for HtmlUnit. TODO (amitmanjhi): refactor
+ * SessionHandler.
+ */
+public class HtmlUnitSessionHandler extends SessionHandler {
+
+  Map<Integer, JavaObject> javaObjectCache;
+  int nextId;
+
+  /**
+   * The htmlPage is also used to synchronize calls to Java code.
+   */
+  private HtmlPage htmlPage;
+
+  private Set<Integer> javaObjectsToFree;
+  private JavaScriptEngine jsEngine;
+  private IdentityHashMap<Scriptable, Integer> jsObjectToRef;
+
+  private final PrintWriterTreeLogger logger = new PrintWriterTreeLogger();
+
+  private int nextRefId = 1;
+  private Map<Integer, Scriptable> refToJsObject;
+
+  private SessionData sessionData;
+  private final Window window;
+
+  HtmlUnitSessionHandler(Window window) {
+    this.window = window;
+    logger.setMaxDetail(TreeLogger.ERROR);
+    jsEngine = this.window.getJavaScriptEngine();
+    htmlPage = (HtmlPage) this.window.getWebWindow().getEnclosedPage();
+    logger.log(TreeLogger.INFO, "jsEngine = " + jsEngine + ", HtmlPage = "
+        + htmlPage);
+
+    jsObjectToRef = new IdentityHashMap<Scriptable, Integer>();
+    javaObjectsToFree = new HashSet<Integer>();
+    nextRefId = 1;
+    refToJsObject = new HashMap<Integer, Scriptable>();
+    
+    // related to JavaObject cache.
+    nextId = 1; // skipping zero, reserved.
+    javaObjectCache = new HashMap<Integer, JavaObject>();
+  }
+
+  @Override
+  public void freeValue(BrowserChannel channel, int[] ids) {
+    for (int id : ids) {
+      Scriptable scriptable = refToJsObject.remove(id);
+      if (scriptable != null) {
+        jsObjectToRef.remove(scriptable);
+      }
+    }
+  }
+
+  public HtmlPage getHtmlPage() {
+    return htmlPage;
+  }
+
+  public JavaObject getOrCreateJavaObject(int refId, Context context) {
+    JavaObject javaObject = javaObjectCache.get(refId);
+    if (javaObject == null) {
+      javaObject = new JavaObject(context, sessionData, nextId++);
+      javaObjectCache.put(refId, javaObject);
+    }
+    return javaObject;
+  }
+
+  @Override
+  public ExceptionOrReturnValue getProperty(BrowserChannel channel, int refId,
+      int dispId) {
+    throw new UnsupportedOperationException(
+        "getProperty should not be called on the client-side");
+  }
+
+  public String getUserAgent() {
+    return "HtmlUnit-"
+        + jsEngine.getWebClient().getBrowserVersion().getUserAgent();
+  }
+
+  @Override
+  public ExceptionOrReturnValue invoke(BrowserChannel channel, Value thisObj,
+      int dispId, Value[] args) {
+    throw new UnsupportedOperationException(
+        "should not be called on the client side");
+  }
+
+  public ExceptionOrReturnValue invoke(BrowserChannel channel, Value thisObj,
+      String methodName, Value[] args) {
+    logger.log(TreeLogger.DEBUG, "INVOKE: thisObj: " + thisObj
+        + ", methodName: " + methodName + ", args: " + args);
+    /*
+     * 1. lookup functions by name. 2. Find context and scope. 3. Convert
+     * thisObject to ScriptableObject 4. Convert args 5. Get return value
+     */
+    Context jsContext = Context.getCurrentContext();
+    ScriptableObject jsThis;
+    if (thisObj.getType() == ValueType.NULL) {
+      jsThis = (ScriptableObject) window;
+    } else {
+      jsThis = (ScriptableObject) makeJsvalFromValue(jsContext, thisObj);
+    }
+    Object functionObject = ScriptableObject.getProperty(
+        (ScriptableObject) window, methodName);
+    if (functionObject == ScriptableObject.NOT_FOUND) {
+      logger.log(TreeLogger.ERROR, "function " + methodName
+          + " NOT FOUND, thisObj: " + jsThis + ", methodName: " + methodName);
+      // TODO: see if this maps to QUIT
+      return new ExceptionOrReturnValue(true, new Value(null));
+    }
+    Function jsFunction = (Function) functionObject;
+    logger.log(TreeLogger.SPAM, "INVOKE: jsFunction: " + jsFunction);
+
+    Object jsArgs[] = new Object[args.length];
+    for (int i = 0; i < args.length; i++) {
+      jsArgs[i] = makeJsvalFromValue(jsContext, args[i]);
+    }
+    Object result = null;
+    try {
+      result = jsEngine.callFunction(htmlPage, jsFunction, jsContext, window,
+          jsThis, jsArgs);
+    } catch (Exception ex) {
+      logger.log(TreeLogger.ERROR, "INVOKE: exception " + ex + ", message: "
+          + ex.getMessage() + " when invoking " + methodName);
+      return new ExceptionOrReturnValue(true, makeValueFromJsval(jsContext,
+          Undefined.instance));
+    }
+    logger.log(TreeLogger.INFO, "INVOKE: result: " + result
+        + " of jsFunction: " + jsFunction);
+    return new ExceptionOrReturnValue(false, makeValueFromJsval(jsContext,
+        result));
+  }
+
+  public ExceptionOrReturnValue invokeSpecial(BrowserChannel channel,
+      SpecialDispatchId specialDispatchId, Value[] args) {
+    throw new UnsupportedOperationException(
+        "InvokeSpecial must not be called on the client side");
+  }
+
+  public void loadJsni(BrowserChannel channel, String jsniString) {
+    logger.log(TreeLogger.SPAM, "LOAD_JSNI: " + jsniString);
+    ScriptResult scriptResult = htmlPage.executeJavaScript(jsniString);
+    logger.log(TreeLogger.INFO, "LOAD_JSNI: scriptResult=" + scriptResult);
+  }
+
+  @Override
+  public TreeLogger loadModule(TreeLogger logger, BrowserChannel channel,
+      String moduleName, String userAgent, String url, String tabKey,
+      String sessionKey) {
+    throw new UnsupportedOperationException("loadModule must not be called");
+  }
+
+  public Value makeValueFromJsval(Context jsContext, Object value) {
+    if (value == Undefined.instance) {
+      return new Value();
+    }
+    if (value instanceof JavaObject) {
+      Value returnVal = new Value();
+      int refId = ((JavaObject) value).getRefId();
+      returnVal.setJavaObject(new JavaObjectRef(refId));
+      return returnVal;
+    }
+    if (value instanceof Scriptable) {
+      Integer refId = jsObjectToRef.get((Scriptable) value);
+      if (refId == null) {
+        refId = nextRefId++;
+        jsObjectToRef.put((Scriptable) value, refId);
+        refToJsObject.put(refId, (Scriptable) value);
+      }
+      Value returnVal = new Value();
+      returnVal.setJsObject(new JsObjectRef(refId));
+      return returnVal;
+    }
+    return new Value(value);
+  }
+
+  // TODO: check synchronization and multi-threading
+  public void sendFreeValues(BrowserChannel channel) {
+    int size = javaObjectsToFree.size();
+    if (size == 0) {
+      return;
+    }
+    int ids[] = new int[size];
+    int index = 0;
+    for (int id : javaObjectsToFree) {
+      ids[index++] = id;
+    }
+    if (ServerMethods.freeJava(channel, this, ids)) {
+      javaObjectsToFree.clear();
+    }
+  }
+
+  @Override
+  public ExceptionOrReturnValue setProperty(BrowserChannel channel, int refId,
+      int dispId, Value newValue) {
+    throw new UnsupportedOperationException(
+        "setProperty should not be called on the client-side");
+  }
+
+  public void setSessionData(SessionData sessionData) {
+    this.sessionData = sessionData;
+  }
+
+  @Override
+  public void unloadModule(BrowserChannel channel, String moduleName) {
+    throw new UnsupportedOperationException("unloadModule must not be called");
+  }
+
+  /*
+   * Returning java objects works. No need to return NativeNumber, NativeString,
+   * NativeBoolean, or Undefined.
+   */
+  Object makeJsvalFromValue(Context jsContext, Value value) {
+    switch (value.getType()) {
+      case NULL:
+        return null;
+      case BOOLEAN:
+        if (value.getBoolean()) {
+          return Boolean.TRUE;
+        }
+        return Boolean.FALSE;
+      case BYTE:
+        return new Byte(value.getByte());
+      case CHAR:
+        return new Character(value.getChar());
+      case SHORT:
+        return new Short(value.getShort());
+      case INT:
+        return new Integer(value.getInt());
+      case FLOAT:
+        return new Float(value.getFloat());
+      case DOUBLE:
+        return new Double(value.getDouble());
+      case STRING:
+        return value.getString();
+      case JAVA_OBJECT:
+        JavaObjectRef javaRef = value.getJavaObject();
+        return JavaObject.getOrCreateJavaObject(javaRef, sessionData, jsContext);
+      case JS_OBJECT:
+        Scriptable scriptable = refToJsObject.get(value.getJsObject().getRefid());
+        assert scriptable != null;
+        return scriptable;
+      case UNDEFINED:
+        return Undefined.instance;
+    }
+    return null;
+  }
+
+}
diff --git a/dev/oophm/src/com/google/gwt/dev/shell/JavaObject.java b/dev/oophm/src/com/google/gwt/dev/shell/JavaObject.java
new file mode 100644
index 0000000..c400c28
--- /dev/null
+++ b/dev/oophm/src/com/google/gwt/dev/shell/JavaObject.java
@@ -0,0 +1,170 @@
+/*
+ * 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.
+ */
+package com.google.gwt.dev.shell;
+
+import com.google.gwt.dev.shell.BrowserChannel.InvokeOnServerMessage;
+import com.google.gwt.dev.shell.BrowserChannel.JavaObjectRef;
+import com.google.gwt.dev.shell.BrowserChannel.ReturnMessage;
+import com.google.gwt.dev.shell.BrowserChannel.Value;
+
+import net.sourceforge.htmlunit.corejs.javascript.Context;
+import net.sourceforge.htmlunit.corejs.javascript.Function;
+import net.sourceforge.htmlunit.corejs.javascript.Scriptable;
+import net.sourceforge.htmlunit.corejs.javascript.ScriptableObject;
+import net.sourceforge.htmlunit.corejs.javascript.Undefined;
+
+import java.io.IOException;
+
+/**
+ * Class to encapsulate JavaObject on the server side.
+ */
+public class JavaObject extends ScriptableObject implements Function {
+
+  private static final long serialVersionUID = -7923090130737830902L;
+
+  public static JavaObject getOrCreateJavaObject(JavaObjectRef javaRef,
+      SessionData sessionData, Context context) {
+    return sessionData.getSessionHandler().getOrCreateJavaObject(
+        javaRef.getRefid(), context);
+  }
+
+  static boolean isJavaObject(Context jsContext, ScriptableObject javaObject) {
+    return javaObject instanceof JavaObject;
+  }
+
+  private Context jsContext;
+
+  private final int objectRef;
+
+  private final SessionData sessionData;
+
+  public JavaObject(Context jsContext, SessionData sessionData, int objectRef) {
+    this.objectRef = objectRef;
+    this.sessionData = sessionData;
+    this.jsContext = jsContext;
+  }
+
+  /*
+   * If this function fails for any reason, we return Undefined instead of
+   * throwing an Exception in all cases except when Java throws an Exception.
+   */
+  public Object call(Context cx, Scriptable scope, Scriptable thisObj,
+      Object[] args) {
+
+    if (args.length < 2) {
+      return Undefined.instance;
+    }
+    Value valueArgs[] = new Value[args.length - 2];
+    for (int i = 0; i < valueArgs.length; i++) {
+      valueArgs[i] = sessionData.getSessionHandler().makeValueFromJsval(cx,
+          args[i + 2]);
+    }
+
+    /**
+     * Called when the JavaObject is invoked as a function. We ignore the
+     * thisObj argument, which is usually the window object.
+     * 
+     * Returns a JS array, with the first element being a boolean indicating
+     * that an exception occured, and the second element is either the return
+     * value or the exception which was thrown. In this case, we always return
+     * false and raise the exception ourselves.
+     */
+
+    Value thisValue = sessionData.getSessionHandler().makeValueFromJsval(cx,
+        args[1]);
+    int dispatchId = ((Number) args[0]).intValue();
+
+    ReturnMessage returnMessage = null;
+    synchronized (sessionData.getSessionHandler().getHtmlPage()) {
+      try {
+        new InvokeOnServerMessage(sessionData.getChannel(), dispatchId,
+            thisValue, valueArgs).send();
+      } catch (IOException e) {
+        return Undefined.instance;
+      }
+      try {
+        returnMessage = ((BrowserChannelClient) sessionData.getChannel()).reactToMessagesWhileWaitingForReturn(sessionData.getSessionHandler());
+      } catch (IOException e) {
+        return Undefined.instance;
+      } catch (BrowserChannelException e) {
+        return Undefined.instance;
+      }
+    }
+    Value returnValue = returnMessage.getReturnValue();
+    if (returnMessage.isException()) {
+      throw new RuntimeException("JavaObject.call failed, returnMessage: "
+          + returnValue.toString());
+    }
+    /*
+     * Return a object array ret. ret[0] is a boolean indicating whether an
+     * exception was thrown or not. ret[1] is the exception or the return value.
+     */
+    Object ret[] = new Object[2];
+    ret[0] = Boolean.FALSE;
+    ret[1] = sessionData.getSessionHandler().makeJsvalFromValue(cx, returnValue);
+    return ret;
+  }
+
+  public Scriptable construct(Context cx, Scriptable scope, Object[] args) {
+    throw Context.reportRuntimeError("JavaObject can't be used as a "
+        + "constructor");
+  }
+
+  // ignoring the 'start' argument.
+  @Override
+  public Object get(String name, Scriptable start) {
+    if ("toString".equals(name)) {
+      return sessionData.getToStringTearOff();
+    }
+    if ("id".equals(name)) {
+      return objectRef;
+    }
+    if ("__noSuchMethod__".equals(name)) {
+      return Undefined.instance;
+    }
+    System.err.println("Unknown property name in get " + name);
+    return Undefined.instance;
+  }
+
+  // ignoring the 'start' argument.
+  @Override
+  public Object get(int index, Scriptable start) {
+    Value value = ServerMethods.getProperty(sessionData.getChannel(),
+        sessionData.getSessionHandler(), objectRef, index);
+    return sessionData.getSessionHandler().makeJsvalFromValue(jsContext, value);
+  }
+
+  @Override
+  public String getClassName() {
+    return "Class JavaObject";
+  }
+
+  @Override
+  public void put(int dispatchId, Scriptable start, Object value) {
+    HtmlUnitSessionHandler sessionHandler = sessionData.getSessionHandler();
+    if (!ServerMethods.setProperty(sessionData.getChannel(), sessionHandler,
+        objectRef, dispatchId, sessionHandler.makeValueFromJsval(jsContext,
+            value))) {
+      // TODO: fix later.
+      throw new RuntimeException("setProperty failed");
+    }
+  }
+
+  int getRefId() {
+    return objectRef;
+  }
+
+}
diff --git a/dev/oophm/src/com/google/gwt/dev/shell/JsValueOOPHM.java b/dev/oophm/src/com/google/gwt/dev/shell/JsValueOOPHM.java
index 4ab0c77..0e3d7c5 100644
--- a/dev/oophm/src/com/google/gwt/dev/shell/JsValueOOPHM.java
+++ b/dev/oophm/src/com/google/gwt/dev/shell/JsValueOOPHM.java
@@ -144,6 +144,7 @@
    * @param jsRefId pointer to underlying JsRootedValue as an integer.
    */
   public JsValueOOPHM(int jsRefId) {
+    JsObjectRef.checkIdMap(jsRefId);
     this.value = new JsObjectRef(jsRefId);
   }
 
diff --git a/dev/oophm/src/com/google/gwt/dev/shell/ServerMethods.java b/dev/oophm/src/com/google/gwt/dev/shell/ServerMethods.java
new file mode 100644
index 0000000..e1051d3
--- /dev/null
+++ b/dev/oophm/src/com/google/gwt/dev/shell/ServerMethods.java
@@ -0,0 +1,117 @@
+/*
+ * 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.
+ */
+package com.google.gwt.dev.shell;
+
+import com.google.gwt.dev.shell.BrowserChannel.FreeMessage;
+import com.google.gwt.dev.shell.BrowserChannel.InvokeSpecialMessage;
+import com.google.gwt.dev.shell.BrowserChannel.ReturnMessage;
+import com.google.gwt.dev.shell.BrowserChannel.Value;
+import com.google.gwt.dev.shell.BrowserChannel.SessionHandler.SpecialDispatchId;
+
+import java.io.IOException;
+
+/**
+ * A class to encapsulate function invocations of objects on the server side.
+ */
+public class ServerMethods {
+  /**
+   * Tell the server that the client no longer has any references to the
+   * specified Java object.
+   * 
+   * @param ids ID of object to free
+   * @return false if an error occurred
+   */
+  static boolean freeJava(BrowserChannel channel,
+      HtmlUnitSessionHandler handler, int ids[]) {
+    if (!((BrowserChannelClient) channel).isConnected()) {
+      // ignoring freeJava after disconnect.
+      return true;
+    }
+    try {
+      new FreeMessage(channel, ids).send();
+    } catch (IOException e) {
+      return false;
+    }
+    return true;
+  }
+
+  /**
+   * Get the value of a property on an object.
+   * 
+   * @param objectRef ID of object to fetch field on
+   * @param dispatchId dispatch ID of field
+   * @return the value of the property, undef if none (or on error)
+   */
+  static Value getProperty(BrowserChannel channel,
+      HtmlUnitSessionHandler handler, int objectRef, int dispatchId) {
+    if (!((BrowserChannelClient) channel).isConnected()) {
+      // ignoring getProperty() after disconnect
+      return new Value();
+    }
+    Value args[] = new Value[2];
+    args[0] = new Value();
+    args[0].setInt(objectRef);
+    args[1] = new Value();
+    args[1].setInt(dispatchId);
+
+    synchronized (handler.getHtmlPage()) {
+      try {
+        new InvokeSpecialMessage(channel, SpecialDispatchId.GetProperty, args).send();
+        // TODO: refactor in order to remove cast.
+        ReturnMessage returnMessage = ((BrowserChannelClient) channel).reactToMessagesWhileWaitingForReturn(handler);
+        if (!returnMessage.isException()) {
+          return returnMessage.getReturnValue();
+        }
+      } catch (IOException e) {
+      } catch (BrowserChannelException e) {
+      }
+    }
+    return new Value();
+  }
+ 
+  /**
+   * Set the value of a property on an object.
+   * 
+   * @param objectRef ID of object to fetch field on
+   * @param dispatchId dispatch ID of field
+   * @param value value to store in the property
+   * @return false if an error occurred
+   */
+  static boolean setProperty(BrowserChannel channel,
+      HtmlUnitSessionHandler handler, int objectRef, int dispatchId, Value value) {
+    Value args[] = new Value[3];
+    for (int i = 0; i < args.length; i++) {
+      args[i] = new Value();
+    }
+    args[0].setInt(objectRef);
+    args[1].setInt(dispatchId);
+    args[2] = value;
+    synchronized (handler.getHtmlPage()) {
+      try {
+        new InvokeSpecialMessage(channel, SpecialDispatchId.SetProperty, args).send();
+        ReturnMessage returnMessage = ((BrowserChannelClient) channel).reactToMessagesWhileWaitingForReturn(handler);
+        if (!returnMessage.isException()) {
+          return true;
+        }
+      } catch (IOException e) {
+      } catch (BrowserChannelException e) {
+      }
+    }
+    // TODO: use the returned exception?
+    return false;
+  }
+
+}
diff --git a/dev/oophm/src/com/google/gwt/dev/shell/SessionData.java b/dev/oophm/src/com/google/gwt/dev/shell/SessionData.java
new file mode 100644
index 0000000..25428f2
--- /dev/null
+++ b/dev/oophm/src/com/google/gwt/dev/shell/SessionData.java
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+package com.google.gwt.dev.shell;
+
+/**
+ * A class to encapsulate data needed by {@code JavaObject}.
+ */
+public class SessionData {
+  private final BrowserChannel browserChannel;
+  private final HtmlUnitSessionHandler sessionHandler;
+  
+  public SessionData(HtmlUnitSessionHandler sessionHandler, BrowserChannel browserChannel) {
+    this.sessionHandler = sessionHandler;
+    this.browserChannel = browserChannel;
+  }
+
+  public BrowserChannel getChannel() {
+    return browserChannel;
+  }
+
+  public HtmlUnitSessionHandler getSessionHandler() {
+    return sessionHandler;
+  }
+  
+  public Object getToStringTearOff() {
+    // TODO Auto-generated method stub
+    return null;
+  }
+}
diff --git a/eclipse/dev/oophm/.classpath b/eclipse/dev/oophm/.classpath
index ab0e3f1..dc7e14f 100644
--- a/eclipse/dev/oophm/.classpath
+++ b/eclipse/dev/oophm/.classpath
@@ -4,6 +4,8 @@
 	<classpathentry kind="src" path="oophm/overlay"/>
 	<classpathentry exported="true" kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
 	<classpathentry exported="true" kind="var" path="GWT_TOOLS/lib/sun/swingworker/swing-worker-1.1.jar" sourcepath="/GWT_TOOLS/lib/sun/swingworker/swing-worker-1.1-src.zip"/>
+	<classpathentry kind="var" path="GWT_TOOLS/lib/htmlunit/htmlunit-core-js-2.5.jar" sourcepath="/GWT_TOOLS/lib/htmlunit/htmlunit-core-js-2.5-sources.jar"/>
+	<classpathentry kind="var" path="GWT_TOOLS/lib/htmlunit/htmlunit-2.5.jar" sourcepath="/GWT_TOOLS/lib/htmlunit/htmlunit-2.5-sources.jar"/>
 	<classpathentry combineaccessrules="false" kind="src" path="/gwt-dev-windows"/>
 	<classpathentry kind="output" path="bin"/>
 </classpath>
diff --git a/eclipse/user/.classpath b/eclipse/user/.classpath
index 37be02a..35baf69 100644
--- a/eclipse/user/.classpath
+++ b/eclipse/user/.classpath
@@ -24,6 +24,7 @@
 	<classpathentry kind="var" path="GWT_TOOLS/lib/xerces/xerces-2_9_1/xml-apis.jar" />
 	<classpathentry kind="var" path="GWT_TOOLS/lib/w3c/sac/sac-1.3.jar"/>
 	<classpathentry kind="var" path="GWT_TOOLS/lib/w3c/flute/flute-1.3.jar"/>
+	<classpathentry combineaccessrules="false" kind="src" path="/gwt-dev-oophm"/>
 	<classpathentry combineaccessrules="false" kind="src" path="/gwt-dev-windows"/>
 	<classpathentry kind="output" path="bin"/>
 </classpath>
diff --git a/user/build.xml b/user/build.xml
index 6a62d37..87bf4c8 100755
--- a/user/build.xml
+++ b/user/build.xml
@@ -49,6 +49,7 @@
         <pathelement location="${gwt.tools.lib}/selenium/selenium-java-client-driver.jar" />
         <pathelement location="${gwt.tools.lib}/w3c/sac/sac-1.3.jar" />
         <pathelement location="${gwt.tools.lib}/w3c/flute/flute-1.3.jar" />
+        <pathelement location="${gwt.build.lib}/gwt-dev-oophm.jar" />
         <pathelement location="${gwt.dev.jar}" />
       </classpath>
     </gwt.javac>
diff --git a/user/src/com/google/gwt/junit/JUnitShell.java b/user/src/com/google/gwt/junit/JUnitShell.java
index 54a6c58..244dc07 100644
--- a/user/src/com/google/gwt/junit/JUnitShell.java
+++ b/user/src/com/google/gwt/junit/JUnitShell.java
@@ -43,6 +43,7 @@
 import junit.framework.TestCase;
 import junit.framework.TestResult;
 
+import java.awt.GraphicsEnvironment;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -216,6 +217,32 @@
       registerHandler(new ArgHandlerString() {
         @Override
         public String getPurpose() {
+          return "Runs hosted mode via HTMLUnit given a list of browsers; "
+              + "e.g. IE6,IE7,FF2,FF3...";
+        }
+
+        @Override
+        public String getTag() {
+          return "-htmlunithosted";
+        }
+
+        @Override
+        public String[] getTagArgs() {
+          return new String[] {"browserNames"};
+        }
+
+        @Override
+        public boolean setString(String str) {
+          String[] targets = str.split(",");
+          runStyle = new RunStyleHtmlUnitHosted(JUnitShell.this, targets);
+          numClients = ((RunStyleHtmlUnit) runStyle).numBrowsers();
+          return runStyle != null;
+        }
+      });
+
+      registerHandler(new ArgHandlerString() {
+        @Override
+        public String getPurpose() {
           return "Runs web mode via HTMLUnit given a list of browsers; "
               + "e.g. " + RunStyleHtmlUnit.getBrowserList();
         }
@@ -400,7 +427,7 @@
    * begin running the test. "Contacted" does not necessarily mean "the test has
    * begun," e.g. for linker errors stopping the test initialization.
    */
-  private static final int TEST_BEGIN_TIMEOUT_MILLIS = 60000;
+  private static final int TEST_BEGIN_TIMEOUT_MILLIS = 6000000;
 
   /**
    * The amount of time to wait for all clients to complete a single test
@@ -590,7 +617,8 @@
    */
   private JUnitShell() {
     setRunTomcat(true);
-    setHeadless(true);
+    setHeadless(false);
+    setHeadless(GraphicsEnvironment.isHeadless());
 
     // Legacy: -Dgwt.hybrid runs web mode
     if (System.getProperty(PROP_JUNIT_HYBRID_MODE) != null) {
@@ -619,7 +647,8 @@
   protected void initializeLogger() {
     if (isHeadless()) {
       consoleLogger = new PrintWriterTreeLogger();
-      consoleLogger.setMaxDetail(getCompilerOptions().getLogLevel());
+      // TODO (amitmanjhi): GwtShell overlay fix.
+      consoleLogger.setMaxDetail(TreeLogger.INFO);
     } else {
       super.initializeLogger();
     }
@@ -683,20 +712,11 @@
     return !messageQueue.hasResult();
   }
 
-  @Override
+  // TODO (amitmanjhi): GwtShell overlay fix, removed Override.
   protected boolean shouldAutoGenerateResources() {
     return runStyle.shouldAutoGenerateResources();
   }
 
-  @Override
-  protected void sleep() {
-    if (runStyle.isLocal()) {
-      super.sleep();
-    } else {
-      messageQueue.waitForResults(1000);
-    }
-  }
-
   void compileForWebMode(String moduleName, String... userAgents)
       throws UnableToCompleteException {
     // Never fresh during JUnit.
@@ -881,7 +901,9 @@
       testBeginTime = System.currentTimeMillis();
       testBeginTimeout = testBeginTime + TEST_BEGIN_TIMEOUT_MILLIS;
       testMethodTimeout = 0; // wait until test execution begins
-      pumpEventLoop();
+      while (notDone()) {
+        messageQueue.waitForResults(1000);
+      }
     } catch (TimeoutException e) {
       lastLaunchFailed = true;
       testResult.addError(testCase, e);
diff --git a/user/src/com/google/gwt/junit/RunStyleHtmlUnit.java b/user/src/com/google/gwt/junit/RunStyleHtmlUnit.java
index e48ef8e..af5c022 100644
--- a/user/src/com/google/gwt/junit/RunStyleHtmlUnit.java
+++ b/user/src/com/google/gwt/junit/RunStyleHtmlUnit.java
@@ -58,6 +58,7 @@
       this.browser = browser;
       this.url = url;
       this.treeLogger = treeLogger;
+      this.setName("htmlUnit client thread");
     }
 
     public void handleAlert(Page page, String message) {
@@ -93,7 +94,7 @@
         // TODO(jat): is this necessary?
         webClient.waitForBackgroundJavaScriptStartingBefore(2000);
         page.getEnclosingWindow().getJobManager().waitForJobs(60000);
-        treeLogger.log(TreeLogger.DEBUG, "getPage returned "
+        treeLogger.log(TreeLogger.SPAM, "getPage returned "
             + ((HtmlPage) page).asXml());
         // TODO(amitmanjhi): call webClient.closeAllWindows()
       } catch (FailingHttpStatusCodeException e) {
@@ -182,7 +183,8 @@
 
   protected HtmlUnitThread createHtmlUnitThread(BrowserVersion browser,
       String url) {
-    return new HtmlUnitThread(browser, url, shell.getTopLogger());
+    return new HtmlUnitThread(browser, url, shell.getTopLogger().branch(
+        TreeLogger.SPAM, "logging for HtmlUnit thread"));
   }
 
   private Set<BrowserVersion> getBrowserSet(String[] targetsIn) {
diff --git a/user/src/com/google/gwt/junit/RunStyleHtmlUnitHosted.java b/user/src/com/google/gwt/junit/RunStyleHtmlUnitHosted.java
new file mode 100644
index 0000000..4d14581
--- /dev/null
+++ b/user/src/com/google/gwt/junit/RunStyleHtmlUnitHosted.java
@@ -0,0 +1,110 @@
+/*
+ * 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.
+ */
+package com.google.gwt.junit;
+
+import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.dev.shell.HostedModePluginObject;
+import com.google.gwt.dev.util.log.PrintWriterTreeLogger;
+
+import com.gargoylesoftware.htmlunit.BrowserVersion;
+import com.gargoylesoftware.htmlunit.WebClient;
+import com.gargoylesoftware.htmlunit.WebWindow;
+import com.gargoylesoftware.htmlunit.javascript.JavaScriptEngine;
+import com.gargoylesoftware.htmlunit.javascript.host.Window;
+
+import net.sourceforge.htmlunit.corejs.javascript.ScriptableObject;
+
+/**
+ * Runstyle for HTMLUnit in hosted mode.
+ */
+public class RunStyleHtmlUnitHosted extends RunStyleHtmlUnit {
+
+  /**
+   * Run HMTLUnit in a separate thread, replacing the default JavaScriptEngine
+   * with one that has the necessary hosted mode hooks.
+   */
+  protected static class HtmlUnitHostedThread extends HtmlUnitThread {
+
+    public HtmlUnitHostedThread(BrowserVersion browser, String url,
+        TreeLogger treeLogger) {
+      super(browser, url, treeLogger);
+    }
+
+    @Override
+    protected void setupWebClient(WebClient webClient) {
+      JavaScriptEngine hostedEngine = new HostedJavaScriptEngine(webClient);
+      webClient.setJavaScriptEngine(hostedEngine);
+    }
+  }
+
+  /**
+   * JavaScriptEngine subclass that provides a hook of initializing the
+   * __gwt_HostedModePlugin property on any new window, so it acts just like
+   * Firefox with the XPCOM plugin installed.
+   */
+  private static class HostedJavaScriptEngine extends JavaScriptEngine {
+
+    private static final long serialVersionUID = 3594816610842448691L;
+
+    public HostedJavaScriptEngine(WebClient webClient) {
+      super(webClient);
+    }
+
+    @Override
+    public void initialize(WebWindow webWindow) {
+      // Hook in the hosted-mode plugin after initializing the JS engine.
+      super.initialize(webWindow);
+      Window window = (Window) webWindow.getScriptObject();
+      window.defineProperty("__gwt_HostedModePlugin",
+          new HostedModePluginObject(), ScriptableObject.READONLY);
+    }
+  }
+
+  public static HtmlUnitThread createHtmlUnitThread(BrowserVersion browser,
+      String url, TreeLogger treeLogger) {
+    return new HtmlUnitHostedThread(browser, url, treeLogger);
+  }
+
+  public static void startHtmlUnitThread(String url) {
+    PrintWriterTreeLogger pw = new PrintWriterTreeLogger();
+    // TODO(amitmanjhi): get the correct browser emulation
+    HtmlUnitThread thread = createHtmlUnitThread(
+        BrowserVersion.FIREFOX_3, url, pw);
+    thread.start();
+  }
+
+  public RunStyleHtmlUnitHosted(JUnitShell unitShell, String[] targets) {
+    super(unitShell, targets);
+  }
+
+  @Override
+  public void maybeCompileModule(String moduleName) {
+    // No compilation needed for hosted mode
+  }
+
+  @Override
+  protected HtmlUnitThread createHtmlUnitThread(BrowserVersion browser,
+      String url) {
+    return RunStyleHtmlUnitHosted.createHtmlUnitThread(browser, url,
+        shell.getTopLogger());
+  }
+
+  @Override
+  protected String getMyUrl(String moduleName) {
+    // TODO(jat): get the correct address/port
+    return super.getMyUrl(moduleName) + "?gwt.hosted=localhost:9997";
+  }
+}
