Author: j16sdiz
Date: 2008-10-02 11:31:29 +0000 (Thu, 02 Oct 2008)
New Revision: 22909

Modified:
   trunk/freenet/src/freenet/clients/http/ConfigToadlet.java
   trunk/freenet/src/freenet/clients/http/ConnectionsToadlet.java
   trunk/freenet/src/freenet/clients/http/DarknetConnectionsToadlet.java
   trunk/freenet/src/freenet/clients/http/FProxyToadlet.java
   trunk/freenet/src/freenet/clients/http/HTTPRequestImpl.java
   trunk/freenet/src/freenet/clients/http/N2NTMToadlet.java
   trunk/freenet/src/freenet/clients/http/PproxyToadlet.java
   trunk/freenet/src/freenet/clients/http/QueueToadlet.java
   trunk/freenet/src/freenet/clients/http/Toadlet.java
   trunk/freenet/src/freenet/clients/http/ToadletContext.java
   trunk/freenet/src/freenet/clients/http/ToadletContextImpl.java
   trunk/freenet/src/freenet/clients/http/TranslationToadlet.java
   trunk/freenet/src/freenet/clients/http/WelcomeToadlet.java
   trunk/freenet/test/freenet/support/MultiValueTableTest.java
Log:
generify with MultiValueTable

Modified: trunk/freenet/src/freenet/clients/http/ConfigToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/ConfigToadlet.java   2008-10-02 
11:30:51 UTC (rev 22908)
+++ trunk/freenet/src/freenet/clients/http/ConfigToadlet.java   2008-10-02 
11:31:29 UTC (rev 22909)
@@ -110,7 +110,7 @@
     public void handlePost(URI uri, HTTPRequest request, ToadletContext ctx) 
throws ToadletContextClosedException, IOException {
                String pass = request.getPartAsString("formPassword", 32);
                if((pass == null) || !pass.equals(core.formPassword)) {
-                       MultiValueTable headers = new MultiValueTable();
+                       MultiValueTable<String,String> headers = new 
MultiValueTable<String,String>();
                        headers.put("Location", "/config/");
                        ctx.sendReplyHeaders(302, "Found", headers, null, 0);
                        return;
@@ -221,7 +221,7 @@
                                writeHTMLReply(ctx, 200, "OK", 
pageNode.generate());
                                return;
                        } else {
-                               MultiValueTable headers = new MultiValueTable();
+                               MultiValueTable<String, String> headers = new 
MultiValueTable<String, String>();
                                headers.put("Location", 
"/config/?mode="+MODE_SECURITY_LEVELS);
                                ctx.sendReplyHeaders(302, "Found", headers, 
null, 0);
                                return;

Modified: trunk/freenet/src/freenet/clients/http/ConnectionsToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/ConnectionsToadlet.java      
2008-10-02 11:30:51 UTC (rev 22908)
+++ trunk/freenet/src/freenet/clients/http/ConnectionsToadlet.java      
2008-10-02 11:31:29 UTC (rev 22909)
@@ -180,7 +180,7 @@
                        SimpleFieldSet fs = getNoderef();
                        StringWriter sw = new StringWriter();
                        fs.writeTo(sw);
-                       MultiValueTable extraHeaders = new MultiValueTable();
+                       MultiValueTable<String, String> extraHeaders = new 
MultiValueTable<String, String>();
                        // Force download to disk
                        extraHeaders.put("Content-Disposition", "attachment; 
filename=myref.fref");
                        this.writeReply(ctx, 200, 
"application/x-freenet-reference", "OK", extraHeaders, sw.toString());
@@ -499,7 +499,7 @@

                String pass = request.getPartAsString("formPassword", 32);
                if((pass == null) || !pass.equals(core.formPassword)) {
-                       MultiValueTable headers = new MultiValueTable();
+                       MultiValueTable<String, String> headers = new 
MultiValueTable<String, String>();
                        headers.put("Location", defaultRedirectLocation());
                        ctx.sendReplyHeaders(302, "Found", headers, null, 0);
                        if(logMINOR) Logger.minor(this, "No password ("+pass+" 
should be "+core.formPassword+ ')');
@@ -607,7 +607,7 @@
                                return;
                        }

-                       MultiValueTable headers = new MultiValueTable();
+                       MultiValueTable<String, String> headers = new 
MultiValueTable<String, String>();
                        headers.put("Location", defaultRedirectLocation());
                        ctx.sendReplyHeaders(302, "Found", headers, null, 0);
                        return;

Modified: trunk/freenet/src/freenet/clients/http/DarknetConnectionsToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/DarknetConnectionsToadlet.java       
2008-10-02 11:30:51 UTC (rev 22908)
+++ trunk/freenet/src/freenet/clients/http/DarknetConnectionsToadlet.java       
2008-10-02 11:31:29 UTC (rev 22909)
@@ -192,7 +192,7 @@
                                        }
                                }
                        }
-                       MultiValueTable headers = new MultiValueTable();
+                       MultiValueTable<String, String> headers = new 
MultiValueTable<String, String>();
                        headers.put("Location", "/friends/");
                        ctx.sendReplyHeaders(302, "Found", headers, null, 0);
                        return;
@@ -205,7 +205,7 @@
                                        peerNodes[i].enablePeer();
                                }
                        }
-                       MultiValueTable headers = new MultiValueTable();
+                       MultiValueTable<String, String> headers = new 
MultiValueTable<String, String>();
                        headers.put("Location", "/friends/");
                        ctx.sendReplyHeaders(302, "Found", headers, null, 0);
                        return;
@@ -218,7 +218,7 @@
                                        peerNodes[i].disablePeer();
                                }
                        }
-                       MultiValueTable headers = new MultiValueTable();
+                       MultiValueTable<String, String> headers = new 
MultiValueTable<String, String>();
                        headers.put("Location", "/friends/");
                        ctx.sendReplyHeaders(302, "Found", headers, null, 0);
                        return;
@@ -231,7 +231,7 @@
                                        peerNodes[i].setBurstOnly(true);
                                }
                        }
-                       MultiValueTable headers = new MultiValueTable();
+                       MultiValueTable<String, String> headers = new 
MultiValueTable<String, String>();
                        headers.put("Location", "/friends/");
                        ctx.sendReplyHeaders(302, "Found", headers, null, 0);
                        return;
@@ -244,7 +244,7 @@
                                        peerNodes[i].setBurstOnly(false);
                                }
                        }
-                       MultiValueTable headers = new MultiValueTable();
+                       MultiValueTable<String, String> headers = new 
MultiValueTable<String, String>();
                        headers.put("Location", "/friends/");
                        ctx.sendReplyHeaders(302, "Found", headers, null, 0);
                        return;
@@ -257,7 +257,7 @@
                                        peerNodes[i].setIgnoreSourcePort(true);
                                }
                        }
-                       MultiValueTable headers = new MultiValueTable();
+                       MultiValueTable<String, String> headers = new 
MultiValueTable<String, String>();
                        headers.put("Location", "/friends/");
                        ctx.sendReplyHeaders(302, "Found", headers, null, 0);
                        return;
@@ -270,7 +270,7 @@
                                        peerNodes[i].setIgnoreSourcePort(false);
                                }
                        }
-                       MultiValueTable headers = new MultiValueTable();
+                       MultiValueTable<String, String> headers = new 
MultiValueTable<String, String>();
                        headers.put("Location", "/friends/");
                        ctx.sendReplyHeaders(302, "Found", headers, null, 0);
                        return;
@@ -281,7 +281,7 @@
                                        peerNodes[i].setRoutingStatus(true, 
true);
                                }
                        }
-                       MultiValueTable headers = new MultiValueTable();
+                       MultiValueTable<String, String> headers = new 
MultiValueTable<String, String>();
                        headers.put("Location", "/friends/");
                        ctx.sendReplyHeaders(302, "Found", headers, null, 0);
                        return;
@@ -292,7 +292,7 @@
                                        peerNodes[i].setRoutingStatus(false, 
true);
                                }
                        }
-                       MultiValueTable headers = new MultiValueTable();
+                       MultiValueTable<String, String> headers = new 
MultiValueTable<String, String>();
                        headers.put("Location", "/friends/");
                        ctx.sendReplyHeaders(302, "Found", headers, null, 0);
                        return;
@@ -305,7 +305,7 @@
                                        peerNodes[i].setListenOnly(true);
                                }
                        }
-                       MultiValueTable headers = new MultiValueTable();
+                       MultiValueTable<String, String> headers = new 
MultiValueTable<String, String>();
                        headers.put("Location", "/friends/");
                        ctx.sendReplyHeaders(302, "Found", headers, null, 0);
                        return;
@@ -318,7 +318,7 @@
                                        peerNodes[i].setListenOnly(false);
                                }
                        }
-                       MultiValueTable headers = new MultiValueTable();
+                       MultiValueTable<String, String> headers = new 
MultiValueTable<String, String>();
                        headers.put("Location", "/friends/");
                        ctx.sendReplyHeaders(302, "Found", headers, null, 0);
                        return;
@@ -331,7 +331,7 @@
                                        
peerNodes[i].setAllowLocalAddresses(true);
                                }
                        }
-                       MultiValueTable headers = new MultiValueTable();
+                       MultiValueTable<String, String> headers = new 
MultiValueTable<String, String>();
                        headers.put("Location", "/friends/");
                        ctx.sendReplyHeaders(302, "Found", headers, null, 0);
                        return;
@@ -344,7 +344,7 @@
                                        
peerNodes[i].setAllowLocalAddresses(false);
                                }
                        }
-                       MultiValueTable headers = new MultiValueTable();
+                       MultiValueTable<String, String> headers = new 
MultiValueTable<String, String>();
                        headers.put("Location", "/friends/");
                        ctx.sendReplyHeaders(302, "Found", headers, null, 0);
                        return;
@@ -378,7 +378,7 @@
                                        if(logMINOR) Logger.minor(this, "Part 
not set: node_"+peerNodes[i].hashCode());
                                }
                        }
-                       MultiValueTable headers = new MultiValueTable();
+                       MultiValueTable<String, String> headers = new 
MultiValueTable<String, String>();
                        headers.put("Location", "/friends/");
                        ctx.sendReplyHeaders(302, "Found", headers, null, 0);
                        return;
@@ -392,7 +392,7 @@
                                        break;
                                }
                        }
-                       MultiValueTable headers = new MultiValueTable();
+                       MultiValueTable<String, String> headers = new 
MultiValueTable<String, String>();
                        headers.put("Location", "/friends/");
                        ctx.sendReplyHeaders(302, "Found", headers, null, 0);
                        return;
@@ -406,7 +406,7 @@
                                        break;
                                }
                        }
-                       MultiValueTable headers = new MultiValueTable();
+                       MultiValueTable<String, String> headers = new 
MultiValueTable<String, String>();
                        headers.put("Location", "/friends/");
                        ctx.sendReplyHeaders(302, "Found", headers, null, 0);
                        return;

Modified: trunk/freenet/src/freenet/clients/http/FProxyToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/FProxyToadlet.java   2008-10-02 
11:30:51 UTC (rev 22908)
+++ trunk/freenet/src/freenet/clients/http/FProxyToadlet.java   2008-10-02 
11:31:29 UTC (rev 22909)
@@ -192,20 +192,20 @@
                                                        new String[] { "<a 
href=\"/\">", "</a>" });

                                        byte[] pageBytes = 
pageNode.generate().getBytes("UTF-8");
-                                       context.sendReplyHeaders(200, "OK", new 
MultiValueTable(), "text/html; charset=utf-8", pageBytes.length);
+                                       context.sendReplyHeaders(200, "OK", new 
MultiValueTable<String, String>(), "text/html; charset=utf-8", 
pageBytes.length);
                                        context.writeData(pageBytes);
                                        return;
                                }
                        }

                        if (forceDownload) {
-                               MultiValueTable headers = new MultiValueTable();
+                               MultiValueTable<String, String> headers = new 
MultiValueTable<String, String>();
                                headers.put("Content-Disposition", "attachment; 
filename=\"" + key.getPreferredFilename() + '"');
                                context.sendReplyHeaders(200, "OK", headers, 
"application/x-msdownload", data.size());
                                context.writeData(data);
                        } else {
                                // Send the data, intact
-                               context.sendReplyHeaders(200, "OK", new 
MultiValueTable(), mimeType, data.size());
+                               context.sendReplyHeaders(200, "OK", new 
MultiValueTable<String, String>(), mimeType, data.size());
                                context.writeData(data);
                        }
                } catch (URISyntaxException use1) {
@@ -256,7 +256,7 @@
                        }

                        byte[] pageBytes = 
pageNode.generate().getBytes("UTF-8");
-                       context.sendReplyHeaders(200, "OK", new 
MultiValueTable(), "text/html; charset=utf-8", pageBytes.length);
+                       context.sendReplyHeaders(200, "OK", new 
MultiValueTable<String, String>(), "text/html; charset=utf-8", 
pageBytes.length);
                        context.writeData(pageBytes);
                }
        }
@@ -330,7 +330,7 @@

                if (ks.equals("/")) {
                        if (httprequest.isParameterSet("key")) {
-                               MultiValueTable headers = new MultiValueTable();
+                               MultiValueTable<String, String> headers = new 
MultiValueTable<String, String>();

                                String k = httprequest.getParam("key");
                                FreenetURI newURI;
@@ -387,12 +387,12 @@
                        this.writeTextReply(ctx, 200, "Ok", "User-agent: 
*\nDisallow: /");
                        return;
                }else if(ks.startsWith("/darknet/")) { //TODO: remove when 
obsolete
-                       MultiValueTable headers = new MultiValueTable();
+                       MultiValueTable<String, String> headers = new 
MultiValueTable<String, String>();
                        headers.put("Location", "/friends/");
                        ctx.sendReplyHeaders(301, "Permanent Redirect", 
headers, null, 0);
                        return;
                }else if(ks.startsWith("/opennet/")) { //TODO: remove when 
obsolete
-                       MultiValueTable headers = new MultiValueTable();
+                       MultiValueTable<String, String> headers = new 
MultiValueTable<String, String>();
                        headers.put("Location", "/strangers/");
                        ctx.sendReplyHeaders(301, "Permanent Redirect", 
headers, null, 0);
                        return;

Modified: trunk/freenet/src/freenet/clients/http/HTTPRequestImpl.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/HTTPRequestImpl.java 2008-10-02 
11:30:51 UTC (rev 22908)
+++ trunk/freenet/src/freenet/clients/http/HTTPRequestImpl.java 2008-10-02 
11:31:29 UTC (rev 22909)
@@ -59,7 +59,7 @@
        /**
         * The headers sent by the client
         */
-       private MultiValueTable headers;
+       private MultiValueTable<String, String> headers;

        /**
         * The data sent in the connection

Modified: trunk/freenet/src/freenet/clients/http/N2NTMToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/N2NTMToadlet.java    2008-10-02 
11:30:51 UTC (rev 22908)
+++ trunk/freenet/src/freenet/clients/http/N2NTMToadlet.java    2008-10-02 
11:31:29 UTC (rev 22909)
@@ -86,7 +86,7 @@
                        this.writeHTMLReply(ctx, 200, "OK", 
pageNode.generate());
                        return;
                }
-               MultiValueTable headers = new MultiValueTable();
+               MultiValueTable<String, String> headers = new 
MultiValueTable<String, String>();
                headers.put("Location", "/friends/");
                ctx.sendReplyHeaders(302, "Found", headers, null, 0);
        }
@@ -122,7 +122,7 @@
                        RedirectException {
                String pass = request.getPartAsString("formPassword", 32);
                if ((pass == null) || !pass.equals(core.formPassword)) {
-                       MultiValueTable headers = new MultiValueTable();
+                       MultiValueTable<String, String> headers = new 
MultiValueTable<String, String>();
                        headers.put("Location", "/send_n2ntm/");
                        ctx.sendReplyHeaders(302, "Found", headers, null, 0);
                        return;
@@ -229,7 +229,7 @@
                        this.writeHTMLReply(ctx, 200, "OK", 
pageNode.generate());
                        return;
                }
-               MultiValueTable headers = new MultiValueTable();
+               MultiValueTable<String, String> headers = new 
MultiValueTable<String, String>();
                headers.put("Location", "/friends/");
                ctx.sendReplyHeaders(302, "Found", headers, null, 0);
        }

Modified: trunk/freenet/src/freenet/clients/http/PproxyToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/PproxyToadlet.java   2008-10-02 
11:30:51 UTC (rev 22908)
+++ trunk/freenet/src/freenet/clients/http/PproxyToadlet.java   2008-10-02 
11:31:29 UTC (rev 22909)
@@ -48,7 +48,7 @@
        public void handlePost(URI uri, HTTPRequest request, ToadletContext ctx)
        throws ToadletContextClosedException, IOException {

-               MultiValueTable headers = new MultiValueTable();
+               MultiValueTable<String, String> headers = new 
MultiValueTable<String, String>();

                String pass = request.getPartAsString("formPassword", 32);
                if((pass == null) || !pass.equals(core.formPassword)) {
@@ -102,7 +102,7 @@
                        catch (DownloadPluginHTTPException e) {
                                // FIXME: maybe it ought to be defined like 
sendErrorPage : in toadlets

-                               MultiValueTable head = new MultiValueTable();
+                               MultiValueTable<String, String> head = new 
MultiValueTable<String, String>();
                                head.put("Content-Disposition", "attachment; 
filename=\"" + e.filename + '"');
                                
ctx.sendReplyHeaders(DownloadPluginHTTPException.CODE, "Found", head, 
e.mimeType, e.data.length);
                                ctx.writeData(e.data);
@@ -365,7 +365,7 @@
                } catch (DownloadPluginHTTPException e) {
                        // FIXME: maybe it ought to be defined like 
sendErrorPage : in toadlets

-                       MultiValueTable head = new MultiValueTable();
+                       MultiValueTable<String, String> head = new 
MultiValueTable<String, String>();
                        head.put("Content-Disposition", "attachment; 
filename=\"" + e.filename + '"');
                        ctx.sendReplyHeaders(DownloadPluginHTTPException.CODE, 
"Found", head, e.mimeType, e.data.length);
                        ctx.writeData(e.data);

Modified: trunk/freenet/src/freenet/clients/http/QueueToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/QueueToadlet.java    2008-10-02 
11:30:51 UTC (rev 22908)
+++ trunk/freenet/src/freenet/clients/http/QueueToadlet.java    2008-10-02 
11:31:29 UTC (rev 22909)
@@ -121,7 +121,7 @@
                                        }
                                }

-                               MultiValueTable responseHeaders = new 
MultiValueTable();
+                               MultiValueTable<String, String> responseHeaders 
= new MultiValueTable<String, String>();
                                responseHeaders.put("Location", 
"/files/?key="+insertURI.toACIIString());
                                ctx.sendReplyHeaders(302, "Found", 
responseHeaders, null, 0);
                                return;
@@ -129,7 +129,7 @@

                        String pass = request.getPartAsString("formPassword", 
32);
                        if ((pass.length() == 0) || 
!pass.equals(core.formPassword)) {
-                               MultiValueTable headers = new MultiValueTable();
+                               MultiValueTable<String, String> headers = new 
MultiValueTable<String, String>();
                                headers.put("Location", "/queue/");
                                ctx.sendReplyHeaders(302, "Found", headers, 
null, 0);
                                if(logMINOR) Logger.minor(this, "No 
formPassword: "+pass);
@@ -425,7 +425,7 @@
                                                                                
if ((System.currentTimeMillis() - forceDownloadTime) > 60 * 1000) {
                                                                                
        break loop;
                                                                                
}
-                                                                               
MultiValueTable responseHeaders = new MultiValueTable();
+                                                                               
MultiValueTable<String, String> responseHeaders = new MultiValueTable<String, 
String>();
                                                                                
responseHeaders.put("Content-Disposition", "attachment; filename=\"" + 
clientGet.getURI().getPreferredFilename() + '"');
                                                                                
writeReply(ctx, 200, "application/x-msdownload", "OK", responseHeaders, 
dataBucket);
                                                                                
return;
@@ -854,7 +854,7 @@

                contentNode.addChild(createBulkDownloadForm(ctx, pageMaker));

-               MultiValueTable pageHeaders = new MultiValueTable();
+               MultiValueTable<String, String> pageHeaders = new 
MultiValueTable<String, String>();
                writeHTMLReply(ctx, 200, "OK", pageHeaders, 
pageNode.generate());
        }


Modified: trunk/freenet/src/freenet/clients/http/Toadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/Toadlet.java 2008-10-02 11:30:51 UTC 
(rev 22908)
+++ trunk/freenet/src/freenet/clients/http/Toadlet.java 2008-10-02 11:31:29 UTC 
(rev 22909)
@@ -72,7 +72,7 @@
                infobox.addChild("div", "class", "infobox-header", 
l10n("notSupportedTitle"));
                infobox.addChild("div", "class", "infobox-content", 
l10n("notSupportedWithClass", "class", getClass().getName()));

-               MultiValueTable hdrtbl = new MultiValueTable();
+               MultiValueTable<String, String> hdrtbl = new 
MultiValueTable<String, String>();
                hdrtbl.put("Allow", this.supportedMethods());

                StringBuilder pageBuffer = new StringBuilder();
@@ -131,7 +131,7 @@
                writeReply(ctx, code, mimeType, desc, null, data);
        }

-       protected void writeReply(ToadletContext context, int code, String 
mimeType, String desc, MultiValueTable headers, Bucket data) throws 
ToadletContextClosedException, IOException {
+       protected void writeReply(ToadletContext context, int code, String 
mimeType, String desc, MultiValueTable<String, String> headers, Bucket data) 
throws ToadletContextClosedException, IOException {
                context.sendReplyHeaders(code, desc, headers, mimeType, 
data.size());
                context.writeData(data);
        }
@@ -148,26 +148,26 @@
                writeReply(ctx, code, "text/plain; charset=utf-8", desc, null, 
reply);
        }

-       protected void writeHTMLReply(ToadletContext ctx, int code, String 
desc, MultiValueTable headers, String reply) throws 
ToadletContextClosedException, IOException {
+       protected void writeHTMLReply(ToadletContext ctx, int code, String 
desc, MultiValueTable<String, String> headers, String reply) throws 
ToadletContextClosedException, IOException {
                writeReply(ctx, code, "text/html; charset=utf-8", desc, 
headers, reply);
        }

-       protected void writeTextReply(ToadletContext ctx, int code, String 
desc, MultiValueTable headers, String reply) throws 
ToadletContextClosedException, IOException {
+       protected void writeTextReply(ToadletContext ctx, int code, String 
desc, MultiValueTable<String, String> headers, String reply) throws 
ToadletContextClosedException, IOException {
                writeReply(ctx, code, "text/plain; charset=utf-8", desc, 
headers, reply);
        }

-       protected void writeReply(ToadletContext context, int code, String 
mimeType, String desc, MultiValueTable headers, String reply) throws 
ToadletContextClosedException, IOException {
+       protected void writeReply(ToadletContext context, int code, String 
mimeType, String desc, MultiValueTable<String, String> headers, String reply) 
throws ToadletContextClosedException, IOException {
                byte[] buffer = reply.getBytes("UTF-8");
                writeReply(context, code, mimeType, desc, headers, buffer, 0, 
buffer.length);
        }

-       protected void writeReply(ToadletContext context, int code, String 
mimeType, String desc, MultiValueTable headers, byte[] buffer, int startIndex, 
int length) throws ToadletContextClosedException, IOException {
+       protected void writeReply(ToadletContext context, int code, String 
mimeType, String desc, MultiValueTable<String, String> headers, byte[] buffer, 
int startIndex, int length) throws ToadletContextClosedException, IOException {
                context.sendReplyHeaders(code, desc, headers, mimeType, length);
                context.writeData(buffer, startIndex, length);
        }

        static void writePermanentRedirect(ToadletContext ctx, String msg, 
String location) throws ToadletContextClosedException, IOException {
-               MultiValueTable mvt = new MultiValueTable();
+               MultiValueTable<String, String> mvt = new 
MultiValueTable<String, String>();
                mvt.put("Location", location);
                if(msg == null) msg = "";
                else msg = HTMLEncoder.encode(msg);
@@ -186,7 +186,7 @@
        }

        protected void writeTemporaryRedirect(ToadletContext ctx, String msg, 
String location) throws ToadletContextClosedException, IOException {
-               MultiValueTable mvt = new MultiValueTable();
+               MultiValueTable<String, String> mvt = new 
MultiValueTable<String, String>();
                mvt.put("Location", location);
                if(msg == null) msg = "";
                else msg = HTMLEncoder.encode(msg);

Modified: trunk/freenet/src/freenet/clients/http/ToadletContext.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/ToadletContext.java  2008-10-02 
11:30:51 UTC (rev 22908)
+++ trunk/freenet/src/freenet/clients/http/ToadletContext.java  2008-10-02 
11:31:29 UTC (rev 22909)
@@ -23,9 +23,9 @@
         * @param length The length of the reply.
         * @param mTime The modification time of the data being sent or null 
for 'now' and disabling caching
         */
-       void sendReplyHeaders(int code, String desc, MultiValueTable mvt, 
String mimeType, long length, Date mTime) throws ToadletContextClosedException, 
IOException;
+       void sendReplyHeaders(int code, String desc, 
MultiValueTable<String,String> mvt, String mimeType, long length, Date mTime) 
throws ToadletContextClosedException, IOException;

-       void sendReplyHeaders(int code, String desc, MultiValueTable mvt, 
String mimeType, long length) throws ToadletContextClosedException, IOException;
+       void sendReplyHeaders(int code, String desc, 
MultiValueTable<String,String> mvt, String mimeType, long length) throws 
ToadletContextClosedException, IOException;

        /**
         * Write data. Note you must send reply headers first.
@@ -63,7 +63,7 @@

        BucketFactory getBucketFactory();

-       MultiValueTable getHeaders();
+       MultiValueTable<String, String> getHeaders();

        /**
         * Add a form node to an HTMLNode under construction. This will have 
the correct enctype and 

Modified: trunk/freenet/src/freenet/clients/http/ToadletContextImpl.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/ToadletContextImpl.java      
2008-10-02 11:30:51 UTC (rev 22908)
+++ trunk/freenet/src/freenet/clients/http/ToadletContextImpl.java      
2008-10-02 11:31:29 UTC (rev 22909)
@@ -38,7 +38,7 @@
  */
 public class ToadletContextImpl implements ToadletContext {

-       private final MultiValueTable headers;
+       private final MultiValueTable<String,String> headers;
        private final OutputStream sockOutputStream;
        private final PageMaker pagemaker;
        private final BucketFactory bf;
@@ -52,7 +52,7 @@
        private boolean closed;
        private boolean shouldDisconnect;

-       public ToadletContextImpl(Socket sock, MultiValueTable headers, 
BucketFactory bf, PageMaker pageMaker, ToadletContainer container) throws 
IOException {
+       public ToadletContextImpl(Socket sock, MultiValueTable<String,String> 
headers, BucketFactory bf, PageMaker pageMaker, ToadletContainer container) 
throws IOException {
                this.headers = headers;
                this.closed = false;
                sockOutputStream = sock.getOutputStream();
@@ -70,7 +70,7 @@

        private void sendMethodNotAllowed(String method, boolean 
shouldDisconnect) throws ToadletContextClosedException, IOException {
                if(closed) throw new ToadletContextClosedException();
-               MultiValueTable mvt = new MultiValueTable();
+               MultiValueTable<String,String> mvt = new 
MultiValueTable<String,String>();
                mvt.put("Allow", "GET, PUT");
                sendError(sockOutputStream, 405, "Method Not Allowed", 
l10n("methodNotAllowed"), shouldDisconnect, mvt);
        }
@@ -87,7 +87,7 @@
         * Send an error message. Caller provides the HTTP code, reason string, 
and a message, which
         * will become the title and the h1'ed contents of the error page. 
         */
-       private static void sendError(OutputStream os, int code, String 
httpReason, String message, boolean shouldDisconnect, MultiValueTable mvt) 
throws IOException {
+       private static void sendError(OutputStream os, int code, String 
httpReason, String message, boolean shouldDisconnect, 
MultiValueTable<String,String> mvt) throws IOException {
                sendHTMLError(os, code, httpReason, 
"<html><head><title>"+message+"</title></head><body><h1>"+message+"</h1></body>",
 shouldDisconnect, mvt);
        }

@@ -102,8 +102,8 @@
         * @param mvt Any additional headers.
         * @throws IOException If we could not send the error message.
         */
-       private static void sendHTMLError(OutputStream os, int code, String 
httpReason, String htmlMessage, boolean disconnect, MultiValueTable mvt) throws 
IOException {
-               if(mvt == null) mvt = new MultiValueTable();
+       private static void sendHTMLError(OutputStream os, int code, String 
httpReason, String htmlMessage, boolean disconnect, 
MultiValueTable<String,String> mvt) throws IOException {
+               if(mvt == null) mvt = new MultiValueTable<String,String>();
                byte[] messageBytes = htmlMessage.getBytes("UTF-8");
                sendReplyHeaders(os, code, httpReason, mvt, "text/html; 
charset=UTF-8", messageBytes.length, null, disconnect);
                os.write(messageBytes);
@@ -123,11 +123,11 @@
                sendHTMLError(os, 400, "Bad Request", message, 
shouldDisconnect, null);
        }

-       public void sendReplyHeaders(int replyCode, String replyDescription, 
MultiValueTable mvt, String mimeType, long contentLength) throws 
ToadletContextClosedException, IOException {
+       public void sendReplyHeaders(int replyCode, String replyDescription, 
MultiValueTable<String,String> mvt, String mimeType, long contentLength) throws 
ToadletContextClosedException, IOException {
                sendReplyHeaders(replyCode, replyDescription, mvt, mimeType, 
contentLength, null);
        }

-       public void sendReplyHeaders(int replyCode, String replyDescription, 
MultiValueTable mvt, String mimeType, long contentLength, Date mTime) throws 
ToadletContextClosedException, IOException {
+       public void sendReplyHeaders(int replyCode, String replyDescription, 
MultiValueTable<String,String> mvt, String mimeType, long contentLength, Date 
mTime) throws ToadletContextClosedException, IOException {
                if(closed) throw new ToadletContextClosedException();
                if(sentReplyHeaders) {
                        throw new IllegalStateException("Already sent 
headers!");
@@ -140,14 +140,14 @@
                return pagemaker;
        }

-       public MultiValueTable getHeaders() {
+       public MultiValueTable<String,String> getHeaders() {
                return headers;
        }

-       static void sendReplyHeaders(OutputStream sockOutputStream, int 
replyCode, String replyDescription, MultiValueTable mvt, String mimeType, long 
contentLength, Date mTime, boolean disconnect) throws IOException {
+       static void sendReplyHeaders(OutputStream sockOutputStream, int 
replyCode, String replyDescription, MultiValueTable<String,String> mvt, String 
mimeType, long contentLength, Date mTime, boolean disconnect) throws 
IOException {
                // Construct headers
                if(mvt == null)
-                       mvt = new MultiValueTable();
+                       mvt = new MultiValueTable<String,String>();
                if(mimeType != null)
                        if(mimeType.equalsIgnoreCase("text/html")){
                                mvt.put("content-type", mimeType+"; 
charset=UTF-8");
@@ -190,8 +190,8 @@
                buf.append(' ');
                buf.append(replyDescription);
                buf.append("\r\n");
-               for(Enumeration e = mvt.keys();e.hasMoreElements();) {
-                       String key = (String) e.nextElement();
+               for(Enumeration<String> e = mvt.keys();e.hasMoreElements();) {
+                       String key = e.nextElement();
                        Object[] list = mvt.getArray(key);
                        key = fixKey(key);
                        for(int i=0;i<list.length;i++) {
@@ -276,7 +276,7 @@

                                String method = split[0];

-                               MultiValueTable headers = new MultiValueTable();
+                               MultiValueTable<String,String> headers = new 
MultiValueTable<String,String>();

                                while(true) {
                                        String line = lis.readLine(32768, 128, 
false); // ISO-8859 or US-ASCII, not UTF-8
@@ -312,7 +312,7 @@
                                Bucket data;

                                if(method.equals("POST")) {
-                                       String slen = (String) 
headers.get("content-length");
+                                       String slen = 
headers.get("content-length");
                                        if(slen == null) {
                                                
sendError(sock.getOutputStream(), 400, "Bad Request", 
l10n("noContentLengthInPOST"), true, null);
                                                return;
@@ -411,8 +411,8 @@
         * @param headers Client headers.
         * @return True if the connection should be closed.
         */
-       private static boolean shouldDisconnectAfterHandled(boolean isHTTP10, 
MultiValueTable headers) {
-               String connection = (String) headers.get("connection");
+       private static boolean shouldDisconnectAfterHandled(boolean isHTTP10, 
MultiValueTable<String,String> headers) {
+               String connection = headers.get("connection");
                if(connection != null) {
                        if(connection.equalsIgnoreCase("close"))
                                return true;

Modified: trunk/freenet/src/freenet/clients/http/TranslationToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/TranslationToadlet.java      
2008-10-02 11:30:51 UTC (rev 22908)
+++ trunk/freenet/src/freenet/clients/http/TranslationToadlet.java      
2008-10-02 11:31:29 UTC (rev 22909)
@@ -49,7 +49,7 @@
                                return;
                        }
                        byte[] data = sfs.toOrderedString().getBytes("UTF-8");
-                       MultiValueTable head = new MultiValueTable();
+                       MultiValueTable<String, String> head = new 
MultiValueTable<String, String>();
                        head.put("Content-Disposition", "attachment; 
filename=\"" + L10n.getSelectedLanguage().l10nOverrideFilename+ '"');
                        ctx.sendReplyHeaders(200, "Found", head, "text/plain; 
charset=utf-8", data.length);
                        ctx.writeData(data);
@@ -244,7 +244,7 @@
        }

        private void redirectTo(ToadletContext ctx, String target) throws 
ToadletContextClosedException, IOException {
-               MultiValueTable headers = new MultiValueTable();
+               MultiValueTable<String, String> headers = new 
MultiValueTable<String, String>();
                headers.put("Location", target);
                ctx.sendReplyHeaders(302, "Found", headers, null, 0);
                return;

Modified: trunk/freenet/src/freenet/clients/http/WelcomeToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/WelcomeToadlet.java  2008-10-02 
11:30:51 UTC (rev 22908)
+++ trunk/freenet/src/freenet/clients/http/WelcomeToadlet.java  2008-10-02 
11:31:29 UTC (rev 22909)
@@ -51,7 +51,7 @@
     }

     void redirectToRoot(ToadletContext ctx) throws 
ToadletContextClosedException, IOException {
-        MultiValueTable headers = new MultiValueTable();
+        MultiValueTable<String, String> headers = new MultiValueTable<String, 
String>();
         headers.put("Location", "/");
         ctx.sendReplyHeaders(302, "Found", headers, null, 0);
         return;
@@ -122,7 +122,7 @@
                 redirectToRoot(ctx);
                 return;
             }
-            MultiValueTable headers = new MultiValueTable();
+            MultiValueTable<String, String> headers = new 
MultiValueTable<String, String>();
             String url = null;
             if ((request.getPartAsString("Go", 32).length() > 0)) {
                 url = 
request.getPartAsString(GenericReadFilterCallback.magicHTTPEscapeString, 
MAX_URL_LENGTH);
@@ -355,7 +355,7 @@
                 redirectToRoot(ctx);
                 return;
             }
-            MultiValueTable headers = new MultiValueTable();
+            MultiValueTable<String, String> headers = new 
MultiValueTable<String, String>();
             headers.put("Location", "/?terminated&formPassword=" + 
core.formPassword);
             ctx.sendReplyHeaders(302, "Found", headers, null, 0);
             node.ps.queueTimedJob(new Runnable() {
@@ -371,7 +371,7 @@
                 return;
             }

-            MultiValueTable headers = new MultiValueTable();
+            MultiValueTable<String, String> headers = new 
MultiValueTable<String, String>();
             headers.put("Location", "/?restarted&formPassword=" + 
core.formPassword);
             ctx.sendReplyHeaders(302, "Found", headers, null, 0);
             node.ps.queueTimedJob(new Runnable() {

Modified: trunk/freenet/test/freenet/support/MultiValueTableTest.java
===================================================================
--- trunk/freenet/test/freenet/support/MultiValueTableTest.java 2008-10-02 
11:30:51 UTC (rev 22908)
+++ trunk/freenet/test/freenet/support/MultiValueTableTest.java 2008-10-02 
11:31:29 UTC (rev 22909)
@@ -77,7 +77,7 @@
         * @param isRandom true if the maxValueNumber is an upper bound, false 
if it is the actual value
         * @return the sample MultiValueTable created
         */
-       private MultiValueTable createSampleMultiValueTable(int keyNumber, int 
maxValueNumber, boolean isRandom) {
+       private MultiValueTable<Object, Object> createSampleMultiValueTable(int 
keyNumber, int maxValueNumber, boolean isRandom) {
                Object[][] sampleObjects = 
createSampleKeyMultiVal(keyNumber,maxValueNumber,isRandom);
                return fillMultiValueTable(sampleObjects);
        }
@@ -87,7 +87,7 @@
         * @param anEnumeration
         * @return the number of present objects
         */
-       private int enumerationSize(Enumeration anEnumeration) {
+       private int enumerationSize(Enumeration<Object> anEnumeration) {
                int counter = 0;
                while(anEnumeration.hasMoreElements()) {
                        anEnumeration.nextElement();
@@ -102,11 +102,12 @@
         * @param sampleObjects Object[][] array, with [i][0] as key and [i][1] 
as list of values
         * @return the created MultiValueTable
         */
-       private MultiValueTable fillMultiValueTable(Object[][] sampleObjects) {
-               MultiValueTable methodMVTable = new MultiValueTable();
-               Iterator itr;
+       @SuppressWarnings("unchecked")
+    private MultiValueTable<Object, Object> fillMultiValueTable(Object[][] 
sampleObjects) {
+               MultiValueTable<Object, Object> methodMVTable = new 
MultiValueTable<Object, Object>();
+               Iterator<Object> itr;
                for(int i=0;i<sampleKeyNumber;i++) {
-                       itr = ((List)(sampleObjects[i][1])).iterator();
+                       itr = ((List<Object>)(sampleObjects[i][1])).iterator();
                        while( itr.hasNext())
                                methodMVTable.put(sampleObjects[i][0], 
itr.next());
                }
@@ -127,14 +128,15 @@
         * Tests get(Object) method with both
         * present keys and not present
         */
-       public void testGet() {
-               MultiValueTable methodMVTable = new MultiValueTable();
+       @SuppressWarnings("unchecked")
+    public void testGet() {
+               MultiValueTable<Object, Object> methodMVTable = new 
MultiValueTable<Object, Object>();
                assertNull(methodMVTable.get(new Object()));
                Object[][] sampleObjects = 
                        
createSampleKeyMultiVal(sampleKeyNumber,sampleMaxValueNumber,sampleIsRandom);
                methodMVTable = fillMultiValueTable(sampleObjects);
                for(int i=0;i<sampleObjects.length;i++)
-                       
assertEquals(methodMVTable.get(sampleObjects[i][0]),((List)sampleObjects[i][1]).get(0));
+                       
assertEquals(methodMVTable.get(sampleObjects[i][0]),((List<Object>)sampleObjects[i][1]).get(0));
        }

        /**
@@ -144,7 +146,7 @@
         * MultiValueTable and not present keys, too.
         */
        public void testContainsKey() {
-               MultiValueTable methodMVTable = new MultiValueTable();
+               MultiValueTable<Object, Object> methodMVTable = new 
MultiValueTable<Object, Object>();
                assertFalse(methodMVTable.containsKey(new Object()));
                Object[][] sampleObjects = 
                        
createSampleKeyMultiVal(sampleKeyNumber,sampleMaxValueNumber,sampleIsRandom);
@@ -161,15 +163,16 @@
         * It verifies the correct behavior with empty
         * MultiValueTable and not present Elements, too.
         */
-       public void testContainsElement() {
-               MultiValueTable methodMVTable = new MultiValueTable();
+       @SuppressWarnings("unchecked")
+    public void testContainsElement() {
+               MultiValueTable<Object, Object> methodMVTable = new 
MultiValueTable<Object, Object>();
                assertFalse(methodMVTable.containsElement(new Object(),new 
Object()));
                Object[][] sampleObjects = 
                        
createSampleKeyMultiVal(sampleKeyNumber,sampleMaxValueNumber,sampleIsRandom);
                methodMVTable = fillMultiValueTable(sampleObjects);
-               Iterator iter;
+               Iterator<Object> iter;
                for(int i=0;i<sampleObjects.length;i++) {
-                       iter = ((List)(sampleObjects[i][1])).iterator();
+                       iter = ((List<Object>)(sampleObjects[i][1])).iterator();
                        
assertFalse(methodMVTable.containsElement(sampleObjects[i][0],new Object()));
                        while(iter.hasNext())
                                
assertTrue(methodMVTable.containsElement(sampleObjects[i][0],iter.next()));
@@ -179,17 +182,18 @@
        /**
         * Tests getAll() method
         */
-       public void testGetAll() {
-               MultiValueTable methodMVTable = new MultiValueTable();
+       @SuppressWarnings("unchecked")
+    public void testGetAll() {
+               MultiValueTable<Object, Object> methodMVTable = new 
MultiValueTable<Object, Object>();
                //TODO: verifies if an Exception is necessary
                methodMVTable.getAll(new Object());
                Object[][] sampleObjects = 
                        
createSampleKeyMultiVal(sampleKeyNumber,sampleMaxValueNumber,sampleIsRandom);
                methodMVTable = fillMultiValueTable(sampleObjects);
-               Iterator iter;
-               Enumeration methodEnumeration;
+               Iterator<Object> iter;
+               Enumeration<Object> methodEnumeration;
                for(int i=0;i<sampleObjects.length;i++) {
-                       iter = ((List)(sampleObjects[i][1])).iterator();
+                       iter = ((List<Object>)(sampleObjects[i][1])).iterator();
                        methodEnumeration = 
methodMVTable.getAll(sampleObjects[i][0]);
                        while(iter.hasNext())
                                
assertEquals(methodEnumeration.nextElement(),iter.next());
@@ -199,42 +203,45 @@
        /**
         * Tests countAll() method
         */
-       public void testCountAll() {
-               MultiValueTable methodMVTable = new MultiValueTable();
+       @SuppressWarnings("unchecked")
+    public void testCountAll() {
+               MultiValueTable<Object, Object> methodMVTable = new 
MultiValueTable<Object, Object>();
                assertEquals(methodMVTable.countAll(new Object()),0);
                Object[][] sampleObjects = 
                        
createSampleKeyMultiVal(sampleKeyNumber,sampleMaxValueNumber,sampleIsRandom);
                methodMVTable = fillMultiValueTable(sampleObjects);
                for(int i=0;i<sampleObjects.length;i++)
-                       
assertEquals(((List)(sampleObjects[i][1])).size(),methodMVTable.countAll(sampleObjects[i][0]));
+                       
assertEquals(((List<Object>)(sampleObjects[i][1])).size(),methodMVTable.countAll(sampleObjects[i][0]));
        }

        /**
         * Tests getSync(Object) method fetching
         * both present and not present keys
         */
-       public void testGetSync() {
-               MultiValueTable methodMVTable = new MultiValueTable();
+       @SuppressWarnings({ "cast", "unchecked" })
+    public void testGetSync() {
+               MultiValueTable<Object, Object> methodMVTable = new 
MultiValueTable<Object, Object>();
                assertNull(methodMVTable.getSync(new Object()));
                Object[][] sampleObjects = 
                        
createSampleKeyMultiVal(sampleKeyNumber,sampleMaxValueNumber,sampleIsRandom);
                methodMVTable = fillMultiValueTable(sampleObjects);
                for(int i=0;i<sampleObjects.length;i++)
-                       
assertEquals(methodMVTable.getSync(sampleObjects[i][0]),((List)sampleObjects[i][1]));
+                       
assertEquals(methodMVTable.getSync(sampleObjects[i][0]),((List<Object>)sampleObjects[i][1]));
        }

        /**
         * Tests getArray(Object) method both
         * with a present key and a not present key
         */
-       public void testGetArray() {
-               MultiValueTable methodMVTable = new MultiValueTable();
+       @SuppressWarnings("unchecked")
+    public void testGetArray() {
+               MultiValueTable<Object, Object> methodMVTable = new 
MultiValueTable<Object, Object>();
                assertNull(methodMVTable.getArray(new Object()));
                Object[][] sampleObjects = 
                        
createSampleKeyMultiVal(sampleKeyNumber,sampleMaxValueNumber,sampleIsRandom);
                methodMVTable = fillMultiValueTable(sampleObjects);
                for(int i=0;i<sampleObjects.length;i++)
-                       
assertTrue(Arrays.equals(((List)(sampleObjects[i][1])).toArray(),methodMVTable.getArray(sampleObjects[i][0])));
+                       
assertTrue(Arrays.equals(((List<Object>)(sampleObjects[i][1])).toArray(),methodMVTable.getArray(sampleObjects[i][0])));
        }

        /**
@@ -244,7 +251,7 @@
         * key, too.
         */
        public void testRemove() {
-               MultiValueTable methodMVTable = new MultiValueTable();
+               MultiValueTable<Object, Object> methodMVTable = new 
MultiValueTable<Object, Object>();
                //TODO: shouldn't it raise an exception?
                methodMVTable.remove(new Object());
                Object[][] sampleObjects = 
@@ -260,7 +267,7 @@
         * after putting objects and after removing all of them.
         */
        public void testIsEmpty() {
-               MultiValueTable methodMVTable = new MultiValueTable();
+               MultiValueTable<Object, Object> methodMVTable = new 
MultiValueTable<Object, Object>();
                assertTrue(methodMVTable.isEmpty());
                Object[][] sampleObjects = 
                        
createSampleKeyMultiVal(sampleKeyNumber,sampleMaxValueNumber,sampleIsRandom);
@@ -279,7 +286,7 @@
        public void testClear() {
                Object[][] sampleObjects = 
                        
createSampleKeyMultiVal(sampleKeyNumber,sampleMaxValueNumber,sampleIsRandom);
-               MultiValueTable methodMVTable = 
fillMultiValueTable(sampleObjects);
+               MultiValueTable<Object, Object> methodMVTable = 
fillMultiValueTable(sampleObjects);
                methodMVTable.clear();
                for(int i=0;i<sampleObjects.length;i++)
                        
assertFalse(methodMVTable.containsKey(sampleObjects[i][0]));
@@ -291,14 +298,15 @@
         * a sample MultiValueTable, and verifying if they are correctly
         * removed and if the result of isEmpty() method is correct.
         */
-       public void testRemoveElement() {
+       @SuppressWarnings("unchecked")
+    public void testRemoveElement() {
                Object[][] sampleObjects = 
                        
createSampleKeyMultiVal(sampleKeyNumber,sampleMaxValueNumber,sampleIsRandom);
-               MultiValueTable methodMVTable = 
fillMultiValueTable(sampleObjects);
+               MultiValueTable<Object, Object> methodMVTable = 
fillMultiValueTable(sampleObjects);
                Object methodValue;
-               Iterator iter;
+               Iterator<Object> iter;
                for(int i=0;i<sampleObjects.length;i++) {
-                       iter = ((List)(sampleObjects[i][1])).iterator();
+                       iter = ((List<Object>)(sampleObjects[i][1])).iterator();
                        
assertFalse(methodMVTable.removeElement(sampleObjects[i][0],new Object()));
                        while(iter.hasNext()) {
                                methodValue = iter.next();
@@ -316,10 +324,10 @@
        public void testKeys() {
                Object[][] sampleObjects = 
                        
createSampleKeyMultiVal(sampleKeyNumber,sampleMaxValueNumber,sampleIsRandom);
-               MultiValueTable methodMVTable = 
fillMultiValueTable(sampleObjects);
+               MultiValueTable<Object, Object> methodMVTable = 
fillMultiValueTable(sampleObjects);
                //TODO: shouldn't it respect keys order?
                int j = sampleObjects.length-1;
-               Enumeration methodEnumeration = methodMVTable.keys();
+               Enumeration<Object> methodEnumeration = methodMVTable.keys();
                while(methodEnumeration.hasMoreElements()) {
                        
assertEquals(sampleObjects[j][0],methodEnumeration.nextElement());
                        j--;}
@@ -332,7 +340,7 @@
         */
        public void testDifferentKeysSameElement() {
                int keysNumber = 2;
-               MultiValueTable methodMVTable = new MultiValueTable();
+               MultiValueTable<Object, Object> methodMVTable = new 
MultiValueTable<Object, Object>();
                String sampleValue = "sampleValue";
                //putting the same value for different keys
                for(int i=0;i<keysNumber;i++)


Reply via email to