gt: 		HTMLNode legendRow = legendTable.addChild("tr");
context: /* This code is part of Freenet. It is distributed under the GNU General
   * Public License, version 2 (or at your option any later version). See
   * http://www.gnu.org/ for further details of the GPL. */
  package freenet.clients.http;
  
  import java.io.IOException;
  import java.net.URI;
  import java.util.ArrayList;
  
  import freenet.client.HighLevelSimpleClient;
  import freenet.l10n.BaseL10n;
  import freenet.l10n.NodeL10n;
  import freenet.l10n.PluginL10n;
  import freenet.node.NodeClientCore;
  import freenet.pluginmanager.FredPluginBaseL10n;
  import freenet.pluginmanager.PluginInfoWrapper;
  import freenet.support.HTMLNode;
  import freenet.support.Logger;
  import freenet.support.MultiValueTable;
  import freenet.support.SimpleFieldSet;
  import freenet.support.Logger.LogLevel;
  import freenet.support.SimpleFieldSet.KeyIterator;
  import freenet.support.api.HTTPRequest;
  import freenet.support.io.BucketTools;
  
  /**
   * A toadlet dedicated to translations ... and easing the work of translators
   * 
   * @author Florent Daigni&egrave;re &lt;nextgens@freenetproject.org&gt;
   * @author Artefact2
   */
  public class TranslationToadlet extends Toadlet {
  	public static final String TOADLET_URL = "/translation/";
  	private final NodeClientCore core;
  	private BaseL10n base;
  	private String translatingFor;
  
  	TranslationToadlet(HighLevelSimpleClient client, NodeClientCore core) {
  		super(client);
  		this.core = core;
  		this.base = NodeL10n.getBase();
  		this.translatingFor = "Node";
  	}
  
  	public void handleMethodGET(URI uri, HTTPRequest request, ToadletContext ctx) throws ToadletContextClosedException, IOException {
  		if(!ctx.isAllowedFullAccess()) {
  			super.sendErrorPage(ctx, 403, "Unauthorized", NodeL10n.getBase().getString("Toadlet.unauthorized"));
  			return;
  		}
  		
  		boolean showEverything = !request.isParameterSet("toTranslateOnly");
  		
  		
  		if (request.isParameterSet("getOverrideTranlationFile")) {
  			SimpleFieldSet sfs = this.base.getOverrideForCurrentLanguageTranslation();
  			if(sfs == null) {
  				super.sendErrorPage(ctx, 503 /* Service Unavailable */, "Service Unavailable", l10n("noCustomTranslations"));
  				return;
  			}
  			byte[] data = sfs.toOrderedString().getBytes("UTF-8");
  			MultiValueTable<String, String> head = new MultiValueTable<String, String>();
  			head.put("Content-Disposition", "attachment; filename=\"" + this.base.getL10nOverrideFileName(this.base.getSelectedLanguage()) + '"');
  			ctx.sendReplyHeaders(200, "Found", head, "text/plain; charset=utf-8", data.length);
  			ctx.writeData(data);
  			return;
  		} else if (request.isParameterSet("translation_updated")) {
  			String key = request.getParam("translation_updated");
  			PageNode page = ctx.getPageMaker().getPageNode(l10n("translationUpdatedTitle"), ctx);
  			HTMLNode pageNode = page.outer;
  			HTMLNode contentNode = page.content;
  
  			HTMLNode translationNode = contentNode.addChild("div", "class", "translation");
  			HTMLNode legendTable = translationNode.addChild("table", "class", "translation");
  			
  			HTMLNode legendRow = legendTable.addChild("tr").addChild("b");
  			legendRow.addChild("td", "class", "translation-key", l10n("translationKeyLabel"));
  			legendRow.addChild("td", "class", "translation-key", l10n("originalVersionLabel"));
  			legendRow.addChild("td", "class", "translation-key", l10n("currentTranslationLabel"));
  			
  			HTMLNode contentRow = legendTable.addChild("tr");
  			contentRow.addChild("td", "class", "translation-key",
  					key
  			);
  			contentRow.addChild("td", "class", "translation-orig",
  					this.base.getDefaultString(key)
  			);
  			contentRow.addChild("td", "class", "translation-new",
  					this.base.getString(key)
  			);
  			
  			HTMLNode footer = translationNode.addChild("div", "class", "warning");
  			footer.addChild("a", "href", TOADLET_URL+"?getOverrideTranlationFile").addChild("#", l10n("downloadTranslationsFile"));
  			footer.addChild("%", "&nbsp;&nbsp;");
  			footer.addChild("a", "href", TOADLET_URL+"?translate="+key+ (showEverything ? "" : "&toTranslateOnly")).addChild("#", l10n("reEdit"));
  			footer.addChild("%", "&nbsp;&nbsp;");
  			footer.addChild("a", "href", TOADLET_URL + (showEverything ? "" : "?toTranslateOnly")).addChild("#", l10n("returnToTranslations"));
  
  			this.writeHTMLReply(ctx, 200, "OK", pageNode.generate());
  			return;				
  		} else if (request.isParameterSet("translate")) {
  			boolean gotoNext = request.isParameterSet("gotoNext");
  			String key = request.getParam("translate");
  			PageNode page = ctx.getPageMaker().getPageNode(l10n("translationUpdateTitle"), ctx);
  			HTMLNode pageNode = page.outer;
  			HTMLNode contentNode = page.content;
  
  			HTMLNode translationNode = contentNode.addChild("div", "class", "translation");
  			HTMLNode updateForm =  ctx.addFormChild(translationNode, TOADLET_URL, "trans_update");
  			HTMLNode legendTable = updateForm.addChild("table", "class", "translation");
  			
  			HTMLNode legendRow = legendTable.addChild("tr");
  			legendRow.addChild("td", "class", "translation-key", l10n("translationKeyLabel"));
  			legendRow.addChild("td", "class", "translation-key", l10n("originalVersionLabel"));
  			legendRow.addChild("td", "class", "translation-key", l10n("currentTranslationLabel"));
  			
  			HTMLNode contentRow = legendTable.addChild("tr");
  			contentRow.addChild("td", "class", "translation-key",
  					key
  			);
  			contentRow.addChild("td", "class", "translation-orig",
  					this.base.getDefaultString(key)
  			);
  			
  			contentRow.addChild("td", "class", "translation-new").addChild(
  					"textarea",
  					new String[] { "name", "rows", "cols" },
  					new String[] { "trans", "20", "80" },
  					this.base.getString(key));
  			
  			contentRow.addChild("input", 
  					new String[] { "type", "name", "value" }, 
  					new String[] { "hidden", "key", key
  			});
  
  			updateForm.addChild("input", 
  					new String[] { "type", "name", "value" }, 
  					new String[] { "submit", "translation_update", l10n("updateTranslationCommand")
  			});
  			updateForm.addChild("input", new String[] { "type", "name" , (gotoNext ? "checked" : "unchecked") } , new String[] { "checkbox", "gotoNext", ""}, l10n("gotoNext"));
  			if(!showEverything)
  				updateForm.addChild("input", new String[] { "type", "name", "value" }, new String[] { "hidden", "toTranslateOnly", key });
  			
  			updateForm.addChild("input", new String[] { "type", "name", "value" }, new String[] { "submit", "cancel", NodeL10n.getBase().getString("Toadlet.cancel") });
  			this.writeHTMLReply(ctx, 200, "OK", pageNode.generate());
  			return;
  		} else if (request.isParameterSet("remove")) {
  			String key = request.getParam("remove");
  			PageNode page = ctx.getPageMaker().getPageNode(l10n("removeOverrideTitle"), ctx);
  			HTMLNode pageNode = page.outer;
  			HTMLNode contentNode = page.content;
  
  			HTMLNode content = ctx.getPageMaker().getInfobox("infobox-warning", l10n("removeOverrideWarningTitle"), contentNode, "translation-override", true);
  			content.addChild("p").addChild("#",
  					NodeL10n.getBase().getString("TranslationToadlet.confirmRemoveOverride", new String[] { "key", "value" },
  							new String[] { key, this.base.getString(key) }));
  			HTMLNode removeForm = ctx.addFormChild(content.addChild("p"), TOADLET_URL, "remove_confirmed");
  			if(!showEverything)
  				removeForm.addChild("input", new String[] { "type", "name", "value" }, new String[] { "hidden", "toTranslateOnly", key });
  			removeForm.addChild("input", new String[] { "type", "name", "value" }, new String[] { "hidden", "remove_confirm", key });
  			removeForm.addChild("input", new String[] { "type", "name", "value" }, new String[] { "submit", "remove_confirmed", l10n("remove") });
  			removeForm.addChild("input", new String[] { "type", "name", "value" }, new String[] { "submit", "cancel", NodeL10n.getBase().getString("Toadlet.cancel") });
  			
  			this.writeHTMLReply(ctx, 200, "OK", pageNode.generate());
  			return;
  		}
  
  		PageNode page = ctx.getPageMaker().getPageNode(l10n("translationUpdateTitle"), ctx);
  		HTMLNode pageNode = page.outer;
  		HTMLNode contentNode = page.content;
  
  		final HTMLNode translatingForBox = ctx.getPageMaker().getInfobox(null, l10n("selectTranslation"), contentNode);
  		ArrayList<String> elementsToTranslate = new ArrayList<String>();
  		elementsToTranslate.add("Node");
  		for(PluginInfoWrapper pluginInfo : this.core.node.pluginManager.getPlugins()) {
  			if(!pluginInfo.isBaseL10nPlugin()) {
  				continue;
  			}
  
  			elementsToTranslate.add(pluginInfo.getPluginClassName());
  		}
  
  		final HTMLNode translatingForForm = ctx.addFormChild(translatingForBox, TOADLET_URL, "ChooseWhatToTranslate").addChild("p", l10n("showTranslationOf"));
  		final HTMLNode translatingForOption = translatingForForm.addChild("select", "name", "translating_for");
  		for(String element : elementsToTranslate) {
  			final HTMLNode option =	translatingForOption.addChild("option", "name", element, element);
  			if(element.equals(this.translatingFor)) {
  				option.addAttribute("selected", "selected");
  			}
  		}
  		translatingForForm.addChild("input", "type", "submit");
  
  		HTMLNode translationNode = contentNode.addChild("div", "class", "translation");
  		HTMLNode translationHeaderNode = translationNode.addChild("p");
  		translationHeaderNode.addChild("#", l10n("contributingToLabelWithLang", "lang", this.base.getSelectedLanguage().fullName));
  		translationHeaderNode.addChild("a", "href", TOADLET_URL+"?getOverrideTranlationFile").addChild("#", l10n("downloadTranslationsFile"));
  		translationHeaderNode.addChild("#", " ");
  		if(showEverything)
  			translationHeaderNode.addChild("a", "href", TOADLET_URL+"?toTranslateOnly").addChild("#", l10n("hideAlreadyTranslated"));
  		else
  			translationHeaderNode.addChild("a", "href", TOADLET_URL).addChild("#", l10n("showEverything"));
  		HTMLNode legendTable = translationNode.addChild("table", "class", "translation");
  		
  