changeset 2005:518cf0feb646

- Support for Chromium and Firefox 3.6 A1 - Added object construction support - Port over cookie/cert cn mismatch/etc. fixes from current plugin
author Deepak Bhole <dbhole@redhat.com>
date Wed, 26 Aug 2009 15:06:47 -0400
parents 52eee2ca6d37
children 5edc8307c7ab
files ChangeLog plugin/icedteanp/IcedTeaJavaRequestProcessor.cc plugin/icedteanp/IcedTeaJavaRequestProcessor.h plugin/icedteanp/IcedTeaNPPlugin.cc plugin/icedteanp/IcedTeaNPPlugin.h plugin/icedteanp/IcedTeaPluginRequestProcessor.cc plugin/icedteanp/IcedTeaPluginRequestProcessor.h plugin/icedteanp/IcedTeaPluginUtils.cc plugin/icedteanp/IcedTeaPluginUtils.h plugin/icedteanp/IcedTeaScriptablePluginObject.cc plugin/icedteanp/IcedTeaScriptablePluginObject.h plugin/icedteanp/java/sun/applet/MethodOverloadResolver.java plugin/icedteanp/java/sun/applet/PluginAppletSecurityContext.java plugin/icedteanp/java/sun/applet/PluginAppletViewer.java plugin/icedteanp/java/sun/applet/PluginCookieInfoRequest.java plugin/icedteanp/java/sun/applet/PluginCookieManager.java plugin/icedteanp/java/sun/applet/PluginCookieStore.java plugin/icedteanp/java/sun/applet/PluginMain.java
diffstat 18 files changed, 834 insertions(+), 350 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Wed Aug 26 01:14:21 2009 -0400
+++ b/ChangeLog	Wed Aug 26 15:06:47 2009 -0400
@@ -1,3 +1,84 @@
+2009-08-26  Deepak Bhole <dbhole@redhat.com>
+
+	* plugin/icedteanp/IcedTeaJavaRequestProcessor.cc
+	(createJavaObjectFromVariant): Add conditional compilation blocks to
+	handle new API along with old. Call renamed newObjectWithConstructor
+	function.
+	(newObject): New function. Creates an object based on the most optimum
+	cost with arbitrary arguments.
+	(newObjectWithConstructor): Renamed from newObject(). Also, take source as
+	an argument to provide to Java.
+	* plugin/icedteanp/IcedTeaJavaRequestProcessor.h: Change as per above .cc
+	file changes.
+	* plugin/icedteanp/IcedTeaNPPlugin.cc: Include XPCOM specific headers only
+	if xulrunner version is < 1.9.2. Instantiate internal Mozilla objects only
+	if xulrunner < 1.9.2.
+	(GCJ_New): Correctly account for documentbase length when allocating tag
+	memory to prevent corruption.
+	(GCJ_Destroy): Remove old instance mappings when destroyed.
+	(GCJ_GetJavaClass): Remove unused method.
+	(get_cookie_info): Change object signature to include length result. Based
+	on xulrunner version, either use internal Mozilla API for fetching cookie
+	info, or use NPN_GetValueForURL.
+	(plugin_get_documentbase): Define for when xulrunner is >= 1.9.2.
+	(consume_message): Deal with single proxy URL rather than components.
+	Update to handle when xulrunner is >= 1.9.2
+	(get_proxy_info): Change signature to deal with single url rather than
+	components. Use NPN_GetValueForURL if xulrunner is >= 1.9.2.
+	(NP_Initialize): Add pointers for getvalueforurl and setvalueforurl in the
+	NPPluginFuncs table. Also, handle case for when browser provides the
+	plugin .so name as the link location rather than target location.
+	* plugin/icedteanp/IcedTeaNPPlugin.h: Include XPCOM specific headers only
+	if xulrunner version is < 1.9.2.
+	* plugin/icedteanp/IcedTeaPluginRequestProcessor.cc
+	(eval): Use the new NPN_PluginThreadAsynCcall function to dispatch events
+	to main thread asynchronously.
+	(call): Same.
+	(setMember): Same.
+	(getMember): Same.
+	(storeVariantInJava): Handle changed API when xulrunner >= 1.9.2
+	(_setMember): Account for changes in the way that the callerpacks
+	arguments.
+	(_getMember): Same.
+	(_call): Same.
+	(_eval): Same.
+	* plugin/icedteanp/IcedTeaPluginRequestProcessor.h: Include Mozilla
+	specific headers only if xulrunner is < 1.9.2. Remove old ThreadData
+	struct and add new AyncCallThreadData struct that contains results and
+	arguments.
+	* plugin/icedteanp/IcedTeaPluginUtils.cc
+	(getSourceFromInstance): Provide null source location due to lack of a
+	secure way to get documentbase.
+	(printNPVariant): Account for change API in xulrunner 1.9.2.
+	(NPVariantToString): Same.
+	* plugin/icedteanp/IcedTeaPluginUtils.h: Include Mozilla specific headers 
+	only if xulrunner is < 1.9.2.
+	* plugin/icedteanp/IcedTeaScriptablePluginObject.cc
+	(invoke): Pass exception over to JS engine.
+	(construct): Implement object construction.
+	* plugin/icedteanp/IcedTeaScriptablePluginObject.h: Include Mozilla
+	specific headers only if xulrunner is < 1.9.2.
+	* plugin/icedteanp/java/sun/applet/MethodOverloadResolver.java
+	(getMatchingConstructor): New method, returns a matching constructor based
+	on arguments.
+	(getMatchingConstructors): New helper method for getMatchingConstructor.
+	* plugin/icedteanp/java/sun/applet/PluginAppletSecurityContext.java
+	(handleMessage): Handle new type of call, "NewObjectWithConstructor".
+	(checkPermission): Disable checks for the time being, as NPRuntime does
+	not allow cross-site calling anyway.
+	* plugin/icedteanp/java/sun/applet/PluginAppletViewer.java
+	(setStatus): Remove newlines from status messages.
+	* plugin/icedteanp/sun/applet/PluginCookieInfoRequest.java
+	(parseReturn): Store cookie info as a string rather than a list of
+	HttpCookie objects.
+	(getObject): Return the new cookie string.
+	* plugin/icedteanp/sun/applet/PluginCookieManager.java: New file, extends
+	CookieManager as is set as the default cookie manager for the plugin.
+	* plugin/icedteanp/sun/applet/PluginCookieStore.java : Deleted. New design
+	uses a custom cookiemanager rather than just a custom store.
+	* plugin/icedteanp/sun/applet/PluginMain.java
+	(init): Wire in the new cookie manager.
+
 2009-08-26  Deepak Bhole <dbhole@redhat.com>
 
 	* plugin/icedtea/sun/applet/PluginAppletViewer.java
--- a/plugin/icedteanp/IcedTeaJavaRequestProcessor.cc	Wed Aug 26 01:14:21 2009 -0400
+++ b/plugin/icedteanp/IcedTeaJavaRequestProcessor.cc	Wed Aug 26 15:06:47 2009 -0400
@@ -122,7 +122,6 @@
 			{
 			    result_ready = true; // nothing else to do
 			} else if ((message_parts->at(4) == "CallMethod") ||
-
 					   (message_parts->at(4) == "CallStaticMethod"))
 			{
 
@@ -656,8 +655,11 @@
     else if (NPVARIANT_IS_STRING(variant))
     {
     	className = "java.lang.String";
-
+#if MOZILLA_VERSION_COLLAPSED < 1090200
     	stringArg += NPVARIANT_TO_STRING(variant).utf8characters;
+#else
+    	stringArg += NPVARIANT_TO_STRING(variant).UTF8Characters;
+#endif
     } else {
     	alreadyCreated = true;
     }
@@ -703,7 +705,7 @@
 		std::string arg = std::string();
 		arg.append(*(java_result->return_string));
 		args.push_back(arg);
-		java_result = java_request.newObject("[System]", jsObjectClassID, jsObjectConstructorID, args);
+		java_result = java_request.newObjectWithConstructor("[System]", jsObjectClassID, jsObjectConstructorID, args);
 
         if (java_result->error_occurred) {
             printf("Unable to create requested object\n");
@@ -808,7 +810,46 @@
 }
 
 JavaResultData*
-JavaRequestProcessor::newObject(std::string source, std::string objectID,
+JavaRequestProcessor::newObject(std::string source, std::string classID,
+                                const NPVariant* args, int argCount)
+{
+    JavaRequestProcessor* java_request;
+    std::string message = std::string();
+
+    this->instance = 0; // context is always 0 (needed for java-side backwards compat.)
+    this->reference = IcedTeaPluginUtilities::getReference();
+
+    IcedTeaPluginUtilities::constructMessagePrefix(0, reference, source, &message);
+    message += " NewObject ";
+    message += classID;
+    message += " ";
+
+    // First, we need to load the arguments into the java-side table
+    for (int i=0; i < argCount; i++) {
+        int objectID = createJavaObjectFromVariant(args[i]);
+        if (objectID == 0)
+        {
+            result->error_occurred = true;
+            result->error_msg->append("Unable to create arguments");
+            return result;
+        }
+
+        char* id = (char*) malloc(sizeof(char)*32);
+        sprintf(id, "%d", objectID);
+        message += id;
+        message += " ";
+        free(id);
+    }
+
+    postAndWaitForResponse(message);
+
+    IcedTeaPluginUtilities::releaseReference();
+
+    return result;
+}
+
+JavaResultData*
+JavaRequestProcessor::newObjectWithConstructor(std::string source, std::string classID,
                                 std::string methodID,
                                 std::vector<std::string> args)
 {
@@ -819,8 +860,8 @@
 	this->reference = IcedTeaPluginUtilities::getReference();
 
 	IcedTeaPluginUtilities::constructMessagePrefix(0, reference, source, &message);
-	message += " NewObject ";
-	message += objectID;
+	message += " NewObjectWithConstructor ";
+	message += classID;
 	message += " ";
 	message += methodID;
 	message += " ";
@@ -980,3 +1021,4 @@
 
     return result;
 }
+
--- a/plugin/icedteanp/IcedTeaJavaRequestProcessor.h	Wed Aug 26 01:14:21 2009 -0400
+++ b/plugin/icedteanp/IcedTeaJavaRequestProcessor.h	Wed Aug 26 15:06:47 2009 -0400
@@ -171,9 +171,14 @@
         /* Returns the class of the given object */
         JavaResultData* getObjectClass(std::string objectID);
 
-    	/* Creates a new object */
+    	/* Creates a new object with choosable constructor */
     	JavaResultData* newObject(std::string source,
-                                  std::string objectID, std::string methodID,
+                                  std::string classID,
+                                  const NPVariant* args, int numArgs);
+
+    	/* Creates a new object when constructor is undetermined */
+    	JavaResultData* newObjectWithConstructor(std::string source, std::string classID,
+                                  std::string methodID,
                                   std::vector<std::string> args);
 
     	/* Returns the class ID */
--- a/plugin/icedteanp/IcedTeaNPPlugin.cc	Wed Aug 26 01:14:21 2009 -0400
+++ b/plugin/icedteanp/IcedTeaNPPlugin.cc	Wed Aug 26 15:06:47 2009 -0400
@@ -47,12 +47,15 @@
 #include <sys/types.h>
 #include <unistd.h>
 
+#if MOZILLA_VERSION_COLLAPSED < 1090200
 // Documentbase retrieval includes.
 #include <nsIPluginInstance.h>
 #include <nsIPluginInstancePeer.h>
 #include <nsIPluginTagInfo2.h>
+#endif
 
 // API's into Mozilla
+#if MOZILLA_VERSION_COLLAPSED < 1090200
 #include <nsCOMPtr.h>
 #include <nsICookieService.h>
 #include <nsIDNSRecord.h>
@@ -66,9 +69,10 @@
 #include <nsNetCID.h>
 #include <nsStringAPI.h>
 #include <nsServiceManagerUtils.h>
+#endif
 
 // Liveconnect extension
- #include "IcedTeaScriptablePluginObject.h"
+#include "IcedTeaScriptablePluginObject.h"
 #include "IcedTeaNPPlugin.h"
 
 // Error reporting macros.
@@ -132,8 +136,10 @@
 #define FAILURE_MESSAGE "gcjwebplugin error: Failed to run %s." \
   "  For more detail rerun \"firefox -g\" in a terminal window."
 
+#if MOZILLA_VERSION_COLLAPSED < 1090200
 // Documentbase retrieval required definition.
 static NS_DEFINE_IID (kIPluginTagInfo2IID, NS_IPLUGINTAGINFO2_IID);
+#endif
 
 // Data directory for plugin.
 static gchar* data_directory = NULL;
@@ -180,14 +186,14 @@
 // Sends messages to Java over the bus
 JavaMessageSender* java_req_proc;
 
-GQuark ITNP_PLUGIN_ERROR = g_quark_from_string("IcedTeaNPPlugin");
-
+#if MOZILLA_VERSION_COLLAPSED < 1090200
 // Documentbase retrieval type-punning union.
 typedef union
 {
   void** void_field;
   nsIPluginTagInfo2** info_field;
 } info_union;
+#endif
 
 // Static instance helper functions.
 // Have the browser allocate a new GCJPluginData structure.
@@ -211,8 +217,8 @@
 // Uninitialize GCJPluginData structure
 static void plugin_data_destroy (NPP instance);
 
-NS_IMETHODIMP get_cookie_info(const char* siteAddr, char** cookieString);
-void get_proxy_info(const char* siteAddr, char** proxy_scheme, char** proxy_host, char** proxy_port, GError *error);
+NPError get_cookie_info(const char* siteAddr, char** cookieString, uint32_t* len);
+NPError get_proxy_info(const char* siteAddr, char** proxy, uint32_t* len);
 void decode_url(const gchar* url, gchar** decoded_url);
 void consume_message(gchar* message);
 void start_jvm_if_needed();
@@ -336,7 +342,7 @@
       // Send applet tag message to appletviewer.
       applet_tag = plugin_create_applet_tag (argc, argn, argv);
 
-      tag_message = (gchar*) malloc(strlen(applet_tag)*sizeof(gchar) + 1024);
+      tag_message = (gchar*) malloc(strlen(applet_tag)*sizeof(gchar) + strlen(documentbase)*sizeof(gchar) + 32);
       g_sprintf(tag_message, "instance %d tag %s %s", instance_counter, documentbase, applet_tag);
 
       //plugin_send_message_to_appletviewer (data, data->instance_string);
@@ -636,6 +642,11 @@
       plugin_data_destroy (instance);
     }
 
+  int id = get_id_from_instance(instance);
+
+  g_hash_table_remove(instance_to_id_map, instance);
+  g_hash_table_remove(id_to_instance_map, GINT_TO_POINTER(id));
+
   PLUGIN_DEBUG_0ARG ("GCJ_Destroy return\n");
 
   return NPERR_NO_ERROR;
@@ -844,31 +855,22 @@
   PLUGIN_DEBUG_0ARG ("GCJ_URLNotify return\n");
 }
 
-jref
-GCJ_GetJavaClass (void)
+NPError
+get_cookie_info(const char* siteAddr, char** cookieString, uint32_t* len)
 {
-  PLUGIN_DEBUG_0ARG ("GCJ_GetJavaClass\n");
-
-  PLUGIN_DEBUG_0ARG ("GCJ_GetJavaClass return\n");
-
-  return 0;
-}
-
-NS_IMETHODIMP
-get_cookie_info(const char* siteAddr, char** cookieString)
-{
+#if MOZILLA_VERSION_COLLAPSED < 1090200
   nsresult rv;
   nsCOMPtr<nsIScriptSecurityManager> sec_man =
     do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
 
   if (!sec_man) {
-    return NS_ERROR_FAILURE;
+    return NPERR_GENERIC_ERROR;
   }
 
   nsCOMPtr<nsIIOService> io_svc = do_GetService("@mozilla.org/network/io-service;1", &rv);
 
   if (NS_FAILED(rv) || !io_svc) {
-    return NS_ERROR_FAILURE;
+    return NPERR_GENERIC_ERROR;
   }
 
   nsCOMPtr<nsIURI> uri;
@@ -877,19 +879,45 @@
   nsCOMPtr<nsICookieService> cookie_svc = do_GetService("@mozilla.org/cookieService;1", &rv);
 
   if (NS_FAILED(rv) || !cookie_svc) {
-    return NS_ERROR_FAILURE;
+    return NPERR_GENERIC_ERROR;
   }
 
   rv = cookie_svc->GetCookieString(uri, NULL, cookieString);
 
   if (NS_FAILED(rv) || !*cookieString) {
-    return NS_ERROR_FAILURE;
+    return NPERR_GENERIC_ERROR;
   }
 
-  return NS_OK;
+#else
+
+  // getvalueforurl needs an NPP instance. Quite frankly, there is no easy way
+  // to know which instance needs the information, as applets on Java side can
+  // be multi-threaded and the thread making a proxy.cookie request cannot be
+  // easily tracked.
+
+  // Fortunately, XULRunner does not care about the instance as long as it is
+  // valid. So we just pick the first valid one and use it. Proxy/Cookie
+  // information is not instance specific anyway, it is URL specific.
+
+  if (browser_functions.getvalueforurl)
+  {
+      GHashTableIter iter;
+      gpointer id, instance;
+
+      g_hash_table_iter_init (&iter, instance_to_id_map);
+      g_hash_table_iter_next (&iter, &instance, &id);
+
+      return browser_functions.getvalueforurl((NPP) instance, NPNURLVCookie, siteAddr, cookieString, len);
+  } else
+  {
+      return NPERR_GENERIC_ERROR;
+  }
+
+#endif
+
+  return NPERR_NO_ERROR;
 }
 
-
 // HELPER FUNCTIONS
 
 static void
@@ -907,12 +935,15 @@
   PLUGIN_DEBUG_0ARG ("plugin_data_new return\n");
 }
 
+
+
 // Documentbase retrieval.  This function gets the current document's
 // documentbase.  This function relies on browser-private data so it
 // will only work when the plugin is loaded in a Mozilla-based
 // browser.  We could not find a way to retrieve the documentbase
 // using the original Netscape plugin API so we use the XPCOM API
 // instead.
+#if MOZILLA_VERSION_COLLAPSED < 1090200
 static gchar*
 plugin_get_documentbase (NPP instance)
 {
@@ -970,8 +1001,56 @@
  cleanup_done:
   PLUGIN_DEBUG_0ARG ("plugin_get_documentbase return\n");
 
+  PLUGIN_DEBUG_1ARG("plugin_get_documentbase returning: %s\n", documentbase_copy);
   return documentbase_copy;
 }
+#else
+static gchar*
+plugin_get_documentbase (NPP instance)
+{
+  PLUGIN_DEBUG_0ARG ("plugin_get_documentbase\n");
+
+  char const* documentbase = NULL;
+  gchar* documentbase_copy = NULL;
+
+  // FIXME: This method is not ideal, but there are no known NPAPI call
+  // for this. See thread for more information:
+  // http://www.mail-archive.com/chromium-dev@googlegroups.com/msg04844.html
+
+  // Additionally, since it is insecure, we cannot use it for making
+  // security decisions.
+  NPObject* window;
+  NPString script = NPString();
+  std::string script_str = std::string();
+  NPVariant* location = new NPVariant();
+  std::string location_str = std::string();
+
+  browser_functions.getvalue(instance, NPNVWindowNPObject, &window);
+  script_str += "window.location.href";
+  script.UTF8Characters = script_str.c_str();
+  script.UTF8Length = script_str.size();
+  browser_functions.evaluate(instance, window, &script, location);
+
+  // Strip everything after the last "/"
+  gchar** parts = g_strsplit (NPVARIANT_TO_STRING(*location).UTF8Characters, "/", -1);
+  guint parts_sz = g_strv_length (parts);
+
+  for (int i=0; i < parts_sz - 1; i++)
+  {
+      location_str += parts[i];
+      location_str += "/";
+  }
+
+  documentbase_copy = g_strdup (location_str.c_str());
+
+  // Release references.
+ cleanup_done:
+  PLUGIN_DEBUG_0ARG ("plugin_get_documentbase return\n");
+  PLUGIN_DEBUG_1ARG("plugin_get_documentbase returning: %s\n", documentbase_copy);
+
+  return documentbase_copy;
+}
+#endif
 
 // This function displays an error message if the appletviewer has not
 // been installed correctly.
@@ -1135,21 +1214,22 @@
       gchar** parts = g_strsplit (message, " ", 3);
       if (g_str_has_prefix(parts[1], "PluginProxyInfo"))
       {
-        gchar* proxy_scheme = (gchar*) malloc(sizeof(gchar)*32);
-        gchar* proxy_host = (gchar*) malloc(sizeof(gchar)*64);
-        gchar* proxy_port = (gchar*) malloc(sizeof(gchar)*8);
-
-        GError *error = g_error_new(ITNP_PLUGIN_ERROR, 0, "");
+        gchar* proxy;
+        uint32_t len;
 
         gchar* decoded_url = (gchar*) malloc(strlen(parts[2])*sizeof(gchar) + sizeof(gchar));
         decode_url(parts[2], &decoded_url);
-        get_proxy_info(decoded_url, &proxy_scheme, &proxy_host, &proxy_port, error);
 
         gchar* proxy_info;
+
+#if MOZILLA_VERSION_COLLAPSED < 1090200
+	proxy = (char*) malloc(sizeof(char)*2048);
+#endif
+
         proxy_info = g_strconcat ("plugin PluginProxyInfo ", NULL);
-        if (error->code == 0)
+        if (get_proxy_info(decoded_url, &proxy, &len) == NPERR_NO_ERROR)
           {
-            proxy_info = g_strconcat (proxy_info, proxy_scheme, " ", proxy_host, " ", proxy_port, NULL);
+            proxy_info = g_strconcat (proxy_info, proxy, NULL);
           }
 
         PLUGIN_DEBUG_1ARG("Proxy info: %s\n", proxy_info);
@@ -1159,22 +1239,21 @@
         decoded_url = NULL;
         g_free(proxy_info);
         proxy_info = NULL;
-        g_free(proxy_scheme);
-        proxy_scheme = NULL;
-        g_free(proxy_host);
-        proxy_host = NULL;
-        g_free(proxy_port);
-        proxy_port = NULL;
+
+#if MOZILLA_VERSION_COLLAPSED < 1090200
+	g_free(proxy);
+	proxy = NULL;
+#endif
+
       } else if (g_str_has_prefix(parts[1], "PluginCookieInfo"))
       {
-        GError *error = g_error_new(ITNP_PLUGIN_ERROR, 0, "");
-
         gchar* decoded_url = (gchar*) malloc(strlen(parts[2])*sizeof(gchar) + sizeof(gchar));
         decode_url(parts[2], &decoded_url);
 
         gchar* cookie_info = g_strconcat ("plugin PluginCookieInfo ", parts[2], " ", NULL);
         gchar* cookie_string;
-        if (get_cookie_info(decoded_url, &cookie_string) == NS_OK)
+        uint32_t len;
+        if (get_cookie_info(decoded_url, &cookie_string, &len) == NPERR_NO_ERROR)
         {
             cookie_info = g_strconcat (cookie_info, cookie_string, NULL);
         }
@@ -1184,8 +1263,6 @@
 
         g_free(decoded_url);
         decoded_url = NULL;
-        g_free(cookie_string);
-        cookie_string = NULL;
         g_free(cookie_info);
         cookie_info = NULL;
       }
@@ -1210,6 +1287,7 @@
 
 void decode_url(const gchar* url, gchar** decoded_url)
 {
+#if MOZILLA_VERSION_COLLAPSED < 1090200
     // There is no GLib function to decode urls, so we fallback to Mozilla's
     // methods
 
@@ -1225,10 +1303,15 @@
     // no need for strn. decoded_url is malloced to sizeof unescaped_url, which
     // will always be <= decoded size
     strcpy(*decoded_url,  nsCString(unescaped_url).get());
+#else
+
+#endif
 }
 
-void get_proxy_info(const char* siteAddr, char** proxy_scheme, char** proxy_host, char** proxy_port, GError *error)
+NPError
+get_proxy_info(const char* siteAddr, char** proxy, uint32_t* len)
 {
+#if MOZILLA_VERSION_COLLAPSED < 1090200
   nsresult rv;
 
   // Initialize service variables
@@ -1236,16 +1319,14 @@
 
   if (!proxy_svc) {
       printf("Cannot initialize proxy service\n");
-      error->code = 1;
-      return;
+      return NPERR_GENERIC_ERROR;
   }
 
   nsCOMPtr<nsIIOService> io_svc = do_GetService("@mozilla.org/network/io-service;1", &rv);
 
   if (NS_FAILED(rv) || !io_svc) {
     printf("Cannot initialize io service\n");
-    error->code = 1;
-    return;
+    return NPERR_GENERIC_ERROR;
   }
 
   // uri which needs to be accessed
@@ -1259,8 +1340,7 @@
   // if there is no proxy found, return immediately
   if (!info) {
      PLUGIN_DEBUG_1ARG("%s does not need a proxy\n", siteAddr);
-     error->code = 1;
-     return;
+     return NPERR_GENERIC_ERROR;
   }
 
   // if proxy info is available, extract it
@@ -1277,8 +1357,7 @@
 
   if (!dns_svc) {
       printf("Cannot initialize DNS service\n");
-      error->code = 1;
-      return;
+      return NPERR_GENERIC_ERROR;
   }
 
   nsCOMPtr<nsIDNSRecord> record;
@@ -1288,12 +1367,31 @@
   nsDependentCString ipAddr;
   record->GetNextAddrAsString(ipAddr);
 
-  // pack information in return variables
-  snprintf(*proxy_scheme, sizeof(char)*32, "%s", ptype.get());
-  snprintf(*proxy_host, sizeof(char)*64, "%s", ipAddr.get());
-  snprintf(*proxy_port, sizeof(char)*8, "%d", pport);
+  snprintf(*proxy, sizeof(char)*1024, "%s://%s:%d", ptype.get(), ipAddr.get(), pport);
+  *len = strlen(*proxy);
+
+  PLUGIN_DEBUG_2ARG("Proxy info for %s: %s\n", siteAddr, *proxy);
+
+#else
+
+  if (browser_functions.getvalueforurl)
+  {
 
-  PLUGIN_DEBUG_4ARG("Proxy info for %s: %s %s %s\n", siteAddr, *proxy_scheme, *proxy_host, *proxy_port);
+      // As in get_cookie_info, we use the first active instance
+      GHashTableIter iter;
+      gpointer id, instance;
+
+      g_hash_table_iter_init (&iter, instance_to_id_map);
+      g_hash_table_iter_next (&iter, &instance, &id);
+
+      browser_functions.getvalueforurl((NPP) instance, NPNURLVProxy, siteAddr, proxy, len);
+  } else
+  {
+      return NPERR_GENERIC_ERROR;
+  }
+#endif
+
+  return NPERR_NO_ERROR;
 }
 
 // plugin_out_pipe_callback is called when the appletviewer crashes or
@@ -1319,7 +1417,7 @@
 static NPError
 plugin_test_appletviewer ()
 {
-  PLUGIN_DEBUG_0ARG ("plugin_test_appletviewer\n");
+  PLUGIN_DEBUG_1ARG ("plugin_test_appletviewer: %s\n", appletviewer_executable);
   NPError error = NPERR_NO_ERROR;
 
   gchar* command_line[3] = { NULL, NULL, NULL };
@@ -1756,9 +1854,7 @@
   // the number of browser functions that we may use.
   if (browserTable->size < sizeof (NPNetscapeFuncs))
     {
-      PLUGIN_ERROR ("Invalid browser function table.");
-
-      return NPERR_INVALID_FUNCTABLE_ERROR;
+      fprintf (stderr, "ERROR: Invalid browser function table. Some functionality may be restricted.\n");
     }
 
   // Store in a local table the browser functions that we may use.
@@ -1804,10 +1900,17 @@
   browser_functions.hasmethod               = browserTable->hasmethod;
   browser_functions.releasevariantvalue     = browserTable->releasevariantvalue;
   browser_functions.setexception            = browserTable->setexception;
+  browser_functions.pluginthreadasynccall   = browserTable->pluginthreadasynccall;
+#if MOZILLA_VERSION_COLLAPSED >= 1090200
+  browser_functions.getvalueforurl          = browserTable->getvalueforurl;
+  browser_functions.setvalueforurl          = browserTable->setvalueforurl;
+#endif
 
   // Return to the browser the plugin functions that we implement.
   pluginTable->version = (NP_VERSION_MAJOR << 8) + NP_VERSION_MINOR;
   pluginTable->size = sizeof (NPPluginFuncs);
+
+#if MOZILLA_VERSION_COLLAPSED < 1090200
   pluginTable->newp = NewNPP_NewProc (GCJ_New);
   pluginTable->destroy = NewNPP_DestroyProc (GCJ_Destroy);
   pluginTable->setwindow = NewNPP_SetWindowProc (GCJ_SetWindow);
@@ -1819,6 +1922,19 @@
   pluginTable->print = NewNPP_PrintProc (GCJ_Print);
   pluginTable->urlnotify = NewNPP_URLNotifyProc (GCJ_URLNotify);
   pluginTable->getvalue = NewNPP_GetValueProc (GCJ_GetValue);
+#else
+  pluginTable->newp = NPP_NewProcPtr (GCJ_New);
+  pluginTable->destroy = NPP_DestroyProcPtr (GCJ_Destroy);
+  pluginTable->setwindow = NPP_SetWindowProcPtr (GCJ_SetWindow);
+  pluginTable->newstream = NPP_NewStreamProcPtr (GCJ_NewStream);
+  pluginTable->destroystream = NPP_DestroyStreamProcPtr (GCJ_DestroyStream);
+  pluginTable->asfile = NPP_StreamAsFileProcPtr (GCJ_StreamAsFile);
+  pluginTable->writeready = NPP_WriteReadyProcPtr (GCJ_WriteReady);
+  pluginTable->write = NPP_WriteProcPtr (GCJ_Write);
+  pluginTable->print = NPP_PrintProcPtr (GCJ_Print);
+  pluginTable->urlnotify = NPP_URLNotifyProcPtr (GCJ_URLNotify);
+  pluginTable->getvalue = NPP_GetValueProcPtr (GCJ_GetValue);
+#endif
 
   // Make sure the plugin data directory exists, creating it if
   // necessary.
@@ -1848,6 +1964,7 @@
 
   // Set appletviewer_executable.
   Dl_info info;
+  int filename_size;
   if (dladdr ((const void*) GCJ_New, &info) == 0)
     {
       PLUGIN_ERROR_TWO ("Failed to determine plugin shared object filename",
@@ -1855,15 +1972,31 @@
       np_error = NPERR_GENERIC_ERROR;
       goto cleanup_data_directory;
     }
-  filename = g_strdup (info.dli_fname);
+  filename = (gchar*) malloc(sizeof(gchar)*1024);
+  filename_size = readlink(info.dli_fname, filename, 1023);
+  if (filename_size >= 0)
+  {
+      filename[filename_size] = '\0';
+  }
+
+  printf("FILENAME=%s\n", filename);
+
   if (!filename)
     {
       PLUGIN_ERROR ("Failed to create plugin shared object filename.");
       np_error = NPERR_OUT_OF_MEMORY_ERROR;
       goto cleanup_data_directory;
     }
+
+  if (filename_size <= 0)
+  {
+      free(filename);
+      filename = g_strdup(info.dli_fname);
+  }
+
   appletviewer_executable = g_strdup_printf ("%s/../../bin/java",
                                              dirname (filename));
+  PLUGIN_DEBUG_4ARG(".so is located at: %s and the link points to: %s. Executing java from dir %s to run %s\n", info.dli_fname, filename, dirname (filename), appletviewer_executable);
   if (!appletviewer_executable)
     {
       PLUGIN_ERROR ("Failed to create appletviewer executable name.");
--- a/plugin/icedteanp/IcedTeaNPPlugin.h	Wed Aug 26 01:14:21 2009 -0400
+++ b/plugin/icedteanp/IcedTeaNPPlugin.h	Wed Aug 26 15:06:47 2009 -0400
@@ -41,8 +41,15 @@
 
 // Netscape plugin API includes.
 #include <npapi.h>
+#include <nsThreadUtils.h>
+
+#if MOZILLA_VERSION_COLLAPSED < 1090200
 #include <npupp.h>
-#include <nsThreadUtils.h>
+#else
+#include <npapi.h>
+#include <npruntime.h>
+#include <npfunctions.h>
+#endif
 
 // GLib includes.
 #include <glib.h>
@@ -112,7 +119,7 @@
 void get_instance_from_id(int id, NPP& instance);
 
 /* Given an instance id, return its pointer */
-int get_id_from_instance(NPP* instance);
+int get_id_from_instance(NPP instance);
 
 /* Sends a message to the appletviewer */
 void plugin_send_message_to_appletviewer(gchar const* message);
--- a/plugin/icedteanp/IcedTeaPluginRequestProcessor.cc	Wed Aug 26 01:14:21 2009 -0400
+++ b/plugin/icedteanp/IcedTeaPluginRequestProcessor.cc	Wed Aug 26 15:06:47 2009 -0400
@@ -206,21 +206,20 @@
     CHECK_JAVA_RESULT(java_result);
     script.append(*(java_result->return_string));
 
-    std::vector<void*> internal_request_params = std::vector<void*>();
-    ResultData rdata = ResultData();
-    nsCOMPtr<nsIRunnable> event;
-
-    internal_request_params.push_back(instance);
-    internal_request_params.push_back(window_ptr);
-    internal_request_params.push_back(&script);
+    AyncCallThreadData thread_data = AyncCallThreadData();
+    thread_data.result_ready = false;
+    thread_data.parameters = std::vector<void*>();
+    thread_data.result = std::string();
 
-    rdata.result_ready = false;
-    event = new IcedTeaRunnableMethod(&_eval, (void*) &internal_request_params, &rdata);
-    NS_DispatchToMainThread(event, 0);
+    thread_data.parameters.push_back(instance);
+    thread_data.parameters.push_back(window_ptr);
+    thread_data.parameters.push_back(&script);
 
-    while (!rdata.result_ready) usleep(2000); // Wait till result is ready
+    browser_functions.pluginthreadasynccall(instance, &_eval, &thread_data);
 
-    NPVariant* result_variant = (NPVariant*) IcedTeaPluginUtilities::stringToJSID(*(rdata.return_string));
+    while (!thread_data.result_ready) usleep(2000); // Wait till result is ready
+
+    NPVariant* result_variant = (NPVariant*) IcedTeaPluginUtilities::stringToJSID(thread_data.result);
     std::string result_variant_jniid = std::string();
     storeVariantInJava(*result_variant, &result_variant_jniid);
 
@@ -438,25 +437,23 @@
     for (int i=0; i < args.size(); i++)
         args_array[i] = args[i];
 
-    std::vector<void*> internal_request_params = std::vector<void*>();
-    ResultData rdata = ResultData();
-    nsCOMPtr<nsIRunnable> event;
-
-    internal_request_params.push_back(instance);
-    internal_request_params.push_back(window_ptr);
-    internal_request_params.push_back(&window_function_name);
-    internal_request_params.push_back(&arg_count);
-    internal_request_params.push_back(args_array);
+    AyncCallThreadData thread_data = AyncCallThreadData();
+    thread_data.result_ready = false;
+    thread_data.parameters = std::vector<void*>();
+    thread_data.result = std::string();
 
-    printf("Packing %p [%p] %p %s@%p %p %p\n", instance, internal_request_params.at(0), window_ptr, window_function_name.c_str(), &window_function_name, &arg_count, args_array);
+    thread_data.parameters.push_back(instance);
+    thread_data.parameters.push_back(window_ptr);
+    thread_data.parameters.push_back(&window_function_name);
+    thread_data.parameters.push_back(&arg_count);
+    thread_data.parameters.push_back(args_array);
 
-    rdata.result_ready = false;
-    event = new IcedTeaRunnableMethod(&_call, (void*) &internal_request_params, &rdata);
-    NS_DispatchToMainThread(event, 0);
+    printf("Packing %p [%p] %p %s@%p %p %p\n", instance, thread_data.parameters.at(0), window_ptr, window_function_name.c_str(), &window_function_name, &arg_count, args_array);
+    browser_functions.pluginthreadasynccall(instance, &_call, &thread_data);
 
-    while (!rdata.result_ready) usleep(2000); // wait till ready
+    while (!thread_data.result_ready) usleep(2000); // wait till ready
 
-    NPVariant* result_variant = (NPVariant*) IcedTeaPluginUtilities::stringToJSID(*(rdata.return_string));
+    NPVariant* result_variant = (NPVariant*) IcedTeaPluginUtilities::stringToJSID(thread_data.result);
     std::string result_variant_jniid = std::string();
     storeVariantInJava(*result_variant, &result_variant_jniid);
 
@@ -467,7 +464,6 @@
     plugin_to_java_bus->post(response.c_str());
 
     cleanup:
-    delete rdata.return_string;
     free(args_array);
 }
 
@@ -535,12 +531,9 @@
     std::string value = std::string();
     std::string type = std::string();
     std::string* value_variant_ptr_str;
-    std::string member_ptr_str = std::string();
-    std::vector<std::string*>* internal_request_params = new std::vector<std::string*>();
 
+    NPP instance;
     NPObject* member;
-    nsCOMPtr<nsIRunnable> event;
-    ResultData* rdata = new ResultData();
 
     JavaRequestProcessor* java_request = new JavaRequestProcessor();
     JavaResultData* java_result;
@@ -550,6 +543,7 @@
     member = reinterpret_cast <NPObject*> (IcedTeaPluginUtilities::stringToJSID(message_parts->at(3)));
     propertyNameID = message_parts->at(4);
     valueID = message_parts->at(5);
+    instance = IcedTeaPluginUtilities::getInstanceFromMemberPtr(member);
 
     java_request = new JavaRequestProcessor();
     java_result = java_request->getString(propertyNameID);
@@ -558,7 +552,7 @@
     if (java_result->error_occurred)
     {
         printf("Unable to get member name for setMember. Error occurred: %s\n", java_result->error_msg);
-        goto cleanup;
+        //goto cleanup;
     }
 
     // Copy into local variable before disposing the object
@@ -575,7 +569,7 @@
     if (java_result->error_occurred)
     {
         printf("Unable to get class name for setMember. Error occurred: %s\n", java_result->error_msg);
-        goto cleanup;
+        //goto cleanup;
     }
 
     // Copy into local variable before disposing the object
@@ -589,26 +583,27 @@
     if (java_result->error_occurred)
     {
         printf("Unable to get value for setMember. Error occurred: %s\n", java_result->error_msg);
-        goto cleanup;
+        //goto cleanup;
     }
 
     value.append(*(java_result->return_string));
 
-    IcedTeaPluginUtilities::JSIDToString(member, &member_ptr_str);
-    internal_request_params->push_back(&member_ptr_str);
-    internal_request_params->push_back(&property_name);
-    internal_request_params->push_back(&type);
-    internal_request_params->push_back(&value);
+    AyncCallThreadData thread_data = AyncCallThreadData();
+    thread_data.result_ready = false;
+    thread_data.parameters = std::vector<void*>();
+    thread_data.result = std::string();
 
-    rdata->result_ready = false;
-    event = new IcedTeaRunnableMethod(&_setMember, (void*) internal_request_params, (void*) rdata);
-    NS_DispatchToMainThread(event, 0);
+    thread_data.parameters.push_back(instance);
+    thread_data.parameters.push_back(member);
+    thread_data.parameters.push_back(&property_name);
+    thread_data.parameters.push_back(&type);
+    thread_data.parameters.push_back(&value);
 
-    while (!rdata->result_ready) usleep(2000); // wait till ready
+    browser_functions.pluginthreadasynccall(instance, &_setMember, &thread_data);
+
+    while (!thread_data.result_ready) usleep(2000); // wait till ready
 
     cleanup:
-    delete rdata;
-    delete rdata->return_string;
     delete message_parts;
     delete java_request;
 
@@ -664,25 +659,23 @@
     std::vector<std::string> args;
     JavaRequestProcessor java_request = JavaRequestProcessor();
     JavaResultData* java_result;
-    ResultData member_data;
+    NPObject* parent_ptr;
+
     std::string member_id = std::string();
-    std::string parent_id = std::string();
     std::string jsObjectClassID = std::string();
     std::string jsObjectConstructorID = std::string();
     std::string response = std::string();
-    nsCOMPtr<nsIRunnable> event;
 
-    std::vector<std::string*> internal_request_params = std::vector<std::string*>();
     int method_id;
-    int instance;
+    int instance_id;
     long reference;
 
     // debug printout of parent thread data
     IcedTeaPluginUtilities::printStringVector("PluginRequestProcessor::getMember:", message_parts);
 
     // store info in local variables for easy access
-    instance = atoi(message_parts->at(1).c_str());
-    parent_id += message_parts->at(3);
+    instance_id = atoi(message_parts->at(1).c_str());
+    parent_ptr = reinterpret_cast <NPObject*> (IcedTeaPluginUtilities::stringToJSID(message_parts->at(3)));
     member_id += message_parts->at(4);
 
     /** Request data from Java **/
@@ -701,18 +694,21 @@
 
     reference = internal_req_ref_counter++;
 
-    internal_request_params.push_back(&parent_id);
-    internal_request_params.push_back(java_result->return_string);
-
-    member_data = ResultData();
-    member_data.result_ready = false;
+    AyncCallThreadData thread_data = AyncCallThreadData();
+    thread_data.result_ready = false;
+    thread_data.parameters = std::vector<void*>();
+    thread_data.result = std::string();
 
-    event = new IcedTeaRunnableMethod(&_getMember, (void*) &internal_request_params, (void*) &member_data);
-    NS_DispatchToMainThread(event, 0);
+    NPP instance = IcedTeaPluginUtilities::getInstanceFromMemberPtr(parent_ptr);
+    thread_data.parameters.push_back(instance);
+    thread_data.parameters.push_back(parent_ptr);
+    thread_data.parameters.push_back(java_result->return_string);
 
-    while (!member_data.result_ready) usleep(2000); // wait till ready
+    browser_functions.pluginthreadasynccall(instance, &_getMember, &thread_data);
 
-    PLUGIN_DEBUG_1ARG("Member PTR after internal request: %s\n", member_data.return_string->c_str());
+    while (!thread_data.result_ready) usleep(2000); // wait till ready
+
+    PLUGIN_DEBUG_1ARG("Member PTR after internal request: %s\n", thread_data.result.c_str());
 
     internal_req_ref_counter--;
 
@@ -747,8 +743,8 @@
     // We have the method id. Now create a new object.
 
     args.clear();
-    args.push_back(*(member_data.return_string));
-    java_result = java_request.newObject("",
+    args.push_back(thread_data.result);
+    java_result = java_request.newObjectWithConstructor("",
                                          jsObjectClassID,
                                          jsObjectConstructorID,
                                          args);
@@ -770,7 +766,6 @@
     // Now be a good citizen and help keep the heap free of garbage
     cleanup:
     delete message_parts; // message_parts vector that was allocated by the caller
-    delete member_data.return_string;
 
     pthread_mutex_lock(&tc_mutex);
     thread_count--;
@@ -890,7 +885,7 @@
 
         boolean_args.clear();
         boolean_args.push_back(value_str);
-        java_result = java_request.newObject("",
+        java_result = java_request.newObjectWithConstructor("",
                                              boolean_classid,
                                              boolean_constructor_id,
                                              boolean_args);
@@ -919,7 +914,7 @@
 
         integer_args.clear();
         integer_args.push_back(value_str);
-        java_result = java_request.newObject("",
+        java_result = java_request.newObjectWithConstructor("",
                                              integer_classid,
                                              integer_constructor_id,
                                              integer_args);
@@ -948,7 +943,7 @@
 
         double_args.clear();
         double_args.push_back(value_str);
-        java_result = java_request.newObject("",
+        java_result = java_request.newObjectWithConstructor("",
                                              double_classid,
                                              double_constructor_id,
                                              double_args);
@@ -959,7 +954,11 @@
     else if (NPVARIANT_IS_STRING(variant))
     {
         NPString str = NPVARIANT_TO_STRING(variant);
+#if MOZILLA_VERSION_COLLAPSED < 1090200
         java_result = java_request.newString(str.utf8characters);
+#else
+        java_result = java_request.newString(str.UTF8Characters);
+#endif
         CHECK_JAVA_RESULT(java_result);
         result->append(*(java_result->return_string));
     } else {
@@ -993,7 +992,7 @@
 
             jsobject_args.clear();
             jsobject_args.push_back(value_str);
-            java_result = java_request.newObject("",
+            java_result = java_request.newObjectWithConstructor("",
                                                  jsobject_classid,
                                                  jsobject_constructor_id,
                                                  jsobject_args);
@@ -1010,28 +1009,26 @@
  * Functions delegated to the main thread *
  ******************************************/
 
-void*
-_setMember(void* data, void* result)
+void
+_setMember(void* data)
 {
     std::string* property_name;
     std::string* value;
     std::string* type;
     std::string response = std::string();
-    std::vector<std::string*>* message_parts = (std::vector<std::string*>*) data;
 
     NPP instance;
     NPVariant* value_variant = new NPVariant();
     NPObject* member;
     NPIdentifier property;
 
-    IcedTeaPluginUtilities::printStringPtrVector("PluginRequestProcessor::_setMember - ", message_parts);
+    std::vector<void*> parameters = ((AyncCallThreadData*) data)->parameters;
+    instance = (NPP) parameters.at(0);
+    member = (NPObject*) parameters.at(1);
+    property_name = (std::string*) parameters.at(2);
+    type = (std::string*) parameters.at(3);
+    value = (std::string*) parameters.at(4);
 
-    member = reinterpret_cast <NPObject*> (IcedTeaPluginUtilities::stringToJSID(*(message_parts->at(0))));
-    property_name = message_parts->at(1);
-    type = message_parts->at(2);
-    value = message_parts->at(3);
-
-    instance = IcedTeaPluginUtilities::getInstanceFromMemberPtr(member);
     convertToNPVariant(*value, *type, value_variant);
 
     PLUGIN_DEBUG_4ARG("Setting %s on instance %p, object %p to value %s\n", property_name->c_str(), instance, member, value_variant);
@@ -1043,17 +1040,15 @@
     response.append(" JavaScriptSetMember ");
     plugin_to_java_bus->post(response.c_str());
 
+    ((AyncCallThreadData*) data)->result_ready = true;
+
     // free memory
     delete value_variant;
-
-    ((ResultData*) result)->result_ready = true;
-
 }
 
-void*
-_getMember(void* data, void* result)
+void
+_getMember(void* data)
 {
-    std::string* parent_ptr_str;
     std::string* member_name;
 
     NPObject* parent_ptr;
@@ -1062,22 +1057,15 @@
     NPP instance;
     NPIdentifier member_identifier;
 
-    std::vector<std::string*>* message_parts = (std::vector<std::string*>*) data;
+    std::vector<void*> parameters = ((AyncCallThreadData*) data)->parameters;
 
-    IcedTeaPluginUtilities::printStringPtrVector("PluginRequestProcessor::_getMember - ", message_parts);
-
-    parent_ptr_str = message_parts->at(0);
-    member_name = message_parts->at(1);
+    instance = (NPP) parameters.at(0);
+    parent_ptr = (NPObject*) parameters.at(1);
+    member_name = (std::string*) parameters.at(2);
 
     // Get the corresponding windowId
     member_identifier = browser_functions.getstringidentifier(member_name->c_str());
 
-    // Get the window pointer
-    parent_ptr = reinterpret_cast <NPObject*> (IcedTeaPluginUtilities::stringToJSID(parent_ptr_str->c_str()));
-
-    // Get the associated instance
-    instance = IcedTeaPluginUtilities::getInstanceFromMemberPtr(parent_ptr);
-
     // Get the NPVariant corresponding to this member
     PLUGIN_DEBUG_4ARG("Looking for %p %p %p (%s)\n", instance, parent_ptr, member_identifier,member_name->c_str());
 
@@ -1091,9 +1079,8 @@
     IcedTeaPluginUtilities::JSIDToString(NPVARIANT_TO_OBJECT(member_ptr), &member_ptr_str);
     PLUGIN_DEBUG_2ARG("Got variant %p (integer value = %s)\n", NPVARIANT_TO_OBJECT(member_ptr), member_ptr_str.c_str());
 
-    ((ResultData*) result)->return_string = new std::string();
-    ((ResultData*) result)->return_string->append(member_ptr_str);
-    ((ResultData*) result)->result_ready = true;
+    ((AyncCallThreadData*) data)->result.append(member_ptr_str);
+    ((AyncCallThreadData*) data)->result_ready = true;
 
     // store member -> instance link
     IcedTeaPluginUtilities::storeInstanceID(NPVARIANT_TO_OBJECT(member_ptr), instance);
@@ -1101,8 +1088,8 @@
     PLUGIN_DEBUG_0ARG("_getMember returning.\n");
 }
 
-void*
-_eval(void* data, void* result)
+void
+_eval(void* data)
 {
     NPP instance;
     NPObject* window_ptr;
@@ -1120,24 +1107,31 @@
     window_ptr = (NPObject*) call_data->at(1);
     script_str = (std::string*) call_data->at(2);
 
+#if MOZILLA_VERSION_COLLAPSED < 1090200
     script.utf8characters = script_str->c_str();
     script.utf8length = script_str->size();
 
     PLUGIN_DEBUG_1ARG("Evaluating: %s\n", script.utf8characters);
+#else
+    script.UTF8Characters = script_str->c_str();
+    script.UTF8Length = script_str->size();
+
+    PLUGIN_DEBUG_1ARG("Evaluating: %s\n", script.UTF8Characters);
+#endif
+
     browser_functions.evaluate(instance, window_ptr, &script, eval_result);
     IcedTeaPluginUtilities::printNPVariant(*eval_result);
 
     IcedTeaPluginUtilities::JSIDToString(eval_result, &eval_result_ptr_str);
-    ((ResultData*) result)->return_string = new std::string();
-    ((ResultData*) result)->return_string->append(eval_result_ptr_str);
-    ((ResultData*) result)->result_ready = true;
+    ((AyncCallThreadData*) data)->result.append(eval_result_ptr_str);
+    ((AyncCallThreadData*) data)->result_ready = true;
 
     PLUGIN_DEBUG_0ARG("_eval returning\n");
 }
 
 
-void*
-_call(void* data, void* result)
+void
+_call(void* data)
 {
     NPP instance;
     NPObject* window_ptr;
@@ -1155,6 +1149,7 @@
     instance = (NPP) call_data->at(0);
     window_ptr = (NPObject*) call_data->at(1);
     function_name = (std::string*) call_data->at(2);
+
     function = browser_functions.getstringidentifier(function_name->c_str());
     arg_count = (int*) call_data->at(3);
     args = (NPVariant*) call_data->at(4);
@@ -1164,9 +1159,8 @@
     browser_functions.invoke(instance, window_ptr, function, args, *arg_count, call_result);
 
     IcedTeaPluginUtilities::JSIDToString(&call_result, &call_result_ptr_str);
-    ((ResultData*) result)->return_string = new std::string();
-    ((ResultData*) result)->return_string->append(call_result_ptr_str);
-    ((ResultData*) result)->result_ready = true;
+    ((AyncCallThreadData*) data)->result.append(call_result_ptr_str);
+    ((AyncCallThreadData*) data)->result_ready = true;
 
     PLUGIN_DEBUG_0ARG("_call returning\n");
 }
--- a/plugin/icedteanp/IcedTeaPluginRequestProcessor.h	Wed Aug 26 01:14:21 2009 -0400
+++ b/plugin/icedteanp/IcedTeaPluginRequestProcessor.h	Wed Aug 26 15:06:47 2009 -0400
@@ -46,7 +46,13 @@
 #include <time.h>
 
 #include <npapi.h>
+
+#if MOZILLA_VERSION_COLLAPSED < 1090200
 #include <npupp.h>
+#else
+#include <npapi.h>
+#include <npruntime.h>
+#endif
 
 #include "IcedTeaRunnable.h"
 #include "IcedTeaPluginUtils.h"
@@ -56,11 +62,12 @@
  * Data structure passed to functions called in a new thread.
  */
 
-typedef struct struct_thread_data
+typedef struct aync_call_thread_data
 {
-	std::vector<std::string>* message_parts;
-	std::string* source;
-} ThreadData;
+    std::vector<void*> parameters;
+	std::string result;
+	bool result_ready;
+} AyncCallThreadData;
 
 /* Internal request reference counter */
 static long internal_req_ref_counter;
@@ -79,10 +86,10 @@
 static void convertToNPVariant(std::string value, std::string type, NPVariant* result_variant);
 
 // Internal methods that need to run in main thread
-void* _getMember(void* message_parts, void* result);
-void* _setMember(void* message_parts, void* result);
-void* _call(void* data, void* result);
-void* _eval(void* data, void* result);
+void _getMember(void* data);
+void _setMember(void* data);
+void _call(void* data);
+void _eval(void* data);
 
 static pthread_mutex_t tc_mutex = PTHREAD_MUTEX_INITIALIZER;
 static int thread_count = 0;
--- a/plugin/icedteanp/IcedTeaPluginUtils.cc	Wed Aug 26 01:14:21 2009 -0400
+++ b/plugin/icedteanp/IcedTeaPluginUtils.cc	Wed Aug 26 15:06:47 2009 -0400
@@ -418,14 +418,23 @@
 	delete str;
 }
 
-gchar*
+const gchar*
 IcedTeaPluginUtilities::getSourceFromInstance(NPP instance)
 {
-    GCJPluginData* data = (GCJPluginData*) instance->pdata;
-    return data->source;
+    // At the moment, src cannot be securely fetched via NPAPI
+    // See:
+    // http://www.mail-archive.com/chromium-dev@googlegroups.com/msg04872.html
+
+    // Since we use the insecure window.location.href attribute to compute
+    // source, we cannot use it to make security decisions. Therefore,
+    // instance associated source will always return empty
+
+    //GCJPluginData* data = (GCJPluginData*) instance->pdata;
+    //return (data->source) ? data->source : "";
+
+    return "http://null.null";
 }
 
-
 /**
  * Stores a window pointer <-> instance mapping
  *
@@ -518,7 +527,11 @@
     }
     else if (NPVARIANT_IS_STRING(variant))
     {
+#if MOZILLA_VERSION_COLLAPSED < 1090200
     	PLUGIN_DEBUG_1ARG("STRING: %s\n", NPVARIANT_TO_STRING(variant).utf8characters);
+#else
+    	PLUGIN_DEBUG_1ARG("STRING: %s\n", NPVARIANT_TO_STRING(variant).UTF8Characters);
+#endif
     }
     else
     {
@@ -557,8 +570,13 @@
     else if (NPVARIANT_IS_STRING(variant))
     {
     	free(str);
+#if MOZILLA_VERSION_COLLAPSED < 1090200
     	str = (char*) malloc(sizeof(char)*NPVARIANT_TO_STRING(variant).utf8length);
     	sprintf(str, "%s", NPVARIANT_TO_STRING(variant).utf8characters);
+#else
+        str = (char*) malloc(sizeof(char)*NPVARIANT_TO_STRING(variant).UTF8Length);
+        sprintf(str, "%s", NPVARIANT_TO_STRING(variant).UTF8Characters);
+#endif
     }
     else
     {
--- a/plugin/icedteanp/IcedTeaPluginUtils.h	Wed Aug 26 01:14:21 2009 -0400
+++ b/plugin/icedteanp/IcedTeaPluginUtils.h	Wed Aug 26 15:06:47 2009 -0400
@@ -56,7 +56,13 @@
 #include <vector>
 
 #include <npapi.h>
+
+#if MOZILLA_VERSION_COLLAPSED < 1090200
 #include <npupp.h>
+#else
+#include <npapi.h>
+#include <npruntime.h>
+#endif
 
 #include "IcedTeaNPPlugin.h"
 
@@ -201,7 +207,7 @@
 
     	static std::string* NPVariantToString(NPVariant variant);
 
-    	static gchar* getSourceFromInstance(NPP instance);
+    	static const gchar* getSourceFromInstance(NPP instance);
 
     	static void storeInstanceID(void* member_ptr, NPP instance);
 
--- a/plugin/icedteanp/IcedTeaScriptablePluginObject.cc	Wed Aug 26 01:14:21 2009 -0400
+++ b/plugin/icedteanp/IcedTeaScriptablePluginObject.cc	Wed Aug 26 15:06:47 2009 -0400
@@ -471,6 +471,9 @@
 
     if (java_result->error_occurred)
     {
+        // error message must be allocated on heap
+        char* error_msg = (char*) malloc(java_result->error_msg->length()*sizeof(char));
+        browser_functions.setexception(npobj, error_msg);
         return false;
     }
 
@@ -541,7 +544,6 @@
 
             PLUGIN_DEBUG_1ARG("Method call returned a string %s\n", return_str);
             STRINGZ_TO_NPVARIANT(return_str, *result);
-            printf("%p -- %p\n", return_str, result->value.stringValue.utf8characters);
 
             // delete string from java side, as it is no longer needed
             java_request.deleteReference(return_obj_instance_id);
@@ -663,6 +665,49 @@
 IcedTeaScriptableJavaObject::construct(NPObject *npobj, const NPVariant *args, uint32_t argCount,
 	           NPVariant *result)
 {
-	printf ("** Unimplemented: IcedTeaScriptableJavaObject::construct %p\n", npobj);
-	return false;
+    NPUTF8* method_name = "";
+
+    // Extract arg type array
+    PLUGIN_DEBUG_1ARG("IcedTeaScriptableJavaObject::construct %s. Args follow.\n", ((IcedTeaScriptableJavaObject*) npobj)->getClassID().c_str());
+    for (int i=0; i < argCount; i++)
+    {
+        IcedTeaPluginUtilities::printNPVariant(args[i]);
+    }
+
+    JavaResultData* java_result;
+    JavaRequestProcessor java_request = JavaRequestProcessor();
+
+    NPObject* obj;
+    std::string class_id = ((IcedTeaScriptableJavaObject*) npobj)->getClassID();
+    NPP instance = IcedTeaPluginUtilities::getInstanceFromMemberPtr(npobj);
+
+    java_result = java_request.newObject(
+                            IcedTeaPluginUtilities::getSourceFromInstance(instance),
+                            class_id,
+                            args,
+                            argCount);
+
+    if (java_result->error_occurred)
+    {
+        // error message must be allocated on heap
+        int length = java_result->error_msg->length();
+        char* error_msg = (char*) malloc((length+1)*sizeof(char));
+        strcpy(error_msg, java_result->error_msg->c_str());
+
+        browser_functions.setexception(npobj, error_msg);
+        return false;
+    }
+
+    std::string return_obj_instance_id = std::string();
+    std::string return_obj_class_id = class_id;
+    return_obj_instance_id.append(*(java_result->return_string));
+
+    obj = IcedTeaScriptableJavaPackageObject::get_scriptable_java_object(
+                                IcedTeaPluginUtilities::getInstanceFromMemberPtr(npobj),
+                                return_obj_class_id, return_obj_instance_id);
+
+    OBJECT_TO_NPVARIANT(obj, *result);
+
+    PLUGIN_DEBUG_0ARG("IcedTeaScriptableJavaObject::construct returning.\n");
+    return true;
 }
--- a/plugin/icedteanp/IcedTeaScriptablePluginObject.h	Wed Aug 26 01:14:21 2009 -0400
+++ b/plugin/icedteanp/IcedTeaScriptablePluginObject.h	Wed Aug 26 15:06:47 2009 -0400
@@ -39,7 +39,12 @@
 #ifndef __ICEDTEASCRIPTABLEPLUGINOBJECT_H_
 #define __ICEDTEASCRIPTABLEPLUGINOBJECT_H_
 
+#if MOZILLA_VERSION_COLLAPSED < 1090200
 #include "npupp.h"
+#else
+#include <npapi.h>
+#include <npruntime.h>
+#endif
 
 #include "IcedTeaJavaRequestProcessor.h"
 #include "IcedTeaNPPlugin.h"
--- a/plugin/icedteanp/java/sun/applet/MethodOverloadResolver.java	Wed Aug 26 01:14:21 2009 -0400
+++ b/plugin/icedteanp/java/sun/applet/MethodOverloadResolver.java	Wed Aug 26 15:06:47 2009 -0400
@@ -37,6 +37,7 @@
 
 package sun.applet;
 
+import java.lang.reflect.Constructor;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 
@@ -152,6 +153,7 @@
                     System.out.println("No match found.\n");
                 
         }
+        
     }
 
     /* 
@@ -222,6 +224,66 @@
         return ret;
     }
 
+    public static Object[] getMatchingConstructor(Object[] callList) {
+        Object[] ret = null;
+        Class c = (Class) callList[0];
+
+        Constructor[] matchingConstructors = getMatchingConstructors(c, callList.length - 1);
+        
+        if (debugging)
+            System.out.println("getMatchingConstructor called with: " + printList(callList));
+
+        int lowestCost = Integer.MAX_VALUE;
+
+        ArrayList<Object> paramList = new ArrayList<Object>();
+
+        for (Constructor matchingConstructor : matchingConstructors) {
+
+            int constructorCost = 0;
+            Class[] paramTypes = matchingConstructor.getParameterTypes();
+            Object[] constructorAndArgs = new Object[paramTypes.length + 1];
+            constructorAndArgs[0] = matchingConstructor;
+
+            // Figure out which of the matched methods best represents what we
+            // want
+            for (int i = 0; i < paramTypes.length; i++) {
+                Class paramTypeClass = paramTypes[i];
+                Object suppliedParam = callList[i + 1];
+                Class suppliedParamClass = suppliedParam != null ? suppliedParam
+                        .getClass()
+                        : null;
+
+                Object[] costAndCastedObj = getCostAndCastedObject(
+                        suppliedParam, paramTypeClass);
+                constructorCost += (Integer) costAndCastedObj[0];
+                Object castedObj = paramTypeClass.isPrimitive() ? costAndCastedObj[1]
+                        : paramTypeClass.cast(costAndCastedObj[1]);
+                constructorAndArgs[i + 1] = castedObj;
+
+                Class castedObjClass = castedObj == null ? null : castedObj
+                        .getClass();
+                Boolean castedObjIsPrim = castedObj == null ? null : castedObj
+                        .getClass().isPrimitive();
+
+                if (debugging)
+                    System.out.println("Param " + i + " of constructor "
+                            + matchingConstructor + " has cost "
+                            + (Integer) costAndCastedObj[0]
+                            + " original param type " + suppliedParamClass
+                            + " casted to " + castedObjClass + " isPrimitive="
+                            + castedObjIsPrim + " value " + castedObj);
+            }
+
+            if ((constructorCost > 0 && constructorCost < lowestCost) || 
+                 paramTypes.length == 0) {
+                ret = constructorAndArgs;
+                lowestCost = constructorCost;
+            }
+        }
+
+        return ret;
+    }
+
     private static Object[] getCostAndCastedObject(Object suppliedParam, Class paramTypeClass) {
         
         Object[] ret = new Object[2];
@@ -300,6 +362,18 @@
 
         return matchingMethods.toArray(new Method[0]);
     }
+    
+    private static Constructor[] getMatchingConstructors(Class c, int paramCount) {
+        Constructor[] allConstructors = c.getConstructors();
+        ArrayList<Constructor> matchingConstructors = new ArrayList<Constructor>(5);
+        
+        for (Constructor cs: allConstructors) {
+            if (cs.getParameterTypes().length == paramCount)
+                matchingConstructors.add(cs);
+        }
+
+        return matchingConstructors.toArray(new Constructor[0]);
+    }
 
     private static Class getPrimitive(Object o) {
         
@@ -415,20 +489,52 @@
 
 class FooClass {
 
-    // First type full match, second Class -> Primitive
-    public void foo(Boolean b, int i) {
+    public FooClass() {}
+    
+    public FooClass(Boolean b, int i) {}
+
+    public FooClass(Boolean b, Integer i) {}
+
+    public FooClass(Boolean b, short s) {}
+
+    public FooClass(String s, int i) {}
 
-    }
+    public FooClass(String s, Integer i) {}
+
+    public FooClass(java.lang.Number num) {}
+
+    public FooClass(java.lang.Integer integer) {}
+
+    public FooClass(long l) {}
+
+    public FooClass(double d) {}
 
-    // Full match
-    public void foo(Boolean b, Integer i) {
+    public FooClass(float f) {}
+    
+    public FooClass(JSObject j) {}
 
-    }
+    public FooClass(BarClass1 b) {}
+
+    public FooClass(BarClass2 b) {}
 
-    // First type full match, second Class -> Primitive ambiguity
-    public void foo(Boolean b, short s) {
+    public FooClass(String s) {}
+    
+    public FooClass(byte b) {}
+    
+    public FooClass(String s, Float f) {}
+    
+    public FooClass (int i) {}
 
-    }
+    public void FooClass() {}
+
+    public void FooClass(boolean b) {}
+
+    
+    public void foo(Boolean b, int i) {}
+
+    public void foo(Boolean b, Integer i) {}
+
+    public void foo(Boolean b, short s) {}
 
     public void foo_string_int(String s, int i) {}
 
--- a/plugin/icedteanp/java/sun/applet/PluginAppletSecurityContext.java	Wed Aug 26 01:14:21 2009 -0400
+++ b/plugin/icedteanp/java/sun/applet/PluginAppletSecurityContext.java	Wed Aug 26 15:06:47 2009 -0400
@@ -202,7 +202,7 @@
 
 		return c;
 	}
-
+	
 	public static Class primitiveNameToType(String name) {
 		if (name.equals("void"))
 			return Void.TYPE;
@@ -912,32 +912,93 @@
 				store.reference(newArray);
 				write(reference, "NewObjectArray "
 						+ store.getIdentifier(newArray));
-			} else if (message.startsWith("NewObject")) {
+			} else if (message.startsWith("NewObjectWithConstructor")) {
+
+                String[] args = message.split(" ");
+                Integer classID = parseCall(args[1], null, Integer.class);
+                Integer methodID = parseCall(args[2], null, Integer.class);
+
+                final Constructor m = (Constructor) store.getObject(methodID);
+                Class[] argTypes = m.getParameterTypes();
+
+                // System.out.println ("NEWOBJ: HERE1");
+                Object[] arguments = new Object[argTypes.length];
+                // System.out.println ("NEWOBJ: HERE2");
+                for (int i = 0; i < argTypes.length; i++) {
+                    arguments[i] = parseArgs(args[3 + i], argTypes[i]);
+                    // System.out.println ("NEWOBJ: GOT ARG: " + arguments[i]);
+                }
+
+                final Object[] fArguments = arguments;
+                AccessControlContext acc = callContext != null ? callContext : getClosedAccessControlContext();
+
+                Class c = (Class) store.getObject(classID);
+                checkPermission(src, c, acc);
+
+                Object ret = AccessController.doPrivileged(new PrivilegedAction<Object> () {
+                    public Object run() {
+                        try {
+                            return m.newInstance(fArguments);
+                        } catch (Throwable t) {
+                            return t;
+                        }
+                    }
+                }, acc);
+
+                if (ret instanceof Throwable)
+                    throw (Throwable) ret;
+
+                store.reference(ret);
+
+                write(reference, "NewObject " + store.getIdentifier(ret));
+
+            } else if (message.startsWith("NewObject")) {
 				String[] args = message.split(" ");
 				Integer classID = parseCall(args[1], null, Integer.class);
-				Integer methodID = parseCall(args[2], null, Integer.class);
+				Class c = (Class) store.getObject(classID);
+                final Constructor cons;
+                final Object[] fArguments;
 
-				final Constructor m = (Constructor) store.getObject(methodID);
-				Class[] argTypes = m.getParameterTypes();
+                Object[] arguments = new Object[args.length - 1];
+                arguments[0] = c;
+                for (int i = 0; i < args.length - 2; i++) {
+                    arguments[i + 1] = store.getObject(parseCall(args[2 + i],
+                            null, Integer.class));
+                    PluginDebug.debug("GOT ARG: " + arguments[i + 1]);
+                }
+
+                Object[] matchingConstructorAndArgs = MethodOverloadResolver
+                        .getMatchingConstructor(arguments);
 
-				// System.out.println ("NEWOBJ: HERE1");
-				Object[] arguments = new Object[argTypes.length];
-				// System.out.println ("NEWOBJ: HERE2");
-				for (int i = 0; i < argTypes.length; i++) {
-					arguments[i] = parseArgs(args[3 + i], argTypes[i]);
-					// System.out.println ("NEWOBJ: GOT ARG: " + arguments[i]);
-				}
+                if (matchingConstructorAndArgs == null) {
+                    write(reference,
+                            "Error: No suitable constructor with matching args found");
+                    return;
+                }
+
+                Object[] castedArgs = new Object[matchingConstructorAndArgs.length - 1];
+                for (int i = 0; i < castedArgs.length; i++) {
+                    castedArgs[i] = matchingConstructorAndArgs[i + 1];
+                }
 
-				final Object[] fArguments = arguments;
-				AccessControlContext acc = callContext != null ? callContext : getClosedAccessControlContext();
+                cons = (Constructor) matchingConstructorAndArgs[0];
+                fArguments = castedArgs;
 
-				Class c = (Class) store.getObject(classID);
+                String collapsedArgs = "";
+                for (Object arg : fArguments) {
+                    collapsedArgs += " " + arg.toString();
+                }
+
+                PluginDebug.debug("Calling constructor on class " + c + 
+                                   " with " + collapsedArgs);
+
+                AccessControlContext acc = callContext != null ? callContext : getClosedAccessControlContext();
 				checkPermission(src, c, acc);
 
 				Object ret = AccessController.doPrivileged(new PrivilegedAction<Object> () {
 					public Object run() {
 						try {
-							return m.newInstance(fArguments);
+							return cons.newInstance(fArguments);
 						} catch (Throwable t) {
 							return t;
 						}
@@ -1084,10 +1145,13 @@
 
 		PluginDebug.debug("target = " + target + " jsSrc=" + jsSrc + " classSrc=" + classSrcURL);
 		
+		// NPRuntime does not allow cross-site calling. The code below is kept 
+		// in case that changes in the future..
+		
 		// if src is not a file and class loader does not map to the same base, UniversalBrowserRead (BrowserReadPermission) must be set
-		if (!jsSrc.equals("file://") && !jsSrc.equals("[System]") && !classSrcURL.equals(jsSrcURL)) {
-			acc.checkPermission(new BrowserReadPermission());
-		}
+		//if (!jsSrc.equals("file://") && !jsSrc.equals("[System]") && !classSrcURL.equals(jsSrcURL)) {
+		//	acc.checkPermission(new BrowserReadPermission());
+		//}
 	}
 
 	private void write(int reference, String message) {
--- a/plugin/icedteanp/java/sun/applet/PluginAppletViewer.java	Wed Aug 26 01:14:21 2009 -0400
+++ b/plugin/icedteanp/java/sun/applet/PluginAppletViewer.java	Wed Aug 26 15:06:47 2009 -0400
@@ -581,7 +581,6 @@
 
              // Wait for the panel to initialize
              // (happens in a separate thread)
-             System.err.println("PANEL = " + panel);
              while (panel == null || ((o = panel.getApplet()) == null && ((NetxPanel) panel).isAlive())) {
             	 try {
             		 Thread.sleep(2000);
@@ -869,6 +868,8 @@
      public void showStatus(String status) {
  	try {
              // FIXME: change to postCallRequest
+ 		// For statuses, we cannot have a newline
+  	    status = status.replace("\n", " ");
  	    write("status " + status);
  	} catch (IOException exception) {
  	    // Deliberately ignore IOException.  showStatus may be
--- a/plugin/icedteanp/java/sun/applet/PluginCookieInfoRequest.java	Wed Aug 26 01:14:21 2009 -0400
+++ b/plugin/icedteanp/java/sun/applet/PluginCookieInfoRequest.java	Wed Aug 26 15:06:47 2009 -0400
@@ -37,12 +37,6 @@
 
 package sun.applet;
 
-import java.net.HttpCookie;
-import java.net.URI;
-import java.util.ArrayList;
-import java.util.List;
-
-import com.sun.jndi.toolkit.url.UrlUtil;
 
 /**
  * This class represents a request object for cookie information for a given URI
@@ -50,7 +44,7 @@
 
 public class PluginCookieInfoRequest extends PluginCallRequest {
 
-    List<HttpCookie> cookieObjects = new ArrayList<HttpCookie>();
+    String cookieString = new String();
 
     public PluginCookieInfoRequest(String message, String returnString) {
         super(message, returnString);
@@ -63,50 +57,11 @@
 
     	PluginDebug.debug ("PluginCookieInfoRequest GOT: " + cookieInfo);
 
-    	String encodedURI = cookieInfo.split(" ")[2];
-    	
     	// Skip the first 3 components. We are guaranteed 3 components, 
     	// so no index -1 to worry about
     	cookieInfo = cookieInfo.substring(cookieInfo.indexOf(' ')+1);
     	cookieInfo = cookieInfo.substring(cookieInfo.indexOf(' ')+1);
-    	cookieInfo = cookieInfo.substring(cookieInfo.indexOf(' ')+1);
-
-    	URI siteURI;
-    	try
-    	{
-    	    siteURI = new URI(UrlUtil.decode(encodedURI, "UTF-8"));
-    	} catch (Exception e)
-    	{
-    	    e.printStackTrace();
-    	    return;
-    	}
-
-    	if (cookieInfo != null && cookieInfo.length() > 0)
-    	{
-    	    String[] cookies = cookieInfo.split(";");
-
-    	    for (int i = 0; i < cookies.length; i++) 
-    	    {
-    	        ArrayList l = new ArrayList();
-
-    	        String cookie = cookies[i];
-    	        cookie = cookie.trim();
-    	        String cookieName; 
-    	        String cookieValue; 
-
-    	        if (cookie.indexOf("=") > 0) {
-    	            cookieName = cookie.substring(0, cookie.indexOf("="));
-    	            cookieValue = cookie.substring(cookie.indexOf("=")+1);
-
-    	            HttpCookie httpCookieObj = new HttpCookie(cookieName, cookieValue);
-    	            httpCookieObj.setPath(siteURI.getPath());
-    	            httpCookieObj.setVersion(0); // force v0
-
-    	            PluginDebug.debug("Adding cookie info COOKIEN=" + cookieName + " and COOKIEV=" + cookieValue);
-    	            cookieObjects.add(httpCookieObj);
-    	        }
-    	    }
-    	}
+    	cookieString = cookieInfo.substring(cookieInfo.indexOf(' ')+1);
 
         setDone(true);
     }
@@ -121,7 +76,7 @@
     	return message.startsWith(returnString);
     }
 
-    public List<HttpCookie> getObject() {
-    	return this.cookieObjects;
+    public String getObject() {
+    	return this.cookieString;
     }
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugin/icedteanp/java/sun/applet/PluginCookieManager.java	Wed Aug 26 15:06:47 2009 -0400
@@ -0,0 +1,88 @@
+/* PluginCookieManager -- Cookie manager for the plugin
+   Copyright (C) 2009  Red Hat
+
+This file is part of IcedTea.
+
+IcedTea is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2, or (at your option)
+any later version.
+
+IcedTea is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with IcedTea; see the file COPYING.  If not, write to the
+Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301 USA.
+
+Linking this library statically or dynamically with other modules is
+making a combined work based on this library.  Thus, the terms and
+conditions of the GNU General Public License cover the whole
+combination.
+
+As a special exception, the copyright holders of this library give you
+permission to link this library with independent modules to produce an
+executable, regardless of the license terms of these independent
+modules, and to copy and distribute the resulting executable under
+terms of your choice, provided that you also meet, for each linked
+independent module, the terms and conditions of the license of that
+module.  An independent module is a module which is not derived from
+or based on this library.  If you modify this library, you may extend
+this exception to your version of the library, but you are not
+obligated to do so.  If you do not wish to do so, delete this
+exception statement from your version. */
+
+package sun.applet;
+
+import java.io.IOException;
+import java.net.CookieManager;
+import java.net.HttpCookie;
+import java.net.URI;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+public class PluginCookieManager extends CookieManager 
+{
+    public Map<String, List<String>> get(URI uri,
+			Map<String, List<String>> requestHeaders) throws IOException {
+		// pre-condition check
+		if (uri == null || requestHeaders == null) {
+			throw new IllegalArgumentException("Argument is null");
+		}
+
+		Map<String, List<String>> cookieMap = new java.util.HashMap<String, List<String>>();
+
+		String cookies = (String) PluginAppletViewer
+				.requestPluginCookieInfo(uri);
+		List<String> cookieHeader = new java.util.ArrayList<String>();
+
+		if (cookies != null && cookies.length() > 0)
+			cookieHeader.add(cookies);
+		
+		// Add anything else that mozilla didn't add
+        for (HttpCookie cookie : getCookieStore().get(uri)) {
+            // apply path-matches rule (RFC 2965 sec. 3.3.4)
+            if (pathMatches(uri.getPath(), cookie.getPath())) {
+            	cookieHeader.add(cookie.toString());
+            }
+        }
+
+		cookieMap.put("Cookie", cookieHeader);
+		return Collections.unmodifiableMap(cookieMap);
+	}
+
+    private boolean pathMatches(String path, String pathToMatchWith) {
+        if (path == pathToMatchWith)
+            return true;
+        if (path == null || pathToMatchWith == null)
+            return false;
+        if (path.startsWith(pathToMatchWith))
+            return true;
+
+        return false;
+    }
+}
--- a/plugin/icedteanp/java/sun/applet/PluginCookieStore.java	Wed Aug 26 01:14:21 2009 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,73 +0,0 @@
-/* PluginCookieStore -- Storage for cookie information
-   Copyright (C) 2009  Red Hat
-
-This file is part of IcedTea.
-
-IcedTea is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
-any later version.
-
-IcedTea is distributed in the hope that it will be useful, but
-WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with IcedTea; see the file COPYING.  If not, write to the
-Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301 USA.
-
-Linking this library statically or dynamically with other modules is
-making a combined work based on this library.  Thus, the terms and
-conditions of the GNU General Public License cover the whole
-combination.
-
-As a special exception, the copyright holders of this library give you
-permission to link this library with independent modules to produce an
-executable, regardless of the license terms of these independent
-modules, and to copy and distribute the resulting executable under
-terms of your choice, provided that you also meet, for each linked
-independent module, the terms and conditions of the license of that
-module.  An independent module is a module which is not derived from
-or based on this library.  If you modify this library, you may extend
-this exception to your version of the library, but you are not
-obligated to do so.  If you do not wish to do so, delete this
-exception statement from your version. */
-
-package sun.applet;
-
-import java.net.HttpCookie;
-import java.net.URI;
-import java.util.List;
-
-import sun.net.www.protocol.http.InMemoryCookieStore;
-
-public class PluginCookieStore extends InMemoryCookieStore 
-{
-    public List<HttpCookie> get(URI uri)
-    {
-        List<HttpCookie> cookies;
-
-        // Try to fetch it from the plugin, but if something goes 
-        // wrong, fall back. Don't crash!
-        try
-        {
-            cookies = (List<HttpCookie>) PluginAppletViewer.requestPluginCookieInfo(uri);
-
-            // If cookies is null, something went wrong. Fall back.
-            if (cookies == null) throw new NullPointerException("Null cookie");
-
-        } catch (Exception e)
-        {
-            PluginDebug.debug("Unable to fetch cookie information from plugin. " +
-            		          "Falling back to default.");
-            e.printStackTrace();
-            cookies = super.get(uri);
-        }
-
-        PluginDebug.debug("Returning cookies " + cookies + " for site: " + uri);
-        
-        return cookies;
-    }
-}
--- a/plugin/icedteanp/java/sun/applet/PluginMain.java	Wed Aug 26 01:14:21 2009 -0400
+++ b/plugin/icedteanp/java/sun/applet/PluginMain.java	Wed Aug 26 15:06:47 2009 -0400
@@ -215,12 +215,12 @@
 		    System.err.println("Unable to set SSLSocketfactory (may _prevent_ access to sites that should be trusted)! Continuing anyway...");
 		    e.printStackTrace();
 		}
-        
+
 		// plug in a custom authenticator and proxy selector
         Authenticator.setDefault(new CustomAuthenticator());
         ProxySelector.setDefault(new PluginProxySelector());
         
-        CookieManager ckManager = new CookieManager(new PluginCookieStore(), null);
+        CookieManager ckManager = new PluginCookieManager();
         CookieHandler.setDefault(ckManager);
 	}