Add back IE proxy handling for CheckForUpdates.
Also remove branch-info.txt inadvertently committed to trunk.

Patch by: scottb
Review by: jat


git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@6390 8db76d5a-ed1c-0410-87a9-c151d255dfc7
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());
+}