changeset 1066:358cb21c4730

More refactoring -- the last big one in the forseeable future. Implemented proper sandbox for liveconnect calls. Added error detection in the plugin, so it doesn't loop forever if Java side encounters an error.
author Deepak Bhole <dbhole@redhat.com>
date Wed, 01 Oct 2008 16:40:56 -0400
parents f4981f8a1720
children e41e54a1c0b0
files .hgignore ChangeLog IcedTeaPlugin.cc Makefile.am plugin/icedtea/org/classpath/icedtea/plugin/GetMemberPluginCallRequest.java plugin/icedtea/org/classpath/icedtea/plugin/GetWindowPluginCallRequest.java plugin/icedtea/org/classpath/icedtea/plugin/PluginAppletSecurityContext.java plugin/icedtea/org/classpath/icedtea/plugin/PluginCallRequestFactoryImpl.java plugin/icedtea/org/classpath/icedtea/plugin/PluginMain.java plugin/icedtea/org/classpath/icedtea/plugin/PluginMessageConsumer.java plugin/icedtea/org/classpath/icedtea/plugin/PluginMessageHandlerWorker.java plugin/icedtea/org/classpath/icedtea/plugin/PluginObjectStore.java plugin/icedtea/org/classpath/icedtea/plugin/PluginStreamHandlerImpl.java plugin/icedtea/org/classpath/icedtea/plugin/RequestQueue.java plugin/icedtea/org/classpath/icedtea/plugin/TestEnv.java plugin/icedtea/org/classpath/icedtea/plugin/VoidPluginCallRequest.java plugin/icedtea/sun/applet/AppletSecurityContext.java plugin/icedtea/sun/applet/AppletSecurityContextManager.java plugin/icedtea/sun/applet/GetMemberPluginCallRequest.java plugin/icedtea/sun/applet/GetWindowPluginCallRequest.java plugin/icedtea/sun/applet/PluginAppletSecurityContext.java plugin/icedtea/sun/applet/PluginCallRequestFactory.java plugin/icedtea/sun/applet/PluginMain.java plugin/icedtea/sun/applet/PluginMessageConsumer.java plugin/icedtea/sun/applet/PluginMessageHandlerWorker.java plugin/icedtea/sun/applet/PluginObjectStore.java plugin/icedtea/sun/applet/PluginStreamHandler.java plugin/icedtea/sun/applet/RequestQueue.java plugin/icedtea/sun/applet/TestEnv.java plugin/icedtea/sun/applet/VoidPluginCallRequest.java
diffstat 30 files changed, 2474 insertions(+), 2265 deletions(-) [+]
line wrap: on
line diff
--- a/.hgignore	Wed Oct 01 05:52:01 2008 -0400
+++ b/.hgignore	Wed Oct 01 16:40:56 2008 -0400
@@ -25,7 +25,6 @@
 gcjwebplugin.so
 IcedTeaPlugin.o
 IcedTeaPlugin.so
-IcedTeaPlugin.jar
 extra-source-files.txt
 rt-source-files.txt
 hotspot-tools-source-files.txt
--- a/ChangeLog	Wed Oct 01 05:52:01 2008 -0400
+++ b/ChangeLog	Wed Oct 01 16:40:56 2008 -0400
@@ -1,3 +1,47 @@
+2008-10-01	Deepak Bhole <dbhole@redhat.com>
+	* .hgignore: Removed IcedTeaPlugin.jar
+	* IcedTeaPlugin.cc: Updated classpath when launching Java. added checks to
+	detect error on Java side.
+	* Makefile.am: Updated to fit new refactored files.
+	* plugin/icedtea/sun/applet/AppletSecurityContextManager.java: New file,
+	moved out of org/classpath/icedtea/plugin/, as a result of refactoring.
+	* plugin/icedtea/sun/applet/PluginCallRequestFactory.java: Same.
+	* plugin/icedtea/sun/applet/PluginStreamHandler.java: Same.
+	* plugin/icedtea/sun/applet/GetMemberPluginCallRequest.java: Same.
+	* plugin/icedtea/sun/applet/GetWindowPluginCallRequest.java: Same.
+	* plugin/icedtea/sun/applet/PluginAppletSecurityContext.java: Same.
+	* plugin/icedtea/sun/applet/PluginMain.java: Same.
+	* plugin/icedtea/sun/applet/PluginMessageConsumer.java: Same.
+	* plugin/icedtea/sun/applet/PluginMessageHandlerWorker.java: Same.
+	* plugin/icedtea/sun/applet/PluginObjectStore.java: Same.
+	* plugin/icedtea/sun/applet/RequestQueue.java: Same.
+	* plugin/icedtea/sun/applet/TestEnv.java: Same.
+	* plugin/icedtea/sun/applet/VoidPluginCallRequest.java: Same.
+	* plugin/icedtea/org/classpath/icedtea/plugin/GetMemberPluginCallRequest.java: 
+	Removed, as a result of refactoring.
+	* plugin/icedtea/org/classpath/icedtea/plugin/GetWindowPluginCallRequest.java:
+	Same.
+	*plugin/icedtea/org/classpath/icedtea/plugin/PluginAppletSecurityContext.java:
+	Same.
+	* plugin/icedtea/org/classpath/icedtea/plugin/PluginCallRequestFactoryImpl.java:
+	Same.
+	* plugin/icedtea/org/classpath/icedtea/plugin/PluginMain.java: Same.
+	* plugin/icedtea/org/classpath/icedtea/plugin/PluginMessageConsumer.java:
+	Same.
+	*
+	plugin/icedtea/org/classpath/icedtea/plugin/PluginMessageHandlerWorker.java:
+	Same.
+	* plugin/icedtea/org/classpath/icedtea/plugin/PluginObjectStore.java:
+	Same.
+	*
+	plugin/icedtea/org/classpath/icedtea/plugin/PluginStreamHandlerImpl.java:
+	Same.
+	* plugin/icedtea/org/classpath/icedtea/plugin/RequestQueue.java: Same.
+	* plugin/icedtea/org/classpath/icedtea/plugin/TestEnv.java: Same.
+	* plugin/icedtea/org/classpath/icedtea/plugin/VoidPluginCallRequest.java:
+	Same.
+	* plugin/icedtea/sun/applet/AppletSecurityContext.java: Same.
+
 2008-10-01  Gary Benson  <gbenson@redhat.com>
 
 	* ports/hotspot/src/share/vm/shark/sharkState.cpp: Remove a
--- a/IcedTeaPlugin.cc	Wed Oct 01 05:52:01 2008 -0400
+++ b/IcedTeaPlugin.cc	Wed Oct 01 16:40:56 2008 -0400
@@ -244,7 +244,6 @@
 static GError* channel_error = NULL;
 // Fully-qualified appletviewer executable.
 static char* appletviewer_executable = NULL;
-static char* extra_jars = NULL;
 static char* libjvm_so = NULL;
 
 class IcedTeaPluginFactory;
@@ -317,8 +316,6 @@
   char context[16]; \
   GetCurrentPageAddress(&addr); \
   GetCurrentContextAddr(context); \
-  printf("Addr: %s , Context: %s\n", addr, context);\
-\
   nsCString message ("context ");                            \
   message.AppendInt (0);                                     \
   message += " reference ";                                  \
@@ -428,12 +425,14 @@
 #define MESSAGE_RECEIVE_REFERENCE(reference, cast, name)                \
   nsresult res = NS_OK;                                                 \
   printf ("RECEIVE 1\n");                                               \
-  while (factory->result_map[reference]->returnIdentifier == -1)     \
+  while (factory->result_map[reference]->returnIdentifier == -1 &&\
+	     factory->result_map[reference]->errorOccured == PR_FALSE)     \
     {                                                                   \
       PROCESS_PENDING_EVENTS_REF (reference);                                \
     }                                                                   \
   printf ("RECEIVE 3\n"); \
-  if (factory->result_map[reference]->returnIdentifier == 0) \
+  if (factory->result_map[reference]->returnIdentifier == 0 || \
+	  factory->result_map[reference]->errorOccured == PR_TRUE) \
   {  \
 	  *name = NULL;                                                     \
   } else {                                                              \
@@ -449,25 +448,33 @@
   PRBool processed = PR_FALSE;                                          \
   nsresult res = NS_OK;                                                 \
   printf("RECEIVE ID 1\n");                                             \
-  while (factory->result_map[reference]->returnIdentifier == -1)     \
+  while (factory->result_map[reference]->returnIdentifier == -1 &&\
+	     factory->result_map[reference]->errorOccured == PR_FALSE)     \
     {                                                                   \
       PROCESS_PENDING_EVENTS_REF (reference);                                \
     }                                                                   \
                                                                         \
+  if (factory->result_map[reference]->errorOccured == PR_TRUE)	 	    \
+  { \
+	  *id = NULL; \
+  } else \
+  { \
   *id = reinterpret_cast<cast>                                  \
     (new JNIID (factory->result_map[reference]->returnIdentifier, signature));         \
    printf ("RECEIVE_ID: %s result: %x = %d, %s\n",               \
            __func__, *id, factory->result_map[reference]->returnIdentifier,             \
-           signature);
+           signature); \
+  }
 
 #define MESSAGE_RECEIVE_VALUE(reference, ctype, result)                    \
   nsresult res = NS_OK;                                                    \
   printf("RECEIVE VALUE 1\n");                                             \
-  while (factory->result_map[reference]->returnValue == "")            \
+  while (factory->result_map[reference]->returnValue == "" && \
+	     factory->result_map[reference]->errorOccured == PR_FALSE)            \
     {                                                                      \
       PROCESS_PENDING_EVENTS_REF (reference);                                   \
     }                                                                      \
-  *result = ParseValue (type, factory->result_map[reference]->returnValue);            
+    *result = ParseValue (type, factory->result_map[reference]->returnValue);            
 // \
 //   char* valueString = ValueString (type, *result);              \
 //   printf ("RECEIVE_VALUE: %s result: %x = %s\n",                \
@@ -479,13 +486,19 @@
   PRBool processed = PR_FALSE;                                  \
   nsresult res = NS_OK;                                         \
   printf("RECEIVE SIZE 1\n");                                 \
-  while (factory->result_map[reference]->returnValue == "")                        \
+  while (factory->result_map[reference]->returnValue == "" && \
+	     factory->result_map[reference]->errorOccured == PR_FALSE) \
     {                                                           \
       PROCESS_PENDING_EVENTS_REF (reference);                        \
     }                                                           \
   nsresult conversionResult;                                    \
-  *result = factory->result_map[reference]->returnValue.ToInteger (&conversionResult); \
-  PLUGIN_CHECK ("parse integer", conversionResult);             
+  if (factory->result_map[reference]->errorOccured == PR_TRUE) \
+	*result = NULL; \
+  else \
+  { \
+    *result = factory->result_map[reference]->returnValue.ToInteger (&conversionResult); \
+    PLUGIN_CHECK ("parse integer", conversionResult);             \
+  }
 // \
 //   printf ("RECEIVE_SIZE: %s result: %x = %d\n",                 \
 //           __func__, result, *result);
@@ -495,13 +508,19 @@
   PRBool processed = PR_FALSE;                                  \
   nsresult res = NS_OK;                                         \
   printf("RECEIVE STRING 1\n");                                 \
-  while (factory->result_map[reference]->returnValue == "")                            \
+  while (factory->result_map[reference]->returnValue == "" && \
+	     factory->result_map[reference]->errorOccured == PR_FALSE)  \
     {                                                           \
       PROCESS_PENDING_EVENTS_REF (reference);                        \
     }                                                           \
-	printf("Setting result to: %s\n", strdup (factory->result_map[reference]->returnValue.get ())); \
-  *result = reinterpret_cast<char_type const*>                  \
-    (strdup (factory->result_map[reference]->returnValue.get ()));                     
+	if (factory->result_map[reference]->errorOccured == PR_TRUE) \
+		*result = NULL; \
+	else \
+	{\
+	  printf("Setting result to: %s\n", strdup (factory->result_map[reference]->returnValue.get ())); \
+      *result = reinterpret_cast<char_type const*>                  \
+                (strdup (factory->result_map[reference]->returnValue.get ()));\
+	}
 // \
 //   printf ("RECEIVE_STRING: %s result: %x = %s\n",               \
 //           __func__, result, *result);
@@ -511,16 +530,22 @@
   PRBool processed = PR_FALSE;                                  \
   nsresult res = NS_OK;                                         \
   printf("RECEIVE STRING UCS 1\n");                                 \
-  while (factory->result_map[reference]->returnValueUCS.IsEmpty())                        \
+  while (factory->result_map[reference]->returnValueUCS.IsEmpty() && \
+	     factory->result_map[reference]->errorOccured == PR_FALSE) \
     {                                                           \
       PROCESS_PENDING_EVENTS_REF (reference);                        \
     }                                                           \
-  int length = factory->result_map[reference]->returnValueUCS.Length ();               \
-  jchar* newstring = static_cast<jchar*> (PR_Malloc (length));  \
-  memset (newstring, 0, length);                                \
-  memcpy (newstring, factory->result_map[reference]->returnValueUCS.get (), length);   \
-  std::cout << "Setting result to: " << factory->result_map[reference]->returnValueUCS.get() << std::endl; \
-  *result = static_cast<jchar const*> (newstring);
+	if (factory->result_map[reference]->errorOccured == PR_TRUE) \
+		*result = NULL; \
+	else \
+	{ \
+	  int length = factory->result_map[reference]->returnValueUCS.Length ();               \
+	  jchar* newstring = static_cast<jchar*> (PR_Malloc (length));  \
+	  memset (newstring, 0, length);                                \
+	  memcpy (newstring, factory->result_map[reference]->returnValueUCS.get (), length);   \
+	  std::cout << "Setting result to: " << factory->result_map[reference]->returnValueUCS.get() << std::endl; \
+	  *result = static_cast<jchar const*> (newstring); \
+	}
 
 // \
 //   printf ("RECEIVE_STRING: %s result: %x = %s\n",               \
@@ -530,11 +555,15 @@
   PRBool processed = PR_FALSE;                                  \
   nsresult res = NS_OK;                                         \
   printf("RECEIVE BOOLEAN 1\n");                             \
-  while (factory->result_map[reference]->returnIdentifier == -1)               \
+  while (factory->result_map[reference]->returnIdentifier == -1 && \
+	     factory->result_map[reference]->errorOccured == PR_FALSE)               \
     {                                                           \
       PROCESS_PENDING_EVENTS_REF (reference);                        \
     }                                                           \
-  *result = factory->result_map[reference]->returnIdentifier;
+	if (factory->result_map[reference]->errorOccured == PR_TRUE) \
+		*result = NULL; \
+	else \
+	  *result = factory->result_map[reference]->returnIdentifier;
 //      res = factory->current->ProcessNextEvent (PR_TRUE,        \
 //                                                &processed);    \
 //      PLUGIN_CHECK_RETURN (__func__, res);                      \
@@ -1225,10 +1254,58 @@
 template <class T> NS_IMETHODIMP
 IcedTeaRunnableMethod<T>::Run ()
 {
-  (object->*method) ();
-  return NS_OK;
+    (object->*method) ();
+    return NS_OK;
 }
 
+
+// FIXME: Special class just for dispatching GetURL to another 
+// thread.. seriously, a class just for that? there has to be a better way!
+
+class GetURLRunnable : public nsIRunnable
+{
+public:
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIRUNNABLE
+
+  GetURLRunnable (nsIPluginInstancePeer* peer, const char* url, const char* target);
+
+  ~GetURLRunnable ();
+
+private:
+  nsIPluginInstancePeer* peer;
+  const char* url;
+  const char* target;
+};
+
+NS_IMPL_ISUPPORTS1 (GetURLRunnable, nsIRunnable)
+
+GetURLRunnable::GetURLRunnable (nsIPluginInstancePeer* peer, const char* url, const char* target)
+: peer(peer),
+  url(url),
+  target(target)
+{
+    NS_ADDREF (peer);
+}
+
+GetURLRunnable::~GetURLRunnable ()
+{
+  NS_RELEASE(peer);
+}
+
+NS_IMETHODIMP
+GetURLRunnable::Run ()
+{
+   nsCOMPtr<nsPIPluginInstancePeer> ownerGetter =
+                do_QueryInterface (peer);
+   nsIPluginInstanceOwner* owner = nsnull;
+   ownerGetter->GetOwner (&owner);
+
+   return owner->GetURL ((const char*) url, (const char*) target,
+                         nsnull, 0, nsnull, 0);
+}
+
+
 NS_IMPL_ISUPPORTS6 (IcedTeaPluginFactory, nsIFactory, nsIPlugin, nsIJVMManager,
                     nsIJVMPrefsWindow, nsIJVMPlugin, nsIInputStreamCallback)
 
@@ -2433,6 +2510,11 @@
   return NS_OK;
 }
 
+#include <nsIWebNavigation.h>
+#include <nsServiceManagerUtils.h>
+#include <nsIExternalProtocolService.h>
+#include <nsNetUtil.h>
+
 void
 IcedTeaPluginFactory::HandleMessage (nsCString const& message)
 {
@@ -2477,8 +2559,11 @@
         {
           IcedTeaPluginInstance* instance = NULL;
           instances.Get (identifier, &instance);
-//          if (instance != 0)
-//            instance->peer->ShowStatus (nsCString (rest).get ());
+          if (instance != 0)
+		  {
+            instance->peer->ShowStatus (nsCString (rest).get ());
+
+          }
         }
       else if (command == "initialized")
         {
@@ -2504,9 +2589,10 @@
               nsIPluginInstanceOwner* owner = nsnull;
               ownerGetter->GetOwner (&owner);
 			  printf("Calling GetURL with %s and %s\n", nsCString (url).get (), nsCString (target).get ());
-              owner->GetURL (nsCString (url).get (),
-                             nsCString (target).get (),
-                             nsnull, 0, nsnull, 0);
+              nsCOMPtr<nsIRunnable> event = new GetURLRunnable (instance->peer,
+													 nsCString (url).get (),
+													 nsCString (target).get ());
+              current->Dispatch(event, nsIEventTarget::DISPATCH_NORMAL);
             }
         }
       else if (command == "GetWindow")
@@ -2841,20 +2927,47 @@
 void IcedTeaPluginFactory::ProcessMessage ()
 {
 	while (true) {
-		printf("Process thread sleeping...\n");
-		PR_Sleep(PR_INTERVAL_NO_TIMEOUT);
+		PR_Sleep(1000);
+
+		// If there was an interrupt, clear it
 		PR_ClearInterrupt();
 
-		printf("Process thread interrupted...\n");
-
-
 		// Was I interrupted for shutting down?
 		if (shutting_down == PR_TRUE) {
 			break;
 		}
 
-		ConsumeMsgFromJVM();
+		// Nope. Ok, is there work to do?
+		if (!jvmMsgQueue.empty())
+		    ConsumeMsgFromJVM();
+
+		// All done. Now let's process pending events
+
+		// Were there new events dispatched?
+		
+		PRBool this_has_pending, curr_has_pending, processed = PR_FALSE;
+		PRBool continue_processing = PR_TRUE;
+
+		while (continue_processing == PR_TRUE) {
+
+		  processThread->HasPendingEvents(&this_has_pending);
+		  if (this_has_pending == PR_TRUE) {
+			  processThread->ProcessNextEvent(PR_TRUE, &processed);
+			  printf("Pending event processed (this) ... %d\n", processed);
+		  }
+
+		  current->HasPendingEvents(&curr_has_pending);
+		  if (curr_has_pending == PR_TRUE) {
+			  current->ProcessNextEvent(PR_TRUE, &processed);
+			  printf("Pending event processed (current) ... %d\n", processed);
+		  }
+
+		  if (this_has_pending != PR_TRUE && curr_has_pending != PR_TRUE) {
+			  continue_processing = PR_FALSE;
+		  }
+		}
 	}
+
 }
 
 void IcedTeaPluginFactory::ConsumeMsgFromJVM ()
@@ -2872,10 +2985,8 @@
 		HandleMessage (message);
 		printf("Processing complete\n");
 	}
-
 }
 
-
 /**
  *
  * JNI I/O code
@@ -3189,9 +3300,9 @@
   PLUGIN_CHECK_RETURN ("init process", result);
 
   // FIXME: hard-coded port number.
-  char const* args[8] = { "-classpath", extra_jars, "-Xdebug", "-Xnoagent", "-Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=n", "org.classpath.icedtea.plugin.PluginMain", "50007" };
+  char const* args[5] = { "-Xdebug", "-Xnoagent", "-Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=n", "sun.applet.PluginMain", "50007" };
 //  char const* args[2] = { "sun.applet.PluginMain", "50007" };
-  result = applet_viewer_process->Run (PR_FALSE, args, 8, nsnull);
+  result = applet_viewer_process->Run (PR_FALSE, args, 5, nsnull);
   PLUGIN_CHECK_RETURN ("run process", result);
 
   // start processing thread
@@ -3812,6 +3923,7 @@
 nsresult
 IcedTeaJNIEnv::GetCurrentContextAddr(char *addr)
 {
+	return NS_OK;
     PLUGIN_TRACE_JNIENV ();
 
     // Get JSContext from stack.
@@ -3835,7 +3947,7 @@
 nsresult
 IcedTeaJNIEnv::GetCurrentPageAddress(const char **addr)
 {
-
+	return NS_OK;
     PLUGIN_TRACE_JNIENV ();
 
     nsIPrincipal *prin;
@@ -4922,17 +5034,11 @@
 
   //executableString += nsCString ("/../../bin/pluginappletviewer");
   executable += nsCString ("/../../bin/java");
-  extrajars += jar;
-  extrajars += nsCString("/IcedTeaPlugin.jar");
-  extrajars += ":";
-  extrajars += jar;
-  extrajars += nsCString("/rt.jar");
 
   //executable += nsCString ("/client/libjvm.so");
 
   // Never freed.
   appletviewer_executable = strdup (executable.get ());
-  extra_jars = strdup (extrajars.get ());
   //libjvm_so = strdup (executable.get ());
   if (!appletviewer_executable)
     {
@@ -4940,12 +5046,6 @@
       return NS_ERROR_OUT_OF_MEMORY;
     }
 
-  if (!extra_jars)
-    {
-      PLUGIN_ERROR ("Failed to create plugin jar name.");
-      return NS_ERROR_OUT_OF_MEMORY;
-    }
-
   if (factory_created == PR_TRUE)
   {
 	  // wait for factory to initialize
--- a/Makefile.am	Wed Oct 01 05:52:01 2008 -0400
+++ b/Makefile.am	Wed Oct 01 16:40:56 2008 -0400
@@ -12,13 +12,11 @@
 if ENABLE_LIVECONNECT
 ICEDTEAPLUGIN_CLEAN = clean-IcedTeaPlugin
 ICEDTEAPLUGIN_TARGET = IcedTeaPlugin.so
-ICEDTEAPLUGIN_JAR = IcedTeaPlugin.jar
 PLUGIN_PATCH = patches/icedtea-liveconnect.patch
 LIVECONNECT = $(abs_top_srcdir)/plugin/icedtea/
 else
 ICEDTEAPLUGIN_CLEAN =
 ICEDTEAPLUGIN_TARGET =
-ICEDTEAPLUGIN_JAR =
 PLUGIN_PATCH = patches/icedtea-plugin.patch
 LIVECONNECT = 
 if ENABLE_PLUGIN
@@ -48,7 +46,6 @@
 	rm -rf hotspot-tools
 if ENABLE_LIVECONNECT
 	rm -f IcedTeaPlugin.so
-	rm -rf IcedTeaPlugin.jar
 else
 if ENABLE_PLUGIN
 	rm -f gcjwebplugin.so
@@ -597,6 +594,7 @@
 	fi
 if ENABLE_LIVECONNECT
 	cp -a plugin/icedtea/sun/applet/*java openjdk/jdk/src/share/classes/sun/applet/
+	cp -a plugin/icedtea/netscape openjdk/jdk/src/share/classes/
 endif
 
 clean-patch:
@@ -616,6 +614,7 @@
 	if ! test x$${all_patches_ok} = "xyes" ; then \
 	  echo "WARNING Not all patches reverted cleanly" ; \
 	fi
+	rm -rf openjdk/jdk/src/share/classes/netscape
 	for file in plugin/icedtea/sun/applet/*java ; \
 	do \
 		rm -f openjdk/jdk/src/share/classes/sun/applet/`basename $file` ; \
@@ -911,7 +910,7 @@
 stamps/icedtea.stamp: stamps/bootstrap-directory-symlink.stamp \
 	stamps/hotspot-tools.stamp stamps/plugs.stamp \
 	stamps/ports.stamp stamps/patch.stamp stamps/overlay.stamp \
-	$(GCJWEBPLUGIN_TARGET) $(ICEDTEAPLUGIN_TARGET) $(ICEDTEAPLUGIN_JAR) \
+	$(GCJWEBPLUGIN_TARGET) $(ICEDTEAPLUGIN_TARGET) \
 	extra-lib/about.jar stamps/cacao.stamp stamps/visualvm.stamp
 	$(MAKE) \
 	  $(ICEDTEA_ENV) \
@@ -922,10 +921,6 @@
 	  $(BUILD_OUTPUT_DIR)/j2sdk-image/jre/lib/$(INSTALL_ARCH_DIR)
 	cp -pPRf IcedTeaPlugin.so \
 	  $(BUILD_OUTPUT_DIR)/j2re-image/lib/$(INSTALL_ARCH_DIR)
-	cp -pPRf IcedTeaPlugin.jar \
-	  $(BUILD_OUTPUT_DIR)/j2sdk-image/jre/lib/
-	cp -pPRf IcedTeaPlugin.jar \
-	  $(BUILD_OUTPUT_DIR)/j2re-image/lib/
 else
 if ENABLE_PLUGIN
 	cp -pPRf gcjwebplugin.so \
@@ -966,7 +961,7 @@
 stamps/icedtea-debug.stamp: stamps/bootstrap-directory-symlink.stamp \
 	stamps/hotspot-tools.stamp stamps/plugs.stamp \
 	stamps/ports.stamp stamps/patch.stamp stamps/overlay.stamp \
-	$(GCJWEBPLUGIN_TARGET) $(ICEDTEAPLUGIN_TARGET) $(ICEDTEAPLUGIN_JAR) \
+	$(GCJWEBPLUGIN_TARGET) $(ICEDTEAPLUGIN_TARGET) \
 	extra-lib/about.jar stamps/cacao.stamp
 	$(MAKE) \
 	  $(ICEDTEA_ENV) \
@@ -977,10 +972,6 @@
 	  $(BUILD_OUTPUT_DIR)-debug/j2sdk-image/jre/lib/$(INSTALL_ARCH_DIR)
 	cp -pPRf IcedTeaPlugin.so \
 	  $(BUILD_OUTPUT_DIR)-debug/j2re-image/lib/$(INSTALL_ARCH_DIR)
-	cp -pPRf IcedTeaPlugin.jar \
-	  $(BUILD_OUTPUT_DIR)-debug/j2sdk-image/jre/lib/
-	cp -pPRf IcedTeaPlugin.jar \
-	  $(BUILD_OUTPUT_DIR)-debug/j2re-image/lib/
 else
 if ENABLE_PLUGIN
 	cp -pPRf gcjwebplugin.so \
@@ -1334,20 +1325,6 @@
 	  $(XULRUNNER_LIBS) \
 	  -shared -o $@
 
-# icedtea plugin jar for java-side classes
-IcedTeaPlugin.jar:
-	mkdir -p $(BUILD_OUTPUT_DIR)/plugin/icedtea/classes
-	(cd plugin/icedtea/; \
-	  $(ICEDTEA_BOOT_DIR)/bin/javac -g \
-	  -d ../../$(BUILD_OUTPUT_DIR)/plugin/icedtea/classes \
-	  -bootclasspath $(ICEDTEA_BOOT_DIR)/jre/lib/rt.jar \
-	  netscape/javascript/*.java org/classpath/icedtea/plugin/*.java \
-	)
-
-	$(JAR) cf $@ \
-	-C $(BUILD_OUTPUT_DIR)/plugin/icedtea/classes org/classpath/icedtea/plugin \
-	-C $(BUILD_OUTPUT_DIR)/plugin/icedtea/classes netscape/javascript
-
 clean-IcedTeaPlugin:
 	rm -f IcedTeaPlugin.o
 	rm -f IcedTeaPlugin.so
--- a/plugin/icedtea/org/classpath/icedtea/plugin/GetMemberPluginCallRequest.java	Wed Oct 01 05:52:01 2008 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,78 +0,0 @@
-/* GetMemberPluginCallRequest -- represent Java-to-JavaScript requests
-   Copyright (C) 2008  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 org.classpath.icedtea.plugin;
-
-import sun.applet.AppletSecurityContextManager;
-import sun.applet.PluginCallRequest;
-
-public class GetMemberPluginCallRequest extends PluginCallRequest {
-    Object object = null;
-
-    public GetMemberPluginCallRequest(String message, String returnString) {
-        super(message, returnString);
-        System.out.println ("GetMEMBerPLUGINCAlL " + message + " " + returnString);
-    }
-
-    public void parseReturn(String message) {
-        System.out.println ("GetMEMBerparseReturn GOT: " + message);
-        String[] args = message.split(" ");
-        // FIXME: add thread ID to messages to support multiple
-        // threads using the netscape.javascript package.
-        object = AppletSecurityContextManager.getSecurityContext(0).getObject(Integer.parseInt(args[1]));
-        setDone(true);
-    }
-
-    /**
-     * Returns whether the given message is serviceable by this object
-     * 
-     * @param message The message to service
-     * @return boolean indicating if message is serviceable
-     */
-    public boolean serviceable(String message) {
-    	return message.contains("JavaScriptCall") ||
-    			message.contains("JavaScriptEval") ||
-    			message.contains("JavaScriptGetMember") ||
-    			message.contains("JavaScriptGetSlot") ||
-    			message.contains("JavaScriptToString");
-    }
-    
-    public Object getObject() {
-    	return this.object;
-    }
-}
-
--- a/plugin/icedtea/org/classpath/icedtea/plugin/GetWindowPluginCallRequest.java	Wed Oct 01 05:52:01 2008 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +0,0 @@
-/* GetWindowPluginCallRequest -- represent Java-to-JavaScript requests
-   Copyright (C) 2008  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 org.classpath.icedtea.plugin;
-
-import java.security.AccessControlContext;
-import java.security.ProtectionDomain;
-
-import sun.applet.PluginCallRequest;
-
-
-public class GetWindowPluginCallRequest extends PluginCallRequest {
-    // FIXME: look into int vs long JavaScript internal values.
-    int internal;
-
-    public GetWindowPluginCallRequest(String message, String returnString) {
-        super(message, returnString);
-    }
-
-    public void parseReturn(String message) {
-        System.out.println ("GetWINDOWparseReturn GOT: " + message);
-        String[] args = message.split(" ");
-        // FIXME: add thread ID to messages to support multiple
-        // threads using the netscape.javascript package.
-        internal = Integer.parseInt(args[1]);
-        setDone(true);
-    }
-    
-    /**
-     * Returns whether the given message is serviceable by this object
-     * 
-     * @param message The message to service
-     * @return boolean indicating if message is serviceable
-     */
-    public boolean serviceable(String message) {
-    	return message.contains("JavaScriptGetWindow");
-    }
-
-    public Integer getObject() {
-    	return this.internal;
-    }
-}
--- a/plugin/icedtea/org/classpath/icedtea/plugin/PluginAppletSecurityContext.java	Wed Oct 01 05:52:01 2008 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,855 +0,0 @@
-/* PluginAppletSecurityContext -- execute plugin JNI messages
-   Copyright (C) 2008  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 org.classpath.icedtea.plugin;
-
-import java.io.FilePermission;
-import java.lang.reflect.Array;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.StringTokenizer;
-
-import sun.applet.AppletSecurityContext;
-import sun.applet.PluginDebug;
-import sun.applet.PluginException;
-
-
-class Signature {
-	private String signature;
-	private int currentIndex;
-	private List<Class> typeList;
-	private static final char ARRAY = '[';
-	private static final char OBJECT = 'L';
-	private static final char SIGNATURE_ENDCLASS = ';';
-	private static final char SIGNATURE_FUNC = '(';
-	private static final char SIGNATURE_ENDFUNC = ')';
-	private static final char VOID = 'V';
-	private static final char BOOLEAN = 'Z';
-	private static final char BYTE = 'B';
-	private static final char CHARACTER = 'C';
-	private static final char SHORT = 'S';
-	private static final char INTEGER = 'I';
-	private static final char LONG = 'J';
-	private static final char FLOAT = 'F';
-	private static final char DOUBLE = 'D';
-
-	private String nextTypeName() {
-		char key = signature.charAt(currentIndex++);
-
-		switch (key) {
-		case ARRAY:
-			return nextTypeName() + "[]";
-
-		case OBJECT:
-			int endClass = signature.indexOf(SIGNATURE_ENDCLASS, currentIndex);
-			String retVal = signature.substring(currentIndex, endClass);
-			retVal = retVal.replace('/', '.');
-			currentIndex = endClass + 1;
-			return retVal;
-
-			// FIXME: generated bytecode with classes named after
-			// primitives will not work in this scheme -- those
-			// classes will be incorrectly treated as primitive
-			// types.
-		case VOID:
-			return "void";
-		case BOOLEAN:
-			return "boolean";
-		case BYTE:
-			return "byte";
-		case CHARACTER:
-			return "char";
-		case SHORT:
-			return "short";
-		case INTEGER:
-			return "int";
-		case LONG:
-			return "long";
-		case FLOAT:
-			return "float";
-		case DOUBLE:
-			return "double";
-
-		case SIGNATURE_ENDFUNC:
-		case SIGNATURE_FUNC:
-			return nextTypeName();
-
-		default:
-			throw new IllegalArgumentException(
-					"Invalid JNI signature character '" + key + "'");
-		}
-	}
-
-	public Signature(String signature, String src) {
-		this.signature = signature;
-		currentIndex = 0;
-		typeList = new ArrayList<Class>(10);
-
-		String elem;
-		while (currentIndex < signature.length()) {
-			elem = nextTypeName();
-			// System.out.println ("NEXT TYPE: " + elem);
-			Class primitive = primitiveNameToType(elem);
-			if (primitive != null)
-				typeList.add(primitive);
-			else {
-				// System.out.println ("HERE1");
-				int dimsize = 0;
-				int n = elem.indexOf('[');
-				if (n != -1) {
-					// System.out.println ("HERE2");
-					String arrayType = elem.substring(0, n);
-					dimsize++;
-					n = elem.indexOf('[', n + 1);
-					// System.out.println ("HERE2.5");
-					while (n != -1) {
-						dimsize++;
-						n = elem.indexOf('[', n + 1);
-						// System.out.println ("HERE2.8");
-					}
-					int[] dims = new int[dimsize];
-					primitive = primitiveNameToType(arrayType);
-					// System.out.println ("HERE3");
-					if (primitive != null) {
-						typeList.add(Array.newInstance(primitive, dims)
-								.getClass());
-						// System.out.println ("HERE4");
-					} else
-						typeList.add(Array.newInstance(
-								getClass(arrayType, src), dims).getClass());
-				} else {
-					typeList.add(getClass(elem, src));
-				}
-			}
-		}
-		if (typeList.size() == 0) {
-			throw new IllegalArgumentException("Invalid JNI signature '"
-					+ signature + "'");
-		}
-	}
-
-	public static Class getClass(String name, String src) {
-
-		Class c = null;
-		
-		try {
-			c = Class.forName(name);
-		} catch (ClassNotFoundException cnfe) {
-
-			StringTokenizer st = new StringTokenizer(src, ",");
-
-			while (st.hasMoreTokens()) {
-
-				String tok = st.nextToken();
-				System.err.println("Searching for " + name  + " at key " + tok);
-
-				try {
-					c = PluginAppletSecurityContext.classLoaders.get(tok).loadClass(name);
-				} catch (ClassNotFoundException e) {
-					// do nothing .. thrown below
-				}
-
-				if (c != null)
-					break;
-			}
-		}
-
-		if (c == null) {
-			throw (new RuntimeException(new ClassNotFoundException("Unable to find class " + name)));
-		}
-
-		return c;
-	}
-	
-	public static Class primitiveNameToType(String name) {
-		if (name.equals("void"))
-			return Void.TYPE;
-		else if (name.equals("boolean"))
-			return Boolean.TYPE;
-		else if (name.equals("byte"))
-			return Byte.TYPE;
-		else if (name.equals("char"))
-			return Character.TYPE;
-		else if (name.equals("short"))
-			return Short.TYPE;
-		else if (name.equals("int"))
-			return Integer.TYPE;
-		else if (name.equals("long"))
-			return Long.TYPE;
-		else if (name.equals("float"))
-			return Float.TYPE;
-		else if (name.equals("double"))
-			return Double.TYPE;
-		else
-			return null;
-	}
-
-	public Class[] getClassArray() {
-		return typeList.subList(0, typeList.size() - 1).toArray(new Class[] {});
-	}
-}
-
-public class PluginAppletSecurityContext extends AppletSecurityContext {
-	
-	public static HashMap<String, ClassLoader> classLoaders = new HashMap<String, ClassLoader>();
-
-	// FIXME: make private
-	public PluginObjectStore store = new PluginObjectStore();
-	private Throwable throwable = null;
-	private ClassLoader liveconnectLoader = ClassLoader.getSystemClassLoader();
-	int identifier = 0;
-
-	public PluginAppletSecurityContext(int identifier) {
-		this.identifier = identifier;
-	}
-
-	private static <V> V parseCall(String s, String src, Class<V> c) {
-		if (c == Integer.class)
-			return (V) new Integer(s);
-		else if (c == String.class)
-			return (V) new String(s);
-		else if (c == Signature.class)
-			return (V) new Signature(s, src);
-		else
-			throw new RuntimeException("Unexpected call value.");
-	}
-
-	private Object parseArgs(String s, Class c) {
-		if (c == Boolean.TYPE || c == Boolean.class)
-			return new Boolean(s);
-		else if (c == Byte.TYPE || c == Byte.class)
-			return new Byte(s);
-		else if (c == Character.TYPE || c == Character.class) {
-			String[] bytes = s.split("_");
-			int low = Integer.parseInt(bytes[0]);
-			int high = Integer.parseInt(bytes[1]);
-			int full = ((high << 8) & 0x0ff00) | (low & 0x0ff);
-			return new Character((char) full);
-		} else if (c == Short.TYPE || c == Short.class)
-			return new Short(s);
-		else if (c == Integer.TYPE || c == Integer.class)
-			return new Integer(s);
-		else if (c == Long.TYPE || c == Long.class)
-			return new Long(s);
-		else if (c == Float.TYPE || c == Float.class)
-			return new Float(s);
-		else if (c == Double.TYPE || c == Double.class)
-			return new Double(s);
-		else
-			return store.getObject(new Integer(s));
-	}
-
-	public void addClassLoader(String id, ClassLoader cl) {
-		this.classLoaders.put(id, cl);
-	}
-	
-	public void handleMessage(String src, int reference, String message) {
-
-		try {
-			if (message.startsWith("FindClass")) {
-				ClassLoader cl = null;
-				Class c = null;
-				cl = liveconnectLoader;
-				String className = message.substring("FindClass".length() + 1)
-						.replace('/', '.');
-
-				try {
-					c = cl.loadClass(className);
-					store.reference(c);
-					write(reference, "FindClass " + store.getIdentifier(c));
-				} catch (ClassNotFoundException cnfe) {
-					write(reference, "FindClass 0");
-				}
-
-			} else if (message.startsWith("GetStaticMethodID")
-					|| message.startsWith("GetMethodID")) {
-				String[] args = message.split(" ");
-				Integer classID = parseCall(args[1], src, Integer.class);
-				String methodName = parseCall(args[2], src, String.class);
-				Signature signature = parseCall(args[3], src, Signature.class);
-				Object[] a = signature.getClassArray();
-
-				Class c = (Class) store.getObject(classID);
-				Method m = null;
-				Constructor cs = null;
-				Object o = null;
-				if (methodName.equals("<init>")
-						|| methodName.equals("<clinit>")) {
-					o = cs = c.getConstructor(signature.getClassArray());
-					store.reference(cs);
-				} else {
-					o = m = c.getMethod(methodName, signature.getClassArray());
-					store.reference(m);
-				}
-				PluginDebug.debug(o + " has id " + store.getIdentifier(o));
-				write(reference, args[0] + " " + store.getIdentifier(o));
-			} else if (message.startsWith("GetStaticFieldID")
-					|| message.startsWith("GetFieldID")) {
-				String[] args = message.split(" ");
-				Integer classID = parseCall(args[1], src, Integer.class);
-				String fieldName = parseCall(args[2], src, String.class);
-				Signature signature = parseCall(args[3], src, Signature.class);
-
-				Class c = (Class) store.getObject(classID);
-				Field f = null;
-				f = c.getField(fieldName);
-
-				store.reference(f);
-
-				write(reference, "GetStaticFieldID " + store.getIdentifier(f));
-			} else if (message.startsWith("GetStaticField")) {
-				String[] args = message.split(" ");
-				String type = parseCall(args[1], src, String.class);
-				Integer classID = parseCall(args[1], src, Integer.class);
-				Integer fieldID = parseCall(args[2], src, Integer.class);
-
-				Class c = (Class) store.getObject(classID);
-				Field f = (Field) store.getObject(fieldID);
-
-				Object ret = null;
-				ret = f.get(c);
-
-				// System.out.println ("FIELD VALUE: " + ret);
-				if (ret == null) {
-					write(reference, "GetStaticField 0");
-				} else if (f.getType() == Boolean.TYPE
-						|| f.getType() == Byte.TYPE
-						|| f.getType() == Character.TYPE
-						|| f.getType() == Short.TYPE
-						|| f.getType() == Integer.TYPE
-						|| f.getType() == Long.TYPE
-						|| f.getType() == Float.TYPE
-						|| f.getType() == Double.TYPE) {
-					write(reference, "GetStaticField " + ret);
-				} else {
-					// Track returned object.
-					store.reference(ret);
-					write(reference, "GetStaticField "
-							+ store.getIdentifier(ret));
-				}
-			} else if (message.startsWith("SetStaticField")) {
-				String[] args = message.split(" ");
-				String type = parseCall(args[1], src, String.class);
-				Integer classID = parseCall(args[2], src, Integer.class);
-				Integer fieldID = parseCall(args[3], src, Integer.class);
-
-				Object value = null;
-				if (Signature.primitiveNameToType(type) != null) {
-					value = parseArgs(args[4], Signature
-							.primitiveNameToType(type));
-					// System.out.println ("HERE1: " + value);
-				} else {
-					value = parseArgs(args[3], Object.class);
-					// System.out.println ("HERE2: " + value);
-				}
-
-				Class c = (Class) store.getObject(classID);
-				Field f = (Field) store.getObject(fieldID);
-
-				f.set(c, value);
-
-				write(reference, "SetStaticField");
-			} else if (message.startsWith("SetField")) {
-				String[] args = message.split(" ");
-				String type = parseCall(args[1], src, String.class);
-				Integer objectID = parseCall(args[2], src, Integer.class);
-				Integer fieldID = parseCall(args[3], src, Integer.class);
-
-				Object value = null;
-				if (Signature.primitiveNameToType(type) != null) {
-					value = parseArgs(args[4], Signature
-							.primitiveNameToType(type));
-					// System.out.println ("HERE1: " + value);
-				} else {
-					value = parseArgs(args[3], Object.class);
-					// System.out.println ("HERE2: " + value);
-				}
-
-				Object o = (Object) store.getObject(objectID);
-				Field f = (Field) store.getObject(fieldID);
-
-				f.set(o, value);
-
-				write(reference, "SetField");
-			} else if (message.startsWith("GetObjectArrayElement")) {
-				String[] args = message.split(" ");
-				Integer arrayID = parseCall(args[1], src, Integer.class);
-				Integer index = parseCall(args[2], src, Integer.class);
-
-				Object[] o = (Object[]) store.getObject(arrayID);
-				Object ret = null;
-
-				ret = o[index];
-
-				// Track returned object.
-				store.reference(ret);
-				// System.out.println ("array element: " + index + " " + ret);
-				write(reference, "GetObjectArrayElement "
-						+ store.getIdentifier(ret));
-			} else if (message.startsWith("SetObjectArrayElement")) {
-				String[] args = message.split(" ");
-				Integer arrayID = parseCall(args[1], src, Integer.class);
-				Integer index = parseCall(args[2], src, Integer.class);
-				Integer objectID = parseCall(args[3], src, Integer.class);
-
-				Object[] o = (Object[]) store.getObject(arrayID);
-				Object toSet = (Object) store.getObject(objectID);
-
-				o[index] = toSet;
-
-				write(reference, "SetObjectArrayElement");
-			} else if (message.startsWith("GetArrayLength")) {
-				String[] args = message.split(" ");
-				Integer arrayID = parseCall(args[1], src, Integer.class);
-
-				System.out.println("ARRAYID: " + arrayID);
-				Object o = (Object) store.getObject(arrayID);
-				int len = 0;
-				len = Array.getLength(o);
-				// System.out.println ("Returning array length: " + len);
-
-				// System.out.println ("array length: " + o + " " + len);
-				write(reference, "GetArrayLength " + Array.getLength(o));
-			} else if (message.startsWith("GetField")) {
-				String[] args = message.split(" ");
-				String type = parseCall(args[1], src, String.class);
-				Integer objectID = parseCall(args[1], src, Integer.class);
-				Integer fieldID = parseCall(args[2], src, Integer.class);
-
-				Object o = (Object) store.getObject(objectID);
-				Field f = (Field) store.getObject(fieldID);
-
-				Object ret = null;
-				ret = f.get(o);
-
-				// System.out.println ("FIELD VALUE: " + ret);
-				if (ret == null) {
-					write(reference, "GetField 0");
-				} else if (f.getType() == Boolean.TYPE
-						|| f.getType() == Byte.TYPE
-						|| f.getType() == Character.TYPE
-						|| f.getType() == Short.TYPE
-						|| f.getType() == Integer.TYPE
-						|| f.getType() == Long.TYPE
-						|| f.getType() == Float.TYPE
-						|| f.getType() == Double.TYPE) {
-					write(reference, "GetField " + ret);
-				} else {
-					// Track returned object.
-					store.reference(ret);
-					write(reference, "GetField " + store.getIdentifier(ret));
-				}
-			} else if (message.startsWith("GetObjectClass")) {
-				int oid = Integer.parseInt(message.substring("GetObjectClass"
-						.length() + 1));
-				// System.out.println ("GETTING CLASS FOR: " + oid);
-				Class c = store.getObject(oid).getClass();
-				// System.out.println (" OBJ: " + store.getObject(oid));
-				// System.out.println (" CLS: " + c);
-				store.reference(c);
-
-				write(reference, "GetObjectClass " + store.getIdentifier(c));
-			} else if (message.startsWith("CallStaticMethod")) {
-				String[] args = message.split(" ");
-				Integer classID = parseCall(args[1], src, Integer.class);
-				Integer methodID = parseCall(args[2], src, Integer.class);
-
-				System.out.println("GETTING: " + methodID);
-				Method m = (Method) store.getObject(methodID);
-				System.out.println("GOT: " + m);
-				Class[] argTypes = m.getParameterTypes();
-
-				Object[] arguments = new Object[argTypes.length];
-				for (int i = 0; i < argTypes.length; i++) {
-					arguments[i] = parseArgs(args[3 + i], argTypes[i]);
-					// System.out.println ("GOT ARG: " + argTypes[i] + " " +
-					// arguments[i]);
-				}
-
-				// System.out.println ("Calling " + m);
-				Object ret = null;
-				ret = m.invoke(null, arguments);
-
-				// if (ret != null)
-				// System.out.println ("RETURN VALUE: " + ret + " " +
-				// ret.getClass());
-				// else
-				// System.out.println ("RETURN VALUE: " + ret);
-				if (ret == null) {
-					write(reference, "CallStaticMethod void");
-				} else if (m.getReturnType() == Boolean.TYPE
-						|| m.getReturnType() == Byte.TYPE
-						|| m.getReturnType() == Short.TYPE
-						|| m.getReturnType() == Integer.TYPE
-						|| m.getReturnType() == Long.TYPE
-						|| m.getReturnType() == Float.TYPE
-						|| m.getReturnType() == Double.TYPE) {
-					write(reference, "CallStaticMethod " + ret);
-				} else if (m.getReturnType() == Character.TYPE) {
-					char ch = (Character) ret;
-					int high = (((int) ch) >> 8) & 0x0ff;
-					int low = ((int) ch) & 0x0ff;
-					write(reference, "CallStaticMethod " + low + "_" + high);
-				} else {
-					// Track returned object.
-					store.reference(ret);
-					write(reference, "CallStaticMethod "
-							+ store.getIdentifier(ret));
-				}
-			} else if (message.startsWith("CallMethod")) {
-				String[] args = message.split(" ");
-				Integer objectID = parseCall(args[1], src, Integer.class);
-				Integer methodID = parseCall(args[2], src, Integer.class);
-
-				Object o = (Object) store.getObject(objectID);
-				Method m = (Method) store.getObject(methodID);
-				Class[] argTypes = m.getParameterTypes();
-
-				Object[] arguments = new Object[argTypes.length];
-				for (int i = 0; i < argTypes.length; i++) {
-					arguments[i] = parseArgs(args[3 + i], argTypes[i]);
-					PluginDebug.debug("GOT ARG: " + argTypes[i] + " "
-							+ arguments[i]);
-				}
-
-				String collapsedArgs = "";
-				for (String s : args) {
-					collapsedArgs += " " + s;
-				}
-
-				PluginDebug.debug("Calling method " + m + " on object " + o
-						+ " with " + arguments);
-				Object ret = null;
-				ret = m.invoke(o, arguments);
-
-				String retO;
-				if (ret == null) {
-					retO = "null";
-				} else {
-					retO = ret.getClass().toString();
-				}
-
-				PluginDebug.debug("Calling " + m + " on " + o + " with "
-						+ collapsedArgs + " and that returned: " + ret
-						+ " of type " + retO);
-
-				if (ret == null) {
-					write(reference, "CallMethod void");
-				} else if (m.getReturnType() == Boolean.TYPE
-						|| m.getReturnType() == Byte.TYPE
-						|| m.getReturnType() == Short.TYPE
-						|| m.getReturnType() == Integer.TYPE
-						|| m.getReturnType() == Long.TYPE
-						|| m.getReturnType() == Float.TYPE
-						|| m.getReturnType() == Double.TYPE) {
-					write(reference, "CallMethod " + ret);
-				} else if (m.getReturnType() == Character.TYPE) {
-					char ch = (Character) ret;
-					int high = (((int) ch) >> 8) & 0x0ff;
-					int low = ((int) ch) & 0x0ff;
-					write(reference, "CallMethod " + low + "_" + high);
-				} else {
-					// Track returned object.
-					store.reference(ret);
-					write(reference, "CallMethod " + store.getIdentifier(ret));
-				}
-			} else if (message.startsWith("GetSuperclass")) {
-				String[] args = message.split(" ");
-				Integer classID = parseCall(args[1], src, Integer.class);
-				Class c = null;
-				Class ret = null;
-
-				c = (Class) store.getObject(classID);
-				ret = c.getSuperclass();
-				store.reference(ret);
-
-				write(reference, "GetSuperclass " + store.getIdentifier(ret));
-			} else if (message.startsWith("IsAssignableFrom")) {
-				String[] args = message.split(" ");
-				Integer classID = parseCall(args[1], src, Integer.class);
-				Integer superclassID = parseCall(args[2], src, Integer.class);
-
-				boolean result = false;
-				Class clz = (Class) store.getObject(classID);
-				Class sup = (Class) store.getObject(superclassID);
-
-				result = sup.isAssignableFrom(clz);
-
-				write(reference, "IsAssignableFrom " + (result ? "1" : "0"));
-			} else if (message.startsWith("IsInstanceOf")) {
-				String[] args = message.split(" ");
-				Integer objectID = parseCall(args[1], src, Integer.class);
-				Integer classID = parseCall(args[2], src, Integer.class);
-
-				boolean result = false;
-				Object o = (Object) store.getObject(objectID);
-				Class c = (Class) store.getObject(classID);
-
-				result = c.isInstance(o);
-
-				write(reference, "IsInstanceOf " + (result ? "1" : "0"));
-			} else if (message.startsWith("GetStringUTFLength")) {
-				String[] args = message.split(" ");
-				Integer stringID = parseCall(args[1], src, Integer.class);
-
-				String o = null;
-				byte[] b = null;
-				o = (String) store.getObject(stringID);
-				b = o.getBytes("UTF-8");
-				// System.out.println ("STRING UTF-8 LENGTH: " + o + " " +
-				// b.length);
-
-				write(reference, "GetStringUTFLength " + o.length());
-			} else if (message.startsWith("GetStringLength")) {
-				String[] args = message.split(" ");
-				Integer stringID = parseCall(args[1], src, Integer.class);
-
-				String o = null;
-				byte[] b = null;
-				o = (String) store.getObject(stringID);
-				b = o.getBytes("UTF-16LE");
-				// System.out.println ("STRING UTF-16 LENGTH: " + o + " " +
-				// b.length);
-
-				// System.out.println ("Java: GetStringLength " + b.length);
-				write(reference, "GetStringLength " + o.length());
-			} else if (message.startsWith("GetStringUTFChars")) {
-				String[] args = message.split(" ");
-				Integer stringID = parseCall(args[1], src, Integer.class);
-
-				String o = null;
-				byte[] b = null;
-				StringBuffer buf = null;
-				o = (String) store.getObject(stringID);
-				b = o.getBytes("UTF-8");
-				buf = new StringBuffer(b.length * 2);
-				buf.append(b.length);
-				for (int i = 0; i < b.length; i++)
-					buf
-							.append(" "
-									+ Integer
-											.toString(((int) b[i]) & 0x0ff, 16));
-
-				// System.out.println ("Java: GetStringUTFChars: " + o);
-				// //System.out.println ("String UTF BYTES: " + buf);
-				write(reference, "GetStringUTFChars " + buf);
-			} else if (message.startsWith("GetStringChars")) {
-				String[] args = message.split(" ");
-				Integer stringID = parseCall(args[1], src, Integer.class);
-
-				String o = null;
-				byte[] b = null;
-				StringBuffer buf = null;
-				o = (String) store.getObject(stringID);
-				// FIXME: LiveConnect uses UCS-2.
-				b = o.getBytes("UTF-16LE");
-				buf = new StringBuffer(b.length * 2);
-				buf.append(b.length);
-				for (int i = 0; i < b.length; i++)
-					buf
-							.append(" "
-									+ Integer
-											.toString(((int) b[i]) & 0x0ff, 16));
-
-				System.out.println("Java: GetStringChars: " + o);
-				System.out.println("  String BYTES: " + buf);
-				write(reference, "GetStringChars " + buf);
-			} else if (message.startsWith("NewArray")) {
-				String[] args = message.split(" ");
-				String type = parseCall(args[1], src, String.class);
-				Integer length = parseCall(args[2], src, Integer.class);
-
-				// System.out.println ("CALLING: NewArray: " + type + " " +
-				// length + " "
-				// + Signature.primitiveNameToType(type));
-
-				Object newArray = null;
-				newArray = Array.newInstance(Signature
-						.primitiveNameToType(type), length);
-
-				store.reference(newArray);
-				write(reference, "NewArray " + store.getIdentifier(newArray));
-			} else if (message.startsWith("NewObjectArray")) {
-				String[] args = message.split(" ");
-				Integer length = parseCall(args[1], src, Integer.class);
-				Integer classID = parseCall(args[2], src, Integer.class);
-				Integer objectID = parseCall(args[3], src, Integer.class);
-
-				// System.out.println ("CALLING: NewObjectArray: " +
-				// classID + " " + length + " "
-				// + objectID);
-
-				Object newArray = null;
-				newArray = Array.newInstance((Class) store.getObject(classID),
-						length);
-
-				Object[] array = (Object[]) newArray;
-				for (int i = 0; i < array.length; i++)
-					array[i] = store.getObject(objectID);
-				store.reference(newArray);
-				write(reference, "NewObjectArray "
-						+ store.getIdentifier(newArray));
-			} else if (message.startsWith("NewObject")) {
-				String[] args = message.split(" ");
-				Integer classID = parseCall(args[1], src, Integer.class);
-				Integer methodID = parseCall(args[2], src, Integer.class);
-
-				final Constructor m = (Constructor) store.getObject(methodID);
-				Class[] argTypes = m.getParameterTypes();
-
-				// System.out.println ("NEWOBJ: HERE1");
-				final 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]);
-				}
-				
-				Object ret = m.newInstance(arguments);
-				store.reference(ret);
-
-				write(reference, "NewObject " + store.getIdentifier(ret));
-				
-			} else if (message.startsWith("NewString")) {
-				System.out.println("MESSAGE: " + message);
-				String[] args = message.split(" ");
-				Integer strlength = parseCall(args[1], src, Integer.class);
-				int bytelength = 2 * strlength;
-				byte[] byteArray = new byte[bytelength];
-				String ret = null;
-				for (int i = 0; i < strlength; i++) {
-					int c = parseCall(args[2 + i], src, Integer.class);
-					System.out.println("char " + i + " " + c);
-					// Low.
-					byteArray[2 * i] = (byte) (c & 0x0ff);
-					// High.
-					byteArray[2 * i + 1] = (byte) ((c >> 8) & 0x0ff);
-				}
-				ret = new String(byteArray, 0, bytelength, "UTF-16LE");
-				System.out.println("NEWSTRING: " + ret);
-
-				// System.out.println ("NEWOBJ: CALLED: " + ret);
-				// System.out.println ("NEWOBJ: CALLED: " +
-				// store.getObject(ret));
-				store.reference(ret);
-				write(reference, "NewString " + store.getIdentifier(ret));
-			} else if (message.startsWith("NewStringUTF")) {
-				System.out.println("MESSAGE: " + message);
-				String[] args = message.split(" ");
-				byte[] byteArray = new byte[60];
-				String ret = null;
-				int i = 0;
-				int c = 0;
-				while (((byte) c) != 0) {
-					c = parseCall(args[1 + i], src, Integer.class);
-					byteArray[i] = (byte) c;
-					i++;
-					if (i == byteArray.length) {
-						byte[] newByteArray = new byte[2 * byteArray.length];
-						System.arraycopy(byteArray, 0, newByteArray, 0,
-								byteArray.length);
-						byteArray = newByteArray;
-					}
-				}
-				byteArray[i] = (byte) 0;
-				ret = new String(byteArray, "UTF-8");
-				System.out.println("NEWSTRINGUTF: " + ret);
-
-				store.reference(ret);
-				write(reference, "NewStringUTF " + store.getIdentifier(ret));
-			} else if (message.startsWith("ExceptionOccurred")) {
-				System.out.println("EXCEPTION: " + throwable);
-				if (throwable != null)
-					store.reference(throwable);
-				write(reference, "ExceptionOccurred "
-						+ store.getIdentifier(throwable));
-			} else if (message.startsWith("ExceptionClear")) {
-				if (throwable != null)
-					store.unreference(store.getIdentifier(throwable));
-				throwable = null;
-				write(reference, "ExceptionClear");
-			} else if (message.startsWith("DeleteGlobalRef")) {
-				String[] args = message.split(" ");
-				Integer id = parseCall(args[1], src, Integer.class);
-				store.unreference(id);
-				write(reference, "DeleteGlobalRef");
-			} else if (message.startsWith("DeleteLocalRef")) {
-				String[] args = message.split(" ");
-				Integer id = parseCall(args[1], src, Integer.class);
-				store.unreference(id);
-				write(reference, "DeleteLocalRef");
-			} else if (message.startsWith("NewGlobalRef")) {
-				String[] args = message.split(" ");
-				Integer id = parseCall(args[1], src, Integer.class);
-				store.reference(store.getObject(id));
-				write(reference, "NewGlobalRef " + id);
-			}
-		} catch (Throwable t) {
-			t.printStackTrace();
-			throwable = t;
-			PluginException p = new PluginException(this.streamhandler, identifier, reference, t);
-		}
-	}
-
-	private void write(int reference, String message) {
-		PluginDebug.debug("appletviewer writing " + message);
-		streamhandler.write("context " + identifier + " reference " + reference
-				+ " " + message);
-	}
-	
-	public void dumpStore() {
-		store.dump();
-	}
-
-	public Object getObject(int identifier) {
-		return store.getObject(identifier);		
-	}
-
-	public int getIdentifier(Object o) {
-		return store.getIdentifier(o);
-	}
-
-	public void store(Object o) {
-		store.reference(o);
-	}
-}
--- a/plugin/icedtea/org/classpath/icedtea/plugin/PluginCallRequestFactoryImpl.java	Wed Oct 01 05:52:01 2008 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,22 +0,0 @@
-package org.classpath.icedtea.plugin;
-
-import sun.applet.PluginCallRequest;
-import sun.applet.PluginCallRequestFactory;
-
-public class PluginCallRequestFactoryImpl implements PluginCallRequestFactory {
-
-	public PluginCallRequest getPluginCallRequest(String id, String message, String returnString) {
-
-		if (id == "member") {
-			return new GetMemberPluginCallRequest(message, returnString);
-		} else if (id == "void") {
-			return new VoidPluginCallRequest(message, returnString);
-		} else if (id == "window") {
-			return new GetWindowPluginCallRequest(message, returnString);
-		} else {
-			throw new RuntimeException ("Unknown plugin call request type requested from factory");
-		}
-		
-	}
-
-}
--- a/plugin/icedtea/org/classpath/icedtea/plugin/PluginMain.java	Wed Oct 01 05:52:01 2008 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,193 +0,0 @@
-/*
- * Copyright 1999-2006 Sun Microsystems, Inc.  All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code 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
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
-
-package org.classpath.icedtea.plugin;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.PrintStream;
-import java.net.Socket;
-import java.util.Enumeration;
-import java.util.Properties;
-
-import sun.applet.AppletSecurityContext;
-import sun.applet.AppletSecurityContextManager;
-import sun.applet.PluginAppletViewer;
-import sun.applet.PluginStreamHandler;
-
-/**
- * The main entry point into PluginAppletViewer.
- */
-public class PluginMain
-{
-	final boolean redirectStreams = true;
-	static PluginStreamHandler streamHandler;
-	
-    // This is used in init().	Getting rid of this is desirable but depends
-    // on whether the property that uses it is necessary/standard.
-    public static final String theVersion = System.getProperty("java.version");
-    
-    private AppletSecurityContext securityContext;
-
-    /**
-     * The main entry point into AppletViewer.
-     */
-    public static void main(String args[])
-	throws IOException
-    {
-
-    	if (args.length != 1) {
-    		// Indicate to plugin that appletviewer is installed correctly.
-    		System.exit(0);
-    	}
-
-    	int port = 0;
-    	try {
-    		port = Integer.parseInt(args[0]);
-    	} catch (NumberFormatException e) {
-    		System.err.println("Failed to parse port number: " + e);
-    		System.exit(1);
-    	}
-
-    	PluginMain pm = new PluginMain();
-    	
-    }
-
-    public PluginMain() {
-    	
-    	if (redirectStreams) {
-    		try {
-    			File errFile = new File("/tmp/java.stderr");
-    			File outFile = new File("/tmp/java.stdout");
-
-    			System.setErr(new PrintStream(new FileOutputStream(errFile)));
-    			System.setOut(new PrintStream(new FileOutputStream(outFile)));
-
-    		} catch (Exception e) {
-    			System.err.println("Unable to redirect streams");
-    			e.printStackTrace();
-    		}
-    	}
-
-    	// INSTALL THE SECURITY MANAGER
-    	init();
-
-    	connect(50007);
-    	
-    	securityContext = new PluginAppletSecurityContext(0);
-    	securityContext.setStreamhandler(streamHandler);
-    	AppletSecurityContextManager.addContext(0, securityContext);
-		
-		PluginAppletViewer.setStreamhandler(streamHandler);
-		PluginAppletViewer.setPluginCallRequestFactory(new PluginCallRequestFactoryImpl());
-
-		// Streams set. Start processing.
-		streamHandler.startProcessing();
-    }
-
-	public void connect(int port) {
-    	/*
-    	 * Code for TCP/IP communication
-    	 */ 
-    	Socket socket = null;
-
-    	try {
-    		socket = new Socket("localhost", port);
-    	} catch (Exception e) {
-    		e.printStackTrace();
-    	}
-    	
-    	System.err.println("Socket initialized. Proceeding with start()");
-
-		try {
-			streamHandler = new PluginStreamHandlerImpl(socket.getInputStream(), socket.getOutputStream());
-	    	System.err.println("Streams initialized");
-		} catch (IOException ioe) {
-			ioe.printStackTrace();
-		}
-	}
-
-	private static void init() {
-		Properties avProps = new Properties();
-
-		// ADD OTHER RANDOM PROPERTIES
-		// XXX 5/18 need to revisit why these are here, is there some
-		// standard for what is available?
-
-		// Standard browser properties
-		avProps.put("browser", "sun.applet.AppletViewer");
-		avProps.put("browser.version", "1.06");
-		avProps.put("browser.vendor", "Sun Microsystems Inc.");
-		avProps.put("http.agent", "Java(tm) 2 SDK, Standard Edition v" + theVersion);
-
-		// Define which packages can be extended by applets
-		// XXX 5/19 probably not needed, not checked in AppletSecurity
-		avProps.put("package.restrict.definition.java", "true");
-		avProps.put("package.restrict.definition.sun", "true");
-
-		// Define which properties can be read by applets.
-		// A property named by "key" can be read only when its twin
-		// property "key.applet" is true.  The following ten properties
-		// are open by default.	 Any other property can be explicitly
-		// opened up by the browser user by calling appletviewer with
-		// -J-Dkey.applet=true
-		avProps.put("java.version.applet", "true");
-		avProps.put("java.vendor.applet", "true");
-		avProps.put("java.vendor.url.applet", "true");
-		avProps.put("java.class.version.applet", "true");
-		avProps.put("os.name.applet", "true");
-		avProps.put("os.version.applet", "true");
-		avProps.put("os.arch.applet", "true");
-		avProps.put("file.separator.applet", "true");
-		avProps.put("path.separator.applet", "true");
-		avProps.put("line.separator.applet", "true");
-
-		// Read in the System properties.  If something is going to be
-		// over-written, warn about it.
-		Properties sysProps = System.getProperties();
-		for (Enumeration e = sysProps.propertyNames(); e.hasMoreElements(); ) {
-			String key = (String) e.nextElement();
-			String val = (String) sysProps.getProperty(key);
-			avProps.setProperty(key, val);
-		}
-
-		// INSTALL THE PROPERTY LIST
-		System.setProperties(avProps);
-
-		// Create and install the security manager
-		//System.setSecurityManager(new AppletSecurity());
-
-		// REMIND: Create and install a socket factory!
-	}
-
-    static boolean messageAvailable() {
-    	return streamHandler.messageAvailable();
-    }
-
-    static String getMessage() {
-    	return streamHandler.getMessage();
-    }
-}
--- a/plugin/icedtea/org/classpath/icedtea/plugin/PluginMessageConsumer.java	Wed Oct 01 05:52:01 2008 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,76 +0,0 @@
-package org.classpath.icedtea.plugin;
-
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.ArrayList;
-import java.util.LinkedList;
-
-import sun.applet.PluginDebug;
-import sun.applet.PluginStreamHandler;
-
-
-
-class PluginMessageConsumer {
-
-	int MAX_WORKERS = 3;
-	LinkedList<String> readQueue = new LinkedList<String>();
-	ArrayList<PluginMessageHandlerWorker> workers = new ArrayList<PluginMessageHandlerWorker>();
-	PluginStreamHandler streamHandler = null;
-
-	public PluginMessageConsumer(PluginStreamHandler streamHandler) {
-		
-		this.streamHandler = streamHandler;
-
-		for (int i=0; i < MAX_WORKERS; i++) {
-			System.err.println("Creating worker " + i);
-			PluginMessageHandlerWorker worker = new PluginMessageHandlerWorker(streamHandler, i);
-			worker.start();
-			workers.add(worker);
-		}
-	}
-
-	public void consume(String message) {
-		
-		PluginDebug.debug("Consumer received message " + message);
-		
-		synchronized(readQueue) {
-			readQueue.add(message);
-		}
-
-		PluginDebug.debug("Message " + message + " added to queue. Looking for free worker...");
-		final PluginMessageHandlerWorker worker = getFreeWorker();
-
-		synchronized(readQueue) {
-			if (readQueue.size() > 0) {
-				worker.setmessage(readQueue.poll());
-			}
-		}
-
-		AccessController.doPrivileged(new PrivilegedAction() {
-			public Object run () {
-				worker.interrupt();
-				return null;
-			}
-		});
-	}
-
-	private PluginMessageHandlerWorker getFreeWorker() {
-		
-		// FIXME: Can be made more efficient by having an idle worker pool
-		
-		while (true) {
-			for (PluginMessageHandlerWorker worker: workers) {
-				if (worker.isFree()) {
-					PluginDebug.debug("Found free worker with id " + worker.getWorkerId());
-					// mark it busy before returning
-					worker.busy();
-					return worker;
-				}
-			}
-			Thread.yield();
-		}
-
-		//throw new RuntimeException("Out of message handler workers");
-	}
-	
-}
--- a/plugin/icedtea/org/classpath/icedtea/plugin/PluginMessageHandlerWorker.java	Wed Oct 01 05:52:01 2008 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,79 +0,0 @@
-package org.classpath.icedtea.plugin;
-
-import sun.applet.PluginException;
-import sun.applet.PluginStreamHandler;
-
-class PluginMessageHandlerWorker extends Thread {
-
-	private boolean free = true;
-	private int id;
-	private String message = null;
-	PluginStreamHandler streamHandler = null;
-	
-	public PluginMessageHandlerWorker(PluginStreamHandler streamHandler, int id) {
-		this.id = id;
-		this.streamHandler = streamHandler;
-	}
-
-	public void setmessage(String message) {
-		this.message = message;
-	}
-
-	public void run() {
-		while (true) {
-
-			if (message != null) {
-				
-				// ideally, whoever returns things object should mark it 
-				// busy first, but just in case..
-				busy();
-				System.err.println("Thread " + id + " picking up " + message + " from queue...");
-
-				try {
-					streamHandler.handleMessage(message);
-				} catch (PluginException pe) {
-					/*
-					   catch the exception and DO NOTHING. The plugin should take over after 
-					   this error and let the user know. We don't quit because otherwise the 
-					   exception will spread to the rest of the applets which is a no-no
-					 */ 
-				}
-
-				this.message = null;
-			} else {
-				
-				// Sleep when there is nothing to do
-				try {
-					Thread.sleep(Integer.MAX_VALUE);
-					System.err.println("Consumer thread " + id + " sleeping...");
-				} catch (InterruptedException ie) {
-					System.err.println("Consumer thread " + id + " woken...");
-					// nothing.. someone woke us up, see if there 
-					// is work to do
-				}
-			}
-			
-			// mark ourselves free again
-			free();
-		}
-	}
-	
-	
-	
-	public int getWorkerId() {
-		return id;
-	}
-
-	public void busy() {
-		this.free = false;
-	}
-
-	
-	public void free() {
-		this.free = true;
-	}
-	
-	public boolean isFree() {
-		return free;
-	}
-}
--- a/plugin/icedtea/org/classpath/icedtea/plugin/PluginObjectStore.java	Wed Oct 01 05:52:01 2008 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,119 +0,0 @@
-/* PluginObjectStore -- manage identifier-to-object mapping
-   Copyright (C) 2008  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 org.classpath.icedtea.plugin;
-
-import java.util.*;
-import java.lang.reflect.*;
-import java.io.*;
-
-public class PluginObjectStore
-{
-    private static HashMap<Integer, Object> objects = new HashMap();
-    private static HashMap<Integer, Integer> counts = new HashMap();
-    private static HashMap<Object, Integer> identifiers = new HashMap();
-    // FIXME:
-    //
-    // IF uniqueID == MAX_LONG, uniqueID =
-    // 0 && wrapped = true
-    //
-    // if (wrapped), check if
-    // objects.get(uniqueID) returns null
-    //
-    // if yes, use uniqueID, if no,
-    // uniqueID++ and keep checking
-    // or:
-    // stack of available ids:
-    // derefed id -> derefed id -> nextUniqueIdentifier
-    private static int nextUniqueIdentifier = 1;
-
-    public Object getObject(Integer identifier) {
-        return objects.get(identifier);
-    }
-
-    public Integer getIdentifier(Object object) {
-        if (object == null)
-            return 0;
-        return identifiers.get(object);
-    }
-
-    public void reference(Object object) {
-        Integer identifier = identifiers.get(object);
-        if (identifier == null) {
-            objects.put(nextUniqueIdentifier, object);
-            counts.put(nextUniqueIdentifier, 1);
-            identifiers.put(object, nextUniqueIdentifier);
-            System.out.println("JAVA ADDED: " + nextUniqueIdentifier);
-            System.out.println("JAVA REFERENCED: " + nextUniqueIdentifier
-                               + " to: 1");
-            nextUniqueIdentifier++;
-        } else {
-            counts.put(identifier, counts.get(identifier) + 1);
-            System.out.println("JAVA REFERENCED: " + identifier +
-                               " to: " + counts.get(identifier));
-        }
-    }
-
-    public void unreference(int identifier) {
-        Integer currentCount = counts.get(identifier);
-        if (currentCount == null)
-            System.out.println("ERROR UNREFERENCING: " + identifier);
-        if (currentCount == 1) {
-            System.out.println("JAVA DEREFERENCED: " + identifier
-                               + " to: 0");
-            Object object = objects.get(identifier);
-            objects.remove(identifier);
-            counts.remove(identifier);
-            identifiers.remove(object);
-            System.out.println("JAVA REMOVED: " + identifier);
-        } else {
-            counts.put(identifier, currentCount - 1);
-            System.out.println("JAVA DEREFERENCED: " +
-                               identifier + " to: " +
-                               counts.get(identifier));
-        }
-    }
-
-    public void dump() {
-   		Iterator i = objects.keySet().iterator();
-   		while (i.hasNext()) {
-   			Object key = i.next();
-   			System.err.println(key + "::" +  objects.get(key));
-   		}
-    }
-}
-
--- a/plugin/icedtea/org/classpath/icedtea/plugin/PluginStreamHandlerImpl.java	Wed Oct 01 05:52:01 2008 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,362 +0,0 @@
-package org.classpath.icedtea.plugin;
-
-import java.io.BufferedReader;
-import java.io.BufferedWriter;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.StreamTokenizer;
-import java.net.MalformedURLException;
-import java.nio.charset.Charset;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.LinkedList;
-import java.util.StringTokenizer;
-
-import sun.applet.AppletSecurityContextManager;
-import sun.applet.PluginAppletViewer;
-import sun.applet.PluginCallRequest;
-import sun.applet.PluginDebug;
-import sun.applet.PluginException;
-import sun.applet.PluginStreamHandler;
-
-public class PluginStreamHandlerImpl implements PluginStreamHandler {
-
-    private BufferedReader pluginInputReader;
-    private StreamTokenizer pluginInputTokenizer;
-    private BufferedWriter pluginOutputWriter;
-    
-    private RequestQueue queue = new RequestQueue();
-
-	LinkedList<String> writeQueue = new LinkedList<String>();
-
-	PluginMessageConsumer consumer;
-	Boolean shuttingDown = false;
-	
-	PluginAppletViewer pav;
-	
-    public PluginStreamHandlerImpl(InputStream inputstream, OutputStream outputstream)
-    throws MalformedURLException, IOException
-    {
-
-    	System.err.println("Current context CL=" + Thread.currentThread().getContextClassLoader());
-    	try {
-			pav = (PluginAppletViewer) ClassLoader.getSystemClassLoader().loadClass("sun.applet.PluginAppletViewer").newInstance();
-			System.err.println("Loaded: " + pav + " CL=" + pav.getClass().getClassLoader());
-		} catch (InstantiationException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		} catch (IllegalAccessException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		} catch (ClassNotFoundException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		}
-
-    	System.err.println("Creating consumer...");
-    	consumer = new PluginMessageConsumer(this);
-
-    	// Set up input and output pipes.  Use UTF-8 encoding.
-    	pluginInputReader =
-    		new BufferedReader(new InputStreamReader(inputstream,
-    				Charset.forName("UTF-8")));
-    	pluginInputTokenizer = new StreamTokenizer(pluginInputReader);
-    	pluginInputTokenizer.resetSyntax();
-    	pluginInputTokenizer.whitespaceChars('\u0000', '\u0000');
-    	pluginInputTokenizer.wordChars('\u0001', '\u00FF');
-    	pluginOutputWriter =
-    		new BufferedWriter(new OutputStreamWriter
-    				(outputstream, Charset.forName("UTF-8")));
-
-    	/*
-	while(true) {
-            String message = read();
-            PluginDebug.debug(message);
-            handleMessage(message);
-            // TODO:
-            // write(queue.peek());
-	}
-    	 */
-    }
-
-    public void startProcessing() {
-
-    	Thread listenerThread = new Thread() {
-
-    		public void run() {
-    			while (true) {
-
-    				System.err.println("Waiting for data...");
-
-    				int readChar = -1;
-    				// blocking read, discard first character
-    				try {
-    					readChar = pluginInputReader.read();
-    				} catch (IOException ioe) {
-    					// plugin may have detached
-    				}
-
-    				// if not disconnected
-    				if (readChar != -1) {
-    					String s = read();
-    					System.err.println("Got data, consuming " + s);
-    					consumer.consume(s);
-    				} else {
-    					try {
-    						// Close input/output channels to plugin.
-    						pluginInputReader.close();
-    						pluginOutputWriter.close();
-    					} catch (IOException exception) {
-    						// Deliberately ignore IOException caused by broken
-    						// pipe since plugin may have already detached.
-    					}
-    					AppletSecurityContextManager.dumpStore(0);
-    					System.err.println("APPLETVIEWER: exiting appletviewer");
-    					System.exit(0);
-    				}
-    			}
-    		}
-    	};
-
-    	listenerThread.start();    	
-    }
-    
-    public void postMessage(String s) {
-
-    	if (s == null || s.equals("shutdown")) {
-    	    try {
-    		// Close input/output channels to plugin.
-    		pluginInputReader.close();
-    		pluginOutputWriter.close();
-    	    } catch (IOException exception) {
-    		// Deliberately ignore IOException caused by broken
-    		// pipe since plugin may have already detached.
-    	    }
-    	    AppletSecurityContextManager.dumpStore(0);
-    	    System.err.println("APPLETVIEWER: exiting appletviewer");
-    	    System.exit(0);
-    	}
-
-   		//PluginAppletSecurityContext.contexts.get(0).store.dump();
-   		PluginDebug.debug("Plugin posted: " + s);
-
-		System.err.println("Consuming " + s);
-		consumer.consume(s);
-
-   		PluginDebug.debug("Added to queue");
-    }
-    
-    public void handleMessage(String message) throws PluginException {
-
-    	StringTokenizer st = new StringTokenizer(message, " ");
-
-    	String type = st.nextToken();
-    	final int identifier = Integer.parseInt(st.nextToken());
-
-    	String rest = "";
-    	int reference = -1;
-    	String src = null;
-
-    	String potentialReference = st.hasMoreTokens() ? st.nextToken() : "";
-
-    	// if the next token is reference, read it, else reset "rest"
-    	if (potentialReference.equals("reference")) {
-    		reference = Integer.parseInt(st.nextToken());
-    	} else {
-    		rest += potentialReference + " ";
-    	}
-
-    	String potentialSrc = st.hasMoreTokens() ? st.nextToken() : "";
-
-    	if (potentialSrc.equals("src")) {
-    		src = st.nextToken();
-    	} else {
-    		rest += potentialSrc + " ";
-    	}
-
-    	while (st.hasMoreElements()) {
-    		rest += st.nextToken();
-    		rest += " ";
-    	}
-
-    	rest = rest.trim();
-
-    	try {
-
-    		System.err.println("Breakdown -- type: " + type + " identifier: " + identifier + " reference: " + reference + " src: " + src + " rest: " + rest);
-
-    		if (rest.contains("JavaScriptGetWindow")
-    				|| rest.contains("JavaScriptGetMember")
-    				|| rest.contains("JavaScriptSetMember")
-    				|| rest.contains("JavaScriptGetSlot")
-    				|| rest.contains("JavaScriptSetSlot")
-    				|| rest.contains("JavaScriptEval")
-    				|| rest.contains("JavaScriptRemoveMember")
-    				|| rest.contains("JavaScriptCall")
-    				|| rest.contains("JavaScriptFinalize")
-    				|| rest.contains("JavaScriptToString")) {
-    			
-				finishCallRequest(rest);
-    			return;
-    		}
-
-    		final int freference = reference;
-    		final String frest = rest;
-
-    		if (type.equals("instance")) {
-    			PluginAppletViewer.handleMessage(identifier, freference,frest);
-    		} else if (type.equals("context")) {
-    			PluginDebug.debug("Sending to PASC: " + identifier + "/" + reference + " and " + rest);
-    			AppletSecurityContextManager.handleMessage(identifier, src, reference, rest);
-    		}
-    	} catch (Exception e) {
-    		throw new PluginException(this, identifier, reference, e);
-    	}
-    }
-
-    public void postCallRequest(PluginCallRequest request) {
-        synchronized(queue) {
-   			queue.post(request);
-        }
-    }
-
-    private void finishCallRequest(String message) {
-    	PluginDebug.debug ("DISPATCHCALLREQUESTS 1");
-    	synchronized(queue) {
-    		PluginDebug.debug ("DISPATCHCALLREQUESTS 2");
-    		PluginCallRequest request = queue.pop();
-
-    		// make sure we give the message to the right request 
-    		// in the queue.. for the love of God, MAKE SURE!
-
-    		// first let's be efficient.. if there was only one 
-    		// request in queue, we're already set
-    		if (queue.size() != 0) {
-
-    			int size = queue.size();
-    			int count = 0;
-
-    			while (!request.serviceable(message)) {
-
-    				// something is very wrong.. we have a message to 
-    				// process, but no one to service it
-    				if (count >= size) {
-    					throw new RuntimeException("Unable to find processor for message " + message);
-    				}
-
-    				// post request at the end of the queue
-    				queue.post(request);
-
-    				// Look at the next request
-    				request = queue.pop();
-
-    				count++;
-    			}
-
-    		}
-
-    		PluginDebug.debug ("DISPATCHCALLREQUESTS 3");
-    		if (request != null) {
-    			PluginDebug.debug ("DISPATCHCALLREQUESTS 5");
-    			synchronized(request) {
-    				request.parseReturn(message);
-    				request.notifyAll();
-    			}
-    			PluginDebug.debug ("DISPATCHCALLREQUESTS 6");
-    			PluginDebug.debug ("DISPATCHCALLREQUESTS 7");
-    		}
-    	}
-    	PluginDebug.debug ("DISPATCHCALLREQUESTS 8");
-    }
-
-    /**
-     * Read string from plugin.
-     *
-     * @return the read string
-     *
-     * @exception IOException if an error occurs
-     */
-    private String read()
-    {
-    	try {
-    		pluginInputTokenizer.nextToken();
-    	} catch (IOException e) {
-    		throw new RuntimeException(e);
-    	}
-    	String message = pluginInputTokenizer.sval;
-    	PluginDebug.debug("  PIPE: appletviewer read: " + message);
-    	if (message == null || message.equals("shutdown")) {
-    		synchronized(shuttingDown) {
-    			shuttingDown = true;
-    		}
-    		try {
-    			// Close input/output channels to plugin.
-    			pluginInputReader.close();
-    			pluginOutputWriter.close();
-    		} catch (IOException exception) {
-    			// Deliberately ignore IOException caused by broken
-    			// pipe since plugin may have already detached.
-    		}
-    		AppletSecurityContextManager.dumpStore(0);
-    		System.err.println("APPLETVIEWER: exiting appletviewer");
-    		System.exit(0);
-    	}
-    	return message;
-    }
-    
-    /**
-     * Write string to plugin.
-     * 
-     * @param message the message to write
-     *
-     * @exception IOException if an error occurs
-     */
-    public void write(String message)
-    {
-
-    	System.err.println("  PIPE: appletviewer wrote: " + message);
-        synchronized(pluginOutputWriter) {
-        	try {
-        		pluginOutputWriter.write(message, 0, message.length());
-        		pluginOutputWriter.write(0);
-        		pluginOutputWriter.flush();
-        	} catch (IOException e) {
-        		// if we are shutting down, ignore write failures as 
-        		// pipe may have closed
-        		synchronized(shuttingDown) {
-        			if (!shuttingDown) {
-        				e.printStackTrace();
-        			}
-        		}
-
-        		// either ways, if the pipe is broken, there is nothing 
-        		// we can do anymore. Don't hang around.
-        		System.err.println("Unable to write to PIPE. APPLETVIEWER exiting");        		
-        		System.exit(1);
-        	}
-		}
-
-		return;
-    /*	
-    	synchronized(writeQueue) {
-            writeQueue.add(message);
-            System.err.println("  PIPE: appletviewer wrote: " + message);
-    	}
-	*/
-
-    }
-    
-    public boolean messageAvailable() {
-    	return writeQueue.size() != 0;
-    }
-
-    public String getMessage() {
-    	synchronized(writeQueue) {
-			String ret = writeQueue.size() > 0 ? writeQueue.poll() : "";
-    		return ret;
-    	}
-    }
-}
--- a/plugin/icedtea/org/classpath/icedtea/plugin/RequestQueue.java	Wed Oct 01 05:52:01 2008 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,40 +0,0 @@
-package org.classpath.icedtea.plugin;
-
-import sun.applet.PluginCallRequest;
-
-public class RequestQueue {
-    PluginCallRequest head = null;
-    PluginCallRequest tail = null;
-    private int size = 0;
-
-    public void post(PluginCallRequest request) {
-    	System.err.println("Securitymanager=" + System.getSecurityManager());
-        if (head == null) {
-            head = tail = request;
-            tail.setNext(null);
-        } else {
-            tail.setNext(request);
-            tail = request;
-            tail.setNext(null);
-        }
-        
-        size++;
-    }
-
-    public PluginCallRequest pop() {
-        if (head == null)
-            return null;
-
-        PluginCallRequest ret = head;
-        head = head.getNext();
-        ret.setNext(null);
-
-        size--;
-        
-        return ret;
-    }
-    
-    public int size() {
-    	return size;
-    }
-}
\ No newline at end of file
--- a/plugin/icedtea/org/classpath/icedtea/plugin/TestEnv.java	Wed Oct 01 05:52:01 2008 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,172 +0,0 @@
-/* TestEnv -- test JavaScript-to-Java calls
-   Copyright (C) 2008  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 org.classpath.icedtea.plugin;
-
-public class TestEnv
-{
-    public static int intField = 103;
-    public int intInstanceField = 7822;
-    public String stringField = "hello";
-    // z <musical G clef> <chinese water>
-    public String complexStringField = "z\uD834\uDD1E\u6C34";
-
-    public static void TestIt() {
-        System.out.println("TestIt");
-    }
-
-    public static void TestItBool(boolean arg) {
-        System.out.println("TestItBool: " + arg);
-    }
-
-    public static void TestItByte(byte arg) {
-        System.out.println("TestItByte: " + arg);
-    }
-
-    public static void TestItChar(char arg) {
-        System.out.println("TestItChar: " + arg);
-    }
-
-    public static void TestItShort(short arg) {
-        System.out.println("TestItShort: " + arg);
-    }
-
-    public static void TestItInt(int arg) {
-        System.out.println("TestItInt: " + arg);
-    }
-
-    public static void TestItLong(long arg) {
-        System.out.println("TestItLong: " + arg);
-    }
-
-    public static void TestItFloat(float arg) {
-        System.out.println("TestItFloat: " + arg);
-    }
-
-    public static void TestItDouble(double arg) {
-        System.out.println("TestItDouble: " + arg);
-    }
-
-    public static void TestItObject(TestEnv arg) {
-        System.out.println("TestItObject: " + arg);
-    }
-
-    public static void TestItObjectString(String arg) {
-        System.out.println("TestItObjectString: " + arg);
-    }
-
-    public static void TestItIntArray(int[] arg) {
-        System.out.println("TestItIntArray: " + arg);
-        for (int i = 0; i < arg.length; i++)
-            System.out.println ("ELEMENT: " + i + " " + arg[i]);
-    }
-
-    public static void TestItObjectArray(String[] arg) {
-        System.out.println("TestItObjectArray: " + arg);
-        for (int i = 0; i < arg.length; i++)
-            System.out.println ("ELEMENT: " + i + " " + arg[i]);
-    }
-
-    public static void TestItObjectArrayMulti(String[][] arg) {
-        System.out.println("TestItObjectArrayMulti: " + arg);
-        for (int i = 0; i < arg.length; i++)
-            for (int j = 0; j < arg[i].length; j++)
-                System.out.println ("ELEMENT: " + i + " " + j + " " + arg[i][j]);
-    }
-
-    public static boolean TestItBoolReturnTrue() {
-        return true;
-    }
-
-    public static boolean TestItBoolReturnFalse() {
-        return false;
-    }
-
-    public static byte TestItByteReturn() {
-        return (byte) 0xfe;
-    }
-
-    public static char TestItCharReturn() {
-        return 'K';
-    }
-
-    public static char TestItCharUnicodeReturn() {
-        return '\u6C34';
-    }
-
-    public static short TestItShortReturn() {
-        return 23;
-    }
-
-    public static int TestItIntReturn() {
-        return 3445;
-    }
-
-    public static long TestItLongReturn() {
-        return 3242883;
-    }
-
-    public static float TestItFloatReturn() {
-        return 9.21E4f;
-    }
-
-    public static double TestItDoubleReturn() {
-        return 8.33E88;
-    }
-
-    public static Object TestItObjectReturn() {
-        return new String("Thomas");
-    }
-
-    public static int[] TestItIntArrayReturn() {
-        return new int[] { 6, 7, 8 };
-    }
-
-    public static String[] TestItObjectArrayReturn() {
-        return new String[] { "Thomas", "Brigitte" };
-    }
-
-    public static String[][] TestItObjectArrayMultiReturn() {
-        return new String[][] { {"Thomas", "Brigitte"},
-                                {"Lindsay", "Michael"} };
-    }
-
-    public int TestItIntInstance(int arg) {
-        System.out.println("TestItIntInstance: " + this + " " + arg);
-        return 899;
-    }
-}
--- a/plugin/icedtea/org/classpath/icedtea/plugin/VoidPluginCallRequest.java	Wed Oct 01 05:52:01 2008 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-/* VoidPluginCallRequest -- represent Java-to-JavaScript requests
-   Copyright (C) 2008  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 org.classpath.icedtea.plugin;
-
-import sun.applet.PluginCallRequest;
-
-public class VoidPluginCallRequest extends PluginCallRequest {
-    public VoidPluginCallRequest(String message, String returnString) {
-        super(message, returnString);
-        System.out.println ("VoidPLUGINCAlL " + message + " " + returnString);
-    }
-
-    public void parseReturn(String message) {
-    	setDone(true);
-    }
-    
-    
-    /**
-     * Returns whether the given message is serviceable by this object
-     * 
-     * @param message The message to service
-     * @return boolean indicating if message is serviceable
-     */
-    public boolean serviceable(String message) {
-    	return message.contains("JavaScriptFinalize") ||
-    			message.contains("JavaScriptRemoveMember") ||
-    			message.contains("JavaScriptSetMember") ||
-    			message.contains("JavaScriptSetSlot");
-    }
-    
-    public Object getObject() {
-    	return null;
-    }
-}
--- a/plugin/icedtea/sun/applet/AppletSecurityContext.java	Wed Oct 01 05:52:01 2008 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +0,0 @@
-package sun.applet;
-
-import java.util.HashMap;
-
-public abstract class AppletSecurityContext {
-
-	public static PluginStreamHandler streamhandler;
-
-	public static void setStreamhandler(PluginStreamHandler sh) {
-		streamhandler = sh;
-	}
-	
-	public abstract void handleMessage(String src, int reference, String message);
-	
-	public abstract void addClassLoader(String id, ClassLoader cl);
-	
-	public abstract void dumpStore();
-	
-	public abstract Object getObject(int identifier);
-	
-	public abstract int getIdentifier(Object o);
-	
-	public abstract void store(Object o);
-
-}
--- a/plugin/icedtea/sun/applet/AppletSecurityContextManager.java	Wed Oct 01 05:52:01 2008 -0400
+++ b/plugin/icedtea/sun/applet/AppletSecurityContextManager.java	Wed Oct 01 16:40:56 2008 -0400
@@ -6,13 +6,13 @@
 
 	// Context identifier -> PluginAppletSecurityContext object.
 	// FIXME: make private
-	private static HashMap<Integer, AppletSecurityContext> contexts = new HashMap();
+	private static HashMap<Integer, PluginAppletSecurityContext> contexts = new HashMap();
 	
-	public static void addContext(int identifier, AppletSecurityContext context) {
+	public static void addContext(int identifier, PluginAppletSecurityContext context) {
 		contexts.put(identifier, context);
 	}
 	
-	public static AppletSecurityContext getSecurityContext(int identifier) {
+	public static PluginAppletSecurityContext getSecurityContext(int identifier) {
 		return contexts.get(identifier);
 	}
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugin/icedtea/sun/applet/GetMemberPluginCallRequest.java	Wed Oct 01 16:40:56 2008 -0400
@@ -0,0 +1,76 @@
+/* GetMemberPluginCallRequest -- represent Java-to-JavaScript requests
+   Copyright (C) 2008  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;
+
+
+public class GetMemberPluginCallRequest extends PluginCallRequest {
+    Object object = null;
+
+    public GetMemberPluginCallRequest(String message, String returnString) {
+        super(message, returnString);
+        System.out.println ("GetMEMBerPLUGINCAlL " + message + " " + returnString);
+    }
+
+    public void parseReturn(String message) {
+        System.out.println ("GetMEMBerparseReturn GOT: " + message);
+        String[] args = message.split(" ");
+        // FIXME: add thread ID to messages to support multiple
+        // threads using the netscape.javascript package.
+        object = AppletSecurityContextManager.getSecurityContext(0).getObject(Integer.parseInt(args[1]));
+        setDone(true);
+    }
+
+    /**
+     * Returns whether the given message is serviceable by this object
+     * 
+     * @param message The message to service
+     * @return boolean indicating if message is serviceable
+     */
+    public boolean serviceable(String message) {
+    	return message.contains("JavaScriptCall") ||
+    			message.contains("JavaScriptEval") ||
+    			message.contains("JavaScriptGetMember") ||
+    			message.contains("JavaScriptGetSlot") ||
+    			message.contains("JavaScriptToString");
+    }
+    
+    public Object getObject() {
+    	return this.object;
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugin/icedtea/sun/applet/GetWindowPluginCallRequest.java	Wed Oct 01 16:40:56 2008 -0400
@@ -0,0 +1,75 @@
+/* GetWindowPluginCallRequest -- represent Java-to-JavaScript requests
+   Copyright (C) 2008  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.security.AccessControlContext;
+import java.security.ProtectionDomain;
+
+
+
+public class GetWindowPluginCallRequest extends PluginCallRequest {
+    // FIXME: look into int vs long JavaScript internal values.
+    int internal;
+
+    public GetWindowPluginCallRequest(String message, String returnString) {
+        super(message, returnString);
+    }
+
+    public void parseReturn(String message) {
+        System.out.println ("GetWINDOWparseReturn GOT: " + message);
+        String[] args = message.split(" ");
+        // FIXME: add thread ID to messages to support multiple
+        // threads using the netscape.javascript package.
+        internal = Integer.parseInt(args[1]);
+        setDone(true);
+    }
+    
+    /**
+     * Returns whether the given message is serviceable by this object
+     * 
+     * @param message The message to service
+     * @return boolean indicating if message is serviceable
+     */
+    public boolean serviceable(String message) {
+    	return message.contains("JavaScriptGetWindow");
+    }
+
+    public Integer getObject() {
+    	return this.internal;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugin/icedtea/sun/applet/PluginAppletSecurityContext.java	Wed Oct 01 16:40:56 2008 -0400
@@ -0,0 +1,1021 @@
+/* PluginAppletSecurityContext -- execute plugin JNI messages
+   Copyright (C) 2008  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.lang.reflect.Array;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import java.security.PrivilegedAction;
+import java.security.ProtectionDomain;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.StringTokenizer;
+
+import net.sourceforge.jnlp.runtime.JNLPRuntime;
+
+
+
+class Signature {
+	private String signature;
+	private int currentIndex;
+	private List<Class> typeList;
+	private static final char ARRAY = '[';
+	private static final char OBJECT = 'L';
+	private static final char SIGNATURE_ENDCLASS = ';';
+	private static final char SIGNATURE_FUNC = '(';
+	private static final char SIGNATURE_ENDFUNC = ')';
+	private static final char VOID = 'V';
+	private static final char BOOLEAN = 'Z';
+	private static final char BYTE = 'B';
+	private static final char CHARACTER = 'C';
+	private static final char SHORT = 'S';
+	private static final char INTEGER = 'I';
+	private static final char LONG = 'J';
+	private static final char FLOAT = 'F';
+	private static final char DOUBLE = 'D';
+
+	private String nextTypeName() {
+		char key = signature.charAt(currentIndex++);
+
+		switch (key) {
+		case ARRAY:
+			return nextTypeName() + "[]";
+
+		case OBJECT:
+			int endClass = signature.indexOf(SIGNATURE_ENDCLASS, currentIndex);
+			String retVal = signature.substring(currentIndex, endClass);
+			retVal = retVal.replace('/', '.');
+			currentIndex = endClass + 1;
+			return retVal;
+
+			// FIXME: generated bytecode with classes named after
+			// primitives will not work in this scheme -- those
+			// classes will be incorrectly treated as primitive
+			// types.
+		case VOID:
+			return "void";
+		case BOOLEAN:
+			return "boolean";
+		case BYTE:
+			return "byte";
+		case CHARACTER:
+			return "char";
+		case SHORT:
+			return "short";
+		case INTEGER:
+			return "int";
+		case LONG:
+			return "long";
+		case FLOAT:
+			return "float";
+		case DOUBLE:
+			return "double";
+
+		case SIGNATURE_ENDFUNC:
+		case SIGNATURE_FUNC:
+			return nextTypeName();
+
+		default:
+			throw new IllegalArgumentException(
+					"Invalid JNI signature character '" + key + "'");
+		}
+	}
+
+	public Signature(String signature, String src) {
+		this.signature = signature;
+		currentIndex = 0;
+		typeList = new ArrayList<Class>(10);
+
+		String elem;
+		while (currentIndex < signature.length()) {
+			elem = nextTypeName();
+			// System.out.println ("NEXT TYPE: " + elem);
+			Class primitive = primitiveNameToType(elem);
+			if (primitive != null)
+				typeList.add(primitive);
+			else {
+				// System.out.println ("HERE1");
+				int dimsize = 0;
+				int n = elem.indexOf('[');
+				if (n != -1) {
+					// System.out.println ("HERE2");
+					String arrayType = elem.substring(0, n);
+					dimsize++;
+					n = elem.indexOf('[', n + 1);
+					// System.out.println ("HERE2.5");
+					while (n != -1) {
+						dimsize++;
+						n = elem.indexOf('[', n + 1);
+						// System.out.println ("HERE2.8");
+					}
+					int[] dims = new int[dimsize];
+					primitive = primitiveNameToType(arrayType);
+					// System.out.println ("HERE3");
+					if (primitive != null) {
+						typeList.add(Array.newInstance(primitive, dims)
+								.getClass());
+						// System.out.println ("HERE4");
+					} else
+						typeList.add(Array.newInstance(
+								getClass(arrayType, src), dims).getClass());
+				} else {
+					typeList.add(getClass(elem, src));
+				}
+			}
+		}
+		if (typeList.size() == 0) {
+			throw new IllegalArgumentException("Invalid JNI signature '"
+					+ signature + "'");
+		}
+	}
+
+	public static Class getClass(String name, String src) {
+
+		Class c = null;
+		
+		try {
+			c = Class.forName(name);
+		} catch (ClassNotFoundException cnfe) {
+
+			StringTokenizer st = new StringTokenizer(src, ",");
+
+			while (st.hasMoreTokens()) {
+
+				String tok = st.nextToken();
+				System.err.println("Searching for " + name  + " at key " + tok);
+
+				try {
+					c = PluginAppletSecurityContext.classLoaders.get(tok).loadClass(name);
+				} catch (ClassNotFoundException e) {
+					// do nothing .. thrown below
+				}
+
+				if (c != null)
+					break;
+			}
+		}
+
+		if (c == null) {
+			throw (new RuntimeException(new ClassNotFoundException("Unable to find class " + name)));
+		}
+
+		return c;
+	}
+	
+	public static Class primitiveNameToType(String name) {
+		if (name.equals("void"))
+			return Void.TYPE;
+		else if (name.equals("boolean"))
+			return Boolean.TYPE;
+		else if (name.equals("byte"))
+			return Byte.TYPE;
+		else if (name.equals("char"))
+			return Character.TYPE;
+		else if (name.equals("short"))
+			return Short.TYPE;
+		else if (name.equals("int"))
+			return Integer.TYPE;
+		else if (name.equals("long"))
+			return Long.TYPE;
+		else if (name.equals("float"))
+			return Float.TYPE;
+		else if (name.equals("double"))
+			return Double.TYPE;
+		else
+			return null;
+	}
+
+	public Class[] getClassArray() {
+		return typeList.subList(0, typeList.size() - 1).toArray(new Class[] {});
+	}
+}
+
+public class PluginAppletSecurityContext {
+	
+	public static HashMap<String, ClassLoader> classLoaders = new HashMap<String, ClassLoader>();
+
+	// FIXME: make private
+	public PluginObjectStore store = new PluginObjectStore();
+	private Throwable throwable = null;
+	private ClassLoader liveconnectLoader = ClassLoader.getSystemClassLoader();
+	int identifier = 0;
+	
+	public static PluginStreamHandler streamhandler;
+
+	public PluginAppletSecurityContext(int identifier) {
+		this.identifier = identifier;
+	}
+
+	private static <V> V parseCall(String s, String src, Class<V> c) {
+		if (c == Integer.class)
+			return (V) new Integer(s);
+		else if (c == String.class)
+			return (V) new String(s);
+		else if (c == Signature.class)
+			return (V) new Signature(s, src);
+		else
+			throw new RuntimeException("Unexpected call value.");
+	}
+
+	private Object parseArgs(String s, Class c) {
+		if (c == Boolean.TYPE || c == Boolean.class)
+			return new Boolean(s);
+		else if (c == Byte.TYPE || c == Byte.class)
+			return new Byte(s);
+		else if (c == Character.TYPE || c == Character.class) {
+			String[] bytes = s.split("_");
+			int low = Integer.parseInt(bytes[0]);
+			int high = Integer.parseInt(bytes[1]);
+			int full = ((high << 8) & 0x0ff00) | (low & 0x0ff);
+			return new Character((char) full);
+		} else if (c == Short.TYPE || c == Short.class)
+			return new Short(s);
+		else if (c == Integer.TYPE || c == Integer.class)
+			return new Integer(s);
+		else if (c == Long.TYPE || c == Long.class)
+			return new Long(s);
+		else if (c == Float.TYPE || c == Float.class)
+			return new Float(s);
+		else if (c == Double.TYPE || c == Double.class)
+			return new Double(s);
+		else
+			return store.getObject(new Integer(s));
+	}
+
+	public void addClassLoader(String id, ClassLoader cl) {
+		this.classLoaders.put(id, cl);
+	}
+
+	public static void setStreamhandler(PluginStreamHandler sh) {
+		streamhandler = sh;
+	}
+
+	public void handleMessage(String src, int reference, String message) {
+
+		// We need a security manager.. and since there is a good chance that 
+		// an applet will be loaded at some point, we should make it the SM 
+		// that JNLPRuntime will try to install
+		if (System.getSecurityManager() == null) {
+			JNLPRuntime.initialize();
+		}
+
+		System.out.println("in handleMessage(), SecurityManager=" + System.getSecurityManager());
+		
+		try {
+			if (message.startsWith("FindClass")) {
+				ClassLoader cl = null;
+				Class c = null;
+				cl = liveconnectLoader;
+				String className = message.substring("FindClass".length() + 1)
+						.replace('/', '.');
+
+				try {
+					c = cl.loadClass(className);
+					store.reference(c);
+					write(reference, "FindClass " + store.getIdentifier(c));
+				} catch (ClassNotFoundException cnfe) {
+					write(reference, "FindClass 0");
+				}
+
+			} else if (message.startsWith("GetStaticMethodID")
+					|| message.startsWith("GetMethodID")) {
+				String[] args = message.split(" ");
+				Integer classID = parseCall(args[1], src, Integer.class);
+				String methodName = parseCall(args[2], src, String.class);
+				Signature signature = parseCall(args[3], src, Signature.class);
+				Object[] a = signature.getClassArray();
+
+				Class c = (Class) store.getObject(classID);
+				Method m = null;
+				Constructor cs = null;
+				Object o = null;
+				if (methodName.equals("<init>")
+						|| methodName.equals("<clinit>")) {
+					o = cs = c.getConstructor(signature.getClassArray());
+					store.reference(cs);
+				} else {
+					o = m = c.getMethod(methodName, signature.getClassArray());
+					store.reference(m);
+				}
+				PluginDebug.debug(o + " has id " + store.getIdentifier(o));
+				write(reference, args[0] + " " + store.getIdentifier(o));
+			} else if (message.startsWith("GetStaticFieldID")
+					|| message.startsWith("GetFieldID")) {
+				String[] args = message.split(" ");
+				Integer classID = parseCall(args[1], src, Integer.class);
+				String fieldName = parseCall(args[2], src, String.class);
+				Signature signature = parseCall(args[3], src, Signature.class);
+
+				Class c = (Class) store.getObject(classID);
+				Field f = null;
+				f = c.getField(fieldName);
+
+				store.reference(f);
+
+				write(reference, "GetStaticFieldID " + store.getIdentifier(f));
+			} else if (message.startsWith("GetStaticField")) {
+				String[] args = message.split(" ");
+				String type = parseCall(args[1], src, String.class);
+				Integer classID = parseCall(args[1], src, Integer.class);
+				Integer fieldID = parseCall(args[2], src, Integer.class);
+
+				final Class c = (Class) store.getObject(classID);
+				final Field f = (Field) store.getObject(fieldID);
+
+				AccessControlContext acc = getAccessControlContext(identifier);
+
+				Object ret = AccessController.doPrivileged(new PrivilegedAction<Object> () {
+					public Object run() {
+						try {
+							return f.get(c);
+						} catch (Throwable t) {
+							return t;
+						}
+					}
+				}, acc);
+
+				if (ret instanceof Throwable)
+					throw (Throwable) ret;
+
+				// System.out.println ("FIELD VALUE: " + ret);
+				if (ret == null) {
+					write(reference, "GetStaticField 0");
+				} else if (f.getType() == Boolean.TYPE
+						|| f.getType() == Byte.TYPE
+						|| f.getType() == Character.TYPE
+						|| f.getType() == Short.TYPE
+						|| f.getType() == Integer.TYPE
+						|| f.getType() == Long.TYPE
+						|| f.getType() == Float.TYPE
+						|| f.getType() == Double.TYPE) {
+					write(reference, "GetStaticField " + ret);
+				} else {
+					// Track returned object.
+					store.reference(ret);
+					write(reference, "GetStaticField "
+							+ store.getIdentifier(ret));
+				}
+			} else if (message.startsWith("SetStaticField")) {
+				String[] args = message.split(" ");
+				String type = parseCall(args[1], src, String.class);
+				Integer classID = parseCall(args[2], src, Integer.class);
+				Integer fieldID = parseCall(args[3], src, Integer.class);
+
+				Object value = null;
+				if (Signature.primitiveNameToType(type) != null) {
+					value = parseArgs(args[4], Signature
+							.primitiveNameToType(type));
+					// System.out.println ("HERE1: " + value);
+				} else {
+					value = parseArgs(args[3], Object.class);
+					// System.out.println ("HERE2: " + value);
+				}
+
+				final Class c = (Class) store.getObject(classID);
+				final Field f = (Field) store.getObject(fieldID);
+
+				final Object fValue = value;
+				AccessControlContext acc = getAccessControlContext(identifier);
+
+				Object ret = AccessController.doPrivileged(new PrivilegedAction<Object> () {
+					public Object run() {
+						try {
+							f.set(c, fValue);
+						} catch (Throwable t) {
+							return t;
+						}
+						
+						return null;
+					}
+				}, acc);
+
+				if (ret instanceof Throwable)
+					throw (Throwable) ret;
+
+				write(reference, "SetStaticField");
+			} else if (message.startsWith("SetField")) {
+				String[] args = message.split(" ");
+				String type = parseCall(args[1], src, String.class);
+				Integer objectID = parseCall(args[2], src, Integer.class);
+				Integer fieldID = parseCall(args[3], src, Integer.class);
+
+				Object value = null;
+				if (Signature.primitiveNameToType(type) != null) {
+					value = parseArgs(args[4], Signature
+							.primitiveNameToType(type));
+					// System.out.println ("HERE1: " + value);
+				} else {
+					value = parseArgs(args[3], Object.class);
+					// System.out.println ("HERE2: " + value);
+				}
+
+				final Object o = (Object) store.getObject(objectID);
+				final Field f = (Field) store.getObject(fieldID);
+
+				final Object fValue = value;
+				AccessControlContext acc = getAccessControlContext(identifier);
+
+				Object ret = AccessController.doPrivileged(new PrivilegedAction<Object> () {
+					public Object run() {
+						try {
+							f.set(o, fValue);
+						} catch (Throwable t) {
+							return t;
+						}
+						
+						return null;
+					}
+				}, acc);
+
+				if (ret instanceof Throwable)
+					throw (Throwable) ret;
+
+				write(reference, "SetField");
+			} else if (message.startsWith("GetObjectArrayElement")) {
+				String[] args = message.split(" ");
+				Integer arrayID = parseCall(args[1], src, Integer.class);
+				Integer index = parseCall(args[2], src, Integer.class);
+
+				Object[] o = (Object[]) store.getObject(arrayID);
+				Object ret = null;
+
+				ret = o[index];
+
+				// Track returned object.
+				store.reference(ret);
+				// System.out.println ("array element: " + index + " " + ret);
+				write(reference, "GetObjectArrayElement "
+						+ store.getIdentifier(ret));
+			} else if (message.startsWith("SetObjectArrayElement")) {
+				String[] args = message.split(" ");
+				Integer arrayID = parseCall(args[1], src, Integer.class);
+				Integer index = parseCall(args[2], src, Integer.class);
+				Integer objectID = parseCall(args[3], src, Integer.class);
+
+				Object[] o = (Object[]) store.getObject(arrayID);
+				Object toSet = (Object) store.getObject(objectID);
+
+				o[index] = toSet;
+
+				write(reference, "SetObjectArrayElement");
+			} else if (message.startsWith("GetArrayLength")) {
+				String[] args = message.split(" ");
+				Integer arrayID = parseCall(args[1], src, Integer.class);
+
+				System.out.println("ARRAYID: " + arrayID);
+				Object o = (Object) store.getObject(arrayID);
+				int len = 0;
+				len = Array.getLength(o);
+				// System.out.println ("Returning array length: " + len);
+
+				// System.out.println ("array length: " + o + " " + len);
+				write(reference, "GetArrayLength " + Array.getLength(o));
+			} else if (message.startsWith("GetField")) {
+				String[] args = message.split(" ");
+				String type = parseCall(args[1], src, String.class);
+				Integer objectID = parseCall(args[1], src, Integer.class);
+				Integer fieldID = parseCall(args[2], src, Integer.class);
+
+				final Object o = (Object) store.getObject(objectID);
+				final Field f = (Field) store.getObject(fieldID);
+
+				AccessControlContext acc = getAccessControlContext(identifier);
+
+				Object ret = AccessController.doPrivileged(new PrivilegedAction<Object> () {
+					public Object run() {
+						try {
+							return f.get(o);
+						} catch (Throwable t) {
+							return t;
+						}
+					}
+				}, acc);
+
+				if (ret instanceof Throwable)
+					throw (Throwable) ret;
+
+				// System.out.println ("FIELD VALUE: " + ret);
+				if (ret == null) {
+					write(reference, "GetField 0");
+				} else if (f.getType() == Boolean.TYPE
+						|| f.getType() == Byte.TYPE
+						|| f.getType() == Character.TYPE
+						|| f.getType() == Short.TYPE
+						|| f.getType() == Integer.TYPE
+						|| f.getType() == Long.TYPE
+						|| f.getType() == Float.TYPE
+						|| f.getType() == Double.TYPE) {
+					write(reference, "GetField " + ret);
+				} else {
+					// Track returned object.
+					store.reference(ret);
+					write(reference, "GetField " + store.getIdentifier(ret));
+				}
+			} else if (message.startsWith("GetObjectClass")) {
+				int oid = Integer.parseInt(message.substring("GetObjectClass"
+						.length() + 1));
+				// System.out.println ("GETTING CLASS FOR: " + oid);
+				Class c = store.getObject(oid).getClass();
+				// System.out.println (" OBJ: " + store.getObject(oid));
+				// System.out.println (" CLS: " + c);
+				store.reference(c);
+
+				write(reference, "GetObjectClass " + store.getIdentifier(c));
+			} else if (message.startsWith("CallStaticMethod")) {
+				String[] args = message.split(" ");
+				Integer classID = parseCall(args[1], src, Integer.class);
+				Integer methodID = parseCall(args[2], src, Integer.class);
+
+				System.out.println("GETTING: " + methodID);
+				final Method m = (Method) store.getObject(methodID);
+				System.out.println("GOT: " + m);
+				Class[] argTypes = m.getParameterTypes();
+
+				Object[] arguments = new Object[argTypes.length];
+				for (int i = 0; i < argTypes.length; i++) {
+					arguments[i] = parseArgs(args[3 + i], argTypes[i]);
+					// System.out.println ("GOT ARG: " + argTypes[i] + " " +
+					// arguments[i]);
+				}
+
+				// System.out.println ("Calling " + m);
+
+				final Object[] fArguments = arguments;
+				AccessControlContext acc = getAccessControlContext(identifier);
+
+				Object ret = AccessController.doPrivileged(new PrivilegedAction<Object> () {
+					public Object run() {
+						try {
+							return m.invoke(null, fArguments);
+						} catch (Throwable t) {
+							return t;
+						}
+					}
+				}, acc);
+
+				if (ret instanceof Throwable)
+					throw (Throwable) ret;
+
+				// if (ret != null)
+				// System.out.println ("RETURN VALUE: " + ret + " " +
+				// ret.getClass());
+				// else
+				// System.out.println ("RETURN VALUE: " + ret);
+				if (ret == null) {
+					write(reference, "CallStaticMethod void");
+				} else if (m.getReturnType() == Boolean.TYPE
+						|| m.getReturnType() == Byte.TYPE
+						|| m.getReturnType() == Short.TYPE
+						|| m.getReturnType() == Integer.TYPE
+						|| m.getReturnType() == Long.TYPE
+						|| m.getReturnType() == Float.TYPE
+						|| m.getReturnType() == Double.TYPE) {
+					write(reference, "CallStaticMethod " + ret);
+				} else if (m.getReturnType() == Character.TYPE) {
+					char ch = (Character) ret;
+					int high = (((int) ch) >> 8) & 0x0ff;
+					int low = ((int) ch) & 0x0ff;
+					write(reference, "CallStaticMethod " + low + "_" + high);
+				} else {
+					// Track returned object.
+					store.reference(ret);
+					write(reference, "CallStaticMethod "
+							+ store.getIdentifier(ret));
+				}
+			} else if (message.startsWith("CallMethod")) {
+				String[] args = message.split(" ");
+				Integer objectID = parseCall(args[1], src, Integer.class);
+				Integer methodID = parseCall(args[2], src, Integer.class);
+
+				final Object o = (Object) store.getObject(objectID);
+				final Method m = (Method) store.getObject(methodID);
+				Class[] argTypes = m.getParameterTypes();
+
+				Object[] arguments = new Object[argTypes.length];
+				for (int i = 0; i < argTypes.length; i++) {
+					arguments[i] = parseArgs(args[3 + i], argTypes[i]);
+					PluginDebug.debug("GOT ARG: " + argTypes[i] + " "
+							+ arguments[i]);
+				}
+
+				String collapsedArgs = "";
+				for (String s : args) {
+					collapsedArgs += " " + s;
+				}
+
+				PluginDebug.debug("Calling method " + m + " on object " + o
+						+ " with " + arguments);
+
+				AccessControlContext acc = getAccessControlContext(identifier);
+
+				final Object[] fArguments = arguments;
+				Object ret = AccessController.doPrivileged(new PrivilegedAction<Object> () {
+					public Object run() {
+						try {
+							return m.invoke(o, fArguments);
+						} catch (Throwable t) {
+							return t;
+						}
+					}
+				}, acc);
+
+				if (ret instanceof Throwable)
+					throw (Throwable) ret;
+
+				String retO;
+				if (ret == null) {
+					retO = "null";
+				} else {
+					retO = ret.getClass().toString();
+				}
+
+				PluginDebug.debug("Calling " + m + " on " + o + " with "
+						+ collapsedArgs + " and that returned: " + ret
+						+ " of type " + retO);
+
+				if (ret == null) {
+					write(reference, "CallMethod void");
+				} else if (m.getReturnType() == Boolean.TYPE
+						|| m.getReturnType() == Byte.TYPE
+						|| m.getReturnType() == Short.TYPE
+						|| m.getReturnType() == Integer.TYPE
+						|| m.getReturnType() == Long.TYPE
+						|| m.getReturnType() == Float.TYPE
+						|| m.getReturnType() == Double.TYPE) {
+					write(reference, "CallMethod " + ret);
+				} else if (m.getReturnType() == Character.TYPE) {
+					char ch = (Character) ret;
+					int high = (((int) ch) >> 8) & 0x0ff;
+					int low = ((int) ch) & 0x0ff;
+					write(reference, "CallMethod " + low + "_" + high);
+				} else {
+					// Track returned object.
+					store.reference(ret);
+					write(reference, "CallMethod " + store.getIdentifier(ret));
+				}
+			} else if (message.startsWith("GetSuperclass")) {
+				String[] args = message.split(" ");
+				Integer classID = parseCall(args[1], src, Integer.class);
+				Class c = null;
+				Class ret = null;
+
+				c = (Class) store.getObject(classID);
+				ret = c.getSuperclass();
+				store.reference(ret);
+
+				write(reference, "GetSuperclass " + store.getIdentifier(ret));
+			} else if (message.startsWith("IsAssignableFrom")) {
+				String[] args = message.split(" ");
+				Integer classID = parseCall(args[1], src, Integer.class);
+				Integer superclassID = parseCall(args[2], src, Integer.class);
+
+				boolean result = false;
+				Class clz = (Class) store.getObject(classID);
+				Class sup = (Class) store.getObject(superclassID);
+
+				result = sup.isAssignableFrom(clz);
+
+				write(reference, "IsAssignableFrom " + (result ? "1" : "0"));
+			} else if (message.startsWith("IsInstanceOf")) {
+				String[] args = message.split(" ");
+				Integer objectID = parseCall(args[1], src, Integer.class);
+				Integer classID = parseCall(args[2], src, Integer.class);
+
+				boolean result = false;
+				Object o = (Object) store.getObject(objectID);
+				Class c = (Class) store.getObject(classID);
+
+				result = c.isInstance(o);
+
+				write(reference, "IsInstanceOf " + (result ? "1" : "0"));
+			} else if (message.startsWith("GetStringUTFLength")) {
+				String[] args = message.split(" ");
+				Integer stringID = parseCall(args[1], src, Integer.class);
+
+				String o = null;
+				byte[] b = null;
+				o = (String) store.getObject(stringID);
+				b = o.getBytes("UTF-8");
+				// System.out.println ("STRING UTF-8 LENGTH: " + o + " " +
+				// b.length);
+
+				write(reference, "GetStringUTFLength " + o.length());
+			} else if (message.startsWith("GetStringLength")) {
+				String[] args = message.split(" ");
+				Integer stringID = parseCall(args[1], src, Integer.class);
+
+				String o = null;
+				byte[] b = null;
+				o = (String) store.getObject(stringID);
+				b = o.getBytes("UTF-16LE");
+				// System.out.println ("STRING UTF-16 LENGTH: " + o + " " +
+				// b.length);
+
+				// System.out.println ("Java: GetStringLength " + b.length);
+				write(reference, "GetStringLength " + o.length());
+			} else if (message.startsWith("GetStringUTFChars")) {
+				String[] args = message.split(" ");
+				Integer stringID = parseCall(args[1], src, Integer.class);
+
+				String o = null;
+				byte[] b = null;
+				StringBuffer buf = null;
+				o = (String) store.getObject(stringID);
+				b = o.getBytes("UTF-8");
+				buf = new StringBuffer(b.length * 2);
+				buf.append(b.length);
+				for (int i = 0; i < b.length; i++)
+					buf
+							.append(" "
+									+ Integer
+											.toString(((int) b[i]) & 0x0ff, 16));
+
+				// System.out.println ("Java: GetStringUTFChars: " + o);
+				// //System.out.println ("String UTF BYTES: " + buf);
+				write(reference, "GetStringUTFChars " + buf);
+			} else if (message.startsWith("GetStringChars")) {
+				String[] args = message.split(" ");
+				Integer stringID = parseCall(args[1], src, Integer.class);
+
+				String o = null;
+				byte[] b = null;
+				StringBuffer buf = null;
+				o = (String) store.getObject(stringID);
+				// FIXME: LiveConnect uses UCS-2.
+				b = o.getBytes("UTF-16LE");
+				buf = new StringBuffer(b.length * 2);
+				buf.append(b.length);
+				for (int i = 0; i < b.length; i++)
+					buf
+							.append(" "
+									+ Integer
+											.toString(((int) b[i]) & 0x0ff, 16));
+
+				System.out.println("Java: GetStringChars: " + o);
+				System.out.println("  String BYTES: " + buf);
+				write(reference, "GetStringChars " + buf);
+			} else if (message.startsWith("NewArray")) {
+				String[] args = message.split(" ");
+				String type = parseCall(args[1], src, String.class);
+				Integer length = parseCall(args[2], src, Integer.class);
+
+				// System.out.println ("CALLING: NewArray: " + type + " " +
+				// length + " "
+				// + Signature.primitiveNameToType(type));
+
+				Object newArray = null;
+				newArray = Array.newInstance(Signature
+						.primitiveNameToType(type), length);
+
+				store.reference(newArray);
+				write(reference, "NewArray " + store.getIdentifier(newArray));
+			} else if (message.startsWith("NewObjectArray")) {
+				String[] args = message.split(" ");
+				Integer length = parseCall(args[1], src, Integer.class);
+				Integer classID = parseCall(args[2], src, Integer.class);
+				Integer objectID = parseCall(args[3], src, Integer.class);
+
+				// System.out.println ("CALLING: NewObjectArray: " +
+				// classID + " " + length + " "
+				// + objectID);
+
+				Object newArray = null;
+				newArray = Array.newInstance((Class) store.getObject(classID),
+						length);
+
+				Object[] array = (Object[]) newArray;
+				for (int i = 0; i < array.length; i++)
+					array[i] = store.getObject(objectID);
+				store.reference(newArray);
+				write(reference, "NewObjectArray "
+						+ store.getIdentifier(newArray));
+			} else if (message.startsWith("NewObject")) {
+				String[] args = message.split(" ");
+				Integer classID = parseCall(args[1], src, Integer.class);
+				Integer methodID = parseCall(args[2], src, 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 = getAccessControlContext(identifier);
+
+				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("NewString")) {
+				System.out.println("MESSAGE: " + message);
+				String[] args = message.split(" ");
+				Integer strlength = parseCall(args[1], src, Integer.class);
+				int bytelength = 2 * strlength;
+				byte[] byteArray = new byte[bytelength];
+				String ret = null;
+				for (int i = 0; i < strlength; i++) {
+					int c = parseCall(args[2 + i], src, Integer.class);
+					System.out.println("char " + i + " " + c);
+					// Low.
+					byteArray[2 * i] = (byte) (c & 0x0ff);
+					// High.
+					byteArray[2 * i + 1] = (byte) ((c >> 8) & 0x0ff);
+				}
+				ret = new String(byteArray, 0, bytelength, "UTF-16LE");
+				System.out.println("NEWSTRING: " + ret);
+
+				// System.out.println ("NEWOBJ: CALLED: " + ret);
+				// System.out.println ("NEWOBJ: CALLED: " +
+				// store.getObject(ret));
+				store.reference(ret);
+				write(reference, "NewString " + store.getIdentifier(ret));
+			} else if (message.startsWith("NewStringUTF")) {
+				System.out.println("MESSAGE: " + message);
+				String[] args = message.split(" ");
+				byte[] byteArray = new byte[60];
+				String ret = null;
+				int i = 0;
+				int c = 0;
+				while (((byte) c) != 0) {
+					c = parseCall(args[1 + i], src, Integer.class);
+					byteArray[i] = (byte) c;
+					i++;
+					if (i == byteArray.length) {
+						byte[] newByteArray = new byte[2 * byteArray.length];
+						System.arraycopy(byteArray, 0, newByteArray, 0,
+								byteArray.length);
+						byteArray = newByteArray;
+					}
+				}
+				byteArray[i] = (byte) 0;
+				ret = new String(byteArray, "UTF-8");
+				System.out.println("NEWSTRINGUTF: " + ret);
+
+				store.reference(ret);
+				write(reference, "NewStringUTF " + store.getIdentifier(ret));
+			} else if (message.startsWith("ExceptionOccurred")) {
+				System.out.println("EXCEPTION: " + throwable);
+				if (throwable != null)
+					store.reference(throwable);
+				write(reference, "ExceptionOccurred "
+						+ store.getIdentifier(throwable));
+			} else if (message.startsWith("ExceptionClear")) {
+				if (throwable != null)
+					store.unreference(store.getIdentifier(throwable));
+				throwable = null;
+				write(reference, "ExceptionClear");
+			} else if (message.startsWith("DeleteGlobalRef")) {
+				String[] args = message.split(" ");
+				Integer id = parseCall(args[1], src, Integer.class);
+				store.unreference(id);
+				write(reference, "DeleteGlobalRef");
+			} else if (message.startsWith("DeleteLocalRef")) {
+				String[] args = message.split(" ");
+				Integer id = parseCall(args[1], src, Integer.class);
+				store.unreference(id);
+				write(reference, "DeleteLocalRef");
+			} else if (message.startsWith("NewGlobalRef")) {
+				String[] args = message.split(" ");
+				Integer id = parseCall(args[1], src, Integer.class);
+				store.reference(store.getObject(id));
+				write(reference, "NewGlobalRef " + id);
+			}
+		} catch (Throwable t) {
+			t.printStackTrace();
+			String msg = t.getCause() != null ? t.getCause().getMessage() : t.getMessage();
+			this.streamhandler.write("instance " + identifier + " reference " + reference + " Error " + msg);
+
+			// ExceptionOccured is only called after Callmethod() by mozilla. So
+			// for exceptions that are not related to CallMethod, we need a way
+			// to log them. This is how we do it.. send an error message to the
+			// c++ side to let it know that something went wrong, and it will do
+			// the right thing to let mozilla know
+
+			// Store the cause as the actual exception. This is needed because 
+			// the exception we get here will always be an 
+			// "InvocationTargetException" due to the use of reflection above
+			if (message.startsWith("CallMethod") || message.startsWith("CallStaticMethod"))
+				throwable = t.getCause();
+		}
+	}
+
+	private void write(int reference, String message) {
+		PluginDebug.debug("appletviewer writing " + message);
+		streamhandler.write("context " + identifier + " reference " + reference
+				+ " " + message);
+	}
+	
+	public void dumpStore() {
+		store.dump();
+	}
+
+	public Object getObject(int identifier) {
+		return store.getObject(identifier);		
+	}
+
+	public int getIdentifier(Object o) {
+		return store.getIdentifier(o);
+	}
+
+	public void store(Object o) {
+		store.reference(o);
+	}
+
+	/**
+	 * Returns an 
+	 * 
+	 * @param identifier The unique instance identity of the applet for which the context is needed
+	 * @return The context associated with the given applet
+	 */
+	public AccessControlContext getAccessControlContext(int identifier) {
+		
+		// TODO: 
+		// 1. Find applet URL
+		// 2. If startsWith file://, some permissions are lax
+		// 3. If not, find out associated permissions
+
+		// Deny everything for now
+		PermissionCollection pc = new PermissionCollection(){
+			@Override
+			public boolean implies(Permission permission) {
+				// TODO Auto-generated method stub
+				return false;
+			}
+		
+			@Override
+			public Enumeration<Permission> elements() {
+				// TODO Auto-generated method stub
+				return null;
+			}
+		
+			@Override
+			public void add(Permission permission) {
+				// TODO Auto-generated method stub
+			}
+		};
+
+		ProtectionDomain pd = new ProtectionDomain(PluginAppletSecurityContext.class.getProtectionDomain().getCodeSource(), pc);
+		return new AccessControlContext(new ProtectionDomain[] {pd});
+	}
+}
--- a/plugin/icedtea/sun/applet/PluginCallRequestFactory.java	Wed Oct 01 05:52:01 2008 -0400
+++ b/plugin/icedtea/sun/applet/PluginCallRequestFactory.java	Wed Oct 01 16:40:56 2008 -0400
@@ -1,7 +1,20 @@
 package sun.applet;
 
-public interface PluginCallRequestFactory {
+
+public class PluginCallRequestFactory {
+
+	public PluginCallRequest getPluginCallRequest(String id, String message, String returnString) {
 
-	public PluginCallRequest getPluginCallRequest(String id, String message, String returnString);
-	
+		if (id == "member") {
+			return new GetMemberPluginCallRequest(message, returnString);
+		} else if (id == "void") {
+			return new VoidPluginCallRequest(message, returnString);
+		} else if (id == "window") {
+			return new GetWindowPluginCallRequest(message, returnString);
+		} else {
+			throw new RuntimeException ("Unknown plugin call request type requested from factory");
+		}
+		
+	}
+
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugin/icedtea/sun/applet/PluginMain.java	Wed Oct 01 16:40:56 2008 -0400
@@ -0,0 +1,188 @@
+/*
+ * Copyright 1999-2006 Sun Microsystems, Inc.  All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Sun designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Sun in the LICENSE file that accompanied this code.
+ *
+ * This code 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
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+package sun.applet;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.net.Socket;
+import java.security.Policy;
+import java.util.Enumeration;
+import java.util.Properties;
+
+
+import net.sourceforge.jnlp.runtime.JNLPRuntime;
+
+/**
+ * The main entry point into PluginAppletViewer.
+ */
+public class PluginMain
+{
+	final boolean redirectStreams = true;
+	static PluginStreamHandler streamHandler;
+	
+    // This is used in init().	Getting rid of this is desirable but depends
+    // on whether the property that uses it is necessary/standard.
+    public static final String theVersion = System.getProperty("java.version");
+    
+    private PluginAppletSecurityContext securityContext;
+
+    /**
+     * The main entry point into AppletViewer.
+     */
+    public static void main(String args[])
+	throws IOException
+    {
+
+    	if (args.length != 1) {
+    		// Indicate to plugin that appletviewer is installed correctly.
+    		System.exit(0);
+    	}
+
+    	int port = 0;
+    	try {
+    		port = Integer.parseInt(args[0]);
+    	} catch (NumberFormatException e) {
+    		System.err.println("Failed to parse port number: " + e);
+    		System.exit(1);
+    	}
+
+    	PluginMain pm = new PluginMain();
+    	
+    }
+
+    public PluginMain() {
+    	
+    	if (redirectStreams) {
+    		try {
+    			File errFile = new File("/tmp/java.stderr");
+    			File outFile = new File("/tmp/java.stdout");
+
+    			System.setErr(new PrintStream(new FileOutputStream(errFile)));
+    			System.setOut(new PrintStream(new FileOutputStream(outFile)));
+
+    		} catch (Exception e) {
+    			System.err.println("Unable to redirect streams");
+    			e.printStackTrace();
+    		}
+    	}
+
+    	connect(50007);
+
+    	securityContext = new PluginAppletSecurityContext(0);
+    	securityContext.setStreamhandler(streamHandler);
+    	AppletSecurityContextManager.addContext(0, securityContext);
+
+		PluginAppletViewer.setStreamhandler(streamHandler);
+		PluginAppletViewer.setPluginCallRequestFactory(new PluginCallRequestFactory());
+
+    	init();
+
+		// Streams set. Start processing.
+		streamHandler.startProcessing();
+    }
+
+	public void connect(int port) {
+    	/*
+    	 * Code for TCP/IP communication
+    	 */ 
+    	Socket socket = null;
+
+    	try {
+    		socket = new Socket("localhost", port);
+    	} catch (Exception e) {
+    		e.printStackTrace();
+    	}
+    	
+    	System.err.println("Socket initialized. Proceeding with start()");
+
+		try {
+			streamHandler = new PluginStreamHandler(socket.getInputStream(), socket.getOutputStream());
+	    	System.err.println("Streams initialized");
+		} catch (IOException ioe) {
+			ioe.printStackTrace();
+		}
+	}
+
+	private static void init() {
+		Properties avProps = new Properties();
+
+		// ADD OTHER RANDOM PROPERTIES
+		// XXX 5/18 need to revisit why these are here, is there some
+		// standard for what is available?
+
+		// Standard browser properties
+		avProps.put("browser", "sun.applet.AppletViewer");
+		avProps.put("browser.version", "1.06");
+		avProps.put("browser.vendor", "Sun Microsystems Inc.");
+		avProps.put("http.agent", "Java(tm) 2 SDK, Standard Edition v" + theVersion);
+
+		// Define which packages can be extended by applets
+		// XXX 5/19 probably not needed, not checked in AppletSecurity
+		avProps.put("package.restrict.definition.java", "true");
+		avProps.put("package.restrict.definition.sun", "true");
+
+		// Define which properties can be read by applets.
+		// A property named by "key" can be read only when its twin
+		// property "key.applet" is true.  The following ten properties
+		// are open by default.	 Any other property can be explicitly
+		// opened up by the browser user by calling appletviewer with
+		// -J-Dkey.applet=true
+		avProps.put("java.version.applet", "true");
+		avProps.put("java.vendor.applet", "true");
+		avProps.put("java.vendor.url.applet", "true");
+		avProps.put("java.class.version.applet", "true");
+		avProps.put("os.name.applet", "true");
+		avProps.put("os.version.applet", "true");
+		avProps.put("os.arch.applet", "true");
+		avProps.put("file.separator.applet", "true");
+		avProps.put("path.separator.applet", "true");
+		avProps.put("line.separator.applet", "true");
+
+		// Read in the System properties.  If something is going to be
+		// over-written, warn about it.
+		Properties sysProps = System.getProperties();
+		for (Enumeration e = sysProps.propertyNames(); e.hasMoreElements(); ) {
+			String key = (String) e.nextElement();
+			String val = (String) sysProps.getProperty(key);
+			avProps.setProperty(key, val);
+		}
+
+		// INSTALL THE PROPERTY LIST
+		System.setProperties(avProps);
+
+		// REMIND: Create and install a socket factory!
+	}
+
+    static boolean messageAvailable() {
+    	return streamHandler.messageAvailable();
+    }
+
+    static String getMessage() {
+    	return streamHandler.getMessage();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugin/icedtea/sun/applet/PluginMessageConsumer.java	Wed Oct 01 16:40:56 2008 -0400
@@ -0,0 +1,67 @@
+package sun.applet;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+
+import sun.applet.AppletSecurity;
+
+class PluginMessageConsumer {
+
+	int MAX_WORKERS = 3;
+	LinkedList<String> readQueue = new LinkedList<String>();
+	ArrayList<PluginMessageHandlerWorker> workers = new ArrayList<PluginMessageHandlerWorker>();
+	PluginStreamHandler streamHandler = null;
+
+	public PluginMessageConsumer(PluginStreamHandler streamHandler) {
+		
+		AppletSecurity as = new AppletSecurity();
+		this.streamHandler = streamHandler;
+
+		for (int i=0; i < MAX_WORKERS; i++) {
+			System.err.println("Creating worker " + i);
+			PluginMessageHandlerWorker worker = new PluginMessageHandlerWorker(streamHandler, i, as);
+			worker.start();
+			workers.add(worker);
+		}
+	}
+
+	public void consume(String message) {
+		
+		PluginDebug.debug("Consumer received message " + message);
+		
+		synchronized(readQueue) {
+			readQueue.add(message);
+		}
+
+		PluginDebug.debug("Message " + message + " added to queue. Looking for free worker...");
+		final PluginMessageHandlerWorker worker = getFreeWorker();
+
+		synchronized(readQueue) {
+			if (readQueue.size() > 0) {
+				worker.setmessage(readQueue.poll());
+			}
+		}
+
+		worker.interrupt();
+	}
+
+	private PluginMessageHandlerWorker getFreeWorker() {
+		
+		// FIXME: Can be made more efficient by having an idle worker pool
+		
+		while (true) {
+			for (PluginMessageHandlerWorker worker: workers) {
+				if (worker.isFree()) {
+					PluginDebug.debug("Found free worker with id " + worker.getWorkerId());
+					// mark it busy before returning
+					worker.busy();
+					return worker;
+				}
+			}
+			Thread.yield();
+		}
+
+		//throw new RuntimeException("Out of message handler workers");
+	}
+	
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugin/icedtea/sun/applet/PluginMessageHandlerWorker.java	Wed Oct 01 16:40:56 2008 -0400
@@ -0,0 +1,78 @@
+package sun.applet;
+
+
+class PluginMessageHandlerWorker extends Thread {
+
+	private boolean free = true;
+	private int id;
+	private String message = null;
+	private SecurityManager sm;
+	PluginStreamHandler streamHandler = null;
+
+	public PluginMessageHandlerWorker(PluginStreamHandler streamHandler, int id, SecurityManager sm) {
+		this.id = id;
+		this.streamHandler = streamHandler;
+		this.sm = sm;
+	}
+
+	public void setmessage(String message) {
+		this.message = message;
+	}
+
+	public void run() {
+		while (true) {
+
+			if (message != null) {
+				
+				// ideally, whoever returns things object should mark it 
+				// busy first, but just in case..
+				busy();
+
+				try {
+					streamHandler.handleMessage(message);
+				} catch (PluginException pe) {
+					/*
+					   catch the exception and DO NOTHING. The plugin should take over after 
+					   this error and let the user know. We don't quit because otherwise the 
+					   exception will spread to the rest of the applets which is a no-no
+					 */ 
+				}
+
+				this.message = null;
+			} else {
+				
+				// Sleep when there is nothing to do
+				try {
+					Thread.sleep(Integer.MAX_VALUE);
+					System.err.println("Consumer thread " + id + " sleeping...");
+				} catch (InterruptedException ie) {
+					System.err.println("Consumer thread " + id + " woken...");
+					// nothing.. someone woke us up, see if there 
+					// is work to do
+				}
+			}
+			
+			// mark ourselves free again
+			free();
+		}
+	}
+	
+	
+	
+	public int getWorkerId() {
+		return id;
+	}
+
+	public void busy() {
+		this.free = false;
+	}
+
+	
+	public void free() {
+		this.free = true;
+	}
+	
+	public boolean isFree() {
+		return free;
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugin/icedtea/sun/applet/PluginObjectStore.java	Wed Oct 01 16:40:56 2008 -0400
@@ -0,0 +1,121 @@
+/* PluginObjectStore -- manage identifier-to-object mapping
+   Copyright (C) 2008  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.util.*;
+import java.lang.reflect.*;
+import java.io.*;
+
+public class PluginObjectStore
+{
+    private static HashMap<Integer, Object> objects = new HashMap();
+    private static HashMap<Integer, Integer> counts = new HashMap();
+    private static HashMap<Object, Integer> identifiers = new HashMap();
+    // FIXME:
+    //
+    // IF uniqueID == MAX_LONG, uniqueID =
+    // 0 && wrapped = true
+    //
+    // if (wrapped), check if
+    // objects.get(uniqueID) returns null
+    //
+    // if yes, use uniqueID, if no,
+    // uniqueID++ and keep checking
+    // or:
+    // stack of available ids:
+    // derefed id -> derefed id -> nextUniqueIdentifier
+    private static int nextUniqueIdentifier = 1;
+
+    public Object getObject(Integer identifier) {
+        return objects.get(identifier);
+    }
+
+    public Integer getIdentifier(Object object) {
+        if (object == null)
+            return 0;
+        return identifiers.get(object);
+    }
+
+    public void reference(Object object) {
+        Integer identifier = identifiers.get(object);
+        if (identifier == null) {
+            objects.put(nextUniqueIdentifier, object);
+            counts.put(nextUniqueIdentifier, 1);
+            identifiers.put(object, nextUniqueIdentifier);
+            System.out.println("JAVA ADDED: " + nextUniqueIdentifier);
+            System.out.println("JAVA REFERENCED: " + nextUniqueIdentifier
+                               + " to: 1");
+            nextUniqueIdentifier++;
+        } else {
+            counts.put(identifier, counts.get(identifier) + 1);
+            System.out.println("JAVA REFERENCED: " + identifier +
+                               " to: " + counts.get(identifier));
+        }
+    }
+
+    public void unreference(int identifier) {
+        Integer currentCount = counts.get(identifier);
+        if (currentCount == null) {
+            System.out.println("ERROR UNREFERENCING: " + identifier);
+            return;
+        }
+        if (currentCount == 1) {
+            System.out.println("JAVA DEREFERENCED: " + identifier
+                               + " to: 0");
+            Object object = objects.get(identifier);
+            objects.remove(identifier);
+            counts.remove(identifier);
+            identifiers.remove(object);
+            System.out.println("JAVA REMOVED: " + identifier);
+        } else {
+            counts.put(identifier, currentCount - 1);
+            System.out.println("JAVA DEREFERENCED: " +
+                               identifier + " to: " +
+                               counts.get(identifier));
+        }
+    }
+
+    public void dump() {
+   		Iterator i = objects.keySet().iterator();
+   		while (i.hasNext()) {
+   			Object key = i.next();
+   			System.err.println(key + "::" +  objects.get(key));
+   		}
+    }
+}
+
--- a/plugin/icedtea/sun/applet/PluginStreamHandler.java	Wed Oct 01 05:52:01 2008 -0400
+++ b/plugin/icedtea/sun/applet/PluginStreamHandler.java	Wed Oct 01 16:40:56 2008 -0400
@@ -1,20 +1,357 @@
 package sun.applet;
 
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.io.StreamTokenizer;
+import java.net.MalformedURLException;
+import java.nio.charset.Charset;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.LinkedList;
+import java.util.StringTokenizer;
+
 
-public interface PluginStreamHandler {
+public class PluginStreamHandler {
+
+    private BufferedReader pluginInputReader;
+    private StreamTokenizer pluginInputTokenizer;
+    private BufferedWriter pluginOutputWriter;
+    
+    private RequestQueue queue = new RequestQueue();
+
+	LinkedList<String> writeQueue = new LinkedList<String>();
+
+	PluginMessageConsumer consumer;
+	Boolean shuttingDown = false;
+	
+	PluginAppletViewer pav;
+	
+    public PluginStreamHandler(InputStream inputstream, OutputStream outputstream)
+    throws MalformedURLException, IOException
+    {
+
+    	System.err.println("Current context CL=" + Thread.currentThread().getContextClassLoader());
+    	try {
+			pav = (PluginAppletViewer) ClassLoader.getSystemClassLoader().loadClass("sun.applet.PluginAppletViewer").newInstance();
+			System.err.println("Loaded: " + pav + " CL=" + pav.getClass().getClassLoader());
+		} catch (InstantiationException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (IllegalAccessException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (ClassNotFoundException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+
+    	System.err.println("Creating consumer...");
+    	consumer = new PluginMessageConsumer(this);
 
-	public void postMessage(String s);
+    	// Set up input and output pipes.  Use UTF-8 encoding.
+    	pluginInputReader =
+    		new BufferedReader(new InputStreamReader(inputstream,
+    				Charset.forName("UTF-8")));
+    	pluginInputTokenizer = new StreamTokenizer(pluginInputReader);
+    	pluginInputTokenizer.resetSyntax();
+    	pluginInputTokenizer.whitespaceChars('\u0000', '\u0000');
+    	pluginInputTokenizer.wordChars('\u0001', '\u00FF');
+    	pluginOutputWriter =
+    		new BufferedWriter(new OutputStreamWriter
+    				(outputstream, Charset.forName("UTF-8")));
+
+    	/*
+	while(true) {
+            String message = read();
+            PluginDebug.debug(message);
+            handleMessage(message);
+            // TODO:
+            // write(queue.peek());
+	}
+    	 */
+    }
+
+    public void startProcessing() {
+
+    	Thread listenerThread = new Thread() {
+
+    		public void run() {
+    			
+    			while (true) {
+
+    				System.err.println("Waiting for data...");
+
+    				int readChar = -1;
+    				// blocking read, discard first character
+    				try {
+    					readChar = pluginInputReader.read();
+    				} catch (IOException ioe) {
+    					// plugin may have detached
+    				}
 
-	public void handleMessage(String message) throws PluginException;
+    				// if not disconnected
+    				if (readChar != -1) {
+    					String s = read();
+    					System.err.println("Got data, consuming " + s);
+    					consumer.consume(s);
+    				} else {
+    					try {
+    						// Close input/output channels to plugin.
+    						pluginInputReader.close();
+    						pluginOutputWriter.close();
+    					} catch (IOException exception) {
+    						// Deliberately ignore IOException caused by broken
+    						// pipe since plugin may have already detached.
+    					}
+    					AppletSecurityContextManager.dumpStore(0);
+    					System.err.println("APPLETVIEWER: exiting appletviewer");
+    					System.exit(0);
+    				}
+    			}
+    		}
+    	};
+    	
+    	listenerThread.start();
+    }
+    
+    public void postMessage(String s) {
+
+    	if (s == null || s.equals("shutdown")) {
+    	    try {
+    		// Close input/output channels to plugin.
+    		pluginInputReader.close();
+    		pluginOutputWriter.close();
+    	    } catch (IOException exception) {
+    		// Deliberately ignore IOException caused by broken
+    		// pipe since plugin may have already detached.
+    	    }
+    	    AppletSecurityContextManager.dumpStore(0);
+    	    System.err.println("APPLETVIEWER: exiting appletviewer");
+    	    System.exit(0);
+    	}
+
+   		//PluginAppletSecurityContext.contexts.get(0).store.dump();
+   		PluginDebug.debug("Plugin posted: " + s);
 
-	public void postCallRequest(PluginCallRequest request);
+		System.err.println("Consuming " + s);
+		consumer.consume(s);
+
+   		PluginDebug.debug("Added to queue");
+    }
+    
+    public void handleMessage(String message) throws PluginException {
+
+    	StringTokenizer st = new StringTokenizer(message, " ");
+
+    	String type = st.nextToken();
+    	final int identifier = Integer.parseInt(st.nextToken());
+
+    	String rest = "";
+    	int reference = -1;
+    	String src = null;
+
+    	String potentialReference = st.hasMoreTokens() ? st.nextToken() : "";
+
+    	// if the next token is reference, read it, else reset "rest"
+    	if (potentialReference.equals("reference")) {
+    		reference = Integer.parseInt(st.nextToken());
+    	} else {
+    		rest += potentialReference + " ";
+    	}
+
+    	String potentialSrc = st.hasMoreTokens() ? st.nextToken() : "";
+
+    	if (potentialSrc.equals("src")) {
+    		src = st.nextToken();
+    	} else {
+    		rest += potentialSrc + " ";
+    	}
+
+    	while (st.hasMoreElements()) {
+    		rest += st.nextToken();
+    		rest += " ";
+    	}
+
+    	rest = rest.trim();
+
+    	try {
+
+    		System.err.println("Breakdown -- type: " + type + " identifier: " + identifier + " reference: " + reference + " src: " + src + " rest: " + rest);
 
-	public void write(String message);
+    		if (rest.contains("JavaScriptGetWindow")
+    				|| rest.contains("JavaScriptGetMember")
+    				|| rest.contains("JavaScriptSetMember")
+    				|| rest.contains("JavaScriptGetSlot")
+    				|| rest.contains("JavaScriptSetSlot")
+    				|| rest.contains("JavaScriptEval")
+    				|| rest.contains("JavaScriptRemoveMember")
+    				|| rest.contains("JavaScriptCall")
+    				|| rest.contains("JavaScriptFinalize")
+    				|| rest.contains("JavaScriptToString")) {
+    			
+				finishCallRequest(rest);
+    			return;
+    		}
+
+    		final int freference = reference;
+    		final String frest = rest;
+
+    		if (type.equals("instance")) {
+    			PluginAppletViewer.handleMessage(identifier, freference,frest);
+    		} else if (type.equals("context")) {
+    			PluginDebug.debug("Sending to PASC: " + identifier + "/" + reference + " and " + rest);
+    			AppletSecurityContextManager.handleMessage(identifier, src, reference, rest);
+    		}
+    	} catch (Exception e) {
+    		throw new PluginException(this, identifier, reference, e);
+    	}
+    }
+
+    public void postCallRequest(PluginCallRequest request) {
+        synchronized(queue) {
+   			queue.post(request);
+        }
+    }
+
+    private void finishCallRequest(String message) {
+    	PluginDebug.debug ("DISPATCHCALLREQUESTS 1");
+    	synchronized(queue) {
+    		PluginDebug.debug ("DISPATCHCALLREQUESTS 2");
+    		PluginCallRequest request = queue.pop();
 
-	public boolean messageAvailable();
+    		// make sure we give the message to the right request 
+    		// in the queue.. for the love of God, MAKE SURE!
+
+    		// first let's be efficient.. if there was only one 
+    		// request in queue, we're already set
+    		if (queue.size() != 0) {
+
+    			int size = queue.size();
+    			int count = 0;
+
+    			while (!request.serviceable(message)) {
+
+    				// something is very wrong.. we have a message to 
+    				// process, but no one to service it
+    				if (count >= size) {
+    					throw new RuntimeException("Unable to find processor for message " + message);
+    				}
+
+    				// post request at the end of the queue
+    				queue.post(request);
+
+    				// Look at the next request
+    				request = queue.pop();
+
+    				count++;
+    			}
+
+    		}
+
+    		PluginDebug.debug ("DISPATCHCALLREQUESTS 3");
+    		if (request != null) {
+    			PluginDebug.debug ("DISPATCHCALLREQUESTS 5");
+    			synchronized(request) {
+    				request.parseReturn(message);
+    				request.notifyAll();
+    			}
+    			PluginDebug.debug ("DISPATCHCALLREQUESTS 6");
+    			PluginDebug.debug ("DISPATCHCALLREQUESTS 7");
+    		}
+    	}
+    	PluginDebug.debug ("DISPATCHCALLREQUESTS 8");
+    }
 
-	public String getMessage();
-	
-	public void startProcessing();
+    /**
+     * Read string from plugin.
+     *
+     * @return the read string
+     *
+     * @exception IOException if an error occurs
+     */
+    private String read()
+    {
+    	try {
+    		pluginInputTokenizer.nextToken();
+    	} catch (IOException e) {
+    		throw new RuntimeException(e);
+    	}
+    	String message = pluginInputTokenizer.sval;
+    	PluginDebug.debug("  PIPE: appletviewer read: " + message);
+    	if (message == null || message.equals("shutdown")) {
+    		synchronized(shuttingDown) {
+    			shuttingDown = true;
+    		}
+    		try {
+    			// Close input/output channels to plugin.
+    			pluginInputReader.close();
+    			pluginOutputWriter.close();
+    		} catch (IOException exception) {
+    			// Deliberately ignore IOException caused by broken
+    			// pipe since plugin may have already detached.
+    		}
+    		AppletSecurityContextManager.dumpStore(0);
+    		System.err.println("APPLETVIEWER: exiting appletviewer");
+    		System.exit(0);
+    	}
+    	return message;
+    }
+    
+    /**
+     * Write string to plugin.
+     * 
+     * @param message the message to write
+     *
+     * @exception IOException if an error occurs
+     */
+    public void write(String message)
+    {
 
-}
\ No newline at end of file
+    	System.err.println("  PIPE: appletviewer wrote: " + message);
+        synchronized(pluginOutputWriter) {
+        	try {
+        		pluginOutputWriter.write(message, 0, message.length());
+        		pluginOutputWriter.write(0);
+        		pluginOutputWriter.flush();
+        	} catch (IOException e) {
+        		// if we are shutting down, ignore write failures as 
+        		// pipe may have closed
+        		synchronized(shuttingDown) {
+        			if (!shuttingDown) {
+        				e.printStackTrace();
+        			}
+        		}
+
+        		// either ways, if the pipe is broken, there is nothing 
+        		// we can do anymore. Don't hang around.
+        		System.err.println("Unable to write to PIPE. APPLETVIEWER exiting");        		
+        		System.exit(1);
+        	}
+		}
+
+		return;
+    /*	
+    	synchronized(writeQueue) {
+            writeQueue.add(message);
+            System.err.println("  PIPE: appletviewer wrote: " + message);
+    	}
+	*/
+
+    }
+    
+    public boolean messageAvailable() {
+    	return writeQueue.size() != 0;
+    }
+
+    public String getMessage() {
+    	synchronized(writeQueue) {
+			String ret = writeQueue.size() > 0 ? writeQueue.poll() : "";
+    		return ret;
+    	}
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugin/icedtea/sun/applet/RequestQueue.java	Wed Oct 01 16:40:56 2008 -0400
@@ -0,0 +1,39 @@
+package sun.applet;
+
+
+public class RequestQueue {
+    PluginCallRequest head = null;
+    PluginCallRequest tail = null;
+    private int size = 0;
+
+    public void post(PluginCallRequest request) {
+    	System.err.println("Securitymanager=" + System.getSecurityManager());
+        if (head == null) {
+            head = tail = request;
+            tail.setNext(null);
+        } else {
+            tail.setNext(request);
+            tail = request;
+            tail.setNext(null);
+        }
+        
+        size++;
+    }
+
+    public PluginCallRequest pop() {
+        if (head == null)
+            return null;
+
+        PluginCallRequest ret = head;
+        head = head.getNext();
+        ret.setNext(null);
+
+        size--;
+        
+        return ret;
+    }
+    
+    public int size() {
+    	return size;
+    }
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugin/icedtea/sun/applet/TestEnv.java	Wed Oct 01 16:40:56 2008 -0400
@@ -0,0 +1,172 @@
+/* TestEnv -- test JavaScript-to-Java calls
+   Copyright (C) 2008  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;
+
+public class TestEnv
+{
+    public static int intField = 103;
+    public int intInstanceField = 7822;
+    public String stringField = "hello";
+    // z <musical G clef> <chinese water>
+    public String complexStringField = "z\uD834\uDD1E\u6C34";
+
+    public static void TestIt() {
+        System.out.println("TestIt");
+    }
+
+    public static void TestItBool(boolean arg) {
+        System.out.println("TestItBool: " + arg);
+    }
+
+    public static void TestItByte(byte arg) {
+        System.out.println("TestItByte: " + arg);
+    }
+
+    public static void TestItChar(char arg) {
+        System.out.println("TestItChar: " + arg);
+    }
+
+    public static void TestItShort(short arg) {
+        System.out.println("TestItShort: " + arg);
+    }
+
+    public static void TestItInt(int arg) {
+        System.out.println("TestItInt: " + arg);
+    }
+
+    public static void TestItLong(long arg) {
+        System.out.println("TestItLong: " + arg);
+    }
+
+    public static void TestItFloat(float arg) {
+        System.out.println("TestItFloat: " + arg);
+    }
+
+    public static void TestItDouble(double arg) {
+        System.out.println("TestItDouble: " + arg);
+    }
+
+    public static void TestItObject(TestEnv arg) {
+        System.out.println("TestItObject: " + arg);
+    }
+
+    public static void TestItObjectString(String arg) {
+        System.out.println("TestItObjectString: " + arg);
+    }
+
+    public static void TestItIntArray(int[] arg) {
+        System.out.println("TestItIntArray: " + arg);
+        for (int i = 0; i < arg.length; i++)
+            System.out.println ("ELEMENT: " + i + " " + arg[i]);
+    }
+
+    public static void TestItObjectArray(String[] arg) {
+        System.out.println("TestItObjectArray: " + arg);
+        for (int i = 0; i < arg.length; i++)
+            System.out.println ("ELEMENT: " + i + " " + arg[i]);
+    }
+
+    public static void TestItObjectArrayMulti(String[][] arg) {
+        System.out.println("TestItObjectArrayMulti: " + arg);
+        for (int i = 0; i < arg.length; i++)
+            for (int j = 0; j < arg[i].length; j++)
+                System.out.println ("ELEMENT: " + i + " " + j + " " + arg[i][j]);
+    }
+
+    public static boolean TestItBoolReturnTrue() {
+        return true;
+    }
+
+    public static boolean TestItBoolReturnFalse() {
+        return false;
+    }
+
+    public static byte TestItByteReturn() {
+        return (byte) 0xfe;
+    }
+
+    public static char TestItCharReturn() {
+        return 'K';
+    }
+
+    public static char TestItCharUnicodeReturn() {
+        return '\u6C34';
+    }
+
+    public static short TestItShortReturn() {
+        return 23;
+    }
+
+    public static int TestItIntReturn() {
+        return 3445;
+    }
+
+    public static long TestItLongReturn() {
+        return 3242883;
+    }
+
+    public static float TestItFloatReturn() {
+        return 9.21E4f;
+    }
+
+    public static double TestItDoubleReturn() {
+        return 8.33E88;
+    }
+
+    public static Object TestItObjectReturn() {
+        return new String("Thomas");
+    }
+
+    public static int[] TestItIntArrayReturn() {
+        return new int[] { 6, 7, 8 };
+    }
+
+    public static String[] TestItObjectArrayReturn() {
+        return new String[] { "Thomas", "Brigitte" };
+    }
+
+    public static String[][] TestItObjectArrayMultiReturn() {
+        return new String[][] { {"Thomas", "Brigitte"},
+                                {"Lindsay", "Michael"} };
+    }
+
+    public int TestItIntInstance(int arg) {
+        System.out.println("TestItIntInstance: " + this + " " + arg);
+        return 899;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugin/icedtea/sun/applet/VoidPluginCallRequest.java	Wed Oct 01 16:40:56 2008 -0400
@@ -0,0 +1,68 @@
+/* VoidPluginCallRequest -- represent Java-to-JavaScript requests
+   Copyright (C) 2008  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;
+
+
+public class VoidPluginCallRequest extends PluginCallRequest {
+    public VoidPluginCallRequest(String message, String returnString) {
+        super(message, returnString);
+        System.out.println ("VoidPLUGINCAlL " + message + " " + returnString);
+    }
+
+    public void parseReturn(String message) {
+    	setDone(true);
+    }
+    
+    
+    /**
+     * Returns whether the given message is serviceable by this object
+     * 
+     * @param message The message to service
+     * @return boolean indicating if message is serviceable
+     */
+    public boolean serviceable(String message) {
+    	return message.contains("JavaScriptFinalize") ||
+    			message.contains("JavaScriptRemoveMember") ||
+    			message.contains("JavaScriptSetMember") ||
+    			message.contains("JavaScriptSetSlot");
+    }
+    
+    public Object getObject() {
+    	return null;
+    }
+}