/*
 * 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::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;

  /*
   * 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();

  JSValueRef toReturn;
  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;

  // 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) {
  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;
}
