diff --git a/branch-info.txt b/branch-info.txt
deleted file mode 100644
index bf03fda..0000000
--- a/branch-info.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-Created from trunk@6101
-========================
-svn copy -r6226 \
-    https://google-web-toolkit.googlecode.com/svn/branches/farewellSwt \
-    https://google-web-toolkit.googlecode.com/svn/changes/jat/noswt-merge6200
-
-Merges
-======
-svn merge https://google-web-toolkit.googlecode.com/svn/trunk \
-    -r6101:6142
-svn merge --ignore-ancestry -r6142:6200 \
-    https://google-web-toolkit.googlecode.com/svn/trunk
-    (via changes/jat/noswt-merge6200)
-svn merge https://google-web-toolkit.googlecode.com/svn/trunk \
-  -r6200:6239 .
-svn merge https://google-web-toolkit.googlecode.com/svn/trunk \
-  -r6239:6249 .
-svn merge https://google-web-toolkit.googlecode.com/svn/trunk \
-  --ignore-ancestry -r6249:6270 .
-svn merge --ignore-ancestry -r6280:6359 \
-    https://google-web-toolkit.googlecode.com/svn/changes/jat/abstractui
diff --git a/build.xml b/build.xml
index e468a51..9c97067 100755
--- a/build.xml
+++ b/build.xml
@@ -38,6 +38,7 @@
     <call-subproject subproject="dev" subtarget="build" />
     <call-subproject subproject="user" subtarget="build" />
     <call-subproject subproject="servlet" subtarget="build" />
+    <call-subproject subproject="jni" subtarget="build" />
   </target>
 
   <target name="dist" depends="build, doc" description="[action] Make all the distributions">
@@ -68,6 +69,10 @@
     <gwt.ant dir="servlet" />
   </target>
 
+  <target name="jni" description="[subdir] Builds (or runs ${target} if set) jni for all platforms">
+    <gwt.ant dir="jni" />
+  </target>
+
   <target name="doc" description="[subdir] Builds (or runs ${target} if set) the doc">
     <call-subproject subproject="user" subtarget="build" />
     <gwt.ant dir="doc" />
@@ -87,6 +92,7 @@
      <call-subproject subproject="user" subtarget="build"/>
      <call-subproject subproject="servlet" subtarget="build"/>
      <call-subproject subproject="tools" subtarget="build"/>
+     <call-subproject subproject="jni" subtarget="build"/>
      <call-subproject subproject="samples" subtarget="build"/>
   </target>
 
diff --git a/dev/core/src/com/google/gwt/dev/shell/CheckForUpdates.java b/dev/core/src/com/google/gwt/dev/shell/CheckForUpdates.java
index 30c699a..ac9bf00 100644
--- a/dev/core/src/com/google/gwt/dev/shell/CheckForUpdates.java
+++ b/dev/core/src/com/google/gwt/dev/shell/CheckForUpdates.java
@@ -18,6 +18,7 @@
 import com.google.gwt.core.ext.TreeLogger;
 import com.google.gwt.core.ext.TreeLogger.HelpInfo;
 import com.google.gwt.dev.About;
+import com.google.gwt.dev.shell.ie.CheckForUpdatesIE6;
 
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
@@ -34,7 +35,6 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.PrintWriter;
-import java.lang.reflect.Constructor;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.net.URLConnection;
@@ -190,15 +190,6 @@
   // The real URL that should be used.
   private static final String QUERY_URL = "http://tools.google.com/webtoolkit/currentversion.xml";
 
-  /**
-   * All of these classes must extend CheckForUpdates. Note that currently only
-   * IE has a custom implementation (to handle proxies) and that CheckForUpdates
-   * must be the last one in the list.
-   */
-  private static final String[] updaterClassNames = new String[] {
-      "com.google.gwt.dev.shell.ie.CheckForUpdatesIE6",
-      "com.google.gwt.dev.shell.CheckForUpdates"};
-
   public static FutureTask<UpdateResult> checkForUpdatesInBackgroundThread(
       final TreeLogger logger, final long minCheckMillis) {
     final String entryPoint = computeEntryPoint();
@@ -243,25 +234,12 @@
 
   public static CheckForUpdates createUpdateChecker(TreeLogger logger,
       String entryPoint) {
-    try {
-      for (int i = 0; i < updaterClassNames.length; i++) {
-        try {
-          Class<? extends CheckForUpdates> clazz = Class.forName(
-              updaterClassNames[i]).asSubclass(CheckForUpdates.class);
-          Constructor<? extends CheckForUpdates> ctor = clazz.getDeclaredConstructor(new Class[] {
-              TreeLogger.class, String.class});
-          CheckForUpdates checker = ctor.newInstance(new Object[] {
-              logger, entryPoint});
-          return checker;
-        } catch (Exception e) {
-          // Other exceptions can occur besides ClassNotFoundException,
-          // so ignore them all so we can find a functional updater.
-        }
-      }
-    } catch (Throwable e) {
-      // silently ignore any errors
+    // Windows has a custom implementation to handle proxies.
+    if (System.getProperty("os.name").toLowerCase().contains("win")) {
+      return new CheckForUpdatesIE6(logger, entryPoint);
+    } else {
+      return new CheckForUpdates(logger, entryPoint);
     }
-    return null;
   }
 
   public static void logUpdateAvailable(TreeLogger logger,
@@ -329,16 +307,6 @@
    * about an update if available.
    * 
    * @param logger TreeLogger to use
-   */
-  public CheckForUpdates(TreeLogger logger) {
-    this(logger, null);
-  }
-
-  /**
-   * Create an update checker which will poll a server URL and log a message
-   * about an update if available.
-   * 
-   * @param logger TreeLogger to use
    * @param entryPoint the name of the main entry point used for this execution
    */
   public CheckForUpdates(TreeLogger logger, String entryPoint) {
diff --git a/dev/core/src/com/google/gwt/dev/shell/LowLevel.java b/dev/core/src/com/google/gwt/dev/shell/LowLevel.java
deleted file mode 100644
index cab33b6..0000000
--- a/dev/core/src/com/google/gwt/dev/shell/LowLevel.java
+++ /dev/null
@@ -1,155 +0,0 @@
-/*
- * Copyright 2006 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 java.lang.reflect.Field;
-
-/**
- * Various cross-platform low-level helper methods.
- */
-public class LowLevel {
-
-  public static final String PACKAGE_PATH = LowLevel.class.getPackage().getName().replace(
-      '.', '/').concat("/");
-
-  private static boolean sInitialized = false;
-
-  /**
-   * Clobbers a field on an object to which we do not have access.
-   */
-  public static void clobberFieldObjectValue(Class<?> victimClass,
-      Object victimObject, String fieldName, Object value) {
-    Throwable rethrow = null;
-    try {
-      Field victimField = victimClass.getDeclaredField(fieldName);
-      victimField.setAccessible(true);
-      victimField.set(victimObject, value);
-      return;
-    } catch (IllegalArgumentException e) {
-      rethrow = e;
-    } catch (SecurityException e) {
-      rethrow = e;
-    } catch (IllegalAccessException e) {
-      rethrow = e;
-    } catch (NoSuchFieldException e) {
-      rethrow = e;
-    }
-    throw new RuntimeException("Unable to clobber field '" + fieldName
-        + "' from class " + victimClass.getName(), rethrow);
-  }
-
-  /**
-   * Clobbers a field on an object to which we do not have access.
-   */
-  public static void clobberFieldObjectValue(Object victim, String fieldName,
-      Object value) {
-    if (victim != null) {
-      clobberFieldObjectValue(victim.getClass(), victim, fieldName, value);
-    } else {
-      throw new NullPointerException("victim must not be null");
-    }
-  }
-
-  /**
-   * Deletes a global ref on the specified object, invalidating its handle.
-   */
-  public static void deleteGlobalRefInt(int globalRef) {
-    _deleteGlobalRefInt(globalRef);
-  }
-
-  /**
-   * Gets an environment variable. This is to replace the deprecated
-   * {@link System#getenv(java.lang.String)}.
-   */
-  public static String getEnv(String key) {
-    return _getEnv(key);
-  }
-
-  public static synchronized void init() {
-    if (!sInitialized) {
-      // TODO(jat): load native code for IE proxy handling?
-      sInitialized = true;
-    }
-  }
-
-  /**
-   * Creates a global ref on the specified object, returning its int handle.
-   */
-  public static int newGlobalRefInt(Object o) {
-    return _newGlobalRefInt(o);
-  }
-
-  /**
-   * Converts a global ref handle from {@link #newGlobalRefInt(Object)} into an
-   * Object. Use at your own risk.
-   */
-  public static Object objFromGlobalRefInt(int globalRef) {
-    return _objFromGlobalRefInt(globalRef);
-  }
-
-  /**
-   * Snatches a field from an object to which we do not have access.
-   */
-  @SuppressWarnings("unchecked")
-  public static <T> T snatchFieldObjectValue(Class<?> victimClass,
-      Object victimObject, String fieldName) {
-    Throwable rethrow = null;
-    try {
-      Field victimField = victimClass.getDeclaredField(fieldName);
-      victimField.setAccessible(true);
-      return (T) victimField.get(victimObject);
-    } catch (IllegalArgumentException e) {
-      rethrow = e;
-    } catch (SecurityException e) {
-      rethrow = e;
-    } catch (IllegalAccessException e) {
-      rethrow = e;
-    } catch (NoSuchFieldException e) {
-      rethrow = e;
-    }
-    throw new RuntimeException("Unable to snatch field '" + fieldName
-        + "' from class " + victimClass.getName(), rethrow);
-  }
-
-  /**
-   * Snatches a field from an object to which we do not have access.
-   */
-  public static Object snatchFieldObjectValue(Object victim, String fieldName) {
-    if (victim != null) {
-      return snatchFieldObjectValue(victim.getClass(), victim, fieldName);
-    } else {
-      throw new NullPointerException("victim must not be null");
-    }
-  }
-
-  // CHECKSTYLE_NAMING_OFF
-  private static native void _deleteGlobalRefInt(int globalRef);
-
-  private static native String _getEnv(String key);
-
-  private static native int _newGlobalRefInt(Object o);
-
-  private static native Object _objFromGlobalRefInt(int globalRef);
-
-  // CHECKSTYLE_NAMING_ON
-
-  /**
-   * This class is not instantiable.
-   */
-  private LowLevel() {
-  }
-
-}
diff --git a/dev/core/src/com/google/gwt/dev/shell/ie/CheckForUpdatesIE6.java b/dev/core/src/com/google/gwt/dev/shell/ie/CheckForUpdatesIE6.java
new file mode 100644
index 0000000..6e400ba
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/shell/ie/CheckForUpdatesIE6.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2007 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.ie;
+
+import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.dev.shell.CheckForUpdates;
+
+/**
+ * IE6 implementation of the update checker.
+ */
+public class CheckForUpdatesIE6 extends CheckForUpdates {
+
+  public CheckForUpdatesIE6(TreeLogger logger, String entryPoint) {
+    super(logger, entryPoint);
+  }
+
+  @Override
+  protected byte[] doHttpGet(TreeLogger branch, String userAgent, String url) {
+    if (LowLevelIE6.init()) {
+      return LowLevelIE6.httpGet(branch, userAgent, url,
+          System.getProperty(PROPERTY_DEBUG_HTTP_GET) != null);
+    } else {
+      return super.doHttpGet(branch, userAgent, url);
+    }
+  }
+
+}
diff --git a/dev/core/src/com/google/gwt/dev/shell/ie/LowLevelIE6.java b/dev/core/src/com/google/gwt/dev/shell/ie/LowLevelIE6.java
new file mode 100644
index 0000000..dd4b740
--- /dev/null
+++ b/dev/core/src/com/google/gwt/dev/shell/ie/LowLevelIE6.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2006 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.ie;
+
+import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.util.tools.Utility;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * Various low-level helper methods for dealing with COM and such.
+ */
+class LowLevelIE6 {
+
+  private static boolean sInitialized = false;
+
+  /**
+   * Does an HTTP GET that works with Windows proxy settings. Set the system
+   * property <code>gwt.debugLowLevelHttpGet</code> to print failure status
+   * codes to stderr.
+   * 
+   * @param userAgent the user-agent to specify for the GET
+   * @param url the absolute URL to GET
+   * @return the bytes of the full response (including headers), or
+   *         <code>null</code> if there's a problem
+   */
+  public static byte[] httpGet(TreeLogger branch, String userAgent, String url,
+      boolean debugFlag) {
+    if (!init()) {
+      return null;
+    }
+    byte[][] out = new byte[1][];
+    int status = _httpGet(userAgent, url, out);
+    if (status == 0) {
+      return out[0];
+    } else {
+      if (debugFlag) {
+        branch.log(TreeLogger.ERROR, "GET failed with status " + status
+            + " for " + url);
+      }
+      return null;
+    }
+  }
+
+  public static synchronized boolean init() {
+    if (!sInitialized) {
+      File lib = new File(Utility.getInstallPath(), "gwt-ll.dll");
+      if (!lib.exists()) {
+        return false;
+      }
+      try {
+        // Try to make canonical.
+        System.load(lib.getCanonicalPath());
+      } catch (IOException e) {
+        return false;
+      } catch (UnsatisfiedLinkError e) {
+        return false;
+      }
+      sInitialized = true;
+    }
+    return true;
+  }
+
+  // CHECKSTYLE_OFF
+  // out must be an array of size 1 to receive the array answer
+  private static native int _httpGet(String userAgent, String url, byte[][] out);
+
+  // CHECKSTYLE_ON
+
+  /**
+   * Not instantiable.
+   */
+  private LowLevelIE6() {
+  }
+}
diff --git a/distro-source/build.xml b/distro-source/build.xml
index 2a83261..9edb2e8 100755
--- a/distro-source/build.xml
+++ b/distro-source/build.xml
@@ -26,6 +26,9 @@
       <zipfileset file="${gwt.build.lib}/gwt-soyc-vis.jar" prefix="${project.distname}" />
       <zipfileset file="${gwt.build.lib}/gwt-api-checker.jar" prefix="${project.distname}" />
 
+      <!-- jni libs-->
+      <zipfileset dir="${gwt.build.jni}/windows" prefix="${project.distname}" />
+
       <!-- raw files -->
       <zipfileset dir="${dist.resources}" prefix="${project.distname}" />
       <zipfileset dir="src" prefix="${project.distname}" />
diff --git a/jni/build.xml b/jni/build.xml
new file mode 100755
index 0000000..fc25ce0
--- /dev/null
+++ b/jni/build.xml
@@ -0,0 +1,9 @@
+<project name="jni" default="build" basedir=".">
+  <property name="gwt.root" location=".." />
+  <property name="project.tail" value="jni" />
+  <import file="${gwt.root}/common.ant.xml" />
+
+  <target name="build" description="Build each platforms">
+    <gwt.ant dir="windows" target="build"/>
+  </target>
+</project>
diff --git a/jni/core/gwt-ll.cpp b/jni/core/gwt-ll.cpp
new file mode 100644
index 0000000..4076aea
--- /dev/null
+++ b/jni/core/gwt-ll.cpp
@@ -0,0 +1,66 @@
+// Copyright 2005-2006 Google Inc.
+// All Rights Reserved.
+
+// A slim and portable set of JNI methods for GWT hosted mode
+
+#include <jni.h>
+#include <stdlib.h>
+
+extern "C" {
+
+/*
+ * Class:     com_google_gwt_dev_shell_LowLevel
+ * Method:    newGlobalRefInt
+ * Signature: (Ljava/lang/Object;)I
+ */
+JNIEXPORT jint JNICALL Java_com_google_gwt_dev_shell_LowLevel__1newGlobalRefInt(JNIEnv* env, jclass, jobject o) {
+	return reinterpret_cast<int>(env->NewGlobalRef(o));
+}
+/*
+ * Class:     com_google_gwt_dev_shell_LowLevel
+ * Method:    objFromGlobalRefInt
+ * Signature: (I)Ljava/lang/Object;
+ */
+JNIEXPORT jobject JNICALL Java_com_google_gwt_dev_shell_LowLevel__1objFromGlobalRefInt(JNIEnv* env, jclass, jint globalRef) {
+	return reinterpret_cast<jobject>(globalRef);
+}
+
+/*
+ * Class:     com_google_gwt_dev_shell_LowLevel
+ * Method:    deleteGlobalRefInt
+ * Signature: (I)I
+ */
+JNIEXPORT void JNICALL Java_com_google_gwt_dev_shell_LowLevel__1deleteGlobalRefInt(JNIEnv* env, jclass, jint globalRef) {
+	env->DeleteGlobalRef(reinterpret_cast<jobject>(globalRef));
+}
+
+/*
+ * Class:     com_google_gwt_dev_shell_LowLevel
+ * Method:    getEnv
+ * Signature: (Ljava/lang/String;)Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_com_google_gwt_dev_shell_LowLevel__1getEnv(JNIEnv* env, jclass, jstring key) {
+    if (!key) {
+        // null -> null
+        return 0;
+    }
+
+	const char* keyPtr = env->GetStringUTFChars(key, 0);
+	if (!keyPtr) {
+		// There will be a pending OutOfMemoryException on this thread, so leave immediately and let it be thrown.
+		return 0;
+	}
+
+    const char* valuePtr = getenv(keyPtr);
+  	env->ReleaseStringUTFChars(key, keyPtr);
+
+    if (!valuePtr) {
+        // no match found
+        return 0;
+    }
+
+    // return the result
+	return env->NewStringUTF(valuePtr);
+}
+
+} // extern "C"
diff --git a/jni/linux/ExternalWrapper.cpp b/jni/linux/ExternalWrapper.cpp
new file mode 100644
index 0000000..3b2854e
--- /dev/null
+++ b/jni/linux/ExternalWrapper.cpp
@@ -0,0 +1,412 @@
+/*
+ * Copyright 2007 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.
+ */
+
+/*
+ * Defines the JavaScript class gwt_external_class, which interface via JNI
+ * to Java objects.
+ */
+
+#include <jni.h>
+#include "JsRootedValue.h"
+#include "gwt-jni.h"
+#include "ExternalWrapper.h"
+#include "Tracer.h"
+#include "JsStringWrap.h"
+
+#ifdef ENABLE_TRACING
+extern void PrintJSValue(JSContext* cx, jsval val, char* prefix="");
+#else
+// Include a null version just to keep from cluttering up call sites.
+static inline void PrintJSValue(JSContext* cx, jsval val, char* prefix="") { }
+#endif
+
+// note that this does not use the NS_DEFINE_CID macro because it defines
+// the variable as const, which by default has internal linkage.  I could
+// work around it by putting extern in front of the macro, but that seems
+// fragile if the macro changes.
+nsCID kGwtExternalCID = GWT_EXTERNAL_FACTORY_CID;
+
+/*
+ * definition of JavaScript gwtOnLoad method which maps to the Java
+ * gwtOnLoad method.
+ */
+static JSBool gwtOnLoad(JSContext *cx, JSObject *obj, uintN argc,
+    jsval *argv, jsval *rval)
+{
+  Tracer tracer("gwtOnLoad");
+  tracer.log("context=%08x", unsigned(cx));
+  JsRootedValue::ContextManager context(cx);
+  JsRootedValue::ensureRuntime(cx);
+  if (argc < 3) {
+    tracer.setFail("less than 3 args");
+    return JS_FALSE;
+  }
+
+  JSObject* scriptWindow = 0;
+  if (argv[0] != JSVAL_NULL && argv[0] != JSVAL_VOID) {
+    if (!JS_ValueToObject(cx, argv[0], &scriptWindow)) {
+      tracer.setFail("can't get script window object");
+      return JS_FALSE;
+    }
+  }
+
+  JSString* moduleName = 0;
+  if (argv[1] != JSVAL_NULL && argv[1] != JSVAL_VOID) {
+    moduleName = JS_ValueToString(cx, argv[1]);
+  }
+
+  JSString* version = 0;
+  if (argv[2] != JSVAL_NULL && argv[2] != JSVAL_VOID) {
+    version = JS_ValueToString(cx, argv[2]);
+  }
+
+  nsCOMPtr<nsIScriptGlobalObject> scriptGlobal(0);
+  if (scriptWindow) {
+    nsCOMPtr<nsIXPConnect> xpConnect = do_GetService(nsIXPConnect::GetCID());
+    nsCOMPtr<nsIXPConnectWrappedNative> wrappedNative;
+    xpConnect->GetWrappedNativeOfJSObject(cx, scriptWindow,
+        getter_AddRefs(wrappedNative));
+    if (wrappedNative) {
+        nsCOMPtr<nsISupports> native;
+        wrappedNative->GetNative(getter_AddRefs(native));
+        scriptGlobal = do_QueryInterface(native);
+    }
+  }
+  jstring jModuleName(0);
+  if (moduleName) {
+    jModuleName = savedJNIEnv->NewString(JS_GetStringChars(moduleName),
+        JS_GetStringLength(moduleName));
+    if (!jModuleName || savedJNIEnv->ExceptionCheck()) {
+      tracer.setFail("can't get module name in Java string");
+      return JS_FALSE;
+    }
+    tracer.log("module name=%s", JS_GetStringBytes(moduleName));
+  } else {
+    tracer.log("null module name");
+  }
+
+  jstring jVersion(0);
+  if (version) {
+    jVersion = savedJNIEnv->NewString(JS_GetStringChars(version),
+        JS_GetStringLength(version));
+    if (!jVersion || savedJNIEnv->ExceptionCheck()) {
+      tracer.setFail("can't get module name in Java string");
+      return JS_FALSE;
+    }
+    tracer.log("version=%s", JS_GetStringBytes(version));
+  } else {
+    tracer.log("null version");
+  }
+
+  jobject externalObject = NS_REINTERPRET_CAST(jobject, JS_GetPrivate(cx, obj));
+  jclass objClass = savedJNIEnv->GetObjectClass(externalObject);
+  if (!objClass || savedJNIEnv->ExceptionCheck()) {
+    tracer.setFail("can't get LowLevelMoz.ExternalObject class");
+    return JS_FALSE;
+  }
+
+  jmethodID methodID = savedJNIEnv->GetMethodID(objClass, "gwtOnLoad",
+      "(ILjava/lang/String;Ljava/lang/String;)Z");
+  if (!methodID || savedJNIEnv->ExceptionCheck()) {
+    tracer.setFail("can't get gwtOnLoad method");
+    return JS_FALSE;
+  }
+
+  tracer.log("scriptGlobal=%08x", unsigned(scriptGlobal.get()));
+
+  jboolean result = savedJNIEnv->CallBooleanMethod(externalObject, methodID,
+      NS_REINTERPRET_CAST(jint, scriptGlobal.get()), jModuleName, jVersion);
+  if (savedJNIEnv->ExceptionCheck()) {
+    tracer.setFail("LowLevelMoz.ExternalObject.gwtOnLoad() threw an exception");
+    return JS_FALSE;
+  }
+  *rval = BOOLEAN_TO_JSVAL((result == JNI_FALSE) ? JS_FALSE : JS_TRUE);
+  return JS_TRUE;
+}
+
+/*
+ * definition of JavaScript initModule method which maps to the Java
+ * initModule method.
+ */
+static JSBool initModule(JSContext *cx, JSObject *obj, uintN argc,
+    jsval *argv, jsval *rval)
+{
+  Tracer tracer("initModule");
+  tracer.log("context=%08x", unsigned(cx));
+  JsRootedValue::ContextManager context(cx);
+  JsRootedValue::ensureRuntime(cx);
+  if (argc < 1) {
+    tracer.setFail("less than 1 args");
+    return JS_FALSE;
+  }
+
+  JSString* moduleName = 0;
+  if (argv[0] != JSVAL_NULL && argv[0] != JSVAL_VOID) {
+    moduleName = JS_ValueToString(cx, argv[0]);
+  }
+
+  jstring jModuleName(0);
+  if (moduleName) {
+    jModuleName = savedJNIEnv->NewString(JS_GetStringChars(moduleName),
+        JS_GetStringLength(moduleName));
+    if (!jModuleName || savedJNIEnv->ExceptionCheck()) {
+      tracer.setFail("can't get module name in Java string");
+      return JS_FALSE;
+    }
+    tracer.log("module name=%s", JS_GetStringBytes(moduleName));
+  } else {
+    tracer.log("null module name");
+  }
+
+  jobject externalObject = NS_REINTERPRET_CAST(jobject, JS_GetPrivate(cx, obj));
+  jclass objClass = savedJNIEnv->GetObjectClass(externalObject);
+  if (!objClass || savedJNIEnv->ExceptionCheck()) {
+    tracer.setFail("can't get LowLevelMoz.ExternalObject class");
+    return JS_FALSE;
+  }
+
+  jmethodID methodID = savedJNIEnv->GetMethodID(objClass, "initModule",
+      "(Ljava/lang/String;)Z");
+  if (!methodID || savedJNIEnv->ExceptionCheck()) {
+    tracer.setFail("can't get initModule method");
+    return JS_FALSE;
+  }
+
+  jboolean result = savedJNIEnv->CallBooleanMethod(externalObject, methodID,
+      jModuleName);
+  if (savedJNIEnv->ExceptionCheck()) {
+    tracer.setFail("LowLevelMoz.ExternalObject.initModule() threw an exception");
+    return JS_FALSE;
+  }
+  *rval = BOOLEAN_TO_JSVAL((result == JNI_FALSE) ? JS_FALSE : JS_TRUE);
+  return JS_TRUE;
+}
+
+/*=======================================================================*/
+/* Implementation of the getProperty, setProperty, and finalize methods  */
+/* for the JavaScript class gwt_external_class.                          */
+/*=======================================================================*/
+
+static JSBool JS_DLL_CALLBACK gwt_external_getProperty(JSContext *cx,
+    JSObject *obj, jsval id, jsval *vp)
+{
+  Tracer tracer("gwt_external_getProperty");
+  JsRootedValue::ContextManager context(cx);
+  if (*vp != JSVAL_VOID) {
+    // we setup the gwtOnLoad function as a property in GetScriptObject and
+    // do not maintain a copy of it anywhere.  So, if there is a cached
+    // value for a property we must return it.  As we never redefine any
+    // property values, this is safe.  If we were going to keep this code
+    // around and add Toby's profiling code we would need to revisit this.
+    return JS_TRUE;
+  }
+
+  if (!JSVAL_IS_STRING(id)) {
+    tracer.setFail("not a string");
+    return JS_FALSE;
+  }
+  JsStringWrap jsStr(cx, id);
+  tracer.log("obj=%08x, property=%.*s", obj, jsStr.length(), jsStr.bytes());
+
+// All this is for calling resolveReference which only returns void.  So,
+// just replace this code to return void for now.  TODO(jat): revisit when
+// merging in Toby's code.
+#if 0
+  jstring jident = savedJNIEnv->NewString(jsStr.chars(), jsStr.length());
+  if (!jident || savedJNIEnv->ExceptionCheck()) {
+    tracer.setFail("can't create Java string ");
+    return JS_FALSE;
+  }
+  jobject externalObject = NS_REINTERPRET_CAST(jobject, JS_GetPrivate(cx, obj));
+  jclass objClass = savedJNIEnv->GetObjectClass(externalObject);
+  if (!objClass || savedJNIEnv->ExceptionCheck()) {
+    tracer.setFail("can't find Java class for JS object");
+    return JS_FALSE;
+  }
+
+  jmethodID methodID = savedJNIEnv->GetMethodID(objClass, "resolveReference",
+      "(Ljava/lang/String;)I");
+  if (!methodID || savedJNIEnv->ExceptionCheck()) {
+    tracer.setFail("exception getting method for int resolveReference(String)");
+    return JS_FALSE;
+  }
+  int retval = savedJNIEnv->CallIntMethod(externalObject, methodID, jident);
+  if (savedJNIEnv->ExceptionCheck()) {
+    tracer.setFail("exception calling int resolveReference(String)");
+    return JS_FALSE;
+  }
+  *vp = retval;
+#else
+  *vp = JSVAL_VOID;
+#endif
+  return JS_TRUE;
+}
+
+static void JS_DLL_CALLBACK gwt_external_finalize(JSContext *cx, JSObject *obj)
+{
+  // We don't need to push a context if all we do is DeleteGlobalRef
+  Tracer tracer("gwt_external_finalize", obj);
+  jobject externalObject = NS_REINTERPRET_CAST(jobject, JS_GetPrivate(cx, obj));
+  if (externalObject) {
+    savedJNIEnv->DeleteGlobalRef(externalObject);
+  }
+  JS_FinalizeStub(cx, obj);
+}
+
+static JSBool JS_DLL_CALLBACK gwt_external_setProperty(JSContext *cx,
+    JSObject *obj, jsval id, jsval *vp)
+{
+  return JS_FALSE;
+}
+ 
+static JSClass gwt_external_class = {
+    "gwt_external_class", JSCLASS_HAS_PRIVATE,
+    JS_PropertyStub, JS_PropertyStub, gwt_external_getProperty,
+    gwt_external_setProperty, JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub,
+    gwt_external_finalize,
+    JSCLASS_NO_OPTIONAL_MEMBERS
+};
+
+NS_IMPL_ISUPPORTS1(ExternalWrapper, nsIScriptObjectOwner)
+
+/*
+ * Create a new LowLevelMoz.ExternalObject instance and a JavaScript object
+ * that refers to it, mapping the gwtOnLoad member function mapping to
+ * a Javascript method.
+ */
+NS_IMETHODIMP ExternalWrapper::GetScriptObject(nsIScriptContext *aContext,
+    void** aScriptObject)
+{
+  Tracer tracer("ExternalWrapper::GetScriptObject"); 
+  if (!aScriptObject) {
+    tracer.setFail("null script object pointer");
+    return NS_ERROR_INVALID_POINTER;
+  }
+  if (!jsWindowExternalObject) {
+    JSContext* cx = NS_REINTERPRET_CAST(JSContext*,
+        aContext->GetNativeContext());
+    if (!cx) {
+      tracer.setFail("can't get JSContext");
+      return NS_ERROR_UNEXPECTED;
+    }
+    JsRootedValue::ContextManager context(cx);
+    *aScriptObject = 0;
+
+    nsIScriptGlobalObject* globalObject = aContext->GetGlobalObject();
+    nsCOMPtr<nsIDOMWindow> domWindow(do_QueryInterface(globalObject));
+    if (!domWindow) {
+      tracer.setFail("can't get DOM window");
+      return NS_ERROR_UNEXPECTED;
+    }
+    nsCOMPtr<nsIDOMWindow> topWindow;
+    domWindow->GetTop(getter_AddRefs(topWindow));
+    if (!topWindow) {
+      tracer.setFail("Can't get top window");
+      return NS_ERROR_UNEXPECTED;
+    }
+
+    tracer.log("savedJNIEnv=%08x, llClass=%08x", unsigned(savedJNIEnv),
+        lowLevelMozClass);
+    
+    jmethodID methodID = savedJNIEnv->GetStaticMethodID(lowLevelMozClass,
+        "createExternalObjectForDOMWindow",
+        "(I)Lcom/google/gwt/dev/shell/moz/LowLevelMoz$ExternalObject;");
+    if (!methodID || savedJNIEnv->ExceptionCheck()) {
+      tracer.setFail("Can't get createExternalObjectForDOMWindow method");
+      return NS_ERROR_UNEXPECTED;
+    }
+
+    jobject externalObject = savedJNIEnv->CallStaticObjectMethod(
+        lowLevelMozClass, methodID, NS_REINTERPRET_CAST(jint, topWindow.get()));
+    if (!externalObject || savedJNIEnv->ExceptionCheck()) {
+      tracer.setFail("createExternalObjectForDOMWindow failed");
+      return NS_ERROR_UNEXPECTED;
+    }
+    externalObject = savedJNIEnv->NewGlobalRef(externalObject);
+    if (!externalObject || savedJNIEnv->ExceptionCheck()) {
+      tracer.setFail("can't get GlobalRef for external object");
+      return NS_ERROR_UNEXPECTED;
+    }
+    JSObject* newObj = JS_NewObject(cx, &gwt_external_class, 0,
+        globalObject->GetGlobalJSObject());
+    if (!newObj) {
+      tracer.setFail("can't create new gwt_external_class object");
+      return NS_ERROR_OUT_OF_MEMORY;
+    }
+    if (!JS_SetPrivate(cx, newObj, externalObject)) {
+      savedJNIEnv->DeleteGlobalRef(externalObject);
+      tracer.setFail("can't store external object private reference");
+      return NS_ERROR_UNEXPECTED;
+    }
+  
+    if (!JS_DefineFunction(cx, newObj, "gwtOnLoad", gwtOnLoad, 3,
+        JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT)) {
+      tracer.setFail("can't define gwtOnLoad function on JavaScript object");
+      return NS_ERROR_UNEXPECTED;
+    }
+    if (!JS_DefineFunction(cx, newObj, "initModule", initModule, 1,
+        JSPROP_ENUMERATE | JSPROP_READONLY | JSPROP_PERMANENT)) {
+      tracer.setFail("can't define initModule function on JavaScript object");
+      return NS_ERROR_UNEXPECTED;
+    }
+    jsWindowExternalObject = newObj;
+  }
+
+  *aScriptObject = jsWindowExternalObject;
+  return NS_OK;
+}
+
+NS_IMETHODIMP ExternalWrapper::SetScriptObject(void* aScriptObject)
+{
+    jsWindowExternalObject = aScriptObject;
+    return NS_OK;
+}
+
+NS_IMPL_ISUPPORTS1(nsRpExternalFactory, nsIFactory)
+
+NS_IMETHODIMP nsRpExternalFactory::CreateInstance(nsISupports *aOuter,
+    const nsIID& aIID, void** aResult)
+{
+  Tracer tracer("nsRpExternalFactory::CreateInstance");
+  if (!aResult) {
+    tracer.setFail("null pointer for return value");
+    return NS_ERROR_INVALID_POINTER;
+  }
+  *aResult  = NULL;
+
+  if (aOuter) {
+    tracer.setFail("aOuter is not null");
+    return NS_ERROR_NO_AGGREGATION;
+  }
+
+  nsISupports* object = new ExternalWrapper();
+  if (!object) {
+    tracer.setFail("can't create a new ExternalWrapper");
+    return NS_ERROR_OUT_OF_MEMORY;
+  }
+
+  nsresult result = object->QueryInterface(aIID, aResult);
+  if (!*aResult || NS_FAILED(result)) {
+    tracer.setFail("ExternalWrapper::QueryInterface failed");
+    delete object;
+  }
+  return result;
+}
+
+NS_IMETHODIMP nsRpExternalFactory::LockFactory(PRBool lock)
+{
+    return NS_ERROR_NOT_IMPLEMENTED;
+}
diff --git a/jni/linux/ExternalWrapper.h b/jni/linux/ExternalWrapper.h
new file mode 100644
index 0000000..0168083
--- /dev/null
+++ b/jni/linux/ExternalWrapper.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2006 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.
+ */
+
+#ifndef EXTERNALWRAPPER_H_
+#define EXTERNALWRAPPER_H_
+
+class ExternalWrapper : public nsIScriptObjectOwner {
+public:
+  NS_DECL_ISUPPORTS
+  NS_IMETHOD GetScriptObject(nsIScriptContext *aContext, void** aScriptObject);
+  NS_IMETHOD SetScriptObject(void* aScriptObject);
+  ExternalWrapper(): jsWindowExternalObject(0) { }
+private:
+  ~ExternalWrapper() { }
+  void *jsWindowExternalObject;
+};
+
+class nsRpExternalFactory : public nsIFactory {
+public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIFACTORY
+  nsRpExternalFactory() { }
+private:
+  ~nsRpExternalFactory() { }
+};
+
+#define GWT_EXTERNAL_FACTORY_CID \
+{ 0xF56E23F8, 0x5D06, 0x47F9, \
+{ 0x88, 0x5A, 0xD9, 0xCA, 0xC3, 0x38, 0x41, 0x7F } }
+#define GWT_EXTERNAL_CONTRACTID "@com.google/GWT/external;1"
+
+#endif /*EXTERNALWRAPPER_H_*/
diff --git a/jni/linux/JStringWrap.h b/jni/linux/JStringWrap.h
new file mode 100644
index 0000000..9d2ebcc
--- /dev/null
+++ b/jni/linux/JStringWrap.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2007 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.
+ */
+
+#ifndef JNI_LINUX_JSTRINGWRAP_H_
+#define JNI_LINUX_JSTRINGWRAP_H_
+
+/*
+ * Wrapper arouond Java Strings, keeps pointers to unpacked strings
+ * and makes sure they are cleaned up. 
+ */
+class JStringWrap {
+  public:
+    JStringWrap(JNIEnv* env, jstring str): env(env), s(str), p(0), jp(0) { }
+    ~JStringWrap() {
+      if (p) env->ReleaseStringUTFChars(s, p);
+      if (jp) env->ReleaseStringChars(s, jp);
+    }
+    const char* str() {
+      if (!p) p = env->GetStringUTFChars(s, 0);
+      return p;
+    }
+    const jchar* jstr() {
+      if (!jp) jp = env->GetStringChars(s, 0);
+      return jp;
+    }
+    int length() {
+      return env->GetStringLength(s);
+    }
+  private:
+    JNIEnv* env;
+    jstring s;
+    const char* p;
+    const jchar* jp;
+};
+
+
+#endif // JNI_LINUX_JSTRINGWRAP_H_
diff --git a/jni/linux/JsRootedValue.cpp b/jni/linux/JsRootedValue.cpp
new file mode 100644
index 0000000..29b95ca
--- /dev/null
+++ b/jni/linux/JsRootedValue.cpp
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2007 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 "JsRootedValue.h"
+
+// Initialize static value used to hold the JavaScript String class.
+JSClass* JsRootedValue::stringClass = 0;
+
+// Initialize static reference to the sole JSRuntime value in Gecko.
+JSRuntime* JsRootedValue::runtime = 0;
+
+// Static stack of JavaScript execution contexts.
+std::stack<JSContext*> JsRootedValue::contextStack;
+
+/*
+ * Actually get the stringClass pointer from JavaScript.
+ */
+void JsRootedValue::fetchStringClass() const {
+  Tracer tracer("JsRootedValue::fetchStringClass");
+  JSContext* cx = currentContext();
+  jsval val = JS_GetEmptyStringValue(cx);
+  JSObject* obj;
+  // on error, leave stringClass null
+  if (!JS_ValueToObject(cx, val, &obj)) return;
+  if (!obj) {
+    tracer.log("ensureStringClass: null object");
+    return;
+  }
+  stringClass = JS_GET_CLASS(cx, obj);
+  tracer.log("stringClass=%08x", unsigned(stringClass));
+}
diff --git a/jni/linux/JsRootedValue.h b/jni/linux/JsRootedValue.h
new file mode 100644
index 0000000..65c25af
--- /dev/null
+++ b/jni/linux/JsRootedValue.h
@@ -0,0 +1,428 @@
+/*
+ * Copyright 2007 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.
+ */
+#ifndef JNI_LINUX_JSROOTEDVALUE_H_
+#define JNI_LINUX_JSROOTEDVALUE_H_
+
+// Mozilla header files
+#include "mozilla-headers.h"
+
+#include "Tracer.h"
+#include <stack>
+
+extern "C" JSClass gwt_nativewrapper_class;
+
+/*
+ * Holds a root for Javascript objects, so the JS interpreter knows not to
+ * garbage-collect the underlying object as long as this object exists.
+ * Java code will pass a pointer to this object around (as an int/long) for
+ * referring to the underlying Javascript object.
+ *
+ * There are also convenience routines for manipulating the underlying value.
+ * Note that all get* methods assume the type is correct, so the corresponding
+ * is* method should be called first if you aren't sure of the type.
+ *
+ * See http://developer.mozilla.org/en/docs/JS_AddRoot for details.
+ *
+ * TODO(jat): rewrite this to minimize the number of roots held and to
+ *    improve 64-bit compatibility.
+ */
+class JsRootedValue
+{
+private:
+  // the JavaScript String class
+  static JSClass* stringClass;
+  
+  // Javascript runtime
+  static JSRuntime* runtime;
+
+  // stack of Javascript contexts
+  static std::stack<JSContext*> contextStack;
+
+  // underlying Javascript value
+  jsval         value_;
+
+protected:
+  /*
+   * Fetch the JavaScript String class.
+   * Not inlined to minimize code bloat since it should only be called once.
+   */
+  void fetchStringClass() const;
+  
+  /*
+   * Make sure we have the JS code to identify String objects installed.
+   */
+  void ensureStringClass() const {
+    if(stringClass) return;
+    fetchStringClass();
+  }
+  
+  /*
+   * Helper for the various constructors
+   */
+  void constructorHelper(const char* ctorDesc) {
+    Tracer tracer(ctorDesc, this);
+    if (!JS_AddNamedRootRT(runtime, &value_, ctorDesc)) {
+      tracer.log("JS_AddNamedRootRT failed");
+      // TODO(jat): handle errors
+    }
+  }
+
+  /*
+   * Push a new JavaScript execution context.
+   */
+  static void pushContext(JSContext* context) {
+    Tracer tracer("JsRootedValue::pushContext");
+    tracer.log("pushed context=%08x", unsigned(context));
+    contextStack.push(context);
+  }
+  
+  /*
+   * Pop a JavaScript execution context from the context stack.
+   */
+  static void popContext() {
+    Tracer tracer("JsRootedValue::popContext");
+    JSContext* context = currentContext();
+    contextStack.pop();
+    tracer.log("popped context=%08x", unsigned(context));
+  }
+
+public:
+  /*
+   * This is a helper class used to push/pop JSContext values automatically,
+   * using RAII.  Simply create a ContextManager object on the stack and it
+   * will push the context at creation time and pop it at destruction time,
+   * so you don't have to worry about covering all the exit paths from a
+   * function.
+   */
+  class ContextManager {
+  public:
+    explicit ContextManager(JSContext* context) {
+      JsRootedValue::pushContext(context);
+    }
+    ~ContextManager() {
+      JsRootedValue::popContext();
+    }
+  };
+
+  /*
+   * This is a helper class to manage short-lived roots on the stack, using
+   * RAII to free the roots when no longer needed.
+   */
+  class Temp {
+  private:
+    void* ptr_;
+  public:
+    explicit Temp(void* ptr) : ptr_(ptr) {
+      JS_AddNamedRootRT(runtime, ptr_, "temporary root");
+    }
+    ~Temp() {
+      JS_RemoveRootRT(runtime, ptr_);
+    }
+  };
+  
+  /*
+   * Copy constructor - make another rooted value that refers to the same
+   * JavaScript object (or has the same value if a primitive)
+   */
+  JsRootedValue(const JsRootedValue& rooted_value) : value_(rooted_value.value_)
+  {
+    constructorHelper("JsRootedValue copy ctor");
+  }
+  
+  /*
+   * Create a value with a given jsval value
+   */
+  JsRootedValue(jsval value) : value_(value)
+  {
+    constructorHelper("JsRootedValue jsval ctor");
+  }
+  
+  /*
+   * Create a void value
+   */
+  JsRootedValue() : value_(JSVAL_VOID) {
+    constructorHelper("JsRootedValue void ctor");
+  }
+  
+  /*
+   * Destroy this object.
+   */
+  ~JsRootedValue() {
+    Tracer tracer("~JsRootedValue", this);
+    // ignore error since currently it is not possible to fail
+    JS_RemoveRootRT(runtime, &value_);
+  }
+  
+  /*
+   * Save a pointer to the JSRuntime if we don't have it yet
+   */
+  static void ensureRuntime(JSContext* context) {
+    if(!runtime) runtime = JS_GetRuntime(context);
+  }
+  
+  /*
+   * Return the current JavaScript execution context.
+   */
+  static JSContext* currentContext() {
+    Tracer tracer("JsRootedValue::currentContext");
+    if (contextStack.empty()) {
+      // TODO(jat): better error handling?
+      fprintf(stderr, "JsRootedValue::currentContext - context stack empty\n");
+      ::abort();
+    }
+    JSContext* context = contextStack.top();
+    tracer.log("context=%08x", unsigned(context));
+    return context;
+  }
+
+  /* 
+   * Return the underlying JS object
+   */
+  jsval getValue() const { return value_; }
+  
+  /*
+   * Sets the value of the underlying JS object.
+   * 
+   * Returns false if an error occurred.
+   */
+  bool setValue(jsval new_value) {
+    value_ = new_value;
+    return true;
+  }
+  
+   /*
+   * Returns true if the underlying value is of some number type.
+   */
+  bool isNumber() const {
+    return JSVAL_IS_NUMBER(value_);
+  }
+  /*
+   * Returns the underlying value as a double.
+   * Result is 0.0 if the underlying value is not a number
+   * type.
+   */
+  double getDouble() const {
+    jsdouble return_value=0.0;
+    // ignore return value -- if it fails, value will remain 0.0
+    JS_ValueToNumber(currentContext(), value_, &return_value); 
+    return double(return_value);
+  }
+  /*
+   * Set the underlying value to a double value.
+   * 
+   * Returns false on failure.
+   */
+  bool setDouble(double val) {
+    jsval js_double;
+    if(!JS_NewDoubleValue(currentContext(), jsdouble(val), &js_double)) {
+      return false;
+    }
+    return setValue(js_double);
+  }
+
+  /*
+   * Returns the underlying value as an integer value.  Note that the result
+   * is undefined if isInt() does not return true.
+   */
+  int getInt() {
+    return JSVAL_TO_INT(value_);
+  }
+  
+  /*
+   * Set the underlying value to an integer value.
+   * 
+   * Returns false on failure.
+   */
+  bool setInt(int val) {
+    // check if it fits in 31 bits (ie, top two bits are equal).
+    // if not, store it as a double
+    if ((val & 0x80000000) != ((val << 1) & 0x80000000)) {
+      return setDouble(val);
+    } else {
+      return setValue(INT_TO_JSVAL(val));
+    }
+  }
+  
+  /*
+   * Returns true if the underlying value is a boolean.
+   */
+  bool isBoolean() const {
+    return JSVAL_IS_BOOLEAN(value_);
+  }
+  /*
+   * Returns the underlying value as a boolean.
+   * Result is undefined if the value is not actually
+   * a boolean.
+   */
+  bool getBoolean() const {
+    return value_ != JSVAL_FALSE;
+  }
+  /*
+   * Set the underlying value to a boolean value.
+   * 
+   * Returns false on failure (impossible?).
+   */
+  bool setBoolean(bool val) {
+    return setValue(val ? JSVAL_TRUE : JSVAL_FALSE);
+  }
+
+  /*
+   * Returns true if the underlying value is a string.
+   */
+  bool isInt() const {
+    return JSVAL_IS_INT(value_);
+  }
+  
+  /*
+   * Returns true if the underlying value is a string.
+   */
+  bool isString() const {
+    return JSVAL_IS_STRING(value_);
+  }
+
+  /*
+   * Check if the value is a JavaScript String object.
+   */
+  bool isJavaScriptStringObject() const {
+    if (!isObject()) return false;
+    ensureStringClass();
+    return getObjectClass() == stringClass;
+  }
+  
+  /*
+   * Return this value as a string, converting as necessary.
+   */
+  JSString* asString() const {
+    return JS_ValueToString(currentContext(), value_);
+  }
+  
+  /* Returns the string as a JSString pointer.
+   * Result is undefined if the value is not actually a string or String object.
+   */
+  const JSString* getString() const {
+    if (JSVAL_IS_STRING(value_)) {
+      return JSVAL_TO_STRING(value_);
+    }
+    return asString();
+  }
+  /*
+   * Returns the string as a zero-terminated array of UTF16 characters.
+   * Note that this pointer may become invalid when JS performs GC, so it
+   * may only be used without calling other JS functions.  Result is
+   * undefined if the value is not actually a string.
+   */
+  const wchar_t* getStringChars() const {
+    return reinterpret_cast<const wchar_t*>(JS_GetStringChars(
+        const_cast<JSString*>(getString())));
+  }
+  
+  /*
+   * Returns the length of the underlying string.  Result is undefined
+   * if the value is not actually a string.
+   */
+  int getStringLength() const {
+    return JS_GetStringLength(const_cast<JSString*>(getString()));
+  } 
+  
+  /*
+   * Sets the underlying value, defined by a null-terminated array of UTF16
+   * chars.
+   * 
+   * Returns false on failure.
+   */
+  bool setString(const wchar_t* utf16) {
+    JSString* str = JS_NewUCStringCopyZ(currentContext(),
+        reinterpret_cast<const jschar*>(utf16));
+    return setValue(STRING_TO_JSVAL(str));
+  }
+  
+  /*
+   * Sets the underlying value, defined by a counted array of UTF16 chars.
+   * 
+   * Returns false on failure.
+   */
+  bool setString(const wchar_t* utf16, size_t len) {
+    JSString* str = JS_NewUCStringCopyN(currentContext(),
+        reinterpret_cast<const jschar*>(utf16), len);
+    return setValue(STRING_TO_JSVAL(str));
+  }
+  
+  /*
+   * Returns true if the underlying value is an object.
+   */
+  bool isObject() const {
+    return JSVAL_IS_OBJECT(value_);
+  }
+  
+  /*
+   * Returns the underlying value as an object.
+   * Result is undefined if it is not actually an object.
+   */
+  JSObject* getObject() const {
+    return isObject() ? JSVAL_TO_OBJECT(value_) : 0;
+  }
+  
+  /*
+   * Returns the class name of the underlying value.
+   *
+   * Result is undefined if it is not actually an object.
+   */
+  const JSClass* getObjectClass() const {
+    return isObject() ? JS_GET_CLASS(currentContext(), getObject()) : 0;
+  }
+  
+  /*
+   * Sets the underlying value to be an object.
+   *
+   * Returns false on failure.
+   */
+  bool setObject(JSObject* obj) {
+    return setValue(OBJECT_TO_JSVAL(obj));
+  }
+
+  /*
+   * Returns true if the underlying value is undefined (void).
+   */
+  bool isUndefined() const {
+    return JSVAL_IS_VOID(value_);
+  }
+  
+  /*
+   * Sets the underlying value to be undefined (void).
+   * 
+   * Returns false on failure (impossible?)
+   */
+  bool setUndefined() {
+    return setValue(JSVAL_VOID);
+  }
+  
+  /*
+   * Returns true if the underlying value is null.
+   */
+  bool isNull() const {
+    return JSVAL_IS_NULL(value_);
+  }
+  /*
+   * Sets the underlying value to be null.
+   * 
+   * Returns false on failure (impossible?)
+   */
+  bool setNull() {
+    return setValue(JSVAL_NULL);
+  }
+};
+
+#endif /*JNI_LINUX_JSROOTEDVALUE_H_*/
diff --git a/jni/linux/JsStringWrap.h b/jni/linux/JsStringWrap.h
new file mode 100644
index 0000000..7ab0ce6
--- /dev/null
+++ b/jni/linux/JsStringWrap.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2007 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.
+ */
+
+#ifndef JNI_LINUX_JSSTRINGWRAP_H_
+#define JNI_LINUX_JSSTRINGWRAP_H_
+
+/*
+ * Wrapper arouond JavaScript Strings, keeps pointers to unpacked strings
+ * and makes sure they are not cleaned up early. 
+ */
+class JsStringWrap {
+  private:
+    JSContext* context_;
+    JSString* string_;
+    const char* bytes_;
+    const wchar_t* chars_;
+
+  public:
+    JsStringWrap(JSContext* context, JSString* str)
+        : context_(context), string_(str), bytes_(0), chars_(0) {
+      JS_AddRoot(context_, &string_);
+      JS_AddRoot(context_, &bytes_);
+      JS_AddRoot(context_, &chars_);
+    }
+    JsStringWrap(JSContext* context, jsval str)
+        : context_(context), string_(JSVAL_TO_STRING(str)), bytes_(0), chars_(0) {
+      JS_AddRoot(context_, &string_);
+      JS_AddRoot(context_, &bytes_);
+      JS_AddRoot(context_, &chars_);
+    }
+    ~JsStringWrap() {
+      JS_RemoveRoot(context_, &string_);
+      JS_RemoveRoot(context_, &bytes_);
+      JS_RemoveRoot(context_, &chars_);
+    }
+    const char* bytes() {
+      if (!bytes_) bytes_ = JS_GetStringBytes(string_);
+      return bytes_;
+    }
+    const wchar_t* chars() {
+      if (!chars_) {
+        chars_ = reinterpret_cast<wchar_t*>(JS_GetStringChars(string_));
+      }
+      return chars_;
+    }
+    int length() {
+      return JS_GetStringLength(string_);
+    }
+};
+
+#endif // JNI_LINUX_JSSTRINGWRAP_H_
diff --git a/jni/linux/JsValueMoz.cpp b/jni/linux/JsValueMoz.cpp
new file mode 100644
index 0000000..195306c
--- /dev/null
+++ b/jni/linux/JsValueMoz.cpp
@@ -0,0 +1,993 @@
+/*
+ * Copyright 2007 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 <jni.h>
+#include "JsRootedValue.h"
+#include "gwt-jni.h"
+#include "ExternalWrapper.h"
+#include "Tracer.h"
+
+// include javah-generated header to make sure things match
+#include "JsValueMoz.h"
+
+/*
+ * Returns the value of a field on a Java object.
+ * 
+ * context - JavaScript context
+ * clazz - class of obj
+ * obj - Java object to retreive field from
+ * fieldName - name of field on Java object to retrieve
+ * 
+ * Returns null on failure.  Caller is responsible for deleting
+ * returned JsRootedValue when done with it.
+ */
+static JsRootedValue* GetFieldAsRootedValue(JSContext* cx, jclass clazz,
+    jobject obj, jstring fieldName)
+{
+  Tracer tracer("GetFieldAsRootedValue");
+  JsRootedValue::ContextManager context(cx);
+  jmethodID getFieldMeth = savedJNIEnv->GetMethodID(clazz, "getField",
+      "(Ljava/lang/String;I)V");
+  if (!getFieldMeth || savedJNIEnv->ExceptionCheck()) {
+    return 0;
+  }
+
+  JsRootedValue* jsRootedValue = new JsRootedValue();
+  savedJNIEnv->CallVoidMethod(obj, getFieldMeth, fieldName,
+  	 reinterpret_cast<jint>(jsRootedValue));
+  if (savedJNIEnv->ExceptionCheck()) {
+  	 delete jsRootedValue;
+    return 0;
+  }
+  return jsRootedValue;
+}
+  
+/*
+ * Sets the value of a field on a Java object.
+ * 
+ * context - JavaScript context
+ * clazz - class of obj
+ * obj - Java object to store into field
+ * fieldName - name of field on Java object to store into
+ * jsRootedValue - the value to store in the field
+ * 
+ * returns true on success, false on failure
+ */
+static bool SetFieldFromRootedValue(JSContext* cx, jclass clazz,
+    jobject obj, jstring fieldName, JsRootedValue* jsRootedValue)
+{
+  Tracer tracer("SetFieldAsRootedValue");
+  JsRootedValue::ContextManager context(cx);
+  jmethodID getFieldMeth = savedJNIEnv->GetMethodID(clazz, "setField",
+      "(Ljava/lang/String;I)V");
+  if (!getFieldMeth || savedJNIEnv->ExceptionCheck()) {
+    return false;
+  }
+
+  savedJNIEnv->CallVoidMethod(obj, getFieldMeth, fieldName,
+  	 reinterpret_cast<jint>(jsRootedValue));
+  if (savedJNIEnv->ExceptionCheck()) {
+    return false;
+  }
+
+  return true;
+}
+
+/*
+ * Throws a HostedModeException with the specified message.
+ */
+static void ThrowHostedModeException(JNIEnv* jniEnv, const char* msg) {
+  jclass exceptionClass
+      = jniEnv->FindClass("com/google/gwt/dev/shell/HostedModeException");
+  jniEnv->ThrowNew(exceptionClass, msg);
+}
+
+/*
+ * Types of jsvals.
+ */
+enum JsValueType {
+  JSVAL_TYPE_VOID=0,
+  JSVAL_TYPE_NULL,
+  JSVAL_TYPE_BOOLEAN,
+  JSVAL_TYPE_NUMBER,
+  JSVAL_TYPE_STRING,
+  JSVAL_TYPE_OBJECT,
+  JSVAL_TYPE_UNKNOWN,
+};
+
+/*
+ * Names of jsval types -- must match the order of the enum above.
+ */
+static const char* JsValueTypeStrings[]={
+  "undefined",
+  "null",
+  "boolean",
+  "number",
+  "string",
+  "object",
+  "unknown",
+};
+
+/*
+ * Return the type of a jsval.
+ */
+static JsValueType GetValueType(jsval val) {
+  if(JSVAL_IS_VOID(val)) {
+    return JSVAL_TYPE_VOID;
+  } else if(JSVAL_IS_NULL(val)) {
+    return JSVAL_TYPE_NULL;
+  } else if(JSVAL_IS_BOOLEAN(val)) {
+    return JSVAL_TYPE_BOOLEAN;
+  } else if(JSVAL_IS_NUMBER(val)) {
+    return JSVAL_TYPE_NUMBER;
+  } else if(JSVAL_IS_STRING(val)) {
+    return JSVAL_TYPE_STRING;
+  } else if(JSVAL_IS_OBJECT(val)) {
+    return JSVAL_TYPE_OBJECT;
+  } else {
+    return JSVAL_TYPE_UNKNOWN;
+  } 
+}
+
+/*
+ * Called from JavaScript to call a Java method that has previously been
+ * wrapped.  See _setWrappedFunction for use.
+ */ 
+static JSBool invokeJavaMethod(JSContext *cx, JSObject *obj, uintN argc,
+    jsval *argv, jsval *rval)
+{
+  Tracer tracer("invokeJavaMethod");
+  JsRootedValue::ContextManager context(cx);
+
+  // I kid you not; this is how XPConnect gets their function object so they can
+  // multiplex dispatch the call from a common site.  See XPCDispObject.cpp(466)
+  //
+  // I now have a secondary confirmation that this trick is legit.
+  // brandon@mozilla.org writes:
+  //
+  // argv[-2] is part of the JS API, unabstracted.  Just as argv[0] is the
+  // first argument (if argc != 0), argv[-1] is the |this| parameter (equal
+  // to OBJECT_TO_JSVAL(obj) in a native method with the standard |obj|
+  // second formal parameter name), and argv[-2] is the callee object, tagged
+  // as a jsval.
+  if (JS_TypeOfValue(cx, argv[-2]) != JSTYPE_FUNCTION) {
+    tracer.setFail("not a function type");
+    return JS_FALSE;
+  }
+  JSObject* funObj = JSVAL_TO_OBJECT(argv[-2]);
+
+  // Pull the wrapper object out of the funObj's reserved slot
+  jsval jsCleanupObj;
+  if (!JS_GetReservedSlot(cx, funObj, 0, &jsCleanupObj)) {
+    tracer.setFail("JS_GetReservedSlot failed");
+    return JS_FALSE;
+  }
+  JSObject* cleanupObj = JSVAL_TO_OBJECT(jsCleanupObj);
+  if (!cleanupObj) {
+    tracer.setFail("cleanupObj is null");
+    return JS_FALSE;
+  }
+
+  // Get DispatchMethod instance out of the wrapper object
+  jobject dispMeth =
+      NS_REINTERPRET_CAST(jobject, JS_GetPrivate(cx, cleanupObj));
+  if (!dispMeth) {
+    tracer.setFail("dispMeth is null");
+    return JS_FALSE;
+  }
+  jclass dispClass = savedJNIEnv->GetObjectClass(dispMeth);
+  if (!dispClass || savedJNIEnv->ExceptionCheck()) {
+    tracer.setFail("GetObjectClass returns null");
+    return JS_FALSE;
+  }
+
+  // lookup the invoke method on the dispatch object
+  jmethodID invokeID =
+      savedJNIEnv->GetMethodID(dispClass, "invoke", "(I[II)V");
+  if (!invokeID || savedJNIEnv->ExceptionCheck()) {
+    tracer.setFail("GetMethodID failed");
+    return JS_FALSE;
+  }
+
+  // create an array of integers to hold the JsRootedValue pointers passed
+  // to the invoke method
+  jintArray args = savedJNIEnv->NewIntArray(argc);
+  if (!args || savedJNIEnv->ExceptionCheck()) {
+    tracer.setFail("NewIntArray failed");
+    return JS_FALSE;
+  }
+
+  // these arguments are already rooted by the JS interpreter, but we
+  // can't easily take advantage of that without complicating the JsRootedValue
+  // interface.
+  
+  // argv[-1] is OBJECT_TO_JSVAL(this)
+  JsRootedValue* jsThis = new JsRootedValue(argv[-1]);
+  tracer.log("jsthis=%08x, RV=%08x", unsigned(argv[-1]), unsigned(jsThis));
+
+  // create JsRootedValues for arguments  
+  JsRootedValue *jsArgs[argc]; 
+  for (uintN i = 0; i < argc; ++i) {
+    jsArgs[i] = new JsRootedValue(argv[i]);
+  }
+  savedJNIEnv->SetIntArrayRegion(args, 0, argc,
+      reinterpret_cast<jint*>(jsArgs));
+  if (savedJNIEnv->ExceptionCheck()) {
+    tracer.setFail("SetIntArrayRegion failed");
+    return JS_FALSE;
+  }
+  
+  // slot for return value
+  JsRootedValue* jsReturnVal = new JsRootedValue();
+
+  // TODO(jat): small window here where invocation may fail before Java
+  // takes ownership of the JsRootedValue objects.  One solution would be
+  // to reference-count them between Java and C++ (so the reference count
+  // would always be 0, 1, or 2).  Also setField has a similar problem.
+  // I plan to fix this when switching away from Java holding pointers to
+  // C++ objects as part of the fix for 64-bit support (which we could
+  // accomplish inefficiently by changing int to long everywhere, but there
+  // are other 64-bit issues to resolve and we need to reduce the number of
+  // roots the JS interpreter has to search.
+  
+  // call Java method
+  savedJNIEnv->CallVoidMethod(dispMeth, invokeID, reinterpret_cast<int>(jsThis),
+      args, reinterpret_cast<int>(jsReturnVal));
+  
+  JSBool returnValue = JS_TRUE;
+  
+  if (savedJNIEnv->ExceptionCheck()) {
+    tracer.log("dispMeth=%08x", unsigned(dispMeth));
+    tracer.setFail("java exception is active:");
+    jobject exception = savedJNIEnv->ExceptionOccurred();
+    if (exception) {
+      fprintf(stderr, "Exception occurred in MethodDispatch.invoke:\n");
+      savedJNIEnv->ExceptionDescribe();
+      savedJNIEnv->DeleteLocalRef(exception);
+    }
+    returnValue = JS_FALSE;
+  } else if (JS_IsExceptionPending(cx)) {
+    tracer.setFail("js exception is active");
+    returnValue = JS_FALSE;
+  }
+
+  // extract return value
+  *rval = jsReturnVal->getValue();
+
+#if 0
+  // NOTE: C++ objects are not cleaned up here because Java now owns them.
+  // TODO(jat): if reference-counted, they *do* need to be Released here.
+  
+  // free JsRootedValues
+  for (uintN i = 0; i < argc; ++i) {
+    delete jsArgs[i];
+  }
+  delete jsThis;
+  delete jsReturnVal;
+#endif
+
+  return returnValue;
+}
+
+/*
+ * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
+ * Method:    _createJsRootedValue()
+ * Signature: (I)I
+ */
+extern "C" JNIEXPORT jint JNICALL
+Java_com_google_gwt_dev_shell_moz_JsValueMoz__1createJsRootedValue
+  (JNIEnv* jniEnv, jclass, jint jsval)
+{
+  Tracer tracer("JsValueMoz._createJsRootedValue");
+  JsRootedValue* jsRootedValue = new JsRootedValue(jsval);
+  return NS_REINTERPRET_CAST(jint, jsRootedValue);
+}
+
+/*
+ * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
+ * Method:    _copyJsRootedValue()
+ * Signature: (I)I
+ */
+extern "C" JNIEXPORT jint JNICALL
+Java_com_google_gwt_dev_shell_moz_JsValueMoz__1copyJsRootedValue
+  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt)
+{
+  const JsRootedValue* jsRootedValue = reinterpret_cast<const JsRootedValue*>
+      (jsRootedValueInt);
+  Tracer tracer("JsValueMoz._copyJsRootedValue", jsRootedValue);
+  JsRootedValue* newRootedValue = new JsRootedValue(*jsRootedValue);
+  return NS_REINTERPRET_CAST(jint, newRootedValue);
+}
+
+/*
+ * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
+ * Method:    _destroyJsRootedValue()
+ * Signature: (I)V
+ */
+extern "C" JNIEXPORT void JNICALL
+Java_com_google_gwt_dev_shell_moz_JsValueMoz__1destroyJsRootedValue
+  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt)
+{
+  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
+      (jsRootedValueInt);
+  Tracer tracer("JsValueMoz._destroyJsRootedValue", jsRootedValue);
+  delete jsRootedValue;
+}
+
+/*
+ * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
+ * Method:    _getBoolean()
+ * Signature: (I)Z
+ * 
+ * TODO(jat): unboxing Javascript Boolean type?
+ */
+extern "C" JNIEXPORT jboolean JNICALL
+Java_com_google_gwt_dev_shell_moz_JsValueMoz__1getBoolean
+  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt)
+{
+  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
+      (jsRootedValueInt);
+  Tracer tracer("JsValueMoz._getBoolean", jsRootedValue);
+  return jsRootedValue->getBoolean();
+}
+
+/**
+ * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
+ * Method:    _getInt()
+ * Signature: (I)I
+ * 
+ * @see com.google.gwt.dev.shell.moz.JsValueMoz#getInt()
+ */
+extern "C" JNIEXPORT jint JNICALL
+Java_com_google_gwt_dev_shell_moz_JsValueMoz__1getInt
+  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt)
+{
+  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
+      (jsRootedValueInt);
+  Tracer tracer("JsValueMoz._getInt", jsRootedValue);
+  int val = jsRootedValue->getInt();
+  tracer.log("value=%d", val);
+  return val;
+}
+
+/**
+ * Return a Javascript number as a Java double.
+ * 
+ * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
+ * Method:    _getNumber()
+ * Signature: (I)D
+ */
+extern "C" JNIEXPORT jdouble JNICALL
+Java_com_google_gwt_dev_shell_moz_JsValueMoz__1getNumber
+  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt)
+{
+  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
+      (jsRootedValueInt);
+  Tracer tracer("JsValueMoz._getNumber", jsRootedValue);
+  return jsRootedValue->getDouble();
+}
+
+/**
+ * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
+ * Method:    _getJsval()
+ * Signature: (I)I
+ */
+extern "C" JNIEXPORT jint JNICALL
+Java_com_google_gwt_dev_shell_moz_JsValueMoz__1getJsval
+  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt)
+{
+  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
+      (jsRootedValueInt);
+  Tracer tracer("JsValueMoz._getObjectPointer", jsRootedValue);
+  int val = jsRootedValue->getValue();
+  tracer.log("value=%d", val);
+  return val;
+}
+
+/**
+ * Return a Javascript string as a Java string.
+ * 
+ * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
+ * Method:    _getString()
+ * Signature: (I)Ljava/lang/String;
+ * 
+ * Note that this relies on jschar being assignment compatible with jchar
+ */
+extern "C" JNIEXPORT jstring JNICALL
+Java_com_google_gwt_dev_shell_moz_JsValueMoz__1getString
+  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt)
+{
+  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
+      (jsRootedValueInt);
+  Tracer tracer("JsValueMoz._getString", jsRootedValue);
+  const JSString* str = jsRootedValue->getString();
+  int len = JS_GetStringLength(const_cast<JSString*>(str));
+  jstring javaStr =jniEnv->NewString(reinterpret_cast<const jchar*>(
+      JS_GetStringChars(const_cast<JSString*>(str))), len);
+  return javaStr;
+}
+
+/*
+ * Returns a human-readable Java string describing the type of a
+ * JavaScript object.
+ * 
+ * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
+ * Method:    _getTypeString
+ * Signature: (I)Ljava/lang/String;
+ */
+extern "C" JNIEXPORT jstring JNICALL
+Java_com_google_gwt_dev_shell_moz_JsValueMoz__1getTypeString
+  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt)
+{
+  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
+      (jsRootedValueInt);
+  Tracer tracer("JsValueMoz._getTypeString", jsRootedValue);
+  jsval val = jsRootedValue->getValue();
+  JSContext* cx = JsRootedValue::currentContext();
+  JsValueType valueType = GetValueType(val);
+  const char* typeString = 0;
+  char buf[256];
+  if(valueType == JSVAL_TYPE_OBJECT) {
+    JSObject* jsObject = JSVAL_TO_OBJECT(val);
+    JSClass* objClass = JS_GET_CLASS(cx, jsObject);
+    if (JS_InstanceOf(cx, jsObject,
+        &gwt_nativewrapper_class, 0)) {
+      typeString = "Java object";
+    } else {
+      snprintf(buf, sizeof(buf), "class %s", objClass->name);
+      typeString = buf;
+    }
+  } else {
+    typeString = JsValueTypeStrings[valueType];
+  }
+  jstring returnValue = jniEnv->NewStringUTF(typeString);
+  return returnValue;
+}
+
+/*
+ * Unwraps a wrapped Java object from a JS object.
+ * 
+ * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
+ * Method:    _getWrappedJavaObject
+ * Signature: (I)Ljava/lang/Object;
+ */
+extern "C" JNIEXPORT jobject JNICALL
+Java_com_google_gwt_dev_shell_moz_JsValueMoz__1getWrappedJavaObject
+  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt)
+{
+  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
+      (jsRootedValueInt);
+  Tracer tracer("JsValueMoz._getWrappedJavaObject", jsRootedValue);
+  JSObject* jsObject = jsRootedValue->getObject();
+  if(!jsObject) {
+    tracer.throwHostedModeException(jniEnv, "Javascript value not an object");
+    return 0;
+  }
+  JSContext* cx = JsRootedValue::currentContext();
+  if(!JS_InstanceOf(cx, jsObject, &gwt_nativewrapper_class, 0)) {
+    tracer.throwHostedModeException(jniEnv,
+      "Javascript object not a Java object");
+    return 0;
+  } 
+  jobject javaObject
+      = NS_REINTERPRET_CAST(jobject, JS_GetPrivate(cx, jsObject));
+  return javaObject;
+} 
+
+/*
+ * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
+ * Method:    _isBoolean()
+ * Signature: (I)Z
+ */
+extern "C" JNIEXPORT jboolean JNICALL
+Java_com_google_gwt_dev_shell_moz_JsValueMoz__1isBoolean
+  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt)
+{
+  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
+      (jsRootedValueInt);
+  Tracer tracer("JsValueMoz._isBoolean", jsRootedValue);
+  return jsRootedValue->isBoolean();
+}
+
+/*
+ * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
+ * Method:    _isInt()
+ * Signature: (I)Z
+ */
+extern "C" JNIEXPORT jboolean JNICALL
+Java_com_google_gwt_dev_shell_moz_JsValueMoz__1isInt
+  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt)
+{
+  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
+      (jsRootedValueInt);
+  Tracer tracer("JsValueMoz._isBoolean", jsRootedValue);
+  return jsRootedValue->isInt();
+}
+
+/*
+ * Checks if a JS object is a JavaScript object.
+ * 
+ * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
+ * Method:    _isJavaScriptObject
+ * Signature: (I)Z
+ */
+extern "C" JNIEXPORT jboolean JNICALL
+Java_com_google_gwt_dev_shell_moz_JsValueMoz__1isJavaScriptObject
+  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt)
+{
+  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
+      (jsRootedValueInt);
+  Tracer tracer("JsValueMoz._isJavaScriptObject", jsRootedValue);
+  jsval val = jsRootedValue->getValue();
+  bool returnValue = false;
+  if(JSVAL_IS_OBJECT(val)) {
+    JSObject* jsObject = JSVAL_TO_OBJECT(val);
+    returnValue = !JS_InstanceOf(JsRootedValue::currentContext(), jsObject,
+        &gwt_nativewrapper_class, 0);
+    tracer.log("jsobject=%08x, isJSObject=%s", unsigned(jsObject),
+        returnValue ? "true" : "false");
+  } else {
+    tracer.log("not an object");
+  }
+  return returnValue;
+} 
+
+/*
+ * Checks if a JS object is a JavaScript String object.
+ * 
+ * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
+ * Method:    _isJavaScriptString
+ * Signature: (I)Z
+ */
+extern "C" JNIEXPORT jboolean JNICALL
+Java_com_google_gwt_dev_shell_moz_JsValueMoz__1isJavaScriptString
+  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt)
+{
+  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
+      (jsRootedValueInt);
+  Tracer tracer("JsValueMoz._isJavaScriptString", jsRootedValue);
+  bool returnValue = jsRootedValue->isJavaScriptStringObject();
+  tracer.log("value=%s", returnValue ? "true" : "false");
+  return returnValue;
+} 
+
+/*
+ * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
+ * Method:    _isNull()
+ * Signature: (I)Z
+ */
+extern "C" JNIEXPORT jboolean JNICALL
+Java_com_google_gwt_dev_shell_moz_JsValueMoz__1isNull
+  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt)
+{
+  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
+      (jsRootedValueInt);
+  Tracer tracer("JsValueMoz._isNull", jsRootedValue);
+  return jsRootedValue->isNull();
+}
+
+/*
+ * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
+ * Method:    _isNumber()
+ * Signature: (I)Z
+ */
+extern "C" JNIEXPORT jboolean JNICALL
+Java_com_google_gwt_dev_shell_moz_JsValueMoz__1isNumber
+  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt)
+{
+  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
+      (jsRootedValueInt);
+  Tracer tracer("JsValueMoz._isNumber", jsRootedValue);
+  return jsRootedValue->isNumber();
+}
+
+/*
+ * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
+ * Method:    _isString()
+ * Signature: (I)Z
+ * 
+ * Handles the case of JavaScript String objects as well
+ */
+extern "C" JNIEXPORT jboolean JNICALL
+Java_com_google_gwt_dev_shell_moz_JsValueMoz__1isString
+  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt)
+{
+  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
+      (jsRootedValueInt);
+  Tracer tracer("JsValueMoz._isString", jsRootedValue);
+  return jsRootedValue->isString();
+}
+
+/*
+ * Checks if a JS object is undefined (void)
+ * 
+ * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
+ * Method:    _isUndefined
+ * Signature: (I)Z
+ */
+extern "C" JNIEXPORT jboolean JNICALL
+Java_com_google_gwt_dev_shell_moz_JsValueMoz__1isUndefined
+  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt)
+{
+  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
+      (jsRootedValueInt);
+  Tracer tracer("JsValueMoz._isUndefined", jsRootedValue);
+  return jsRootedValue->isUndefined();
+} 
+
+/*
+ * Checks if a JS object is a wrapped Java object.
+ * 
+ * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
+ * Method:    _isWrappedJavaObject
+ * Signature: (I)Z
+ */
+extern "C" JNIEXPORT jboolean JNICALL
+Java_com_google_gwt_dev_shell_moz_JsValueMoz__1isWrappedJavaObject
+  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt)
+{
+  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
+      (jsRootedValueInt);
+  Tracer tracer("JsValueMoz._isWrappedJavaObject", jsRootedValue);
+  jsval val = jsRootedValue->getValue();
+  bool returnValue = false;
+  if(JSVAL_IS_OBJECT(val)) {
+    JSObject* jsObject = JSVAL_TO_OBJECT(val);
+    returnValue = JS_InstanceOf(JsRootedValue::currentContext(), jsObject,
+        &gwt_nativewrapper_class, 0);
+    tracer.log("jsobject=%08x, wrappedJava=%s", unsigned(jsObject),
+        returnValue ? "true" : "false");
+  } else {
+    tracer.log("not an object");
+  }
+  return returnValue;
+} 
+
+/*
+ * Set the JavaScript value to be a boolean of the supplied value.
+ * 
+ * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
+ * Method:    _setBoolean()
+ * Signature: (IZ)V
+ */
+extern "C" JNIEXPORT void JNICALL
+Java_com_google_gwt_dev_shell_moz_JsValueMoz__1setBoolean
+  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt, jboolean val)
+{
+  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
+      (jsRootedValueInt);
+  Tracer tracer("JsValueMoz._setBoolean", jsRootedValue);
+  jsRootedValue->setBoolean(val == JNI_TRUE);
+  return;
+}
+
+/*
+ * Set the JavaScript value to be a double of the supplied value.
+ * 
+ * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
+ * Method:    _setDouble()
+ * Signature: (ID)V
+ */
+extern "C" JNIEXPORT void
+JNICALL Java_com_google_gwt_dev_shell_moz_JsValueMoz__1setDouble
+  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt, jdouble val)
+{
+  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
+      (jsRootedValueInt);
+  Tracer tracer("JsValueMoz._setDouble", jsRootedValue);
+  if(!jsRootedValue->setDouble(val)) {
+    tracer.throwHostedModeException(jniEnv, "Unable to allocate JS double");
+    return;
+  }
+}
+
+/*
+ * Set the Javascript value to be an integer.
+ * 
+ * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
+ * Method:    _setInt()
+ * Signature: (II)V
+ */
+extern "C" JNIEXPORT void JNICALL
+Java_com_google_gwt_dev_shell_moz_JsValueMoz__1setInt
+  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt, jint val)
+{
+  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
+      (jsRootedValueInt);
+  Tracer tracer("JsValueMoz._setInt", jsRootedValue);
+  tracer.log("val=%d", val);
+  jsRootedValue->setInt(val);
+}
+
+/*
+ * Set the Javascript value to be another JsRootedValue's value.
+ * 
+ * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
+ * Method:    _setJsRootedValue()
+ * Signature: (II)V
+ */
+extern "C" JNIEXPORT void JNICALL
+Java_com_google_gwt_dev_shell_moz_JsValueMoz__1setJsRootedValue
+  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt, jint jsOtherRootedValueInt)
+{
+  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
+      (jsRootedValueInt);
+  JsRootedValue* jsOtherRootedValue = reinterpret_cast<JsRootedValue*>
+      (jsOtherRootedValueInt);
+  Tracer tracer("JsValueMoz._setJsRootedValue", jsRootedValue);
+  jsRootedValue->setValue(jsOtherRootedValue->getValue());
+}
+
+/*
+ * Set the Javascript value to a specific jsval.
+ * 
+ * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
+ * Method:    _setJsval()
+ * Signature: (II)V
+ */
+extern "C" JNIEXPORT void JNICALL
+Java_com_google_gwt_dev_shell_moz_JsValueMoz__1setJsval
+  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt, jint jsval)
+{
+  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
+      (jsRootedValueInt);
+  Tracer tracer("JsValueMoz._setJsval", jsRootedValue);
+  jsRootedValue->setValue(jsval);
+}
+
+/*
+ * Set the JavaScript value to be null.
+ * 
+ * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
+ * Method:    _setNull()
+ * Signature: (I)V
+ */
+extern "C" JNIEXPORT void JNICALL
+Java_com_google_gwt_dev_shell_moz_JsValueMoz__1setNull
+  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt)
+{
+  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
+      (jsRootedValueInt);
+  Tracer tracer("JsValueMoz._setNull", jsRootedValue);
+  jsRootedValue->setNull();
+}
+
+/*
+ * Set the JavaScript value to be a string of the supplied value.
+ * 
+ * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
+ * Method:    _setString()
+ * Signature: (ILjava/lang/String;)V
+ */
+extern "C" JNIEXPORT void JNICALL
+Java_com_google_gwt_dev_shell_moz_JsValueMoz__1setString
+  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt, jstring val)
+{
+  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
+      (jsRootedValueInt);
+  Tracer tracer("JsValueMoz._setString", jsRootedValue);
+  JStringWrap strVal(jniEnv, val);
+  const jchar* stringUTF16 = strVal.jstr();
+  if(!stringUTF16) {
+    tracer.throwHostedModeException(jniEnv, "Unable to retrieve Java string");
+    return;
+  }
+  tracer.log("string=%s", strVal.str());
+  if(!jsRootedValue->setString(reinterpret_cast<const wchar_t*>(stringUTF16),
+      strVal.length())) {
+    tracer.throwHostedModeException(jniEnv, "Unable to allocate JS string");
+    return;
+  }
+}
+
+/*
+ * Set the JavaScript value to be undefined (void).
+ * 
+ * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
+ * Method:    _setUndefined()
+ * Signature: (I)V
+ */
+extern "C" JNIEXPORT void JNICALL
+Java_com_google_gwt_dev_shell_moz_JsValueMoz__1setUndefined
+  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt)
+{
+  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
+      (jsRootedValueInt);
+  Tracer tracer("JsValueMoz._setUndefined", jsRootedValue);
+  jsRootedValue->setUndefined();
+}
+
+/*
+ * Wraps a Java object in a JS object.
+ * 
+ * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
+ * Method:    _setWrappedJavaObject
+ * Signature: (ILjava/lang/Object)V
+ */
+extern "C" JNIEXPORT void JNICALL
+Java_com_google_gwt_dev_shell_moz_JsValueMoz__1setWrappedJavaObject
+  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt, jobject obj)
+{
+  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
+      (jsRootedValueInt);
+  Tracer tracer("JsValueMoz._setWrappedJavaObject", jsRootedValue);
+  JSContext* cx = JsRootedValue::currentContext();
+  JSObject* scriptWindow = JS_GetGlobalObject(cx);
+  JSObject* newObj = JS_NewObject(cx, &gwt_nativewrapper_class, 0,
+      scriptWindow);
+  if (!newObj) {
+    tracer.throwHostedModeException(jniEnv,
+        "Unable to allocate JS object to wrap Java object");
+    return;
+  }
+  // Save in output value so it won't get GCed.
+  jsRootedValue->setObject(newObj); 
+  tracer.log("jsobject=%08x", unsigned(newObj));
+  
+  // This is collected when the gwt_nativewrapper_class destructor runs.
+  jobject dispObjRef = jniEnv->NewGlobalRef(obj);
+  if (!dispObjRef || jniEnv->ExceptionCheck()) {
+    tracer.throwHostedModeException(jniEnv,
+        "Unable to allocate global reference for JS wrapper");
+    return;
+  } 
+  if (!JS_SetPrivate(cx, newObj, dispObjRef)) {
+    jniEnv->DeleteGlobalRef(dispObjRef);
+    tracer.throwHostedModeException(jniEnv,
+        "Unable to allocate global reference for JS wrapper");
+    return;
+  } 
+  // forcibly setup a "toString" method to override the default
+  jclass dispClass = jniEnv->GetObjectClass(obj);
+  if (jniEnv->ExceptionCheck()) {
+    tracer.throwHostedModeException(jniEnv, "Can't get object class");
+    return;
+  } 
+  jmethodID getFieldMeth = jniEnv->GetMethodID(dispClass, "getField",
+      "(Ljava/lang/String;I)V");
+  if (!getFieldMeth || jniEnv->ExceptionCheck()) {
+    tracer.throwHostedModeException(jniEnv, "Can't get getField method");
+    return;
+  } 
+  jstring ident = jniEnv->NewStringUTF("@java.lang.Object::toString()");
+  if (!ident || jniEnv->ExceptionCheck()) {
+    tracer.throwHostedModeException(jniEnv,
+        "Can't create Java string for toString method name");
+    return;
+  }
+  // allocate a new root to hold the result of the getField call
+  JsRootedValue* toStringFunc = new JsRootedValue(); 
+  jniEnv->CallVoidMethod(obj, getFieldMeth, ident,
+      NS_REINTERPRET_CAST(jint, toStringFunc));
+  if (toStringFunc->isUndefined() || jniEnv->ExceptionCheck()) {
+    tracer.throwHostedModeException(jniEnv, "getField(toString) failed");
+    return;
+  } 
+  if (!JS_DefineProperty(cx, newObj, "toString", toStringFunc->getValue(),
+      JS_PropertyStub, JS_PropertyStub, JSPROP_READONLY | JSPROP_PERMANENT)) {
+    tracer.throwHostedModeException(jniEnv, "Can't define JS toString method");
+    return;
+  }
+} 
+
+/*
+ * Wraps a Java function in a JS object.
+ * 
+ * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
+ * Method:    _setWrappedFunction
+ * Signature: (ILjava/lang/String;Lcom/google/gwt/dev/shell/moz/DispatchMethod;)V
+ */
+extern "C" JNIEXPORT void JNICALL
+Java_com_google_gwt_dev_shell_moz_JsValueMoz__1setWrappedFunction
+    (JNIEnv* jniEnv, jclass, jint jsRootedValueInt, jstring methodName,
+     jobject dispatchMethod)
+{
+  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
+      (jsRootedValueInt);
+  Tracer tracer("JsValueMoz._setWrappedFunction", jsRootedValue);
+  JSContext* cx = JsRootedValue::currentContext();
+  JSObject* scriptWindow = JS_GetGlobalObject(cx);
+  JStringWrap nameStr(jniEnv, methodName);
+  if (!nameStr.str()) {
+    tracer.throwHostedModeException(jniEnv,
+       "null method name passed to setWrappedFunction");
+    return;
+  }
+  tracer.log("JsRootedValue=%08x, method=%s, obj=%08x", jsRootedValueInt,
+      nameStr.str(), unsigned(dispatchMethod));
+  JSFunction* function = JS_NewFunction(cx, invokeJavaMethod, 0,
+      JSFUN_LAMBDA, 0, nameStr.str());
+  if (!function) {
+    tracer.throwHostedModeException(jniEnv, "JS_NewFunction failed");
+    return;
+  }
+  JSObject* funObj = JS_GetFunctionObject(function);
+  if (!funObj) {
+    tracer.throwHostedModeException(jniEnv, "JS_GetFunctionObject failed");
+    return;
+  }
+  // Save in output value so it won't get GCed.
+  jsRootedValue->setObject(funObj); 
+
+  // Create a cleanup object to hold and clean up dispMeth
+  JSObject* cleanupObj = JS_NewObject(cx, &gwt_functionwrapper_class, 0,
+      scriptWindow);
+  if (!cleanupObj) {
+    tracer.throwHostedModeException(jniEnv, "JS_NewObject failed");
+    return;
+  }
+  tracer.log("funObj=%08x, cleanupObj=%08x", unsigned(funObj),
+      unsigned(cleanupObj));
+  // Store the cleanup object in funObj's reserved slot; now GC protected.
+  if(!JS_SetReservedSlot(cx, funObj, 0, OBJECT_TO_JSVAL(cleanupObj))) {
+    tracer.throwHostedModeException(jniEnv, "JS_SetReservedSlot failed");
+    return;
+  }
+  jobject dispMethRef = jniEnv->NewGlobalRef(dispatchMethod);
+  if (!dispMethRef || jniEnv->ExceptionCheck()) {
+    tracer.throwHostedModeException(jniEnv,
+        "NewGlobalRef(dispatchMethod) failed");
+    return;
+  }
+  // Store our global ref in the wrapper object
+  if (!JS_SetPrivate(cx, cleanupObj, dispMethRef)) {
+    jniEnv->DeleteGlobalRef(dispMethRef);
+    tracer.throwHostedModeException(jniEnv, "JS_SetPrivate(cleanupObj) failed");
+    return;
+  }
+}      
+
+/*
+ * Returns a JavaScript value as a string.
+ * 
+ * Class:     com_google_gwt_dev_shell_moz_JsValueMoz
+ * Method:    _toString
+ * Signature: (I)Ljava/lang/String;
+ */
+extern "C" JNIEXPORT jstring JNICALL
+Java_com_google_gwt_dev_shell_moz_JsValueMoz__1toString
+  (JNIEnv* jniEnv, jclass, jint jsRootedValueInt)
+{
+  JsRootedValue* jsRootedValue = reinterpret_cast<JsRootedValue*>
+      (jsRootedValueInt);
+  Tracer tracer("JsValueMoz._toString", jsRootedValue);
+  jsval val = jsRootedValue->getValue();
+  JSContext* cx = JsRootedValue::currentContext();
+
+  // if it is a JavaScript object that has a toString member function
+  // call that, otherwise call JS_ValueToString
+  if(JSVAL_IS_OBJECT(val)) {
+    JSObject* jsObject = JSVAL_TO_OBJECT(val);
+    jsval fval;
+    jsval rval;
+    if (!JS_InstanceOf(cx, jsObject, &gwt_nativewrapper_class, 0)
+        && JS_GetProperty(cx, jsObject, "toString", &fval)
+        && JS_ValueToFunction(cx, fval)
+        && JS_CallFunctionValue(cx, jsObject, fval, 0, 0, &rval)) {
+      // all the steps succeeded, so use the result of toString() instead
+      // of the value for JS_ValueToString below
+      val = rval;
+    }
+  }
+  JSString* str = JS_ValueToString(cx, val);
+  if (!str) {
+    return 0;
+  }
+  int len = JS_GetStringLength(str);
+  jstring javaStr =jniEnv->NewString(reinterpret_cast<const jchar*>(
+      JS_GetStringChars(str)), len);
+  return javaStr;
+} 
diff --git a/jni/linux/LowLevelMoz.cpp b/jni/linux/LowLevelMoz.cpp
new file mode 100644
index 0000000..9c3aba2
--- /dev/null
+++ b/jni/linux/LowLevelMoz.cpp
@@ -0,0 +1,380 @@
+/*
+ * Copyright 2007 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.
+ */
+
+// Mozilla-specific hosted-mode methods
+
+// Define to log debug-level output rather than just warnings.
+#define DEBUG
+
+#include <cstdio>
+#include <cstdarg>
+#include <cwchar>
+
+// Mozilla header files
+#include "mozilla-headers.h"
+
+#include <jni.h>
+#include "gwt-jni.h"
+#include "JsRootedValue.h"
+#include "ExternalWrapper.h"
+#include "Tracer.h"
+#include "JsStringWrap.h"
+
+/*
+ * Debug definitions -- define FILETRACE to have debug output written to
+ * a file named gwt-ll.log, or JAVATRACE to have debug output passed to the
+ * Java LowLevelMoz.trace method.
+ */
+#ifdef ENABLE_TRACING
+#define FILETRACE
+//#define JAVATRACE
+#endif
+
+// include javah-generated header to make sure we match
+#include "LowLevelMoz.h"
+
+JNIEnv* savedJNIEnv = 0;
+jclass lowLevelMozClass;
+
+// Only include debugging code if we are tracing somewhere.
+#ifdef ENABLE_TRACING
+
+/*
+ * Template so vsnprintf/vswprintf can be used interchangeably in the
+ * append_sprintf template below.
+ *   buf - pointer to the start of the output buffer
+ *   len - maximum number of characters to write into the buffer
+ *         (including the null terminator)
+ *   fmt - printf-style format string
+ *   args - stdarg-style variable arguments list
+ *  Returns the number of characters written (excluding the null terminator)
+ *   or -1 if an error occurred.
+ * 
+ * Note that %lc and %ls are only legal in the wchar_t implementation.
+ */
+template<class charT>
+int safe_vsprintf(charT* buf, size_t len, const charT* fmt, va_list args); 
+
+// specialization for char that maps to vsnprintf
+template<>
+inline int safe_vsprintf<char>(char* buf, size_t len, const char* fmt,
+    va_list args) {
+  return ::vsnprintf(buf, len, fmt, args);
+}
+
+// specialization for wchar_t that maps to vswprintf
+template<>
+inline int safe_vsprintf<wchar_t>(wchar_t* buf, size_t len, const wchar_t* fmt,
+    va_list args) {
+  return ::vswprintf(buf, len, fmt, args);
+}
+
+/*
+ * Safely append to a string buffer, updating the output pointer and always
+ * reserving the last character of the buffer for a null terminator.
+ *   bufStart - pointer to the start of the output buffer
+ *   bufEnd - pointer just past the end of the output buffer
+ *   fmt - format string
+ *   additional arguments as passed to *printf
+ * Returns the number of characters actually written, not including the null
+ * terminator.  Nothing is written, including the null terminator, if the
+ * buffer start points beyond the output buffer.
+ *
+ * Templated to work with any character type that has a safe_vsprintf
+ * implementation.
+ */
+template<class charT>
+static int append_sprintf(charT* bufStart, const charT* bufEnd,
+    const charT* fmt, ...) {
+  va_list args;
+  va_start(args, fmt); // initialize variable arguments list
+  // compute space left in buffer: -1 for null terminator
+  int maxlen = bufEnd - bufStart - 1;
+  if (maxlen <= 0) return 0;
+  int n = safe_vsprintf(bufStart, maxlen, fmt, args);
+  va_end(args);
+  if (n > maxlen) {
+    n = maxlen;
+  }
+  bufStart[n] = 0;
+  return n;
+}
+
+/*
+ * Log a given jsval with a prefix.
+ *  cx - JSContext for the JS execution context to use
+ *  val - jsval to print
+ *  prefix - string to print before the value, defaults to empty string
+ *
+ * TODO(jat): this whole printf-style logging needs to be replaced, but we
+ * run into library version issues if we use C++ iostreams so we would need
+ * to implement our own equivalent.  Given that this code is all likely to
+ * be rewritten for out-of-process hosted mode, it seems unlikely to be worth
+ * the effort until that is completed.
+ */
+void PrintJSValue(JSContext* cx, jsval val, char* prefix="") {
+  JSType type = JS_TypeOfValue(cx, val);
+  const char* typeString=JS_GetTypeName(cx, type);
+  static const int BUF_SIZE = 256;
+  char buf[BUF_SIZE];
+  const char *bufEnd = buf + BUF_SIZE;
+  char* p = buf;
+  p += append_sprintf(p, bufEnd, "%s%s", prefix, typeString);
+  switch(type) {
+    case JSTYPE_VOID:
+      break;
+    case JSTYPE_BOOLEAN:
+      p += append_sprintf(p, bufEnd, ": %s",
+          JSVAL_TO_BOOLEAN(val) ? "true" : "false");
+      break;
+    case JSTYPE_NUMBER:
+      if (JSVAL_IS_INT(val)) {
+        p += append_sprintf(p, bufEnd, ": %d", JSVAL_TO_INT(val));
+      } else {
+        p += append_sprintf(p, bufEnd, ": %lf", (double)*JSVAL_TO_DOUBLE(val));
+      }
+      break;
+    case JSTYPE_OBJECT: {
+      JSObject* obj = JSVAL_TO_OBJECT(val);
+      if (!JSVAL_IS_OBJECT(val)) break;
+      JSClass* clazz = obj ? JS_GET_CLASS(cx, obj) : 0;
+      p += append_sprintf(p, bufEnd, " @ %08x, class %s",
+          (unsigned)obj, clazz ? clazz->name : "<null>");
+      break;
+    }
+    case JSTYPE_FUNCTION:
+    case JSTYPE_LIMIT:
+      break;
+    case JSTYPE_STRING: {
+      /*
+       * TODO(jat): support JS strings with international characters
+       */
+      JsStringWrap str(cx, JSVAL_TO_STRING(val));
+      p += append_sprintf(p, bufEnd, ": %.*s", str.length(), str.bytes());
+      break;
+    }
+  }
+  Tracer::log("%s", buf);
+}
+#else
+// Include a null version just to keep from cluttering up call sites.
+static inline void PrintJSValue(JSContext* cx, jsval val, char* prefix="") { }
+#endif
+
+
+static bool InitGlobals(JNIEnv* env, jclass llClass) {
+  if (savedJNIEnv)
+    return false;
+
+#ifdef FILETRACE
+  Tracer::setFile("gwt-ll.log");
+#endif // FILETRACE
+
+#ifdef JAVATRACE
+  Tracer::setJava(env, llClass);
+#endif // JAVATRACE
+
+#ifdef DEBUG
+  Tracer::setLevel(Tracer::LEVEL_DEBUG);
+#endif
+
+  savedJNIEnv = env;
+  lowLevelMozClass = static_cast<jclass>(env->NewGlobalRef(llClass));
+  return true;
+}
+
+/*
+ * Class:     com_google_gwt_dev_shell_moz_LowLevelMoz
+ * Method:    _executeScriptWithInfo
+ * Signature: (ILjava/lang/String;Ljava/lang/String;I)Z
+ */
+extern "C" JNIEXPORT jboolean JNICALL
+Java_com_google_gwt_dev_shell_moz_LowLevelMoz__1executeScriptWithInfo
+    (JNIEnv* env, jclass llClass, jint scriptObjectInt, jstring code,
+     jstring file, jint line)
+{
+  Tracer tracer("LowLevelMoz._executeScriptWithInfo");
+  JStringWrap jcode(env, code);
+  if (!jcode.jstr()) {
+    tracer.setFail("null code string");
+    return JNI_FALSE;
+  }
+  JStringWrap jfile(env, file);
+  if (!jfile.str()) {
+    tracer.setFail("null file name");
+    return JNI_FALSE;
+  }
+  tracer.log("code=%s, file=%s, line=%d", jcode.str(), jfile.str(), line);
+  JSContext* cx = JsRootedValue::currentContext();
+  nsCOMPtr<nsIScriptContext> scriptContext(GetScriptContextFromJSContext(cx));
+
+  nsIScriptGlobalObject* scriptObject =
+      NS_REINTERPRET_CAST(nsIScriptGlobalObject*, scriptObjectInt);
+  JSObject* scriptWindow =
+      reinterpret_cast<JSObject*>(scriptObject->GetGlobalJSObject());
+  nsXPIDLString scriptString;
+  scriptString = jcode.jstr();
+
+  nsXPIDLString aRetValue;
+  PRBool aIsUndefined;
+  if (NS_FAILED(scriptContext->EvaluateString(scriptString, scriptWindow, 0,
+      jfile.str(), line, 0, aRetValue, &aIsUndefined))) {
+    tracer.setFail("EvaluateString failed");
+    return JNI_FALSE;
+  }
+  return JNI_TRUE;
+}
+
+/*
+ * Class:     com_google_gwt_dev_shell_moz_LowLevelMoz
+ * Method:    _invoke
+ * Signature: (ILjava/lang/String;I[I)I
+ */
+extern "C" JNIEXPORT jboolean JNICALL
+Java_com_google_gwt_dev_shell_moz_LowLevelMoz__1invoke
+    (JNIEnv* env, jclass, jint scriptObjInt, jstring methodName, jint jsThisInt,
+     jintArray jsArgsInt, jint jsRetValInt)
+{
+  Tracer tracer("LowLevelMoz._invoke");
+
+  JStringWrap methodStr(env, methodName);
+  if (!methodStr.str()) {
+    tracer.setFail("null method name");
+    return JNI_FALSE;
+  }
+  JsRootedValue* jsThisRV = reinterpret_cast<JsRootedValue*>(jsThisInt);
+  jint jsArgc = env->GetArrayLength(jsArgsInt);
+  tracer.log("method=%s, jsthis=%08x, #args=%d", methodStr.str(), jsThisInt,
+     jsArgc);
+  JSContext* cx = JsRootedValue::currentContext();
+  nsIScriptGlobalObject* scriptObject =
+      NS_REINTERPRET_CAST(nsIScriptGlobalObject*, scriptObjInt);
+  JSObject* scriptWindow
+      = reinterpret_cast<JSObject*>(scriptObject->GetGlobalJSObject());
+
+  jsval fval;
+  if (!JS_GetProperty(cx, scriptWindow, methodStr.str(), &fval)) {
+    tracer.setFail("JS_GetProperty(method) failed");
+    return JNI_FALSE;
+  }
+  JSFunction* jsFunction = JS_ValueToFunction(cx, fval);
+  if (!jsFunction) {
+    tracer.setFail("JS_ValueToFunction failed");
+    return JNI_FALSE;
+  }
+  
+  // extract arguments in jsval form
+  nsAutoArrayPtr<jint> jsargvals(new jint[jsArgc]);
+  if (!jsargvals) {
+    tracer.setFail("failed to allocate arg array");
+    return JNI_FALSE;
+  }
+  env->GetIntArrayRegion(jsArgsInt, 0, jsArgc, jsargvals);
+  if (env->ExceptionCheck()) {
+    tracer.setFail("copy from Java array failed");
+    return JNI_FALSE;
+  }
+  nsAutoArrayPtr<jsval> jsargs(new jsval[jsArgc]);
+  for (int i = 0; i < jsArgc; ++i) {
+    JsRootedValue* arg = reinterpret_cast<JsRootedValue*>(jsargvals[i]);
+    jsargs[i] = arg->getValue();
+  }
+
+  jsval jsrval;
+  JSObject* jsThis;
+  if (jsThisRV->isNull()) {
+    jsThis = scriptWindow;
+  } else {
+    jsThis = jsThisRV->getObject();
+  }
+  
+  PrintJSValue(cx, OBJECT_TO_JSVAL(jsThis), "jsThis=");
+  for (int i = 0; i < jsArgc; ++i) {
+    char buf[256];
+    snprintf(buf, sizeof(buf), "arg[%d]=", i);
+    PrintJSValue(cx, jsargs[i], buf);
+  }
+  //tracer.log("fval = %08x, args=%08x", fval, jsargs.get());
+  if (!JS_CallFunctionValue(cx, jsThis, fval, jsArgc, jsargs.get(), &jsrval)) {
+    tracer.setFail("JS_CallFunctionValue failed");
+    return JNI_FALSE;
+  }
+
+  PrintJSValue(cx, jsrval, "return value=");
+  JsRootedValue* returnVal = reinterpret_cast<JsRootedValue*>(jsRetValInt);
+  returnVal->setValue(jsrval);
+  return JNI_TRUE;
+}
+
+
+/*
+ * Class:     com_google_gwt_dev_shell_moz_LowLevelMoz
+ * Method:    _raiseJavaScriptException
+ * Signature: ()Z
+ */
+extern "C" JNIEXPORT jboolean JNICALL
+Java_com_google_gwt_dev_shell_moz_LowLevelMoz__1raiseJavaScriptException
+    (JNIEnv* env, jclass)
+{
+  Tracer tracer("LowLevelMoz._raiseJavaScriptException");
+  JS_SetPendingException(JsRootedValue::currentContext(), JSVAL_NULL);
+  return JNI_TRUE;
+}
+
+/*
+ * Class:     com_google_gwt_dev_shell_moz_LowLevelMoz
+ * Method:    _registerExternalFactoryHandler
+ * Signature: ()Z
+ */
+extern "C" JNIEXPORT jboolean JNICALL
+Java_com_google_gwt_dev_shell_moz_LowLevelMoz__1registerExternalFactoryHandler
+    (JNIEnv* env, jclass llClass)
+{
+  if (!InitGlobals(env, llClass))
+    return JNI_FALSE;
+
+  // tracing isn't setup until after InitGlobals is called
+  Tracer tracer("LowLevelMoz._registerExternalFactoryHandler");
+
+  char buf[256];
+  sprintf(buf, " jniEnv=%08x, llClass=%08x", (unsigned)env, (unsigned)llClass);
+  tracer.log(buf);
+  
+  // Register "window.external" as our own class
+  if (NS_FAILED(nsComponentManager::RegisterFactory(
+      kGwtExternalCID, "externalFactory", GWT_EXTERNAL_CONTRACTID,
+      new nsRpExternalFactory(), PR_TRUE))) {
+    tracer.setFail("RegisterFactory failed");
+    return JNI_FALSE;
+  }
+
+  nsCOMPtr<nsICategoryManager> categoryManager =
+      do_GetService(NS_CATEGORYMANAGER_CONTRACTID);
+  if (!categoryManager) {
+    tracer.setFail("unable to get category manager");
+    return JNI_FALSE;
+  }
+
+  nsXPIDLCString previous;
+  if (NS_FAILED(categoryManager->AddCategoryEntry(
+      JAVASCRIPT_GLOBAL_PROPERTY_CATEGORY, "external", GWT_EXTERNAL_CONTRACTID,
+      PR_TRUE, PR_TRUE, getter_Copies(previous)))) {
+    tracer.setFail("AddCategoryEntry failed");
+    return JNI_FALSE;
+  }
+
+  return JNI_TRUE;
+}
diff --git a/jni/linux/Makefile b/jni/linux/Makefile
new file mode 100644
index 0000000..8b3a8cf
--- /dev/null
+++ b/jni/linux/Makefile
@@ -0,0 +1,153 @@
+# Copyright 2007 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.
+
+##
+# Target settings
+##
+#JAVA_HOME
+#JAVA_HOME=/usr/lib/j2sdk1.5-sun
+
+# set GWT_TOOLS only if it is not already defined
+GWT_TOOLS ?= ../../../tools
+
+GWT_ROOT = ../../
+OBJDIR  := $(GWT_ROOT)build/out/jni/linux/
+OUTDIR  := $(GWT_ROOT)build/jni/linux/
+OUT     := $(OUTDIR)libgwt-ll.so
+STAGING := $(GWT_ROOT)build/staging/gwt-linux-0.0.0/
+
+##
+# The location to get .class files from for javah
+##
+CLASSDIR := $(GWT_ROOT)build/out/dev/linux/bin
+
+# use this instead if you want to use eclipse to build the class files during
+# development
+#CLASSDIR := $(GWT_ROOT)eclipse/dev/linux/bin
+
+##
+# Tools
+##
+CXX      := g++
+AR       := ar
+STRIP    := strip
+LD       := $(CXX)
+JAVAH    := $(JAVA_HOME)/bin/javah
+
+##
+# List of source, object, and dependency paths plus the path to them
+##
+SRCDIRS := ./:../core/
+VPATH   := .:../core
+SRCS    := gwt-ll.cpp LowLevelMoz.cpp JsValueMoz.cpp Tracer.cpp \
+	ExternalWrapper.cpp NativeWrapper.cpp JsRootedValue.cpp
+OBJS    := $(addprefix $(OBJDIR),$(SRCS:.cpp=.o))
+DEPS    := $(addprefix $(OBJDIR),$(SRCS:.cpp=.d))
+
+MOZDIR = $(GWT_TOOLS)/sdk/mozilla-1.7.12
+MOZINC = $(MOZDIR)/include
+MOZLIB = $(MOZDIR)/lib
+
+##
+# Include path configuration
+##
+SYSINCS := \
+    $(JAVA_HOME)/include \
+    $(JAVA_HOME)/include/linux \
+    $(MOZINC) $(MOZINC)/extra
+
+INCS := $(OBJDIR)
+INCS := $(addprefix -I ,$(INCS)) $(addprefix -isystem ,$(SYSINCS))
+
+##
+# Libraries and library path
+##
+LIBS    = xpcomglue_s
+LIBPATH = -L$(MOZLIB)
+LIBS     := $(addprefix -l,$(LIBS))
+
+# for notes on auto-dependency generation, see
+#   http://make.paulandlesley.org/autodep.html
+# -MP obviates the need for sed hackery
+CFLAGS   := -ggdb -m32 -Os -fPIC -fno-omit-frame-pointer -fno-strict-aliasing -D_REENTRANT -MMD -MP -Wno-system-headers $(CFLAGS)
+LDFLAGS  := -ggdb -m32 -s -fPIC -fno-omit-frame-pointer -fno-strict-aliasing -D_REENTRANT -Wl,-shared-gcc $(LDFLAGS)
+
+#-------------------------------------------------------------------------------
+# Rules
+#-------------------------------------------------------------------------------
+
+##
+# default rule
+##
+all: $(OUT)
+
+# install into prebuilt directory
+install: $(OUT)
+	cp $(OUT) prebuilt/
+
+##
+# Include the dependency rules
+##
+-include $(DEPS)
+
+##
+# javah-generated headers for native methods
+##
+$(OBJDIR)LowLevelMoz.h : $(CLASSDIR)/com/google/gwt/dev/shell/moz/LowLevelMoz.class
+	$(JAVAH) -classpath $(CLASSDIR) -o $(OBJDIR)LowLevelMoz.h com.google.gwt.dev.shell.moz.LowLevelMoz
+
+$(OBJDIR)JsValueMoz.h : $(CLASSDIR)/com/google/gwt/dev/shell/moz/JsValueMoz.class
+	$(JAVAH) -classpath $(CLASSDIR) -o $(OBJDIR)JsValueMoz.h com.google.gwt.dev.shell.moz.JsValueMoz
+
+##
+# Dependency rules for generated headers
+# TODO(jat): autogenerate these and others
+##
+$(OBJDIR)LowLevelMoz.o: $(OBJDIR)LowLevelMoz.h $(JAVA_HOME)/include/jni.h
+$(OBJDIR)JsValueMoz.o: $(OBJDIR)JsValueMoz.h $(JAVA_HOME)/include/jni.h
+
+##
+# Compilation rule for cpp files
+##
+$(OBJDIR)%.o : $(SRCDIR)%.cpp
+	@[ -d $(OBJDIR) ] || mkdir -p $(OBJDIR)
+	$(CXX) -c $(CFLAGS) $(INCS) -o $@ $<
+
+# generate preprocessed output files upon request for debugging
+%.i : $(SRCDIR)%.cpp
+	$(CXX) -E $(CFLAGS) $(INCS) -o $@ $<
+
+%.I : $(SRCDIR)%.cpp
+	$(CXX) -E -dDI $(CFLAGS) $(INCS) -o $@ $<
+
+##
+# Actual output file
+##
+$(OUT): $(OBJS) $(MOZLIB)/libxpcomglue_s.a
+	@[ -d $(OUTDIR) ] || mkdir -p $(OUTDIR)
+	$(LD) -shared $(LDFLAGS) $(LIBPATH) -o $@ $^ $(LIBS)
+	$(STRIP) --strip-unneeded $@
+
+##
+# copy to staging area for hosted-mode development
+##
+staging: $(OUT)
+	@[ -d $(STAGING) ] || mkdir -p $(STAGING)
+	cp $(OUT) $(STAGING)
+
+##
+# Clean rule
+##
+clean:
+	@-rm -rf $(OBJDIR) $(OUT)
diff --git a/jni/linux/NativeWrapper.cpp b/jni/linux/NativeWrapper.cpp
new file mode 100644
index 0000000..38958d0
--- /dev/null
+++ b/jni/linux/NativeWrapper.cpp
@@ -0,0 +1,211 @@
+/*
+ * Copyright 2007 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.
+ */
+
+/*
+ * Defines the JavaScript classes gwt_nativewrapper_class and
+ * gwt_functionwrapper_class, which interface via JNI to Java objects.
+ */
+
+#include <jni.h>
+#include "JsRootedValue.h"
+#include "gwt-jni.h"
+#include "Tracer.h"
+
+/*
+ * Helper function to get reference Java attributes from Javascript.
+ * 
+ * cx - JSContext pointer
+ * obj - JavaScript object which is a wrapped Java object
+ * id - property name, as a jsval string
+ * dispClass - output parameter of DispatchMethod subclass
+ * dispObj - output parameter of Java object
+ * jident - output parameter of property name as a Java string
+ */
+static JSBool getJavaPropertyStats(JSContext *cx, JSObject *obj, jsval id,
+    jclass& dispClass, jobject& dispObj, jstring& jident)
+{
+  Tracer tracer("getJavaPropertyStats");
+  if (!JSVAL_IS_STRING(id)) {
+    tracer.setFail("id is not a string");
+    return JS_FALSE;
+  }
+
+  jident = savedJNIEnv->NewString(JS_GetStringChars(JSVAL_TO_STRING(id)),
+      JS_GetStringLength(JSVAL_TO_STRING(id)));
+  if (!jident || savedJNIEnv->ExceptionCheck()) {
+    tracer.setFail("unable to create Java string");
+    return JS_FALSE;
+  }
+
+  dispObj = NS_REINTERPRET_CAST(jobject, JS_GetPrivate(cx, obj));
+  if (!dispObj) {
+    tracer.setFail("can't get dispatch object");
+    return JS_FALSE;
+  }
+
+  dispClass = savedJNIEnv->GetObjectClass(dispObj);
+  if (savedJNIEnv->ExceptionCheck()) {
+    tracer.setFail("can't get class of dispatch object");
+    return JS_FALSE;
+  }
+
+  return JS_TRUE;
+}
+  
+/*
+ * Returns the value of a field on a Java object.
+ * 
+ * context - JavaScript context
+ * clazz - class of obj
+ * obj - Java object to retreive field from
+ * fieldName - name of field on Java object to retrieve
+ * 
+ * Returns null on failure.  Caller is responsible for deleting
+ * returned JsRootedValue when done with it.
+ */
+static JsRootedValue* GetFieldAsRootedValue(JSContext* cx, jclass clazz,
+    jobject obj, jstring fieldName)
+{
+  Tracer tracer("GetFieldAsRootedValue");
+  JsRootedValue::ContextManager context(cx);
+  jmethodID getFieldMeth = savedJNIEnv->GetMethodID(clazz, "getField",
+      "(Ljava/lang/String;I)V");
+  if (!getFieldMeth || savedJNIEnv->ExceptionCheck()) {
+    return 0;
+  }
+
+  JsRootedValue* jsRootedValue = new JsRootedValue();
+  savedJNIEnv->CallVoidMethod(obj, getFieldMeth, fieldName,
+    reinterpret_cast<jint>(jsRootedValue));
+  if (savedJNIEnv->ExceptionCheck()) {
+    delete jsRootedValue;
+    return 0;
+  }
+  return jsRootedValue;
+}
+  
+/*
+ * Sets the value of a field on a Java object.
+ * 
+ * context - JavaScript context
+ * clazz - class of obj
+ * obj - Java object to store into field
+ * fieldName - name of field on Java object to store into
+ * jsRootedValue - the value to store in the field
+ * 
+ * returns true on success, false on failure
+ */
+static bool SetFieldFromRootedValue(JSContext* cx, jclass clazz,
+    jobject obj, jstring fieldName, JsRootedValue* jsRootedValue)
+{
+  Tracer tracer("SetFieldAsRootedValue");
+  JsRootedValue::ContextManager context(cx);
+  jmethodID getFieldMeth = savedJNIEnv->GetMethodID(clazz, "setField",
+      "(Ljava/lang/String;I)V");
+  if (!getFieldMeth || savedJNIEnv->ExceptionCheck()) {
+    return false;
+  }
+
+  savedJNIEnv->CallVoidMethod(obj, getFieldMeth, fieldName,
+    reinterpret_cast<jint>(jsRootedValue));
+  if (savedJNIEnv->ExceptionCheck()) {
+    return false;
+  }
+
+  return true;
+}
+
+static JSBool JS_DLL_CALLBACK gwt_nativewrapper_getProperty(JSContext *cx,
+    JSObject *obj, jsval id, jsval *vp)
+{
+  Tracer tracer("gwt_nativewrapper_getProperty");
+  tracer.log("context=%08x, obj=%08x", unsigned(cx), unsigned(obj));
+  JsRootedValue::ContextManager context(cx);
+
+  jclass dispClass;
+  jobject dispObj;
+  jstring ident;
+  if (!getJavaPropertyStats(cx, obj, id, dispClass, dispObj, ident)) {
+    tracer.setFail("getJavaPropertyStats failed");
+    return JS_FALSE;
+  }
+  JsRootedValue* js_rooted_value = GetFieldAsRootedValue(cx, dispClass,
+      dispObj, ident);
+  if (!js_rooted_value) {
+    tracer.setFail("can't get field");
+    return JS_FALSE;
+  }
+  *vp = js_rooted_value->getValue();
+  return JS_TRUE;
+}
+
+static void JS_DLL_CALLBACK gwt_nativewrapper_finalize(JSContext *cx,
+    JSObject *obj)
+{
+  Tracer tracer("gwt_nativewrapper_finalize");
+  jobject dispObj = NS_REINTERPRET_CAST(jobject, JS_GetPrivate(cx, obj));
+  if (dispObj) {
+    // Remove this pairing from the global map.
+    jmethodID removeMethod = savedJNIEnv->GetStaticMethodID(lowLevelMozClass, "removeJsvalForObject",
+      "(Ljava/lang/Object;)V");
+    if (!removeMethod || savedJNIEnv->ExceptionCheck()) {
+      tracer.setFail("Cannot GetMethodID for removeJsvalForObject");
+      return;
+    }
+    savedJNIEnv->CallStaticVoidMethod(lowLevelMozClass, removeMethod, dispObj);
+    if (savedJNIEnv->ExceptionCheck()) {
+      tracer.setFail("Exception calling removeJsvalForObject");
+      return;
+    }
+    savedJNIEnv->DeleteGlobalRef(dispObj);
+  }
+}
+
+static JSBool JS_DLL_CALLBACK gwt_nativewrapper_setProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
+{
+  Tracer tracer("gwt_nativewrapper_setProperty");
+  tracer.log("context=%08x", unsigned(cx));
+  JsRootedValue::ContextManager context(cx);
+  jclass dispClass;
+  jobject dispObj;
+  jstring ident;
+  if (!getJavaPropertyStats(cx, obj, id, dispClass, dispObj, ident)) {
+    tracer.setFail("getJavaPropertyStats failed");
+    return JS_FALSE;
+  }
+  JsRootedValue* js_rooted_value = new JsRootedValue(*vp); 
+  if (!SetFieldFromRootedValue(cx, dispClass, dispObj, ident,
+      js_rooted_value)) {
+    tracer.setFail("can't set field");
+    return JS_FALSE;
+  }
+  return JS_TRUE;
+}
+
+JSClass gwt_nativewrapper_class = {
+  "gwt_nativewrapper_class", JSCLASS_HAS_PRIVATE,
+  JS_PropertyStub, JS_PropertyStub, gwt_nativewrapper_getProperty,
+  gwt_nativewrapper_setProperty, JS_EnumerateStub, JS_ResolveStub,
+  JS_ConvertStub, gwt_nativewrapper_finalize,
+  JSCLASS_NO_OPTIONAL_MEMBERS
+};
+
+JSClass gwt_functionwrapper_class = {
+  "gwt_functionwrapper_class", JSCLASS_HAS_PRIVATE,
+  JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
+  JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, gwt_nativewrapper_finalize,
+  JSCLASS_NO_OPTIONAL_MEMBERS
+};
diff --git a/jni/linux/Tracer.cpp b/jni/linux/Tracer.cpp
new file mode 100644
index 0000000..e5f3189
--- /dev/null
+++ b/jni/linux/Tracer.cpp
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2007 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 "Tracer.h"
+
+#ifdef ENABLE_TRACING
+
+// initialize static fields
+FILE* Tracer::outfp = 0;
+JNIEnv* Tracer::jniEnv = 0;
+jclass Tracer::traceClass;
+jmethodID Tracer::traceMethod;
+int Tracer::indentation = 0;
+Tracer::LogLevel Tracer::logLevel = Tracer::LEVEL_WARNING;
+
+/*
+ * Sets a JNI environment and Java class to pass trace messages to.
+ * 
+ * env - JNI environment to use for trace calls
+ * clazz - Java class, which must provide static void trace(String)
+ */
+bool Tracer::setJava(JNIEnv* env, jclass clazz) {
+  jniEnv = env;
+  if (!env) {
+    return true;
+  }
+  traceClass = static_cast<jclass>(env->NewGlobalRef(clazz));
+  if (!traceClass || env->ExceptionCheck()) {
+    return false;
+  }
+  traceMethod = env->GetStaticMethodID(traceClass, "trace",
+    "(Ljava/lang/String;)V");
+  if (!traceMethod || env->ExceptionCheck()) {
+    return false;
+  }
+
+  jstring msg = jniEnv->NewStringUTF("== Java trace started ==");
+  jniEnv->CallStaticVoidMethod(traceClass, traceMethod, msg);
+  return true;
+}
+
+#endif // ENABLE_TRACING
+
+/*
+ * Throw a HostedModeException and log a failure message.
+ * 
+ * Creates a new HostedModeException with the failure message,
+ * and also logs the failure message 
+ * 
+ * env - JNI environment to throw the exception in
+ * msg - failure message 
+ */
+void Tracer::throwHostedModeException(JNIEnv* env, const char* msg) {
+#ifdef ENABLE_TRACING
+  setFail(msg);
+#endif // ENABLE_TRACING
+  jclass exceptionClass
+      = env->FindClass("com/google/gwt/dev/shell/HostedModeException");
+  env->ThrowNew(exceptionClass, msg);
+}
diff --git a/jni/linux/Tracer.h b/jni/linux/Tracer.h
new file mode 100644
index 0000000..ef9fd7d
--- /dev/null
+++ b/jni/linux/Tracer.h
@@ -0,0 +1,297 @@
+/*
+ * Copyright 2007 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.
+ */
+#ifndef JNI_LINUX_TRACER_H_
+#define JNI_LINUX_TRACER_H_
+
+#include <cstdio>
+#include <cstdarg>
+#include <cstring>
+#include <jni.h>
+
+// comment this out to remove almost all runtime overhead (with usual compiler
+// support) from tracing.
+//#define ENABLE_TRACING
+
+/*
+ * Utility class for tracing.  This class is intended to be used as follows:
+ * 
+ * {
+ *   Tracer tracer("method name");
+ *   ... do work
+ *   if (fail) {
+ *      tracer.setFail("failure explanation");
+ *      return;
+ *   }
+ *   if (fail2) {
+ *      tracer.throwHostedModeException("failure explanation");
+ *      return;
+ *   }
+ *   return;
+ * }
+ * 
+ * The class automatically logs an enter message when it is created, as well
+ * as leave/fail messages when it is destroyed.  Logging is performed to a
+ * file or to a Java static member function on a class (or both) -- these
+ * are configured by using static member functions setFile() and setJava().
+ * 
+ * This class knows about the Java class
+ *   com.google.gwt.dev.shell.HostedModeException
+ * and throws a new instance of that exception if requested.
+ */
+class Tracer {
+public:
+  enum LogLevel {
+    LEVEL_ERROR = 0,
+    LEVEL_WARNING,
+    LEVEL_NOTICE,
+    LEVEL_INFO,
+    LEVEL_DEBUG,
+    LEVEL_DEBUG_V1,
+    LEVEL_DEBUG_V2,
+  };
+protected:
+#ifdef ENABLE_TRACING
+  // static variables that specify where logging is performed.  This are
+  // set by calling setFile() and setJava().
+  static FILE*     outfp;
+  static JNIEnv*   jniEnv;
+  static jclass    traceClass;
+  static jmethodID traceMethod;
+  static int       indentation;
+  static LogLevel  logLevel;
+
+  // method is set when the instance is created.
+  const char*		method_;
+  // fail_msg is set to indicate a failure has occurred.
+  const char*		fail_msg_;
+  // level of this trace object
+  LogLevel  log_level_;
+#endif
+  
+public:
+  /*
+   * Set the logging level.
+   */
+  static void setLevel(LogLevel level) {
+#ifdef ENABLE_TRACING
+    logLevel = level;
+#endif
+  }
+  
+protected:
+  /*
+   * Log a message (with supplied prefix) to the configured file.
+   * Only called if a file was specified and successfully opened for writing.
+   */
+  static void logFile(const char* msg) {
+#ifdef ENABLE_TRACING
+    for (int i = 0; i < indentation; ++i) {
+      putc(' ', outfp);
+    }
+    fputs(msg, outfp);
+    putc('\n', outfp);
+    fflush(outfp);
+#else
+    (void)msg; // avoid unused warning
+#endif
+  }
+
+  /*
+   * Log a message (with supplied prefix) to the configured Java class.
+   * Only called if a file was specified and successfully accessed.
+   * 
+   * Call static void trace(String msg) on the configured class. 
+   */
+  static void logJava(const char* msg) {
+#ifdef ENABLE_TRACING
+    // TODO(jat): fixed buffer size
+    char buf[512];
+    for (int i = 0; (i < indentation) && (i < int(sizeof(buf))); ++i) {
+      buf[i] = ' ';
+    }
+    strncpy(buf + indentation, msg, sizeof(buf) - indentation);
+    buf[sizeof(buf) - 1] = 0; // ensure null termination
+    jstring str = jniEnv->NewStringUTF(buf);
+    jniEnv->CallStaticVoidMethod(traceClass, traceMethod, str);
+#else
+    (void)msg; // avoid unused warning
+#endif
+  }
+
+  /*
+   * Log a message to a file and/or class with the default logging level.
+   * 
+   * If the preprocessor symbol DISABLE_TRACING has been defined, this is
+   * completely removed from the code path.
+   */
+  void logPrefix(const char* prefix) {
+#ifdef ENABLE_TRACING
+    logPrefix(prefix, log_level_);
+#else
+    (void)prefix; // avoid unused warning
+#endif
+  }
+  
+  /*
+   * Log a message to a file and/or class.
+   * 
+   * If the preprocessor symbol DISABLE_TRACING has been defined, this is
+   * completely removed from the code path.
+   */
+  void logPrefix(const char* prefix, LogLevel level) {
+#ifdef ENABLE_TRACING
+    if (level>logLevel) return;
+    log("%-5.5s %s%s%s", prefix, method_, fail_msg_ ? ": " : "",
+        fail_msg_ ? fail_msg_ : "");
+#endif
+  }
+    
+public:
+  /*
+   * Create an instance with the specified method name and no failure
+   * message.  Log an ENTER message.
+   */
+  Tracer(const char* method, LogLevel log_level = LEVEL_ERROR)
+#ifdef ENABLE_TRACING
+      : method_(method), fail_msg_(0), log_level_(log_level) {
+    log("ENTER %s", method);
+    indentation++;
+#else
+  { (void)method; (void)log_level; // avoid unused warnings
+#endif
+  }
+
+  /*
+   * Create an instance with the specified method name and no failure
+   * message.  Log an ENTER message and the this pointer.
+   */
+  Tracer(const char* method, const void* objThis,
+      LogLevel log_level = LEVEL_ERROR)
+#ifdef ENABLE_TRACING
+      : method_(method), fail_msg_(0), log_level_(log_level) {
+    log("ENTER %s(this=%08x)", method, unsigned(objThis));
+    indentation++;
+#else
+  { (void)method; (void)objThis; (void)log_level; // avoid unused warnings
+#endif
+  }
+
+  /*
+   * Destroy the instance and log a fail or leave message.
+   */
+  ~Tracer() {
+#ifdef ENABLE_TRACING
+    --indentation;
+    if(fail_msg_) {
+      logPrefix("*FAIL", LEVEL_ERROR);
+    } else {
+      logPrefix("LEAVE");
+    }
+#endif
+  }
+  
+  /*
+   * Specify a filename to receive logging output.  Close any previously
+   * opened file.  If a null filename is passed, disable logging to a
+   * file.
+   * 
+   * filename - the file path to receive logging output.  This file is
+   *     truncated if it already exists.
+   * 
+   * Returns false on failure.
+   */
+  static bool setFile(const char* filename) {
+#ifdef ENABLE_TRACING
+    if (outfp) {
+      fclose(outfp);
+      outfp = 0;
+    }
+    if (!filename) {
+      return true;
+    }
+    outfp = fopen(filename, "w");
+    if (!outfp) {
+      return false;
+    }
+    fprintf(outfp, "== started logging ==\n");
+    fflush(outfp);
+#else
+    (void)filename; // avoid unused warning
+#endif
+    return true;
+  }
+  
+  /*
+   * Specify a Java class to receive logging output.  The supplied class
+   * must have a static void trace(String) member function which is called
+   * for output.  Logging to a Java class is disabled if the supplied JNI
+   * environment is null.
+   * 
+   * env - JNI environment
+   * clazz - the Java class to receive logging output
+   * 
+   * Returns false on failure.
+   */ 
+  static bool setJava(JNIEnv* env, jclass clazz)
+#ifdef ENABLE_TRACING  
+  ;
+#else
+  // inline a null body if we aren't debugging; avoid unused warnings
+  { (void)env; (void)clazz; return true; }
+#endif
+  
+  /*
+   * Set a failure message, overwriting any previously specified failure
+   * message.  Passing a null string will remove any previous failure
+   * notification.
+   */
+  void setFail(const char* fail_msg) {
+#ifdef ENABLE_TRACING
+    fail_msg_ = fail_msg;
+#else
+    (void)fail_msg; // avoid unused warning
+#endif
+  }
+  
+  /*
+   * Throw a Java HostedModeException as well as set a failure message to
+   * be logged.
+   * 
+   * env - JNI environment to throw exception into
+   * fail_msg - failure message 
+   */
+  void throwHostedModeException(JNIEnv* env, const char* fail_msg);
+  
+  /*
+   * Log an arbitrary message.
+   */
+  static void log(const char* format, ...) {
+#ifdef ENABLE_TRACING
+    va_list args;
+    va_start(args, format);
+    char msg[512]; // TODO(jat): fixed size buffer
+    vsnprintf(msg, sizeof(msg), format, args);
+    msg[sizeof(msg) - 1] = 0; // ensure null termination
+    if(outfp) logFile(msg);
+    if(jniEnv) logJava(msg);
+    va_end(args);
+#else
+    (void)format; // avoid unused warning
+#endif
+  }
+};
+
+#endif /* JNI_LINUX_TRACER_H_ */
diff --git a/jni/linux/build.xml b/jni/linux/build.xml
new file mode 100755
index 0000000..5f0db6b
--- /dev/null
+++ b/jni/linux/build.xml
@@ -0,0 +1,18 @@
+<project name="jni-linux" default="build" basedir=".">
+  <property name="gwt.root" location="../.." />
+  <property name="project.tail" value="jni/linux" />
+  <import file="${gwt.root}/common.ant.xml" />
+
+  <target name="build" description="Builds a JNI lib">
+    <mkdir dir="${project.jni}" />
+    <!-- TODO: Actually build this from source! -->
+    <copy todir="${project.jni}">
+      <fileset dir="prebuilt" />
+    </copy>
+  </target>
+
+  <target name="clean" description="Cleans this project's intermediate and output files">
+    <delete dir="${project.build}" failonerror="false" />
+    <delete dir="${project.jni}" failonerror="false" />
+  </target>
+</project>
diff --git a/jni/linux/gwt-jni.h b/jni/linux/gwt-jni.h
new file mode 100644
index 0000000..c477f1c
--- /dev/null
+++ b/jni/linux/gwt-jni.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2007 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.
+ */
+#ifndef JNI_LINUX_GWT_JNI_H_
+#define JNI_LINUX_GWT_JNI_H_
+
+#include <jni.h>
+#include "JsRootedValue.h"
+#include "JStringWrap.h"
+
+extern JNIEnv* savedJNIEnv;
+extern jclass lowLevelMozClass;
+
+extern nsCID kGwtExternalCID;
+
+// JavaScript class objects
+extern JSClass gwt_nativewrapper_class;
+extern JSClass gwt_functionwrapper_class;
+
+#endif /*JNI_LINUX_GWT_JNI_H_*/
diff --git a/jni/linux/mozilla-headers.h b/jni/linux/mozilla-headers.h
new file mode 100644
index 0000000..6259b41
--- /dev/null
+++ b/jni/linux/mozilla-headers.h
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2007 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 all of the necessary Mozilla headers.
+#include "mozilla-config.h"
+#include "nsIServiceManagerUtils.h"
+#include "nsComponentManagerUtils.h"
+#include "nsICategoryManager.h"
+#include "nsIScriptNameSpaceManager.h"
+#include "nsIScriptObjectOwner.h"
+#include "nsIScriptGlobalObject.h"
+#include "nsIScriptContext.h"
+#include "nsIDOMWindow.h"
+#include "nsIXPConnect.h"
+#include "nsIFactory.h"
+#include "nsCOMPtr.h"
+#include "nsAutoPtr.h"
diff --git a/jni/linux/prebuilt/libgwt-ll.so b/jni/linux/prebuilt/libgwt-ll.so
new file mode 100755
index 0000000..97ead651
--- /dev/null
+++ b/jni/linux/prebuilt/libgwt-ll.so
Binary files differ
diff --git a/jni/mac/JStringWrap.h b/jni/mac/JStringWrap.h
new file mode 100644
index 0000000..e17981f
--- /dev/null
+++ b/jni/mac/JStringWrap.h
@@ -0,0 +1,42 @@
+/* 
+ * Copyright 2007 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.
+ */
+#ifndef JSTRINGWRAP_H
+#define JSTRINGWRAP_H
+
+#include <jni.h>
+
+/*
+ * Wrap a Java String and automatically clean up temporary storage allocated
+ * for accessing its contents.
+ */
+struct JStringWrap
+{
+  JStringWrap(JNIEnv* env, jstring str): env(env), s(str), p(0), jp(0) { }
+  ~JStringWrap() {
+  	if (p) env->ReleaseStringUTFChars(s, p);
+  	if (jp) env->ReleaseStringChars(s, jp);
+  }
+  const char* str() { if (!p) p = env->GetStringUTFChars(s, 0); return p; }
+  const jchar* jstr() { if (!jp) jp = env->GetStringChars(s, 0); return jp; }
+  jsize length() { return env->GetStringLength(s); }
+private:
+  JNIEnv* env;
+  jstring s;
+  const char* p;
+  const jchar* jp;
+};
+
+#endif
diff --git a/jni/mac/Makefile b/jni/mac/Makefile
new file mode 100644
index 0000000..867b511
--- /dev/null
+++ b/jni/mac/Makefile
@@ -0,0 +1,89 @@
+# 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.
+
+CC = g++
+JAVAH = javah
+
+##
+# Try a GWT_TOOLS default if it isn't set
+##
+GWT_TOOLS ?= ../../../tools
+GWT_ROOT ?= ../..
+
+##
+# The location to get .class files for javah
+##
+CLASSDIR := $(GWT_ROOT)/build/out/dev/mac/bin
+
+##
+# External SWT products.
+##
+SWT_ORIGINAL_SRC = $(GWT_TOOLS)/lib/eclipse/org.eclipse.swt.carbon-macosx-3.2.1.src.zip
+SWT_PATCH_DIR = ./swt-build
+SWT_LIBS=$(SWT_PATCH_DIR)/libswt-webkit-carbon-3235.jnilib \
+	$(SWT_PATCH_DIR)/libswt-agl-carbon-3235.jnilib \
+	$(SWT_PATCH_DIR)/libswt-carbon-3235.jnilib \
+	$(SWT_PATCH_DIR)/libswt-pi-carbon-3235.jnilib
+
+GWT_LL_LIB = libgwt-ll.jnilib
+GWT_LL_OBJS = gwt-ll.o java-dispatch.o gwt-webkit.o trace.o
+GWT_LL_JNI = gwt-webkit.h
+
+TARGETS = $(GWT_LL_LIB) $(SWT_LIBS)
+ARCHS = -arch i386 -arch ppc
+CFLAGS = -I/System/Library/Frameworks/JavaScriptCore.framework/Headers -I/System/Library/Frameworks/JavaVM.framework/Headers
+LFLAGS = -bundle -framework JavaScriptCore
+
+ALL : $(TARGETS)
+
+##
+# Unpack and patch SWT source.
+##
+$(SWT_PATCH_DIR): $(SWT_ORIGINAL_SRC) ./org.eclipse.swt/webkit.c
+	unzip $(SWT_ORIGINAL_SRC) -d $(SWT_PATCH_DIR)
+	cp ./org.eclipse.swt/webkit.c  $(SWT_PATCH_DIR)
+
+##
+# Build SWT.
+##
+$(SWT_LIBS):$(SWT_PATCH_DIR)
+	make -C $(SWT_PATCH_DIR) -f make_macosx.mak
+
+##
+# Build core gwt-ll object.
+##
+gwt-ll.o : ../core/gwt-ll.cpp
+	$(CC) -c -Wall -o $@ $(ARCHS) $(CFLAGS) $<
+
+##
+# General coff target.
+##
+%.o : %.cpp
+	$(CC) -c -Wall -o $@ $(ARCHS) $(CFLAGS) $<
+
+##
+# Generate JNI Header
+##
+gwt-webkit.h : $(CLASSDIR)/com/google/gwt/dev/shell/mac/LowLevelSaf.class
+	$(JAVAH) -classpath $(CLASSDIR) -o gwt-webkit.h com.google.gwt.dev.shell.mac.LowLevelSaf
+
+##
+# Build gwt-ll library.
+##
+$(GWT_LL_LIB) : $(GWT_LL_JNI) $(GWT_LL_OBJS)
+	$(CC) -Wall -o $@ $(ARCHS) $(LFLAGS) $(GWT_LL_OBJS)
+
+clean:
+	rm -f $(GWT_LL_JNI) $(GWT_LL_OBJS) $(TARGETS)
+	rm -rf $(SWT_PATCH_DIR)
diff --git a/jni/mac/build.xml b/jni/mac/build.xml
new file mode 100755
index 0000000..66b6580
--- /dev/null
+++ b/jni/mac/build.xml
@@ -0,0 +1,18 @@
+<project name="jni-mac" default="build" basedir=".">
+  <property name="gwt.root" location="../.." />
+  <property name="project.tail" value="jni/mac" />
+  <import file="${gwt.root}/common.ant.xml" />
+
+  <target name="build" description="Builds a JNI lib">
+    <mkdir dir="${project.jni}" />
+    <!-- TODO: Actually build this from source! -->
+    <copy todir="${project.jni}">
+      <fileset dir="prebuilt" />
+    </copy>
+  </target>
+
+  <target name="clean" description="Cleans this project's intermediate and output files">
+    <delete dir="${project.build}" failonerror="false" />
+    <delete dir="${project.jni}" failonerror="false" />
+  </target>
+</project>
diff --git a/jni/mac/gwt-webkit.cpp b/jni/mac/gwt-webkit.cpp
new file mode 100644
index 0000000..477b312
--- /dev/null
+++ b/jni/mac/gwt-webkit.cpp
@@ -0,0 +1,886 @@
+/*
+ * Copyright 2008 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+#include <iostream>
+#include <JavaScriptCore/JavaScriptCore.h>
+#include "gwt-webkit.h"
+#include "JStringWrap.h"
+#include "java-dispatch.h"
+#include "trace.h"
+
+
+// http://unixjunkie.blogspot.com/2006/07/access-argc-and-argv-from-anywhere.html
+extern "C" int *_NSGetArgc(void);
+extern "C" char ***_NSGetArgv(void);
+
+/*
+ *
+ */
+JSContextRef ToJSContextRef(jint context) {
+  return reinterpret_cast<JSContextRef>(context);
+}
+
+/*
+ *
+ */
+JSValueRef ToJSValueRef(jint value) {
+  return reinterpret_cast<JSValueRef>(value);
+}
+
+/*
+ *
+ */
+JSObjectRef ToJSObjectRef(JSContextRef jsContext, jint object,
+    JSValueRef* jsException) {
+  JSValueRef jsValue = reinterpret_cast<JSValueRef>(object);
+  if (!jsValue || !JSValueIsObject(jsContext, jsValue)) {
+    return NULL;
+  }
+  return JSValueToObject(jsContext, jsValue, jsException);
+}
+
+/*
+ *
+ */
+JSObjectRef ToJSObjectRef(JSContextRef jsContext, JSValueRef jsValue,
+    JSValueRef* jsException) {
+  if (!jsValue || !JSValueIsObject(jsContext, jsValue)) {
+    return NULL;
+  }
+  return JSValueToObject(jsContext, jsValue, jsException);
+}
+
+/*
+ *
+ */
+JSObjectRef GetStringConstructor(JSContextRef jsContext,
+    JSValueRef* jsException) {
+  // This could only be cached relative to jsContext.
+  JSStringRef script = JSStringCreateWithUTF8CString("(String)");
+  JSValueRef ctorVal = JSEvaluateScript(jsContext, script, NULL, NULL, 0, jsException);
+  JSStringRelease(script);
+  return ToJSObjectRef(jsContext, ctorVal, jsException);
+}
+
+/*
+ *
+ */
+bool IsObjectOfStringConstructor(JSContextRef jsContext, JSValueRef jsValue,
+    JSValueRef* jsException) {
+  JSObjectRef jsObject = ToJSObjectRef(jsContext, jsValue, jsException);
+  if (!jsObject) {
+    return false;
+  }
+  JSObjectRef stringCtor = GetStringConstructor(jsContext, jsException);
+  if (!stringCtor) {
+    return false;
+  }
+  return JSValueIsInstanceOfConstructor(jsContext, jsObject, stringCtor,
+      jsException);
+}
+
+#if 0 // For debugging purposes only.
+void PrintJSString(JSStringRef jsString)
+{
+  size_t length = JSStringGetMaximumUTF8CStringSize(jsString);
+  char* buffer = new char[length];
+  JSStringGetUTF8CString(jsString, buffer, length);
+  std::cerr << "JSString: " << buffer << std::endl;
+  delete[] buffer;
+}
+
+void PrintJSValue(JSContextRef jsContext, JSValueRef jsValue)
+{
+  JSValueRef jsException = NULL;
+  JSStringRef jsResult = JSValueToStringCopy(jsContext, jsValue,
+      &jsException);
+  if (!jsException && jsValue) {
+    PrintJSString(jsResult);
+  } else {
+    std::cerr << "Could not convert the value to string." << std::endl;
+  }
+}
+#endif
+
+/*
+ *
+ */
+JSStringRef ToJSStringRef(JNIEnv* env, jstring jstr) {
+  if (!jstr) {
+    return NULL;
+  }
+
+  JStringWrap jstrw(env, jstr);
+  if (!jstrw.jstr()) {
+    return NULL;
+  }
+
+  return JSStringCreateWithCharacters(static_cast<const JSChar*>(jstrw.jstr()),
+      static_cast<size_t>(jstrw.length()));
+}
+
+/*
+ *
+ */
+JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_isJsNull
+    (JNIEnv *env, jclass klass, jint context, jint value) {
+  TR_ENTER();
+  JSContextRef jsContext = ToJSContextRef(context);
+  JSValueRef jsValue = ToJSValueRef(value);
+  if (!jsContext || !jsValue) {
+    TR_FAIL();
+    return JNI_FALSE;
+  }
+  TR_LEAVE();
+  return static_cast<jboolean>(JSValueIsNull(jsContext, jsValue));
+}
+
+/*
+ *
+ */
+JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_isJsUndefined
+    (JNIEnv *env, jclass klass, jint context, jint value) {
+  TR_ENTER();
+  JSContextRef jsContext = ToJSContextRef(context);
+  JSValueRef jsValue = ToJSValueRef(value);
+  if (!jsContext || !jsValue) {
+    TR_FAIL();
+    return JNI_FALSE;
+  }
+  TR_LEAVE();
+  return static_cast<jboolean>(JSValueIsUndefined(jsContext, jsValue));
+}
+
+/*
+ *
+ */
+JNIEXPORT jint JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_getJsUndefined
+    (JNIEnv *env, jclass klass, jint context) {
+  TR_ENTER();
+  JSContextRef jsContext = ToJSContextRef(context);
+  if (!jsContext) {
+    return static_cast<jint>(NULL);
+  }
+
+  JSValueRef jsUndefined = JSValueMakeUndefined(jsContext);
+  JSValueProtectChecked(jsContext, jsUndefined);
+  TR_LEAVE();
+  return reinterpret_cast<jint>(jsUndefined);
+}
+
+/*
+ *
+ */
+JNIEXPORT jint JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_getJsNull
+    (JNIEnv *env, jclass klass, jint context) {
+  TR_ENTER();
+  JSContextRef jsContext = ToJSContextRef(context);
+  if (!jsContext) {
+    return static_cast<jint>(NULL);
+  }
+  JSValueRef jsNull = JSValueMakeNull(jsContext);
+  JSValueProtectChecked(jsContext, jsNull);
+  TR_LEAVE();
+  return reinterpret_cast<jint>(jsNull);
+}
+
+/*
+ *
+ */
+JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_isJsBoolean
+    (JNIEnv *env, jclass klass, jint context, jint value) {
+  TR_ENTER();
+  JSContextRef jsContext = ToJSContextRef(context);
+  JSValueRef jsValue = ToJSValueRef(value);
+  if (!jsContext || !jsValue) {
+    TR_FAIL();
+    return JNI_FALSE;
+  }
+  TR_LEAVE();
+  return static_cast<jboolean>(JSValueIsBoolean(jsContext, jsValue));
+}
+
+/*
+ *
+ */
+JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_isJsNumber
+    (JNIEnv *env, jclass klass, jint context, jint value) {
+  TR_ENTER();
+  JSContextRef jsContext = ToJSContextRef(context);
+  JSValueRef jsValue = ToJSValueRef(value);
+  if (!jsContext || !jsValue) {
+    TR_FAIL();
+    return JNI_FALSE;
+  }
+  TR_LEAVE();
+  return static_cast<jboolean>(JSValueIsNumber(jsContext, jsValue));
+}
+
+/*
+ *
+ */
+JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_toJsBooleanImpl
+    (JNIEnv *env, jclass klass, jint context, jboolean jValue, jintArray rval) {
+  TR_ENTER();
+  JSContextRef jsContext = ToJSContextRef(context);
+  if (!jsContext) {
+    TR_FAIL();
+    return JNI_FALSE;
+  }
+
+  JSValueRef jsValue = JSValueMakeBoolean(jsContext, static_cast<bool>(jValue));
+
+  env->SetIntArrayRegion(rval, 0, 1, reinterpret_cast<const jint*>(&jsValue));
+  if (env->ExceptionCheck()) {
+    TR_FAIL();
+    return JNI_FALSE;
+  }
+  JSValueProtectChecked(jsContext, jsValue);
+
+  TR_LEAVE();
+  return JNI_TRUE;
+}
+
+/*
+ *
+ */
+JNIEXPORT void JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_gcUnprotect
+    (JNIEnv *env, jclass klass, jint context, jint value) {
+  TR_ENTER();
+  JSContextRef jsContext = ToJSContextRef(context);
+  JSValueRef jsValue = ToJSValueRef(value);
+  if (!jsContext || !jsValue) {
+    return;
+  }
+  JSValueUnprotectChecked(jsContext, jsValue);
+  TR_LEAVE();
+}
+
+/*
+ *
+ */
+JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_toJsNumberImpl
+    (JNIEnv *env, jclass klass, jint context, jdouble jValue, jintArray rval) {
+  TR_ENTER();
+  JSContextRef jsContext = ToJSContextRef(context);
+  if (!jsContext) {
+    TR_FAIL();
+    return JNI_FALSE;
+  }
+
+  JSValueRef jsValue = JSValueMakeNumber(jsContext, static_cast<jdouble>(jValue));
+
+  env->SetIntArrayRegion(rval, 0, 1, reinterpret_cast<const jint*>(&jsValue));
+  if (env->ExceptionCheck()) {
+    TR_FAIL();
+    return JNI_FALSE;
+  }
+
+  JSValueProtectChecked(jsContext, jsValue);
+
+  TR_LEAVE();
+  return JNI_TRUE;
+}
+
+/*
+ *
+ */
+JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_executeScriptWithInfoImpl
+    (JNIEnv *env, jclass klass, jint context, jstring jScript, jstring jUrl,
+    jint jLine, jintArray rval) {
+  TR_ENTER();
+  JSValueRef jsException = NULL;
+
+  JSContextRef jsContext = ToJSContextRef(context);
+  if (!jsContext) {
+    TR_FAIL();
+    return JNI_FALSE;
+  }
+
+  JSStringRef jsScript = ToJSStringRef(env, jScript);
+  if (!jsScript) {
+    TR_FAIL();
+    return JNI_FALSE;
+  }
+
+  JSStringRef jsUrl = ToJSStringRef(env, jUrl);
+
+  // Evaluate will set this to global object.
+  JSValueRef jsResult = JSEvaluateScript(jsContext, jsScript, NULL, jsUrl,
+      static_cast<int>(jLine), &jsException);
+  if (jsException) {
+    TR_FAIL();
+    return JNI_FALSE;
+  }
+
+  JSStringRelease(jsScript);
+  if (jsUrl) {
+    JSStringRelease(jsUrl);
+  }
+
+  env->SetIntArrayRegion(rval, 0, 1, reinterpret_cast<const jint*>(&jsResult));
+  if (env->ExceptionCheck()) {
+    TR_FAIL();
+    return JNI_FALSE;
+  }
+
+  JSValueProtectChecked(jsContext, jsResult);
+
+  TR_LEAVE();
+  return JNI_TRUE;
+}
+
+/*
+ *
+ */
+JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_toJsStringImpl
+    (JNIEnv *env, jclass klass, jint context, jstring jValue, jintArray rval) {
+  TR_ENTER();
+  JSContextRef jsContext = ToJSContextRef(context);
+  if (!jsContext) {
+    TR_FAIL();
+    return JNI_FALSE;
+  }
+
+  JSStringRef jsString = ToJSStringRef(env, jValue);
+  if (!jsString) {
+    TR_FAIL();
+    return JNI_FALSE;
+  }
+
+  JSValueRef jsValue = JSValueMakeString(jsContext, jsString);
+  JSStringRelease(jsString);
+
+  env->SetIntArrayRegion(rval, 0, 1, reinterpret_cast<const jint*>(&jsValue));
+  if (env->ExceptionCheck()) {
+    TR_FAIL();
+    return JNI_FALSE;
+  }
+
+  JSValueProtectChecked(jsContext, jsValue);
+
+  TR_LEAVE();
+  return JNI_TRUE;
+}
+
+/*
+ *
+ */
+JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_isJsStringImpl
+    (JNIEnv *env, jclass klass, jint context, jint value, jbooleanArray rval) {
+  TR_ENTER();
+  JSContextRef jsContext = ToJSContextRef(context);
+  JSValueRef jsValue = ToJSValueRef(value);
+  if (!jsContext || !jsValue) {
+    TR_FAIL();
+    return JNI_FALSE;
+  }
+
+  bool isString = JSValueIsString(jsContext, jsValue);
+  if (!isString) {
+    JSValueRef jsException = NULL;
+    isString = IsObjectOfStringConstructor(jsContext, jsValue, &jsException);
+    if (jsException) {
+      TR_FAIL();
+      return JNI_FALSE;
+    }
+  }
+
+  jboolean jIsString = static_cast<jboolean>(isString);
+  env->SetBooleanArrayRegion(rval, 0, 1, &jIsString);
+  if (env->ExceptionCheck()) {
+    TR_FAIL();
+    return JNI_FALSE;
+  }
+
+  TR_LEAVE();
+  return JNI_TRUE;
+}
+
+/*
+ *
+ */
+JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_invokeImpl
+    (JNIEnv *env, jclass klass, jint context, jint scriptValue,
+    jstring jMethodName, jint thisVal, jintArray jArgs, jint jArgsLength,
+    jintArray rval) {
+  TR_ENTER();
+
+  JSContextRef jsContext = ToJSContextRef(context);
+  if (!jsContext) {
+    TR_FAIL();
+    return JNI_FALSE;
+  }
+
+  JSObjectRef jsScriptObj = ToJSObjectRef(jsContext, scriptValue, NULL);
+  if (!jsScriptObj) {
+    TR_FAIL();
+    return JNI_FALSE;
+  }
+
+  JSValueRef jsThisVal = ToJSValueRef(thisVal);
+  JSObjectRef jsThisObj = NULL;
+  // If thisVal is null, jsNull, or jsUndefined use the script object
+  // as this.
+  if (!jsThisVal || JSValueIsNull(jsContext, jsThisVal)
+      || JSValueIsUndefined(jsContext, jsThisVal)) {
+    jsThisObj = jsScriptObj;
+  } else {
+    // If we are given a value, ensure that it is an object.
+    jsThisObj = ToJSObjectRef(jsContext, jsThisVal, NULL);
+    if (!jsThisObj) {
+      TR_FAIL();
+      return JNI_FALSE;
+    }
+  }
+
+  JSStringRef jsMethodName = ToJSStringRef(env, jMethodName);
+  if (!jsMethodName) {
+    TR_FAIL();
+    return JNI_FALSE;
+  }
+
+  JSObjectRef jsMethod = ToJSObjectRef(jsContext, JSObjectGetProperty(jsContext,
+      jsScriptObj, jsMethodName, NULL), NULL);
+  if (!jsMethod || !JSObjectIsFunction(jsContext, jsMethod)) {
+    TR_FAIL();
+    return JNI_FALSE;
+  }
+
+  JSStringRelease(jsMethodName);
+
+  // NOTE (knorton): Fix for 64-bit.
+  JSValueRef* jsArgs = new JSValueRef[static_cast<size_t>(jArgsLength)];
+  env->GetIntArrayRegion(jArgs, 0, jArgsLength,
+      reinterpret_cast<jint*>(jsArgs));
+  if (env->ExceptionCheck()) {
+    TR_FAIL();
+    delete[] jsArgs;
+    return JNI_FALSE;
+  }
+
+  JSValueRef jsException = NULL;
+  JSValueRef jsResult = JSObjectCallAsFunction(jsContext, jsMethod, jsThisObj,
+      static_cast<size_t>(jArgsLength), jsArgs, &jsException);
+  if (jsException) {
+    TR_FAIL();
+    delete[] jsArgs;
+    return JNI_FALSE;
+  }
+  delete[] jsArgs;
+
+  env->SetIntArrayRegion(rval, 0, 1, reinterpret_cast<const jint*>(&jsResult));
+  if (env->ExceptionCheck()) {
+    TR_FAIL();
+    return JNI_FALSE;
+  }
+
+  JSValueProtectChecked(jsContext, jsResult);
+
+  TR_LEAVE();
+  return JNI_TRUE;
+}
+
+/*
+ *
+ */
+JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_isJsObject
+    (JNIEnv *env, jclass klass, jint context, jint value) {
+  TR_ENTER();
+  JSContextRef jsContext = ToJSContextRef(context);
+  JSValueRef jsValue = ToJSValueRef(value);
+  if (!jsContext || !jsValue) {
+    TR_FAIL();
+    return JNI_FALSE;
+  }
+
+  TR_LEAVE();
+  return static_cast<jboolean>(JSValueIsObject(jsContext, jsValue));
+}
+
+JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_toBooleanImpl
+    (JNIEnv *env, jclass klass, jint context, jint value, jbooleanArray rval) {
+  TR_ENTER();
+  JSContextRef jsContext = ToJSContextRef(context);
+  JSValueRef jsValue = ToJSValueRef(value);
+  if (!jsContext || !jsValue) {
+    TR_FAIL();
+    return JNI_FALSE;
+  }
+
+  jboolean jResult = static_cast<jboolean>(JSValueToBoolean(jsContext, jsValue));
+  env->SetBooleanArrayRegion(rval, 0, 1, &jResult);
+  if (env->ExceptionCheck()) {
+    TR_FAIL();
+    return JNI_FALSE;
+  }
+
+  TR_LEAVE();
+  return JNI_TRUE;
+}
+
+/*
+ *
+ */
+JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_toDoubleImpl
+    (JNIEnv *env, jclass klass, jint context, jint value, jdoubleArray rval) {
+  TR_ENTER();
+  JSContextRef jsContext = ToJSContextRef(context);
+  JSValueRef jsValue = ToJSValueRef(value);
+  if (!jsContext || !jsValue) {
+    TR_FAIL();
+    return JNI_FALSE;
+  }
+
+  JSValueRef jsException = NULL;
+  double result = JSValueToNumber(jsContext, jsValue, &jsException);
+  if (jsException) {
+    TR_FAIL();
+    return JNI_FALSE;
+  }
+
+  env->SetDoubleArrayRegion(rval, 0, 1, static_cast<jdouble*>(&result));
+  if (env->ExceptionCheck()) {
+    TR_FAIL();
+    return JNI_FALSE;
+  }
+
+  TR_LEAVE();
+  return JNI_TRUE;
+}
+
+/*
+ *
+ */
+JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_toStringImpl
+    (JNIEnv *env, jclass klass, jint context, jint value, jobjectArray rval) {
+  TR_ENTER();
+  JSValueRef jsException = NULL;
+  JSContextRef jsContext = ToJSContextRef(context);
+  JSValueRef jsValue = ToJSValueRef(value);
+  if (!jsContext || !jsValue) {
+    TR_FAIL();
+    return JNI_FALSE;
+  }
+
+  jstring jResult = NULL;
+   // Convert all objects to their string representation, EXCEPT
+   // null and undefined which will be returned as a true NULL.
+  if (!JSValueIsNull(jsContext, jsValue) &&
+      !JSValueIsUndefined(jsContext, jsValue)) {
+    JSStringRef jsResult = JSValueToStringCopy(jsContext, jsValue, &jsException);
+    if (jsException) {
+      TR_FAIL();
+      return JNI_FALSE;
+    }
+
+    jResult = env->NewString(
+        static_cast<const jchar*>(JSStringGetCharactersPtr(jsResult)),
+        static_cast<jsize>(JSStringGetLength(jsResult)));
+    if (env->ExceptionCheck()) {
+      TR_FAIL();
+      return JNI_FALSE;
+    }
+
+    JSStringRelease(jsResult);
+  }
+
+  env->SetObjectArrayElement(rval, 0, jResult);
+  if (env->ExceptionCheck()) {
+    TR_FAIL();
+    return JNI_FALSE;
+  }
+
+  TR_LEAVE();
+  return JNI_TRUE;
+}
+
+/*
+ *
+ */
+JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_wrapDispatchObjectImpl
+    (JNIEnv *env, jclass klass, jint context, jobject dispatch, jintArray rval) {
+  TR_ENTER();
+  JSContextRef jsContext = ToJSContextRef(context);
+  if (!jsContext) {
+    TR_FAIL();
+    return JNI_FALSE;
+  }
+
+  JSObjectRef jsDispatch = gwt::DispatchObjectCreate(jsContext, dispatch);
+  if (!jsDispatch || env->ExceptionCheck()) {
+    TR_FAIL();
+    return JNI_FALSE;
+  }
+
+  env->SetIntArrayRegion(rval, 0, 1, reinterpret_cast<jint*>(&jsDispatch));
+  if (env->ExceptionCheck()) {
+    TR_FAIL();
+    return JNI_FALSE;
+  }
+
+  JSValueProtectChecked(jsContext, jsDispatch);
+
+  TR_LEAVE();
+  return JNI_TRUE;
+}
+
+/*
+ *
+ */
+JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_unwrapDispatchObjectImpl
+    (JNIEnv *env, jclass klass, jint context, jint value, jobjectArray rval) {
+  TR_ENTER();
+  JSContextRef jsContext = ToJSContextRef(context);
+  JSValueRef jsValue = ToJSValueRef(value);
+  if (!jsContext || !jsValue) {
+    TR_FAIL();
+    return JNI_FALSE;
+  }
+
+  if (!JSValueIsObjectOfClass(jsContext, jsValue, gwt::GetDispatchObjectClass())) {
+    TR_FAIL();
+    return JNI_FALSE;
+  }
+
+  JSObjectRef jsObject = ToJSObjectRef(jsContext, jsValue, NULL);
+  if (!jsObject) {
+    TR_FAIL();
+    return JNI_FALSE;
+  }
+
+  env->SetObjectArrayElement(rval, 0, reinterpret_cast<jobject>(JSObjectGetPrivate(jsObject)));
+  if (env->ExceptionCheck()) {
+    TR_FAIL();
+    return JNI_FALSE;
+  }
+
+  TR_LEAVE();
+  return JNI_TRUE;
+}
+
+/*
+ *
+ */
+JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_initImpl
+    (JNIEnv *env, jclass klass, jclass dispatchObjectClass,
+    jclass dispatchMethodClass, jclass lowLevelSafClass) {
+  TR_ENTER();
+  TR_LEAVE();
+  return static_cast<jboolean>(gwt::Initialize(env, dispatchObjectClass, dispatchMethodClass, lowLevelSafClass));
+}
+
+/*
+ *
+ */
+JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_wrapDispatchMethodImpl
+    (JNIEnv *env, jclass klass, jint context, jstring name, jobject jDispatch,
+    jintArray rval) {
+  TR_ENTER();
+  JSContextRef jsContext = ToJSContextRef(context);
+  if (!jsContext) {
+    TR_FAIL();
+    return JNI_FALSE;
+  }
+
+  JStringWrap nameWrap(env, name);
+  std::string nameStr(nameWrap.str());
+  JSObjectRef jsDispatch = gwt::DispatchMethodCreate(jsContext, nameStr,
+      jDispatch);
+  if (!jsDispatch || env->ExceptionCheck()) {
+    TR_FAIL();
+    return JNI_FALSE;
+  }
+
+  env->SetIntArrayRegion(rval, 0, 1, reinterpret_cast<jint*>(&jsDispatch));
+  if (env->ExceptionCheck()) {
+    TR_FAIL();
+    return JNI_FALSE;
+  }
+
+  JSValueProtectChecked(jsContext, jsDispatch);
+
+  TR_LEAVE();
+  return JNI_TRUE;
+}
+
+/*
+ *
+ */
+JNIEXPORT jstring JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_getTypeString
+    (JNIEnv *env, jclass klass, jint context, jint value) {
+  TR_ENTER();
+  JSContextRef jsContext = ToJSContextRef(context);
+  JSValueRef jsValue = ToJSValueRef(value);
+  if (!jsContext || !jsValue) {
+    return NULL;
+  }
+
+  switch (JSValueGetType(jsContext, jsValue)) {
+    case kJSTypeUndefined:
+      return env->NewStringUTF("undefined");
+    case kJSTypeNull:
+      return env->NewStringUTF("null");
+    case kJSTypeBoolean:
+      return env->NewStringUTF("boolean");
+    case kJSTypeNumber:
+      return env->NewStringUTF("number");
+    case kJSTypeString:
+      return env->NewStringUTF("string");
+    case kJSTypeObject:
+      return (JSValueIsObjectOfClass(jsContext, jsValue, gwt::GetDispatchObjectClass()))
+        ? env->NewStringUTF("Java object") : env->NewStringUTF("JavaScript object");
+    default:
+      return env->NewStringUTF("unknown");
+  }
+}
+
+/*
+ *
+ */
+JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_isDispatchObjectImpl
+    (JNIEnv *env, jclass klass, jint context, jint value, jbooleanArray rval) {
+  TR_ENTER();
+  JSContextRef jsContext = ToJSContextRef(context);
+  JSValueRef jsValue = ToJSValueRef(value);
+  if (!jsContext || !jsValue) {
+    TR_FAIL();
+    return JNI_FALSE;
+  }
+
+  jboolean jIsDispatchObject = static_cast<jboolean>(JSValueIsObjectOfClass(
+      jsContext, jsValue, gwt::GetDispatchObjectClass()));
+  env->SetBooleanArrayRegion(rval, 0, 1, &jIsDispatchObject);
+  if (env->ExceptionCheck()) {
+    TR_FAIL();
+    return JNI_FALSE;
+  }
+
+  TR_LEAVE();
+  return JNI_TRUE;
+}
+
+/*
+ *
+ */
+JNIEXPORT jint JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_getArgc
+    (JNIEnv *env, jclass klass) {
+  return *_NSGetArgc();
+}
+
+/*
+ *
+ */
+JNIEXPORT jstring JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_getArgv
+    (JNIEnv *env, jclass klass, jint index) {
+  int argc = *_NSGetArgc();
+  if (index < 0 || index >= argc) {
+    return 0;
+  }
+  char **argv = *_NSGetArgv();
+  return env->NewStringUTF(argv[index]);
+}
+
+/*
+ *
+ */
+JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_getGlobalJsObjectImpl
+    (JNIEnv *env, jclass klass, jint context, jintArray rval) {
+  TR_ENTER();
+
+  JSContextRef jsContext = ToJSContextRef(context);
+  if (!jsContext) {
+    TR_FAIL();
+    return JNI_FALSE;
+  }
+
+  JSObjectRef jsGlobalObject = JSContextGetGlobalObject(jsContext);
+  env->SetIntArrayRegion(rval, 0, 1, reinterpret_cast<jint*>(&jsGlobalObject));
+  if (env->ExceptionCheck()) {
+    TR_FAIL();
+    return JNI_FALSE;
+  }
+
+  JSValueProtectChecked(jsContext, jsGlobalObject);
+
+  TR_LEAVE();
+  return JNI_TRUE;
+}
+
+/*
+ *
+ */
+JNIEXPORT void JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_gcProtect
+    (JNIEnv *env, jclass klass, jint context, jint value) {
+  TR_ENTER();
+
+  JSContextRef jsContext = ToJSContextRef(context);
+  JSValueRef jsValue = ToJSValueRef(value);
+  if (!jsContext || !jsValue) {
+    return;
+  }
+
+  JSValueProtectChecked(jsContext, jsValue);
+  TR_LEAVE();
+}
+
+/*
+ *
+ */
+JNIEXPORT void JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_retainJsGlobalContext
+    (JNIEnv *env, jclass klass, jint context) {
+  TR_ENTER();
+  JSGlobalContextRef jsContext = reinterpret_cast<JSGlobalContextRef>(context);
+  if (!jsContext) {
+    TR_FAIL();
+    return;
+  }
+  JSGlobalContextRetain(jsContext);
+  TR_LEAVE();
+}
+
+/*
+ *
+ */
+JNIEXPORT void JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_releaseJsGlobalContext
+    (JNIEnv *env, jclass klass, jint context) {
+  TR_ENTER();
+  JSGlobalContextRef jsContext = reinterpret_cast<JSGlobalContextRef>(context);
+  if (!jsContext) {
+    TR_FAIL();
+    return;
+  }
+  JSGlobalContextRelease(jsContext);
+  TR_LEAVE();
+}
+
+/*
+ *
+ */
+JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_isGcProtected
+    (JNIEnv *env, jclass klass, jint value) {
+  JSValueRef jsValue = ToJSValueRef(value);
+  TR_ENTER();
+  TR_LEAVE();
+  return static_cast<jboolean>(JSValueIsProtected(jsValue));
+}
+
+JNIEXPORT jboolean JNICALL Java_com_google_gwt_dev_shell_mac_LowLevelSaf_isJsValueProtectionCheckingEnabledImpl
+    (JNIEnv *env, jclass klass) {
+  TR_ENTER();
+  TR_LEAVE();
+  return static_cast<jboolean>(JSValueProtectCheckingIsEnabled());
+}
diff --git a/jni/mac/java-dispatch.cpp b/jni/mac/java-dispatch.cpp
new file mode 100644
index 0000000..fafab11
--- /dev/null
+++ b/jni/mac/java-dispatch.cpp
@@ -0,0 +1,524 @@
+/*
+ * Copyright 2008 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+#include <string>
+#include <sstream>
+#include "jni.h"
+#include "java-dispatch.h"
+#include "trace.h"
+#include "JStringWrap.h"
+
+namespace gwt {
+
+  /*
+   * Declarations for private functions.
+   */
+  JSClassRef DispatchObjectClassCreate();
+
+  JSClassRef DispatchMethodClassCreate();
+
+  JSValueRef DispatchObjectGetProperty(JSContextRef, JSObjectRef, JSStringRef,
+                                       JSValueRef*);
+
+  JSValueRef DispatchObjectToString(JSContextRef, JSObjectRef, JSObjectRef,
+                                    size_t, const JSValueRef*, JSValueRef*);
+
+  bool DispatchObjectSetProperty(JSContextRef, JSObjectRef, JSStringRef,
+                                 JSValueRef, JSValueRef*);
+
+  void DispatchObjectFinalize(JSObjectRef);
+
+  JSValueRef DispatchMethodCallAsFunction(JSContextRef, JSObjectRef,
+                                          JSObjectRef, size_t,
+                                          const JSValueRef*, JSValueRef*);
+
+  JSValueRef DispatchMethodGetToString(JSContextRef, JSObjectRef, JSStringRef,
+                                       JSValueRef*);
+
+  JSValueRef DispatchMethodToString(JSContextRef, JSObjectRef, JSObjectRef,
+                                    size_t, const JSValueRef*, JSValueRef*);
+
+  void DispatchMethodFinalize(JSObjectRef);
+
+  /*
+   * Call this when an underlying Java Object should be freed.
+   */
+  void ReleaseJavaObject(jobject jObject);
+
+
+  /*
+   * The class definition stuct for DispatchObjects.
+   */
+  static JSClassDefinition _dispatchObjectClassDef = { 0,
+      kJSClassAttributeNone, "DispatchObject", 0, 0, 0, 0,
+      DispatchObjectFinalize, 0, DispatchObjectGetProperty,
+      DispatchObjectSetProperty, 0, 0, 0, 0, 0, 0 };
+
+  /*
+   * The class definition structs for DispatchMethods.
+   */
+  static JSStaticValue _dispatchMethodStaticValues[] = {
+    { "toString", DispatchMethodGetToString, 0, kJSPropertyAttributeNone },
+    { 0, 0, 0, 0 }
+  };
+  static JSClassDefinition _dispatchMethodClassDef = { 0,
+      kJSClassAttributeNoAutomaticPrototype, "DispatchMethod", 0,
+      _dispatchMethodStaticValues, 0, 0, DispatchMethodFinalize, 0, 0, 0, 0,
+      0, DispatchMethodCallAsFunction, 0, 0, 0 };
+
+  /*
+   * The classes used to create DispatchObjects and DispatchMethods.
+   */
+  static JSClassRef _dispatchObjectClass = DispatchObjectClassCreate();
+  static JSClassRef _dispatchMethodClass = DispatchMethodClassCreate();
+
+  /*
+   * Java class and method references needed to do delegation.
+   */
+  
+  /*
+   * The main JVM, used by foreign threads to attach.
+   */
+  static JavaVM* _javaVM;
+
+  /*
+   * Only valid for the main thread!  WebKit can finalized on a foreign thread.
+   */
+  static JNIEnv* _javaEnv;
+
+  static jclass _javaDispatchObjectClass;
+  static jclass _javaDispatchMethodClass;
+  static jclass _lowLevelSafClass;
+  static jmethodID _javaDispatchObjectSetFieldMethod;
+  static jmethodID _javaDispatchObjectGetFieldMethod;
+  static jmethodID _javaDispatchMethodInvokeMethod;
+  static jmethodID _javaDispatchObjectToStringMethod;
+  static jmethodID _lowLevelSafReleaseObject;
+
+  /*
+   * Structure to hold DispatchMethod private data.
+   *
+   * NOTE: utf8Name is defensively copied.
+   */
+  class DispatchMethodData {
+   public:
+    DispatchMethodData(jobject jObject, std::string& utf8Name)
+        : _jObject(jObject), _utf8Name(utf8Name) { }
+    ~DispatchMethodData() {
+      ReleaseJavaObject(_jObject);
+    }
+    jobject _jObject;
+    std::string _utf8Name;
+  };
+
+/*
+ * The following takes the prototype from the Function constructor, this allows
+ * us to easily support call and apply on our objects that support CallAsFunction.
+ *
+ * NOTE: The return value is not protected.
+ */
+JSValueRef GetFunctionPrototype(JSContextRef jsContext, JSValueRef* exception) {
+  TR_ENTER();
+  JSObjectRef globalObject = JSContextGetGlobalObject(jsContext);
+  JSStringRef fnPropName= JSStringCreateWithUTF8CString("Function");
+  JSValueRef fnCtorValue = JSObjectGetProperty(jsContext, globalObject,
+      fnPropName, exception);
+  JSStringRelease(fnPropName);
+  if (!fnCtorValue) {
+    return JSValueMakeUndefined(jsContext);
+  }
+
+  JSObjectRef fnCtorObject = JSValueToObject(jsContext, fnCtorValue, exception);
+  if (!fnCtorObject) {
+    return JSValueMakeUndefined(jsContext);
+  }
+
+  JSStringRef protoPropName = JSStringCreateWithUTF8CString("prototype");
+  JSValueRef fnPrototype = JSObjectGetProperty(jsContext, fnCtorObject,
+      protoPropName, exception);
+  JSStringRelease(protoPropName);
+  if (!fnPrototype) {
+    return JSValueMakeUndefined(jsContext);
+  }
+
+  TR_LEAVE();
+  return fnPrototype;
+}
+
+/*
+ *
+ */
+JSClassRef GetDispatchObjectClass() {
+  TR_ENTER();
+  TR_LEAVE();
+  return _dispatchObjectClass;
+}
+
+/*
+ *
+ */
+JSClassRef GetDispatchMethodClass() {
+  TR_ENTER();
+  TR_LEAVE();
+  return _dispatchMethodClass;
+}
+
+/*
+ *
+ */
+JSClassRef DispatchObjectClassCreate() {
+  TR_ENTER();
+  JSClassRef dispClass = JSClassCreate(&_dispatchObjectClassDef);
+  JSClassRetain(dispClass);
+  TR_LEAVE();
+  return dispClass;
+}
+
+/*
+ *
+ */
+JSClassRef DispatchMethodClassCreate() {
+  TR_ENTER();
+  JSClassRef dispClass = JSClassCreate(&_dispatchMethodClassDef);
+  JSClassRetain(dispClass);
+  TR_LEAVE();
+  return dispClass;
+}
+
+/*
+ * NOTE: The object returned from this function is not protected.
+ */
+JSObjectRef DispatchObjectCreate(JSContextRef jsContext, jobject jObject) {
+  TR_ENTER();
+  JSObjectRef dispInst = JSObjectMake(jsContext, _dispatchObjectClass,
+      _javaEnv->NewGlobalRef(jObject));
+  TR_LEAVE();
+  return dispInst;
+}
+
+/*
+ * NOTE: The object returned from this function is not protected.
+ */
+JSObjectRef DispatchMethodCreate(JSContextRef jsContext, std::string& name,
+    jobject jObject) {
+  TR_ENTER();
+ 
+  JSObjectRef dispInst = JSObjectMake(jsContext, _dispatchMethodClass,
+      new DispatchMethodData(_javaEnv->NewGlobalRef(jObject), name));
+
+  // This could only be cached relative to jsContext.
+  JSValueRef fnProtoValue = GetFunctionPrototype(jsContext, NULL);
+  JSObjectSetPrototype(jsContext, dispInst, fnProtoValue);
+  TR_LEAVE();
+  return dispInst;
+}
+
+/*
+ * NOTE: The value returned from this function is not protected, but all
+ * JSValues that are passed into Java are protected before the invocation.
+ */
+JSValueRef DispatchObjectGetProperty(JSContextRef jsContext,
+    JSObjectRef jsObject, JSStringRef jsPropertyName,
+    JSValueRef* jsException) {
+  TR_ENTER();
+
+  // If you call toString on a DispatchObject, you should get the results
+  // of the java object's toString invcation.
+  if (JSStringIsEqualToUTF8CString(jsPropertyName, "toString")) {
+    JSObjectRef jsFunction = JSObjectMakeFunctionWithCallback(jsContext,
+        jsPropertyName, DispatchObjectToString);
+    return jsFunction;
+  }
+
+  // The class check is omitted because it should not be possible to tear off
+  // a getter.
+  jobject jObject = reinterpret_cast<jobject>(JSObjectGetPrivate(jsObject));
+
+  jstring jPropertyName = _javaEnv->NewString(
+      static_cast<const jchar*>(JSStringGetCharactersPtr(jsPropertyName)),
+      static_cast<jsize>(JSStringGetLength(jsPropertyName)));
+  if (!jObject || !jPropertyName || _javaEnv->ExceptionCheck()) {
+    TR_FAIL();
+    _javaEnv->ExceptionClear();
+    return JSValueMakeUndefined(jsContext);
+  }
+
+  JSValueRef jsResult = reinterpret_cast<JSValueRef>(
+      _javaEnv->CallIntMethod(jObject, _javaDispatchObjectGetFieldMethod,
+      reinterpret_cast<jint>(jsContext),
+      jPropertyName));
+  if (!jsResult || _javaEnv->ExceptionCheck()) {
+    TR_FAIL();
+    _javaEnv->ExceptionClear();
+    return JSValueMakeUndefined(jsContext);
+  }
+
+  // Java left us an extra reference to eat.
+  JSValueUnprotectChecked(jsContext, jsResult);
+  TR_LEAVE();
+  return jsResult;
+}
+
+/*
+ *
+ */
+bool DispatchObjectSetProperty(JSContextRef jsContext, JSObjectRef jsObject,
+    JSStringRef jsPropertyName, JSValueRef jsValue, JSValueRef* jsException) {
+  TR_ENTER();
+
+  // The class check is omitted because it should not be possible to tear off
+  // a getter.
+  jobject jObject = reinterpret_cast<jobject>(JSObjectGetPrivate(jsObject));
+
+  jstring jPropertyName = _javaEnv->NewString(
+      static_cast<const jchar*>(JSStringGetCharactersPtr(jsPropertyName)),
+      static_cast<jsize>(JSStringGetLength(jsPropertyName)));
+  if (!jObject || !jPropertyName || _javaEnv->ExceptionCheck()) {
+    _javaEnv->ExceptionClear();
+    return false;
+  }
+
+  JSValueProtectChecked(jsContext, jsValue);
+
+  _javaEnv->CallIntMethod(jObject, _javaDispatchObjectSetFieldMethod,
+      reinterpret_cast<jint>(jsContext), jPropertyName,
+      reinterpret_cast<jint>(jsValue));
+  if (_javaEnv->ExceptionCheck()) {
+    _javaEnv->ExceptionClear();
+    return false;
+  }
+
+  TR_LEAVE();
+  return true;
+}
+
+/*
+ *
+ */
+void DispatchObjectFinalize(JSObjectRef jsObject) {
+  TR_ENTER();
+  jobject jObject = reinterpret_cast<jobject>(JSObjectGetPrivate(jsObject));
+  ReleaseJavaObject(jObject);
+  TR_LEAVE();
+}
+
+/*
+ *
+ */
+void DispatchMethodFinalize(JSObjectRef jsObject) {
+  TR_ENTER();
+  DispatchMethodData* data = reinterpret_cast<DispatchMethodData*>(
+      JSObjectGetPrivate(jsObject));
+  delete data;
+  TR_LEAVE();
+}
+
+/*
+ * NOTE: The value returned from this function is not protected.
+ */
+JSValueRef DispatchObjectToString(JSContextRef jsContext, JSObjectRef,
+    JSObjectRef jsThis, size_t, const JSValueRef*, JSValueRef*) {
+  TR_ENTER();
+
+  // This function cannot be torn off and applied to any JSValue. If this does
+  // not reference a DispatchObject, return undefined.
+  if (!JSValueIsObjectOfClass(jsContext, jsThis, GetDispatchObjectClass())) {
+    return JSValueMakeUndefined(jsContext);
+  }
+
+  jobject jObject = reinterpret_cast<jobject>(JSObjectGetPrivate(jsThis));
+  jstring jResult = reinterpret_cast<jstring>(
+      _javaEnv->CallObjectMethod(jObject, _javaDispatchObjectToStringMethod));
+  if (_javaEnv->ExceptionCheck()) {
+    return JSValueMakeUndefined(jsContext);
+  } else if (!jResult) {
+    return JSValueMakeNull(jsContext);
+  } else {
+    JStringWrap result(_javaEnv, jResult);
+    JSStringRef resultString = JSStringCreateWithCharacters(
+        static_cast<const JSChar*>(result.jstr()),
+        static_cast<size_t>(result.length()));
+    JSValueRef jsResultString = JSValueMakeString(jsContext, resultString);
+    JSStringRelease(resultString);
+    return jsResultString;
+  }
+  TR_LEAVE();
+}
+
+/*
+ *
+ */
+JSValueRef DispatchMethodCallAsFunction(JSContextRef jsContext,
+    JSObjectRef jsFunction, JSObjectRef jsThis, size_t argumentCount,
+    const JSValueRef arguments[], JSValueRef* exception) {
+  TR_ENTER();
+
+  // We don't need to check the class here because we take the private
+  // data from jsFunction and not jsThis.
+
+  DispatchMethodData* data = reinterpret_cast<DispatchMethodData*>(
+      JSObjectGetPrivate(jsFunction));
+  jobject jObject = data->_jObject;
+
+  jintArray jArguments = _javaEnv->NewIntArray(argumentCount);
+  if (!jArguments || _javaEnv->ExceptionCheck()) {
+    return JSValueMakeUndefined(jsContext);
+  }
+
+  // This single element int array will be passed into the java call to allow the
+  // called java method to raise an exception. We will check for a non-null value
+  // after the call is dispatched.
+  jintArray jException = _javaEnv->NewIntArray(1);
+  if (!jException || _javaEnv->ExceptionCheck()) {
+    return JNI_FALSE;
+  }
+
+  for (size_t i = 0; i < argumentCount; ++i) {
+    JSValueRef arg = arguments[i];
+    // Java will take ownership of the arguments.
+    JSValueProtectChecked(jsContext, arg);
+    _javaEnv->SetIntArrayRegion(jArguments, i, 1, reinterpret_cast<jint*>(&arg));
+    if (_javaEnv->ExceptionCheck()) {
+      return JSValueMakeUndefined(jsContext);
+    }
+  }
+
+  // Java will take ownership of this.
+  JSValueProtectChecked(jsContext, jsThis);
+
+  JSValueRef jsResult = reinterpret_cast<JSValueRef>(_javaEnv->CallIntMethod(jObject,
+      _javaDispatchMethodInvokeMethod, reinterpret_cast<jint>(jsContext),
+      reinterpret_cast<jint>(jsThis), jArguments, jException));
+  if (_javaEnv->ExceptionCheck()) {
+    return JSValueMakeUndefined(jsContext);
+  }
+
+  JSValueRef jsException = NULL;
+  _javaEnv->GetIntArrayRegion(jException, 0, 1, reinterpret_cast<jint*>(&jsException));
+  if (!_javaEnv->ExceptionCheck() && jsException) {
+    // If the java dispatch set an exception, then we pass it back to our caller.
+	if (exception) {
+      *exception = jsException;
+	}
+    // Java left us an extra reference to eat.
+    JSValueUnprotectChecked(jsContext, jsException);
+  }
+
+  // Java left us an extra reference to eat.
+  JSValueUnprotectChecked(jsContext, jsResult);
+  TR_LEAVE();
+  return jsResult;
+}
+
+/*
+ * NOTE: The object returned from this function is not protected.
+ */
+JSValueRef DispatchMethodToString(JSContextRef jsContext, JSObjectRef,
+    JSObjectRef thisObject, size_t, const JSValueRef*, JSValueRef*) {
+  TR_ENTER();
+  
+  // This function cannot be torn off and applied to any JSValue. If this does
+  // not reference a DispatchMethod, return undefined.
+  if (!JSValueIsObjectOfClass(jsContext, thisObject, GetDispatchMethodClass())) {
+    return JSValueMakeUndefined(jsContext);
+  }
+
+  std::ostringstream ss;
+  DispatchMethodData* data = reinterpret_cast<DispatchMethodData*>(
+      JSObjectGetPrivate(thisObject));
+  ss << "function " << data->_utf8Name << "() {\n    [native code]\n}\n";
+  JSStringRef stringRep = JSStringCreateWithUTF8CString(ss.str().c_str());
+  JSValueRef jsStringRep = JSValueMakeString(jsContext, stringRep);
+  JSStringRelease(stringRep);
+  TR_LEAVE();
+  return jsStringRep;
+}
+
+/*
+ * NOTE: The object returned from this function is not protected.
+ */
+JSValueRef DispatchMethodGetToString(JSContextRef jsContext,
+    JSObjectRef jsObject, JSStringRef jsPropertyName, JSValueRef* jsException) {
+  TR_ENTER();
+  JSObjectRef toStringFn = JSObjectMakeFunctionWithCallback(jsContext,
+      jsPropertyName, DispatchMethodToString);
+  TR_LEAVE();
+  return toStringFn;
+}
+
+/*
+ *
+ */
+bool Initialize(JNIEnv* javaEnv, jclass javaDispatchObjectClass,
+    jclass javaDispatchMethodClass, jclass lowLevelSafClass) {
+  TR_ENTER();
+  if (!javaEnv || !javaDispatchObjectClass || !javaDispatchMethodClass
+      || !lowLevelSafClass) {
+    return false;
+  }
+
+  _javaVM = 0;
+  javaEnv->GetJavaVM(&_javaVM);
+
+  _javaEnv = javaEnv;
+  _javaDispatchObjectClass = static_cast<jclass>(
+      javaEnv->NewGlobalRef(javaDispatchObjectClass));
+  _javaDispatchMethodClass = static_cast<jclass>(
+      javaEnv->NewGlobalRef(javaDispatchMethodClass));
+  _lowLevelSafClass = static_cast<jclass>(
+      javaEnv->NewGlobalRef(lowLevelSafClass));
+  _javaDispatchObjectSetFieldMethod = javaEnv->GetMethodID(
+      javaDispatchObjectClass, "setField", "(ILjava/lang/String;I)V");
+  _javaDispatchObjectGetFieldMethod = javaEnv->GetMethodID(
+      javaDispatchObjectClass, "getField", "(ILjava/lang/String;)I");
+  _javaDispatchMethodInvokeMethod = javaEnv->GetMethodID(
+      javaDispatchMethodClass, "invoke", "(II[I[I)I");
+  _javaDispatchObjectToStringMethod = javaEnv->GetMethodID(
+      javaDispatchObjectClass, "toString", "()Ljava/lang/String;");
+  _lowLevelSafReleaseObject = javaEnv->GetStaticMethodID(
+      lowLevelSafClass, "releaseObject", "(Ljava/lang/Object;)V");
+
+  if (!_javaVM
+      || !_javaDispatchObjectSetFieldMethod || !_javaDispatchObjectGetFieldMethod
+      || !_javaDispatchMethodInvokeMethod || !_javaDispatchObjectToStringMethod
+      || !_lowLevelSafReleaseObject || javaEnv->ExceptionCheck()) {
+    return false;
+  }
+
+  TR_LEAVE();
+  return true;
+}
+
+void ReleaseJavaObject(jobject jObject) {
+  // Tricky: this call may be on a foreign thread.
+  JNIEnv* javaEnv = 0;
+  if ((_javaVM->AttachCurrentThreadAsDaemon(reinterpret_cast<void**>(&javaEnv),
+      NULL) < 0) || !javaEnv) {
+    TR_FAIL();
+    return;
+  }
+
+  // Tell the Java code we're done with this object.
+  javaEnv->CallStaticVoidMethod(_lowLevelSafClass, _lowLevelSafReleaseObject,
+      jObject);
+  if (javaEnv->ExceptionCheck()) {
+    TR_FAIL();
+    return;
+  }
+  javaEnv->DeleteGlobalRef(jObject);
+}
+
+} // namespace gwt
diff --git a/jni/mac/java-dispatch.h b/jni/mac/java-dispatch.h
new file mode 100644
index 0000000..f8fa80b
--- /dev/null
+++ b/jni/mac/java-dispatch.h
@@ -0,0 +1,65 @@
+/*
+ * 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.
+ */
+
+#ifndef JAVA_DISPATCHER_H__
+#define JAVA_DISPATCHER_H__
+#include <iostream>
+#include <JavaScriptCore/JavaScriptCore.h>
+#include <jni.h>
+
+namespace gwt {
+
+/*
+ * Initializes static members needed by DispatchObject, DispatchMethod,
+ * and LowLevelSaf.  This should be called before before calling anything
+ * else.
+ */
+bool Initialize(JNIEnv*, jclass, jclass, jclass);
+
+/*
+ * Returns a shared reference to the DispatchObject class
+ */
+JSClassRef GetDispatchObjectClass();
+
+/*
+ * Constructs a new DispatchObject.
+ *
+ * jContext - the JavaScript context
+ * jObject - the java instance of DispatchObject to which
+ *   this instance will dispatch calls
+ */
+JSObjectRef DispatchObjectCreate(JSContextRef jContext, jobject jObject);
+
+/*
+ * Returns a shared reference to the DispatchMethod class
+ */
+JSClassRef GetDispatchMethodClass();
+
+/*
+ * Constructs a new DispatchMethod object.
+ *
+ * jsContext - the JavaScript context
+ * name - the name of the method (used in toString)
+ * jObject - the java instance of DispatchMethod to which this object will
+ *   delegate calls.
+ */
+JSObjectRef DispatchMethodCreate(JSContextRef jsContext, std::string& name,
+                                 jobject jObject);
+
+
+} // namespace gwt
+
+#endif // JAVA_DISPATCHER_H__
diff --git a/jni/mac/org.eclipse.swt/webkit.c b/jni/mac/org.eclipse.swt/webkit.c
new file mode 100644
index 0000000..3b704ec
--- /dev/null
+++ b/jni/mac/org.eclipse.swt/webkit.c
@@ -0,0 +1,250 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+// Modified by Google
+#include <Carbon/Carbon.h>
+#include <WebKit/WebKit.h>
+#include <WebKit/HIWebView.h>
+
+#include "jni.h"
+
+JNIEXPORT void JNICALL Java_org_eclipse_swt_browser_WebKit_WebInitForCarbon(JNIEnv *env, jclass zz) {
+	WebInitForCarbon();
+}
+
+JNIEXPORT jint JNICALL Java_org_eclipse_swt_browser_WebKit_HIWebViewCreate(JNIEnv *env, jclass zz, jintArray outView) {
+	jint *a = (*env)->GetIntArrayElements(env, outView, NULL);
+	jint status = (jint) HIWebViewCreate((HIViewRef *)a);
+	(*env)->ReleaseIntArrayElements(env, outView, a, 0);
+	return status;
+}
+
+JNIEXPORT jint JNICALL Java_org_eclipse_swt_browser_WebKit_HIWebViewGetWebView(JNIEnv *env, jclass zz, jint viewRef) {
+	return (jint) HIWebViewGetWebView((HIViewRef)viewRef);
+}
+
+JNIEXPORT jint JNICALL Java_org_eclipse_swt_browser_WebKit_objc_1msgSend__II(JNIEnv *env, jclass zz, jint obj, jint sel) {
+	return (jint) objc_msgSend((void *)obj, (void *)sel);
+}
+
+JNIEXPORT jint JNICALL Java_org_eclipse_swt_browser_WebKit_objc_1msgSend__III(JNIEnv *env, jclass zz, jint obj, jint sel, jint arg0) {
+	return (jint) objc_msgSend((void *)obj, (void *)sel, (void *)arg0);
+}
+
+JNIEXPORT jint JNICALL Java_org_eclipse_swt_browser_WebKit_objc_1msgSend__IIII(JNIEnv *env, jclass zz, jint obj, jint sel, jint arg0, jint arg1) {
+	return (jint) objc_msgSend((void *)obj, (void *)sel, (void *)arg0, (void *)arg1);
+}
+
+JNIEXPORT jint JNICALL Java_org_eclipse_swt_browser_WebKit_objc_1msgSend__IIIII(JNIEnv *env, jclass zz, jint obj, jint sel, jint arg0, jint arg1, jint arg2) {
+	return (jint) objc_msgSend((void *)obj, (void *)sel, (void *)arg0, (void *)arg1, (void *)arg2);
+}
+
+JNIEXPORT jint JNICALL Java_org_eclipse_swt_browser_WebKit_objc_1msgSend__IIIIII(JNIEnv *env, jclass zz, jint obj, jint sel, jint arg0, jint arg1, jint arg2, jint arg3) {
+	return (jint) objc_msgSend((void *)obj, (void *)sel, (void *)arg0, (void *)arg1, (void *)arg2, (void *)arg3);
+}
+
+JNIEXPORT jint JNICALL Java_org_eclipse_swt_browser_WebKit_objc_1getClass(JNIEnv *env, jclass zz, jbyteArray name) {
+	jbyte *a = (*env)->GetByteArrayElements(env, name, NULL);
+	jint id = (jint) objc_getClass((const char *)a);
+	(*env)->ReleaseByteArrayElements(env, name, a, 0);
+	return id;
+}
+
+JNIEXPORT jint JNICALL Java_org_eclipse_swt_browser_WebKit_sel_1registerName(JNIEnv *env, jclass zz, jbyteArray name) {
+	jbyte *a= (*env)->GetByteArrayElements(env, name, NULL);
+	jint sel= (jint) sel_registerName((const char *)a);
+	(*env)->ReleaseByteArrayElements(env, name, a, 0);
+	return sel;
+}
+
+@interface WebKitDelegate : NSObject
+{
+	int user_data;
+	int (*proc) (int sender, int user_data, int selector, int arg0, int arg1, int arg2, int arg3);
+}
+@end
+
+@implementation WebKitDelegate
+
+- (id)initWithProc:(id)prc user_data:(int)data
+{
+    [super init];
+    proc= (void *) prc;
+    user_data = data;
+    return self;
+}
+
+/* WebFrameLoadDelegate */
+
+- (void)webView:(WebView *)sender didFailProvisionalLoadWithError:(NSError *)error forFrame:(WebFrame *)frame
+{
+	proc((int)sender, user_data, 1, (int)error, (int)frame, 0, 0);
+}
+
+- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame
+{
+	proc((int)sender, user_data, 2, (int)frame, 0, 0, 0);
+}
+
+- (void)webView:(WebView *)sender didReceiveTitle:(NSString *)title forFrame:(WebFrame *)frame
+{
+	proc((int)sender, user_data, 3, (int)title, (int)frame, 0, 0);
+}
+
+- (void)webView:(WebView *)sender didStartProvisionalLoadForFrame:(WebFrame *)frame
+{
+	proc((int)sender, user_data, 4, (int)frame, 0, 0, 0);
+}
+
+- (void)webView:(WebView *)sender didCommitLoadForFrame:(WebFrame *)frame
+{
+	proc((int)sender, user_data, 10, (int)frame, 0, 0, 0);
+}
+
+/* WebResourceLoadDelegate */
+
+- (void)webView:(WebView *)sender resource:(id)identifier didFinishLoadingFromDataSource:(WebDataSource *)dataSource
+{
+	proc((int)sender, user_data, 5, (int)identifier, (int)dataSource, 0, 0);
+}
+
+- (void)webView:(WebView *)sender resource:(id)identifier didFailLoadingWithError:(NSError *)error fromDataSource:(WebDataSource *)dataSource
+{
+	proc((int)sender, user_data, 6, (int)identifier, (int)error, (int)dataSource, 0);
+}
+
+- (id)webView:(WebView *)sender identifierForInitialRequest:(NSURLRequest *)request fromDataSource:(WebDataSource *)dataSource
+{
+    return (id) proc((int)sender, user_data, 7, (int)request, (int)dataSource, 0, 0);    
+}
+
+- (NSURLRequest *)webView:(WebView *)sender resource:(id)identifier willSendRequest:(NSURLRequest *)request redirectResponse:(NSURLResponse *)redirectResponse fromDataSource:(WebDataSource *)dataSource
+{
+	return (NSURLRequest *) proc((int)sender, user_data, 8, (int)identifier, (int)request, (int)redirectResponse, (int)dataSource);
+}
+
+/* handleNotification */
+
+- (void)handleNotification:(NSNotification *)notification
+{
+	proc((int)[notification object], user_data, 9, (int)notification, 0, 0, 0);
+}
+
+/* UIDelegate */
+
+- (WebView *)webView:(WebView *)sender createWebViewWithRequest:(NSURLRequest *)request
+{
+	return (WebView *) proc((int)sender, user_data, 11, (int)request, 0, 0, 0);
+}
+
+- (void)webViewShow:(WebView *)sender
+{
+	proc((int)sender, user_data, 12, 0, 0, 0, 0);
+}
+
+- (void)webView:(WebView *)sender setFrame:(NSRect)frame
+{
+	proc((int)sender, user_data, 13, (int)&frame, 0, 0, 0);
+}
+
+- (void)webViewClose:(WebView *)sender
+{
+	proc((int)sender, user_data, 14, 0, 0, 0, 0);
+}
+
+- (NSArray *)webView:(WebView *)sender contextMenuItemsForElement:(NSDictionary *)element defaultMenuItems:(NSArray *)defaultMenuItems
+{
+	return (NSArray *)proc((int)sender, user_data, 15, (int)element, (int)defaultMenuItems, 0, 0);
+}
+
+- (void)webView:(WebView *)sender setStatusBarVisible:(BOOL)visible
+{
+	proc((int)sender, user_data, 16, (int)visible, 0, 0, 0);
+}
+
+- (void)webView:(WebView *)sender setResizable:(BOOL)resizable
+{
+	proc((int)sender, user_data, 17, (int)resizable, 0, 0, 0);
+}
+
+- (void)webView:(WebView *)sender setToolbarsVisible:(BOOL)visible
+{
+	proc((int)sender, user_data, 18, (int)visible, 0, 0, 0);
+}
+
+- (void)webView:(WebView *)sender setStatusText:(NSString *)text
+{
+	proc((int)sender, user_data, 23, (int)text, 0, 0, 0);
+}
+
+- (void)webViewFocus:(WebView *)sender
+{
+	proc((int)sender, user_data, 24, 0, 0, 0, 0);
+}
+
+- (void)webViewUnfocus:(WebView *)sender
+{
+	proc((int)sender, user_data, 25, 0, 0, 0, 0);
+}
+
+- (void)webView:(WebView *)sender runJavaScriptAlertPanelWithMessage:(NSString *)message
+{
+	proc((int)sender, user_data, 26, (int)message, 0, 0, 0);
+}
+
+- (BOOL)webView:(WebView *)sender runJavaScriptConfirmPanelWithMessage:(NSString *)message
+{
+	return (BOOL) proc((int)sender, user_data, 27, (int)message, 0, 0, 0);
+}
+
+- (void)webView:(WebView *)sender runOpenPanelForFileButtonWithResultListener:(id<WebOpenPanelResultListener>)resultListener
+{
+	proc((int)sender, user_data, 28, (int)resultListener, 0, 0, 0);
+}
+
+/* WebPolicyDelegate */
+- (void)webView:(WebView *)sender decidePolicyForMIMEType:(NSString *)type request:(NSURLRequest *)request frame:(WebFrame*)frame decisionListener:(id<WebPolicyDecisionListener>)listener
+{
+	proc((int)sender, user_data, 19, (int)type, (int)request, (int)frame, (int)listener);
+}
+
+- (void)webView:(WebView *)sender decidePolicyForNavigationAction:(NSDictionary *)actionInformation request:(NSURLRequest *)request frame:(WebFrame *)frame decisionListener:(id<WebPolicyDecisionListener>)listener
+{
+	proc((int)sender, user_data, 20, (int)actionInformation, (int)request, (int)frame, (int)listener);
+}
+
+
+- (void)webView:(WebView *)sender decidePolicyForNewWindowAction:(NSDictionary *)actionInformation request:(NSURLRequest *)request newFrameName:(NSString *)frameName decisionListener:(id<WebPolicyDecisionListener>)listener
+{
+	proc((int)sender, user_data, 21, (int)actionInformation, (int)request, (int)frameName, (int)listener);
+}
+
+
+- (void)webView:(WebView *)sender unableToImplementPolicyWithError:(NSError *)error frame:(WebFrame *)frame
+{
+	proc((int)sender, user_data, 22, (int)error, (int)frame, 0, 0);
+}
+
+/* WebDownload */
+
+- (void)download:(NSURLDownload *)download decideDestinationWithSuggestedFilename:(NSString *)filename
+{
+	proc((int)download, user_data, 29, (int)download, (int)filename, 0, 0);
+}
+
+// GOOGLE: we need a notification when the window object is available so we can
+// setup our own hooks before any JavaScript runs.
+- (void)webView:(WebView *)sender windowScriptObjectAvailable:(WebScriptObject *)windowScriptObject
+{
+	proc((int)sender, user_data, 99, (int)windowScriptObject, 0, 0, 0);
+}
+
+@end
+
diff --git a/jni/mac/prebuilt/libgwt-ll.jnilib b/jni/mac/prebuilt/libgwt-ll.jnilib
new file mode 100755
index 0000000..5a4030f
--- /dev/null
+++ b/jni/mac/prebuilt/libgwt-ll.jnilib
Binary files differ
diff --git a/jni/mac/trace.cpp b/jni/mac/trace.cpp
new file mode 100644
index 0000000..2127351
--- /dev/null
+++ b/jni/mac/trace.cpp
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2008 Google Inc.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * 
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+
+#include <iostream>
+#include <map>
+#include <JavaScriptCore/JavaScriptCore.h>
+#include "trace.h"
+
+#ifdef ENABLE_JSVALUE_PROTECTION_CHECKING
+static std::map<JSValueRef, int> _protectMap;
+#endif
+
+/*
+ *
+ */
+void JSValueProtectChecked(JSContextRef jsContext, JSValueRef jsValue) {
+  JSValueProtect(jsContext, jsValue);
+#ifdef ENABLE_JSVALUE_PROTECTION_CHECKING
+  _protectMap[jsValue]++;
+#endif
+}
+
+/*
+ *
+ */
+void JSValueUnprotectChecked(JSContextRef jsContext, JSValueRef jsValue) {
+#ifdef ENABLE_JSVALUE_PROTECTION_CHECKING
+  // Unrecord in a hash_map
+  unsigned count = _protectMap[jsValue];
+  if (count == 0) {
+    std::cerr << "[WARNING] JSValueUnprotect called on unprotected JSValueRef (0x"
+        << std::hex << ((unsigned)jsValue) << ")" << std::endl;
+    return;
+  }
+  _protectMap[jsValue] = count - 1;
+#else
+  JSValueUnprotect(jsContext, jsValue);
+#endif
+}
+
+bool JSValueIsProtected(JSValueRef jsValue) {
+#ifdef ENABLE_JSVALUE_PROTECTION_CHECKING
+  return _protectMap[jsValue] > 0;
+#else
+  return true;
+#endif
+}
+
+bool JSValueProtectCheckingIsEnabled() {
+#ifdef ENABLE_JSVALUE_PROTECTION_CHECKING
+  return true;
+#else
+  return false;
+#endif
+}
diff --git a/jni/mac/trace.h b/jni/mac/trace.h
new file mode 100644
index 0000000..e58ca96
--- /dev/null
+++ b/jni/mac/trace.h
@@ -0,0 +1,45 @@
+/*
+ * 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.
+ */
+
+#ifndef TRACE_H__
+#define TRACE_H__
+#include <iostream>
+#include <map>
+
+// Uncomment to trace enter, exit and fail for all native calls.
+// #define ENABLE_CALL_TRACE
+
+// Uncomment to double check that JSValueRef's are protected and
+// unprotected properly.
+// #define ENABLE_JSVALUE_PROTECTION_CHECKING
+
+#ifdef ENABLE_CALL_TRACE
+#define TR_ENTER() std::cout << "ENTER " << __PRETTY_FUNCTION__ << std::endl
+#define TR_LEAVE() std::cout << "LEAVE " << __PRETTY_FUNCTION__ << std::endl
+#define TR_FAIL() std::cout << "FAIL " << __FILE__ << "@" << __LINE__ \
+    << std::endl;
+#else
+#define TR_ENTER()
+#define TR_LEAVE()
+#define TR_FAIL()
+#endif // ENABLE_CALL_TRACE
+
+void JSValueUnprotectChecked(JSContextRef, JSValueRef);
+void JSValueProtectChecked(JSContextRef, JSValueRef);
+bool JSValueIsProtected(JSValueRef jsValue);
+bool JSValueProtectCheckingIsEnabled();
+
+#endif // TRACE_H__
diff --git a/jni/windows/IE6.cpp b/jni/windows/IE6.cpp
new file mode 100644
index 0000000..58330a1
--- /dev/null
+++ b/jni/windows/IE6.cpp
@@ -0,0 +1,220 @@
+/*
+ * Copyright 2006 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.
+ */
+
+// A very slim and portable set of JNI methods for GWT.
+
+#include <jni.h>
+#include <windows.h>
+#include "wininet.h"
+
+// A home-brewed vector class to eliminate dependence on STL.
+// Reuse at your own peril, it hasn't been tested to do anything
+// more than we're actually using it for here.
+struct char_vector {
+    char_vector(long initSize=0): sz(0), cap(0), buf(0) {
+        resize(initSize);
+    }
+    
+    ~char_vector() {
+        clear();
+    }
+
+    char& operator[](long i) {
+        return buf[i];
+    }
+
+    void append(const char* start, const char* end) {
+        long len = end - start;
+        long cursize = sz;
+        resize(sz + len);
+        memcpy(&buf[cursize], start, len);
+    }
+
+    void clear() {
+        if (buf)
+            free(buf);
+        buf = 0;
+        sz = cap = 0;
+    }
+
+    void reserve(long newcap) {
+        if (newcap <= cap)
+            return;
+        char* newbuf = (char*)malloc(newcap);
+        if (!newbuf)
+            return;
+        if (buf) {
+            memcpy(newbuf, buf, sz);
+            free(buf);
+        }
+        buf = newbuf;
+        cap = newcap;
+    }
+
+    void resize(long newsize) {
+        reserve(newsize);
+        sz = newsize;
+    }
+
+    long size() {
+        return sz;
+    }
+
+private:
+    long sz;
+    long cap;
+    char* buf;
+};
+
+// Does an HTTP GET on the specified URL using the WinInet subsystem, which respects proxy settings.
+// Returns a status code such that 
+//      0  Success
+//    < 0  Failure at some step (see the code below)
+//    > 0  Windows system error code
+//
+int fetch(const char* userAgent, const char* url, char_vector& response) {
+    int status = -1;
+    HINTERNET h1 = InternetOpenA(userAgent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0);
+    if (h1 != NULL) {
+        status = -2;
+        DWORD flags = INTERNET_FLAG_PRAGMA_NOCACHE | INTERNET_FLAG_RELOAD | INTERNET_FLAG_NO_COOKIES | INTERNET_FLAG_NO_UI;
+        HINTERNET h2 = InternetOpenUrlA(h1, url, "", -1L, flags, 0);
+        if (h2 != NULL) {
+            status = -3;
+            const int MAX_BUFFER = 1024 * 1024; // don't grow past this ever
+            bool notDone = true;
+            response.clear();
+            response.reserve(4096);
+            char_vector chunk(4096); // initial buffer size
+            while (notDone && chunk.size() < MAX_BUFFER) {
+                DWORD toRead = (DWORD)chunk.size();
+                DWORD didRead;
+                while (true) {
+                    if (InternetReadFile(h2, (LPVOID)&chunk[0], toRead, &didRead)) {
+                        if (didRead != 0) {
+                            // Copy to response.
+                            //
+                            response.append(&chunk[0], &chunk[0] + didRead);
+
+                            // Keep going.
+                            //
+                        } else {
+                            // EOF.
+                            //
+                            status = 0;
+                            notDone = false;
+                            break;
+                        }
+                    } else {
+                        // Oops -- why?
+                        //
+                        DWORD err = GetLastError();
+                        if (err == ERROR_INSUFFICIENT_BUFFER) {
+                            // Grow the buffer and retry.
+                            //
+                            chunk.resize(toRead * 2);
+                            break;
+                        } else {
+                            // Give up.
+                            //
+                            status = err;
+                            notDone = false;
+                            break;
+                        }
+                    }
+                }
+            }
+            InternetCloseHandle(h2);
+        }
+        InternetCloseHandle(h1);
+    }
+    return status;
+}
+
+extern "C" {
+
+class UTFChars {
+public:
+    UTFChars(JNIEnv* env, jstring str): m_env(env), m_str(str) {
+        m_ptr = env->GetStringUTFChars(str, NULL);
+    }
+
+    ~UTFChars() {
+        if (m_ptr) {
+            m_env->ReleaseStringUTFChars(m_str, m_ptr);
+        }
+    }
+
+    operator const char*() const {
+        return m_ptr;
+    }
+
+    JNIEnv* m_env;
+    jstring m_str;
+    const char* m_ptr;
+};
+
+/*
+ * Class:     com_google_gwt_dev_shell_ie_LowLevelIE6
+ * Method:    _httpGet
+ * Signature: (Ljava/lang/String;Ljava/lang/String;[[B)I
+ */
+JNIEXPORT jint JNICALL Java_com_google_gwt_dev_shell_ie_LowLevelIE6__1httpGet(JNIEnv* env, jclass, jstring userAgent, jstring url, jobjectArray out) {
+    UTFChars userAgentChars(env, userAgent);
+    if (!userAgentChars || env->ExceptionCheck()) {
+		return -100;
+	}
+
+    UTFChars urlChars(env, url);
+    if (!urlChars || env->ExceptionCheck()) {
+		return -101;
+	}
+
+    // Do the fetch.
+    //
+    char_vector response;
+    int status = fetch(userAgentChars, urlChars, response);
+
+    if (status != 0) {
+        // Failure.
+        //
+        return status;
+    }
+
+    // Copy the response.
+    //
+    jbyteArray byteArray = env->NewByteArray(response.size());
+    if (!byteArray || env->ExceptionCheck()) {
+		return -102;
+	}
+
+    jbyte* bytes = env->GetByteArrayElements(byteArray, NULL);
+    if (!bytes || env->ExceptionCheck()) {
+		return -103;
+    }
+
+    memcpy(bytes, &response[0], response.size());
+
+    env->ReleaseByteArrayElements(byteArray, bytes, 0);
+
+    // May throw immediately after return if out array is bad.
+    //
+    env->SetObjectArrayElement(out, 0, byteArray);  
+
+	return 0;
+}
+
+} // extern "C"
diff --git a/jni/windows/Makefile b/jni/windows/Makefile
new file mode 100644
index 0000000..14da521
--- /dev/null
+++ b/jni/windows/Makefile
@@ -0,0 +1,113 @@
+# Copyright 2006 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.
+
+##
+# Target settings
+##
+GWT_ROOT = ../../
+OBJDIR  := $(GWT_ROOT)build/out/jni/win32/
+OUTDIR  := $(GWT_ROOT)build/jni/win32/
+OUT     := $(OUTDIR)gwt-ll.dll
+STAGING := $(GWT_ROOT)build/staging/gwt-windows-0.0.0/
+
+##
+# Tools
+##
+CXX      := mingw-gcc
+AR       := mingw-ar
+STRIP    := mingw-strip
+LD       := $(CXX)
+
+##
+# List of source, object, and dependency paths plus the path to them
+##
+SRCDIRS := ./:../core/
+VPATH   := .:../core
+SRCS    := gwt-ll.cpp IE6.cpp
+OBJS    := $(addprefix $(OBJDIR),$(SRCS:.cpp=.o))
+DEPS    := $(addprefix $(OBJDIR),$(SRCS:.cpp=.d))
+
+##
+# Include path configuration
+##
+SYSINCS := \
+    $(JAVA_HOME)/include \
+    $(JAVA_HOME)/include/win32
+INCS := $(addprefix -isystem ,$(SYSINCS))
+
+##
+# Libraries and library path
+##
+LIBS    := wininet
+LIBPATH := -L$(OBJDIR)
+LIBS    := $(addprefix -l,$(LIBS))
+
+# for notes on auto-dependency generation, see
+#   http://make.paulandlesley.org/autodep.html
+# -MP obviates the need for sed hackery
+CFLAGS   := -Os -fno-exceptions -fshort-wchar -c -MMD -MP -Wno-system-headers $(CFLAGS)
+LDFLAGS  := -s -Wl,--kill-at $(LDFLAGS)
+
+#-------------------------------------------------------------------------------
+# Rules
+#-------------------------------------------------------------------------------
+
+##
+# default rule
+##
+all: $(OUT)
+
+# install into prebuilt directory
+install: $(OUT)
+	cp $(OUT) prebuilt/
+
+##
+# Include the dependency rules
+##
+-include $(DEPS)
+
+##
+# Compilation rule for cpp files
+##
+$(OBJDIR)%.o : $(SRCDIR)%.cpp
+	@[ -d $(OBJDIR) ] || mkdir -p $(OBJDIR)
+	$(CXX) $(CFLAGS) $(INCS) -o $@ $<
+
+##
+# Compilation rule for .def files to lib*.a files
+##
+$(OBJDIR)lib%.a : $(SRCDIR)%.def
+	@[ -d $(OBJDIR) ] || mkdir -p $(OBJDIR)
+	mingw-dlltool -k -d $< -l $@
+	
+##
+# Actual output file
+##
+$(OUT): $(OBJS) $(OBJDIR)libwininet.a
+	@[ -d $(OUTDIR) ] || mkdir -p $(OUTDIR)
+	$(LD) -shared $(LDFLAGS) $(LIBPATH) -o $@ $^ $(LIBS)
+	$(STRIP) --strip-unneeded $@
+
+##
+# copy to staging area for hosted-mode development
+##
+staging: $(OUT)
+	@[ -d $(STAGING) ] || mkdir -p $(STAGING)
+	cp $(OUT) $(STAGING)
+
+##
+# Clean rule
+##
+clean:
+	@-rm -rf $(OBJDIR) $(OUT)
diff --git a/jni/windows/build.xml b/jni/windows/build.xml
new file mode 100755
index 0000000..f5951cf
--- /dev/null
+++ b/jni/windows/build.xml
@@ -0,0 +1,18 @@
+<project name="jni-windows" default="build" basedir=".">
+  <property name="gwt.root" location="../.." />
+  <property name="project.tail" value="jni/windows" />
+  <import file="${gwt.root}/common.ant.xml" />
+
+  <target name="build" description="Builds a JNI lib">
+    <mkdir dir="${project.jni}" />
+    <!-- TODO: Actually build this from source! -->
+    <copy todir="${project.jni}">
+      <fileset dir="prebuilt" />
+    </copy>
+  </target>
+
+  <target name="clean" description="Cleans this project's intermediate and output files">
+    <delete dir="${project.build}" failonerror="false" />
+    <delete dir="${project.jni}" failonerror="false" />
+  </target>
+</project>
diff --git a/jni/windows/gwt-ll.vcproj b/jni/windows/gwt-ll.vcproj
new file mode 100644
index 0000000..18fee56
--- /dev/null
+++ b/jni/windows/gwt-ll.vcproj
@@ -0,0 +1,136 @@
+<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+	ProjectType="Visual C++"
+	Version="7.10"
+	Name="gwt-ll"
+	ProjectGUID="{AA853538-40A6-4413-A5B1-74031CB4E887}"
+	RootNamespace="gwt-ll"
+	Keyword="Win32Proj">
+	<Platforms>
+		<Platform
+			Name="Win32"/>
+	</Platforms>
+	<Configurations>
+		<Configuration
+			Name="Debug|Win32"
+			OutputDirectory="Debug"
+			IntermediateDirectory="Debug"
+			ConfigurationType="2"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				Optimization="0"
+				AdditionalIncludeDirectories="&quot;$(ProjectDir)..\..\..\..\..\third_party\j2sdk1.4.2_09\include&quot;;&quot;$(ProjectDir)..\..\..\..\..\third_party\j2sdk1.4.2_09\include\win32&quot;"
+				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL"
+				MinimalRebuild="TRUE"
+				ExceptionHandling="FALSE"
+				BasicRuntimeChecks="3"
+				RuntimeLibrary="1"
+				ForceConformanceInForLoopScope="TRUE"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="FALSE"
+				DebugInformationFormat="3"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="wininet.lib"
+				OutputFile="$(OutDir)\$(ProjectName).dll"
+				LinkIncremental="1"
+				GenerateDebugInformation="TRUE"
+				ProgramDatabaseFile="$(OutDir)/$(ProjectName).pdb"
+				SubSystem="2"
+				ImportLibrary="$(OutDir)/$(ProjectName).lib"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+		<Configuration
+			Name="Release|Win32"
+			OutputDirectory="Release"
+			IntermediateDirectory="Release"
+			ConfigurationType="2"
+			CharacterSet="2">
+			<Tool
+				Name="VCCLCompilerTool"
+				AdditionalIncludeDirectories="&quot;$(ProjectDir)..\..\..\..\..\third_party\j2sdk1.4.2_09\include&quot;;&quot;$(ProjectDir)..\..\..\..\..\third_party\j2sdk1.4.2_09\include\win32&quot;"
+				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL"
+				ExceptionHandling="FALSE"
+				RuntimeLibrary="0"
+				ForceConformanceInForLoopScope="TRUE"
+				UsePrecompiledHeader="0"
+				WarningLevel="3"
+				Detect64BitPortabilityProblems="FALSE"
+				DebugInformationFormat="3"/>
+			<Tool
+				Name="VCCustomBuildTool"/>
+			<Tool
+				Name="VCLinkerTool"
+				AdditionalDependencies="wininet.lib"
+				OutputFile="$(OutDir)\$(ProjectName).dll"
+				LinkIncremental="1"
+				GenerateDebugInformation="TRUE"
+				SubSystem="2"
+				OptimizeReferences="2"
+				EnableCOMDATFolding="2"
+				ImportLibrary="$(OutDir)/$(ProjectName).lib"
+				TargetMachine="1"/>
+			<Tool
+				Name="VCMIDLTool"/>
+			<Tool
+				Name="VCPostBuildEventTool"/>
+			<Tool
+				Name="VCPreBuildEventTool"/>
+			<Tool
+				Name="VCPreLinkEventTool"/>
+			<Tool
+				Name="VCResourceCompilerTool"/>
+			<Tool
+				Name="VCWebServiceProxyGeneratorTool"/>
+			<Tool
+				Name="VCXMLDataGeneratorTool"/>
+			<Tool
+				Name="VCWebDeploymentTool"/>
+			<Tool
+				Name="VCManagedWrapperGeneratorTool"/>
+			<Tool
+				Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
+		</Configuration>
+	</Configurations>
+	<References>
+	</References>
+	<Files>
+		<Filter
+			Name="Source Files"
+			Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
+			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}">
+			<File
+				RelativePath="..\..\..\..\gwt-ll-core\src\main\cpp\gwt-ll.cpp">
+			</File>
+			<File
+				RelativePath=".\IE6.cpp">
+			</File>
+		</Filter>
+	</Files>
+	<Globals>
+	</Globals>
+</VisualStudioProject>
diff --git a/jni/windows/prebuilt/gwt-ll.dll b/jni/windows/prebuilt/gwt-ll.dll
new file mode 100755
index 0000000..49a0a1f
--- /dev/null
+++ b/jni/windows/prebuilt/gwt-ll.dll
Binary files differ
diff --git a/jni/windows/wininet.def b/jni/windows/wininet.def
new file mode 100644
index 0000000..83d6751
--- /dev/null
+++ b/jni/windows/wininet.def
@@ -0,0 +1,6 @@
+LIBRARY wininet.dll
+EXPORTS
+InternetOpenA@20        @264
+InternetOpenUrlA@24     @265
+InternetReadFile@16     @272
+InternetCloseHandle@4   @223
diff --git a/jni/windows/wininet.h b/jni/windows/wininet.h
new file mode 100644
index 0000000..935c615
--- /dev/null
+++ b/jni/windows/wininet.h
@@ -0,0 +1,20 @@
+#ifndef __wininet_h__
+#define __wininet_h__
+
+extern "C"  {
+
+#define INTERNET_OPEN_TYPE_PRECONFIG    0
+#define INTERNET_FLAG_PRAGMA_NOCACHE    0x00000100
+#define INTERNET_FLAG_RELOAD            0x80000000
+#define INTERNET_FLAG_NO_COOKIES        0x00080000
+#define INTERNET_FLAG_NO_UI             0x00000200
+
+typedef void* HINTERNET;
+HINTERNET STDAPICALLTYPE InternetOpenA(LPCSTR lpszAgent, DWORD dwAccessType, LPCSTR lpszProxy, LPCSTR lpszProxyBypass, DWORD dwFlags);
+HINTERNET STDAPICALLTYPE InternetOpenUrlA(HINTERNET hInternet, LPCSTR lpszUrl, LPCSTR lpszHeaders, DWORD dwHeadersLength, DWORD dwFlags, DWORD_PTR dwContext);
+BOOL STDAPICALLTYPE InternetReadFile(HINTERNET hFile, void* lpBuffer, DWORD dwNumberOfBytesToRead, LPDWORD lpdwNumberOfBytesRead);
+BOOL STDAPICALLTYPE InternetCloseHandle(HINTERNET hInternet);
+
+}
+
+#endif // __wininet_h__
