/*
 * 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.
 */

#import "WebScriptSessionHandler.h"
#import "InvokeMessage.h"
#import "ObjectFunctions.h"
#import "ServerMethods.h"
#import "TrackingData.h"
#import "scoped_ptr.h"


WebScriptSessionHandler::WebScriptSessionHandler(HostChannel* channel,
                                                 JSGlobalContextRef contextRef,
                                                 CrashHandlerRef crashHandler) :
SessionData(channel, contextRef, this), jsObjectId(1), crashHandler(crashHandler) {

  JSClassDefinition def = kJSClassDefinitionEmpty;
  def.className = "JavaObject";
  def.hasProperty = JavaObjectHasProperty;
  def.callAsFunction = JavaObjectCallAsFunction;
  def.finalize = JavaObjectFinalize;
  def.getProperty = JavaObjectGetProperty;
  def.setProperty = JavaObjectSetProperty;
  javaObjectWrapperClass = JSClassCreate(&def);
  JSClassRetain(javaObjectWrapperClass);

  // Get the String constructor function to tell Strings from other Objects
  JSStringRef stringString = JSStringCreateWithUTF8CString("String");
  JSValueRef stringConstructorValue = JSObjectGetProperty(contextRef,
                                                          JSContextGetGlobalObject(contextRef),
                                                          stringString, NULL);
  stringConstructor = JSValueToObject(contextRef, stringConstructorValue, NULL);
  JSValueProtect(contextRef, stringConstructor);
  JSStringRelease(stringString);

  // Call out to the utility __gwt_makeResult function to create the return array
  JSStringRef makeResultString = JSStringCreateWithUTF8CString("__gwt_makeResult");
  JSValueRef makeResultValue = JSObjectGetProperty(contextRef, JSContextGetGlobalObject(contextRef), makeResultString, NULL);
  JSStringRelease(makeResultString);

  if (!JSValueIsObject(contextRef, makeResultValue)) {
    crashHandler->crash(__PRETTY_FUNCTION__, "Could not find __gwt_makeResult");
  } else {
    makeResultFunction = JSValueToObject(contextRef, makeResultValue, NULL);
    JSValueProtect(contextRef, makeResultFunction);
  }

  pthread_mutexattr_t mutexAttrs;
  pthread_mutexattr_init(&mutexAttrs);
  // This behaves basically like the Java synchronized keyword
  pthread_mutexattr_settype(&mutexAttrs, PTHREAD_MUTEX_RECURSIVE);
  pthread_mutex_init(&javaObjectsLock, &mutexAttrs);
  pthread_mutexattr_destroy(&mutexAttrs);
}

WebScriptSessionHandler::~WebScriptSessionHandler() {
  std::map<int, JSObjectRef>::iterator i;

  pthread_mutex_lock(&javaObjectsLock);
  while ((i = javaObjectsById.begin()) != javaObjectsById.end()) {
    JavaObjectFinalize(i->second);
  }
  pthread_mutex_unlock(&javaObjectsLock);

  for (i = jsObjectsById.begin(); i != jsObjectsById.end(); i++) {
    JSObjectRef ref = i->second;
    delete static_cast<TrackingDataRef>(JSObjectGetPrivate(ref));
    JSObjectSetPrivate(ref, NULL);
    JSValueUnprotect(contextRef, i->second);
  }

  JSClassRelease(javaObjectWrapperClass);

  JSValueUnprotect(contextRef, stringConstructor);
  JSValueUnprotect(contextRef, makeResultFunction);

  JSGarbageCollect(contextRef);
  pthread_mutex_destroy(&javaObjectsLock);
}

void WebScriptSessionHandler::disconnectDetectedImpl() {
  crashHandler->crash(__PRETTY_FUNCTION__, "Server disconnect detected");
}

void WebScriptSessionHandler::fatalError(HostChannel& channel,
    const std::string& message) {
  // TODO: better way of reporting error?
  Debug::log(Debug::Error) << "Fatal error: " << message << Debug::flush;
}

void WebScriptSessionHandler::sendFreeValues(HostChannel& channel) {
  pthread_mutex_lock(&javaObjectsLock);
  int idCount = javaObjectsToFree.size();
  if (idCount == 0) {
    pthread_mutex_unlock(&javaObjectsLock);
    return;
  }

  int ids[idCount];
  std::set<int>::iterator it = javaObjectsToFree.begin();
  for (int i = 0; i < idCount; it++) {
    ids[i++] = *it;
  }
  if (!ServerMethods::freeJava(channel, this, idCount, ids)) {
    Debug::log(Debug::Error) << "Unable to free Java ids" << Debug::flush;
  } else {
    Debug::log(Debug::Debugging) << "Freed " << idCount << " Java ids" << Debug::flush;
  }
  javaObjectsToFree.clear();
  pthread_mutex_unlock(&javaObjectsLock);
}

void WebScriptSessionHandler::freeValue(HostChannel& channel, int idCount, const int* ids) {
  Debug::log(Debug::Spam) << "freeValue freeing " << idCount << " js objects" << Debug::flush;
  if (idCount == 0) {
    return;
  }

  for (int i = 0; i < idCount; i++) {
    int objId = ids[i];

    std::map<int, JSObjectRef>::iterator i = jsObjectsById.find(objId);
    if (i == jsObjectsById.end()) {
      Debug::log(Debug::Error) << "Unknown object id " << objId << Debug::flush;
      continue;
    }

    JSObjectRef ref = i->second;
    jsObjectsById.erase(objId);
    jsIdsByObject.erase(ref);
    JSValueUnprotect(contextRef, ref);
  }
  Debug::log(Debug::Debugging) << "Freed " << idCount << " JS objects" << Debug::flush;
}

void WebScriptSessionHandler::initiateAutodestructSequence(const char* functionName, const char* message) {
  crashHandler->crash(functionName, message);
}

bool WebScriptSessionHandler::invoke(HostChannel& channel, const Value& thisObj,
                                    const std::string& methodName,
                                    int numArgs, const Value* args, Value* returnValue) {
  Debug::log(Debug::Spam) << "invoke " << methodName << Debug::flush;

  JSValueRef argsJS[numArgs];
  JSValueRef localException = NULL;
  JSStringRef methodNameJS = JSStringCreateWithUTF8CString(methodName.c_str());
  JSObjectRef thisObjJs;

  if (thisObj.isNull()) {
    thisObjJs = JSContextGetGlobalObject(contextRef);
  } else {
    thisObjJs = (JSObjectRef) makeValueRef(thisObj);
  }

  JSValueRef functionValueJS = JSObjectGetProperty(contextRef, JSContextGetGlobalObject(contextRef),
                                                   methodNameJS, &localException);
  JSStringRelease(methodNameJS);

  if (!JSValueIsObject(contextRef, functionValueJS)) {
    char message[512];
    snprintf(message, sizeof(message), "Could not find method for property name %s on %s", methodName.c_str(), thisObj.toString().c_str());
    makeExceptionValue(*returnValue, message);
    return true;
  }

  JSObjectRef functionJS = JSValueToObject(contextRef, functionValueJS,
                                           &localException);
  if (localException) {
    makeValue(*returnValue, localException);
    return true;
  }

  // Convert the arguments
  for (int i = 0; i < numArgs; i++) {
    argsJS[i] = makeValueRef(args[i]);
  }

  JSValueRef retVal = JSObjectCallAsFunction(contextRef, functionJS,
                                             thisObjJs, numArgs, argsJS,
                                             &localException);

  if (localException) {
    Debug::log(Debug::Spam) << "Returning exception to server" << Debug::flush;
    makeValue(*returnValue, localException);
    return true;
  } else {
    makeValue(*returnValue, retVal);
    return false;
  }
}

bool WebScriptSessionHandler::invokeSpecial(HostChannel& channel, SpecialMethodId method, int numArgs,
                                            const Value* const args, Value* returnValue) {
  Debug::log(Debug::Spam) << "invokeSpecial " << method << Debug::flush;
  switch (method) {
    case GetProperty:
    {
      int objId = args[0].getInt();
      std::map<int, JSObjectRef>::iterator i = jsObjectsById.find(objId);
      if (i == jsObjectsById.end()) {
        char message[50];
        snprintf(message, sizeof(message), "Unknown object id %i", objId);
        makeExceptionValue(*returnValue, message);
        return true;
      }

      JSObjectRef jsObj = i->second;
      if (args[1].isString()) {
        JSStringRef asString = JSValueToStringCopy(contextRef, jsObj, NULL);
        int maxLength = JSStringGetMaximumUTF8CStringSize(asString);
        scoped_array<char> asChars(new char[maxLength]);
        JSStringGetUTF8CString(asString, asChars.get(), maxLength);

        JSValueRef localException = NULL;
        JSStringRef str = JSStringCreateWithUTF8CString(args[1].getString().c_str());
        JSValueRef value = JSObjectGetProperty(contextRef, jsObj, str, &localException);
        JSStringRelease(str);
        if (localException) {
          makeValue(*returnValue, localException);
          return true;
        } else {
          makeValue(*returnValue, value);
          return false;
        }
      } else if (args[1].isInt()) {
        JSValueRef localException = NULL;
        JSValueRef value = JSObjectGetPropertyAtIndex(contextRef, jsObj, args[1].getInt(), &localException);

        if (localException) {
          makeValue(*returnValue, localException);
          return true;
        } else {
          makeValue(*returnValue, value);
          return false;
        }
      } else {
        char message[50];
        snprintf(message, sizeof(message), "Unhandled argument type %s for getProperty", args[1].toString().c_str());
        makeExceptionValue(*returnValue, message);
        return true;
      }
    }
    default:
      Debug::log(Debug::Error) << "Unhandled invokeSpecial " << method << Debug::flush;
      makeExceptionValue(*returnValue, "Unhandled invokeSpecial");
      return true;
  }
}

JSValueRef WebScriptSessionHandler::javaFunctionCallbackImpl (int dispatchId,
                                                              JSObjectRef thisObject,
                                                              size_t argumentCount,
                                                              const JSValueRef arguments[],
                                                              JSValueRef* exception){
  /*
   * NB: Because throwing exceptions in JavaScriptCore is trivial, we don't rely
   * on any special return values to indicate that an exception is thrown, we'll simply
   * throw the exception.
   */
  Debug::log(Debug::Debugging) << "Java method " << dispatchId << " invoked" << Debug::flush;

  JSValueRef toReturn;
  if (crashHandler->hasCrashed()) {
    Debug::log(Debug::Debugging) << "Not executing method since we have crashed" << Debug::flush;
    toReturn =  JSValueMakeUndefined(contextRef);
  } else {
    /*
     * If a JS function is evaluated without an meaningful this object or the global
     * object is implicitly used as the this object, we'll assume that the
     * Java-derived method is static, and send a null this object to the server
     */
    Value thisValue;
    if (JSValueIsEqual(contextRef, thisObject, JSContextGetGlobalObject(contextRef), NULL)) {
      thisValue = Value();
      thisValue.setNull();
    } else {
      makeValue(thisValue, thisObject);
    }

    // Argument conversion is straightforward
    Value args[argumentCount];
    for (int i = 0; i < argumentCount; i++) {
      makeValue(args[i], arguments[i]);
    }

    if (!InvokeMessage::send(*channel, thisValue, dispatchId,
                             argumentCount, args)) {
      initiateAutodestructSequence(__PRETTY_FUNCTION__, "Unable to send invocation message");
      *exception = makeException("Unable to send invocation message");
      return JSValueMakeUndefined(contextRef);
    }

    scoped_ptr<ReturnMessage> ret(channel->reactToMessagesWhileWaitingForReturn(sessionHandler));

    if (!ret.get()) {
      initiateAutodestructSequence(__PRETTY_FUNCTION__, "Unable to receive return message");
      *exception = makeException("Unable to receive return message");
      return JSValueMakeUndefined(contextRef);
    }

    Value v = ret->getReturnValue();

    if (ret->isException()) {
      *exception = makeValueRef(v);
      toReturn = JSValueMakeUndefined(contextRef);
    } else {
      toReturn = makeValueRef(v);
    }
  }

  JSValueRef makeResultArguments[] = {JSValueMakeBoolean(contextRef, false), toReturn};
  return JSObjectCallAsFunction(contextRef, makeResultFunction, NULL, 2, makeResultArguments, exception);
}

void WebScriptSessionHandler::javaObjectFinalizeImpl(int objId) {
  if (pthread_mutex_lock(&javaObjectsLock)) {
    Debug::log(Debug::Error) << "Unable to acquire javaObjectsLock in thread " << pthread_self() << " " << __PRETTY_FUNCTION__ << Debug::flush;
    initiateAutodestructSequence(__PRETTY_FUNCTION__, "Unable to acquire javaObjectsLock");
    return;
  }
  javaObjectsById.erase(objId);
  javaObjectsToFree.insert(objId);
  if (pthread_mutex_unlock(&javaObjectsLock)) {
    Debug::log(Debug::Error) << "Unable to release javaObjectsLock in thread " << pthread_self() << " " << __PRETTY_FUNCTION__ << Debug::flush;
    initiateAutodestructSequence(__PRETTY_FUNCTION__, "Unable to release javaObjectsLock");
  }
}

JSValueRef WebScriptSessionHandler::javaObjectGetPropertyImpl (TrackingDataRef tracker, JSObjectRef object,
                                                               JSStringRef propertyName, JSValueRef* exception) {
  *exception = NULL;
  
  if (crashHandler->hasCrashed()) {
    Debug::log(Debug::Debugging) << "Not executing since we have crashed" << Debug::flush;
    return JSValueMakeUndefined(contextRef);
  }

  // Convert the name
  int maxLength = JSStringGetMaximumUTF8CStringSize(propertyName);
  scoped_array<char> propertyNameChars(new char[maxLength]);
  JSStringGetUTF8CString(propertyName, propertyNameChars.get(), maxLength);
  JSValueRef toReturn;

  if (!strcmp(propertyNameChars.get(), "toString")) {
    // We'll call out to the JSNI tear-off support function
    JSStringRef tearOffName =JSStringCreateWithUTF8CString("__gwt_makeTearOff");
    JSValueRef makeTearOffValue = JSObjectGetProperty(contextRef, JSContextGetGlobalObject(contextRef), tearOffName, exception);
    JSStringRelease(tearOffName);
    if (*exception) {
      return JSValueMakeUndefined(contextRef);
    }

    JSObjectRef makeTearOff = JSValueToObject(contextRef, makeTearOffValue, exception);
    if (*exception) {
      return JSValueMakeUndefined(contextRef);
    }

    JSValueRef arguments[3];
    arguments[0] = object;
    arguments[1] = JSValueMakeNumber(contextRef, 0);
    arguments[2] = JSValueMakeNumber(contextRef, 0);
    toReturn = JSObjectCallAsFunction(contextRef, makeTearOff, JSContextGetGlobalObject(contextRef), 3, arguments, exception);
  } else {
    char* endptr;
    int dispatchId = strtol(propertyNameChars.get(), &endptr, 10);

    if (*endptr != '\0') {
      Debug::log(Debug::Error) << "Unable to parse dispatch id " << propertyNameChars.get() << Debug::flush;
      *exception = makeException("Unable to parse dispatch id");
    } else if (dispatchId < 0) {
      Debug::log(Debug::Error) << "Dispatch ids may not be negative" << Debug::flush;
      *exception = makeException("Dispatch ids may not be negative");
    } else {
      Value v = ServerMethods::getProperty(*channel, this, tracker->getObjectId(), dispatchId);
      toReturn = makeValueRef(v);
    }
  }

  return toReturn;
}

bool WebScriptSessionHandler::javaObjectHasPropertyImpl (TrackingDataRef tracker, JSObjectRef object, JSStringRef propertyName) {
  // The property name must either be "toString" or a number
  int maxLength = JSStringGetMaximumUTF8CStringSize(propertyName);
  scoped_array<char> propertyNameChars(new char[maxLength]);
  JSStringGetUTF8CString(propertyName, propertyNameChars.get(), maxLength);
  if (!strcmp(propertyNameChars.get(), "toString")) {
    return true;
  }

  char* endptr;
  int dispatchId = strtol(propertyNameChars.get(), &endptr, 10);

  if (*endptr != '\0') {
    return false;
  } else if (dispatchId < 0) {
    return false;
  } else {
    return true;
  }
}

bool WebScriptSessionHandler::javaObjectSetPropertyImpl (TrackingDataRef tracker, JSObjectRef object,
                                                         JSStringRef propertyName, JSValueRef jsValue,
                                                         JSValueRef* exception) {

  if (crashHandler->hasCrashed()) {
    Debug::log(Debug::Debugging) << "Not executing since we have crashed" << Debug::flush;
    return true;
  }

  int maxLength = JSStringGetMaximumUTF8CStringSize(propertyName);
  scoped_array<char> propertyNameChars(new char[maxLength]);
  JSStringGetUTF8CString(propertyName, propertyNameChars.get(), maxLength);
  Value value;

  char* endptr;
  int dispatchId = strtol(propertyNameChars.get(), &endptr, 10);

  if (*endptr != '\0') {
    // TODO Figure out the right policy here; when we throw a Java object, JSCore wants to
    // add expandos to record stack information.  It would be possible to map the limited
    // number of properties into a synthetic causal exception in the exception being thrown.
  } else if (dispatchId < 0) {
    // Do nothing.
    Debug::log(Debug::Error) << "Dispatch ids may not be negative" << Debug::flush;
    *exception = makeException("Dispatch ids may not be negative");
  } else {

    makeValue(value, jsValue);

    if (!ServerMethods::setProperty(*channel, this, tracker->getObjectId(), dispatchId, value)) {
      char message[50];
      snprintf(message, sizeof(message), "Unable to set value object %i dispatchId %i", tracker->getObjectId(), dispatchId);
      *exception = makeException(message);
    }
  }

  // true means to not try to follow the prototype chain; not an indication of success
  return true;
}

void WebScriptSessionHandler::loadJsni(HostChannel& channel, const std::string& js) {
  Debug::log(Debug::Spam) << "loadJsni " << js << Debug::flush;
  JSValueRef localException = NULL;

  JSStringRef script = JSStringCreateWithUTF8CString(js.c_str());
  JSEvaluateScript(contextRef, script, NULL, NULL, NULL, &localException);
  JSStringRelease(script);

  if (localException) {
    // TODO Exception handling
    Debug::log(Debug::Error) << "Exception thrown during loadJsni" << Debug::flush;
  } else {
    Debug::log(Debug::Spam) << "Success" << Debug::flush;
  }
}

JSValueRef WebScriptSessionHandler::makeException(const char* message) {
  JSValueRef localException = NULL;
  JSObjectRef global = JSContextGetGlobalObject(contextRef);

  JSStringRef errorName = JSStringCreateWithUTF8CString("Error");
  JSValueRef errorValue = JSObjectGetProperty(contextRef, global, errorName, &localException);
  JSStringRelease(errorName);

  if (!JSValueIsObject(contextRef, errorValue)) {
    initiateAutodestructSequence(__PRETTY_FUNCTION__, "Could not get reference to Error");
    return JSValueMakeUndefined(contextRef);
  }

  JSObjectRef errorObject = (JSObjectRef) errorValue;

  if (!JSObjectIsFunction(contextRef, errorObject)) {
    initiateAutodestructSequence(__PRETTY_FUNCTION__, "Error was not a function");
    return JSValueMakeUndefined(contextRef);
  }

  JSValueRef args[1];
  JSStringRef messageJs = JSStringCreateWithUTF8CString(message);
  args[0] = JSValueMakeString(contextRef, messageJs);
  JSStringRelease(messageJs);

  return JSObjectCallAsConstructor(contextRef, errorObject, 1, args, &localException);
}

void WebScriptSessionHandler::makeExceptionValue(Value& value, const char* message) {
  makeValue(value, makeException(message));
}

JSObjectRef WebScriptSessionHandler::makeJavaWrapper(int objId) {
  Debug::log(Debug::Spam) << "Creating wrapper for Java object " << objId << Debug::flush;

  TrackingDataRef data = new TrackingData(this, objId);
  return JSObjectMake(contextRef, javaObjectWrapperClass,
                      const_cast<TrackingData*>(data));
}

JSValueRef WebScriptSessionHandler::makeValueRef(const Value& v) {
  std::map<int, JSObjectRef>::iterator i;
  switch (v.getType()) {
    case Value::NULL_TYPE:
      return JSValueMakeNull(contextRef);

    case Value::BOOLEAN:
      return JSValueMakeBoolean(contextRef, v.getBoolean());

    case Value::BYTE:
      return JSValueMakeNumber(contextRef, v.getByte());

    case Value::CHAR:
      return JSValueMakeNumber(contextRef, v.getChar());

    case Value::SHORT:
      return JSValueMakeNumber(contextRef, v.getShort());

    case Value::INT:
      return JSValueMakeNumber(contextRef, v.getInt());

    case Value::LONG:
      return JSValueMakeNumber(contextRef, v.getLong());

    case Value::FLOAT:
      return JSValueMakeNumber(contextRef, v.getFloat());

    case Value::DOUBLE:
      return JSValueMakeNumber(contextRef, v.getDouble());

    case Value::STRING:
    {
      std::string stringValue = v.getString();

      // We need to handle the conversion ourselves to be able to get both
      // UTF8 encoding as well as explicit control over the length of the string
      // due to the possibility of null characters being part of the data
      CFStringRef cfString = CFStringCreateWithBytesNoCopy(NULL, (UInt8*)stringValue.data(),
                                                           stringValue.length(), kCFStringEncodingUTF8,
                                                           false, kCFAllocatorNull);
      JSStringRef stringRef = JSStringCreateWithCFString(cfString);
      JSValueRef toReturn = JSValueMakeString(contextRef, stringRef);
      JSStringRelease(stringRef);
      CFRelease(cfString);
      return toReturn;
    }

    case Value::JAVA_OBJECT:
      unsigned javaId = v.getJavaObjectId();
      JSObjectRef ref;

      pthread_mutex_lock(&javaObjectsLock);
      i = javaObjectsById.find(javaId);

      /*
       * It's possible that we've already finalized the JsObjectRef that
       * represented the object with the given id.  If so, we must remove it
       * from the list of finalized object ids to avoid prematurely freeing
       * the object on the server.
       */
      javaObjectsToFree.erase(javaId);

      if (i == javaObjectsById.end()) {
        /*
         * We don't call JSValueProtect so that the JavaObject peer can be
         * garbage-collected during the lifetime of the program.  Object
         * identity is maintained as long as the object hasn't been finalized.
         * If it had been finalized, then there wouldn't be an object to use
         * as a basis for identity comparison.
         *
         * NB: The act of creating the wrapper may trigger a GC.
         */
        ref = makeJavaWrapper(javaId);

        javaObjectsById[javaId] = ref;

      } else {
        ref = i->second;
      }
      pthread_mutex_unlock(&javaObjectsLock);


      return ref;

      case Value::JS_OBJECT:
      int jsId = v.getJsObjectId();

      i = jsObjectsById.find(jsId);
      if (i == jsObjectsById.end()) {
        char errMsg[50];
        snprintf(errMsg, sizeof(errMsg), "Missing JsObject with id %i", jsId);
        return makeException(errMsg);

      } else {
        return i->second;
      }

      case Value::UNDEFINED:
      return JSValueMakeUndefined(contextRef);

      default:
      char message[50];
      snprintf(message, sizeof(message), "Could not convert %s", v.toString().c_str());
      initiateAutodestructSequence(__PRETTY_FUNCTION__, message);
      return makeException(message);
  }
}

bool WebScriptSessionHandler::makeValue(Value& ret, JSValueRef v) {
  JSValueRef localException = NULL;

  if (JSValueIsNull(contextRef, v)) {
    ret.setNull();

  } else if (JSValueIsUndefined(contextRef, v)) {
    ret.setUndefined();

  } else if (JSValueIsBoolean(contextRef, v)) {
    ret.setBoolean(JSValueToBoolean(contextRef, v));

  } else if (JSValueIsNumber(contextRef, v)) {
    double d = JSValueToNumber(contextRef, v, &localException);
    int i = round(d);
    if (i == d) {
      ret.setInt(i);
    } else {
      ret.setDouble(d);
    }

  } else if (JSValueIsString(contextRef, v) ||
             JSValueIsInstanceOfConstructor(contextRef, v, stringConstructor, &localException)) {
    return makeValueFromString(ret, v);

  } else if (JSValueIsObjectOfClass(contextRef, v, javaObjectWrapperClass)) {
    // It's one of our Java object proxies
    JSObjectRef objectRef = JSValueToObject(contextRef, v, &localException);

    if (!localException) {
      TrackingDataRef tracker = (TrackingDataRef) JSObjectGetPrivate(objectRef);
      int objId = tracker->getObjectId();
      ret.setJavaObject(objId);
      Debug::log(Debug::Spam) << "Made a Java object Value " << objId << Debug::flush;
    }

  } else if (JSValueIsObject(contextRef, v)) {
    JSObjectRef objectRef = JSValueToObject(contextRef, v, &localException);
    if (!localException) {
      /*
       * Then this is just a plain-old JavaScript Object.  Because JSCore
       * doesn't retain private data for objects derived from the built-in
       * Object type, we'll simply revert to using a pair of maps to provide
       * a 1:1 mapping of JSObjectRefs and ints.
       */
      std::map<JSObjectRef, int>::iterator i = jsIdsByObject.find(objectRef);
      if (i != jsIdsByObject.end()) {
        // We've seen the object before
        ret.setJsObjectId(i->second);
      } else {
        // Allocate a new id
        int objId = ++jsObjectId;
        JSValueProtect(contextRef, objectRef);

        jsObjectsById[objId] = objectRef;
        jsIdsByObject[objectRef] = objId;

        ret.setJsObjectId(objId);
        Debug::log(Debug::Spam) << "Made JS Value " << objId << Debug::flush;
      }
    }
  } else {
    Debug::log(Debug::Error) << "Unhandled JSValueRef -> Value conversion in plugin" << Debug::flush;
    ret.setString("Unhandled JSValueRef -> Value conversion in plugin");
  }

  if (localException) {
    makeValue(ret, localException);
    return true;
  } else {
    return false;
  }
}

bool WebScriptSessionHandler::makeValueFromString(Value& ret, JSValueRef value) {
  JSValueRef localException = NULL;

  JSStringRef jsString = JSValueToStringCopy(contextRef, value, &localException);
  if (localException) {
    makeValue(ret, localException);
    return true;
  }

  CFStringRef cfString = JSStringCopyCFString(NULL, jsString);
  JSStringRelease(jsString);

  CFIndex cfLength = CFStringGetLength(cfString);
  CFIndex maxLength = CFStringGetMaximumSizeForEncoding(cfLength, kCFStringEncodingUTF8);
  scoped_array<char> utf8(new char[maxLength]);

  CFIndex numBytes;
  CFStringGetBytes(cfString, CFRangeMake(0, cfLength), kCFStringEncodingUTF8,
                   0, false, (UInt8*) utf8.get(), maxLength, &numBytes);
  CFRelease(cfString);

  ret.setString(utf8.get(), numBytes);
  Debug::log(Debug::Spam) << "Made a string Value " << ret.getString() << Debug::flush;
  return false;
}
