changeset 1048:5cf4df1bc010

- Refactor java-side of icedtea code for proper security management - Remove most new files from iced tea plugin patch, and move it to a directory
author Deepak Bhole <dbhole@redhat.com>
date Tue, 23 Sep 2008 16:33:17 -0400
parents 30b1dbd707d5
children abdb5c94757d
files Makefile.am plugin/icedtea/java/src/main/netscape/javascript/JSException.java plugin/icedtea/java/src/main/netscape/javascript/JSObject.java plugin/icedtea/java/src/main/netscape/javascript/JSProxy.java plugin/icedtea/java/src/main/netscape/javascript/JSRunnable.java plugin/icedtea/java/src/main/netscape/javascript/JSUtil.java plugin/icedtea/java/src/main/org/classpath/icedtea/plugin/GetMemberPluginCallRequest.java plugin/icedtea/java/src/main/org/classpath/icedtea/plugin/GetWindowPluginCallRequest.java plugin/icedtea/java/src/main/org/classpath/icedtea/plugin/PluginAppletSecurityContext.java plugin/icedtea/java/src/main/org/classpath/icedtea/plugin/PluginCallRequestFactoryImpl.java plugin/icedtea/java/src/main/org/classpath/icedtea/plugin/PluginMain.java plugin/icedtea/java/src/main/org/classpath/icedtea/plugin/PluginMessageConsumer.java plugin/icedtea/java/src/main/org/classpath/icedtea/plugin/PluginMessageHandlerWorker.java plugin/icedtea/java/src/main/org/classpath/icedtea/plugin/PluginObjectStore.java plugin/icedtea/java/src/main/org/classpath/icedtea/plugin/PluginStreamHandlerImpl.java plugin/icedtea/java/src/main/org/classpath/icedtea/plugin/RequestQueue.java plugin/icedtea/java/src/main/org/classpath/icedtea/plugin/TestEnv.java plugin/icedtea/java/src/main/org/classpath/icedtea/plugin/VoidPluginCallRequest.java plugin/icedtea/java/src/main/sun/applet/AppletAudioClip.java plugin/icedtea/java/src/main/sun/applet/AppletClassLoader.java plugin/icedtea/java/src/main/sun/applet/AppletEvent.java plugin/icedtea/java/src/main/sun/applet/AppletEventMulticaster.java plugin/icedtea/java/src/main/sun/applet/AppletIOException.java plugin/icedtea/java/src/main/sun/applet/AppletIllegalArgumentException.java plugin/icedtea/java/src/main/sun/applet/AppletImageRef.java plugin/icedtea/java/src/main/sun/applet/AppletListener.java plugin/icedtea/java/src/main/sun/applet/AppletMessageHandler.java plugin/icedtea/java/src/main/sun/applet/AppletObjectInputStream.java plugin/icedtea/java/src/main/sun/applet/AppletPanel.java plugin/icedtea/java/src/main/sun/applet/AppletProps.java plugin/icedtea/java/src/main/sun/applet/AppletResourceLoader.java plugin/icedtea/java/src/main/sun/applet/AppletSecurity.java plugin/icedtea/java/src/main/sun/applet/AppletSecurityContext.java plugin/icedtea/java/src/main/sun/applet/AppletSecurityContextManager.java plugin/icedtea/java/src/main/sun/applet/AppletSecurityException.java plugin/icedtea/java/src/main/sun/applet/AppletThreadGroup.java plugin/icedtea/java/src/main/sun/applet/AppletViewerFactory.java plugin/icedtea/java/src/main/sun/applet/AppletViewerPanel.java plugin/icedtea/java/src/main/sun/applet/GetMemberPluginCallRequest.java plugin/icedtea/java/src/main/sun/applet/GetWindowPluginCallRequest.java plugin/icedtea/java/src/main/sun/applet/Main.java plugin/icedtea/java/src/main/sun/applet/PluginAppletSecurityContext.java plugin/icedtea/java/src/main/sun/applet/PluginAppletViewer.java plugin/icedtea/java/src/main/sun/applet/PluginCallRequest.java plugin/icedtea/java/src/main/sun/applet/PluginCallRequestFactory.java plugin/icedtea/java/src/main/sun/applet/PluginClassLoader.java plugin/icedtea/java/src/main/sun/applet/PluginDebug.java plugin/icedtea/java/src/main/sun/applet/PluginException.java plugin/icedtea/java/src/main/sun/applet/PluginMain.java plugin/icedtea/java/src/main/sun/applet/PluginMessageConsumer.java plugin/icedtea/java/src/main/sun/applet/PluginMessageHandlerWorker.java plugin/icedtea/java/src/main/sun/applet/PluginObjectStore.java plugin/icedtea/java/src/main/sun/applet/PluginStreamHandler.java plugin/icedtea/java/src/main/sun/applet/TestEnv.java plugin/icedtea/java/src/main/sun/applet/VoidPluginCallRequest.java rt/net/sourceforge/jnlp/Launcher.java rt/net/sourceforge/jnlp/runtime/JNLPRuntime.java rt/netscape/javascript/JSException.java rt/netscape/javascript/JSObject.java rt/netscape/javascript/JSProxy.java rt/netscape/javascript/JSRunnable.java rt/netscape/javascript/JSUtil.java
diffstat 62 files changed, 7627 insertions(+), 2756 deletions(-) [+]
line wrap: on
line diff
--- a/Makefile.am	Sun Sep 21 15:58:46 2008 -0400
+++ b/Makefile.am	Tue Sep 23 16:33:17 2008 -0400
@@ -16,11 +16,13 @@
 ICEDTEAPLUGIN_TARGET = IcedTeaPlugin.so
 ICEDTEAPLUGIN_JAR = IcedTeaPlugin.jar
 PLUGIN_PATCH = patches/icedtea-liveconnect.patch
+LIVECONNECT = $(abs_top_srcdir)/plugin/icedtea/java/src/main
 else
 ICEDTEAPLUGIN_CLEAN =
 ICEDTEAPLUGIN_TARGET =
 ICEDTEAPLUGIN_JAR =
 PLUGIN_PATCH = patches/icedtea-plugin.patch
+LIVECONNECT = 
 if ENABLE_PLUGIN
 GCJWEBPLUGIN_CLEAN = clean-gcjwebplugin
 GCJWEBPLUGIN_TARGET = gcjwebplugin.so
@@ -578,7 +580,7 @@
 	  else \
 	    test x$${all_patches_ok} = "xyes" && all_patches_ok=$$p ; \
 	  fi ; \
-	done ;
+	done ; \
 	mv stamps/patch.stamp.tmp stamps/patch.stamp ; \
 	if ! test x$${all_patches_ok} = "xyes"; then \
 	  echo ERROR patch $${all_patches_ok} FAILED! ; \
@@ -909,12 +911,6 @@
 	  $(BUILD_OUTPUT_DIR)/j2sdk-image/jre/lib/
 	cp -pPRf IcedTeaPlugin.jar \
 	  $(BUILD_OUTPUT_DIR)/j2re-image/lib/
-
-	$(JAR) uf $(BUILD_OUTPUT_DIR)/j2sdk-image/jre/lib/rt.jar \
-	  -C $(BUILD_OUTPUT_DIR)/plugin/icedtea/classes sun
-
-	$(JAR) uf $(BUILD_OUTPUT_DIR)/j2re-image/lib/rt.jar \
-	  -C $(BUILD_OUTPUT_DIR)/plugin/icedtea/classes sun
 else
 if ENABLE_PLUGIN
 	cp -pPRf gcjwebplugin.so \
@@ -970,12 +966,6 @@
 	  $(BUILD_OUTPUT_DIR)-debug/j2sdk-image/jre/lib/
 	cp -pPRf IcedTeaPlugin.jar \
 	  $(BUILD_OUTPUT_DIR)-debug/j2re-image/lib/
-
-	$(JAR) uf $(BUILD_OUTPUT_DIR)/j2sdk-image/jre/lib/rt.jar \
-	  -C $(BUILD_OUTPUT_DIR)/plugin/icedtea/classes sun
-
-	$(JAR) uf $(BUILD_OUTPUT_DIR)/j2re-image/lib/rt.jar \
-	  -C $(BUILD_OUTPUT_DIR)/plugin/icedtea/classes sun
 else
 if ENABLE_PLUGIN
 	cp -pPRf gcjwebplugin.so \
@@ -1207,8 +1197,8 @@
 
 # rt-closed.jar class files.
 rt-source-files.txt: stamps/extract.stamp stamps/copy-source-files.stamp
-	find $(abs_top_srcdir)/rt $(abs_top_builddir)/rt -name '*.java' \
-	  $(EXCLUDE_LIVECONNECT) \
+	find $(abs_top_srcdir)/rt $(abs_top_builddir)/rt $(LIVECONNECT) -name '*.java' \
+	$(EXCLUDE_LIVECONNECT) \
 	  | sort -u > $@
 
 stamps/rt-class-files.stamp: rt-source-files.txt
@@ -1337,7 +1327,7 @@
 	  $(ICEDTEA_BOOT_DIR)/bin/javac -g \
 	  -d ../../../../../$(BUILD_OUTPUT_DIR)/plugin/icedtea/classes \
 	  -bootclasspath $(ICEDTEA_BOOT_DIR)/jre/lib/rt.jar \
-	  sun/applet/*.java netscape/javascript/*.java org/classpath/icedtea/plugin/*.java \
+	  netscape/javascript/*.java org/classpath/icedtea/plugin/*.java \
 	)
 
 	$(JAR) cf $@ \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugin/icedtea/java/src/main/netscape/javascript/JSException.java	Tue Sep 23 16:33:17 2008 -0400
@@ -0,0 +1,140 @@
+/* -*- Mode: Java; tab-width: 8; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package netscape.javascript;
+
+/**
+ * JSException is an exception which is thrown when JavaScript code
+ * returns an error.
+ */
+
+public
+class JSException extends RuntimeException {
+    public static final int EXCEPTION_TYPE_EMPTY = -1;
+    public static final int EXCEPTION_TYPE_VOID = 0;
+    public static final int EXCEPTION_TYPE_OBJECT = 1;
+    public static final int EXCEPTION_TYPE_FUNCTION = 2;
+    public static final int EXCEPTION_TYPE_STRING = 3;
+    public static final int EXCEPTION_TYPE_NUMBER = 4;
+    public static final int EXCEPTION_TYPE_BOOLEAN = 5;
+    public static final int EXCEPTION_TYPE_ERROR = 6;
+
+    public String filename;
+    public int lineno;
+    public String source;
+    public int tokenIndex;
+    public int wrappedExceptionType;
+    public Object wrappedException;
+
+    /**
+     * Constructs a JSException without a detail message.
+     * A detail message is a String that describes this particular exception.
+     *
+     * @deprecated Not for public use in future versions.
+     */
+    public JSException() {
+	super();
+        filename = "unknown";
+        lineno = 0;
+        source = "";
+        tokenIndex = 0;
+	wrappedExceptionType = EXCEPTION_TYPE_EMPTY;
+    }
+
+    /**
+     * Constructs a JSException with a detail message.
+     * A detail message is a String that describes this particular exception.
+     * @param s the detail message
+     *
+     * @deprecated Not for public use in future versions.
+     */
+    public JSException(String s) {
+	super(s);
+        filename = "unknown";
+        lineno = 0;
+        source = "";
+        tokenIndex = 0;
+	wrappedExceptionType = EXCEPTION_TYPE_EMPTY;
+    }
+
+    /**
+     * Constructs a JSException with a wrapped JavaScript exception object.
+     * This constructor needs to be public so that Java users can throw 
+     * exceptions to JS cleanly.
+     */
+    public JSException(int wrappedExceptionType, Object wrappedException) {
+	super();
+	this.wrappedExceptionType = wrappedExceptionType;
+	this.wrappedException = wrappedException;
+    }
+    
+    /**
+     * Constructs a JSException with a detail message and all the
+     * other info that usually comes with a JavaScript error.
+     * @param s the detail message
+     *
+     * @deprecated Not for public use in future versions.
+     */
+    public JSException(String s, String filename, int lineno,
+                       String source, int tokenIndex) {
+	super(s);
+        this.filename = filename;
+        this.lineno = lineno;
+        this.source = source;
+        this.tokenIndex = tokenIndex;
+	wrappedExceptionType = EXCEPTION_TYPE_EMPTY;
+    }
+
+    /**
+     * Instance method getWrappedExceptionType returns the int mapping of the
+     * type of the wrappedException Object.
+     */
+    public int getWrappedExceptionType() {
+	return wrappedExceptionType;
+    }
+
+    /**
+     * Instance method getWrappedException.
+     */
+    public Object getWrappedException() {
+	return wrappedException;
+    }
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugin/icedtea/java/src/main/netscape/javascript/JSObject.java	Tue Sep 23 16:33:17 2008 -0400
@@ -0,0 +1,258 @@
+/* -*- Mode: Java; tab-width: 8; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/* more doc todo:
+ *  threads
+ *  gc
+ *  
+ *
+ */
+
+package netscape.javascript;
+
+import java.applet.Applet;
+import java.io.IOException;
+import sun.applet.PluginAppletViewer;
+
+/**
+ * JSObject allows Java to manipulate objects that are
+ * defined in JavaScript.
+ * Values passed from Java to JavaScript are converted as
+ * follows:<ul>
+ * <li>JSObject is converted to the original JavaScript object
+ * <li>Any other Java object is converted to a JavaScript wrapper,
+ *   which can be used to access methods and fields of the java object.
+ *   Converting this wrapper to a string will call the toString method
+ *   on the original object, converting to a number will call the
+ *   doubleValue method if possible and fail otherwise.  Converting
+ *   to a boolean will try to call the booleanValue method in the
+ *   same way.
+ * <li>Java arrays are wrapped with a JavaScript object that understands
+ *   array.length and array[index]
+ * <li>A Java boolean is converted to a JavaScript boolean
+ * <li>Java byte, char, short, int, long, float, and double are converted
+ *   to JavaScript numbers
+ * </ul>
+ * Values passed from JavaScript to Java are converted as follows:<ul>
+ * <li>objects which are wrappers around java objects are unwrapped
+ * <li>other objects are wrapped with a JSObject
+ * <li>strings, numbers and booleans are converted to String, Double,
+ *   and Boolean objects respectively
+ * </ul>
+ * This means that all JavaScript values show up as some kind
+ * of java.lang.Object in Java.  In order to make much use of them,
+ * you will have to cast them to the appropriate subclass of Object,
+ * e.g. <code>(String) window.getMember("name");</code> or
+ * <code>(JSObject) window.getMember("document");</code>.
+ */
+public final class JSObject {
+    /* the internal object data */
+    private int                               internal;
+    private long                              long_internal;
+
+    /**
+     * initialize
+     */
+    private static void initClass() {
+        System.err.println ("JSObject.initClass");
+    }
+
+    static {
+        System.err.println ("JSObject INITIALIZER");
+    }
+
+    /**
+     * it is illegal to construct a JSObject manually
+     */
+    // FIXME: make private!
+    public JSObject(int jsobj_addr) {
+        System.err.println ("JSObject int CONSTRUCTOR");
+        internal = jsobj_addr;
+    }
+
+    private JSObject(long jsobj_addr) {
+        System.err.println ("JSObject long CONSTRUCTOR");
+        long_internal = jsobj_addr;
+    }
+
+    /**
+     * Retrieves a named member of a JavaScript object. 
+     * Equivalent to "this.<i>name</i>" in JavaScript.
+     */
+    public Object	getMember(String name)
+    {
+        System.err.println ("JSObject.getMember " + name);
+
+        Object o = PluginAppletViewer.getMember(internal, name);
+        System.out.println ("JSObject.getMember GOT " + o);
+        return o;
+    }
+
+
+    /**
+     * Retrieves an indexed member of a JavaScript object.
+     * Equivalent to "this[<i>index</i>]" in JavaScript.
+     */
+    //    public Object		getMember(int index) { return getSlot(index); }
+    public Object	getSlot(int index)
+    {
+        System.err.println ("JSObject.getSlot " + index);
+
+        return PluginAppletViewer.getSlot(internal, index);
+    }
+
+
+    /**
+     * Sets a named member of a JavaScript object. 
+     * Equivalent to "this.<i>name</i> = <i>value</i>" in JavaScript.
+     */
+    public void 		setMember(String name, Object value)
+    {
+        System.err.println ("JSObject.setMember " + name + " " + value);
+
+        PluginAppletViewer.setMember(internal, name, value);
+    }
+
+    /**
+     * Sets an indexed member of a JavaScript object. 
+     * Equivalent to "this[<i>index</i>] = <i>value</i>" in JavaScript.
+     */
+    //    public void 		setMember(int index, Object value) {
+    //        setSlot(index, value);
+    //    }
+    public void 		setSlot(int index, Object value)
+    {
+        System.err.println ("JSObject.setSlot " + index + " " + value);
+
+        PluginAppletViewer.setSlot(internal, index, value);
+    }
+
+
+    // TODO: toString, finalize.
+
+    /**
+     * Removes a named member of a JavaScript object.
+     */
+    public void 		removeMember(String name)
+    {
+        System.err.println ("JSObject.removeMember " + name);
+
+        PluginAppletViewer.removeMember(internal, name);
+    }
+
+
+    /**
+     * Calls a JavaScript method.
+     * Equivalent to "this.<i>methodName</i>(<i>args</i>[0], <i>args</i>[1], ...)" in JavaScript.
+     */
+    public Object	call(String methodName, Object args[])
+    {
+        System.err.print ("JSObject.call " + methodName);
+        for (int i = 0; i < args.length; i++)
+            System.err.print (" " + args[i]);
+        System.err.println("");
+        return PluginAppletViewer.call(internal, methodName, args);
+    }
+
+
+    /**
+     * Evaluates a JavaScript expression. The expression is a string 
+     * of JavaScript source code which will be evaluated in the context
+     * given by "this".
+     */
+    public Object	eval(String s)
+    {
+        System.err.println("JSObject.eval " + s);
+        return PluginAppletViewer.eval(internal, s);
+    }
+
+
+    /**
+     * Converts a JSObject to a String.
+     */
+    public String        toString()
+    {
+        System.err.println("JSObject.toString");
+        return PluginAppletViewer.javascriptToString(internal);
+    }
+
+
+    // should use some sort of identifier rather than String
+    // is "property" the right word?
+    //    native String[]                         listProperties();
+
+
+    /**
+     * get a JSObject for the window containing the given applet
+     */
+    public static JSObject	getWindow(Applet applet)
+    {
+        System.err.println("JSObject.getWindow");
+        // FIXME: handle long case as well.
+        int internal = 0;
+        internal = ((PluginAppletViewer)
+                    applet.getAppletContext()).getWindow();
+        System.out.println ("GOT IT: " + internal);
+        return new JSObject(internal);
+    }
+
+
+    /**
+     * Finalization decrements the reference count on the corresponding
+     * JavaScript object.
+     */
+    protected void	finalize()
+    {
+        System.err.println("JSObject.finalize ");
+        PluginAppletViewer.JavaScriptFinalize(internal);
+    }
+
+
+    /**
+     * Override java.lang.Object.equals() because identity is not preserved
+     * with instances of JSObject.
+     */
+    public boolean equals(Object obj)
+    {
+        System.err.println("JSObject.equals " + obj);
+
+        return false;
+    }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugin/icedtea/java/src/main/netscape/javascript/JSProxy.java	Tue Sep 23 16:33:17 2008 -0400
@@ -0,0 +1,58 @@
+/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+/**
+ * The JSProxy interface allows applets and plugins to
+ * share javascript contexts.
+ */
+
+package netscape.javascript;
+import java.applet.Applet;
+
+public interface JSProxy {
+    Object  getMember(JSObject jso, String name);
+    Object  getSlot(JSObject jso, int index);
+    void    setMember(JSObject jso, String name, Object value);
+    void    setSlot(JSObject jso, int index, Object value);
+    void    removeMember(JSObject jso, String name);
+    Object  call(JSObject jso, String methodName, Object args[]);
+    Object  eval(JSObject jso, String s);
+    String      toString(JSObject jso);
+    JSObject    getWindow(Applet applet);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugin/icedtea/java/src/main/netscape/javascript/JSRunnable.java	Tue Sep 23 16:33:17 2008 -0400
@@ -0,0 +1,70 @@
+/* -*- Mode: Java; tab-width: 8; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+package netscape.javascript;
+
+/**
+ * Runs a JavaScript object with a run() method in a separate thread.
+ */
+public class JSRunnable implements Runnable {
+	private JSObject runnable;
+
+	public JSRunnable(JSObject runnable) {
+		this.runnable = runnable;
+		synchronized(this) {
+			new Thread(this).start();
+			try {
+				this.wait();
+			} catch (InterruptedException ie) {
+			}
+		}
+	}
+	
+	public void run() {
+		try {
+			runnable.call("run", null);
+			synchronized(this) {
+				notifyAll();
+			}
+		} catch (Throwable t) {
+			System.err.println(t);
+			t.printStackTrace(System.err);
+		}
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugin/icedtea/java/src/main/netscape/javascript/JSUtil.java	Tue Sep 23 16:33:17 2008 -0400
@@ -0,0 +1,59 @@
+/* -*- Mode: Java; tab-width: 8; c-basic-offset: 4 -*-
+ *
+ * ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of the GNU General Public License Version 2 or later (the "GPL"),
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+/* ** */
+
+package netscape.javascript;
+import java.io.*;
+
+public class JSUtil {
+
+    /* Return the stack trace of an exception or error as a String */
+    public static String getStackTrace(Throwable t) {
+	ByteArrayOutputStream captureStream;
+	PrintWriter p;
+	
+	captureStream = new ByteArrayOutputStream();
+	p = new PrintWriter(captureStream);
+
+	t.printStackTrace(p);
+	p.flush();
+
+	return captureStream.toString();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugin/icedtea/java/src/main/org/classpath/icedtea/plugin/GetMemberPluginCallRequest.java	Tue Sep 23 16:33:17 2008 -0400
@@ -0,0 +1,78 @@
+/* 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;
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugin/icedtea/java/src/main/org/classpath/icedtea/plugin/GetWindowPluginCallRequest.java	Tue Sep 23 16:33:17 2008 -0400
@@ -0,0 +1,76 @@
+/* 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;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugin/icedtea/java/src/main/org/classpath/icedtea/plugin/PluginAppletSecurityContext.java	Tue Sep 23 16:33:17 2008 -0400
@@ -0,0 +1,855 @@
+/* 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);
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugin/icedtea/java/src/main/org/classpath/icedtea/plugin/PluginCallRequestFactoryImpl.java	Tue Sep 23 16:33:17 2008 -0400
@@ -0,0 +1,22 @@
+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");
+		}
+		
+	}
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugin/icedtea/java/src/main/org/classpath/icedtea/plugin/PluginMain.java	Tue Sep 23 16:33:17 2008 -0400
@@ -0,0 +1,193 @@
+/*
+ * 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();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugin/icedtea/java/src/main/org/classpath/icedtea/plugin/PluginMessageConsumer.java	Tue Sep 23 16:33:17 2008 -0400
@@ -0,0 +1,76 @@
+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");
+	}
+	
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugin/icedtea/java/src/main/org/classpath/icedtea/plugin/PluginMessageHandlerWorker.java	Tue Sep 23 16:33:17 2008 -0400
@@ -0,0 +1,79 @@
+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;
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugin/icedtea/java/src/main/org/classpath/icedtea/plugin/PluginObjectStore.java	Tue Sep 23 16:33:17 2008 -0400
@@ -0,0 +1,119 @@
+/* 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));
+   		}
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugin/icedtea/java/src/main/org/classpath/icedtea/plugin/PluginStreamHandlerImpl.java	Tue Sep 23 16:33:17 2008 -0400
@@ -0,0 +1,362 @@
+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;
+    	}
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugin/icedtea/java/src/main/org/classpath/icedtea/plugin/RequestQueue.java	Tue Sep 23 16:33:17 2008 -0400
@@ -0,0 +1,40 @@
+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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugin/icedtea/java/src/main/org/classpath/icedtea/plugin/TestEnv.java	Tue Sep 23 16:33:17 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 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;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugin/icedtea/java/src/main/org/classpath/icedtea/plugin/VoidPluginCallRequest.java	Tue Sep 23 16:33:17 2008 -0400
@@ -0,0 +1,69 @@
+/* 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;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugin/icedtea/java/src/main/sun/applet/AppletAudioClip.java	Tue Sep 23 16:33:17 2008 -0400
@@ -0,0 +1,151 @@
+/*
+ * Copyright 1995-2003 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.IOException;
+import java.io.InputStream;
+import java.io.ByteArrayInputStream;
+import java.net.URL;
+import java.net.URLConnection;
+import java.applet.AudioClip;
+
+import com.sun.media.sound.JavaSoundAudioClip;
+
+
+/**
+ * Applet audio clip;
+ *
+ * @author Arthur van Hoff, Kara Kytle
+ */
+
+public class AppletAudioClip implements AudioClip {
+
+    // url that this AudioClip is based on
+    private URL url = null;
+
+    // the audio clip implementation
+    private AudioClip audioClip = null;
+
+    boolean DEBUG = false /*true*/;
+
+    /**
+     * Constructs an AppletAudioClip from an URL.
+     */
+    public AppletAudioClip(URL url) {
+
+        // store the url
+        this.url = url;
+
+        try {
+            // create a stream from the url, and use it
+            // in the clip.
+            InputStream in = url.openStream();
+            createAppletAudioClip(in);
+
+        } catch (IOException e) {
+                /* just quell it */
+            if (DEBUG) {
+                System.err.println("IOException creating AppletAudioClip" + e);
+            }
+        }
+    }
+
+    /**
+     * Constructs an AppletAudioClip from a URLConnection.
+     */
+    public AppletAudioClip(URLConnection uc) {
+
+        try {
+            // create a stream from the url, and use it
+            // in the clip.
+            createAppletAudioClip(uc.getInputStream());
+
+        } catch (IOException e) {
+                /* just quell it */
+            if (DEBUG) {
+                System.err.println("IOException creating AppletAudioClip" + e);
+            }
+        }
+    }
+
+
+    /**
+     * For constructing directly from Jar entries, or any other
+     * raw Audio data. Note that the data provided must include the format
+     * header.
+     */
+    public AppletAudioClip(byte [] data) {
+
+        try {
+
+            // construct a stream from the byte array
+            InputStream in = new ByteArrayInputStream(data);
+
+            createAppletAudioClip(in);
+
+        } catch (IOException e) {
+                /* just quell it */
+            if (DEBUG) {
+                System.err.println("IOException creating AppletAudioClip " + e);
+            }
+        }
+    }
+
+
+    /*
+     * Does the real work of creating an AppletAudioClip from an InputStream.
+     * This function is used by both constructors.
+     */
+    void createAppletAudioClip(InputStream in) throws IOException {
+
+        try {
+            audioClip = new JavaSoundAudioClip(in);
+        } catch (Exception e3) {
+            // no matter what happened, we throw an IOException to avoid changing the interfaces....
+            throw new IOException("Failed to construct the AudioClip: " + e3);
+        }
+    }
+
+
+    public synchronized void play() {
+
+                if (audioClip != null)
+                        audioClip.play();
+    }
+
+
+    public synchronized void loop() {
+
+                if (audioClip != null)
+                        audioClip.loop();
+    }
+
+    public synchronized void stop() {
+
+                if (audioClip != null)
+                        audioClip.stop();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugin/icedtea/java/src/main/sun/applet/AppletClassLoader.java	Tue Sep 23 16:33:17 2008 -0400
@@ -0,0 +1,861 @@
+/*
+ * Copyright 1995-2005 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.lang.NullPointerException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.net.SocketPermission;
+import java.net.URLConnection;
+import java.net.MalformedURLException;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.io.File;
+import java.io.FilePermission;
+import java.io.IOException;
+import java.io.BufferedInputStream;
+import java.io.InputStream;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.NoSuchElementException;
+import java.security.AccessController;
+import java.security.AccessControlContext;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedExceptionAction;
+import java.security.PrivilegedActionException;
+import java.security.CodeSource;
+import java.security.Permission;
+import java.security.PermissionCollection;
+import sun.awt.AppContext;
+import sun.awt.SunToolkit;
+import sun.net.www.ParseUtil;
+import sun.security.util.SecurityConstants;
+
+/**
+ * This class defines the class loader for loading applet classes and
+ * resources. It extends URLClassLoader to search the applet code base
+ * for the class or resource after checking any loaded JAR files.
+ */
+public class AppletClassLoader extends URLClassLoader {
+    private URL base;   /* applet code base URL */
+    private CodeSource codesource; /* codesource for the base URL */
+    private AccessControlContext acc;
+    private boolean exceptionStatus = false;
+
+    private final Object threadGroupSynchronizer = new Object();
+    private final Object grabReleaseSynchronizer = new Object();
+
+    private boolean codebaseLookup = true;
+
+    /*
+     * Creates a new AppletClassLoader for the specified base URL.
+     */
+    protected AppletClassLoader(URL base) {
+        super(new URL[0]);
+        this.base = base;
+        this.codesource =
+            new CodeSource(base, (java.security.cert.Certificate[]) null);
+        acc = AccessController.getContext();
+    }
+
+    /**
+     * Set the codebase lookup flag.
+     */
+    void setCodebaseLookup(boolean codebaseLookup)  {
+        this.codebaseLookup = codebaseLookup;
+    }
+
+    /*
+     * Returns the applet code base URL.
+     */
+    URL getBaseURL() {
+        return base;
+    }
+
+    /*
+     * Returns the URLs used for loading classes and resources.
+     */
+    public URL[] getURLs() {
+        URL[] jars = super.getURLs();
+        URL[] urls = new URL[jars.length + 1];
+        System.arraycopy(jars, 0, urls, 0, jars.length);
+        urls[urls.length - 1] = base;
+        return urls;
+    }
+
+    /*
+     * Adds the specified JAR file to the search path of loaded JAR files.
+     * Changed modifier to protected in order to be able to overwrite addJar()
+     * in PluginClassLoader.java
+     */
+    protected void addJar(String name) throws IOException {
+        URL url;
+        try {
+            url = new URL(base, name);
+        } catch (MalformedURLException e) {
+            throw new IllegalArgumentException("name");
+        }
+        addURL(url);
+        // DEBUG
+        //URL[] urls = getURLs();
+        //for (int i = 0; i < urls.length; i++) {
+        //    System.out.println("url[" + i + "] = " + urls[i]);
+        //}
+    }
+
+    /*
+     * Override loadClass so that class loading errors can be caught in
+     * order to print better error messages.
+     */
+    public synchronized Class loadClass(String name, boolean resolve)
+        throws ClassNotFoundException
+    {
+        // First check if we have permission to access the package. This
+        // should go away once we've added support for exported packages.
+        int i = name.lastIndexOf('.');
+        if (i != -1) {
+            SecurityManager sm = System.getSecurityManager();
+            if (sm != null)
+                sm.checkPackageAccess(name.substring(0, i));
+        }
+        try {
+            return super.loadClass(name, resolve);
+        } catch (ClassNotFoundException e) {
+            //printError(name, e.getException());
+            throw e;
+        } catch (RuntimeException e) {
+            //printError(name, e);
+            throw e;
+        } catch (Error e) {
+            //printError(name, e);
+            throw e;
+        }
+    }
+
+    /*
+     * Finds the applet class with the specified name. First searches
+     * loaded JAR files then the applet code base for the class.
+     */
+    protected Class findClass(String name) throws ClassNotFoundException {
+
+        int index = name.indexOf(";");
+        String cookie = "";
+        if(index != -1) {
+                cookie = name.substring(index, name.length());
+                name = name.substring(0, index);
+        }
+
+        // check loaded JAR files
+        try {
+            return super.findClass(name);
+        } catch (ClassNotFoundException e) {
+        }
+
+        // Otherwise, try loading the class from the code base URL
+
+        // 4668479: Option to turn off codebase lookup in AppletClassLoader
+        // during resource requests. [stanley.ho]
+        if (codebaseLookup == false)
+            throw new ClassNotFoundException(name);
+
+//      final String path = name.replace('.', '/').concat(".class").concat(cookie);
+        String encodedName = ParseUtil.encodePath(name.replace('.', '/'), false);
+        final String path = (new StringBuffer(encodedName)).append(".class").append(cookie).toString();
+        try {
+            byte[] b = (byte[]) AccessController.doPrivileged(
+                               new PrivilegedExceptionAction() {
+                public Object run() throws IOException {
+                    return getBytes(new URL(base, path));
+                }
+            }, acc);
+
+            if (b != null) {
+                return defineClass(name, b, 0, b.length, codesource);
+            } else {
+                throw new ClassNotFoundException(name);
+            }
+        } catch (PrivilegedActionException e) {
+            throw new ClassNotFoundException(name, e.getException());
+        }
+    }
+
+    /**
+     * Returns the permissions for the given codesource object.
+     * The implementation of this method first calls super.getPermissions,
+     * to get the permissions
+     * granted by the super class, and then adds additional permissions
+     * based on the URL of the codesource.
+     * <p>
+     * If the protocol is "file"
+     * and the path specifies a file, permission is granted to read all files
+     * and (recursively) all files and subdirectories contained in
+     * that directory. This is so applets with a codebase of
+     * file:/blah/some.jar can read in file:/blah/, which is needed to
+     * be backward compatible. We also add permission to connect back to
+     * the "localhost".
+     *
+     * @param codesource the codesource
+     * @return the permissions granted to the codesource
+     */
+    protected PermissionCollection getPermissions(CodeSource codesource)
+    {
+        final PermissionCollection perms = super.getPermissions(codesource);
+
+        URL url = codesource.getLocation();
+
+        String path = null;
+        Permission p;
+
+        try {
+            p = url.openConnection().getPermission();
+        } catch (java.io.IOException ioe) {
+            p = null;
+        }
+
+        if (p instanceof FilePermission) {
+            path = p.getName();
+        } else if ((p == null) && (url.getProtocol().equals("file"))) {
+            path = url.getFile().replace('/', File.separatorChar);
+            path = ParseUtil.decode(path);
+        }
+
+        if (path != null) {
+            if (!path.endsWith(File.separator)) {
+                int endIndex = path.lastIndexOf(File.separatorChar);
+                if (endIndex != -1) {
+                        path = path.substring(0, endIndex+1) + "-";
+                        perms.add(new FilePermission(path,
+                            SecurityConstants.FILE_READ_ACTION));
+                }
+            }
+            perms.add(new SocketPermission("localhost",
+                SecurityConstants.SOCKET_CONNECT_ACCEPT_ACTION));
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    try {
+                        String host = InetAddress.getLocalHost().getHostName();
+                        perms.add(new SocketPermission(host,
+                            SecurityConstants.SOCKET_CONNECT_ACCEPT_ACTION));
+                    } catch (UnknownHostException uhe) {
+
+                    }
+                    return null;
+                }
+            });
+
+            Permission bperm;
+            try {
+                bperm = base.openConnection().getPermission();
+            } catch (java.io.IOException ioe) {
+                bperm = null;
+            }
+            if (bperm instanceof FilePermission) {
+                String bpath = bperm.getName();
+                if (bpath.endsWith(File.separator)) {
+                    bpath += "-";
+                }
+                perms.add(new FilePermission(bpath,
+                    SecurityConstants.FILE_READ_ACTION));
+            } else if ((bperm == null) && (base.getProtocol().equals("file"))) {
+                String bpath = base.getFile().replace('/', File.separatorChar);
+                bpath = ParseUtil.decode(bpath);
+                if (bpath.endsWith(File.separator)) {
+                    bpath += "-";
+                }
+                perms.add(new FilePermission(bpath, SecurityConstants.FILE_READ_ACTION));
+            }
+
+        }
+        return perms;
+    }
+
+    /*
+     * Returns the contents of the specified URL as an array of bytes.
+     */
+    private static byte[] getBytes(URL url) throws IOException {
+        URLConnection uc = url.openConnection();
+        if (uc instanceof java.net.HttpURLConnection) {
+            java.net.HttpURLConnection huc = (java.net.HttpURLConnection) uc;
+            int code = huc.getResponseCode();
+            if (code >= java.net.HttpURLConnection.HTTP_BAD_REQUEST) {
+                throw new IOException("open HTTP connection failed.");
+            }
+        }
+        int len = uc.getContentLength();
+
+        // Fixed #4507227: Slow performance to load
+        // class and resources. [stanleyh]
+        //
+        // Use buffered input stream [stanleyh]
+        InputStream in = new BufferedInputStream(uc.getInputStream());
+
+        byte[] b;
+        try {
+            if (len != -1) {
+                // Read exactly len bytes from the input stream
+                b = new byte[len];
+                while (len > 0) {
+                    int n = in.read(b, b.length - len, len);
+                    if (n == -1) {
+                        throw new IOException("unexpected EOF");
+                    }
+                    len -= n;
+                }
+            } else {
+                // Read until end of stream is reached - use 8K buffer
+                // to speed up performance [stanleyh]
+                b = new byte[8192];
+                int total = 0;
+                while ((len = in.read(b, total, b.length - total)) != -1) {
+                    total += len;
+                    if (total >= b.length) {
+                        byte[] tmp = new byte[total * 2];
+                        System.arraycopy(b, 0, tmp, 0, total);
+                        b = tmp;
+                    }
+                }
+                // Trim array to correct size, if necessary
+                if (total != b.length) {
+                    byte[] tmp = new byte[total];
+                    System.arraycopy(b, 0, tmp, 0, total);
+                    b = tmp;
+                }
+            }
+        } finally {
+            in.close();
+        }
+        return b;
+    }
+
+    // Object for synchronization around getResourceAsStream()
+    private Object syncResourceAsStream = new Object();
+    private Object syncResourceAsStreamFromJar = new Object();
+
+    // Flag to indicate getResourceAsStream() is in call
+    private boolean resourceAsStreamInCall = false;
+    private boolean resourceAsStreamFromJarInCall = false;
+
+    /**
+     * Returns an input stream for reading the specified resource.
+     *
+     * The search order is described in the documentation for {@link
+     * #getResource(String)}.<p>
+     *
+     * @param  name the resource name
+     * @return an input stream for reading the resource, or <code>null</code>
+     *         if the resource could not be found
+     * @since  JDK1.1
+     */
+    public InputStream getResourceAsStream(String name)
+    {
+
+        if (name == null) {
+            throw new NullPointerException("name");
+        }
+
+        try
+        {
+            InputStream is = null;
+
+            // Fixed #4507227: Slow performance to load
+            // class and resources. [stanleyh]
+            //
+            // The following is used to avoid calling
+            // AppletClassLoader.findResource() in
+            // super.getResourceAsStream(). Otherwise,
+            // unnecessary connection will be made.
+            //
+            synchronized(syncResourceAsStream)
+            {
+                resourceAsStreamInCall = true;
+
+                // Call super class
+                is = super.getResourceAsStream(name);
+
+                resourceAsStreamInCall = false;
+            }
+
+            // 4668479: Option to turn off codebase lookup in AppletClassLoader
+            // during resource requests. [stanley.ho]
+            if (codebaseLookup == true && is == null)
+            {
+                // If resource cannot be obtained,
+                // try to download it from codebase
+                URL url = new URL(base, ParseUtil.encodePath(name, false));
+                is = url.openStream();
+            }
+
+            return is;
+        }
+        catch (Exception e)
+        {
+            return null;
+        }
+    }
+
+
+    /**
+     * Returns an input stream for reading the specified resource from the
+     * the loaded jar files.
+     *
+     * The search order is described in the documentation for {@link
+     * #getResource(String)}.<p>
+     *
+     * @param  name the resource name
+     * @return an input stream for reading the resource, or <code>null</code>
+     *         if the resource could not be found
+     * @since  JDK1.1
+     */
+    public InputStream getResourceAsStreamFromJar(String name) {
+
+        if (name == null) {
+            throw new NullPointerException("name");
+        }
+
+        try {
+            InputStream is = null;
+            synchronized(syncResourceAsStreamFromJar) {
+                resourceAsStreamFromJarInCall = true;
+                // Call super class
+                is = super.getResourceAsStream(name);
+                resourceAsStreamFromJarInCall = false;
+            }
+
+            return is;
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
+
+    /*
+     * Finds the applet resource with the specified name. First checks
+     * loaded JAR files then the applet code base for the resource.
+     */
+    public URL findResource(String name) {
+        // check loaded JAR files
+        URL url = super.findResource(name);
+
+        // 6215746:  Disable META-INF/* lookup from codebase in
+        // applet/plugin classloader. [stanley.ho]
+        if (name.startsWith("META-INF/"))
+            return url;
+
+        // 4668479: Option to turn off codebase lookup in AppletClassLoader
+        // during resource requests. [stanley.ho]
+        if (codebaseLookup == false)
+            return url;
+
+        if (url == null)
+        {
+            //#4805170, if it is a call from Applet.getImage()
+            //we should check for the image only in the archives
+            boolean insideGetResourceAsStreamFromJar = false;
+                synchronized(syncResourceAsStreamFromJar) {
+                insideGetResourceAsStreamFromJar = resourceAsStreamFromJarInCall;
+            }
+
+            if (insideGetResourceAsStreamFromJar) {
+                return null;
+            }
+
+            // Fixed #4507227: Slow performance to load
+            // class and resources. [stanleyh]
+            //
+            // Check if getResourceAsStream is called.
+            //
+            boolean insideGetResourceAsStream = false;
+
+            synchronized(syncResourceAsStream)
+            {
+                insideGetResourceAsStream = resourceAsStreamInCall;
+            }
+
+            // If getResourceAsStream is called, don't
+            // trigger the following code. Otherwise,
+            // unnecessary connection will be made.
+            //
+            if (insideGetResourceAsStream == false)
+            {
+                // otherwise, try the code base
+                try {
+                    url = new URL(base, ParseUtil.encodePath(name, false));
+                    // check if resource exists
+                    if(!resourceExists(url))
+                        url = null;
+                } catch (Exception e) {
+                    // all exceptions, including security exceptions, are caught
+                    url = null;
+                }
+            }
+        }
+        return url;
+    }
+
+
+    private boolean resourceExists(URL url) {
+        // Check if the resource exists.
+        // It almost works to just try to do an openConnection() but
+        // HttpURLConnection will return true on HTTP_BAD_REQUEST
+        // when the requested name ends in ".html", ".htm", and ".txt"
+        // and we want to be able to handle these
+        //
+        // Also, cannot just open a connection for things like FileURLConnection,
+        // because they succeed when connecting to a nonexistent file.
+        // So, in those cases we open and close an input stream.
+        boolean ok = true;
+        try {
+            URLConnection conn = url.openConnection();
+            if (conn instanceof java.net.HttpURLConnection) {
+                java.net.HttpURLConnection hconn =
+                    (java.net.HttpURLConnection) conn;
+
+                // To reduce overhead, using http HEAD method instead of GET method
+                hconn.setRequestMethod("HEAD");
+
+                int code = hconn.getResponseCode();
+                if (code == java.net.HttpURLConnection.HTTP_OK) {
+                    return true;
+                }
+                if (code >= java.net.HttpURLConnection.HTTP_BAD_REQUEST) {
+                    return false;
+                }
+            } else {
+                /**
+                 * Fix for #4182052 - stanleyh
+                 *
+                 * The same connection should be reused to avoid multiple
+                 * HTTP connections
+                 */
+
+                // our best guess for the other cases
+                InputStream is = conn.getInputStream();
+                is.close();
+            }
+        } catch (Exception ex) {
+            ok = false;
+        }
+        return ok;
+    }
+
+    /*
+     * Returns an enumeration of all the applet resources with the specified
+     * name. First checks loaded JAR files then the applet code base for all
+     * available resources.
+     */
+    public Enumeration findResources(String name) throws IOException {
+
+        final Enumeration e = super.findResources(name);
+
+        // 6215746:  Disable META-INF/* lookup from codebase in
+        // applet/plugin classloader. [stanley.ho]
+        if (name.startsWith("META-INF/"))
+            return e;
+
+        // 4668479: Option to turn off codebase lookup in AppletClassLoader
+        // during resource requests. [stanley.ho]
+        if (codebaseLookup == false)
+            return e;
+
+        URL u = new URL(base, ParseUtil.encodePath(name, false));
+        if (!resourceExists(u)) {
+            u = null;
+        }
+
+        final URL url = u;
+        return new Enumeration() {
+            private boolean done;
+            public Object nextElement() {
+                if (!done) {
+                    if (e.hasMoreElements()) {
+                        return e.nextElement();
+                    }
+                    done = true;
+                    if (url != null) {
+                        return url;
+                    }
+                }
+                throw new NoSuchElementException();
+            }
+            public boolean hasMoreElements() {
+                return !done && (e.hasMoreElements() || url != null);
+            }
+        };
+    }
+
+    /*
+     * Load and resolve the file specified by the applet tag CODE
+     * attribute. The argument can either be the relative path
+     * of the class file itself or just the name of the class.
+     */
+    Class loadCode(String name) throws ClassNotFoundException {
+        // first convert any '/' or native file separator to .
+        name = name.replace('/', '.');
+        name = name.replace(File.separatorChar, '.');
+
+        // deal with URL rewriting
+        String cookie = null;
+        int index = name.indexOf(";");
+        if(index != -1) {
+                cookie = name.substring(index, name.length());
+                name = name.substring(0, index);
+        }
+
+        // save that name for later
+        String fullName = name;
+        // then strip off any suffixes
+        if (name.endsWith(".class") || name.endsWith(".java")) {
+            name = name.substring(0, name.lastIndexOf('.'));
+        }
+        try {
+                if(cookie != null)
+                        name = (new StringBuffer(name)).append(cookie).toString();
+            return loadClass(name);
+        } catch (ClassNotFoundException e) {
+        }
+        // then if it didn't end with .java or .class, or in the
+        // really pathological case of a class named class or java
+        if(cookie != null)
+                fullName = (new StringBuffer(fullName)).append(cookie).toString();
+
+        return loadClass(fullName);
+    }
+
+    /*
+     * The threadgroup that the applets loaded by this classloader live
+     * in. In the sun.* implementation of applets, the security manager's
+     * (AppletSecurity) getThreadGroup returns the thread group of the
+     * first applet on the stack, which is the applet's thread group.
+     */
+    private AppletThreadGroup threadGroup;
+    private AppContext appContext;
+
+    public ThreadGroup getThreadGroup() {
+      synchronized (threadGroupSynchronizer) {
+        if (threadGroup == null || threadGroup.isDestroyed()) {
+            AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    threadGroup = new AppletThreadGroup(base + "-threadGroup");
+                    // threadGroup.setDaemon(true);
+                    // threadGroup is now destroyed by AppContext.dispose()
+
+                    // Create the new AppContext from within a Thread belonging
+                    // to the newly created ThreadGroup, and wait for the
+                    // creation to complete before returning from this method.
+                    AppContextCreator creatorThread = new AppContextCreator(threadGroup);
+
+                    // Since this thread will later be used to launch the
+                    // applet's AWT-event dispatch thread and we want the applet
+                    // code executing the AWT callbacks to use their own class
+                    // loader rather than the system class loader, explicitly
+                    // set the context class loader to the AppletClassLoader.
+                    creatorThread.setContextClassLoader(AppletClassLoader.this);
+
+                    synchronized(creatorThread.syncObject)  {
+                        creatorThread.start();
+                        try {
+                            creatorThread.syncObject.wait();
+                        } catch (InterruptedException e) { }
+                        appContext = creatorThread.appContext;
+                    }
+                    return null;
+                }
+            });
+        }
+        return threadGroup;
+      }
+    }
+
+    /*
+     * Get the AppContext, if any, corresponding to this AppletClassLoader.
+     */
+    public AppContext getAppContext()  {
+        return appContext;
+    }
+
+    int usageCount = 0;
+
+    /**
+     * Grab this AppletClassLoader and its ThreadGroup/AppContext, so they
+     * won't be destroyed.
+     */
+    void grab() {
+        synchronized(grabReleaseSynchronizer) {
+            usageCount++;
+        }
+        getThreadGroup(); // Make sure ThreadGroup/AppContext exist
+    }
+
+    protected void setExceptionStatus()
+    {
+        exceptionStatus = true;
+    }
+
+    public boolean getExceptionStatus()
+    {
+        return exceptionStatus;
+    }
+
+    /**
+     * Release this AppletClassLoader and its ThreadGroup/AppContext.
+     * If nothing else has grabbed this AppletClassLoader, its ThreadGroup
+     * and AppContext will be destroyed.
+     *
+     * Because this method may destroy the AppletClassLoader's ThreadGroup,
+     * this method should NOT be called from within the AppletClassLoader's
+     * ThreadGroup.
+     *
+     * Changed modifier to protected in order to be able to overwrite this
+     * function in PluginClassLoader.java
+     */
+    protected void release() {
+
+        AppContext tempAppContext = null;
+
+        synchronized(grabReleaseSynchronizer) {
+            if (usageCount > 1)  {
+                --usageCount;
+            } else {
+                synchronized(threadGroupSynchronizer) {
+                    // Store app context in temp variable
+                    tempAppContext = appContext;
+                    usageCount = 0;
+                    appContext = null;
+                    threadGroup = null;
+                }
+            }
+        }
+
+        // Dispose appContext outside any sync block to
+        // prevent potential deadlock.
+        if (tempAppContext != null)  {
+            try {
+                tempAppContext.dispose(); // nuke the world!
+            } catch (IllegalThreadStateException e) { }
+        }
+    }
+
+    // Hash map to store applet compatibility info
+    private HashMap jdk11AppletInfo = new HashMap();
+    private HashMap jdk12AppletInfo = new HashMap();
+
+    /**
+     * Set applet target level as JDK 1.1.
+     *
+     * @param clazz Applet class.
+     * @param bool true if JDK is targeted for JDK 1.1;
+     *             false otherwise.
+     */
+    void setJDK11Target(Class clazz, boolean bool)
+    {
+         jdk11AppletInfo.put(clazz.toString(), Boolean.valueOf(bool));
+    }
+
+    /**
+     * Set applet target level as JDK 1.2.
+     *
+     * @param clazz Applet class.
+     * @param bool true if JDK is targeted for JDK 1.2;
+     *             false otherwise.
+     */
+    void setJDK12Target(Class clazz, boolean bool)
+    {
+        jdk12AppletInfo.put(clazz.toString(), Boolean.valueOf(bool));
+    }
+
+    /**
+     * Determine if applet is targeted for JDK 1.1.
+     *
+     * @param applet Applet class.
+     * @return TRUE if applet is targeted for JDK 1.1;
+     *         FALSE if applet is not;
+     *         null if applet is unknown.
+     */
+    Boolean isJDK11Target(Class clazz)
+    {
+        return (Boolean) jdk11AppletInfo.get(clazz.toString());
+    }
+
+    /**
+     * Determine if applet is targeted for JDK 1.2.
+     *
+     * @param applet Applet class.
+     * @return TRUE if applet is targeted for JDK 1.2;
+     *         FALSE if applet is not;
+     *         null if applet is unknown.
+     */
+    Boolean isJDK12Target(Class clazz)
+    {
+        return (Boolean) jdk12AppletInfo.get(clazz.toString());
+    }
+
+    private static AppletMessageHandler mh =
+        new AppletMessageHandler("appletclassloader");
+
+    /*
+     * Prints a class loading error message.
+     */
+    private static void printError(String name, Throwable e) {
+        String s = null;
+        if (e == null) {
+            s = mh.getMessage("filenotfound", name);
+        } else if (e instanceof IOException) {
+            s = mh.getMessage("fileioexception", name);
+        } else if (e instanceof ClassFormatError) {
+            s = mh.getMessage("fileformat", name);
+        } else if (e instanceof ThreadDeath) {
+            s = mh.getMessage("filedeath", name);
+        } else if (e instanceof Error) {
+            s = mh.getMessage("fileerror", e.toString(), name);
+        }
+        if (s != null) {
+            System.err.println(s);
+        }
+    }
+}
+
+/*
+ * The AppContextCreator class is used to create an AppContext from within
+ * a Thread belonging to the new AppContext's ThreadGroup.  To wait for
+ * this operation to complete before continuing, wait for the notifyAll()
+ * operation on the syncObject to occur.
+ */
+class AppContextCreator extends Thread  {
+    Object syncObject = new Object();
+    AppContext appContext = null;
+
+    AppContextCreator(ThreadGroup group)  {
+        super(group, "AppContextCreator");
+    }
+
+    public void run()  {
+        synchronized(syncObject)  {
+            appContext = SunToolkit.createNewAppContext();
+            syncObject.notifyAll();
+        }
+    } // run()
+
+} // class AppContextCreator
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugin/icedtea/java/src/main/sun/applet/AppletEvent.java	Tue Sep 23 16:33:17 2008 -0400
@@ -0,0 +1,65 @@
+/*
+ * Copyright 1997 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.util.EventObject;
+
+
+/**
+ * AppletEvent class.
+ *
+ * @author  Sunita Mani
+ */
+
+public class AppletEvent extends EventObject {
+
+    private Object arg;
+    private int id;
+
+
+    public AppletEvent(Object source, int id, Object argument) {
+        super(source);
+        this.arg = argument;
+        this.id = id;
+    }
+
+    public int getID() {
+        return id;
+    }
+
+    public Object getArgument() {
+        return arg;
+    }
+
+    public String toString() {
+        String str = getClass().getName() + "[source=" + source + " + id="+ id;
+        if (arg != null) {
+            str += " + arg=" + arg;
+        }
+        str += " ]";
+        return str;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugin/icedtea/java/src/main/sun/applet/AppletEventMulticaster.java	Tue Sep 23 16:33:17 2008 -0400
@@ -0,0 +1,127 @@
+/*
+ * Copyright 1997 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.util.EventListener;
+import java.io.Serializable;
+import java.io.ObjectOutputStream;
+import java.io.IOException;
+
+/**
+ * AppletEventMulticaster class.  This class manages an immutable
+ * structure consisting of a chain of AppletListeners and is
+ * responsible for dispatching events to them.
+ *
+ * @author  Sunita Mani
+ */
+public class AppletEventMulticaster implements AppletListener {
+
+    private final AppletListener a, b;
+
+    public AppletEventMulticaster(AppletListener a, AppletListener b) {
+        this.a = a; this.b = b;
+    }
+
+    public void appletStateChanged(AppletEvent e) {
+        a.appletStateChanged(e);
+        b.appletStateChanged(e);
+    }
+
+    /**
+     * Adds Applet-listener-a with Applet-listener-b and
+     * returns the resulting multicast listener.
+     * @param a Applet-listener-a
+     * @param b Applet-listener-b
+     */
+    public static AppletListener add(AppletListener a, AppletListener b) {
+        return addInternal(a, b);
+    }
+
+    /**
+     * Removes the old Applet-listener from Applet-listener-l and
+     * returns the resulting multicast listener.
+     * @param l Applet-listener-l
+     * @param oldl the Applet-listener being removed
+     */
+    public static AppletListener remove(AppletListener l, AppletListener oldl) {
+        return removeInternal(l, oldl);
+    }
+
+    /**
+     * Returns the resulting multicast listener from adding listener-a
+     * and listener-b together.
+     * If listener-a is null, it returns listener-b;
+     * If listener-b is null, it returns listener-a
+     * If neither are null, then it creates and returns
+     * a new AppletEventMulticaster instance which chains a with b.
+     * @param a event listener-a
+     * @param b event listener-b
+     */
+    private static AppletListener addInternal(AppletListener a, AppletListener b) {
+        if (a == null)  return b;
+        if (b == null)  return a;
+        return new AppletEventMulticaster(a, b);
+    }
+
+
+    /**
+     * Removes a listener from this multicaster and returns the
+     * resulting multicast listener.
+     * @param oldl the listener to be removed
+     */
+    protected AppletListener remove(AppletListener oldl) {
+        if (oldl == a)  return b;
+        if (oldl == b)  return a;
+        AppletListener a2 = removeInternal(a, oldl);
+        AppletListener b2 = removeInternal(b, oldl);
+        if (a2 == a && b2 == b) {
+            return this;        // it's not here
+        }
+        return addInternal(a2, b2);
+    }
+
+
+    /**
+     * Returns the resulting multicast listener after removing the
+     * old listener from listener-l.
+     * If listener-l equals the old listener OR listener-l is null,
+     * returns null.
+     * Else if listener-l is an instance of AppletEventMulticaster
+     * then it removes the old listener from it.
+     * Else, returns listener l.
+     * @param l the listener being removed from
+     * @param oldl the listener being removed
+     */
+    private static AppletListener removeInternal(AppletListener l, AppletListener oldl) {
+        if (l == oldl || l == null) {
+            return null;
+        } else if (l instanceof AppletEventMulticaster) {
+            return ((AppletEventMulticaster)l).remove(oldl);
+        } else {
+            return l;           // it's not here
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugin/icedtea/java/src/main/sun/applet/AppletIOException.java	Tue Sep 23 16:33:17 2008 -0400
@@ -0,0 +1,59 @@
+/*
+ * Copyright 1996 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.IOException;
+
+/**
+ * An applet IO exception.
+ *
+ * @author      Koji Uno
+ */
+public
+class AppletIOException extends IOException {
+    private String key = null;
+    private Object msgobj = null;
+
+    public AppletIOException(String key) {
+        super(key);
+        this.key = key;
+
+    }
+    public AppletIOException(String key, Object arg) {
+        this(key);
+        msgobj = arg;
+    }
+
+    public String getLocalizedMessage() {
+        if( msgobj != null)
+            return amh.getMessage(key, msgobj);
+        else
+            return amh.getMessage(key);
+    }
+
+    private static AppletMessageHandler amh = new AppletMessageHandler("appletioexception");
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugin/icedtea/java/src/main/sun/applet/AppletIllegalArgumentException.java	Tue Sep 23 16:33:17 2008 -0400
@@ -0,0 +1,48 @@
+/*
+ * Copyright 1996 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;
+
+/**
+ * An applet security exception.
+ *
+ * @author      Arthur van Hoff
+ */
+public
+class AppletIllegalArgumentException extends IllegalArgumentException {
+    private String key = null;
+
+    public AppletIllegalArgumentException(String key) {
+        super(key);
+        this.key = key;
+
+    }
+
+    public String getLocalizedMessage() {
+        return amh.getMessage(key);
+    }
+
+    private static AppletMessageHandler amh = new AppletMessageHandler("appletillegalargumentexception");
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugin/icedtea/java/src/main/sun/applet/AppletImageRef.java	Tue Sep 23 16:33:17 2008 -0400
@@ -0,0 +1,54 @@
+/*
+ * Copyright 1996 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.awt.Toolkit;
+import java.awt.Image;
+import sun.awt.image.URLImageSource;
+import java.net.URL;
+
+class AppletImageRef extends sun.misc.Ref {
+    URL url;
+
+    /**
+     * Create the Ref
+     */
+    AppletImageRef(URL url) {
+        this.url = url;
+    }
+
+    public void flush() {
+        super.flush();
+    }
+
+    /**
+     * Reconsitute the image.  Only called when the ref has been flushed.
+     */
+    public Object reconstitute() {
+        Image img = Toolkit.getDefaultToolkit().createImage(new URLImageSource(url));
+        return img;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugin/icedtea/java/src/main/sun/applet/AppletListener.java	Tue Sep 23 16:33:17 2008 -0400
@@ -0,0 +1,39 @@
+/*
+ * Copyright 1997 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.util.EventListener;
+
+/**
+ * Applet Listener interface.  This interface is to be implemented
+ * by objects interested in AppletEvents.
+ *
+ * @author  Sunita Mani
+ */
+
+public interface AppletListener extends EventListener {
+    public void appletStateChanged(AppletEvent e);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugin/icedtea/java/src/main/sun/applet/AppletMessageHandler.java	Tue Sep 23 16:33:17 2008 -0400
@@ -0,0 +1,113 @@
+/*
+ * Copyright 1996-1997 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.util.ResourceBundle;
+import java.util.MissingResourceException;
+import java.text.MessageFormat;
+
+/**
+ * An hanlder of localized messages.
+ *
+ * @author      Koji Uno
+ */
+class AppletMessageHandler {
+    private static ResourceBundle rb;
+    private String baseKey = null;
+
+    static {
+        try {
+            rb = ResourceBundle.getBundle
+                ("sun.applet.resources.MsgAppletViewer");
+        } catch (MissingResourceException e) {
+            System.out.println(e.getMessage());
+            System.exit(1);
+        }
+    }
+
+    AppletMessageHandler(String baseKey) {
+        this.baseKey = baseKey;
+    }
+
+    String getMessage(String key) {
+        return (String)rb.getString(getQualifiedKey(key));
+    }
+
+    String getMessage(String key, Object arg){
+        String basemsgfmt = (String)rb.getString(getQualifiedKey(key));
+        MessageFormat msgfmt = new MessageFormat(basemsgfmt);
+        Object msgobj[] = new Object[1];
+        if (arg == null) {
+            arg = "null"; // mimic java.io.PrintStream.print(String)
+        }
+        msgobj[0] = arg;
+        return msgfmt.format(msgobj);
+    }
+
+    String getMessage(String key, Object arg1, Object arg2) {
+        String basemsgfmt = (String)rb.getString(getQualifiedKey(key));
+        MessageFormat msgfmt = new MessageFormat(basemsgfmt);
+        Object msgobj[] = new Object[2];
+        if (arg1 == null) {
+            arg1 = "null";
+        }
+        if (arg2 == null) {
+            arg2 = "null";
+        }
+        msgobj[0] = arg1;
+        msgobj[1] = arg2;
+        return msgfmt.format(msgobj);
+    }
+
+    String getMessage(String key, Object arg1, Object arg2, Object arg3) {
+        String basemsgfmt = (String)rb.getString(getQualifiedKey(key));
+        MessageFormat msgfmt = new MessageFormat(basemsgfmt);
+        Object msgobj[] = new Object[3];
+        if (arg1 == null) {
+            arg1 = "null";
+        }
+        if (arg2 == null) {
+            arg2 = "null";
+        }
+        if (arg3 == null) {
+            arg3 = "null";
+        }
+        msgobj[0] = arg1;
+        msgobj[1] = arg2;
+        msgobj[2] = arg3;
+        return msgfmt.format(msgobj);
+    }
+
+    String getMessage(String key, Object arg[]) {
+        String basemsgfmt = (String)rb.getString(getQualifiedKey(key));
+        MessageFormat msgfmt = new MessageFormat(basemsgfmt);
+        return msgfmt.format(arg);
+    }
+
+    String getQualifiedKey(String subKey) {
+        return baseKey + "." + subKey;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugin/icedtea/java/src/main/sun/applet/AppletObjectInputStream.java	Tue Sep 23 16:33:17 2008 -0400
@@ -0,0 +1,106 @@
+/*
+ * Copyright 1996-1997 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.
+ */
+/*
+ * COPYRIGHT goes here
+ */
+
+package sun.applet;
+
+import java.io.*;
+import java.lang.reflect.Array;
+
+/**
+ * This subclass of ObjectInputStream delegates loading of classes to
+ * an existing ClassLoader.
+ */
+
+class AppletObjectInputStream extends ObjectInputStream
+{
+    private AppletClassLoader loader;
+
+    /**
+     * Loader must be non-null;
+     */
+
+    public AppletObjectInputStream(InputStream in, AppletClassLoader loader)
+            throws IOException, StreamCorruptedException {
+
+        super(in);
+        if (loader == null) {
+            throw new AppletIllegalArgumentException("appletillegalargumentexception.objectinputstream");
+
+        }
+        this.loader = loader;
+    }
+
+    /**
+     * Make a primitive array class
+     */
+
+    private Class primitiveType(char type) {
+        switch (type) {
+        case 'B': return byte.class;
+        case 'C': return char.class;
+        case 'D': return double.class;
+        case 'F': return float.class;
+        case 'I': return int.class;
+        case 'J': return long.class;
+        case 'S': return short.class;
+        case 'Z': return boolean.class;
+        default: return null;
+        }
+    }
+
+    /**
+     * Use the given ClassLoader rather than using the system class
+     */
+    protected Class resolveClass(ObjectStreamClass classDesc)
+        throws IOException, ClassNotFoundException {
+
+        String cname = classDesc.getName();
+        if (cname.startsWith("[")) {
+            // An array
+            Class component;            // component class
+            int dcount;                 // dimension
+            for (dcount=1; cname.charAt(dcount)=='['; dcount++) ;
+            if (cname.charAt(dcount) == 'L') {
+                component = loader.loadClass(cname.substring(dcount+1,
+                                                             cname.length()-1));
+            } else {
+                if (cname.length() != dcount+1) {
+                    throw new ClassNotFoundException(cname);// malformed
+                }
+                component = primitiveType(cname.charAt(dcount));
+            }
+            int dim[] = new int[dcount];
+            for (int i=0; i<dcount; i++) {
+                dim[i]=0;
+            }
+            return Array.newInstance(component, dim).getClass();
+        } else {
+            return loader.loadClass(cname);
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugin/icedtea/java/src/main/sun/applet/AppletPanel.java	Tue Sep 23 16:33:17 2008 -0400
@@ -0,0 +1,1334 @@
+/*
+ * Copyright 1995-2007 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.applet.*;
+import java.awt.*;
+import java.awt.event.*;
+import java.awt.image.ColorModel;
+import java.awt.image.MemoryImageSource;
+import java.io.*;
+import java.lang.ref.WeakReference;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.InetAddress;
+import java.net.JarURLConnection;
+import java.net.MalformedURLException;
+import java.net.SocketPermission;
+import java.net.URL;
+import java.net.UnknownHostException;
+import java.security.*;
+import java.util.*;
+import javax.swing.SwingUtilities;
+import sun.awt.AppContext;
+import sun.awt.EmbeddedFrame;
+import sun.awt.SunToolkit;
+import sun.misc.MessageUtils;
+import sun.misc.PerformanceLogger;
+import sun.misc.Queue;
+import sun.security.util.SecurityConstants;
+
+/**
+ * Applet panel class. The panel manages and manipulates the
+ * applet as it is being loaded. It forks a separate thread in a new
+ * thread group to call the applet's init(), start(), stop(), and
+ * destroy() methods.
+ *
+ * @author      Arthur van Hoff
+ */
+public
+abstract class AppletPanel extends Panel implements AppletStub, Runnable {
+
+    /**
+     * The applet (if loaded).
+     */
+    protected Applet applet;
+
+    /**
+     * Applet will allow initialization.  Should be
+     * set to false if loading a serialized applet
+     * that was pickled in the init=true state.
+     */
+    protected boolean doInit = true;
+
+
+    /**
+     * The classloader for the applet.
+     */
+    AppletClassLoader loader;
+
+    /* applet event ids */
+    public final static int APPLET_DISPOSE = 0;
+    public final static int APPLET_LOAD = 1;
+    public final static int APPLET_INIT = 2;
+    public final static int APPLET_START = 3;
+    public final static int APPLET_STOP = 4;
+    public final static int APPLET_DESTROY = 5;
+    public final static int APPLET_QUIT = 6;
+    public final static int APPLET_ERROR = 7;
+
+    /* send to the parent to force relayout */
+    public final static int APPLET_RESIZE = 51234;
+
+    /* sent to a (distant) parent to indicate that the applet is being
+     * loaded or as completed loading
+     */
+    public final static int APPLET_LOADING = 51235;
+    public final static int APPLET_LOADING_COMPLETED = 51236;
+
+    /**
+     * The current status. One of:
+     *    APPLET_DISPOSE,
+     *    APPLET_LOAD,
+     *    APPLET_INIT,
+     *    APPLET_START,
+     *    APPLET_STOP,
+     *    APPLET_DESTROY,
+     *    APPLET_ERROR.
+     */
+    protected int status;
+
+    /**
+     * The thread for the applet.
+     */
+    protected Thread handler;
+
+
+    /**
+     * The initial applet size.
+     */
+    Dimension defaultAppletSize = new Dimension(10, 10);
+
+    /**
+     * The current applet size.
+     */
+    Dimension currentAppletSize = new Dimension(10, 10);
+
+    MessageUtils mu = new MessageUtils();
+
+    /**
+     * The thread to use during applet loading
+     */
+
+    Thread loaderThread = null;
+
+    /**
+     * Flag to indicate that a loading has been cancelled
+     */
+    boolean loadAbortRequest = false;
+
+    /* abstract classes */
+    abstract protected String getCode();
+    abstract protected String getJarFiles();
+    abstract protected String getSerializedObject();
+
+    abstract public int    getWidth();
+    abstract public int    getHeight();
+    abstract public boolean hasInitialFocus();
+
+    private static int threadGroupNumber = 0;
+
+    protected void setupAppletAppContext() {
+        // do nothing
+    }
+
+    /*
+     * Creates a thread to run the applet. This method is called
+     * each time an applet is loaded and reloaded.
+     */
+	//Overridden by NetxPanel.
+    protected synchronized void createAppletThread() {
+        // Create a thread group for the applet, and start a new
+        // thread to load the applet.
+        String nm = "applet-" + getCode();
+        loader = getClassLoader(getCodeBase(), getClassLoaderCacheKey());
+        loader.grab(); // Keep this puppy around!
+
+        // 4668479: Option to turn off codebase lookup in AppletClassLoader
+        // during resource requests. [stanley.ho]
+        String param = getParameter("codebase_lookup");
+
+        if (param != null && param.equals("false"))
+            loader.setCodebaseLookup(false);
+        else
+            loader.setCodebaseLookup(true);
+
+
+        ThreadGroup appletGroup = loader.getThreadGroup();
+
+        handler = new Thread(appletGroup, this, "thread " + nm);
+        // set the context class loader for this thread
+        AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    handler.setContextClassLoader(loader);
+                    return null;
+                }
+            });
+        handler.start();
+    }
+
+    void joinAppletThread() throws InterruptedException {
+        if (handler != null) {
+            handler.join();
+            handler = null;
+        }
+    }
+
+    void release() {
+        if (loader != null) {
+            loader.release();
+            loader = null;
+        }
+    }
+
+    /**
+     * Construct an applet viewer and start the applet.
+     */
+    public void init() {
+        try {
+            // Get the width (if any)
+            defaultAppletSize.width = getWidth();
+            currentAppletSize.width = defaultAppletSize.width;
+
+            // Get the height (if any)
+            defaultAppletSize.height = getHeight();
+            currentAppletSize.height = defaultAppletSize.height;
+
+        } catch (NumberFormatException e) {
+            // Turn on the error flag and let TagAppletPanel
+            // do the right thing.
+            status = APPLET_ERROR;
+            showAppletStatus("badattribute.exception");
+            showAppletLog("badattribute.exception");
+            showAppletException(e);
+        }
+
+        setLayout(new BorderLayout());
+
+        createAppletThread();
+    }
+
+    /**
+     * Minimum size
+     */
+    public Dimension minimumSize() {
+        return new Dimension(defaultAppletSize.width,
+                             defaultAppletSize.height);
+    }
+
+    /**
+     * Preferred size
+     */
+    public Dimension preferredSize() {
+        return new Dimension(currentAppletSize.width,
+                             currentAppletSize.height);
+    }
+
+    private AppletListener listeners;
+
+    /**
+     * AppletEvent Queue
+     */
+    private Queue queue = null;
+
+
+    synchronized public void addAppletListener(AppletListener l) {
+        listeners = AppletEventMulticaster.add(listeners, l);
+    }
+
+    synchronized public void removeAppletListener(AppletListener l) {
+        listeners = AppletEventMulticaster.remove(listeners, l);
+    }
+
+    /**
+     * Dispatch event to the listeners..
+     */
+    public void dispatchAppletEvent(int id, Object argument) {
+        //System.out.println("SEND= " + id);
+        if (listeners != null) {
+            AppletEvent evt = new AppletEvent(this, id, argument);
+            listeners.appletStateChanged(evt);
+        }
+    }
+
+    /**
+     * Send an event. Queue it for execution by the handler thread.
+     */
+    public void sendEvent(int id) {
+        synchronized(this) {
+            if (queue == null) {
+                //System.out.println("SEND0= " + id);
+                queue = new Queue();
+            }
+            Integer eventId = new Integer(id);
+            queue.enqueue(eventId);
+            notifyAll();
+        }
+        if (id == APPLET_QUIT) {
+            try {
+                joinAppletThread(); // Let the applet event handler exit
+            } catch (InterruptedException e) {
+            }
+
+            // AppletClassLoader.release() must be called by a Thread
+            // not within the applet's ThreadGroup
+            if (loader == null)
+                loader = getClassLoader(getCodeBase(), getClassLoaderCacheKey());
+            release();
+        }
+    }
+
+    /**
+     * Get an event from the queue.
+     */
+    protected synchronized AppletEvent getNextEvent() throws InterruptedException {
+        while (queue == null || queue.isEmpty()) {
+            wait();
+        }
+        Integer eventId = (Integer)queue.dequeue();
+        return new AppletEvent(this, eventId.intValue(), null);
+    }
+
+    boolean emptyEventQueue() {
+        if ((queue == null) || (queue.isEmpty()))
+            return true;
+        else
+            return false;
+    }
+
+    /**
+     * This kludge is specific to get over AccessControlException thrown during
+     * Applet.stop() or destroy() when static thread is suspended.  Set a flag
+     * in AppletClassLoader to indicate that an
+     * AccessControlException for RuntimePermission "modifyThread" or
+     * "modifyThreadGroup" had occurred.
+     */
+     private void setExceptionStatus(AccessControlException e) {
+     Permission p = e.getPermission();
+     if (p instanceof RuntimePermission) {
+         if (p.getName().startsWith("modifyThread")) {
+             if (loader == null)
+                 loader = getClassLoader(getCodeBase(), getClassLoaderCacheKey());
+             loader.setExceptionStatus();
+         }
+     }
+     }
+
+    /**
+     * Execute applet events.
+     * Here is the state transition diagram
+     *
+     *   Note: (XXX) is the action
+     *         APPLET_XXX is the state
+     *  (applet code loaded) --> APPLET_LOAD -- (applet init called)--> APPLET_INIT -- (
+     *   applet start called) --> APPLET_START -- (applet stop called) -->APPLET_STOP --(applet
+     *   destroyed called) --> APPLET_DESTROY -->(applet gets disposed) -->
+     *   APPLET_DISPOSE -->....
+     *
+     * In the legacy lifecycle model. The applet gets loaded, inited and started. So it stays
+     * in the APPLET_START state unless the applet goes away(refresh page or leave the page).
+     * So the applet stop method called and the applet enters APPLET_STOP state. Then if the applet
+     * is revisited, it will call applet start method and enter the APPLET_START state and stay there.
+     *
+     * In the modern lifecycle model. When the applet first time visited, it is same as legacy lifecycle
+     * model. However, when the applet page goes away. It calls applet stop method and enters APPLET_STOP
+     * state and then applet destroyed method gets called and enters APPLET_DESTROY state.
+     *
+     * This code is also called by AppletViewer. In AppletViewer "Restart" menu, the applet is jump from
+     * APPLET_STOP to APPLET_DESTROY and to APPLET_INIT .
+     *
+     * Also, the applet can jump from APPLET_INIT state to APPLET_DESTROY (in Netscape/Mozilla case).
+         * Same as APPLET_LOAD to
+     * APPLET_DISPOSE since all of this are triggered by browser.
+     *
+     *
+     */
+    public void run() {
+
+        Thread curThread = Thread.currentThread();
+        if (curThread == loaderThread) {
+            // if we are in the loader thread, cause
+            // loading to occur.  We may exit this with
+            // status being APPLET_DISPOSE, APPLET_ERROR,
+            // or APPLET_LOAD
+            runLoader();
+            return;
+        }
+
+        boolean disposed = false;
+        while (!disposed && !curThread.isInterrupted()) {
+            AppletEvent evt;
+            try {
+                evt = getNextEvent();
+            } catch (InterruptedException e) {
+                showAppletStatus("bail");
+                return;
+            }
+
+            //showAppletStatus("EVENT = " + evt.getID());
+            try {
+                switch (evt.getID()) {
+                  case APPLET_LOAD:
+                      if (!okToLoad()) {
+                          break;
+                      }
+                      // This complexity allows loading of applets to be
+                      // interruptable.  The actual thread loading runs
+                      // in a separate thread, so it can be interrupted
+                      // without harming the applet thread.
+                      // So that we don't have to worry about
+                      // concurrency issues, the main applet thread waits
+                      // until the loader thread terminates.
+                      // (one way or another).
+                      if (loaderThread == null) {
+                          // REMIND: do we want a name?
+                          //System.out.println("------------------- loading applet");
+                          setLoaderThread(new Thread(this));
+                          loaderThread.start();
+                          // we get to go to sleep while this runs
+                          loaderThread.join();
+                          setLoaderThread(null);
+                      } else {
+                          // REMIND: issue an error -- this case should never
+                          // occur.
+                      }
+                      break;
+
+                  case APPLET_INIT:
+                    // AppletViewer "Restart" will jump from destroy method to
+                    // init, that is why we need to check status w/ APPLET_DESTROY
+                      if (status != APPLET_LOAD && status != APPLET_DESTROY) {
+                          showAppletStatus("notloaded");
+                          break;
+                      }
+                      applet.resize(defaultAppletSize);
+                      if (doInit) {
+                          if (PerformanceLogger.loggingEnabled()) {
+                              PerformanceLogger.setTime("Applet Init");
+                              PerformanceLogger.outputLog();
+                          }
+                          applet.init();
+                      }
+
+                      //Need the default(fallback) font to be created in this AppContext
+                      Font f = getFont();
+                      if (f == null ||
+                          "dialog".equals(f.getFamily().toLowerCase(Locale.ENGLISH)) &&
+                          f.getSize() == 12 && f.getStyle() == Font.PLAIN) {
+                          setFont(new Font(Font.DIALOG, Font.PLAIN, 12));
+                      }
+
+                      doInit = true;    // allow restarts
+
+                      // Validate the applet in event dispatch thread
+                      // to avoid deadlock.
+                      try {
+                          final AppletPanel p = this;
+
+                          SwingUtilities.invokeAndWait(new Runnable() {
+                                  public void run() {
+                                      p.validate();
+                                  }
+                              });
+                      }
+                      catch(InterruptedException ie) {
+                      }
+                      catch(InvocationTargetException ite) {
+                      }
+
+                      status = APPLET_INIT;
+                      showAppletStatus("inited");
+                      break;
+
+                  case APPLET_START:
+                  {
+                      if (status != APPLET_INIT && status != APPLET_STOP) {
+                          showAppletStatus("notinited");
+                          break;
+                      }
+                      applet.resize(currentAppletSize);
+                      applet.start();
+
+                      // Validate and show the applet in event dispatch thread
+                      // to avoid deadlock.
+                      try {
+                          final AppletPanel p = this;
+                          final Applet a = applet;
+
+                          SwingUtilities.invokeAndWait(new Runnable() {
+                                  public void run() {
+                                      p.validate();
+                                      a.setVisible(true);
+
+                                      // Fix for BugTraq ID 4041703.
+                                      // Set the default focus for an applet.
+                                      if (hasInitialFocus())
+                                        setDefaultFocus();
+                                  }
+                              });
+                      }
+                      catch(InterruptedException ie) {
+                      }
+                      catch(InvocationTargetException ite) {
+                      }
+
+                      status = APPLET_START;
+                      showAppletStatus("started");
+
+                      // reset size to make up for applets that specify height in %
+                      try {
+                    	  javax.swing.SwingUtilities.invokeLater(new Runnable() {
+                    		  public void run() {
+                    			  int width = getWidth();
+                    			  int height = getHeight();
+
+                    			  appletResize(width, height);
+                    			  validate();
+                    		  }
+                    	  });
+                      } catch (Exception e) {
+                    	  System.err.println("Applet resize failed.");
+                    	  e.printStackTrace();
+                      }
+
+                      break;
+                  }
+                case APPLET_STOP:
+                    if (status != APPLET_START) {
+                        showAppletStatus("notstarted");
+                        break;
+                    }
+                    status = APPLET_STOP;
+
+                    // Hide the applet in event dispatch thread
+                    // to avoid deadlock.
+                    try {
+                        final Applet a = applet;
+
+                        SwingUtilities.invokeAndWait(new Runnable() {
+                                public void run()
+                                {
+                                    a.setVisible(false);
+                                }
+                            });
+                    }
+                    catch(InterruptedException ie) {
+                    }
+                    catch(InvocationTargetException ite) {
+                    }
+
+
+                    // During Applet.stop(), any AccessControlException on an involved Class remains in
+                    // the "memory" of the AppletClassLoader.  If the same instance of the ClassLoader is
+                    // reused, the same exception will occur during class loading.  Set the AppletClassLoader's
+                    // exceptionStatusSet flag to allow recognition of what had happened
+                    // when reusing AppletClassLoader object.
+                    try {
+                        applet.stop();
+                    } catch (java.security.AccessControlException e) {
+                        setExceptionStatus(e);
+                        // rethrow exception to be handled as it normally would be.
+                        throw e;
+                    }
+                    showAppletStatus("stopped");
+                    break;
+
+                case APPLET_DESTROY:
+                    if (status != APPLET_STOP && status != APPLET_INIT) {
+                        showAppletStatus("notstopped");
+                        break;
+                    }
+                    status = APPLET_DESTROY;
+
+                    // During Applet.destroy(), any AccessControlException on an involved Class remains in
+                    // the "memory" of the AppletClassLoader.  If the same instance of the ClassLoader is
+                    // reused, the same exception will occur during class loading.  Set the AppletClassLoader's
+                    // exceptionStatusSet flag to allow recognition of what had happened
+                    // when reusing AppletClassLoader object.
+                    try {
+                        applet.destroy();
+                    } catch (java.security.AccessControlException e) {
+                        setExceptionStatus(e);
+                        // rethrow exception to be handled as it normally would be.
+                        throw e;
+                    }
+                    showAppletStatus("destroyed");
+                    break;
+
+                case APPLET_DISPOSE:
+                    if (status != APPLET_DESTROY && status != APPLET_LOAD) {
+                        showAppletStatus("notdestroyed");
+                        break;
+                    }
+                    status = APPLET_DISPOSE;
+
+                    try
+                    {
+                        final Applet a = applet;
+
+                        EventQueue.invokeAndWait(new Runnable()
+                        {
+                            public void run()
+                            {
+                                remove(a);
+                            }
+                        });
+                    }
+                    catch(InterruptedException ie)
+                    {
+                    }
+                    catch(InvocationTargetException ite)
+                    {
+                    }
+                    applet = null;
+                    showAppletStatus("disposed");
+                    disposed = true;
+                    break;
+
+                case APPLET_QUIT:
+                    return;
+                }
+            } catch (Exception e) {
+                status = APPLET_ERROR;
+                if (e.getMessage() != null) {
+                    showAppletStatus("exception2", e.getClass().getName(),
+                                     e.getMessage());
+                } else {
+                    showAppletStatus("exception", e.getClass().getName());
+                }
+                showAppletException(e);
+            } catch (ThreadDeath e) {
+                showAppletStatus("death");
+                return;
+            } catch (Error e) {
+                status = APPLET_ERROR;
+                if (e.getMessage() != null) {
+                    showAppletStatus("error2", e.getClass().getName(),
+                                     e.getMessage());
+                } else {
+                    showAppletStatus("error", e.getClass().getName());
+                }
+                showAppletException(e);
+            }
+            clearLoadAbortRequest();
+        }
+    }
+
+    /**
+     * Gets most recent focus owner component associated with the given window.
+     * It does that without calling Window.getMostRecentFocusOwner since it
+     * provides its own logic contradicting with setDefautlFocus. Instead, it
+     * calls KeyboardFocusManager directly.
+     */
+    private Component getMostRecentFocusOwnerForWindow(Window w) {
+        Method meth = (Method)AccessController.doPrivileged(new PrivilegedAction() {
+                public Object run() {
+                    Method meth = null;
+                    try {
+                        meth = KeyboardFocusManager.class.getDeclaredMethod("getMostRecentFocusOwner", new Class[] {Window.class});
+                        meth.setAccessible(true);
+                    } catch (Exception e) {
+                        // Must never happen
+                        e.printStackTrace();
+                    }
+                    return meth;
+                }
+            });
+        if (meth != null) {
+            // Meth refers static method
+            try {
+                return (Component)meth.invoke(null, new Object[] {w});
+            } catch (Exception e) {
+                // Must never happen
+                e.printStackTrace();
+            }
+        }
+        // Will get here if exception was thrown or meth is null
+        return w.getMostRecentFocusOwner();
+    }
+
+    /*
+     * Fix for BugTraq ID 4041703.
+     * Set the focus to a reasonable default for an Applet.
+     */
+    private void setDefaultFocus() {
+        Component toFocus = null;
+        Container parent = getParent();
+
+        if(parent != null) {
+            if (parent instanceof Window) {
+                toFocus = getMostRecentFocusOwnerForWindow((Window)parent);
+                if (toFocus == parent || toFocus == null) {
+                    toFocus = parent.getFocusTraversalPolicy().
+                        getInitialComponent((Window)parent);
+                }
+            } else if (parent.isFocusCycleRoot()) {
+                toFocus = parent.getFocusTraversalPolicy().
+                    getDefaultComponent(parent);
+            }
+        }
+
+        if (toFocus != null) {
+            if (parent instanceof EmbeddedFrame) {
+                ((EmbeddedFrame)parent).synthesizeWindowActivation(true);
+            }
+            // EmbeddedFrame might have focus before the applet was added.
+            // Thus after its activation the most recent focus owner will be
+            // restored. We need the applet's initial focusabled component to
+            // be focused here.
+            toFocus.requestFocusInWindow();
+        }
+    }
+
+    /**
+     * Load the applet into memory.
+     * Runs in a seperate (and interruptible) thread from the rest of the
+     * applet event processing so that it can be gracefully interrupted from
+     * things like HotJava.
+     */
+	//Overridden by NetxPanel.
+    protected void runLoader() {
+        if (status != APPLET_DISPOSE) {
+            showAppletStatus("notdisposed");
+            return;
+        }
+
+        dispatchAppletEvent(APPLET_LOADING, null);
+
+        // REMIND -- might be cool to visually indicate loading here --
+        // maybe do animation?
+        status = APPLET_LOAD;
+
+        // Create a class loader
+        loader = getClassLoader(getCodeBase(), getClassLoaderCacheKey());
+
+        // Load the archives if present.
+        // REMIND - this probably should be done in a separate thread,
+        // or at least the additional archives (epll).
+
+        String code = getCode();
+
+        // setup applet AppContext
+        // this must be called before loadJarFiles
+        setupAppletAppContext();
+
+        try {
+            loadJarFiles(loader);
+            applet = createApplet(loader);
+        } catch (ClassNotFoundException e) {
+            status = APPLET_ERROR;
+            showAppletStatus("notfound", code);
+            showAppletLog("notfound", code);
+            showAppletException(e);
+            return;
+        } catch (InstantiationException e) {
+            status = APPLET_ERROR;
+            showAppletStatus("nocreate", code);
+            showAppletLog("nocreate", code);
+            showAppletException(e);
+            return;
+        } catch (IllegalAccessException e) {
+            status = APPLET_ERROR;
+            showAppletStatus("noconstruct", code);
+            showAppletLog("noconstruct", code);
+            showAppletException(e);
+            // sbb -- I added a return here
+            return;
+        } catch (Exception e) {
+            status = APPLET_ERROR;
+            showAppletStatus("exception", e.getMessage());
+            showAppletException(e);
+            return;
+        } catch (ThreadDeath e) {
+            status = APPLET_ERROR;
+            showAppletStatus("death");
+            return;
+        } catch (Error e) {
+            status = APPLET_ERROR;
+            showAppletStatus("error", e.getMessage());
+            showAppletException(e);
+            return;
+        } finally {
+            // notify that loading is no longer going on
+            dispatchAppletEvent(APPLET_LOADING_COMPLETED, null);
+        }
+
+        // Fixed #4508194: NullPointerException thrown during
+        // quick page switch
+        //
+        if (applet != null)
+        {
+            // Stick it in the frame
+            applet.setStub(this);
+            applet.hide();
+            add("Center", applet);
+            showAppletStatus("loaded");
+            validate();
+        }
+    }
+
+    protected Applet createApplet(final AppletClassLoader loader) throws ClassNotFoundException,
+                                                                         IllegalAccessException, IOException, InstantiationException, InterruptedException {
+        final String serName = getSerializedObject();
+        String code = getCode();
+
+        if (code != null && serName != null) {
+            System.err.println(amh.getMessage("runloader.err"));
+//          return null;
+            throw new InstantiationException("Either \"code\" or \"object\" should be specified, but not both.");
+        }
+        if (code == null && serName == null) {
+            String msg = "nocode";
+            status = APPLET_ERROR;
+            showAppletStatus(msg);
+            showAppletLog(msg);
+            repaint();
+        }
+        if (code != null) {
+            applet = (Applet)loader.loadCode(code).newInstance();
+            doInit = true;
+        } else {
+            // serName is not null;
+            InputStream is = (InputStream)
+                java.security.AccessController.doPrivileged(
+                                                            new java.security.PrivilegedAction() {
+                                                                public Object run() {
+                                                                    return loader.getResourceAsStream(serName);
+                                                                }
+                                                            });
+            ObjectInputStream ois =
+                new AppletObjectInputStream(is, loader);
+            Object serObject = ois.readObject();
+            applet = (Applet) serObject;
+            doInit = false; // skip over the first init
+        }
+
+        // Determine the JDK level that the applet targets.
+        // This is critical for enabling certain backward
+        // compatibility switch if an applet is a JDK 1.1
+        // applet. [stanley.ho]
+        findAppletJDKLevel(applet);
+
+        if (Thread.interrupted()) {
+            try {
+                status = APPLET_DISPOSE; // APPLET_ERROR?
+                applet = null;
+                // REMIND: This may not be exactly the right thing: the
+                // status is set by the stop button and not necessarily
+                // here.
+                showAppletStatus("death");
+            } finally {
+                Thread.currentThread().interrupt(); // resignal interrupt
+            }
+            return null;
+        }
+        return applet;
+    }
+
+    protected void loadJarFiles(AppletClassLoader loader) throws IOException,
+                                                                 InterruptedException {
+        // Load the archives if present.
+        // REMIND - this probably should be done in a separate thread,
+        // or at least the additional archives (epll).
+        String jarFiles = getJarFiles();
+
+        if (jarFiles != null) {
+            StringTokenizer st = new StringTokenizer(jarFiles, ",", false);
+            while(st.hasMoreTokens()) {
+                String tok = st.nextToken().trim();
+                try {
+                    loader.addJar(tok);
+                } catch (IllegalArgumentException e) {
+                    // bad archive name
+                    continue;
+                }
+            }
+        }
+    }
+
+    /**
+     * Request that the loading of the applet be stopped.
+     */
+    protected synchronized void stopLoading() {
+        // REMIND: fill in the body
+        if (loaderThread != null) {
+            //System.out.println("Interrupting applet loader thread: " + loaderThread);
+            loaderThread.interrupt();
+        } else {
+            setLoadAbortRequest();
+        }
+    }
+
+
+    protected synchronized boolean okToLoad() {
+        return !loadAbortRequest;
+    }
+
+    protected synchronized void clearLoadAbortRequest() {
+        loadAbortRequest = false;
+    }
+
+    protected synchronized void setLoadAbortRequest() {
+        loadAbortRequest = true;
+    }
+
+
+    private synchronized void setLoaderThread(Thread loaderThread) {
+        this.loaderThread = loaderThread;
+    }
+
+    /**
+     * Return true when the applet has been started.
+     */
+    public boolean isActive() {
+        return status == APPLET_START;
+    }
+
+    private EventQueue appEvtQ = null;
+
+    /**
+     * Is called when the applet wants to be resized.
+     */
+    public void appletResize(int width, int height) {
+        currentAppletSize.width = width;
+        currentAppletSize.height = height;
+        final Dimension currentSize = new Dimension(currentAppletSize.width,
+                                                    currentAppletSize.height);
+
+        if(loader != null) {
+            AppContext appCtxt = loader.getAppContext();
+            if(appCtxt != null)
+                appEvtQ = (java.awt.EventQueue)appCtxt.get(AppContext.EVENT_QUEUE_KEY);
+        }
+
+        final AppletPanel ap = this;
+        if (appEvtQ != null){
+            appEvtQ.postEvent(new InvocationEvent(Toolkit.getDefaultToolkit(),
+                                                  new Runnable(){
+                                                      public void run(){
+                                                          if(ap != null)
+                                                          {
+                                                              ap.dispatchAppletEvent(APPLET_RESIZE, currentSize);
+                                                          }
+                                                      }
+                                                  }));
+        }
+    }
+
+    public void setBounds(int x, int y, int width, int height) {
+        super.setBounds(x, y, width, height);
+        currentAppletSize.width = width;
+        currentAppletSize.height = height;
+    }
+
+    public Applet getApplet() {
+        return applet;
+    }
+
+    /**
+     * Status line. Called by the AppletPanel to provide
+     * feedback on the Applet's state.
+     */
+    protected void showAppletStatus(String status) {
+        getAppletContext().showStatus(amh.getMessage(status));
+    }
+
+    protected void showAppletStatus(String status, Object arg) {
+        getAppletContext().showStatus(amh.getMessage(status, arg));
+    }
+    protected void showAppletStatus(String status, Object arg1, Object arg2) {
+        getAppletContext().showStatus(amh.getMessage(status, arg1, arg2));
+    }
+
+    /**
+     * Called by the AppletPanel to print to the log.
+     */
+    protected void showAppletLog(String msg) {
+        System.out.println(amh.getMessage(msg));
+    }
+
+    protected void showAppletLog(String msg, Object arg) {
+        System.out.println(amh.getMessage(msg, arg));
+    }
+
+    /**
+     * Called by the AppletPanel to provide
+     * feedback when an exception has happened.
+     */
+    protected void showAppletException(Throwable t) {
+        t.printStackTrace();
+        repaint();
+    }
+
+    /**
+     * Get caching key for classloader cache
+     */
+    public String getClassLoaderCacheKey()
+    {
+        /**
+         * Fixed #4501142: Classlaoder sharing policy doesn't
+         * take "archive" into account. This will be overridden
+         * by Java Plug-in.                     [stanleyh]
+         */
+        return getCodeBase().toString();
+    }
+
+    /**
+     * The class loaders
+     */
+    private static HashMap classloaders = new HashMap();
+
+    /**
+     * Flush a class loader.
+     */
+    public static synchronized void flushClassLoader(String key) {
+        classloaders.remove(key);
+    }
+
+    /**
+     * Flush all class loaders.
+     */
+    public static synchronized void flushClassLoaders() {
+        classloaders = new HashMap();
+    }
+
+    /**
+     * This method actually creates an AppletClassLoader.
+     *
+     * It can be override by subclasses (such as the Plug-in)
+     * to provide different classloaders.
+     */
+    protected AppletClassLoader createClassLoader(final URL codebase) {
+        return new AppletClassLoader(codebase);
+    }
+
+    /**
+     * Get a class loader. Create in a restricted context
+     */
+    synchronized AppletClassLoader getClassLoader(final URL codebase, final String key) {
+        AppletClassLoader c = (AppletClassLoader)classloaders.get(key);
+        if (c == null) {
+            AccessControlContext acc =
+                getAccessControlContext(codebase);
+            c = (AppletClassLoader)
+                AccessController.doPrivileged(new PrivilegedAction() {
+                        public Object run() {
+                            AppletClassLoader ac = createClassLoader(codebase);
+                            /* Should the creation of the classloader be
+                             * within the class synchronized block?  Since
+                             * this class is used by the plugin, take care
+                             * to avoid deadlocks, or specialize
+                             * AppletPanel within the plugin.  It may take
+                             * an arbitrary amount of time to create a
+                             * class loader (involving getting Jar files
+                             * etc.) and may block unrelated applets from
+                             * finishing createAppletThread (due to the
+                             * class synchronization). If
+                             * createAppletThread does not finish quickly,
+                             * the applet cannot process other messages,
+                             * particularly messages such as destroy
+                             * (which timeout when called from the browser).
+                             */
+                            synchronized (getClass()) {
+                                AppletClassLoader res =
+                                    (AppletClassLoader)classloaders.get(key);
+                                if (res == null) {
+                                    classloaders.put(key, ac);
+                                    return ac;
+                                } else {
+                                    return res;
+                                }
+                            }
+                        }
+                    },acc);
+        }
+        return c;
+    }
+
+    /**
+     * get the context for the AppletClassLoader we are creating.
+     * the context is granted permission to create the class loader,
+     * connnect to the codebase, and whatever else the policy grants
+     * to all codebases.
+     */
+    private AccessControlContext getAccessControlContext(final URL codebase) {
+
+        PermissionCollection perms = (PermissionCollection)
+            AccessController.doPrivileged(new PrivilegedAction() {
+                    public Object run() {
+                        Policy p = java.security.Policy.getPolicy();
+                        if (p != null) {
+                            return p.getPermissions(new CodeSource(null,
+                                                                   (java.security.cert.Certificate[]) null));
+                        } else {
+                            return null;
+                        }
+                    }
+                });
+
+        if (perms == null)
+            perms = new Permissions();
+
+        //XXX: this is needed to be able to create the classloader itself!
+
+        perms.add(SecurityConstants.CREATE_CLASSLOADER_PERMISSION);
+
+        Permission p;
+        java.net.URLConnection urlConnection = null;
+        try {
+            urlConnection = codebase.openConnection();
+            p = urlConnection.getPermission();
+        } catch (java.io.IOException ioe) {
+            p = null;
+        }
+
+        if (p != null)
+            perms.add(p);
+
+        if (p instanceof FilePermission) {
+
+            String path = p.getName();
+
+            int endIndex = path.lastIndexOf(File.separatorChar);
+
+            if (endIndex != -1) {
+                path = path.substring(0, endIndex+1);
+
+                if (path.endsWith(File.separator)) {
+                    path += "-";
+                }
+                perms.add(new FilePermission(path,
+                                             SecurityConstants.FILE_READ_ACTION));
+            }
+        } else {
+            URL locUrl = codebase;
+            if (urlConnection instanceof JarURLConnection) {
+                locUrl = ((JarURLConnection)urlConnection).getJarFileURL();
+            }
+            String host = locUrl.getHost();
+            if (host != null && (host.length() > 0))
+                perms.add(new SocketPermission(host,
+                                               SecurityConstants.SOCKET_CONNECT_ACCEPT_ACTION));
+        }
+
+        ProtectionDomain domain =
+            new ProtectionDomain(new CodeSource(codebase,
+                                                (java.security.cert.Certificate[]) null), perms);
+        AccessControlContext acc =
+            new AccessControlContext(new ProtectionDomain[] { domain });
+
+        return acc;
+    }
+
+    public Thread getAppletHandlerThread() {
+        return handler;
+    }
+
+    public int getAppletWidth() {
+        return currentAppletSize.width;
+    }
+
+    public int getAppletHeight() {
+        return currentAppletSize.height;
+    }
+
+    public static void changeFrameAppContext(Frame frame, AppContext newAppContext)
+    {
+        // Fixed #4754451: Applet can have methods running on main
+        // thread event queue.
+        //
+        // The cause of this bug is that the frame of the applet
+        // is created in main thread group. Thus, when certain
+        // AWT/Swing events are generated, the events will be
+        // dispatched through the wrong event dispatch thread.
+        //
+        // To fix this, we rearrange the AppContext with the frame,
+        // so the proper event queue will be looked up.
+        //
+        // Swing also maintains a Frame list for the AppContext,
+        // so we will have to rearrange it as well.
+
+        // Check if frame's AppContext has already been set properly
+        AppContext oldAppContext = SunToolkit.targetToAppContext(frame);
+
+        if (oldAppContext == newAppContext)
+            return;
+
+        // Synchronization on Window.class is needed for locking the
+        // critical section of the window list in AppContext.
+        synchronized (Window.class)
+        {
+            WeakReference weakRef = null;
+            // Remove frame from the Window list in wrong AppContext
+            {
+                // Lookup current frame's AppContext
+                Vector<WeakReference<Window>> windowList = (Vector<WeakReference<Window>>)oldAppContext.get(Window.class);
+                if (windowList != null) {
+                    for (WeakReference ref : windowList) {
+                        if (ref.get() == frame) {
+                            weakRef = ref;
+                            break;
+                        }
+                    }
+                    // Remove frame from wrong AppContext
+                    if (weakRef != null)
+                        windowList.remove(weakRef);
+                }
+            }
+
+            // Put the frame into the applet's AppContext map
+            SunToolkit.insertTargetMapping(frame, newAppContext);
+
+            // Insert frame into the Window list in the applet's AppContext map
+            {
+                Vector<WeakReference<Window>> windowList = (Vector)newAppContext.get(Window.class);
+                if (windowList == null) {
+                    windowList = new Vector<WeakReference<Window>>();
+                    newAppContext.put(Window.class, windowList);
+                }
+                // use the same weakRef here as it is used elsewhere
+                windowList.add(weakRef);
+            }
+        }
+    }
+
+    // Flag to indicate if applet is targeted for JDK 1.1.
+    private boolean jdk11Applet = false;
+
+    // Flag to indicate if applet is targeted for JDK 1.2.
+    private boolean jdk12Applet = false;
+
+    /**
+     * Determine JDK level of an applet.
+     */
+    private void findAppletJDKLevel(Applet applet)
+    {
+        // To determine the JDK level of an applet, the
+        // most reliable way is to check the major version
+        // of the applet class file.
+
+        // synchronized on applet class object, so calling from
+        // different instances of the same applet will be
+        // serialized.
+        Class appletClass = applet.getClass();
+
+        synchronized(appletClass)  {
+            // Determine if the JDK level of an applet has been
+            // checked before.
+            Boolean jdk11Target = (Boolean) loader.isJDK11Target(appletClass);
+            Boolean jdk12Target = (Boolean) loader.isJDK12Target(appletClass);
+
+            // if applet JDK level has been checked before, retrieve
+            // value and return.
+            if (jdk11Target != null || jdk12Target != null) {
+                jdk11Applet = (jdk11Target == null) ? false : jdk11Target.booleanValue();
+                jdk12Applet = (jdk12Target == null) ? false : jdk12Target.booleanValue();
+                return;
+            }
+
+            String name = appletClass.getName();
+
+            // first convert any '.' to '/'
+            name = name.replace('.', '/');
+
+            // append .class
+            final String resourceName = name + ".class";
+
+            InputStream is = null;
+            byte[] classHeader = new byte[8];
+
+            try {
+                is = (InputStream) java.security.AccessController.doPrivileged(
+                    new java.security.PrivilegedAction() {
+                        public Object run() {
+                            return loader.getResourceAsStream(resourceName);
+                        }
+                    });
+
+                // Read the first 8 bytes of the class file
+                int byteRead = is.read(classHeader, 0, 8);
+                is.close();
+
+                // return if the header is not read in entirely
+                // for some reasons.
+                if (byteRead != 8)
+                    return;
+            }
+            catch (IOException e)   {
+                return;
+            }
+
+            // Check major version in class file header
+            int major_version = readShort(classHeader, 6);
+
+            // Major version in class file is as follows:
+            //   45 - JDK 1.1
+            //   46 - JDK 1.2
+            //   47 - JDK 1.3
+            //   48 - JDK 1.4
+            //   49 - JDK 1.5
+            if (major_version < 46)
+                jdk11Applet = true;
+            else if (major_version == 46)
+                jdk12Applet = true;
+
+            // Store applet JDK level in AppContext for later lookup,
+            // e.g. page switch.
+            loader.setJDK11Target(appletClass, jdk11Applet);
+            loader.setJDK12Target(appletClass, jdk12Applet);
+        }
+    }
+
+    /**
+     * Return true if applet is targeted to JDK 1.1.
+     */
+    protected boolean isJDK11Applet()   {
+        return jdk11Applet;
+    }
+
+    /**
+     * Return true if applet is targeted to JDK1.2.
+     */
+    protected boolean isJDK12Applet()   {
+        return jdk12Applet;
+    }
+
+    /**
+     * Read short from byte array.
+     */
+    private int readShort(byte[] b, int off)    {
+        int hi = readByte(b[off]);
+        int lo = readByte(b[off + 1]);
+        return (hi << 8) | lo;
+    }
+
+    private int readByte(byte b) {
+        return ((int)b) & 0xFF;
+    }
+
+
+    private static AppletMessageHandler amh = new AppletMessageHandler("appletpanel");
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugin/icedtea/java/src/main/sun/applet/AppletProps.java	Tue Sep 23 16:33:17 2008 -0400
@@ -0,0 +1,221 @@
+/*
+ * Copyright 1995-2003 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.awt.*;
+import java.io.*;
+import java.util.Properties;
+import sun.net.www.http.HttpClient;
+import sun.net.ftp.FtpClient;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedExceptionAction;
+import java.security.PrivilegedActionException;
+
+import sun.security.action.*;
+
+class AppletProps extends Frame {
+
+    TextField proxyHost;
+    TextField proxyPort;
+    Choice accessMode;
+
+    AppletProps() {
+        setTitle(amh.getMessage("title"));
+        Panel p = new Panel();
+        p.setLayout(new GridLayout(0, 2));
+
+        p.add(new Label(amh.getMessage("label.http.server", "Http proxy server:")));
+        p.add(proxyHost = new TextField());
+
+        p.add(new Label(amh.getMessage("label.http.proxy")));
+        p.add(proxyPort = new TextField());
+
+        p.add(new Label(amh.getMessage("label.class")));
+        p.add(accessMode = new Choice());
+        accessMode.addItem(amh.getMessage("choice.class.item.restricted"));
+        accessMode.addItem(amh.getMessage("choice.class.item.unrestricted"));
+
+        add("Center", p);
+        p = new Panel();
+        p.add(new Button(amh.getMessage("button.apply")));
+        p.add(new Button(amh.getMessage("button.reset")));
+        p.add(new Button(amh.getMessage("button.cancel")));
+        add("South", p);
+        move(200, 150);
+        pack();
+        reset();
+    }
+
+    void reset() {
+        AppletSecurity security = (AppletSecurity) System.getSecurityManager();
+        if (security != null)
+            security.reset();
+
+        String proxyhost = (String) AccessController.doPrivileged(
+                new GetPropertyAction("http.proxyHost"));
+        String proxyport = (String)  AccessController.doPrivileged(
+                new GetPropertyAction("http.proxyPort"));
+
+        Boolean tmp = (Boolean) AccessController.doPrivileged(
+                new GetBooleanAction("package.restrict.access.sun"));
+
+        boolean packageRestrict = tmp.booleanValue();
+        if (packageRestrict) {
+           accessMode.select(amh.getMessage("choice.class.item.restricted"));
+        } else {
+           accessMode.select(amh.getMessage("choice.class.item.unrestricted"));
+        }
+
+        if (proxyhost != null) {
+            proxyHost.setText(proxyhost);
+            proxyPort.setText(proxyport);
+        } else {
+            proxyHost.setText("");
+            proxyPort.setText("");
+        }
+    }
+
+    void apply() {
+        String proxyHostValue = proxyHost.getText().trim();
+        String proxyPortValue = proxyPort.getText().trim();
+
+        // Get properties
+        final Properties props = (Properties) AccessController.doPrivileged(
+             new PrivilegedAction() {
+                 public Object run() {
+                     return System.getProperties();
+                 }
+        });
+
+        if (proxyHostValue.length() != 0) {
+            /* 4066402 */
+            /* Check for parsable value in proxy port number field before */
+            /* applying. Display warning to user until parsable value is  */
+            /* entered. */
+            int proxyPortNumber = 0;
+            try {
+                proxyPortNumber = Integer.parseInt(proxyPortValue);
+            } catch (NumberFormatException e) {}
+
+            if (proxyPortNumber <= 0) {
+                proxyPort.selectAll();
+                proxyPort.requestFocus();
+                (new AppletPropsErrorDialog(this,
+                                            amh.getMessage("title.invalidproxy"),
+                                            amh.getMessage("label.invalidproxy"),
+                                            amh.getMessage("button.ok"))).show();
+                return;
+            }
+            /* end 4066402 */
+
+            props.put("http.proxyHost", proxyHostValue);
+            props.put("http.proxyPort", proxyPortValue);
+        } else {
+            props.put("http.proxyHost", "");
+        }
+
+        if (amh.getMessage("choice.class.item.restricted").equals(accessMode.getSelectedItem())) {
+            props.put("package.restrict.access.sun", "true");
+        } else {
+            props.put("package.restrict.access.sun", "false");
+        }
+
+        // Save properties
+        try {
+            reset();
+            AccessController.doPrivileged(new PrivilegedExceptionAction() {
+                public Object run() throws IOException {
+                    File dotAV = Main.theUserPropertiesFile;
+                    FileOutputStream out = new FileOutputStream(dotAV);
+                    Properties avProps = new Properties();
+                    for (int i = 0; i < Main.avDefaultUserProps.length; i++) {
+                        String avKey = Main.avDefaultUserProps[i][0];
+                        avProps.setProperty(avKey, props.getProperty(avKey));
+                    }
+                    avProps.store(out, amh.getMessage("prop.store"));
+                    out.close();
+                    return null;
+                }
+            });
+            hide();
+        } catch (java.security.PrivilegedActionException e) {
+            System.out.println(amh.getMessage("apply.exception",
+                                              e.getException()));
+            // XXX what's the general feeling on stack traces to System.out?
+            e.printStackTrace();
+            reset();
+        }
+    }
+
+    public boolean action(Event evt, Object obj) {
+        if (amh.getMessage("button.apply").equals(obj)) {
+            apply();
+            return true;
+        }
+        if (amh.getMessage("button.reset").equals(obj)) {
+            reset();
+            return true;
+        }
+        if (amh.getMessage("button.cancel").equals(obj)) {
+            reset();
+            hide();
+            return true;
+        }
+        return false;
+    }
+
+    private static AppletMessageHandler amh = new AppletMessageHandler("appletprops");
+
+}
+
+/* 4066432 */
+/* Dialog class to display property-related errors to user */
+
+class AppletPropsErrorDialog extends Dialog {
+    public AppletPropsErrorDialog(Frame parent, String title, String message,
+                String buttonText) {
+        super(parent, title, true);
+        Panel p = new Panel();
+        add("Center", new Label(message));
+        p.add(new Button(buttonText));
+        add("South", p);
+        pack();
+
+        Dimension dDim = size();
+        Rectangle fRect = parent.bounds();
+        move(fRect.x + ((fRect.width - dDim.width) / 2),
+             fRect.y + ((fRect.height - dDim.height) / 2));
+    }
+
+    public boolean action(Event event, Object object) {
+        hide();
+        dispose();
+        return true;
+    }
+}
+
+/* end 4066432 */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugin/icedtea/java/src/main/sun/applet/AppletResourceLoader.java	Tue Sep 23 16:33:17 2008 -0400
@@ -0,0 +1,48 @@
+/*
+ * Copyright 1996-1998 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.net.URL;
+import java.awt.Image;
+import sun.misc.Ref;
+
+/**
+ * Part of this class still remains only to support legacy, 100%-impure
+ * applications such as HotJava 1.0.1.
+ */
+public class AppletResourceLoader {
+    public static Image getImage(URL url) {
+        return AppletViewer.getCachedImage(url);
+    }
+
+    public static Ref getImageRef(URL url) {
+        return AppletViewer.getCachedImageRef(url);
+    }
+
+    public static void flushImages() {
+        AppletViewer.flushImageCache();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugin/icedtea/java/src/main/sun/applet/AppletSecurity.java	Tue Sep 23 16:33:17 2008 -0400
@@ -0,0 +1,371 @@
+/*
+ * Copyright 1995-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.FilePermission;
+import java.io.IOException;
+import java.io.FileDescriptor;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.net.SocketPermission;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.HashSet;
+import java.util.StringTokenizer;
+import java.security.*;
+import java.lang.reflect.*;
+import sun.awt.AWTSecurityManager;
+import sun.awt.AppContext;
+import sun.security.provider.*;
+import sun.security.util.SecurityConstants;
+
+
+/**
+ * This class defines an applet security policy
+ *
+ */
+public
+class AppletSecurity extends AWTSecurityManager {
+    private AppContext mainAppContext;
+
+    //URLClassLoader.acc
+    private static Field facc = null;
+
+    //AccessControlContext.context;
+    private static Field fcontext = null;
+
+    static {
+        try {
+            facc = URLClassLoader.class.getDeclaredField("acc");
+            facc.setAccessible(true);
+            fcontext = AccessControlContext.class.getDeclaredField("context");
+            fcontext.setAccessible(true);
+        } catch (NoSuchFieldException e) {
+            throw new UnsupportedOperationException(e);
+        }
+    }
+
+
+    /**
+     * Construct and initialize.
+     */
+    public AppletSecurity() {
+        reset();
+        mainAppContext = AppContext.getAppContext();
+    }
+
+    // Cache to store known restricted packages
+    private HashSet restrictedPackages = new HashSet();
+
+    /**
+     * Reset from Properties
+     */
+    public void reset()
+    {
+        // Clear cache
+        restrictedPackages.clear();
+
+        AccessController.doPrivileged(new PrivilegedAction() {
+            public Object run()
+            {
+                // Enumerate system properties
+                Enumeration e = System.getProperties().propertyNames();
+
+                while (e.hasMoreElements())
+                {
+                    String name = (String) e.nextElement();
+
+                    if (name != null && name.startsWith("package.restrict.access."))
+                    {
+                        String value = System.getProperty(name);
+
+                        if (value != null && value.equalsIgnoreCase("true"))
+                        {
+                            String pkg = name.substring(24);
+
+                            // Cache restricted packages
+                            restrictedPackages.add(pkg);
+                        }
+                    }
+                }
+                return null;
+            }
+        });
+    }
+
+    /**
+     * get the current (first) instance of an AppletClassLoader on the stack.
+     */
+    private AppletClassLoader currentAppletClassLoader()
+    {
+        // try currentClassLoader first
+        ClassLoader loader = currentClassLoader();
+
+        if ((loader == null) || (loader instanceof AppletClassLoader))
+            return (AppletClassLoader)loader;
+
+        // if that fails, get all the classes on the stack and check them.
+        Class[] context = getClassContext();
+        for (int i = 0; i < context.length; i++) {
+            loader = context[i].getClassLoader();
+            if (loader instanceof AppletClassLoader)
+                return (AppletClassLoader)loader;
+        }
+
+        /*
+         * fix bug # 6433620 the logic here is : try to find URLClassLoader from
+         * class context, check its AccessControlContext to see if
+         * AppletClassLoader is in stack when it's created. for this kind of
+         * URLClassLoader, return the AppContext assocated with the
+         * AppletClassLoader.
+         */
+        for (int i = 0; i < context.length; i++) {
+            final ClassLoader currentLoader = context[i].getClassLoader();
+
+            if (currentLoader instanceof URLClassLoader) {
+                loader = (ClassLoader) AccessController.doPrivileged(new PrivilegedAction() {
+                    public Object run() {
+
+                        AccessControlContext acc = null;
+                        ProtectionDomain[] pds = null;
+
+                        try {
+                            acc = (AccessControlContext) facc.get(currentLoader);
+                            if (acc == null) {
+                                return null;
+                            }
+
+                            pds = (ProtectionDomain[]) fcontext.get(acc);
+                            if (pds == null) {
+                                return null;
+                            }
+                        } catch (Exception e) {
+                            throw new UnsupportedOperationException(e);
+                        }
+
+                        for (int i=0; i<pds.length; i++) {
+                            ClassLoader cl = pds[i].getClassLoader();
+
+                            if (cl instanceof AppletClassLoader) {
+                                    return cl;
+                            }
+                        }
+
+                        return null;
+                    }
+                });
+
+                if (loader != null) {
+                    return (AppletClassLoader) loader;
+                }
+            }
+        }
+
+        // if that fails, try the context class loader
+        loader = Thread.currentThread().getContextClassLoader();
+        if (loader instanceof AppletClassLoader)
+            return (AppletClassLoader)loader;
+
+        // no AppletClassLoaders on the stack
+        return (AppletClassLoader)null;
+    }
+
+    /**
+     * Returns true if this threadgroup is in the applet's own thread
+     * group. This will return false if there is no current class
+     * loader.
+     */
+    protected boolean inThreadGroup(ThreadGroup g) {
+        if (currentAppletClassLoader() == null)
+            return false;
+        else
+            return getThreadGroup().parentOf(g);
+    }
+
+    /**
+     * Returns true of the threadgroup of thread is in the applet's
+     * own threadgroup.
+     */
+    protected boolean inThreadGroup(Thread thread) {
+        return inThreadGroup(thread.getThreadGroup());
+    }
+
+    /**
+     * Applets are not allowed to manipulate threads outside
+     * applet thread groups. However a terminated thread no longer belongs
+     * to any group.
+     */
+    public void checkAccess(Thread t) {
+        /* When multiple applets is reloaded simultaneously, there will be
+         * multiple invocations to this method from plugin's SecurityManager.
+         * This method should not be synchronized to avoid deadlock when
+         * a page with multiple applets is reloaded
+         */
+        if ((t.getState() != Thread.State.TERMINATED) && !inThreadGroup(t)) {
+            checkPermission(SecurityConstants.MODIFY_THREAD_PERMISSION);
+        }
+    }
+
+    private boolean inThreadGroupCheck = false;
+
+    /**
+     * Applets are not allowed to manipulate thread groups outside
+     * applet thread groups.
+     */
+    public synchronized void checkAccess(ThreadGroup g) {
+        if (inThreadGroupCheck) {
+            // if we are in a recursive check, it is because
+            // inThreadGroup is calling appletLoader.getThreadGroup
+            // in that case, only do the super check, as appletLoader
+            // has a begin/endPrivileged
+            checkPermission(SecurityConstants.MODIFY_THREADGROUP_PERMISSION);
+        } else {
+            try {
+                inThreadGroupCheck = true;
+                if (!inThreadGroup(g)) {
+                    checkPermission(SecurityConstants.MODIFY_THREADGROUP_PERMISSION);
+                }
+            } finally {
+                inThreadGroupCheck = false;
+            }
+        }
+    }
+
+
+    /**
+     * Throws a <code>SecurityException</code> if the
+     * calling thread is not allowed to access the package specified by
+     * the argument.
+     * <p>
+     * This method is used by the <code>loadClass</code> method of class
+     * loaders.
+     * <p>
+     * The <code>checkPackageAccess</code> method for class
+     * <code>SecurityManager</code>  calls
+     * <code>checkPermission</code> with the
+     * <code>RuntimePermission("accessClassInPackage."+pkg)</code>
+     * permission.
+     *
+     * @param      pkg   the package name.
+     * @exception  SecurityException  if the caller does not have
+     *             permission to access the specified package.
+     * @see        java.lang.ClassLoader#loadClass(java.lang.String, boolean)
+     */
+    public void checkPackageAccess(final String pkgname) {
+
+        // first see if the VM-wide policy allows access to this package
+        super.checkPackageAccess(pkgname);
+
+        // now check the list of restricted packages
+        for (Iterator iter = restrictedPackages.iterator(); iter.hasNext();)
+        {
+            String pkg = (String) iter.next();
+
+            // Prevent matching "sun" and "sunir" even if they
+            // starts with similar beginning characters
+            //
+            if (pkgname.equals(pkg) || pkgname.startsWith(pkg + "."))
+            {
+                checkPermission(new java.lang.RuntimePermission
+                            ("accessClassInPackage." + pkgname));
+            }
+        }
+    }
+
+    /**
+     * Tests if a client can get access to the AWT event queue.
+     * <p>
+     * This method calls <code>checkPermission</code> with the
+     * <code>AWTPermission("accessEventQueue")</code> permission.
+     *
+     * @since   JDK1.1
+     * @exception  SecurityException  if the caller does not have
+     *             permission to accesss the AWT event queue.
+     */
+    public void checkAwtEventQueueAccess() {
+        AppContext appContext = AppContext.getAppContext();
+        AppletClassLoader appletClassLoader = currentAppletClassLoader();
+
+        if ((appContext == mainAppContext) && (appletClassLoader != null)) {
+            // If we're about to allow access to the main EventQueue,
+            // and anything untrusted is on the class context stack,
+            // disallow access.
+            super.checkAwtEventQueueAccess();
+        }
+    } // checkAwtEventQueueAccess()
+
+    /**
+     * Returns the thread group of the applet. We consult the classloader
+     * if there is one.
+     */
+    public ThreadGroup getThreadGroup() {
+        /* If any applet code is on the execution stack, we return
+           that applet's ThreadGroup.  Otherwise, we use the default
+           behavior. */
+        AppletClassLoader appletLoader = currentAppletClassLoader();
+        ThreadGroup loaderGroup = (appletLoader == null) ? null
+                                          : appletLoader.getThreadGroup();
+        if (loaderGroup != null) {
+            return loaderGroup;
+        } else {
+            return super.getThreadGroup();
+        }
+    } // getThreadGroup()
+
+    /**
+      * Get the AppContext corresponding to the current context.
+      * The default implementation returns null, but this method
+      * may be overridden by various SecurityManagers
+      * (e.g. AppletSecurity) to index AppContext objects by the
+      * calling context.
+      *
+      * @return  the AppContext corresponding to the current context.
+      * @see     sun.awt.AppContext
+      * @see     java.lang.SecurityManager
+      * @since   JDK1.2.1
+      */
+    public AppContext getAppContext() {
+        AppletClassLoader appletLoader = currentAppletClassLoader();
+
+        if (appletLoader == null) {
+            return null;
+        } else {
+            AppContext context =  appletLoader.getAppContext();
+
+            // context == null when some thread in applet thread group
+            // has not been destroyed in AppContext.dispose()
+            if (context == null) {
+                throw new SecurityException("Applet classloader has invalid AppContext");
+            }
+
+            return context;
+        }
+    }
+
+} // class AppletSecurity
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugin/icedtea/java/src/main/sun/applet/AppletSecurityContext.java	Tue Sep 23 16:33:17 2008 -0400
@@ -0,0 +1,25 @@
+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);
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugin/icedtea/java/src/main/sun/applet/AppletSecurityContextManager.java	Tue Sep 23 16:33:17 2008 -0400
@@ -0,0 +1,27 @@
+package sun.applet;
+
+import java.util.HashMap;
+
+public class AppletSecurityContextManager {
+
+	// Context identifier -> PluginAppletSecurityContext object.
+	// FIXME: make private
+	private static HashMap<Integer, AppletSecurityContext> contexts = new HashMap();
+	
+	public static void addContext(int identifier, AppletSecurityContext context) {
+		contexts.put(identifier, context);
+	}
+	
+	public static AppletSecurityContext getSecurityContext(int identifier) {
+		return contexts.get(identifier);
+	}
+
+	public static void dumpStore(int identifier) {
+		contexts.get(identifier).dumpStore();
+	}
+	
+	public static void handleMessage(int identifier, String src, int reference,	String message) {
+		System.err.println(identifier + " -- " + src + " -- " + reference + " -- " + message + " CONTEXT= " + contexts.get(identifier));
+		contexts.get(identifier).handleMessage(src, reference, message);
+	}
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugin/icedtea/java/src/main/sun/applet/AppletSecurityException.java	Tue Sep 23 16:33:17 2008 -0400
@@ -0,0 +1,65 @@
+/*
+ * Copyright 1995-1998 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;
+
+/**
+ * An applet security exception.
+ *
+ * @author      Arthur van Hoff
+ */
+public
+class AppletSecurityException extends SecurityException {
+    private String key = null;
+    private Object msgobj[] = null;
+
+    public AppletSecurityException(String name) {
+        super(name);
+        this.key = name;
+    }
+
+    public AppletSecurityException(String name, String arg) {
+        this(name);
+        msgobj = new Object[1];
+        msgobj[0] = (Object)arg;
+    }
+
+    public AppletSecurityException(String name, String arg1, String arg2) {
+        this(name);
+        msgobj = new Object[2];
+        msgobj[0] = (Object)arg1;
+        msgobj[1] = (Object)arg2;
+    }
+
+    public String getLocalizedMessage() {
+        if( msgobj != null)
+            return amh.getMessage(key, msgobj);
+        else
+            return amh.getMessage(key);
+    }
+
+    private static AppletMessageHandler amh = new AppletMessageHandler("appletsecurityexception");
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugin/icedtea/java/src/main/sun/applet/AppletThreadGroup.java	Tue Sep 23 16:33:17 2008 -0400
@@ -0,0 +1,64 @@
+/*
+ * Copyright 1995-1997 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;
+
+/**
+ * This class defines an applet thread group.
+ *
+ * @author      Arthur van Hoff
+ */
+public class AppletThreadGroup extends ThreadGroup {
+
+    /**
+     * Constructs a new thread group for an applet.
+     * The parent of this new group is the thread
+     * group of the currently running thread.
+     *
+     * @param   name   the name of the new thread group.
+     */
+    public AppletThreadGroup(String name) {
+        this(Thread.currentThread().getThreadGroup(), name);
+    }
+
+    /**
+     * Creates a new thread group for an applet.
+     * The parent of this new group is the specified
+     * thread group.
+     *
+     * @param     parent   the parent thread group.
+     * @param     name     the name of the new thread group.
+     * @exception  NullPointerException  if the thread group argument is
+     *               <code>null</code>.
+     * @exception  SecurityException  if the current thread cannot create a
+     *               thread in the specified thread group.
+     * @see     java.lang.SecurityException
+     * @since   JDK1.1.1
+     */
+    public AppletThreadGroup(ThreadGroup parent, String name) {
+        super(parent, name);
+        setMaxPriority(Thread.NORM_PRIORITY - 1);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugin/icedtea/java/src/main/sun/applet/AppletViewerFactory.java	Tue Sep 23 16:33:17 2008 -0400
@@ -0,0 +1,41 @@
+/*
+ * Copyright 1996 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.
+ */
+
+/*
+ * AppletViewerFactory.java
+ */
+
+package sun.applet;
+
+import java.util.Hashtable;
+import java.net.URL;
+import java.awt.MenuBar;
+
+public
+interface AppletViewerFactory {
+        public AppletViewer createAppletViewer(int x, int y, URL doc, Hashtable atts);
+        public MenuBar getBaseMenuBar();
+        public boolean isStandalone();
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugin/icedtea/java/src/main/sun/applet/AppletViewerPanel.java	Tue Sep 23 16:33:17 2008 -0400
@@ -0,0 +1,254 @@
+/*
+ * Copyright 1995-2005 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.applet.AppletContext;
+import java.awt.Dimension;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.Hashtable;
+
+
+/**
+ * Sample applet panel class. The panel manages and manipulates the
+ * applet as it is being loaded. It forks a seperate thread in a new
+ * thread group to call the applet's init(), start(), stop(), and
+ * destroy() methods.
+ *
+ * @author      Arthur van Hoff
+ */
+public class AppletViewerPanel extends AppletPanel {
+
+    /* Are we debugging? */
+    protected static boolean debug = true;
+
+    /**
+     * The document url.
+     */
+    protected URL documentURL;
+
+    /**
+     * The base url.
+     */
+    protected URL baseURL;
+
+    /**
+     * The attributes of the applet.
+     */
+    protected Hashtable atts;
+
+    /*
+     * JDK 1.1 serialVersionUID
+     */
+    private static final long serialVersionUID = 8890989370785545619L;
+
+    private Dimension windowSizeFactor = new Dimension(750, 350);
+    
+    /**
+     * Construct an applet viewer and start the applet.
+     */
+    protected AppletViewerPanel(URL documentURL, Hashtable atts) {
+        this.documentURL = documentURL;
+        this.atts = atts;
+
+        String att = getParameter("codebase");
+        if (att != null) {
+            if (!att.endsWith("/")) {
+                att += "/";
+            }
+            try {
+                baseURL = new URL(documentURL, att);
+            } catch (MalformedURLException e) {
+            }
+        }
+        if (baseURL == null) {
+            String file = documentURL.getFile();
+            int i = file.lastIndexOf('/');
+            if (i >= 0 && i < file.length() - 1) {
+                try {
+                    baseURL = new URL(documentURL, file.substring(0, i + 1));
+                } catch (MalformedURLException e) {
+                }
+            }
+        }
+
+        // when all is said & done, baseURL shouldn't be null
+        if (baseURL == null)
+                baseURL = documentURL;
+
+
+    }
+
+
+    /**
+     * Get an applet parameter.
+     */
+    public String getParameter(String name) {
+        return (String)atts.get(name.toLowerCase());
+    }
+
+    /**
+     * Get the document url.
+     */
+    public URL getDocumentBase() {
+        return documentURL;
+
+    }
+
+    /**
+     * Get the base url.
+     */
+    public URL getCodeBase() {
+        return baseURL;
+    }
+
+    /**
+     * Set applet size (as proportion of window size) if needed
+     */
+    public synchronized void setAppletSizeIfNeeded(int width, int height) {
+
+    	Dimension newD = new Dimension(getWidth(), getHeight());
+
+    	String h = getParameter("height");
+    	String w = getParameter("width");
+
+    	if (width != -1 && w != null && w.endsWith("%")) {
+    		newD.width = (Integer.valueOf(w.substring(0, w.length() - 1)).intValue()/100)*width;
+    	}
+
+    	if (height != -1 && h != null && h.endsWith("%")) {
+    		newD.height = (Integer.valueOf(h.substring(0, h.length() - 1)).intValue()/100)*height;
+    	}
+    	
+    	synchronized(windowSizeFactor) {
+    		windowSizeFactor = newD;
+    	}
+    }
+
+    /**
+     * Get the width.
+     */
+    public int getWidth() {
+        String w = getParameter("width");
+        if (w != null) {
+        	try {
+        		return Integer.valueOf(w).intValue();
+        	} catch (NumberFormatException nfe) {
+        		synchronized(windowSizeFactor) {
+        			System.err.println("getWidth() returning " + windowSizeFactor.width);
+        			return windowSizeFactor.width;
+        		}
+        	}
+        }
+        return 0;
+    }
+
+
+    /**
+     * Get the height.
+     */
+    public int getHeight() {
+        String h = getParameter("height");
+        if (h != null) {
+        	try {
+        		return Integer.valueOf(h).intValue();
+        	} catch (NumberFormatException nfe) {
+        		synchronized(windowSizeFactor) {
+        			System.err.println("getHeight() returning " + windowSizeFactor.height);
+        			return windowSizeFactor.height;
+        		}
+        	}
+        }
+        return 0;
+    }
+
+    /**
+     * Get initial_focus
+     */
+    public boolean hasInitialFocus()
+    {
+
+        // 6234219: Do not set initial focus on an applet
+        // during startup if applet is targeted for
+        // JDK 1.1/1.2. [stanley.ho]
+        if (isJDK11Applet() || isJDK12Applet())
+            return false;
+
+        String initialFocus = getParameter("initial_focus");
+
+        if (initialFocus != null)
+        {
+            if (initialFocus.toLowerCase().equals("false"))
+                return false;
+        }
+
+        return true;
+    }
+
+    /**
+     * Get the code parameter
+     */
+    public String getCode() {
+        return getParameter("code");
+    }
+
+
+    /**
+     * Return the list of jar files if specified.
+     * Otherwise return null.
+     */
+    public String getJarFiles() {
+        return getParameter("archive");
+    }
+
+    /**
+     * Return the value of the object param
+     */
+    public String getSerializedObject() {
+        return getParameter("object");// another name?
+    }
+
+
+    /**
+     * Get the applet context. For now this is
+     * also implemented by the AppletPanel class.
+     */
+    public AppletContext getAppletContext() {
+        return (AppletContext)getParent();
+    }
+
+    protected static void debug(String s) {
+        if(debug)
+            System.err.println("AppletViewerPanel:::" + s);
+    }
+
+    protected static void debug(String s, Throwable t) {
+        if(debug) {
+            t.printStackTrace();
+            debug(s);
+        }
+    }
+}
--- a/plugin/icedtea/java/src/main/sun/applet/GetMemberPluginCallRequest.java	Sun Sep 21 15:58:46 2008 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +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 sun.applet;
-
-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 = PluginAppletSecurityContext.contexts.get(
-            0).store.getObject(Integer.parseInt(args[1]));
-        done = 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");
-    }
-}
-
--- a/plugin/icedtea/java/src/main/sun/applet/GetWindowPluginCallRequest.java	Sun Sep 21 15:58:46 2008 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,66 +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 sun.applet;
-
-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]);
-        done = 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");
-    }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugin/icedtea/java/src/main/sun/applet/Main.java	Tue Sep 23 16:33:17 2008 -0400
@@ -0,0 +1,533 @@
+/*
+ * 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.BufferedInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
+import java.net.URL;
+import java.net.MalformedURLException;
+import java.util.Enumeration;
+import java.util.Properties;
+import java.util.Vector;
+import sun.net.www.ParseUtil;
+
+/**
+ * The main entry point into AppletViewer.
+ */
+public class Main {
+    /**
+     * The file which contains all of the AppletViewer specific properties.
+     */
+    static File theUserPropertiesFile;
+
+    /**
+     * The default key/value pairs for the required user-specific properties.
+     */
+    static final String [][] avDefaultUserProps = {
+        // There's a bootstrapping problem here.  If we don't have a proxyHost,
+        // then we will not be able to connect to a URL outside the firewall;
+        // however, there's no way for us to set the proxyHost without starting
+        // AppletViewer.  This problem existed before the re-write.
+        {"http.proxyHost", ""},
+        {"http.proxyPort", "80"},
+        {"package.restrict.access.sun", "true"}
+    };
+
+    static {
+        File userHome = new File(System.getProperty("user.home"));
+        // make sure we can write to this location
+        userHome.canWrite();
+
+        theUserPropertiesFile = new File(userHome, ".appletviewer");
+    }
+
+    // i18n
+    private static AppletMessageHandler amh = new AppletMessageHandler("appletviewer");
+
+    /**
+     * Member variables set according to options passed in to AppletViewer.
+     */
+    private boolean debugFlag = false;
+    private boolean helpFlag  = false;
+    private String  encoding  = null;
+    private boolean noSecurityFlag  = false;
+    private static boolean cmdLineTestFlag = false;
+
+    /**
+     * The list of valid URLs passed in to AppletViewer.
+     */
+    private static Vector urlList = new Vector(1);
+
+    // 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");
+
+    /**
+     * The main entry point into AppletViewer.
+     */
+    public static void main(String [] args) {
+        Main m = new Main();
+        int ret = m.run(args);
+
+        // Exit immediately if we got some sort of error along the way.
+        // For debugging purposes, if we have passed in "-XcmdLineTest" we
+        // force a premature exit.
+        if ((ret != 0) || (cmdLineTestFlag))
+            System.exit(ret);
+    }
+
+    private int run(String [] args) {
+        // DECODE ARGS
+        try {
+            if (args.length == 0) {
+                usage();
+                return 0;
+            }
+            for (int i = 0; i < args.length; ) {
+                int j = decodeArg(args, i);
+                if (j == 0) {
+                    throw new ParseException(lookup("main.err.unrecognizedarg",
+                                                    args[i]));
+                }
+                i += j;
+            }
+        } catch (ParseException e) {
+            System.err.println(e.getMessage());
+            return 1;
+        }
+
+        // CHECK ARGUMENTS
+        if (helpFlag) {
+            usage();
+            return 0;
+        }
+
+        if (urlList.size() == 0) {
+            System.err.println(lookup("main.err.inputfile"));
+            return 1;
+        }
+
+        if (debugFlag) {
+            // START A DEBUG SESSION
+            // Given the current architecture, we will end up decoding the
+            // arguments again, but at least we are guaranteed to have
+            // arguments which are valid.
+            return invokeDebugger(args);
+        }
+
+        // INSTALL THE SECURITY MANAGER (if necessary)
+        if (!noSecurityFlag && (System.getSecurityManager() == null))
+            init();
+
+        // LAUNCH APPLETVIEWER FOR EACH URL
+        for (int i = 0; i < urlList.size(); i++) {
+            try {
+                // XXX 5/17 this parsing method should be changed/fixed so that
+                // it doesn't do both parsing of the html file and launching of
+                // the AppletPanel
+                AppletViewer.parse((URL) urlList.elementAt(i), encoding);
+            } catch (IOException e) {
+                System.err.println(lookup("main.err.io", e.getMessage()));
+                return 1;
+            }
+        }
+        return 0;
+    }
+
+    private static void usage() {
+        System.out.println(lookup("usage"));
+    }
+
+    /**
+     * Decode a single argument in an array and return the number of elements
+     * used.
+     *
+     * @param args The array of arguments.
+     * @param i    The argument to decode.
+     * @return     The number of array elements used when the argument was
+     *             decoded.
+     * @exception ParseException
+     *             Thrown when there is a problem with something in the
+     *             argument array.
+     */
+    private int decodeArg(String [] args, int i) throws ParseException {
+        String arg = args[i];
+        int argc = args.length;
+
+        if ("-help".equalsIgnoreCase(arg) || "-?".equals(arg)) {
+            helpFlag = true;
+            return 1;
+        } else if ("-encoding".equals(arg) && (i < argc - 1)) {
+            if (encoding != null)
+                throw new ParseException(lookup("main.err.dupoption", arg));
+            encoding = args[++i];
+            return 2;
+        } else if ("-debug".equals(arg)) {
+            debugFlag = true;
+            return 1;
+        } else if ("-Xnosecurity".equals(arg)) {
+            // This is an undocumented (and, in the future, unsupported)
+            // flag which prevents AppletViewer from installing its own
+            // SecurityManager.
+
+            System.err.println();
+            System.err.println(lookup("main.warn.nosecmgr"));
+            System.err.println();
+
+            noSecurityFlag = true;
+            return 1;
+        } else if ("-XcmdLineTest".equals(arg)) {
+            // This is an internal flag which should be used for command-line
+            // testing.  It instructs AppletViewer to force a premature exit
+            // immediately after the applet has been launched.
+            cmdLineTestFlag = true;
+            return 1;
+        } else if (arg.startsWith("-")) {
+            throw new ParseException(lookup("main.err.unsupportedopt", arg));
+        } else {
+            // we found what we hope is a url
+            URL url = parseURL(arg);
+            if (url != null) {
+                urlList.addElement(url);
+                return 1;
+            }
+        }
+        return 0;
+    }
+
+    /**
+     * Following the relevant RFC, construct a valid URL based on the passed in
+     * string.
+     *
+     * @param url  a string which represents either a relative or absolute URL.
+     * @return     a URL when the passed in string can be interpreted according
+     *             to the RFC, <code>null</code> otherwise.
+     * @exception  ParseException
+     *             Thrown when we are unable to construct a proper URL from the
+     *             passed in string.
+     */
+    private URL parseURL(String url) throws ParseException {
+        URL u = null;
+        // prefix of the urls with 'file' scheme
+        String prefix = "file:";
+
+        try {
+            if (url.indexOf(':') <= 1)
+            {
+                // appletviewer accepts only unencoded filesystem paths
+                u = ParseUtil.fileToEncodedURL(new File(url));
+            } else if (url.startsWith(prefix) &&
+                       url.length() != prefix.length() &&
+                       !(new File(url.substring(prefix.length())).isAbsolute()))
+            {
+                // relative file URL, like this "file:index.html"
+                // ensure that this file URL is absolute
+                // ParseUtil.fileToEncodedURL should be done last (see 6329251)
+                String path = ParseUtil.fileToEncodedURL(new File(System.getProperty("user.dir"))).getPath() +
+                    url.substring(prefix.length());
+                u = new URL("file", "", path);
+            } else {
+                // appletviewer accepts only encoded urls
+                u = new URL(url);
+            }
+        } catch (MalformedURLException e) {
+            throw new ParseException(lookup("main.err.badurl",
+                                            url, e.getMessage()));
+        }
+
+        return u;
+    }
+
+    /**
+     * Invoke the debugger with the arguments passed in to appletviewer.
+     *
+     * @param args The arguments passed into the debugger.
+     * @return     <code>0</code> if the debugger is invoked successfully,
+     *             <code>1</code> otherwise.
+     */
+    private int invokeDebugger(String [] args) {
+        // CONSTRUCT THE COMMAND LINE
+        String [] newArgs = new String[args.length + 1];
+        int current = 0;
+
+        // Add a -classpath argument that prevents
+        // the debugger from launching appletviewer with the default of
+        // ".". appletviewer's classpath should never contain valid
+        // classes since they will result in security exceptions.
+        // Ideally, the classpath should be set to "", but the VM won't
+        // allow an empty classpath, so a phony directory name is used.
+        String phonyDir = System.getProperty("java.home") +
+                          File.separator + "phony";
+        newArgs[current++] = "-Djava.class.path=" + phonyDir;
+
+        // Appletviewer's main class is the debuggee
+        newArgs[current++] = "sun.applet.Main";
+
+        // Append all the of the original appletviewer arguments,
+        // leaving out the "-debug" option.
+        for (int i = 0; i < args.length; i++) {
+            if (!("-debug".equals(args[i]))) {
+                newArgs[current++] = args[i];
+            }
+        }
+
+        // LAUNCH THE DEBUGGER
+        // Reflection is used for two reasons:
+        // 1) The debugger classes are on classpath and thus must be loaded
+        // by the application class loader. (Currently, appletviewer are
+        // loaded through the boot class path out of rt.jar.)
+        // 2) Reflection removes any build dependency between appletviewer
+        // and jdb.
+        try {
+            Class c = Class.forName("com.sun.tools.example.debug.tty.TTY", true,
+                                    ClassLoader.getSystemClassLoader());
+            Method m = c.getDeclaredMethod("main",
+                                           new Class[] { String[].class });
+            m.invoke(null, new Object[] { newArgs });
+        } catch (ClassNotFoundException cnfe) {
+            System.err.println(lookup("main.debug.cantfinddebug"));
+            return 1;
+        } catch (NoSuchMethodException nsme) {
+            System.err.println(lookup("main.debug.cantfindmain"));
+            return 1;
+        } catch (InvocationTargetException ite) {
+            System.err.println(lookup("main.debug.exceptionindebug"));
+            return 1;
+        } catch (IllegalAccessException iae) {
+            System.err.println(lookup("main.debug.cantaccess"));
+            return 1;
+        }
+        return 0;
+    }
+
+    private void init() {
+        // GET APPLETVIEWER USER-SPECIFIC PROPERTIES
+        Properties avProps = getAVProps();
+
+        // 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);
+            String oldVal;
+            if ((oldVal = (String) avProps.setProperty(key, val)) != null)
+                System.err.println(lookup("main.warn.prop.overwrite", key,
+                                          oldVal, val));
+        }
+
+        // INSTALL THE PROPERTY LIST
+        System.setProperties(avProps);
+
+        // Create and install the security manager
+        if (!noSecurityFlag) {
+            System.setSecurityManager(new AppletSecurity());
+        } else {
+            System.err.println(lookup("main.nosecmgr"));
+        }
+
+        // REMIND: Create and install a socket factory!
+    }
+
+    /**
+     * Read the AppletViewer user-specific properties.  Typically, these
+     * properties should reside in the file $USER/.appletviewer.  If this file
+     * does not exist, one will be created.  Information for this file will
+     * be gleaned from $USER/.hotjava/properties.  If that file does not exist,
+     * then default values will be used.
+     *
+     * @return     A Properties object containing all of the AppletViewer
+     *             user-specific properties.
+     */
+    private Properties getAVProps() {
+        Properties avProps = new Properties();
+
+        File dotAV = theUserPropertiesFile;
+        if (dotAV.exists()) {
+            // we must have already done the conversion
+            if (dotAV.canRead()) {
+                // just read the file
+                avProps = getAVProps(dotAV);
+            } else {
+                // send out warning and use defaults
+                System.err.println(lookup("main.warn.cantreadprops",
+                                          dotAV.toString()));
+                avProps = setDefaultAVProps();
+            }
+        } else {
+            // create the $USER/.appletviewer file
+
+            // see if $USER/.hotjava/properties exists
+            File userHome = new File(System.getProperty("user.home"));
+            File dotHJ = new File(userHome, ".hotjava");
+            dotHJ = new File(dotHJ, "properties");
+            if (dotHJ.exists()) {
+                // just read the file
+                avProps = getAVProps(dotHJ);
+            } else {
+                // send out warning and use defaults
+                System.err.println(lookup("main.warn.cantreadprops",
+                                          dotHJ.toString()));
+                avProps = setDefaultAVProps();
+            }
+
+            // SAVE THE FILE
+            try {
+                FileOutputStream out = new FileOutputStream(dotAV);
+                avProps.store(out, lookup("main.prop.store"));
+                out.close();
+            } catch (IOException e) {
+                System.err.println(lookup("main.err.prop.cantsave",
+                                          dotAV.toString()));
+            }
+        }
+        return avProps;
+    }
+
+    /**
+     * Set the AppletViewer user-specific properties to be the default values.
+     *
+     * @return     A Properties object containing all of the AppletViewer
+     *             user-specific properties, set to the default values.
+     */
+    private Properties setDefaultAVProps() {
+        Properties avProps = new Properties();
+        for (int i = 0; i < avDefaultUserProps.length; i++) {
+            avProps.setProperty(avDefaultUserProps[i][0],
+                                avDefaultUserProps[i][1]);
+        }
+        return avProps;
+    }
+
+    /**
+     * Given a file, find only the properties that are setable by AppletViewer.
+     *
+     * @param inFile A Properties file from which we select the properties of
+     *             interest.
+     * @return     A Properties object containing all of the AppletViewer
+     *             user-specific properties.
+     */
+    private Properties getAVProps(File inFile) {
+        Properties avProps  = new Properties();
+
+        // read the file
+        Properties tmpProps = new Properties();
+        try {
+            FileInputStream in = new FileInputStream(inFile);
+            tmpProps.load(new BufferedInputStream(in));
+            in.close();
+        } catch (IOException e) {
+            System.err.println(lookup("main.err.prop.cantread",
+                                      inFile.toString()));
+        }
+
+        // pick off the properties we care about
+        for (int i = 0; i < avDefaultUserProps.length; i++) {
+            String value = tmpProps.getProperty(avDefaultUserProps[i][0]);
+            if (value != null) {
+                // the property exists in the file, so replace the default
+                avProps.setProperty(avDefaultUserProps[i][0], value);
+            } else {
+                // just use the default
+                avProps.setProperty(avDefaultUserProps[i][0],
+                                    avDefaultUserProps[i][1]);
+            }
+        }
+        return avProps;
+    }
+
+    /**
+     * Methods for easier i18n handling.
+     */
+
+    private static String lookup(String key) {
+        return amh.getMessage(key);
+    }
+
+    private static String lookup(String key, String arg0) {
+        return amh.getMessage(key, arg0);
+    }
+
+    private static String lookup(String key, String arg0, String arg1) {
+        return amh.getMessage(key, arg0, arg1);
+    }
+
+    private static String lookup(String key, String arg0, String arg1,
+                                 String arg2) {
+        return amh.getMessage(key, arg0, arg1, arg2);
+    }
+
+    class ParseException extends RuntimeException
+    {
+        public ParseException(String msg) {
+            super(msg);
+        }
+
+        public ParseException(Throwable t) {
+            super(t.getMessage());
+            this.t = t;
+        }
+
+        Throwable t = null;
+    }
+}
--- a/plugin/icedtea/java/src/main/sun/applet/PluginAppletSecurityContext.java	Sun Sep 21 15:58:46 2008 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,847 +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 sun.applet;
-
-import java.lang.reflect.Array;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Field;
-import java.lang.reflect.Method;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.StringTokenizer;
-
-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 {
-	// Context identifier -> PluginAppletSecurityContext object.
-	// FIXME: make private
-	public static HashMap<Integer, PluginAppletSecurityContext> contexts = new HashMap();
-	
-	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;
-
-	static {
-		// FIXME: when should we add each new security context? but how would 
-		// we be able to know which context applies to which request from nspr? 
-		// the nspr jni functions do not know what applet they are being called
-		// in reference to
-		contexts.put(0, new PluginAppletSecurityContext(0));
-	}
-
-	public PluginAppletSecurityContext(int identifier) {
-		this.identifier = identifier;
-	}
-
-	public 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.");
-	}
-
-	public 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 static void handleMessage(int identifier, String src, int reference,
-			String message) {
-		contexts.get(identifier).handleMessage(reference, src, message);
-	}
-
-	public void handleMessage(int reference, String src, 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);
-
-				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]);
-				}
-
-				// System.out.println ("NEWOBJ: Calling " + m);
-				Object ret = null;
-				ret = m.newInstance(arguments);
-
-				// System.out.println ("NEWOBJ: CALLED: " + ret);
-				// System.out.println ("NEWOBJ: CALLED: " +
-				// store.getObject(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();
-			throwable = t;
-			PluginException p = new PluginException(identifier, reference, t);
-		}
-	}
-
-	public void write(int reference, String message) {
-		PluginDebug.debug("appletviewer writing " + message);
-		PluginMain.write("context " + identifier + " reference " + reference
-				+ " " + message);
-	}
-}
--- a/plugin/icedtea/java/src/main/sun/applet/PluginAppletViewer.java	Sun Sep 21 15:58:46 2008 -0400
+++ b/plugin/icedtea/java/src/main/sun/applet/PluginAppletViewer.java	Tue Sep 23 16:33:17 2008 -0400
@@ -25,26 +25,45 @@
  
  package sun.applet;
  
- import java.util.*;
- import java.io.*;
- import java.awt.*;
- import java.awt.event.*;
- import java.awt.print.*;
- import javax.print.attribute.*;
- import java.applet.*;
- import java.net.URL;
- import java.net.MalformedURLException;
- import java.net.SocketPermission;
- import sun.misc.Ref;
- import java.security.AccessController;
- import java.security.PrivilegedAction;
- import java.lang.reflect.InvocationTargetException;
- import java.lang.reflect.Method;
- import sun.awt.SunToolkit;
- import sun.awt.AppContext;
- import sun.awt.X11.*;
- import java.lang.ref.WeakReference;
- import net.sourceforge.jnlp.NetxPanel;
+ import java.applet.Applet;
+import java.applet.AppletContext;
+import java.applet.AudioClip;
+import java.awt.Dimension;
+import java.awt.Frame;
+import java.awt.Graphics;
+import java.awt.Image;
+import java.awt.Insets;
+import java.awt.Label;
+import java.awt.Toolkit;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.awt.event.WindowListener;
+import java.awt.print.PageFormat;
+import java.awt.print.Printable;
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.PrintStream;
+import java.io.Reader;
+import java.io.StringReader;
+import java.net.SocketPermission;
+import java.net.URL;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Vector;
+
+import net.sourceforge.jnlp.NetxPanel;
+
+import sun.awt.AppContext;
+import sun.awt.SunToolkit;
+import sun.awt.X11.XEmbeddedFrame;
+import sun.misc.Ref;
  
  /**
   * Lets us construct one using unix-style one shot behaviors
@@ -109,7 +128,17 @@
  
      // Instance identifier -> PluginAppletViewer object.
      private static HashMap<Integer, PluginAppletViewer> applets = new HashMap();
- 
+     
+     private static PluginStreamHandler streamhandler;
+     
+     private static PluginCallRequestFactory requestFactory;
+
+     /**
+      * Null constructor to allow instantiation via newInstance()
+      */
+     public PluginAppletViewer() {
+     }
+     
      /**
       * Create the applet viewer
       */
@@ -117,20 +146,25 @@
                                final Hashtable atts, PrintStream statusMsgStream,
                                PluginAppletViewerFactory factory) {
          super(handle, true);
-     	this.factory = factory;
+    	this.factory = factory;
  	this.statusMsgStream = statusMsgStream;
          this.identifier = identifier;
          // FIXME: when/where do we remove this?
          PluginDebug.debug ("PARSING: PUTTING " + identifier + " " + this);
          applets.put(identifier, this);
  
- 	try {
- 		panel = new NetxPanel(doc, atts);
- 		AppletViewerPanel.debug("Using NetX panel");
- 	} catch (Exception ex) {
- 		AppletViewerPanel.debug("Unable to start NetX applet - defaulting to Sun applet", ex);
- 		panel = new AppletViewerPanel(doc, atts);
- 	}
+         AccessController.doPrivileged(new PrivilegedAction() {
+             public Object run() {
+            	 	try {
+            	 		panel = new NetxPanel(doc, atts);
+            	 		AppletViewerPanel.debug("Using NetX panel");
+            	 	} catch (Exception ex) {
+            	 		AppletViewerPanel.debug("Unable to start NetX applet - defaulting to Sun applet", ex);
+            	 		panel = new AppletViewerPanel(doc, atts);
+            	 	}
+                 return null;
+             }
+         });  
 
  	add("Center", panel);
  	panel.init();
@@ -227,21 +261,32 @@
    		 sleepTime += 100;
    		 PluginDebug.debug("Waiting for applet to initialize... ");
    	 } catch (InterruptedException ie) {
-   		 // ignore
+   		 ie.printStackTrace();
    	 }
     }
 
+    PluginDebug.debug("Applet initialized");
+    
     // Applet initialized. Find out it's classloader and add it to the list
-    PluginAppletSecurityContext.classLoaders.put(Integer.toString(identifier), a.getClass().getClassLoader());
-    
+    AppletSecurityContextManager.getSecurityContext(0).addClassLoader(Integer.toString(identifier), a.getClass().getClassLoader());
+
      }
  
+ 	public static void setStreamhandler(PluginStreamHandler sh) {
+		streamhandler = sh;
+	}
+     
+ 	public static void setPluginCallRequestFactory(PluginCallRequestFactory rf) {
+		requestFactory = rf;
+	}
+ 	
      /**
       * Handle an incoming message from the plugin.
       */
      public static void handleMessage(int identifier, int reference, String message)
      {
-         PluginDebug.debug("PAV handling: " + message);
+
+		 PluginDebug.debug("PAV handling: " + message);
 
          try {
         	 if (message.startsWith("tag")) {
@@ -296,7 +341,7 @@
             			 PluginDebug.debug ("REQUEST HANDLE, DONE PARSING " +
             					 Thread.currentThread());
             		 } else {
-            			 PluginDebug.debug ("REQUEST HANDLE NOT SET: " + request.tag + ". BYPASSING");
+            			 PluginDebug.debug ("REQUEST TAG NOT SET: " + request.tag + ". BYPASSING");
             		 }
             	 }
              } else {
@@ -314,12 +359,12 @@
          if (message.startsWith("width")) {
         	 int width =
         		 Integer.parseInt(message.substring("width".length() + 1));
-             panel.setAppletSizeIfNeeded(width, -1);
+             //panel.setAppletSizeIfNeeded(width, -1);
              setSize(width, getHeight());
          } else if (message.startsWith("height")) {
              int height = 
             	 Integer.parseInt(message.substring("height".length() + 1));
-             panel.setAppletSizeIfNeeded(-1, height);
+             //panel.setAppletSizeIfNeeded(-1, height);
              setSize(getWidth(), height);
          } else if (message.startsWith("destroy")) {
              dispose();
@@ -338,16 +383,16 @@
             		 sleepTime += 100;
             		 PluginDebug.debug("Waiting for applet to initialize...");
             	 } catch (InterruptedException ie) {
-            		 // ignore
+            		 ie.printStackTrace();
             	 }
              }
 
              System.err.println ("Looking for object " + o + " panel is " + panel.getClass());
-             PluginAppletSecurityContext.contexts.get(0).store.reference(o);
+             AppletSecurityContextManager.getSecurityContext(0).store(o);
              System.err.println ("WRITING 1: " + "context 0 reference " + reference + " GetJavaObject "
-                                 + PluginAppletSecurityContext.contexts.get(0).store.getIdentifier(o));
-             PluginMain.write("context 0 reference " + reference + " GetJavaObject "
-                              + PluginAppletSecurityContext.contexts.get(0).store.getIdentifier(o));
+                                 + AppletSecurityContextManager.getSecurityContext(0).getIdentifier(o));
+             streamhandler.write("context 0 reference " + reference + " GetJavaObject "
+                              + AppletSecurityContextManager.getSecurityContext(0).getIdentifier(o));
              System.err.println ("WRITING 1 DONE");
          }
      }
@@ -360,7 +405,12 @@
      private void initEventQueue() {
  	// appletviewer.send.event is an undocumented and unsupported system
  	// property which is used exclusively for testing purposes.
- 	String eventList = System.getProperty("appletviewer.send.event");
+    	 PrivilegedAction pa = new PrivilegedAction() {
+    		 public Object run() {
+    			 return System.getProperty("appletviewer.send.event");
+    		 }
+    	 };
+ 	String eventList = (String) AccessController.doPrivileged(pa); 
  
  	if (eventList == null) {
  	    // Add the standard events onto the event queue.
@@ -562,7 +612,7 @@
  	} catch (IOException exception) {
  	    // Deliberately ignore IOException.  showDocument may be
  	    // called from threads other than the main thread after
- 	    // PluginMain.pluginOutputStream has been closed.
+ 	    // streamhandler.pluginOutputStream has been closed.
  	}
      }
  
@@ -576,24 +626,24 @@
  	} catch (IOException exception) {
  	    // Deliberately ignore IOException.  showStatus may be
  	    // called from threads other than the main thread after
- 	    // PluginMain.pluginOutputStream has been closed.
+ 	    // streamhandler.pluginOutputStream has been closed.
  	}
      }
  
      public int getWindow() {
     	 System.out.println ("STARTING getWindow");
-    	 GetWindowPluginCallRequest request =
-    		 new GetWindowPluginCallRequest("instance " + identifier + " " +
-    				 "GetWindow", "JavaScriptGetWindow");
+    	 PluginCallRequest request = requestFactory.getPluginCallRequest("window",
+    			 							"instance " + identifier + " " + "GetWindow", 
+    			 							"JavaScriptGetWindow");
     	 System.out.println ("STARTING postCallRequest");
-    	 PluginMain.postCallRequest(request);
+		 streamhandler.postCallRequest(request);
     	 System.out.println ("STARTING postCallRequest done");
-    	 PluginMain.write(request.message);
+    	 streamhandler.write(request.getMessage());
     	 try {
     		 System.out.println ("wait request 1");
     		 synchronized(request) {
     			 System.out.println ("wait request 2");
-    			 while (request.internal == 0)
+    			 while ((Integer) request.getObject() == 0)
     				 request.wait();
     			 System.out.println ("wait request 3");
     		 }
@@ -603,60 +653,55 @@
     	 }
 
     	 System.out.println ("STARTING getWindow DONE");
-    	 return request.internal;
+    	 return (Integer) request.getObject();
      }
  
      // FIXME: make private, access via reflection.
      public static Object getMember(int internal, String name)
      {
-         PluginAppletSecurityContext.contexts.get(0).store.reference(name);
-         int nameID = PluginAppletSecurityContext.contexts.get(
-             0).store.getIdentifier(name);
+    	 AppletSecurityContextManager.getSecurityContext(0).store(name);
+         int nameID = AppletSecurityContextManager.getSecurityContext(0).getIdentifier(name);
  
          // Prefix with dummy instance for convenience.
-         GetMemberPluginCallRequest request =
-             new GetMemberPluginCallRequest("instance " + 0 +
-                                            " GetMember " + internal +
-                                            " " + nameID, "JavaScriptGetMember");
-         PluginMain.postCallRequest(request);
-         PluginMain.write(request.message);
+         PluginCallRequest request = requestFactory.getPluginCallRequest("member", 
+        		 							"instance " + 0 + " GetMember " + internal + " " + nameID, 
+        		 							"JavaScriptGetMember");
+         streamhandler.postCallRequest(request);
+         streamhandler.write(request.getMessage());
          try {
-             System.out.println ("wait getMEM request 1");
+             System.err.println ("wait getMEM request 1");
              synchronized(request) {
-                 System.out.println ("wait getMEM request 2");
-                 while (request.done == false)
+                 System.err.println ("wait getMEM request 2");
+                 while (request.isDone() == false)
                      request.wait();
-                 System.out.println ("wait getMEM request 3");
+                 System.err.println ("wait getMEM request 3 GOT: " + request.getObject().getClass());
              }
          } catch (InterruptedException e) {
              throw new RuntimeException("Interrupted waiting for call request.",
                                         e);
          }
-         System.out.println (" getMember DONE");
-         return request.object;
+         System.err.println (" getMember DONE");
+         return request.getObject();
      }
  
      public static void setMember(int internal, String name, Object value) {
-         PluginAppletSecurityContext.contexts.get(0).store.reference(name);
-         int nameID = PluginAppletSecurityContext.contexts.get(
-             0).store.getIdentifier(name);
-         PluginAppletSecurityContext.contexts.get(0).store.reference(value);
-         int valueID = PluginAppletSecurityContext.contexts.get(
-             0).store.getIdentifier(value);
+    	 AppletSecurityContextManager.getSecurityContext(0).store(name);
+         int nameID = AppletSecurityContextManager.getSecurityContext(0).getIdentifier(name);
+         AppletSecurityContextManager.getSecurityContext(0).store(value);
+         int valueID = AppletSecurityContextManager.getSecurityContext(0).getIdentifier(value);
  
          // Prefix with dummy instance for convenience.
-         VoidPluginCallRequest request =
-             new VoidPluginCallRequest("instance " + 0 +
-                                            " SetMember " + internal +
-                                            " " + nameID + " " + valueID, "JavaScriptSetMember");
-         PluginMain.postCallRequest(request);
-         PluginMain.write(request.message);
+         PluginCallRequest request = requestFactory.getPluginCallRequest("void",
+        		 							"instance " + 0 + " SetMember " + internal + " " + nameID + " " + valueID, 
+        		 							"JavaScriptSetMember");
+         streamhandler.postCallRequest(request);
+         streamhandler.write(request.getMessage());
          try {
-             System.out.println ("wait setMem request: " + request.message);
+             System.out.println ("wait setMem request: " + request.getMessage());
              System.out.println ("wait setMem request 1");
              synchronized(request) {
                  System.out.println ("wait setMem request 2");
-                 while (request.done == false)
+                 while (request.isDone() == false)
                      request.wait();
                  System.out.println ("wait setMem request 3");
              }
@@ -669,22 +714,20 @@
  
      // FIXME: handle long index as well.
      public static void setSlot(int internal, int index, Object value) {
-         PluginAppletSecurityContext.contexts.get(0).store.reference(value);
-         int valueID = PluginAppletSecurityContext.contexts.get(
-             0).store.getIdentifier(value);
+    	 AppletSecurityContextManager.getSecurityContext(0).store(value);
+         int valueID = AppletSecurityContextManager.getSecurityContext(0).getIdentifier(value);
  
          // Prefix with dummy instance for convenience.
-         VoidPluginCallRequest request =
-             new VoidPluginCallRequest("instance " + 0 +
-                                       " SetSlot " + internal +
-                                       " " + index + " " + valueID, "JavaScriptSetSlot");
-         PluginMain.postCallRequest(request);
-         PluginMain.write(request.message);
+         PluginCallRequest request = requestFactory.getPluginCallRequest("void",
+        		 						"instance " + 0 + " SetSlot " + internal + " " + index + " " + valueID, 
+        		 						"JavaScriptSetSlot");
+         streamhandler.postCallRequest(request);
+         streamhandler.write(request.getMessage());
          try {
              System.out.println ("wait setSlot request 1");
              synchronized(request) {
                  System.out.println ("wait setSlot request 2");
-                 while (request.done == false)
+                 while (request.isDone() == false)
                      request.wait();
                  System.out.println ("wait setSlot request 3");
              }
@@ -698,17 +741,16 @@
      public static Object getSlot(int internal, int index)
      {
          // Prefix with dummy instance for convenience.
-         GetMemberPluginCallRequest request =
-             new GetMemberPluginCallRequest("instance " + 0 +
-                                            " GetSlot " + internal +
-                                            " " + index, "JavaScriptGetSlot");
-         PluginMain.postCallRequest(request);
-         PluginMain.write(request.message);
+         PluginCallRequest request = requestFactory.getPluginCallRequest("member", 
+        		 								"instance " + 0 + " GetSlot " + internal + " " + index, 
+        		 								"JavaScriptGetSlot");
+         streamhandler.postCallRequest(request);
+         streamhandler.write(request.getMessage());
          try {
              System.out.println ("wait getSlot request 1");
              synchronized(request) {
                  System.out.println ("wait getSlot request 2");
-                 while (request.done == false)
+                 while (request.isDone() == false)
                      request.wait();
                  System.out.println ("wait getSlot request 3");
              }
@@ -717,27 +759,25 @@
                                         e);
          }
          System.out.println (" getSlot DONE");
-         return request.object;
+         return request.getObject();
      }
  
      public static Object eval(int internal, String s)
      {
-         PluginAppletSecurityContext.contexts.get(0).store.reference(s);
-         int stringID = PluginAppletSecurityContext.contexts.get(
-             0).store.getIdentifier(s);
+    	 AppletSecurityContextManager.getSecurityContext(0).store(s);
+         int stringID = AppletSecurityContextManager.getSecurityContext(0).getIdentifier(s);
          // Prefix with dummy instance for convenience.
          // FIXME: rename GetMemberPluginCallRequest ObjectPluginCallRequest.
-         GetMemberPluginCallRequest request =
-             new GetMemberPluginCallRequest("instance " + 0 +
-                                            " Eval " + internal +
-                                            " " + stringID, "JavaScriptEval");
-         PluginMain.postCallRequest(request);
-         PluginMain.write(request.message);
+         PluginCallRequest request = requestFactory.getPluginCallRequest("member",	
+        		 								"instance " + 0 + " Eval " + internal + " " + stringID, 
+        		 								"JavaScriptEval");
+         streamhandler.postCallRequest(request);
+         streamhandler.write(request.getMessage());
          try {
              System.out.println ("wait eval request 1");
              synchronized(request) {
                  System.out.println ("wait eval request 2");
-                 while (request.done == false)
+                 while (request.isDone() == false)
                      request.wait();
                  System.out.println ("wait eval request 3");
              }
@@ -746,26 +786,24 @@
                                         e);
          }
          System.out.println (" getSlot DONE");
-         return request.object;
+         return request.getObject();
      }
  
      public static void removeMember (int internal, String name) {
-         PluginAppletSecurityContext.contexts.get(0).store.reference(name);
-         int nameID = PluginAppletSecurityContext.contexts.get(
-             0).store.getIdentifier(name);
+    	 AppletSecurityContextManager.getSecurityContext(0).store(name);
+         int nameID = AppletSecurityContextManager.getSecurityContext(0).getIdentifier(name);
  
          // Prefix with dummy instance for convenience.
-         VoidPluginCallRequest request =
-             new VoidPluginCallRequest("instance " + 0 +
-                                         " RemoveMember " + internal +
-                                         " " + nameID, "JavaScriptRemoveMember");
-         PluginMain.postCallRequest(request);
-         PluginMain.write(request.message);
+         PluginCallRequest request = requestFactory.getPluginCallRequest("void",
+        		 						"instance " + 0 + " RemoveMember " + internal + " " + nameID, 
+        		 						"JavaScriptRemoveMember");
+         streamhandler.postCallRequest(request);
+         streamhandler.write(request.getMessage());
          try {
              System.out.println ("wait removeMember request 1");
              synchronized(request) {
                  System.out.println ("wait removeMember request 2");
-                 while (request.done == false)
+                 while (request.isDone() == false)
                      request.wait();
                  System.out.println ("wait removeMember request 3");
              }
@@ -781,25 +819,22 @@
          // FIXME: when is this removed from the object store?
          // FIXME: reference should return the ID.
          // FIXME: convenience method for this long line.
-         PluginAppletSecurityContext.contexts.get(0).store.reference(name);
-         int nameID = PluginAppletSecurityContext.contexts.get(
-             0).store.getIdentifier(name);
-         PluginAppletSecurityContext.contexts.get(0).store.reference(args);
-         int argsID = PluginAppletSecurityContext.contexts.get(
-             0).store.getIdentifier(args);
+    	 AppletSecurityContextManager.getSecurityContext(0).store(name);
+         int nameID = AppletSecurityContextManager.getSecurityContext(0).getIdentifier(name);
+         AppletSecurityContextManager.getSecurityContext(0).store(args);
+         int argsID = AppletSecurityContextManager.getSecurityContext(0).getIdentifier(args);
  
          // Prefix with dummy instance for convenience.
-         GetMemberPluginCallRequest request =
-             new GetMemberPluginCallRequest("instance " + 0 +
-                                            " Call " + internal +
-                                            " " + nameID + " " + argsID, "JavaScriptCall");
-         PluginMain.postCallRequest(request);
-         PluginMain.write(request.message);
+         PluginCallRequest request = requestFactory.getPluginCallRequest("member",
+        		 							"instance " + 0 + " Call " + internal + " " + nameID + " " + argsID, 
+        		 							"JavaScriptCall");
+         streamhandler.postCallRequest(request);
+         streamhandler.write(request.getMessage());
          try {
              System.out.println ("wait call request 1");
              synchronized(request) {
                  System.out.println ("wait call request 2");
-                 while (request.done == false)
+                 while (request.isDone() == false)
                      request.wait();
                  System.out.println ("wait call request 3");
              }
@@ -808,22 +843,22 @@
                                         e);
          }
          System.out.println (" Call DONE");
-         return request.object;
+         return request.getObject();
      }
  
      public static void JavaScriptFinalize(int internal)
      {
          // Prefix with dummy instance for convenience.
-         VoidPluginCallRequest request =
-             new VoidPluginCallRequest("instance " + 0 +
-                                            " Finalize " + internal, "JavaScriptFinalize");
-         PluginMain.postCallRequest(request);
-         PluginMain.write(request.message);
+         PluginCallRequest request = requestFactory.getPluginCallRequest("void",
+        		 						"instance " + 0 + " Finalize " + internal, 
+        		 						"JavaScriptFinalize");
+         streamhandler.postCallRequest(request);
+         streamhandler.write(request.getMessage());
          try {
              System.out.println ("wait finalize request 1");
              synchronized(request) {
                  System.out.println ("wait finalize request 2");
-                 while (request.done == false)
+                 while (request.isDone() == false)
                      request.wait();
                  System.out.println ("wait finalize request 3");
              }
@@ -837,16 +872,16 @@
      public static String javascriptToString(int internal)
      {
          // Prefix with dummy instance for convenience.
-         GetMemberPluginCallRequest request =
-             new GetMemberPluginCallRequest("instance " + 0 +
-                                       " ToString " + internal, "JavaScriptToString");
-         PluginMain.postCallRequest(request);
-         PluginMain.write(request.message);
+         PluginCallRequest request = requestFactory.getPluginCallRequest("member",
+        		 								"instance " + 0 + " ToString " + internal, 
+        		 								"JavaScriptToString");
+         streamhandler.postCallRequest(request);
+         streamhandler.write(request.getMessage());
          try {
              System.out.println ("wait ToString request 1");
              synchronized(request) {
                  System.out.println ("wait ToString request 2");
-                 while (request.done == false)
+                 while (request.isDone() == false)
                      request.wait();
                  System.out.println ("wait ToString request 3");
              }
@@ -855,26 +890,17 @@
                                         e);
          }
          System.out.println (" ToString DONE");
-         return (String) request.object;
+         return (String) request.getObject();
      }
  
      // FIXME: make this private and access it from JSObject using
      // reflection.
      private void write(String message) throws IOException {
          System.err.println ("WRITING 2: " + "instance " + identifier + " " + message);
-         PluginMain.write("instance " + identifier + " " + message);
+         streamhandler.write("instance " + identifier + " " + message);
          System.err.println ("WRITING 2 DONE");
      }
- 
-     // FIXME: make this private and access it from JSObject using
-     // reflection.
-     private String read() throws IOException {
-         System.out.println ("READING 1");
-         String ret = PluginMain.read();
-         System.out.println ("READING 1 DONE");
-         return ret;
-     }
- 
+
      public void setStream(String key, InputStream stream)throws IOException{
  	// We do nothing.
      }
@@ -1014,7 +1040,13 @@
              return;   // abort the reload
          }
  
-         panel.createAppletThread();
+         AccessController.doPrivileged(new PrivilegedAction() {
+             public Object run() {
+            	 panel.createAppletThread();
+                 return null;
+             }
+         });     
+    
  	panel.sendEvent(AppletPanel.APPLET_LOAD);
  	panel.sendEvent(AppletPanel.APPLET_INIT);
  	panel.sendEvent(AppletPanel.APPLET_START);
@@ -1207,7 +1239,26 @@
  
      public static void parse(int identifier, long handle, Reader in, URL url)
          throws IOException {
-         parse(identifier, handle, in, url, System.out, new PluginAppletViewerFactory());
+    	 final int fIdentifier = identifier;
+    	 final long fHandle = handle;
+    	 final Reader fIn = in;
+    	 final URL fUrl = url;
+    	 PrivilegedAction pa = new PrivilegedAction() {
+    		 public Object run() {
+    			 try {
+    				 parse(fIdentifier, fHandle, fIn, fUrl, System.out, new PluginAppletViewerFactory());
+    			 } catch (IOException ioe) {
+    				 return ioe;
+    			 }
+    	         
+    			 return null;
+    		 }
+    	 };
+
+    	 Object ret = AccessController.doPrivileged(pa);
+    	 if (ret instanceof IOException) {
+    		 throw (IOException) ret;
+    	 }
      }
  
      public static void parse(int identifier, long handle, Reader in, URL url,
@@ -1408,16 +1459,7 @@
     	 in.close();
      }
  
-     /**
-      * Old main entry point.
-      *
-      * @deprecated
-      */
-     @Deprecated
-     public static void main(String args[]) throws IOException {
-         PluginMain.main(args);
-     }
- 
+
      private static AppletMessageHandler amh = new AppletMessageHandler("appletviewer");
  
      private static void checkConnect(URL url)
--- a/plugin/icedtea/java/src/main/sun/applet/PluginCallRequest.java	Sun Sep 21 15:58:46 2008 -0400
+++ b/plugin/icedtea/java/src/main/sun/applet/PluginCallRequest.java	Tue Sep 23 16:33:17 2008 -0400
@@ -37,9 +37,12 @@
 
 package sun.applet;
 
+import java.security.AccessControlContext;
+import java.security.ProtectionDomain;
+
 // FIXME: for each type of request extend a new (anonymous?)
 // PluginCallRequest.
-abstract class PluginCallRequest {
+public abstract class PluginCallRequest {
     String message;
     String returnString;
     PluginCallRequest next;
@@ -50,7 +53,33 @@
         this.returnString = returnString;
     }
 
+    public String getMessage() {
+    	return this.message;
+    }
+    
+    public String getReturnString() {
+    	return this.returnString;
+    }
+    
+    public boolean isDone() {
+    	return this.done;
+    }
+    
+    public boolean setDone(boolean done) {
+    	return this.done = done;
+    }
+    
+    public void setNext(PluginCallRequest next) {
+    	this.next = next;
+    }
+    
+    public PluginCallRequest getNext() {
+    	return this.next;
+    }
+
     public abstract void parseReturn(String message);
     
     public abstract boolean serviceable(String message);
+    
+    public abstract Object getObject();
 }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugin/icedtea/java/src/main/sun/applet/PluginCallRequestFactory.java	Tue Sep 23 16:33:17 2008 -0400
@@ -0,0 +1,7 @@
+package sun.applet;
+
+public interface PluginCallRequestFactory {
+
+	public PluginCallRequest getPluginCallRequest(String id, String message, String returnString);
+	
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugin/icedtea/java/src/main/sun/applet/PluginClassLoader.java	Tue Sep 23 16:33:17 2008 -0400
@@ -0,0 +1,13 @@
+package sun.applet;
+
+public class PluginClassLoader extends ClassLoader {
+
+	public PluginClassLoader() {
+		super();
+	}
+
+	public Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
+		return super.loadClass(name, resolve);
+	}
+	
+}
--- a/plugin/icedtea/java/src/main/sun/applet/PluginDebug.java	Sun Sep 21 15:58:46 2008 -0400
+++ b/plugin/icedtea/java/src/main/sun/applet/PluginDebug.java	Tue Sep 23 16:33:17 2008 -0400
@@ -3,7 +3,7 @@
 import java.io.*;
 
 public class PluginDebug {
-	
+
 	static final boolean DEBUG = true; 
 
     public static void debug(String message) {
--- a/plugin/icedtea/java/src/main/sun/applet/PluginException.java	Sun Sep 21 15:58:46 2008 -0400
+++ b/plugin/icedtea/java/src/main/sun/applet/PluginException.java	Tue Sep 23 16:33:17 2008 -0400
@@ -1,14 +1,15 @@
 package sun.applet;
 
+
 public class PluginException extends Exception {
 
-	public PluginException (int instance, int reference, Throwable t) {
+	public PluginException (PluginStreamHandler sh, int instance, int reference, Throwable t) {
 		t.printStackTrace();
 		this.setStackTrace(t.getStackTrace());
 		
-		PluginAppletSecurityContext.contexts.get(0).store.dump();
+		AppletSecurityContextManager.dumpStore(0);
 
 		String message = "instance " + instance + " reference " + reference + " Error " + t.getMessage();
-		PluginMain.write(message);
+		sh.write(message);
 	}
 }
--- a/plugin/icedtea/java/src/main/sun/applet/PluginMain.java	Sun Sep 21 15:58:46 2008 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,533 +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 sun.applet;
-
-import java.io.*;
-import java.lang.reflect.*;
-import java.net.*;
-import java.nio.charset.Charset;
-import java.util.*;
-
-import sun.net.www.ParseUtil;
-
-class RequestQueue {
-    PluginCallRequest head = null;
-    PluginCallRequest tail = null;
-    private int size = 0;
-
-    void post(PluginCallRequest request) {
-        if (head == null) {
-            head = tail = request;
-            tail.next = null;
-        } else {
-            tail.next = request;
-            tail = request;
-            tail.next = null;
-        }
-        
-        size++;
-    }
-
-    PluginCallRequest pop() {
-        if (head == null)
-            return null;
-
-        PluginCallRequest ret = head;
-        head = head.next;
-        ret.next = null;
-        
-        size--;
-        
-        return ret;
-    }
-    
-    int size() {
-    	return size;
-    }
-}
-
-/**
- * The main entry point into PluginAppletViewer.
- */
-public class PluginMain
-{
-    private static BufferedReader pluginInputReader;
-    private static StreamTokenizer pluginInputTokenizer;
-    private static BufferedWriter pluginOutputWriter;
-    // 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 static RequestQueue queue = new RequestQueue();
-
-	static LinkedList<String> readQueue = new LinkedList<String>();
-	static LinkedList<String> writeQueue = new LinkedList<String>();
-
-	static PluginMessageConsumer consumer;
-	static Boolean shuttingDown = false;
-	
-	static final boolean redirectStreams = false;
-
-    /**
-     * 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);
-    	}
-
-    	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();
-
-    	System.err.println("Creating consumer...");
-    	consumer = new PluginMessageConsumer();
-
-    	beginListening(50007);
-    }
-
-    public PluginMain() {
-    	
-    	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();
-
-    	System.err.println("Creating consumer...");
-    	consumer = new PluginMessageConsumer();
-
-		beginListening(50007);
-
-    }
-
-	private static void beginListening(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 {
-	    	start(socket.getInputStream(), socket.getOutputStream());
-	    	System.err.println("Streams initialized");
-		} catch (IOException ioe) {
-			ioe.printStackTrace();
-		}
-	}
-    
-    public static 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.
-    	    }
-                PluginAppletSecurityContext.contexts.get(0).store.dump();
-    	    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");
-    }
-
-    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!
-    }
-
-    public static void handleMessage(String message) throws PluginException{
-
-    	StringTokenizer st = new StringTokenizer(message, " ");
-
-    	String type = st.nextToken();
-    	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;
-    		}
-
-    		if (type.equals("instance"))
-    			PluginAppletViewer.handleMessage(identifier, reference, rest);
-    		else if (type.equals("context")) {
-    			PluginDebug.debug("Sending to PASC: " + identifier + "/" + reference + " and " + rest);
-    			PluginAppletSecurityContext.handleMessage(identifier, src, reference, rest);
-    		}
-    	} catch (Exception e) {
-    		throw new PluginException(identifier, reference, e);
-    	}
-    }
-
-    static void start(InputStream inputstream, OutputStream outputstream)
-	throws MalformedURLException, IOException
-    {
-	// 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")));
-
-	
-	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.
-					}
-					PluginAppletSecurityContext.contexts.get(0).store.dump();
-					System.err.println("APPLETVIEWER: exiting appletviewer");
-					System.exit(0);
-				}
-			}
-		}
-	};
-	
-	listenerThread.start();
-	
-/*
-	while(true) {
-            String message = read();
-            PluginDebug.debug(message);
-            handleMessage(message);
-            // TODO:
-            // write(queue.peek());
-	}
-*/
-    }
-
-    public static void postCallRequest(PluginCallRequest request) {
-        synchronized(queue) {
-            queue.post(request);
-        }
-    }
-
-    private static 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");
-    }
-
-    /**
-     * Write string to plugin.
-     * 
-     * @param message the message to write
-     *
-     * @exception IOException if an error occurs
-     */
-    static 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);
-    	}
-	*/
-
-    }
-
-    static boolean messageAvailable() {
-    	return writeQueue.size() != 0;
-    }
-
-    static String getMessage() {
-    	synchronized(writeQueue) {
-			String ret = writeQueue.size() > 0 ? writeQueue.poll() : "";
-    		return ret;
-    	}
-    }
-
-    /**
-     * Read string from plugin.
-     *
-     * @return the read string
-     *
-     * @exception IOException if an error occurs
-     */
-    static 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.
-    		}
-    		PluginAppletSecurityContext.contexts.get(0).store.dump();
-    		System.err.println("APPLETVIEWER: exiting appletviewer");
-    		System.exit(0);
-    	}
-    	return message;
-    }
-}
--- a/plugin/icedtea/java/src/main/sun/applet/PluginMessageConsumer.java	Sun Sep 21 15:58:46 2008 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-package sun.applet;
-
-import java.util.ArrayList;
-
-class PluginMessageConsumer {
-
-	int MAX_WORKERS = 3;
-	ArrayList<PluginMessageHandlerWorker> workers = new ArrayList<PluginMessageHandlerWorker>();
-
-	public PluginMessageConsumer() {
-		for (int i=0; i < MAX_WORKERS; i++) {
-			System.err.println("Creating worker " + i);
-			PluginMessageHandlerWorker worker = new PluginMessageHandlerWorker(i);
-			worker.start();
-			workers.add(worker);
-		}
-	}
-
-	public void consume(String message) {
-		
-		PluginDebug.debug("Consumer received message " + message);
-		
-		synchronized(PluginMain.readQueue) {
-			PluginMain.readQueue.add(message);
-		}
-
-		PluginDebug.debug("Message " + message + " added to queue. Looking for free worker...");
-		PluginMessageHandlerWorker worker = getFreeWorker();
-		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());
-					return worker;
-				}
-			}
-			Thread.yield();
-		}
-
-		//throw new RuntimeException("Out of message handler workers");
-	}
-	
-}
--- a/plugin/icedtea/java/src/main/sun/applet/PluginMessageHandlerWorker.java	Sun Sep 21 15:58:46 2008 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-package sun.applet;
-
-class PluginMessageHandlerWorker extends Thread {
-
-	private boolean free = true;
-	private int id;
-	
-	public PluginMessageHandlerWorker(int id) {
-		this.id = id;
-	}
-	
-	public void run() {
-		while (true) {
-
-			String msg = null;
-			synchronized(PluginMain.readQueue) {
-				if (PluginMain.readQueue.size() > 0) {
-					msg = PluginMain.readQueue.poll();
-				}
-			}
-			
-			if (msg != null) {
-				free = false;
-				System.err.println("Thread " + id + " picking up " + msg + " from queue...");
-
-				try {
-					PluginMain.handleMessage(msg);
-				} 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
-					 */ 
-				}
-
-				free = true;
-			} 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
-				}
-			}
-		}
-	}
-	
-	public int getWorkerId() {
-		return id;
-	}
-	
-	public boolean isFree() {
-		return free;
-	}
-}
--- a/plugin/icedtea/java/src/main/sun/applet/PluginObjectStore.java	Sun Sep 21 15:58:46 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 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);
-        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));
-   		}
-    }
-}
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/plugin/icedtea/java/src/main/sun/applet/PluginStreamHandler.java	Tue Sep 23 16:33:17 2008 -0400
@@ -0,0 +1,20 @@
+package sun.applet;
+
+
+public interface PluginStreamHandler {
+
+	public void postMessage(String s);
+
+	public void handleMessage(String message) throws PluginException;
+
+	public void postCallRequest(PluginCallRequest request);
+
+	public void write(String message);
+
+	public boolean messageAvailable();
+
+	public String getMessage();
+	
+	public void startProcessing();
+
+}
\ No newline at end of file
--- a/plugin/icedtea/java/src/main/sun/applet/TestEnv.java	Sun Sep 21 15:58:46 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 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;
-    }
-}
--- a/plugin/icedtea/java/src/main/sun/applet/VoidPluginCallRequest.java	Sun Sep 21 15:58:46 2008 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +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 sun.applet;
-
-class VoidPluginCallRequest extends PluginCallRequest {
-    public VoidPluginCallRequest(String message, String returnString) {
-        super(message, returnString);
-        System.out.println ("VoidPLUGINCAlL " + message + " " + returnString);
-    }
-
-    public void parseReturn(String message) {
-        done = 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");
-    }
-}
--- a/rt/net/sourceforge/jnlp/Launcher.java	Sun Sep 21 15:58:46 2008 -0400
+++ b/rt/net/sourceforge/jnlp/Launcher.java	Tue Sep 23 16:33:17 2008 -0400
@@ -592,6 +592,7 @@
                 }
             }
             catch (LaunchException ex) {
+                ex.printStackTrace();
                 exception = ex;
                 // Exit if we can't launch the application.
                 System.exit(0);
--- a/rt/net/sourceforge/jnlp/runtime/JNLPRuntime.java	Sun Sep 21 15:58:46 2008 -0400
+++ b/rt/net/sourceforge/jnlp/runtime/JNLPRuntime.java	Tue Sep 23 16:33:17 2008 -0400
@@ -135,6 +135,8 @@
         if (baseDir == null)
             throw new IllegalStateException(JNLPRuntime.getMessage("BNoBase"));
 
+        ServiceManager.setServiceManagerStub(new XServiceManagerStub()); // ignored if we're running under Web Start
+	
         policy = new JNLPPolicy();
         security = new JNLPSecurityManager(); // side effect: create JWindow
 
@@ -143,8 +145,6 @@
             System.setSecurityManager(security);
         }
 
-        ServiceManager.setServiceManagerStub(new XServiceManagerStub()); // ignored if we're running under Web Start
-
         initialized = true;
     }
 
--- a/rt/netscape/javascript/JSException.java	Sun Sep 21 15:58:46 2008 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,140 +0,0 @@
-/* -*- Mode: Java; tab-width: 8; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-package netscape.javascript;
-
-/**
- * JSException is an exception which is thrown when JavaScript code
- * returns an error.
- */
-
-public
-class JSException extends RuntimeException {
-    public static final int EXCEPTION_TYPE_EMPTY = -1;
-    public static final int EXCEPTION_TYPE_VOID = 0;
-    public static final int EXCEPTION_TYPE_OBJECT = 1;
-    public static final int EXCEPTION_TYPE_FUNCTION = 2;
-    public static final int EXCEPTION_TYPE_STRING = 3;
-    public static final int EXCEPTION_TYPE_NUMBER = 4;
-    public static final int EXCEPTION_TYPE_BOOLEAN = 5;
-    public static final int EXCEPTION_TYPE_ERROR = 6;
-
-    public String filename;
-    public int lineno;
-    public String source;
-    public int tokenIndex;
-    public int wrappedExceptionType;
-    public Object wrappedException;
-
-    /**
-     * Constructs a JSException without a detail message.
-     * A detail message is a String that describes this particular exception.
-     *
-     * @deprecated Not for public use in future versions.
-     */
-    public JSException() {
-	super();
-        filename = "unknown";
-        lineno = 0;
-        source = "";
-        tokenIndex = 0;
-	wrappedExceptionType = EXCEPTION_TYPE_EMPTY;
-    }
-
-    /**
-     * Constructs a JSException with a detail message.
-     * A detail message is a String that describes this particular exception.
-     * @param s the detail message
-     *
-     * @deprecated Not for public use in future versions.
-     */
-    public JSException(String s) {
-	super(s);
-        filename = "unknown";
-        lineno = 0;
-        source = "";
-        tokenIndex = 0;
-	wrappedExceptionType = EXCEPTION_TYPE_EMPTY;
-    }
-
-    /**
-     * Constructs a JSException with a wrapped JavaScript exception object.
-     * This constructor needs to be public so that Java users can throw 
-     * exceptions to JS cleanly.
-     */
-    public JSException(int wrappedExceptionType, Object wrappedException) {
-	super();
-	this.wrappedExceptionType = wrappedExceptionType;
-	this.wrappedException = wrappedException;
-    }
-    
-    /**
-     * Constructs a JSException with a detail message and all the
-     * other info that usually comes with a JavaScript error.
-     * @param s the detail message
-     *
-     * @deprecated Not for public use in future versions.
-     */
-    public JSException(String s, String filename, int lineno,
-                       String source, int tokenIndex) {
-	super(s);
-        this.filename = filename;
-        this.lineno = lineno;
-        this.source = source;
-        this.tokenIndex = tokenIndex;
-	wrappedExceptionType = EXCEPTION_TYPE_EMPTY;
-    }
-
-    /**
-     * Instance method getWrappedExceptionType returns the int mapping of the
-     * type of the wrappedException Object.
-     */
-    public int getWrappedExceptionType() {
-	return wrappedExceptionType;
-    }
-
-    /**
-     * Instance method getWrappedException.
-     */
-    public Object getWrappedException() {
-	return wrappedException;
-    }
-
-}
-
--- a/rt/netscape/javascript/JSObject.java	Sun Sep 21 15:58:46 2008 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,258 +0,0 @@
-/* -*- Mode: Java; tab-width: 8; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/* more doc todo:
- *  threads
- *  gc
- *  
- *
- */
-
-package netscape.javascript;
-
-import java.applet.Applet;
-import java.io.IOException;
-import sun.applet.PluginAppletViewer;
-
-/**
- * JSObject allows Java to manipulate objects that are
- * defined in JavaScript.
- * Values passed from Java to JavaScript are converted as
- * follows:<ul>
- * <li>JSObject is converted to the original JavaScript object
- * <li>Any other Java object is converted to a JavaScript wrapper,
- *   which can be used to access methods and fields of the java object.
- *   Converting this wrapper to a string will call the toString method
- *   on the original object, converting to a number will call the
- *   doubleValue method if possible and fail otherwise.  Converting
- *   to a boolean will try to call the booleanValue method in the
- *   same way.
- * <li>Java arrays are wrapped with a JavaScript object that understands
- *   array.length and array[index]
- * <li>A Java boolean is converted to a JavaScript boolean
- * <li>Java byte, char, short, int, long, float, and double are converted
- *   to JavaScript numbers
- * </ul>
- * Values passed from JavaScript to Java are converted as follows:<ul>
- * <li>objects which are wrappers around java objects are unwrapped
- * <li>other objects are wrapped with a JSObject
- * <li>strings, numbers and booleans are converted to String, Double,
- *   and Boolean objects respectively
- * </ul>
- * This means that all JavaScript values show up as some kind
- * of java.lang.Object in Java.  In order to make much use of them,
- * you will have to cast them to the appropriate subclass of Object,
- * e.g. <code>(String) window.getMember("name");</code> or
- * <code>(JSObject) window.getMember("document");</code>.
- */
-public final class JSObject {
-    /* the internal object data */
-    private int                               internal;
-    private long                              long_internal;
-
-    /**
-     * initialize
-     */
-    private static void initClass() {
-        System.err.println ("JSObject.initClass");
-    }
-
-    static {
-        System.err.println ("JSObject INITIALIZER");
-    }
-
-    /**
-     * it is illegal to construct a JSObject manually
-     */
-    // FIXME: make private!
-    public JSObject(int jsobj_addr) {
-        System.err.println ("JSObject int CONSTRUCTOR");
-        internal = jsobj_addr;
-    }
-
-    private JSObject(long jsobj_addr) {
-        System.err.println ("JSObject long CONSTRUCTOR");
-        long_internal = jsobj_addr;
-    }
-
-    /**
-     * Retrieves a named member of a JavaScript object. 
-     * Equivalent to "this.<i>name</i>" in JavaScript.
-     */
-    public Object	getMember(String name)
-    {
-        System.err.println ("JSObject.getMember " + name);
-
-        Object o = PluginAppletViewer.getMember(internal, name);
-        System.out.println ("JSObject.getMember GOT " + o);
-        return o;
-    }
-
-
-    /**
-     * Retrieves an indexed member of a JavaScript object.
-     * Equivalent to "this[<i>index</i>]" in JavaScript.
-     */
-    //    public Object		getMember(int index) { return getSlot(index); }
-    public Object	getSlot(int index)
-    {
-        System.err.println ("JSObject.getSlot " + index);
-
-        return PluginAppletViewer.getSlot(internal, index);
-    }
-
-
-    /**
-     * Sets a named member of a JavaScript object. 
-     * Equivalent to "this.<i>name</i> = <i>value</i>" in JavaScript.
-     */
-    public void 		setMember(String name, Object value)
-    {
-        System.err.println ("JSObject.setMember " + name + " " + value);
-
-        PluginAppletViewer.setMember(internal, name, value);
-    }
-
-    /**
-     * Sets an indexed member of a JavaScript object. 
-     * Equivalent to "this[<i>index</i>] = <i>value</i>" in JavaScript.
-     */
-    //    public void 		setMember(int index, Object value) {
-    //        setSlot(index, value);
-    //    }
-    public void 		setSlot(int index, Object value)
-    {
-        System.err.println ("JSObject.setSlot " + index + " " + value);
-
-        PluginAppletViewer.setSlot(internal, index, value);
-    }
-
-
-    // TODO: toString, finalize.
-
-    /**
-     * Removes a named member of a JavaScript object.
-     */
-    public void 		removeMember(String name)
-    {
-        System.err.println ("JSObject.removeMember " + name);
-
-        PluginAppletViewer.removeMember(internal, name);
-    }
-
-
-    /**
-     * Calls a JavaScript method.
-     * Equivalent to "this.<i>methodName</i>(<i>args</i>[0], <i>args</i>[1], ...)" in JavaScript.
-     */
-    public Object	call(String methodName, Object args[])
-    {
-        System.err.print ("JSObject.call " + methodName);
-        for (int i = 0; i < args.length; i++)
-            System.err.print (" " + args[i]);
-        System.err.println("");
-        return PluginAppletViewer.call(internal, methodName, args);
-    }
-
-
-    /**
-     * Evaluates a JavaScript expression. The expression is a string 
-     * of JavaScript source code which will be evaluated in the context
-     * given by "this".
-     */
-    public Object	eval(String s)
-    {
-        System.err.println("JSObject.eval " + s);
-        return PluginAppletViewer.eval(internal, s);
-    }
-
-
-    /**
-     * Converts a JSObject to a String.
-     */
-    public String        toString()
-    {
-        System.err.println("JSObject.toString");
-        return PluginAppletViewer.javascriptToString(internal);
-    }
-
-
-    // should use some sort of identifier rather than String
-    // is "property" the right word?
-    //    native String[]                         listProperties();
-
-
-    /**
-     * get a JSObject for the window containing the given applet
-     */
-    public static JSObject	getWindow(Applet applet)
-    {
-        System.err.println("JSObject.getWindow");
-        // FIXME: handle long case as well.
-        int internal = 0;
-        internal = ((PluginAppletViewer)
-                    applet.getAppletContext()).getWindow();
-        System.out.println ("GOT IT: " + internal);
-        return new JSObject(internal);
-    }
-
-
-    /**
-     * Finalization decrements the reference count on the corresponding
-     * JavaScript object.
-     */
-    protected void	finalize()
-    {
-        System.err.println("JSObject.finalize ");
-        PluginAppletViewer.JavaScriptFinalize(internal);
-    }
-
-
-    /**
-     * Override java.lang.Object.equals() because identity is not preserved
-     * with instances of JSObject.
-     */
-    public boolean equals(Object obj)
-    {
-        System.err.println("JSObject.equals " + obj);
-
-        return false;
-    }
-
-}
--- a/rt/netscape/javascript/JSProxy.java	Sun Sep 21 15:58:46 2008 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,58 +0,0 @@
-/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-/**
- * The JSProxy interface allows applets and plugins to
- * share javascript contexts.
- */
-
-package netscape.javascript;
-import java.applet.Applet;
-
-public interface JSProxy {
-    Object  getMember(JSObject jso, String name);
-    Object  getSlot(JSObject jso, int index);
-    void    setMember(JSObject jso, String name, Object value);
-    void    setSlot(JSObject jso, int index, Object value);
-    void    removeMember(JSObject jso, String name);
-    Object  call(JSObject jso, String methodName, Object args[]);
-    Object  eval(JSObject jso, String s);
-    String      toString(JSObject jso);
-    JSObject    getWindow(Applet applet);
-}
--- a/rt/netscape/javascript/JSRunnable.java	Sun Sep 21 15:58:46 2008 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-/* -*- Mode: Java; tab-width: 8; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-
-package netscape.javascript;
-
-/**
- * Runs a JavaScript object with a run() method in a separate thread.
- */
-public class JSRunnable implements Runnable {
-	private JSObject runnable;
-
-	public JSRunnable(JSObject runnable) {
-		this.runnable = runnable;
-		synchronized(this) {
-			new Thread(this).start();
-			try {
-				this.wait();
-			} catch (InterruptedException ie) {
-			}
-		}
-	}
-	
-	public void run() {
-		try {
-			runnable.call("run", null);
-			synchronized(this) {
-				notifyAll();
-			}
-		} catch (Throwable t) {
-			System.err.println(t);
-			t.printStackTrace(System.err);
-		}
-	}
-}
--- a/rt/netscape/javascript/JSUtil.java	Sun Sep 21 15:58:46 2008 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-/* -*- Mode: Java; tab-width: 8; c-basic-offset: 4 -*-
- *
- * ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-/* ** */
-
-package netscape.javascript;
-import java.io.*;
-
-public class JSUtil {
-
-    /* Return the stack trace of an exception or error as a String */
-    public static String getStackTrace(Throwable t) {
-	ByteArrayOutputStream captureStream;
-	PrintWriter p;
-	
-	captureStream = new ByteArrayOutputStream();
-	p = new PrintWriter(captureStream);
-
-	t.printStackTrace(p);
-	p.flush();
-
-	return captureStream.toString();
-    }
-}