Author: toad
Date: 2008-09-24 23:54:07 +0000 (Wed, 24 Sep 2008)
New Revision: 22829

Added:
   branches/db4o/freenet/src/freenet/node/SecurityLevelListener.java
   branches/db4o/freenet/src/freenet/node/SecurityLevels.java
   branches/db4o/freenet/src/freenet/pluginmanager/FredPluginToadlet.java
   branches/db4o/freenet/src/freenet/pluginmanager/FredPluginUoF.java
   branches/db4o/freenet/src/freenet/store/saltedhash/
   branches/db4o/freenet/src/freenet/store/saltedhash/CipherManager.java
   branches/db4o/freenet/src/freenet/store/saltedhash/LockManager.java
   
branches/db4o/freenet/src/freenet/store/saltedhash/SaltedHashFreenetStore.java
   branches/db4o/freenet/test/freenet/support/BloomFilterTest.java
Removed:
   branches/db4o/freenet/src/freenet/store/saltedhash/CipherManager.java
   branches/db4o/freenet/src/freenet/store/saltedhash/LockManager.java
   
branches/db4o/freenet/src/freenet/store/saltedhash/SaltedHashFreenetStore.java
   branches/db4o/freenet/src/freenet/support/ImmutableByteArrayWrapper.java
Modified:
   branches/db4o/freenet/src/freenet/client/FailureCodeTracker.java
   branches/db4o/freenet/src/freenet/client/FetchException.java
   branches/db4o/freenet/src/freenet/client/async/ClientRequestScheduler.java
   branches/db4o/freenet/src/freenet/client/events/SplitfileProgressEvent.java
   branches/db4o/freenet/src/freenet/clients/http/ConfigToadlet.java
   branches/db4o/freenet/src/freenet/clients/http/ConnectionsToadlet.java
   branches/db4o/freenet/src/freenet/clients/http/FProxyToadlet.java
   branches/db4o/freenet/src/freenet/clients/http/FirstTimeWizardToadlet.java
   branches/db4o/freenet/src/freenet/clients/http/PageMaker.java
   branches/db4o/freenet/src/freenet/clients/http/PproxyToadlet.java
   branches/db4o/freenet/src/freenet/clients/http/StatisticsToadlet.java
   branches/db4o/freenet/src/freenet/clients/http/ToadletContextImpl.java
   branches/db4o/freenet/src/freenet/clients/http/TranslationToadlet.java
   branches/db4o/freenet/src/freenet/clients/http/WelcomeToadlet.java
   branches/db4o/freenet/src/freenet/clients/http/filter/CSSTokenizerFilter.java
   
branches/db4o/freenet/src/freenet/clients/http/filter/GenericReadFilterCallback.java
   branches/db4o/freenet/src/freenet/clients/http/filter/HTMLFilter.java
   branches/db4o/freenet/src/freenet/clients/http/filter/JPEGFilter.java
   
branches/db4o/freenet/src/freenet/clients/http/filter/KnownUnsafeContentTypeException.java
   branches/db4o/freenet/src/freenet/clients/http/filter/PNGFilter.java
   
branches/db4o/freenet/src/freenet/clients/http/staticfiles/defaultbookmarks.dat
   branches/db4o/freenet/src/freenet/config/Config.java
   branches/db4o/freenet/src/freenet/config/InvalidConfigValueException.java
   branches/db4o/freenet/src/freenet/config/NodeNeedRestartException.java
   branches/db4o/freenet/src/freenet/config/PersistentConfig.java
   branches/db4o/freenet/src/freenet/crypt/CryptoKey.java
   branches/db4o/freenet/src/freenet/crypt/DHGroup.java
   branches/db4o/freenet/src/freenet/crypt/DiffieHellman.java
   branches/db4o/freenet/src/freenet/crypt/DiffieHellmanLightContext.java
   branches/db4o/freenet/src/freenet/crypt/SHA1.java
   branches/db4o/freenet/src/freenet/crypt/SSL.java
   branches/db4o/freenet/src/freenet/crypt/Util.java
   branches/db4o/freenet/src/freenet/frost/message/FrostMessage.java
   branches/db4o/freenet/src/freenet/io/AddressTracker.java
   branches/db4o/freenet/src/freenet/io/AddressTrackerItem.java
   branches/db4o/freenet/src/freenet/io/AllowedHosts.java
   branches/db4o/freenet/src/freenet/io/Inet4AddressMatcher.java
   branches/db4o/freenet/src/freenet/io/Inet6AddressMatcher.java
   branches/db4o/freenet/src/freenet/io/comm/Message.java
   branches/db4o/freenet/src/freenet/io/comm/MessageType.java
   branches/db4o/freenet/src/freenet/io/comm/UdpSocketHandler.java
   branches/db4o/freenet/src/freenet/keys/FreenetURI.java
   branches/db4o/freenet/src/freenet/l10n/freenet.l10n.de.properties
   branches/db4o/freenet/src/freenet/l10n/freenet.l10n.en.properties
   branches/db4o/freenet/src/freenet/l10n/freenet.l10n.fi.properties
   branches/db4o/freenet/src/freenet/l10n/freenet.l10n.it.properties
   branches/db4o/freenet/src/freenet/l10n/freenet.l10n.se.properties
   branches/db4o/freenet/src/freenet/l10n/freenet.l10n.zh-cn.properties
   branches/db4o/freenet/src/freenet/l10n/freenet.l10n.zh-tw.properties
   branches/db4o/freenet/src/freenet/node/Announcer.java
   branches/db4o/freenet/src/freenet/node/DarknetPeerNode.java
   branches/db4o/freenet/src/freenet/node/IPDetectorPluginManager.java
   branches/db4o/freenet/src/freenet/node/LocationManager.java
   branches/db4o/freenet/src/freenet/node/Node.java
   branches/db4o/freenet/src/freenet/node/NodeClientCore.java
   branches/db4o/freenet/src/freenet/node/NodeCryptoConfig.java
   branches/db4o/freenet/src/freenet/node/NodeDispatcher.java
   branches/db4o/freenet/src/freenet/node/NodeIPDetector.java
   branches/db4o/freenet/src/freenet/node/NodeIPPortDetector.java
   branches/db4o/freenet/src/freenet/node/NodeStarter.java
   branches/db4o/freenet/src/freenet/node/NodeStats.java
   branches/db4o/freenet/src/freenet/node/OpennetManager.java
   branches/db4o/freenet/src/freenet/node/OpennetPeerNode.java
   branches/db4o/freenet/src/freenet/node/PeerManager.java
   branches/db4o/freenet/src/freenet/node/PeerNode.java
   branches/db4o/freenet/src/freenet/node/PeerNodeStatus.java
   branches/db4o/freenet/src/freenet/node/RequestStarterGroup.java
   branches/db4o/freenet/src/freenet/node/TextModeClientInterface.java
   branches/db4o/freenet/src/freenet/node/Version.java
   branches/db4o/freenet/src/freenet/node/fcp/AddPeer.java
   branches/db4o/freenet/src/freenet/node/fcp/FCPClient.java
   branches/db4o/freenet/src/freenet/node/fcp/FCPServer.java
   branches/db4o/freenet/src/freenet/node/simulator/BootstrapPullTest.java
   branches/db4o/freenet/src/freenet/node/simulator/BootstrapPushPullTest.java
   branches/db4o/freenet/src/freenet/node/simulator/BootstrapSeedTest.java
   branches/db4o/freenet/src/freenet/node/simulator/RealNodeBusyNetworkTest.java
   
branches/db4o/freenet/src/freenet/node/simulator/RealNodeNetworkColoringTest.java
   branches/db4o/freenet/src/freenet/node/simulator/RealNodePingTest.java
   
branches/db4o/freenet/src/freenet/node/simulator/RealNodeRequestInsertTest.java
   branches/db4o/freenet/src/freenet/node/simulator/RealNodeRoutingTest.java
   branches/db4o/freenet/src/freenet/node/simulator/RealNodeSecretPingTest.java
   branches/db4o/freenet/src/freenet/node/simulator/RealNodeULPRTest.java
   branches/db4o/freenet/src/freenet/node/simulator/SeednodePingTest.java
   branches/db4o/freenet/src/freenet/node/updater/NodeUpdater.java
   
branches/db4o/freenet/src/freenet/node/updater/UpdateOverMandatoryManager.java
   branches/db4o/freenet/src/freenet/node/useralerts/PeerManagerUserAlert.java
   
branches/db4o/freenet/src/freenet/node/useralerts/UpdatedVersionAvailableUserAlert.java
   branches/db4o/freenet/src/freenet/node/useralerts/UserAlertManager.java
   branches/db4o/freenet/src/freenet/pluginmanager/PluginManager.java
   branches/db4o/freenet/src/freenet/store/BerkeleyDBFreenetStore.java
   branches/db4o/freenet/src/freenet/store/FreenetStore.java
   branches/db4o/freenet/src/freenet/store/PubkeyStore.java
   branches/db4o/freenet/src/freenet/store/RAMFreenetStore.java
   branches/db4o/freenet/src/freenet/store/StoreCallback.java
   branches/db4o/freenet/src/freenet/support/BinaryBloomFilter.java
   branches/db4o/freenet/src/freenet/support/BitArray.java
   branches/db4o/freenet/src/freenet/support/BloomFilter.java
   branches/db4o/freenet/src/freenet/support/Buffer.java
   branches/db4o/freenet/src/freenet/support/CPUInformation/CPUID.java
   branches/db4o/freenet/src/freenet/support/CountingBloomFilter.java
   branches/db4o/freenet/src/freenet/support/Fields.java
   branches/db4o/freenet/src/freenet/support/HTMLDecoder.java
   branches/db4o/freenet/src/freenet/support/HTMLEncoder.java
   branches/db4o/freenet/src/freenet/support/HTMLEntities.java
   branches/db4o/freenet/src/freenet/support/HTMLNode.java
   branches/db4o/freenet/src/freenet/support/HexUtil.java
   branches/db4o/freenet/src/freenet/support/JarClassLoader.java
   branches/db4o/freenet/src/freenet/support/LimitedEnumeration.java
   branches/db4o/freenet/src/freenet/support/LimitedRangeIntByteArrayMap.java
   branches/db4o/freenet/src/freenet/support/Loader.java
   branches/db4o/freenet/src/freenet/support/LoggerHook.java
   branches/db4o/freenet/src/freenet/support/LoggerHookChain.java
   branches/db4o/freenet/src/freenet/support/NumberedItemComparator.java
   branches/db4o/freenet/src/freenet/support/NumberedRecentItems.java
   branches/db4o/freenet/src/freenet/support/PooledExecutor.java
   branches/db4o/freenet/src/freenet/support/ReceivedPacketNumbers.java
   branches/db4o/freenet/src/freenet/support/SerialExecutor.java
   branches/db4o/freenet/src/freenet/support/Serializer.java
   branches/db4o/freenet/src/freenet/support/ShortBuffer.java
   branches/db4o/freenet/src/freenet/support/SimpleFieldSet.java
   branches/db4o/freenet/src/freenet/support/StringCounter.java
   branches/db4o/freenet/src/freenet/support/TimeUtil.java
   branches/db4o/freenet/src/freenet/support/URIPreEncoder.java
   branches/db4o/freenet/src/freenet/support/URLDecoder.java
   branches/db4o/freenet/src/freenet/support/URLEncoder.java
   branches/db4o/freenet/src/freenet/support/VoidLogger.java
   branches/db4o/freenet/src/freenet/support/io/ArrayBucket.java
   branches/db4o/freenet/src/freenet/support/io/BaseFileBucket.java
   branches/db4o/freenet/src/freenet/support/io/BucketChainBucket.java
   branches/db4o/freenet/src/freenet/support/io/BucketTools.java
   branches/db4o/freenet/src/freenet/support/io/FileUtil.java
   branches/db4o/freenet/src/freenet/support/io/MultiReaderBucket.java
   
branches/db4o/freenet/src/freenet/support/io/PaddedEphemerallyEncryptedBucket.java
   branches/db4o/freenet/src/freenet/support/io/PersistentTempBucketFactory.java
   
branches/db4o/freenet/src/freenet/support/io/SerializableToFieldSetBucketUtil.java
   branches/db4o/freenet/src/freenet/support/io/TempBucketFactory.java
   
branches/db4o/freenet/src/freenet/support/math/SimpleBinaryRunningAverage.java
   branches/db4o/freenet/src/freenet/support/transport/ip/IPAddressDetector.java
   branches/db4o/freenet/test/DatastoreTest.java
   branches/db4o/freenet/test/PreNodeTest.java
   branches/db4o/freenet/test/PreQuasiNodeTest.java
   branches/db4o/freenet/test/QuasiNodeTest.java
   branches/db4o/freenet/test/freenet/config/ConfigTest.java
   branches/db4o/freenet/test/freenet/support/BitArrayTest.java
   branches/db4o/freenet/test/freenet/support/FieldsTest.java
   branches/db4o/freenet/test/freenet/support/HTMLEncoderDecoderTest.java
Log:
Merge 1161 into db4o branch. 22339 -> 22484.


Modified: branches/db4o/freenet/src/freenet/client/FailureCodeTracker.java
===================================================================
--- branches/db4o/freenet/src/freenet/client/FailureCodeTracker.java    
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/client/FailureCodeTracker.java    
2008-09-24 23:54:07 UTC (rev 22829)
@@ -60,14 +60,16 @@
        final HashMap map = new HashMap();

        public synchronized void inc(int k) {
-               Item i = (Item) map.get(k);
+               Integer key = k;
+               Item i = (Item) map.get(key);
                if(i == null)
-                       map.put(k, i = new Item());
+                       map.put(key, i = new Item());
                i.x++;
                total++;
        }

-       public synchronized void inc(Integer key, int val) {
+       public synchronized void inc(Integer k, int val) {
+               Integer key = k;
                Item i = (Item) map.get(key);
                if(i == null)
                        map.put(key, i = new Item());
@@ -76,7 +78,7 @@
        }

        public synchronized String toVerboseString() {
-               StringBuffer sb = new StringBuffer();
+               StringBuilder sb = new StringBuilder();
                Collection values = map.keySet();
                Iterator i = values.iterator();
                while(i.hasNext()) {
@@ -92,7 +94,7 @@
        }

        public synchronized String toString() {
-               StringBuffer sb = new StringBuffer(super.toString());
+               StringBuilder sb = new StringBuilder(super.toString());
                sb.append(':');
                if(map.size() == 0) sb.append("empty");
                else if(map.size() == 1) {

Modified: branches/db4o/freenet/src/freenet/client/FetchException.java
===================================================================
--- branches/db4o/freenet/src/freenet/client/FetchException.java        
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/client/FetchException.java        
2008-09-24 23:54:07 UTC (rev 22829)
@@ -247,7 +247,7 @@
        }

        public String toString() {
-               StringBuffer sb = new StringBuffer(200);
+               StringBuilder sb = new StringBuilder(200);
                sb.append("FetchException:");
                sb.append(getShortMessage(mode));
                sb.append(':');

Modified: 
branches/db4o/freenet/src/freenet/client/async/ClientRequestScheduler.java
===================================================================
--- branches/db4o/freenet/src/freenet/client/async/ClientRequestScheduler.java  
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/client/async/ClientRequestScheduler.java  
2008-09-24 23:54:07 UTC (rev 22829)
@@ -851,7 +851,7 @@
                short priority = Short.MAX_VALUE;
                if(force) {
                        // FIXME what priority???
-                       priority = 
RequestStarter.IMMEDIATE_SPLITFILE_PRIORITY_CLASS;
+                       priority = RequestStarter.BULK_SPLITFILE_PRIORITY_CLASS;
                }
                priority = schedTransient.getKeyPrio(key, priority, null, 
clientContext);
                if(priority < Short.MAX_VALUE) {

Modified: 
branches/db4o/freenet/src/freenet/client/events/SplitfileProgressEvent.java
===================================================================
--- branches/db4o/freenet/src/freenet/client/events/SplitfileProgressEvent.java 
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/client/events/SplitfileProgressEvent.java 
2008-09-24 23:54:07 UTC (rev 22829)
@@ -31,7 +31,7 @@
        }

        public String getDescription() {
-               StringBuffer sb = new StringBuffer();
+               StringBuilder sb = new StringBuilder();
                sb.append("Completed ");
                if((minSuccessfulBlocks == 0) && (fetchedBlocks == 0))
                        minSuccessfulBlocks = 1;

Modified: branches/db4o/freenet/src/freenet/clients/http/ConfigToadlet.java
===================================================================
--- branches/db4o/freenet/src/freenet/clients/http/ConfigToadlet.java   
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/clients/http/ConfigToadlet.java   
2008-09-24 23:54:07 UTC (rev 22829)
@@ -20,6 +20,10 @@
 import freenet.l10n.L10n;
 import freenet.node.Node;
 import freenet.node.NodeClientCore;
+import freenet.node.SecurityLevels;
+import freenet.node.SecurityLevels.FRIENDS_THREAT_LEVEL;
+import freenet.node.SecurityLevels.NETWORK_THREAT_LEVEL;
+import freenet.node.SecurityLevels.PHYSICAL_THREAT_LEVEL;
 import freenet.node.useralerts.AbstractUserAlert;
 import freenet.node.useralerts.UserAlert;
 import freenet.support.HTMLNode;
@@ -104,9 +108,6 @@

        @Override
     public void handlePost(URI uri, HTTPRequest request, ToadletContext ctx) 
throws ToadletContextClosedException, IOException {
-               StringBuffer errbuf = new StringBuffer();
-               SubConfig[] sc = config.getConfigs();
-               
                String pass = request.getPartAsString("formPassword", 32);
                if((pass == null) || !pass.equals(core.formPassword)) {
                        MultiValueTable headers = new MultiValueTable();
@@ -115,6 +116,121 @@
                        return;
                }

+               if(request.isPartSet("seclevels")) {
+                       // Handle the security level changes.
+                       
+                       HTMLNode pageNode = null;
+                       HTMLNode content = null;
+                       HTMLNode ul = null;
+                       HTMLNode formNode = null;
+                       boolean changedAnything = false;
+                       String configName = 
"security-levels.networkThreatLevel";
+                       String confirm = 
"security-levels.networkThreatLevel.confirm";
+                       String tryConfirm = 
"security-levels.networkThreatLevel.tryConfirm";
+                       String networkThreatLevel = 
request.getPartAsString(configName, 128);
+                       NETWORK_THREAT_LEVEL newThreatLevel = 
SecurityLevels.parseNetworkThreatLevel(networkThreatLevel);
+                       if(newThreatLevel != null) {
+                               if(newThreatLevel != 
node.securityLevels.getNetworkThreatLevel()) {
+                                       if(!request.isPartSet(confirm) && 
!request.isPartSet(tryConfirm)) {
+                                               HTMLNode warning = 
node.securityLevels.getConfirmWarning(newThreatLevel, confirm);
+                                               if(warning != null) {
+                                                       if(pageNode == null) {
+                                                               pageNode = 
ctx.getPageMaker().getPageNode(L10n.getString("ConfigToadlet.fullTitle", new 
String[] { "name" }, new String[] { node.getMyName() }), ctx);
+                                                               content = 
ctx.getPageMaker().getContentNode(pageNode);
+                                                               formNode = 
ctx.addFormChild(content, ".", "configFormSecLevels");
+                                                               ul = 
formNode.addChild("ul", "class", "config");
+                                                       }
+                                                       HTMLNode seclevelGroup 
= ul.addChild("li");
+
+                                                       
seclevelGroup.addChild("input", new String[] { "type", "name", "value" }, new 
String[] { "hidden", configName, networkThreatLevel });
+                                                       HTMLNode infobox = 
seclevelGroup.addChild("div", "class", "infobox infobox-information");
+                                                       infobox.addChild("div", 
"class", "infobox-header", l10nSec("networkThreatLevelConfirmTitle", "mode", 
SecurityLevels.localisedName(newThreatLevel)));
+                                                       HTMLNode infoboxContent 
= infobox.addChild("div", "class", "infobox-content");
+                                                       
infoboxContent.addChild(warning);
+                                                       
infoboxContent.addChild("input", new String[] { "type", "name", "value" }, new 
String[] { "hidden", tryConfirm, "on" });
+                                               } else {
+                                                       // Apply immediately, 
no confirm needed.
+                                                       
node.securityLevels.setThreatLevel(newThreatLevel);
+                                                       changedAnything = true;
+                                               }
+                                       } else if(request.isPartSet(confirm)) {
+                                               // Apply immediately, user 
confirmed it.
+                                               
node.securityLevels.setThreatLevel(newThreatLevel);
+                                               changedAnything = true;
+                                       }
+                               }
+                       }
+                       
+                       configName = "security-levels.friendsThreatLevel";
+                       confirm = "security-levels.friendsThreatLevel.confirm";
+                       tryConfirm = 
"security-levels.friendsThreatLevel.tryConfirm";
+                       String friendsThreatLevel = 
request.getPartAsString(configName, 128);
+                       FRIENDS_THREAT_LEVEL newFriendsLevel = 
SecurityLevels.parseFriendsThreatLevel(friendsThreatLevel);
+                       if(newFriendsLevel != null) {
+                               if(newFriendsLevel != 
node.securityLevels.getFriendsThreatLevel()) {
+                                       if(!request.isPartSet(confirm) && 
!request.isPartSet(tryConfirm)) {
+                                               HTMLNode warning = 
node.securityLevels.getConfirmWarning(newFriendsLevel, confirm);
+                                               if(warning != null) {
+                                                       if(pageNode == null) {
+                                                               pageNode = 
ctx.getPageMaker().getPageNode(L10n.getString("ConfigToadlet.fullTitle", new 
String[] { "name" }, new String[] { node.getMyName() }), ctx);
+                                                               content = 
ctx.getPageMaker().getContentNode(pageNode);
+                                                               formNode = 
ctx.addFormChild(content, ".", "configFormSecLevels");
+                                                               ul = 
formNode.addChild("ul", "class", "config");
+                                                       }
+                                                       HTMLNode seclevelGroup 
= ul.addChild("li");
+
+                                                       
seclevelGroup.addChild("input", new String[] { "type", "name", "value" }, new 
String[] { "hidden", configName, friendsThreatLevel });
+                                                       HTMLNode infobox = 
seclevelGroup.addChild("div", "class", "infobox infobox-information");
+                                                       infobox.addChild("div", 
"class", "infobox-header", l10nSec("friendsThreatLevelConfirmTitle", "mode", 
SecurityLevels.localisedName(newFriendsLevel)));
+                                                       HTMLNode infoboxContent 
= infobox.addChild("div", "class", "infobox-content");
+                                                       
infoboxContent.addChild(warning);
+                                                       
infoboxContent.addChild("input", new String[] { "type", "name", "value" }, new 
String[] { "hidden", tryConfirm, "on" });
+                                               } else {
+                                                       // Apply immediately, 
no confirm needed.
+                                                       
node.securityLevels.setThreatLevel(newFriendsLevel);
+                                                       changedAnything = true;
+                                               }
+                                       } else if(request.isPartSet(confirm)) {
+                                               // Apply immediately, user 
confirmed it.
+                                               
node.securityLevels.setThreatLevel(newFriendsLevel);
+                                               changedAnything = true;
+                                       }
+                               }
+                       }
+                       
+                       configName = "security-levels.physicalThreatLevel";
+                       confirm = "security-levels.physicalThreatLevel.confirm";
+                       tryConfirm = 
"security-levels.physicalThreatLevel.tryConfirm";
+                       String physicalThreatLevel = 
request.getPartAsString(configName, 128);
+                       PHYSICAL_THREAT_LEVEL newPhysicalLevel = 
SecurityLevels.parsePhysicalThreatLevel(physicalThreatLevel);
+                       if(newPhysicalLevel != null) {
+                               if(newPhysicalLevel != 
node.securityLevels.getPhysicalThreatLevel()) {
+                                       // No confirmation for changes to 
physical threat level.
+                                       
node.securityLevels.setThreatLevel(newPhysicalLevel);
+                                       changedAnything = true;
+                               }
+                       }
+                       
+                       if(changedAnything)
+                               core.storeConfig();
+                       
+                       if(pageNode != null) {
+                               formNode.addChild("input", new String[] { 
"type", "name", "value" }, new String[] { "hidden", "seclevels", "on" });
+                               formNode.addChild("input", new String[] { 
"type", "value" }, new String[] { "submit", l10n("apply")});
+                               formNode.addChild("input", new String[] { 
"type", "value" }, new String[] { "reset",  l10n("reset")});
+                               writeHTMLReply(ctx, 200, "OK", 
pageNode.generate());
+                               return;
+                       } else {
+                               MultiValueTable headers = new MultiValueTable();
+                               headers.put("Location", 
"/config/?mode="+MODE_SECURITY_LEVELS);
+                               ctx.sendReplyHeaders(302, "Found", headers, 
null, 0);
+                               return;
+                       }
+               }
+               
+               SubConfig[] sc = config.getConfigs();
+               StringBuilder errbuf = new StringBuilder();
+               
                if(!ctx.isAllowedFullAccess()) {
                        super.sendErrorPage(ctx, 403, 
L10n.getString("Toadlet.unauthorizedTitle"), 
L10n.getString("Toadlet.unauthorized"));
                        return;
@@ -215,6 +331,8 @@
                return L10n.getString("ConfigToadlet." + string);
        }

+       public static final int MODE_SECURITY_LEVELS = 3;
+       
        @Override
     public void handleGet(URI uri, HTTPRequest req, ToadletContext ctx) throws 
ToadletContextClosedException, IOException {

@@ -231,8 +349,12 @@

                contentNode.addChild(core.alerts.createSummary());

-               final int mode = 
ctx.getPageMaker().drawModeSelectionArray(core, req, contentNode);
+               final int mode = 
ctx.getPageMaker().drawModeSelectionArray(core, req, contentNode, 
MODE_SECURITY_LEVELS, "SecurityLevels.title", "SecurityLevels.tooltip");

+               if(mode == MODE_SECURITY_LEVELS) {
+                       drawSecurityLevelsPage(contentNode, ctx);
+               } else {
+               
                if(mode >= PageMaker.MODE_ADVANCED){
                        HTMLNode navigationBar = 
ctx.getPageMaker().getInfobox("navbar", l10n("configNavTitle"));
                        HTMLNode navigationContent = 
ctx.getPageMaker().getContentNode(navigationBar).addChild("ul");
@@ -243,6 +365,7 @@
                        HTMLNode nextTableCell = navigationTableRow;

                        for(int i=0; i<sc.length;i++){
+                               if(sc[i].getPrefix().equals("security-levels")) 
continue;
                                nextTableCell.addChild("td", "class", 
"config_navigation").addChild("li").addChild("a", "href", '#' 
+sc[i].getPrefix(), l10n(sc[i].getPrefix()));
                        }
                        contentNode.addChild(navigationBar);
@@ -271,6 +394,7 @@
                for(int i=0; i<sc.length;i++){
                        short displayedConfigElements = 0;

+                       if(sc[i].getPrefix().equals("security-levels")) 
continue;
                        Option<?>[] o = sc[i].getOptions();
                        HTMLNode configGroupUlNode = new HTMLNode("ul", 
"class", "config");

@@ -321,9 +445,103 @@
                formNode.addChild("input", new String[] { "type", "value" }, 
new String[] { "submit", l10n("apply")});
                formNode.addChild("input", new String[] { "type", "value" }, 
new String[] { "reset",  l10n("reset")});

+               }
+               
                this.writeHTMLReply(ctx, 200, "OK", pageNode.generate());
        }

+       private void drawSecurityLevelsPage(HTMLNode contentNode, 
ToadletContext ctx) {
+               HTMLNode infobox = contentNode.addChild("div", "class", 
"infobox infobox-normal");
+               infobox.addChild("div", "class", "infobox-header", 
l10nSec("title"));
+               HTMLNode configNode = infobox.addChild("div", "class", 
"infobox-content");
+               HTMLNode formNode = ctx.addFormChild(configNode, ".", 
"configFormSecLevels");
+               // Network security level
+               formNode.addChild("div", "class", "configprefix", 
l10nSec("networkThreatLevelShort"));
+               HTMLNode ul = formNode.addChild("ul", "class", "config");
+               HTMLNode seclevelGroup = ul.addChild("li");
+               seclevelGroup.addChild("#", l10nSec("networkThreatLevel"));
+               
+               NETWORK_THREAT_LEVEL networkLevel = 
node.securityLevels.getNetworkThreatLevel();
+               
+               String controlName = "security-levels.networkThreatLevel";
+               for(NETWORK_THREAT_LEVEL level : NETWORK_THREAT_LEVEL.values()) 
{
+                       HTMLNode input;
+                       if(level == networkLevel) {
+                               input = 
seclevelGroup.addChild("p").addChild("input", new String[] { "type", "checked", 
"name", "value" }, new String[] { "radio", "on", controlName, level.name() });
+                       } else {
+                               input = 
seclevelGroup.addChild("p").addChild("input", new String[] { "type", "name", 
"value" }, new String[] { "radio", controlName, level.name() });
+                       }
+                       input.addChild("b", 
l10nSec("networkThreatLevel.name."+level));
+                       input.addChild("#", ": ");
+                       L10n.addL10nSubstitution(input, 
"SecurityLevels.networkThreatLevel.choice."+level, new String[] { "bold", 
"/bold" }, new String[] { "<b>", "</b>" });
+                       HTMLNode inner = input.addChild("p").addChild("i");
+                       L10n.addL10nSubstitution(inner, 
"SecurityLevels.networkThreatLevel.desc."+level, new String[] { "bold", "/bold" 
}, new String[] { "<b>", "</b>" });
+               }
+               
+               // Friends security level
+               formNode.addChild("div", "class", "configprefix", 
l10nSec("friendsThreatLevelShort"));
+               ul = formNode.addChild("ul", "class", "config");
+               seclevelGroup = ul.addChild("li");
+               seclevelGroup.addChild("#", l10nSec("friendsThreatLevel"));
+               
+               FRIENDS_THREAT_LEVEL friendsLevel = 
node.securityLevels.getFriendsThreatLevel();
+               
+               controlName = "security-levels.friendsThreatLevel";
+               for(FRIENDS_THREAT_LEVEL level : FRIENDS_THREAT_LEVEL.values()) 
{
+                       HTMLNode input;
+                       if(level == friendsLevel) {
+                               input = 
seclevelGroup.addChild("p").addChild("input", new String[] { "type", "checked", 
"name", "value" }, new String[] { "radio", "on", controlName, level.name() });
+                       } else {
+                               input = 
seclevelGroup.addChild("p").addChild("input", new String[] { "type", "name", 
"value" }, new String[] { "radio", controlName, level.name() });
+                       }
+                       input.addChild("b", 
l10nSec("friendsThreatLevel.name."+level));
+                       input.addChild("#", ": ");
+                       L10n.addL10nSubstitution(input, 
"SecurityLevels.friendsThreatLevel.choice."+level, new String[] { "bold", 
"/bold" }, new String[] { "<b>", "</b>" });
+                       HTMLNode inner = input.addChild("p").addChild("i");
+                       L10n.addL10nSubstitution(inner, 
"SecurityLevels.friendsThreatLevel.desc."+level, new String[] { "bold", "/bold" 
}, new String[] { "<b>", "</b>" });
+               }
+               
+               // Physical security level
+               formNode.addChild("div", "class", "configprefix", 
l10nSec("physicalThreatLevelShort"));
+               ul = formNode.addChild("ul", "class", "config");
+               seclevelGroup = ul.addChild("li");
+               seclevelGroup.addChild("#", l10nSec("physicalThreatLevel"));
+               
+               PHYSICAL_THREAT_LEVEL physicalLevel = 
node.securityLevels.getPhysicalThreatLevel();
+               
+               controlName = "security-levels.physicalThreatLevel";
+               for(PHYSICAL_THREAT_LEVEL level : 
PHYSICAL_THREAT_LEVEL.values()) {
+                       HTMLNode input;
+                       if(level == physicalLevel) {
+                               input = 
seclevelGroup.addChild("p").addChild("input", new String[] { "type", "checked", 
"name", "value" }, new String[] { "radio", "on", controlName, level.name() });
+                       } else {
+                               input = 
seclevelGroup.addChild("p").addChild("input", new String[] { "type", "name", 
"value" }, new String[] { "radio", controlName, level.name() });
+                       }
+                       input.addChild("b", 
l10nSec("physicalThreatLevel.name."+level));
+                       input.addChild("#", ": ");
+                       L10n.addL10nSubstitution(input, 
"SecurityLevels.physicalThreatLevel.choice."+level, new String[] { "bold", 
"/bold" }, new String[] { "<b>", "</b>" });
+                       HTMLNode inner = input.addChild("p").addChild("i");
+                       L10n.addL10nSubstitution(inner, 
"SecurityLevels.physicalThreatLevel.desc."+level, new String[] { "bold", 
"/bold" }, new String[] { "<b>", "</b>" });
+               }
+               
+               
+               
+               // FIXME implement the rest, it should be very similar to the 
above.
+               
+               formNode.addChild("input", new String[] { "type", "name", 
"value" }, new String[] { "hidden", "seclevels", "on" });
+               formNode.addChild("input", new String[] { "type", "value" }, 
new String[] { "submit", l10n("apply")});
+               formNode.addChild("input", new String[] { "type", "value" }, 
new String[] { "reset",  l10n("reset")});
+       }
+
+
+       private String l10nSec(String key) {
+               return L10n.getString("SecurityLevels."+key);
+       }
+       
+       private String l10nSec(String key, String pattern, String value) {
+               return L10n.getString("SecurityLevels."+key, pattern, value);
+       }
+
        @Override
     public String supportedMethods() {
                return "GET, POST";

Modified: branches/db4o/freenet/src/freenet/clients/http/ConnectionsToadlet.java
===================================================================
--- branches/db4o/freenet/src/freenet/clients/http/ConnectionsToadlet.java      
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/clients/http/ConnectionsToadlet.java      
2008-09-24 23:54:07 UTC (rev 22829)
@@ -121,7 +121,7 @@
                                return compareLongs(total1, total2);
                        }else if(sortBy.equals("selection_percentage")){
                                long sinceWhen = System.currentTimeMillis() - 
PeerNode.SELECTION_SAMPLING_PERIOD;
-                               return 
compareInts(firstNode.getNumberOfSelections().headSet(sinceWhen).size(), 
secondNode.getNumberOfSelections().headSet(sinceWhen).size());
+                               return 
Double.compare(firstNode.getSelectionRate(), secondNode.getSelectionRate());
                        }else if(sortBy.equals("time_delta")){
                                return compareLongs(firstNode.getClockDelta(), 
secondNode.getClockDelta());
                        }else if(sortBy.equals(("uptime"))){
@@ -325,7 +325,7 @@

                        // BEGIN PEER TABLE
                        if(fProxyJavascriptEnabled) {
-                               StringBuffer jsBuf = new StringBuffer();
+                               StringBuilder jsBuf = new StringBuilder();
                                // FIXME: There's probably some icky Javascript 
in here (this is the first thing that worked for me); feel free to fix up to 
Javascript guru standards
                                jsBuf.append( "  function peerNoteChange() {\n" 
);
                                jsBuf.append( "    var theobj = 
document.getElementById( \"action\" );\n" );
@@ -418,11 +418,14 @@
                                                header.addChild("span", new 
String[] { "title", "style" }, new String[] { 
L10n.getString(col.getExplanationKey()), "border-bottom: 1px dotted; cursor: 
help;" }, L10n.getString(col.getTitleKey()));
                                        }
                                }
-                               
-                               int numberOfSelectionSamples = 
peers.getNumberOfSelectionSamples().tailSet(now - 
PeerNode.SELECTION_SAMPLING_PERIOD).size();
+
+                               double totalSelectionRate = 0.0;
+                               for(PeerNodeStatus status : peerNodeStatuses) {
+                                       totalSelectionRate += 
status.getSelectionRate();
+                               }
                                for (int peerIndex = 0, peerCount = 
peerNodeStatuses.length; peerIndex < peerCount; peerIndex++) {                  
                    
                                        PeerNodeStatus peerNodeStatus = 
peerNodeStatuses[peerIndex];
-                                       drawRow(peerTable, peerNodeStatus, mode 
>= PageMaker.MODE_ADVANCED, fProxyJavascriptEnabled, now, path, 
enablePeerActions, endCols, drawMessageTypes, numberOfSelectionSamples);
+                                       drawRow(peerTable, peerNodeStatus, mode 
>= PageMaker.MODE_ADVANCED, fProxyJavascriptEnabled, now, path, 
enablePeerActions, endCols, drawMessageTypes, totalSelectionRate);

                                }

@@ -515,7 +518,7 @@
                        if(!isOpennet())
                                privateComment = 
request.getPartAsString("peerPrivateNote", 250).trim();

-                       StringBuffer ref = new StringBuffer(1024);
+                       StringBuilder ref = new StringBuilder(1024);
                        if (urltext.length() > 0) {
                                // fetch reference from a URL
                                BufferedReader in = null;
@@ -539,13 +542,13 @@
                        } else if (reftext.length() > 0) {
                                // read from post data or file upload
                                // this slightly scary looking regexp chops any 
extra characters off the beginning or ends of lines and removes extra line 
breaks
-                               ref = new 
StringBuffer(reftext.replaceAll(".*?((?:[\\w,\\.]+\\=[^\r\n]+?)|(?:End))[ 
\\t]*(?:\\r?\\n)+", "$1\n"));
+                               ref = new 
StringBuilder(reftext.replaceAll(".*?((?:[\\w,\\.]+\\=[^\r\n]+?)|(?:End))[ 
\\t]*(?:\\r?\\n)+", "$1\n"));
                        } else {
                                this.sendErrorPage(ctx, 200, 
l10n("failedToAddNodeTitle"), l10n("noRefOrURL"));
                                request.freeParts();
                                return;
                        }
-                       ref = new StringBuffer(ref.toString().trim());
+                       ref = new StringBuilder(ref.toString().trim());

                        request.freeParts();
                        // we have a node reference in ref
@@ -693,9 +696,11 @@

        abstract protected SimpleFieldSet getNoderef();

-       private void drawRow(HTMLNode peerTable, PeerNodeStatus peerNodeStatus, 
boolean advancedModeEnabled, boolean fProxyJavascriptEnabled, long now, String 
path, boolean enablePeerActions, SimpleColumn[] endCols, boolean 
drawMessageTypes, int numberOfSelectionSamples) {
-               int peerSelectionCount = 
peerNodeStatus.getNumberOfSelections().tailSet(now - 
PeerNode.SELECTION_SAMPLING_PERIOD).size();
-               int peerSelectionPercentage = (numberOfSelectionSamples > 0 ? 
(peerSelectionCount*100/numberOfSelectionSamples) : 0);
+       private void drawRow(HTMLNode peerTable, PeerNodeStatus peerNodeStatus, 
boolean advancedModeEnabled, boolean fProxyJavascriptEnabled, long now, String 
path, boolean enablePeerActions, SimpleColumn[] endCols, boolean 
drawMessageTypes, double totalSelectionRate) {
+               double selectionRate = peerNodeStatus.getSelectionRate();
+               int peerSelectionPercentage = 0;
+               if(totalSelectionRate > 0)
+                       peerSelectionPercentage = (int) (selectionRate * 100 / 
totalSelectionRate);
                HTMLNode peerRow = peerTable.addChild("tr", "class", 
"darknet_connections_"+(peerSelectionPercentage > 
PeerNode.SELECTION_PERCENTAGE_WARNING ? "warning" : "normal"));

                if(enablePeerActions) {
@@ -777,7 +782,7 @@
                        // percent of time connected column
                        peerRow.addChild("td", "class", "peer-idle" /* FIXME 
*/).addChild("#", 
fix1.format(peerNodeStatus.getPercentTimeRoutableConnection()));
                        // selection stats
-                       peerRow.addChild("td", "class", "peer-idle" /* FIXME 
*/).addChild("#", (numberOfSelectionSamples > 0 ? (peerSelectionPercentage+"%") 
: "N/A"));
+                       peerRow.addChild("td", "class", "peer-idle" /* FIXME 
*/).addChild("#", (totalSelectionRate > 0 ? (peerSelectionPercentage+"%") : 
"N/A"));
                        // total traffic column
                        peerRow.addChild("td", "class", "peer-idle" /* FIXME 
*/).addChild("#", SizeUtil.formatSize(peerNodeStatus.getTotalInputBytes())+" / 
"+SizeUtil.formatSize(peerNodeStatus.getTotalOutputBytes())+"/"+SizeUtil.formatSize(peerNodeStatus.getResendBytesSent()));
                        // congestion control

Modified: branches/db4o/freenet/src/freenet/clients/http/FProxyToadlet.java
===================================================================
--- branches/db4o/freenet/src/freenet/clients/http/FProxyToadlet.java   
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/clients/http/FProxyToadlet.java   
2008-09-24 23:54:07 UTC (rev 22829)
@@ -235,7 +235,6 @@
                        L10n.addL10nSubstitution(option, 
"FProxyToadlet.openForceDisk", new String[] { "link", "/link" }, new String[] { 
"<a href=\""+basePath+key.toString()+"?forcedownload"+extras+"\">", "</a>" });
                        if(!(mimeType.equals("application/octet-stream") || 
mimeType.equals("application/x-msdownload"))) {
                                option = optionList.addChild("li");
-                               
                                L10n.addL10nSubstitution(option, 
"FProxyToadlet.openForce", new String[] { "link", "/link", "mime" }, new 
String[] { "<a href=\""+basePath + key.toString() + "?force=" + 
getForceValue(key, now)+extras+"\">", "</a>", HTMLEncoder.encode(mimeType)});
                        }
                        if(referrer != null) {
@@ -520,6 +519,12 @@
                                infoboxContent = infobox.addChild("div", 
"class", "infobox-content");

                                HTMLNode optionList = 
infoboxContent.addChild("ul");
+                               
+                               if((e.mode == FetchException.NOT_IN_ARCHIVE) && 
(core.node.pluginManager.isPluginLoaded("plugins.KeyExplorer.KeyExplorer"))) {
+                                       option = optionList.addChild("li");
+                                       L10n.addL10nSubstitution(option, 
"FProxyToadlet.openWithKeyExplorer", new String[] { "link", "/link" }, new 
String[] { "<a href=\"/plugins/plugins.KeyExplorer.KeyExplorer/?key=" + 
key.toString() + "\">", "</a>" });
+                               }
+                               
                                if(!e.isFatal() && ctx.isAllowedFullAccess()) {
                                        option = optionList.addChild("li");
                                        HTMLNode optionForm = 
ctx.addFormChild(option, "/queue/", "dnfQueueForm");
@@ -588,7 +593,7 @@

        private String getLink(FreenetURI uri, String requestedMimeType, long 
maxSize, String force, 
                        boolean forceDownload) {
-               StringBuffer sb = new StringBuffer();
+               StringBuilder sb = new StringBuilder();
                sb.append("/");
                sb.append(uri.toACIIString());
                char c = '?';

Modified: 
branches/db4o/freenet/src/freenet/clients/http/FirstTimeWizardToadlet.java
===================================================================
--- branches/db4o/freenet/src/freenet/clients/http/FirstTimeWizardToadlet.java  
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/clients/http/FirstTimeWizardToadlet.java  
2008-09-24 23:54:07 UTC (rev 22829)
@@ -11,12 +11,14 @@
 import freenet.client.HighLevelSimpleClient;
 import freenet.config.Config;
 import freenet.config.ConfigException;
-import freenet.config.InvalidConfigValueException;
-import freenet.config.NodeNeedRestartException;
 import freenet.config.WrapperConfig;
 import freenet.l10n.L10n;
 import freenet.node.Node;
 import freenet.node.NodeClientCore;
+import freenet.node.SecurityLevels;
+import freenet.node.SecurityLevels.FRIENDS_THREAT_LEVEL;
+import freenet.node.SecurityLevels.NETWORK_THREAT_LEVEL;
+import freenet.node.SecurityLevels.PHYSICAL_THREAT_LEVEL;
 import freenet.pluginmanager.FredPluginBandwidthIndicator;
 import freenet.support.Fields;
 import freenet.support.HTMLNode;
@@ -36,7 +38,9 @@

        private enum WIZARD_STEP {
                WELCOME,
-               OPENNET,
+               SECURITY_NETWORK,
+               SECURITY_FRIENDS,
+               SECURITY_PHYSICAL,
                NAME_SELECTION,
                BANDWIDTH,
                DATASTORE_SIZE,
@@ -62,26 +66,84 @@

                WIZARD_STEP currentStep = 
WIZARD_STEP.valueOf(request.getParam("step", WIZARD_STEP.WELCOME.toString()));

-               if(currentStep == WIZARD_STEP.OPENNET) {
-                       HTMLNode pageNode = 
ctx.getPageMaker().getPageNode(l10n("step1Title"), false, ctx);
+               if(currentStep == WIZARD_STEP.SECURITY_NETWORK) {
+                       HTMLNode pageNode = 
ctx.getPageMaker().getPageNode(l10n("networkSecurityPageTitle"), false, ctx);
                        HTMLNode contentNode = 
ctx.getPageMaker().getContentNode(pageNode);

-                       HTMLNode opennetInfobox = contentNode.addChild("div", 
"class", "infobox infobox-normal");
-                       HTMLNode opennetInfoboxHeader = 
opennetInfobox.addChild("div", "class", "infobox-header");
-                       HTMLNode opennetInfoboxContent = 
opennetInfobox.addChild("div", "class", "infobox-content");
+                       HTMLNode infobox = contentNode.addChild("div", "class", 
"infobox infobox-normal");
+                       HTMLNode infoboxHeader = infobox.addChild("div", 
"class", "infobox-header");
+                       HTMLNode infoboxContent = infobox.addChild("div", 
"class", "infobox-content");

-                       opennetInfoboxHeader.addChild("#", 
l10n("connectToStrangers"));
-                       opennetInfoboxContent.addChild("p", 
l10n("connectToStrangersLong"));
-                       opennetInfoboxContent.addChild("p", 
l10n("enableOpennet"));
-                       HTMLNode opennetForm = 
ctx.addFormChild(opennetInfoboxContent, ".", "opennetForm");
-                       HTMLNode opennetDiv = opennetForm.addChild("div", 
"class", "opennetDiv");
-                       opennetDiv.addChild("input", new String[] { "type", 
"name", "value" }, new String[] { "radio", "enableOpennet", "true" }, 
l10n("opennetYes"));
-                       opennetDiv.addChild("br");
-                       opennetDiv.addChild("input", new String[] { "type", 
"name", "value" }, new String[] { "radio", "enableOpennet", "false" }, 
l10n("opennetNo"));
-                       opennetForm.addChild("input", new String[] { "type", 
"name", "value" }, new String[] { "submit", "opennetF", 
L10n.getString("FirstTimeWizardToadlet.continue")});
-                       opennetForm.addChild("input", new String[] { "type", 
"name", "value" }, new String[] { "submit", "cancel", 
L10n.getString("Toadlet.cancel")});
+                       infoboxHeader.addChild("#", 
l10nSec("networkThreatLevelShort"));
+                       infoboxContent.addChild("p", 
l10nSec("networkThreatLevel"));
+                       HTMLNode form = ctx.addFormChild(infoboxContent, ".", 
"networkSecurityForm");
+                       HTMLNode div = form.addChild("div", "class", 
"opennetDiv");
+                       String controlName = 
"security-levels.networkThreatLevel";
+                       for(NETWORK_THREAT_LEVEL level : 
NETWORK_THREAT_LEVEL.values()) {
+                               HTMLNode input;
+                               input = div.addChild("p").addChild("input", new 
String[] { "type", "name", "value" }, new String[] { "radio", controlName, 
level.name() });
+                               input.addChild("b", 
l10nSec("networkThreatLevel.name."+level));
+                               input.addChild("#", ": ");
+                               L10n.addL10nSubstitution(input, 
"SecurityLevels.networkThreatLevel.choice."+level, new String[] { "bold", 
"/bold" }, new String[] { "<b>", "</b>" });
+                               HTMLNode inner = 
input.addChild("p").addChild("i");
+                               L10n.addL10nSubstitution(inner, 
"SecurityLevels.networkThreatLevel.desc."+level, new String[] { "bold", "/bold" 
}, new String[] { "<b>", "</b>" });
+                       }
+                       form.addChild("input", new String[] { "type", "name", 
"value" }, new String[] { "submit", "networkSecurityF", 
L10n.getString("FirstTimeWizardToadlet.continue")});
+                       form.addChild("input", new String[] { "type", "name", 
"value" }, new String[] { "submit", "cancel", 
L10n.getString("Toadlet.cancel")});
                        this.writeHTMLReply(ctx, 200, "OK", 
pageNode.generate());
                        return;
+               } else if(currentStep == WIZARD_STEP.SECURITY_FRIENDS) {
+                       HTMLNode pageNode = 
ctx.getPageMaker().getPageNode(l10n("friendsSecurityPageTitle"), false, ctx);
+                       HTMLNode contentNode = 
ctx.getPageMaker().getContentNode(pageNode);
+                       
+                       HTMLNode infobox = contentNode.addChild("div", "class", 
"infobox infobox-normal");
+                       HTMLNode infoboxHeader = infobox.addChild("div", 
"class", "infobox-header");
+                       HTMLNode infoboxContent = infobox.addChild("div", 
"class", "infobox-content");
+                       
+                       infoboxHeader.addChild("#", 
l10nSec("friendsThreatLevelShort"));
+                       infoboxContent.addChild("p", 
l10nSec("friendsThreatLevel"));
+                       HTMLNode form = ctx.addFormChild(infoboxContent, ".", 
"friendsSecurityForm");
+                       HTMLNode div = form.addChild("div", "class", 
"opennetDiv");
+                       String controlName = 
"security-levels.friendsThreatLevel";
+                       for(FRIENDS_THREAT_LEVEL level : 
FRIENDS_THREAT_LEVEL.values()) {
+                               HTMLNode input;
+                               input = div.addChild("p").addChild("input", new 
String[] { "type", "name", "value" }, new String[] { "radio", controlName, 
level.name() });
+                               input.addChild("b", 
l10nSec("friendsThreatLevel.name."+level));
+                               input.addChild("#", ": ");
+                               L10n.addL10nSubstitution(input, 
"SecurityLevels.friendsThreatLevel.choice."+level, new String[] { "bold", 
"/bold" }, new String[] { "<b>", "</b>" });
+                               HTMLNode inner = 
input.addChild("p").addChild("i");
+                               L10n.addL10nSubstitution(inner, 
"SecurityLevels.friendsThreatLevel.desc."+level, new String[] { "bold", "/bold" 
}, new String[] { "<b>", "</b>" });
+                       }
+                       form.addChild("input", new String[] { "type", "name", 
"value" }, new String[] { "submit", "friendsSecurityF", 
L10n.getString("FirstTimeWizardToadlet.continue")});
+                       form.addChild("input", new String[] { "type", "name", 
"value" }, new String[] { "submit", "cancel", 
L10n.getString("Toadlet.cancel")});
+                       this.writeHTMLReply(ctx, 200, "OK", 
pageNode.generate());
+                       return;
+               } else if(currentStep == WIZARD_STEP.SECURITY_PHYSICAL) {
+                       HTMLNode pageNode = 
ctx.getPageMaker().getPageNode(l10n("physicalSecurityPageTitle"), false, ctx);
+                       HTMLNode contentNode = 
ctx.getPageMaker().getContentNode(pageNode);
+                       
+                       HTMLNode infobox = contentNode.addChild("div", "class", 
"infobox infobox-normal");
+                       HTMLNode infoboxHeader = infobox.addChild("div", 
"class", "infobox-header");
+                       HTMLNode infoboxContent = infobox.addChild("div", 
"class", "infobox-content");
+                       
+                       infoboxHeader.addChild("#", 
l10nSec("physicalThreatLevelShort"));
+                       infoboxContent.addChild("p", 
l10nSec("physicalThreatLevel"));
+                       HTMLNode form = ctx.addFormChild(infoboxContent, ".", 
"physicalSecurityForm");
+                       HTMLNode div = form.addChild("div", "class", 
"opennetDiv");
+                       String controlName = 
"security-levels.physicalThreatLevel";
+                       for(PHYSICAL_THREAT_LEVEL level : 
PHYSICAL_THREAT_LEVEL.values()) {
+                               HTMLNode input;
+                               input = div.addChild("p").addChild("input", new 
String[] { "type", "name", "value" }, new String[] { "radio", controlName, 
level.name() });
+                               input.addChild("b", 
l10nSec("physicalThreatLevel.name."+level));
+                               input.addChild("#", ": ");
+                               L10n.addL10nSubstitution(input, 
"SecurityLevels.physicalThreatLevel.choice."+level, new String[] { "bold", 
"/bold" }, new String[] { "<b>", "</b>" });
+                               HTMLNode inner = 
input.addChild("p").addChild("i");
+                               L10n.addL10nSubstitution(inner, 
"SecurityLevels.physicalThreatLevel.desc."+level, new String[] { "bold", 
"/bold" }, new String[] { "<b>", "</b>" });
+                       }
+                       form.addChild("input", new String[] { "type", "name", 
"value" }, new String[] { "submit", "physicalSecurityF", 
L10n.getString("FirstTimeWizardToadlet.continue")});
+                       form.addChild("input", new String[] { "type", "name", 
"value" }, new String[] { "submit", "cancel", 
L10n.getString("Toadlet.cancel")});
+                       this.writeHTMLReply(ctx, 200, "OK", 
pageNode.generate());
+                       return;
                } else if(currentStep == WIZARD_STEP.NAME_SELECTION) {
                        // Attempt to skip one step if possible: opennet nodes 
don't need a name
                        if(Boolean.valueOf(request.getParam("opennet"))) {
@@ -224,7 +286,7 @@
                HTMLNode firstParagraph = welcomeInfoboxContent.addChild("p");
                firstParagraph.addChild("#", l10n("welcomeInfoboxContent1"));
                HTMLNode secondParagraph = welcomeInfoboxContent.addChild("p");
-               secondParagraph.addChild("a", "href", 
"?step="+WIZARD_STEP.OPENNET).addChild("#", 
L10n.getString("FirstTimeWizardToadlet.clickContinue"));
+               secondParagraph.addChild("a", "href", 
"?step="+WIZARD_STEP.SECURITY_NETWORK).addChild("#", 
L10n.getString("FirstTimeWizardToadlet.clickContinue"));

                HTMLNode thirdParagraph = welcomeInfoboxContent.addChild("p");
                thirdParagraph.addChild("a", "href", "/").addChild("#", 
l10n("skipWizard"));
@@ -232,6 +294,14 @@
                this.writeHTMLReply(ctx, 200, "OK", pageNode.generate());
        }

+       private String l10nSec(String key) {
+               return L10n.getString("SecurityLevels."+key);
+       }
+
+       private String l10nSec(String key, String pattern, String value) {
+               return L10n.getString("SecurityLevels."+key, pattern, value);
+       }
+
        @Override
        public void handlePost(URI uri, HTTPRequest request, ToadletContext 
ctx) throws ToadletContextClosedException, IOException {

@@ -248,30 +318,103 @@
                        return;
                }

-               
-               if(request.isPartSet("enableOpennet")) {
-                       String isOpennetEnabled = 
request.getPartAsString("enableOpennet", 255);
-                       boolean enable;
-                       try {
-                               enable = Fields.stringToBool(isOpennetEnabled);
-                       } catch (NumberFormatException e) {
-                               Logger.error(this, "Invalid opennetEnabled: 
"+isOpennetEnabled, e);
-                               super.writeTemporaryRedirect(ctx, "step1", 
TOADLET_URL+"?step="+WIZARD_STEP.OPENNET);
+               if(request.isPartSet("security-levels.networkThreatLevel")) {
+                       // We don't require a confirmation here, since it's one 
page at a time, so there's less information to
+                       // confuse the user, and we don't know whether the node 
has friends yet etc.
+                       // FIXME should we have confirmation here???
+                       String networkThreatLevel = 
request.getPartAsString("security-levels.networkThreatLevel", 128);
+                       NETWORK_THREAT_LEVEL newThreatLevel = 
SecurityLevels.parseNetworkThreatLevel(networkThreatLevel);
+                       if(newThreatLevel == null) {
+                               super.writeTemporaryRedirect(ctx, "step1", 
TOADLET_URL+"?step="+WIZARD_STEP.SECURITY_NETWORK);
                                return;
                        }
-                       try {
-                               config.get("node.opennet").set("enabled", 
enable);
-                       } catch (InvalidConfigValueException e) {
-                               Logger.error(this, "Should not happen setting 
opennet.enabled=" + enable + " please report: " + e, e);
-                               super.writeTemporaryRedirect(ctx, "step1", 
TOADLET_URL+"?step="+WIZARD_STEP.OPENNET);
+                       if((newThreatLevel == NETWORK_THREAT_LEVEL.MAXIMUM || 
newThreatLevel == NETWORK_THREAT_LEVEL.HIGH)) {
+                               
if((!request.isPartSet("security-levels.networkThreatLevel.confirm")) &&
+                                       
(!request.isPartSet("security-levels.networkThreatLevel.tryConfirm"))) {
+                                       HTMLNode pageNode = 
ctx.getPageMaker().getPageNode(l10n("networkSecurityPageTitle"), ctx);
+                                       HTMLNode content = 
ctx.getPageMaker().getContentNode(pageNode);
+                                       HTMLNode formNode = 
ctx.addFormChild(content, ".", "configFormSecLevels");
+                                       
+                                       formNode.addChild("input", new String[] 
{ "type", "name", "value" }, new String[] { "hidden", 
"security-levels.networkThreatLevel", networkThreatLevel });
+                                       HTMLNode infobox = 
formNode.addChild("div", "class", "infobox infobox-information");
+                                       infobox.addChild("div", "class", 
"infobox-header", l10nSec("networkThreatLevelConfirmTitle", "mode", 
SecurityLevels.localisedName(newThreatLevel)));
+                                       HTMLNode infoboxContent = 
infobox.addChild("div", "class", "infobox-content");
+                                       if(newThreatLevel == 
NETWORK_THREAT_LEVEL.MAXIMUM) {
+                                               HTMLNode p = 
infoboxContent.addChild("p");
+                                               L10n.addL10nSubstitution(p, 
"SecurityLevels.maximumNetworkThreatLevelWarning", new String[] { "bold", 
"/bold" }, new String[] { "<b>", "</b>" });
+                                               p.addChild("#", " ");
+                                               L10n.addL10nSubstitution(p, 
"SecurityLevels.maxSecurityYouNeedFriends", new String[] { "bold", "/bold" }, 
new String[] { "<b>", "</b>" });
+                                               
infoboxContent.addChild("input", new String[] { "type", "name", "value" }, new 
String[] { "checkbox", "security-levels.networkThreatLevel.confirm", "off" }, 
l10nSec("maximumNetworkThreatLevelCheckbox"));
+                                       } else /*if(newThreatLevel == 
NETWORK_THREAT_LEVEL.HIGH)*/ {
+                                               HTMLNode p = 
infoboxContent.addChild("p");
+                                               L10n.addL10nSubstitution(p, 
"FirstTimeWizardToadlet.highNetworkThreatLevelWarning", new String[] { "bold", 
"/bold" }, new String[] { "<b>", "</b>" });
+                                               
infoboxContent.addChild("input", new String[] { "type", "name", "value" }, new 
String[] { "checkbox", "security-levels.networkThreatLevel.confirm", "off" }, 
l10n("highNetworkThreatLevelCheckbox"));
+                                       }
+                                       infoboxContent.addChild("input", new 
String[] { "type", "name", "value" }, new String[] { "hidden", 
"security-levels.networkThreatLevel.tryConfirm", "on" });
+                                       formNode.addChild("input", new String[] 
{ "type", "name", "value" }, new String[] { "hidden", "seclevels", "on" });
+                                       formNode.addChild("input", new String[] 
{ "type", "value" }, new String[] { "submit", 
L10n.getString("ConfigToadlet.apply")});
+                                       formNode.addChild("input", new String[] 
{ "type", "value" }, new String[] { "reset",  
L10n.getString("ConfigToadlet.reset")});
+                                       writeHTMLReply(ctx, 200, "OK", 
pageNode.generate());
+                                       return;
+                               } else 
if((!request.isPartSet("security-levels.networkThreatLevel.confirm")) &&
+                                               
request.isPartSet("security-levels.networkThreatLevel.tryConfirm")) {
+                                       super.writeTemporaryRedirect(ctx, 
"step1", TOADLET_URL+"?step="+WIZARD_STEP.SECURITY_NETWORK);
+                                       return;
+                               }
+                       }
+                       core.node.securityLevels.setThreatLevel(newThreatLevel);
+                       super.writeTemporaryRedirect(ctx, "step1", 
TOADLET_URL+"?step="+WIZARD_STEP.SECURITY_FRIENDS);
+               } else 
if(request.isPartSet("security-levels.friendsThreatLevel")) {
+                       // We don't require a confirmation here, since it's one 
page at a time, so there's less information to
+                       // confuse the user, and we don't know whether the node 
has friends yet etc.
+                       // FIXME should we have confirmation here???
+                       String friendsThreatLevel = 
request.getPartAsString("security-levels.friendsThreatLevel", 128);
+                       FRIENDS_THREAT_LEVEL newThreatLevel = 
SecurityLevels.parseFriendsThreatLevel(friendsThreatLevel);
+                       if(newThreatLevel == null) {
+                               super.writeTemporaryRedirect(ctx, "step1", 
TOADLET_URL+"?step="+WIZARD_STEP.SECURITY_FRIENDS);
                                return;
-                       } catch (NodeNeedRestartException e) {
-                               Logger.error(this, "Should not happen setting 
opennet.enabled=" + enable + " please report: " + e, e);
-                               super.writeTemporaryRedirect(ctx, "step1", 
TOADLET_URL + "?step=" + WIZARD_STEP.OPENNET);
+                       }
+                       if((newThreatLevel == FRIENDS_THREAT_LEVEL.HIGH)) {
+                               
if((!request.isPartSet("security-levels.friendsThreatLevel.confirm")) &&
+                                       
(!request.isPartSet("security-levels.friendsThreatLevel.tryConfirm"))) {
+                                       HTMLNode pageNode = 
ctx.getPageMaker().getPageNode(l10n("friendsSecurityPageTitle"), ctx);
+                                       HTMLNode content = 
ctx.getPageMaker().getContentNode(pageNode);
+                                       HTMLNode formNode = 
ctx.addFormChild(content, ".", "configFormSecLevels");
+                                       
+                                       formNode.addChild("input", new String[] 
{ "type", "name", "value" }, new String[] { "hidden", 
"security-levels.friendsThreatLevel", friendsThreatLevel });
+                                       HTMLNode infobox = 
formNode.addChild("div", "class", "infobox infobox-information");
+                                       infobox.addChild("div", "class", 
"infobox-header", l10nSec("friendsThreatLevelConfirmTitle", "mode", 
SecurityLevels.localisedName(newThreatLevel)));
+                                       HTMLNode infoboxContent = 
infobox.addChild("div", "class", "infobox-content");
+                                       HTMLNode p = 
infoboxContent.addChild("p");
+                                       L10n.addL10nSubstitution(p, 
"FirstTimeWizardToadlet.highFriendsThreatLevelWarning", new String[] { "bold", 
"/bold" }, new String[] { "<b>", "</b>" });
+                                       infoboxContent.addChild("input", new 
String[] { "type", "name", "value" }, new String[] { "checkbox", 
"security-levels.friendsThreatLevel.confirm", "off" }, 
l10nSec("highFriendsThreatLevelCheckbox"));
+                                       infoboxContent.addChild("input", new 
String[] { "type", "name", "value" }, new String[] { "hidden", 
"security-levels.friendsThreatLevel.tryConfirm", "on" });
+                                       formNode.addChild("input", new String[] 
{ "type", "name", "value" }, new String[] { "hidden", "seclevels", "on" });
+                                       formNode.addChild("input", new String[] 
{ "type", "value" }, new String[] { "submit", 
L10n.getString("ConfigToadlet.apply")});
+                                       formNode.addChild("input", new String[] 
{ "type", "value" }, new String[] { "reset",  
L10n.getString("ConfigToadlet.reset")});
+                                       writeHTMLReply(ctx, 200, "OK", 
pageNode.generate());
+                                       return;
+                               } else 
if((!request.isPartSet("security-levels.friendsThreatLevel.confirm")) &&
+                                               
request.isPartSet("security-levels.friendsThreatLevel.tryConfirm")) {
+                                       super.writeTemporaryRedirect(ctx, 
"step1", TOADLET_URL+"?step="+WIZARD_STEP.SECURITY_FRIENDS);
+                                       return;
+                               }
+                       }
+                       core.node.securityLevels.setThreatLevel(newThreatLevel);
+                       super.writeTemporaryRedirect(ctx, "step1", 
TOADLET_URL+"?step="+WIZARD_STEP.SECURITY_PHYSICAL);
+               } else 
if(request.isPartSet("security-levels.physicalThreatLevel")) {
+                       // We don't require a confirmation here, since it's one 
page at a time, so there's less information to
+                       // confuse the user, and we don't know whether the node 
has friends yet etc.
+                       // FIXME should we have confirmation here???
+                       String physicalThreatLevel = 
request.getPartAsString("security-levels.physicalThreatLevel", 128);
+                       PHYSICAL_THREAT_LEVEL newThreatLevel = 
SecurityLevels.parsePhysicalThreatLevel(physicalThreatLevel);
+                       if(newThreatLevel == null) {
+                               super.writeTemporaryRedirect(ctx, "step1", 
TOADLET_URL+"?step="+WIZARD_STEP.SECURITY_PHYSICAL);
                                return;
                        }
-                       super.writeTemporaryRedirect(ctx, "step1", 
TOADLET_URL+"?step="+WIZARD_STEP.NAME_SELECTION+"&opennet="+enable);
-                       return;
+                       core.node.securityLevels.setThreatLevel(newThreatLevel);
+                       core.storeConfig();
+                       super.writeTemporaryRedirect(ctx, "step1", 
TOADLET_URL+"?step="+WIZARD_STEP.NAME_SELECTION+"&opennet="+core.node.isOpennetEnabled());
                } else if(request.isPartSet("nnameF")) {
                        String selectedNName = request.getPartAsString("nname", 
128);
                        try {
@@ -369,8 +512,8 @@
                long freeSpace = -1;
                File dir = FileUtil.getCanonicalFile(core.node.getNodeDir());
                try {
-                       Class c = dir.getClass();
-                       Method m = c.getDeclaredMethod("getFreeSpace", new 
Class[0]);
+                       Class<? extends File> c = dir.getClass();
+                       Method m = c.getDeclaredMethod("getFreeSpace", new 
Class<?>[0]);
                        if(m != null) {
                                Long lFreeSpace = (Long) m.invoke(dir, new 
Object[0]);
                                if(lFreeSpace != null) {

Modified: branches/db4o/freenet/src/freenet/clients/http/PageMaker.java
===================================================================
--- branches/db4o/freenet/src/freenet/clients/http/PageMaker.java       
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/clients/http/PageMaker.java       
2008-09-24 23:54:07 UTC (rev 22829)
@@ -255,6 +255,10 @@
        }

        protected int drawModeSelectionArray(NodeClientCore core, HTTPRequest 
req, HTMLNode contentNode) {
+               return drawModeSelectionArray(core, req, contentNode, -1, null, 
null);
+       }
+       
+       protected int drawModeSelectionArray(NodeClientCore core, HTTPRequest 
req, HTMLNode contentNode, int alternateMode, String alternateModeTitleKey, 
String alternateModeTooltipKey) {
                // Mode can be changed by a link, not just by the default

                int mode = core.isAdvancedModeEnabled() ? MODE_ADVANCED : 
MODE_SIMPLE;
@@ -268,6 +272,14 @@
                HTMLNode row = table.addChild("tr");
                HTMLNode cell = row.addChild("td");

+               if(alternateMode > -1) {
+                       if(mode != alternateMode)
+                               cell.addChild("a", new String[] { "href", 
"title" }, new String[] { "?mode="+alternateMode, 
L10n.getString(alternateModeTooltipKey) }, 
L10n.getString(alternateModeTitleKey));
+                       else
+                               cell.addChild("b", "title", 
L10n.getString(alternateModeTooltipKey), L10n.getString(alternateModeTitleKey));
+                       cell = row.addChild("td");
+               }
+               
                if(mode != MODE_SIMPLE)
                        cell.addChild("a", new String[] { "href", "title" }, 
new String[] { "?mode=1", l10n("modeSimpleTooltip") }, l10n("modeSimple"));
                else
@@ -277,7 +289,6 @@
                        cell.addChild("a", new String[] { "href", "title" }, 
new String[] { "?mode=2", l10n("modeAdvancedTooltip") }, l10n("modeAdvanced"));
                else
                        cell.addChild("b", "title", 
l10n("modeAdvancedTooltip"), l10n("modeAdvanced"));
-               
                return mode;
        }


Modified: branches/db4o/freenet/src/freenet/clients/http/PproxyToadlet.java
===================================================================
--- branches/db4o/freenet/src/freenet/clients/http/PproxyToadlet.java   
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/clients/http/PproxyToadlet.java   
2008-09-24 23:54:07 UTC (rev 22829)
@@ -39,10 +39,12 @@
                this.core = core;
        }

+       @Override
        public String supportedMethods() {
                return "GET, POST";
        }

+       @Override
        public void handlePost(URI uri, HTTPRequest request, ToadletContext ctx)
        throws ToadletContextClosedException, IOException {

@@ -255,9 +257,9 @@
         *         no plugin was found
         */
        private String getPluginSpecification(PluginManager pluginManager, 
String pluginThreadName) {
-               Iterator it = pluginManager.getPlugins().iterator();
+               Iterator<PluginInfoWrapper> it = 
pluginManager.getPlugins().iterator();
                while (it.hasNext()) {
-                       PluginInfoWrapper pi = (PluginInfoWrapper) it.next();
+                       PluginInfoWrapper pi = it.next();
                        if (pi.getThreadName().equals(pluginThreadName)) {
                                return pi.getFilename();
                        }
@@ -273,6 +275,7 @@
                return L10n.getString("PproxyToadlet."+key);
        }

+       @Override
        public void handleGet(URI uri, HTTPRequest request, ToadletContext ctx)
        throws ToadletContextClosedException, IOException {

@@ -294,7 +297,7 @@
                                        return;
                                }

-                               Iterator/* <PluginProgress> */loadingPlugins = 
pm.getStartingPlugins().iterator();
+                               Iterator<PluginProgress> loadingPlugins = 
pm.getStartingPlugins().iterator();

                                HTMLNode pageNode = 
ctx.getPageMaker().getPageNode(l10n("pluginsWithNodeName", "name", 
core.getMyName()), ctx);
                                if (loadingPlugins.hasNext()) {
@@ -316,15 +319,15 @@

                                /* find which plugins have already been loaded. 
*/
                                List<String> availablePlugins = 
pm.findAvailablePlugins();
-                               Iterator/*<PluginInfoWrapper>*/ loadedPlugins = 
pm.getPlugins().iterator();
+                               Iterator<PluginInfoWrapper> loadedPlugins = 
pm.getPlugins().iterator();
                                while (loadedPlugins.hasNext()) {
-                                       PluginInfoWrapper pluginInfoWrapper = 
(PluginInfoWrapper) loadedPlugins.next();
+                                       PluginInfoWrapper pluginInfoWrapper = 
loadedPlugins.next();
                                        String pluginName = 
pluginInfoWrapper.getPluginClassName();
                                        String shortPluginName = 
pluginName.substring(pluginName.lastIndexOf('.') + 1);
                                        
availablePlugins.remove(shortPluginName);
                                }
                                while (loadingPlugins.hasNext()) {
-                                       PluginProgress pluginProgress = 
(PluginProgress) loadingPlugins.next();
+                                       PluginProgress pluginProgress = 
loadingPlugins.next();
                                        String pluginName = 
pluginProgress.getName();
                                        availablePlugins.remove(pluginName);
                                }
@@ -383,7 +386,7 @@
         *            The node to add content to
         */
        private void showStartingPlugins(PluginManager pluginManager, HTMLNode 
contentNode) {
-               Set/*<PluginProgress>*/ startingPlugins = 
pluginManager.getStartingPlugins();
+               Set<PluginProgress> startingPlugins = 
pluginManager.getStartingPlugins();
                if (!startingPlugins.isEmpty()) {
                        HTMLNode startingPluginsBox = 
contentNode.addChild("div", "class", "infobox infobox-normal");
                        startingPluginsBox.addChild("div", "class", 
"infobox-header", l10n("startingPluginsTitle"));
@@ -393,9 +396,9 @@
                        startingPluginsHeader.addChild("th", 
l10n("startingPluginName"));
                        startingPluginsHeader.addChild("th", 
l10n("startingPluginStatus"));
                        startingPluginsHeader.addChild("th", 
l10n("startingPluginTime"));
-                       Iterator/*<PluginProgress>*/ startingPluginsIterator = 
startingPlugins.iterator();
+                       Iterator<PluginProgress> startingPluginsIterator = 
startingPlugins.iterator();
                        while (startingPluginsIterator.hasNext()) {
-                               PluginProgress pluginProgress = 
(PluginProgress) startingPluginsIterator.next();
+                               PluginProgress pluginProgress = 
startingPluginsIterator.next();
                                HTMLNode startingPluginsRow = 
startingPluginsTable.addChild("tr");
                                startingPluginsRow.addChild("td", 
pluginProgress.getName());
                                startingPluginsRow.addChild("td", 
l10n("startingPluginStatus." + pluginProgress.getProgress().toString()));
@@ -420,9 +423,9 @@
                        headerRow.addChild("th");
                        headerRow.addChild("th");
                        headerRow.addChild("th");
-                       Iterator it = pm.getPlugins().iterator();
+                       Iterator<PluginInfoWrapper> it = 
pm.getPlugins().iterator();
                        while (it.hasNext()) {
-                               PluginInfoWrapper pi = (PluginInfoWrapper) 
it.next();
+                               PluginInfoWrapper pi = it.next();
                                HTMLNode pluginRow = pluginTable.addChild("tr");
                                pluginRow.addChild("td", 
pi.getPluginClassName());
                                pluginRow.addChild("td", pi.getPluginVersion());
@@ -450,7 +453,7 @@
                }
        }

-       private void showOfficialPluginLoader(ToadletContext toadletContext, 
HTMLNode contentNode, List/*<String>*/ availablePlugins) {
+       private void showOfficialPluginLoader(ToadletContext toadletContext, 
HTMLNode contentNode, List<String> availablePlugins) {
                /* box for "official" plugins. */
                HTMLNode addOfficialPluginBox = contentNode.addChild("div", 
"class", "infobox infobox-normal");
                addOfficialPluginBox.addChild("div", "class", "infobox-header", 
l10n("loadOfficialPlugin"));
@@ -461,9 +464,9 @@
                addOfficialForm.addChild("p").addChild("b").addChild("font", 
new String[] { "color" }, new String[] { "red" }, 
l10n("loadOfficialPluginWarning"));
                addOfficialForm.addChild("#", (l10n("loadOfficialPluginLabel") 
+ ": "));
                HTMLNode selectNode = addOfficialForm.addChild("select", 
"name", "plugin-name");
-               Iterator/*<String>*/ availablePluginIterator = 
availablePlugins.iterator();
+               Iterator<String> availablePluginIterator = 
availablePlugins.iterator();
                while (availablePluginIterator.hasNext()) {
-                       String pluginName = (String) 
availablePluginIterator.next();
+                       String pluginName = availablePluginIterator.next();
                        selectNode.addChild("option", "value", pluginName, 
pluginName);
                }
                addOfficialForm.addChild("#", " ");

Modified: branches/db4o/freenet/src/freenet/clients/http/StatisticsToadlet.java
===================================================================
--- branches/db4o/freenet/src/freenet/clients/http/StatisticsToadlet.java       
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/clients/http/StatisticsToadlet.java       
2008-09-24 23:54:07 UTC (rev 22829)
@@ -494,6 +494,8 @@
                long storeAccesses = storeHits + storeMisses;
                long cacheWrites=node.getChkDatacache().writes();
                long storeWrites=node.getChkDatastore().writes();
+               long cacheFalsePos = 
node.getChkDatacache().getBloomFalsePositive();
+               long storeFalsePos = 
node.getChkDatastore().getBloomFalsePositive();

                // REDFLAG Don't show database version because it's not 
possible to get it accurately.
                // (It's a public static constant, so it will use the version 
from compile time of freenet.jar)
@@ -568,6 +570,13 @@
                row.addChild("td", 
fix1p2.format(1.0*storeWrites/nodeUptimeSeconds)+" /sec");
                row.addChild("td", 
fix1p2.format(1.0*cacheWrites/nodeUptimeSeconds)+" /sec");

+               if (storeFalsePos != -1 || cacheFalsePos != -1) {
+                       row = storeSizeTable.addChild("tr");
+                       row.addChild("td", "False Pos.");
+                       row.addChild("td", thousendPoint.format(storeFalsePos));
+                       row.addChild("td", thousendPoint.format(cacheFalsePos));
+               }
+               
                // location-based stats
                double nodeLoc=0.0;


Modified: branches/db4o/freenet/src/freenet/clients/http/ToadletContextImpl.java
===================================================================
--- branches/db4o/freenet/src/freenet/clients/http/ToadletContextImpl.java      
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/clients/http/ToadletContextImpl.java      
2008-09-24 23:54:07 UTC (rev 22829)
@@ -179,7 +179,7 @@
                        mvt.put("connection", "close");
                else
                        mvt.put("connection", "keep-alive");
-               StringBuffer buf = new StringBuffer(1024);
+               StringBuilder buf = new StringBuilder(1024);
                buf.append("HTTP/1.1 ");
                buf.append(replyCode);
                buf.append(' ');
@@ -215,7 +215,7 @@
         * send something as close to the spec as possible in case of broken 
clients... 
         */
        private static String fixKey(String key) {
-               StringBuffer sb = new StringBuffer(key.length());
+               StringBuilder sb = new StringBuilder(key.length());
                char prev = 0;
                for(int i=0;i<key.length();i++) {
                        char c = key.charAt(i);

Modified: branches/db4o/freenet/src/freenet/clients/http/TranslationToadlet.java
===================================================================
--- branches/db4o/freenet/src/freenet/clients/http/TranslationToadlet.java      
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/clients/http/TranslationToadlet.java      
2008-09-24 23:54:07 UTC (rev 22829)
@@ -32,6 +32,7 @@
                this.core = core;
        }

+       @Override
        public void handleGet(URI uri, HTTPRequest request, ToadletContext ctx) 
throws ToadletContextClosedException, IOException {
                if(!ctx.isAllowedFullAccess()) {
                        super.sendErrorPage(ctx, 403, "Unauthorized", 
L10n.getString("Toadlet.unauthorized"));
@@ -40,6 +41,7 @@

                boolean showEverything = 
!request.isParameterSet("toTranslateOnly");

+               
                if (request.isParameterSet("getOverrideTranlationFile")) {
                        SimpleFieldSet sfs = 
L10n.getOverrideForCurrentLanguageTranslation();
                        if(sfs == null) {
@@ -86,6 +88,7 @@
                        this.writeHTMLReply(ctx, 200, "OK", 
pageNode.generate());
                        return;                         
                } else if (request.isParameterSet("translate")) {
+                       boolean gotoNext = request.isParameterSet("gotoNext");
                        String key = request.getParam("translate");
                        HTMLNode pageNode = 
ctx.getPageMaker().getPageNode(l10n("translationUpdateTitle"), true, ctx);
                        HTMLNode contentNode = 
ctx.getPageMaker().getContentNode(pageNode);
@@ -110,7 +113,7 @@
                        contentRow.addChild("td", "class", 
"translation-new").addChild(
                                        "textarea",
                                        new String[] { "name", "rows", "cols" },
-                                       new String[] { "trans", "3", "80" },
+                                       new String[] { "trans", "6", "80" },
                                        L10n.getString(key));

                        contentRow.addChild("input", 
@@ -122,6 +125,7 @@
                                        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 });

@@ -191,6 +195,7 @@
                this.writeHTMLReply(ctx, 200, "OK", pageNode.generate());
        }

+       @Override
        public void handlePost(URI uri, HTTPRequest request, ToadletContext 
ctx) throws ToadletContextClosedException, IOException {
                if(!ctx.isAllowedFullAccess()) {
                        super.sendErrorPage(ctx, 403, "Unauthorized", 
L10n.getString("Toadlet.unauthorized"));
@@ -206,17 +211,33 @@
                        return;
                }

+               boolean toTranslateOnly = request.isPartSet("toTranslateOnly");
+               
                if(request.getPartAsString("translation_update", 32).length() > 
0){
                        String key = request.getPartAsString("key", 256);
                        L10n.setOverride(key, new 
String(BucketTools.toByteArray(request.getPart("trans")), "UTF-8").trim());

-                       redirectTo(ctx, 
TOADLET_URL+"?translation_updated="+key+ (request.isPartSet("toTranslateOnly") 
? "&toTranslateOnly" : ""));
+                       
if("on".equalsIgnoreCase(request.getPartAsString("gotoNext", 7))) {
+                               KeyIterator it = 
DEFAULT_TRANSLATION.keyIterator("");
+                               
+                               while(it.hasNext()) {
+                                       String newKey = it.nextKey();
+                                       boolean isOverriden = 
L10n.isOverridden(newKey);
+                                       System.out.println("newkey:"+newKey);
+                                       if(isOverriden || 
(L10n.getString(newKey, true) != null))
+                                               continue;
+                                       redirectTo(ctx, 
TOADLET_URL+"?gotoNext&translate="+newKey+ (toTranslateOnly ? 
"&toTranslateOnly" : ""));
+                                       return;
+                               }
+                       }
+                       
+                       redirectTo(ctx, 
TOADLET_URL+"?translation_updated="+key+ (toTranslateOnly ? "&toTranslateOnly" 
: ""));
                        return;
                } else if(request.getPartAsString("remove_confirmed", 
32).length() > 0) {
                        String key = request.getPartAsString("remove_confirm", 
256).trim();
                        L10n.setOverride(key, "");

-                       redirectTo(ctx, 
TOADLET_URL+"?translation_updated="+key+ (request.isPartSet("toTranslateOnly") 
? "&toTranslateOnly" : ""));
+                       redirectTo(ctx, 
TOADLET_URL+"?translation_updated="+key+ (toTranslateOnly ? "&toTranslateOnly" 
: ""));
                        return;
                }else // Shouldn't reach that point!
                        redirectTo(ctx, "/");

Modified: branches/db4o/freenet/src/freenet/clients/http/WelcomeToadlet.java
===================================================================
--- branches/db4o/freenet/src/freenet/clients/http/WelcomeToadlet.java  
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/clients/http/WelcomeToadlet.java  
2008-09-24 23:54:07 UTC (rev 22829)
@@ -569,7 +569,8 @@

         HTMLNode bookmarkBoxContent = bookmarkBox.addChild("div", "class", 
"infobox-content");
         HTMLNode bookmarksList = bookmarkBoxContent.addChild("ul", "id", 
"bookmarks");
-        addCategoryToList(BookmarkManager.MAIN_CATEGORY, bookmarksList, 
useragent != null && useragent.toLowerCase().indexOf("khtml") >= 0);
+       String userAgent = useragent.toLowerCase();
+        addCategoryToList(BookmarkManager.MAIN_CATEGORY, bookmarksList, 
useragent != null && userAgent.contains("khtml") && 
!userAgent.contains("chrome"));

         // Fetch-a-key box
         HTMLNode fetchKeyBox = 
contentNode.addChild(ctx.getPageMaker().getInfobox("infobox-normal", 
l10n("fetchKeyLabel")));

Modified: 
branches/db4o/freenet/src/freenet/clients/http/filter/CSSTokenizerFilter.java
===================================================================
--- 
branches/db4o/freenet/src/freenet/clients/http/filter/CSSTokenizerFilter.java   
    2008-09-24 23:18:12 UTC (rev 22828)
+++ 
branches/db4o/freenet/src/freenet/clients/http/filter/CSSTokenizerFilter.java   
    2008-09-24 23:54:07 UTC (rev 22829)
@@ -965,11 +965,11 @@
                                quote = q;
                                s = s.substring(1);
                        } else quote = ' ';
-                       StringBuffer buffer = new StringBuffer();
+                       StringBuilder buffer = new StringBuilder();
                        int x = 0;
                        boolean justEscaping = false;
                        boolean stillEscaping = false;
-                       StringBuffer hexEscape = new StringBuffer();
+                       StringBuilder hexEscape = new StringBuilder();
                        while(x < s.length()) {
                                char c = s.charAt(x);
                                x++;
@@ -1006,7 +1006,7 @@
                                                        buffer.append(c);
                                                }
                                                stillEscaping = false;
-                                               hexEscape = new StringBuffer();
+                                               hexEscape = new StringBuilder();
                                        } else {
                                                int d = 
Integer.parseInt(hexEscape.toString(),
                                                                         16);
@@ -1024,7 +1024,7 @@
                                                }
                                                buffer.append(c);
                                                stillEscaping = false;
-                                               hexEscape = new StringBuffer();
+                                               hexEscape = new StringBuilder();
                                        }
                                } else {
                                        if(quote != ' ' && c == quote) {
@@ -1048,7 +1048,7 @@
                }

                public String toString() {
-                       StringBuffer out = new StringBuffer();
+                       StringBuilder out = new StringBuilder();
                        if(url) out.append("url(");
                        if(quote != ' ') out.append(quote);
                        out.append(unescapeData());
@@ -1059,7 +1059,7 @@
                }

                public String unescapeData() {
-                       StringBuffer sb = new StringBuffer();
+                       StringBuilder sb = new StringBuilder();
                        for(int i=0;i<data.length();i++) {
                                char c = data.charAt(i);
                                if(c == quote || c == '\n') {
@@ -1072,7 +1072,7 @@
        }

        String commentEncode(String s) {
-               StringBuffer sb = new StringBuffer(s.length());
+               StringBuilder sb = new StringBuilder(s.length());
                for(int i=0;i<s.length();i++) {
                        char c = s.charAt(i);
                        if(c == '/')
@@ -1566,7 +1566,7 @@
         case 55: break;
         case 22: 
           { String s = yytext();
-       StringBuffer sb = new StringBuffer(s.length());
+       StringBuilder sb = new StringBuilder(s.length());
        sb.append("/* ");
        boolean inPrefix = true;
        for(int i=2;i<s.length()-2;i++) {

Modified: 
branches/db4o/freenet/src/freenet/clients/http/filter/GenericReadFilterCallback.java
===================================================================
--- 
branches/db4o/freenet/src/freenet/clients/http/filter/GenericReadFilterCallback.java
        2008-09-24 23:18:12 UTC (rev 22828)
+++ 
branches/db4o/freenet/src/freenet/clients/http/filter/GenericReadFilterCallback.java
        2008-09-24 23:54:07 UTC (rev 22829)
@@ -218,7 +218,7 @@
                        // would be much easier if we had a component-wise 
constructor for URI that didn't 
                        // re-encode, but at least it works...

-                       StringBuffer sb = new StringBuffer();
+                       StringBuilder sb = new StringBuilder();
                        sb.append(path);
                        if(typeOverride != null) {
                                sb.append("?type=");

Modified: branches/db4o/freenet/src/freenet/clients/http/filter/HTMLFilter.java
===================================================================
--- branches/db4o/freenet/src/freenet/clients/http/filter/HTMLFilter.java       
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/clients/http/filter/HTMLFilter.java       
2008-09-24 23:54:07 UTC (rev 22829)
@@ -148,8 +148,8 @@
                         * whitespace -> (1)
                         * </p>
                         */
-                       StringBuffer b = new StringBuffer(100);
-                       StringBuffer balt = new StringBuffer(4000);
+                       StringBuilder b = new StringBuilder(100);
+                       StringBuilder balt = new StringBuilder(4000);
                        Vector splitTag = new Vector();
                        String currentTag = null;
                        char pprevC = 0;
@@ -356,11 +356,11 @@
                boolean killStyle = false;
                int styleScriptRecurseCount = 0;
                String currentStyleScriptChunk = "";
-               StringBuffer writeAfterTag = new StringBuffer(1024);
+               StringBuilder writeAfterTag = new StringBuilder(1024);
        }


-       void saveText(StringBuffer s, String tagName, Writer w, 
HTMLParseContext pc)
+       void saveText(StringBuilder s, String tagName, Writer w, 
HTMLParseContext pc)
                throws IOException {

                if(pc.noOutput) return;
@@ -386,7 +386,7 @@
                        pc.currentStyleScriptChunk += style;
                        return; // is parsed and written elsewhere
                }
-               StringBuffer out = new StringBuffer(s.length()*2);
+               StringBuilder out = new StringBuilder(s.length()*2);
                for(int i=0;i<s.length();i++) {
                        char c = s.charAt(i);
                        if(c == '<') {
@@ -426,7 +426,7 @@
                                t.write(w);
                                if (pc.writeAfterTag.length() > 0) {
                                        w.write(pc.writeAfterTag.toString());
-                                       pc.writeAfterTag = new 
StringBuffer(1024);
+                                       pc.writeAfterTag = new 
StringBuilder(1024);
                                }
                        } else
                                pc.writeStyleScriptWithTag = false;
@@ -436,7 +436,7 @@
                }
        }

-       void saveComment(StringBuffer s, Writer w, HTMLParseContext pc)
+       void saveComment(StringBuilder s, Writer w, HTMLParseContext pc)
                throws IOException {
                if(pc.noOutput) return;
                if((s.length() > 3) && (s.charAt(0) == '!') && (s.charAt(1) == 
'-') && (s.charAt(2) == '-')) {
@@ -458,7 +458,7 @@
                        pc.killTag = false;
                        return;
                }
-               StringBuffer sb = new StringBuffer();
+               StringBuilder sb = new StringBuilder();
                for(int i=0;i<s.length();i++) {
                        char c = s.charAt(i);
                        if(c == '<') {
@@ -551,7 +551,7 @@
                public String toString() {
                        if (element == null)
                                return "";
-                       StringBuffer sb = new StringBuffer("<");
+                       StringBuilder sb = new StringBuilder("<");
                        if (startSlash)
                                sb.append('/');
                        sb.append(element);
@@ -1215,7 +1215,7 @@
                                        y = (String) o;
                                else
                                        y = null;
-                               StringBuffer out = new StringBuffer(x);
+                               StringBuilder out = new StringBuilder(x);
                                if (y != null)
                                        out.append( "=\"" ).append( y ).append( 
'"' );
                                outAttrs[i++] = out.toString();
@@ -1964,7 +1964,7 @@
        }

        static String escapeQuotes(String s) {
-               StringBuffer buf = new StringBuffer(s.length());
+               StringBuilder buf = new StringBuilder(s.length());
                for (int x = 0; x < s.length(); x++) {
                        char c = s.charAt(x);
                        if (c == '\"') {

Modified: branches/db4o/freenet/src/freenet/clients/http/filter/JPEGFilter.java
===================================================================
--- branches/db4o/freenet/src/freenet/clients/http/filter/JPEGFilter.java       
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/clients/http/filter/JPEGFilter.java       
2008-09-24 23:54:07 UTC (rev 22829)
@@ -375,7 +375,7 @@
        }

        private String readNullTerminatedAsciiString(DataInputStream dis) 
throws IOException {
-               StringBuffer sb = new StringBuffer();
+               StringBuilder sb = new StringBuilder();
                while(true) {
                        int x = dis.read();
                        if(x == -1)

Modified: 
branches/db4o/freenet/src/freenet/clients/http/filter/KnownUnsafeContentTypeException.java
===================================================================
--- 
branches/db4o/freenet/src/freenet/clients/http/filter/KnownUnsafeContentTypeException.java
  2008-09-24 23:18:12 UTC (rev 22828)
+++ 
branches/db4o/freenet/src/freenet/clients/http/filter/KnownUnsafeContentTypeException.java
  2008-09-24 23:54:07 UTC (rev 22829)
@@ -16,7 +16,7 @@
        }

        public String getExplanation() {
-               StringBuffer sb = new StringBuffer();
+               StringBuilder sb = new StringBuilder();
                sb.append("<p><b>");
                sb.append(type.readDescription);
                sb.append("</b></p>\n" + "<p>" + l10n("knownUnsafe") + "<ul>");

Modified: branches/db4o/freenet/src/freenet/clients/http/filter/PNGFilter.java
===================================================================
--- branches/db4o/freenet/src/freenet/clients/http/filter/PNGFilter.java        
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/clients/http/filter/PNGFilter.java        
2008-09-24 23:54:07 UTC (rev 22829)
@@ -154,7 +154,7 @@

                                // Type of the chunk : Should match [a-zA-Z]{4}
                                dis.readFully(lengthBytes);
-                               StringBuffer sb = new StringBuffer();
+                               StringBuilder sb = new StringBuilder();
                                byte[] chunkTypeBytes = new byte[4];
                                for(int i = 0; i < 4; i++) {
                                        char val = (char) lengthBytes[i];

Modified: 
branches/db4o/freenet/src/freenet/clients/http/staticfiles/defaultbookmarks.dat
===================================================================
--- 
branches/db4o/freenet/src/freenet/clients/http/staticfiles/defaultbookmarks.dat 
    2008-09-24 23:18:12 UTC (rev 22828)
+++ 
branches/db4o/freenet/src/freenet/clients/http/staticfiles/defaultbookmarks.dat 
    2008-09-24 23:54:07 UTC (rev 22829)
@@ -7,19 +7,19 @@
 BookmarkCategory0.Content.Bookmark0.Name=The Ultimate FreeNet Index
 BookmarkCategory0.Content.Bookmark0.Description=A new one-page index with a 
menu including categories
 BookmarkCategory0.Content.Bookmark0.hasAnActivelink=true
-BookmarkCategory0.Content.Bookmark0.URI=USK at 
0I8gctpUE32CM0iQhXaYpCMvtPPGfT4pjXm01oid5Zc,3dAcn4fX2LyxO6uCnWFTx-2HKZ89uruurcKwLSCxbZ4,AQACAAE/Ultimate-Freenet-Index/28/
+BookmarkCategory0.Content.Bookmark0.URI=USK at 
0I8gctpUE32CM0iQhXaYpCMvtPPGfT4pjXm01oid5Zc,3dAcn4fX2LyxO6uCnWFTx-2HKZ89uruurcKwLSCxbZ4,AQACAAE/Ultimate-Freenet-Index/31/
 BookmarkCategory0.Content.Bookmark3.Name=Index des sites Fran?ais
 BookmarkCategory0.Content.Bookmark3.Description=A small French index with 
descriptions
 BookmarkCategory0.Content.Bookmark3.hasAnActivelink=true
-BookmarkCategory0.Content.Bookmark3.URI=USK at 
RJnh1EnvOSPwOWVRS2nyhC4eIQkKoNE5hcTv7~yY-sM,pOloLxnKWM~AL24iDMHOAvTvCqMlB-p2BO9zK96TOZA,AQACAAE/index_fr/61/
+BookmarkCategory0.Content.Bookmark3.URI=USK at 
RJnh1EnvOSPwOWVRS2nyhC4eIQkKoNE5hcTv7~yY-sM,pOloLxnKWM~AL24iDMHOAvTvCqMlB-p2BO9zK96TOZA,AQACAAE/index_fr/64/
 BookmarkCategory0.Content.Bookmark2.Name=Freenet Activelink Index (SLOW: 
graphical index, preloads all the sites, so takes *ages* to load)
 BookmarkCategory0.Content.Bookmark2.hasAnActivelink=true
 BookmarkCategory0.Content.Bookmark2.Description=A graphical freenet index 
(this will take a long time to load as it preloads the sites)
-BookmarkCategory0.Content.Bookmark2.URI=USK at 
qd-hk0vHYg7YvK2BQsJMcUD5QSF0tDkgnnF6lnWUH0g,xTFOV9ddCQQk6vQ6G~jfL6IzRUgmfMcZJ6nuySu~NUc,AQACAAE/activelink-index/78/
+BookmarkCategory0.Content.Bookmark2.URI=USK at 
qd-hk0vHYg7YvK2BQsJMcUD5QSF0tDkgnnF6lnWUH0g,xTFOV9ddCQQk6vQ6G~jfL6IzRUgmfMcZJ6nuySu~NUc,AQACAAE/activelink-index/82/
 BookmarkCategory0.Content.Bookmark1.Name=Freenet Activelink Index Text Version 
(a quick-loading non-graphical index site, no porn)
 BookmarkCategory0.Content.Bookmark1.hasAnActivelink=true
 BookmarkCategory0.Content.Bookmark1.Description=Text version of the Activelink 
Index
-BookmarkCategory0.Content.Bookmark1.URI=USK at 
qd-hk0vHYg7YvK2BQsJMcUD5QSF0tDkgnnF6lnWUH0g,xTFOV9ddCQQk6vQ6G~jfL6IzRUgmfMcZJ6nuySu~NUc,AQACAAE/activelink-index-text/39/
+BookmarkCategory0.Content.Bookmark1.URI=USK at 
qd-hk0vHYg7YvK2BQsJMcUD5QSF0tDkgnnF6lnWUH0g,xTFOV9ddCQQk6vQ6G~jfL6IzRUgmfMcZJ6nuySu~NUc,AQACAAE/activelink-index-text/43/
 BookmarkCategory1.Name=Freenet devel's flogs
 BookmarkCategory1.Content.BookmarkCategory=0
 BookmarkCategory1.Content.Bookmark=5
@@ -49,7 +49,7 @@
 BookmarkCategory2.Content.Bookmark0.Name=Freenet Message System
 BookmarkCategory2.Content.Bookmark0.Description=The official freesite of FMS, 
a spam resistant message board system for Freenet
 BookmarkCategory2.Content.Bookmark0.hasAnActivelink=true
-BookmarkCategory2.Content.Bookmark0.URI=USK at 
0npnMrqZNKRCRoGojZV93UNHCMN-6UU3rRSAmP6jNLE,~BG-edFtdCC1cSH4O3BWdeIYa8Sw5DfyrSV-TKdO5ec,AQACAAE/fms/78/
+BookmarkCategory2.Content.Bookmark0.URI=USK at 
0npnMrqZNKRCRoGojZV93UNHCMN-6UU3rRSAmP6jNLE,~BG-edFtdCC1cSH4O3BWdeIYa8Sw5DfyrSV-TKdO5ec,AQACAAE/fms/80/
 BookmarkCategory2.Content.Bookmark1.Name=Freemail
 BookmarkCategory2.Content.Bookmark1.Description=The official site for Freemail 
- email over Freenet
 BookmarkCategory2.Content.Bookmark1.hasAnActivelink=true

Modified: branches/db4o/freenet/src/freenet/config/Config.java
===================================================================
--- branches/db4o/freenet/src/freenet/config/Config.java        2008-09-24 
23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/config/Config.java        2008-09-24 
23:54:07 UTC (rev 22829)
@@ -39,7 +39,7 @@
                // Do nothing
        }

-       public void onRegister(SubConfig config, Option o) {
+       public void onRegister(SubConfig config, Option<?> o) {
                // Do nothing
        }


Modified: 
branches/db4o/freenet/src/freenet/config/InvalidConfigValueException.java
===================================================================
--- branches/db4o/freenet/src/freenet/config/InvalidConfigValueException.java   
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/config/InvalidConfigValueException.java   
2008-09-24 23:54:07 UTC (rev 22829)
@@ -10,8 +10,8 @@
  * it merely means that there are no immediately detectable problems with 
  * it.
  */
+ at SuppressWarnings("serial")
 public class InvalidConfigValueException extends ConfigException {
-
        public InvalidConfigValueException(String msg) {
                super(msg);
        }

Modified: branches/db4o/freenet/src/freenet/config/NodeNeedRestartException.java
===================================================================
--- branches/db4o/freenet/src/freenet/config/NodeNeedRestartException.java      
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/config/NodeNeedRestartException.java      
2008-09-24 23:54:07 UTC (rev 22829)
@@ -8,8 +8,8 @@
  * The thrower must ensure that the value reaches the config file, even though
  * it cannot be immediately used.
  */
+ at SuppressWarnings("serial")
 public class NodeNeedRestartException extends ConfigException {
-
        public NodeNeedRestartException(String msg) {
                super(msg);
        }

Modified: branches/db4o/freenet/src/freenet/config/PersistentConfig.java
===================================================================
--- branches/db4o/freenet/src/freenet/config/PersistentConfig.java      
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/config/PersistentConfig.java      
2008-09-24 23:54:07 UTC (rev 22829)
@@ -23,9 +23,9 @@
        public synchronized void finishedInit() {
                finishedInit = true;
                if(origConfigFileContents == null) return;
-               Iterator i = origConfigFileContents.keyIterator();
+               Iterator<String> i = origConfigFileContents.keyIterator();
                while(i.hasNext()) {
-                       String key = (String) i.next();
+                       String key = i.next();
                        Logger.error(this, "Unknown option: "+key+" 
(value="+origConfigFileContents.get(key)+ ')');
                }
                origConfigFileContents = null;
@@ -55,7 +55,7 @@
                return fs; 
        }

-       public void onRegister(SubConfig config, Option o) {
+       public void onRegister(SubConfig config, Option<?> o) {
                String val, name;
                synchronized(this) {
                        if(finishedInit)

Modified: branches/db4o/freenet/src/freenet/crypt/CryptoKey.java
===================================================================
--- branches/db4o/freenet/src/freenet/crypt/CryptoKey.java      2008-09-24 
23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/crypt/CryptoKey.java      2008-09-24 
23:54:07 UTC (rev 22829)
@@ -13,6 +13,7 @@
 import freenet.support.HexUtil;
 import freenet.support.Logger;

+ at SuppressWarnings("serial")
 public abstract class CryptoKey implements CryptoElement, Serializable {

        protected static final Digest shactx = SHA1.getInstance();
@@ -24,7 +25,7 @@
                DataInputStream dis = new DataInputStream(i);
                String type = dis.readUTF();
                try {
-                       Class keyClass = Class.forName(type);
+                       Class<?> keyClass = Class.forName(type);
                        Method m =
                                keyClass.getMethod("read", new Class[] { 
InputStream.class });
                        return (CryptoKey) m.invoke(null, new Object[] { dis });
@@ -56,13 +57,13 @@
        }

        public String verboseToString() {
-               StringBuffer b = new StringBuffer();
+               StringBuilder b = new StringBuilder();
                b.append(toString()).append('\t').append(fingerprintToString());
                return b.toString();
        }

        public String toString() {
-               StringBuffer b = new StringBuffer(keyType().length() + 1 + 4);
+               StringBuilder b = new StringBuilder(keyType().length() + 1 + 4);
                b.append(keyType()).append('/');
                HexUtil.bytesToHexAppend(fingerprint(), 16, 4, b);
                return b.toString();
@@ -74,7 +75,7 @@
 //
        public String fingerprintToString() {
                String fphex = HexUtil.bytesToHex(fingerprint());
-               StringBuffer b = new StringBuffer(40 + 10);
+               StringBuilder b = new StringBuilder(40 + 10);
                b
                        .append(fphex.substring(0, 4))
                        .append(' ')

Modified: branches/db4o/freenet/src/freenet/crypt/DHGroup.java
===================================================================
--- branches/db4o/freenet/src/freenet/crypt/DHGroup.java        2008-09-24 
23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/crypt/DHGroup.java        2008-09-24 
23:54:07 UTC (rev 22829)
@@ -30,7 +30,7 @@
        public String toLongString() {
                String pStr = HexUtil.biToHex(p);
                String gStr = HexUtil.biToHex(g);
-               StringBuffer b = new StringBuffer(pStr.length() + gStr.length() 
+ 1);
+               StringBuilder b = new StringBuilder(pStr.length() + 
gStr.length() + 1);
                b.append(pStr).append(',').append(gStr);
                return b.toString();
        }

Modified: branches/db4o/freenet/src/freenet/crypt/DiffieHellman.java
===================================================================
--- branches/db4o/freenet/src/freenet/crypt/DiffieHellman.java  2008-09-24 
23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/crypt/DiffieHellman.java  2008-09-24 
23:54:07 UTC (rev 22829)
@@ -6,14 +6,14 @@

 package freenet.crypt;

-import freenet.node.FNPPacketMangler;
 import java.math.BigInteger;
 import java.util.Random;
 import java.util.Stack;

+import net.i2p.util.NativeBigInteger;
+import freenet.node.FNPPacketMangler;
 import freenet.support.Logger;
 import freenet.support.io.NativeThread;
-import net.i2p.util.NativeBigInteger;

 public class DiffieHellman {

@@ -145,7 +145,7 @@
         * @see http://securitytracker.com/alerts/2005/Aug/1014739.html
         * @see http://www.it.iitb.ac.in/~praj/acads/netsec/FinalReport.pdf
         */
-       public static boolean checkDHExponentialValidity(Class caller, 
BigInteger exponential) {
+       public static boolean checkDHExponentialValidity(Class<?> caller, 
BigInteger exponential) {
                int onesCount=0, zerosCount=0;

                // Ensure that we have at least 16 bits of each gender

Modified: branches/db4o/freenet/src/freenet/crypt/DiffieHellmanLightContext.java
===================================================================
--- branches/db4o/freenet/src/freenet/crypt/DiffieHellmanLightContext.java      
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/crypt/DiffieHellmanLightContext.java      
2008-09-24 23:54:07 UTC (rev 22829)
@@ -19,7 +19,7 @@
        public final long lifetime = System.currentTimeMillis();

        public String toString() {
-               StringBuffer sb = new StringBuffer();
+               StringBuilder sb = new StringBuilder();
                sb.append(super.toString());
                sb.append(": myExponent=");
                sb.append(myExponent.toHexString());

Modified: branches/db4o/freenet/src/freenet/crypt/SHA1.java
===================================================================
--- branches/db4o/freenet/src/freenet/crypt/SHA1.java   2008-09-24 23:18:12 UTC 
(rev 22828)
+++ branches/db4o/freenet/src/freenet/crypt/SHA1.java   2008-09-24 23:54:07 UTC 
(rev 22829)
@@ -343,7 +343,7 @@
      * to the test vectors.
      */
     protected String digout() {
-        StringBuffer sb = new StringBuffer();
+        StringBuilder sb = new StringBuilder();
         for (int i = 0; i < 20; i++) {
             char c1, c2;


Modified: branches/db4o/freenet/src/freenet/crypt/SSL.java
===================================================================
--- branches/db4o/freenet/src/freenet/crypt/SSL.java    2008-09-24 23:18:12 UTC 
(rev 22828)
+++ branches/db4o/freenet/src/freenet/crypt/SSL.java    2008-09-24 23:54:07 UTC 
(rev 22829)
@@ -221,13 +221,13 @@
                                // If keystore not exist, create keystore and 
server certificate
                                keystore.load(null, keyStorePass.toCharArray());
                                try {
-                                       Class certAndKeyGenClazz = 
Class.forName("sun.security.x509.CertAndKeyGen");
-                                       Constructor certAndKeyGenCtor = 
certAndKeyGenClazz.getConstructor(String.class, String.class);
+                                       Class<?> certAndKeyGenClazz = 
Class.forName("sun.security.x509.CertAndKeyGen");
+                                       Constructor<?> certAndKeyGenCtor = 
certAndKeyGenClazz.getConstructor(String.class, String.class);
                                        Object keypair = 
certAndKeyGenCtor.newInstance("DSA", "SHA1WithDSA");

-                                       Class x500NameClazz = 
Class.forName("sun.security.x509.X500Name");
-                                       Constructor x500NameCtor = 
x500NameClazz.getConstructor(String.class, String.class, String.class,
-                                               String.class, String.class, 
String.class);
+                                       Class<?> x500NameClazz = 
Class.forName("sun.security.x509.X500Name");
+                                       Constructor<?> x500NameCtor = 
x500NameClazz.getConstructor(String.class, String.class,
+                                               String.class, String.class, 
String.class, String.class);
                                        Object x500Name = 
x500NameCtor.newInstance("Freenet", "Freenet", "Freenet", "", "", "");

                                        Method certAndKeyGenGenerate = 
certAndKeyGenClazz.getMethod("generate", int.class);
@@ -245,6 +245,8 @@
                                        keystore.setKeyEntry("freenet", 
privKey, keyPass.toCharArray(), chain);
                                        storeKeyStore();
                                        createSSLContext();
+                               } catch (ClassNotFoundException cnfe) {
+                                       throw new 
UnsupportedOperationException("The JVM you are using is not supported!", cnfe);
                                } catch (NoSuchMethodException nsme) {
                                        throw new 
UnsupportedOperationException("The JVM you are using is not supported!", nsme);
                                }

Modified: branches/db4o/freenet/src/freenet/crypt/Util.java
===================================================================
--- branches/db4o/freenet/src/freenet/crypt/Util.java   2008-09-24 23:18:12 UTC 
(rev 22828)
+++ branches/db4o/freenet/src/freenet/crypt/Util.java   2008-09-24 23:54:07 UTC 
(rev 22829)
@@ -8,14 +8,14 @@
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.math.BigInteger;
+import java.security.MessageDigest;
 import java.util.Arrays;
 import java.util.Random;

+import net.i2p.util.NativeBigInteger;
 import freenet.crypt.ciphers.Rijndael;
 import freenet.support.HexUtil;
 import freenet.support.Loader;
-import java.security.MessageDigest;
-import net.i2p.util.NativeBigInteger;

 public class Util {

@@ -230,7 +230,7 @@
                try {
                        return (BlockCipher) Loader.getInstance(
                                "freenet.crypt.ciphers." + name,
-                               new Class[] { Integer.class },
+                               new Class<?>[] { Integer.class },
                                new Object[] { new Integer(keySize)});
                } catch (Exception e) {
                        //throw new UnsupportedCipherException(""+e);

Modified: branches/db4o/freenet/src/freenet/frost/message/FrostMessage.java
===================================================================
--- branches/db4o/freenet/src/freenet/frost/message/FrostMessage.java   
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/frost/message/FrostMessage.java   
2008-09-24 23:54:07 UTC (rev 22829)
@@ -51,7 +51,7 @@
             String date = DateFun.getExtendedDateFromSqlDate(getSqlDate());
             String time = DateFun.getExtendedTimeFromSqlTime(getSqlTime());

-            StringBuffer sb = new StringBuffer(29);
+            StringBuilder sb = new StringBuilder(29);
             sb.append(date).append(" ").append(time);

             this.dateAndTime = sb.toString();
@@ -119,7 +119,7 @@
     public String getId() {
        Random rnd = new Random((new Date()).getTime());

-       StringBuffer sb = new StringBuffer();
+       StringBuilder sb = new StringBuilder();

        for(int i = 0; i<4; i++) {
                sb.append(Long.toHexString(rnd.nextLong()).toUpperCase());
@@ -191,12 +191,12 @@
     private final String getXml() {
        if(xml==null)
        {
-               String messageContent = new StringBuffer()
+               String messageContent = new StringBuilder()
                        .append("----- ").append(this.getName()).append(" ----- 
")
                        .append(this.getDateStr(true)).append(" - 
").append(this.getTimeStr()).append(" -----\n\n")
                        .append(this.getContent()).toString();

-               StringBuffer sb = new StringBuffer();
+               StringBuilder sb = new StringBuilder();
                sb.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
                sb.append("<FrostMessage>");

@@ -241,7 +241,7 @@
         FreenetURI key;
         if (board.isWriteAccessBoard()) {
             key = new FreenetURI(
-                       new StringBuffer()
+                       new StringBuilder()
                     .append(board.getPrivateKey())
                     .append('/')
                     .append(board.getName())
@@ -253,7 +253,7 @@
                     .toString());
         } else {
             key = new FreenetURI("KSK",
-                       new StringBuffer()
+                       new StringBuilder()
                     .append("frost|message|")
                     .append(this.getMessageBase())
                     .append('|')

Modified: branches/db4o/freenet/src/freenet/io/AddressTracker.java
===================================================================
--- branches/db4o/freenet/src/freenet/io/AddressTracker.java    2008-09-24 
23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/io/AddressTracker.java    2008-09-24 
23:54:07 UTC (rev 22829)
@@ -56,6 +56,7 @@
        private long timeDefinitelyNoPacketsSent;

        private boolean isBroken;
+       private long brokenTime;

        public static AddressTracker create(long lastBootID, File nodeDir, int 
port) {
                File data = new File(nodeDir, "packets-"+port+".dat");
@@ -191,7 +192,8 @@

        public static final int DEFINITELY_PORT_FORWARDED = 2;
        public static final int MAYBE_PORT_FORWARDED = 1;
-       public static final int DEFINITELY_NATED = -1;
+       public static final int MAYBE_NATED = -1;
+       public static final int DEFINITELY_NATED = -2;
        public static final int DONT_KNOW = 0;

        /** If the minimum gap is at least this, we might be port forwarded. 
@@ -229,20 +231,33 @@

        public int getPortForwardStatus() {
                long minGap = getLongestSendReceiveGap(HORIZON);
-               if(isBroken) return DEFINITELY_NATED;
+               
                if(minGap > DEFINITELY_TUNNEL_LENGTH)
                        return DEFINITELY_PORT_FORWARDED;
                if(minGap > MAYBE_TUNNEL_LENGTH)
                        return MAYBE_PORT_FORWARDED;
+               // Only take isBroken into account if we're not sure.
+               // Somebody could be playing with us by sending bogus 
FNPSentPackets...
+               synchronized(this) {
+                       if(isBroken()) return DEFINITELY_NATED;
+                       if(minGap == 0 && timePresumeGuilty > 0 && 
System.currentTimeMillis() > timePresumeGuilty)
+                               return MAYBE_NATED;
+               }
                return DONT_KNOW;
        }

+       private boolean isBroken() {
+               return System.currentTimeMillis() - brokenTime < HORIZON;
+       }
+
        public static String statusString(int status) {
                switch(status) {
                case DEFINITELY_PORT_FORWARDED:
                        return "Port forwarded";
                case MAYBE_PORT_FORWARDED:
                        return "Maybe port forwarded";
+               case MAYBE_NATED:
+                       return "Maybe behind NAT";
                case DEFINITELY_NATED:
                        return "Behind NAT";
                case DONT_KNOW:
@@ -255,7 +270,7 @@
        /** Persist the table to disk */
        public void storeData(long bootID, File nodeDir, int port) {
                // Don't write to disk if we know we're NATed anyway!
-               if(isBroken) return;
+               if(isBroken()) return;
                File data = new File(nodeDir, "packets-"+port+".dat");
                File dataBak = new File(nodeDir, "packets-"+port+".bak");
                data.delete();
@@ -314,6 +329,17 @@
        }

        public synchronized void setBroken() {
-               isBroken = true;
+               brokenTime = System.currentTimeMillis();
        }
+
+       private long timePresumeGuilty = -1;
+       
+       public synchronized void setPresumedGuiltyAt(long l) {
+               if(timePresumeGuilty <= 0)
+                       timePresumeGuilty = l;
+       }
+
+       public synchronized void setPresumedInnocent() {
+               timePresumeGuilty = -1;
+       }
 }

Modified: branches/db4o/freenet/src/freenet/io/AddressTrackerItem.java
===================================================================
--- branches/db4o/freenet/src/freenet/io/AddressTrackerItem.java        
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/io/AddressTrackerItem.java        
2008-09-24 23:54:07 UTC (rev 22829)
@@ -111,8 +111,6 @@
                        startTime = Math.max(startTime, 
timeDefinitelyNoPacketsReceived);
                }
                if(startTime <= 0) return; // No information
-               if(timeLastSentPacket > 0) startTime = timeLastSentPacket;
-               else startTime = timeDefinitelyNoPacketsSent;
                if(now - startTime > GAP_THRESHOLD) {
                        // Not necessarily a new gap
                        // If no packets sent since last one, just replace it

Modified: branches/db4o/freenet/src/freenet/io/AllowedHosts.java
===================================================================
--- branches/db4o/freenet/src/freenet/io/AllowedHosts.java      2008-09-24 
23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/io/AllowedHosts.java      2008-09-24 
23:54:07 UTC (rev 22829)
@@ -84,7 +84,7 @@
        }

        public synchronized String getAllowedHosts() {
-               StringBuffer sb = new StringBuffer();
+               StringBuilder sb = new StringBuilder();
                for(int i=0;i<addressMatchers.size();i++) {
                        AddressMatcher matcher = (AddressMatcher) 
addressMatchers.get(i);
                        if(matcher instanceof EverythingMatcher) return "*";

Modified: branches/db4o/freenet/src/freenet/io/Inet4AddressMatcher.java
===================================================================
--- branches/db4o/freenet/src/freenet/io/Inet4AddressMatcher.java       
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/io/Inet4AddressMatcher.java       
2008-09-24 23:54:07 UTC (rev 22829)
@@ -133,7 +133,7 @@
        }

        private String convertToString(int addr) {
-               StringBuffer sb = new StringBuffer();
+               StringBuilder sb = new StringBuilder();
                for(int i=0;i<4;i++) {
                        int x = addr >>> 24;
                        addr = addr << 8;

Modified: branches/db4o/freenet/src/freenet/io/Inet6AddressMatcher.java
===================================================================
--- branches/db4o/freenet/src/freenet/io/Inet6AddressMatcher.java       
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/io/Inet6AddressMatcher.java       
2008-09-24 23:54:07 UTC (rev 22829)
@@ -102,7 +102,7 @@
        }

        private String convertToString(byte[] addr) {
-               StringBuffer sb = new StringBuffer(4*8+7);
+               StringBuilder sb = new StringBuilder(4*8+7);
                for(int i=0;i<8;i++) {
                        if(i != 0) sb.append(':');
                        int token = ((addr[i*2] & 0xff) << 8) + (addr[i*2+1] & 
0xff);

Modified: branches/db4o/freenet/src/freenet/io/comm/Message.java
===================================================================
--- branches/db4o/freenet/src/freenet/io/comm/Message.java      2008-09-24 
23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/io/comm/Message.java      2008-09-24 
23:54:07 UTC (rev 22829)
@@ -24,7 +24,6 @@
 import java.io.EOFException;
 import java.io.IOException;
 import java.lang.ref.WeakReference;
-import java.nio.ByteBuffer;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.LinkedList;
@@ -78,10 +77,11 @@
                try {
                    for (Iterator i = mspec.getOrderedFields().iterator(); 
i.hasNext();) {
                        String name = (String) i.next();
-                       Class type = (Class) mspec.getFields().get(name);
+                       Class<?> type = (Class<?>) mspec.getFields().get(name);
                        if (type.equals(LinkedList.class)) { // Special 
handling for LinkedList to deal with element type
                            m.set(name, Serializer
-                                               
.readListFromDataInputStream((Class) mspec.getLinkedListTypes().get(name), bb));
+                                               
.readListFromDataInputStream((Class<?>) mspec.getLinkedListTypes().get(name),
+                                               bb));
                        } else {
                            m.set(name, 
Serializer.readFromDataInputStream(type, bb));
                        }
@@ -251,7 +251,7 @@
        }

        public String toString() {
-               StringBuffer ret = new StringBuffer(1000);
+               StringBuilder ret = new StringBuilder(1000);
                String comma = "";
         ret.append(_spec.getName()).append(" {");
                for (Iterator i = _spec.getFields().keySet().iterator(); 
i.hasNext();) {

Modified: branches/db4o/freenet/src/freenet/io/comm/MessageType.java
===================================================================
--- branches/db4o/freenet/src/freenet/io/comm/MessageType.java  2008-09-24 
23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/io/comm/MessageType.java  2008-09-24 
23:54:07 UTC (rev 22829)
@@ -19,7 +19,9 @@

 package freenet.io.comm;

-import java.util.*;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.Map;

 import freenet.support.Logger;
 import freenet.support.ShortBuffer;
@@ -60,12 +62,12 @@
                _specs.remove(new Integer(_name.hashCode()));
        }

-       public void addLinkedListField(String name, Class parameter) {
+       public void addLinkedListField(String name, Class<?> parameter) {
                _linkedListTypes.put(name, parameter);
                addField(name, LinkedList.class);
        }

-       public void addField(String name, Class type) {
+       public void addField(String name, Class<?> type) {
                _fields.put(name, type);
                _orderedFields.addLast(name);
        }
@@ -81,15 +83,15 @@
                if (fieldValue == null) {
                        return false;
                }
-               Class defClass = (Class)(_fields.get(fieldName));
-               Class valueClass = fieldValue.getClass();
+               Class<?> defClass = (Class<?>) (_fields.get(fieldName));
+               Class<?> valueClass = fieldValue.getClass();
                if(defClass == valueClass) return true;
                if(defClass.isAssignableFrom(valueClass)) return true;
                return false;
        }

-       public Class typeOf(String field) {
-               return (Class) _fields.get(new Integer(field.hashCode()));
+       public Class<?> typeOf(String field) {
+               return (Class<?>) _fields.get(new Integer(field.hashCode()));
        }

        public boolean equals(Object o) {

Modified: branches/db4o/freenet/src/freenet/io/comm/UdpSocketHandler.java
===================================================================
--- branches/db4o/freenet/src/freenet/io/comm/UdpSocketHandler.java     
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/io/comm/UdpSocketHandler.java     
2008-09-24 23:54:07 UTC (rev 22829)
@@ -44,6 +44,7 @@
        private final int listenPort;
        private final String title;
        private boolean _started;
+       private long startTime;
        private Thread _thread;
        private final IOStatisticCollector collector;

@@ -300,6 +301,7 @@
                synchronized(this) {
                        if(!_active) return;
                        _started = true;
+                       startTime = System.currentTimeMillis();
                }
                node.executor.execute(this, "UdpSocketHandler for port 
"+listenPort);
                if(!disableHangChecker) {
@@ -441,5 +443,9 @@
        public int getPriority() {
                return NativeThread.MAX_PRIORITY;
        }
+       
+       public long getStartTime() {
+               return startTime;
+       }

 }

Modified: branches/db4o/freenet/src/freenet/keys/FreenetURI.java
===================================================================
--- branches/db4o/freenet/src/freenet/keys/FreenetURI.java      2008-09-24 
23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/keys/FreenetURI.java      2008-09-24 
23:54:07 UTC (rev 22829)
@@ -582,7 +582,7 @@
        }

        public String toShortString() {
-               StringBuffer b = new StringBuffer();
+               StringBuilder b = new StringBuilder();

                b.append(keyType).append('@');


Modified: branches/db4o/freenet/src/freenet/l10n/freenet.l10n.de.properties
===================================================================
--- branches/db4o/freenet/src/freenet/l10n/freenet.l10n.de.properties   
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/l10n/freenet.l10n.de.properties   
2008-09-24 23:54:07 UTC (rev 22829)
@@ -8,6 +8,7 @@
 Announcer.announceDisabledTooOldTitle=Ank?ndigungen deaktiviert (zu alt)
 Announcer.announceLoading=Freenet l?dt gerade die Seednodes(Saat-Knoten)-Datei 
herunter, sodass es versuchen kann sich im Rest des Netzwerks bekannt zu 
machen. Die Bekanntgabe kann ein paar Minuten dauern.
 Announcer.coolingOff=In den n?chsten ${time} Sekunden wartet der Knoten auf 
die Knoten, bei denen er sich gerade gemeldet hat um sich zu verbinden. Wenn 
dies nicht gen?gend Knoten hervorbringt, wird er es mit einem anderen Knoten 
versuchen.
+Announcer.dontKnowAddress=Freenet konnte bis jetzt noch nicht ihre IP Adresse 
feststellen. Wir k?nnen nicht nach fremden Knoten anfragen, bis wir die IP 
kennen.
 Bookmark.noName=unbenannt
 BookmarkEditorToadlet.addBookmark=Lesezeichen hinzuf?gen
 BookmarkEditorToadlet.addCategory=Kategorie hinzuf?gen
@@ -291,6 +292,7 @@
 FProxyToadlet.openPossRSSForceDisk=${link}Klicken Sie hier${/link} um Ihren 
Browser zu zwingen, die Datei auf einen Datentr?ger herunterzuladen 
(${bold}dies k?nnte auch gef?hrlich sein${/bold} wenn Sie Firefox 2.0.0 
benutzen, 2.0.1 sollte dies beheben).
 FProxyToadlet.openRSSAsRSS=${link}Klicken Sie hier${/link} um die Datei als 
RSS-Datei zu ?ffnen (dies ${bold}ist gef?hrlich${/bold} wenn der 
Seiten-Betreiber b?swillig ist, da Freenet bis jetzt noch nicht wei?, wie man 
RSS filtert).
 FProxyToadlet.openRSSForce=${link}Klicken Sie hier${/link} um die Datei als 
${mime} zu ?ffnen (dies ${bold}kann gef?hrlich sein${/bold} wenn Sie Internet 
Explorer 7 oder Firefox 2 benutzen).
+FProxyToadlet.openWithKeyExplorer=${link}Klicken sie hier${/link}, um den 
Freenet Link im KeyExplorer zu ?ffnen.
 FProxyToadlet.opennet=Nicht vertrauensw?rdige Verbindungen verwalten
 FProxyToadlet.opennetTitle=Fremde
 FProxyToadlet.options=Ihre M?glichkeiten sind:
@@ -432,17 +434,22 @@
 FirstTimeWizardToadlet.datastoreSizeLong=Bitte w?hlen Sie eine Gr??e f?r Ihren 
Datenspeicher. Der Datenspeicher verh?lt sich wie ein Zwischenspeicher (Cache); 
Daten f?r das Netzwerk zu speichern wird Ihnen zu einem besseren 
Daten-Durchsatz verhelfen, wenn Sie popul?re Dateien anfordern. Je mehr Platz 
Sie zur Verf?gung stellen k?nnen, desto besser ist es f?r die Gemeinschaft und 
desto schneller wird Ihr Knoten, besonders das Herunterladen, sein.
 FirstTimeWizardToadlet.enableOpennet=Es ist auch sp?ter, wenn Sie genug 
Freunde hinzugef?gt haben, noch m?glich die Verbindung zu Fremden 
auszuschalten. Sie werden dann jedoch in der Zwischenzeit bereits ein paar 
Informationen an Fremde preisgegeben haben. Freenet ist immer noch 
experimentell und wir geben keine Garantie f?r die Sicherheit.
 FirstTimeWizardToadlet.fivePercentDisk=(= 5% des freien Speicherplatzes)
+FirstTimeWizardToadlet.friendsSecurityPageTitle=Freenet-Einrichtungs-Assistent!
 - Freenet Sicherheitseinstellungen
+FirstTimeWizardToadlet.highNetworkThreatLevelCheckbox=Ich kenne mindestens 
eine Person, die Freenet benutzt (besser 3, 5-10 f?r ene ordentliche 
Geschwindigkeit). Ich werde sie auf der Freundesseite hinzuf?gen. Ich verstehe, 
dass Freenet nur funktionieren wird, wenn mindestens einer meiner Freunde 
online ist.
+FirstTimeWizardToadlet.highNetworkThreatLevelWarning=${bold}WARNUNG${/bold}: 
Sie sind dabei, das Netzwerk Sicherheitslevel auf hoch  zu setzen. Dies 
bedeutet, dass sich ihr Knoten nicht verbinden kann, wenn sie nicht 
${bold}einige Verbindungen zu Freunden hinzuf?gen${/bold}. Diese Freunde 
sollten Menschen sein, die sie schon kennen und denen sie zumindest etwas 
vertrauen. Wenn sie niemanden kennen, der bereits Freenet benutzt, benutzen sie 
bitte das Netzwerk Sicherheitslevel NORMAL, so dass Freenet automatisch 
Verbindungen aufbaut. Das Hinzuf?gen von Fremden zu ihren Freunden wird ihre 
Sicherheit nicht erh?hen und wird der Geschwindigkeit schaden. Beachten sie 
auch, dass das Schutzlevel HOCH langsamer ist, besonders wenn sie wenige 
Freunde haben (sie ben?tigen mindestens 5-10 Freunde f?r eine ordentliche 
Geschwindigkeit).
 FirstTimeWizardToadlet.homepageTitle=Freenet-Einrichtungs-Assistent!
 FirstTimeWizardToadlet.iDoTrust=Trauen Sie Leuten die mit ${interface} (${ip}) 
verbunden sind?
 FirstTimeWizardToadlet.isNetworkTrusted=Ist Ihr lokales Netzwerk 
vertrauensw?rdig?
 FirstTimeWizardToadlet.isNetworkTrustedLong=Ist Ihr lokales Netzwerk 
vertrauensw?rdig? Wenn Sie hier mit Ja antworten, werden alle Dienste, die Ihr 
Knoten anbietet, f?r jeden der vom lokalen Netzwerk auf sie zugreifen will, 
frei zug?nglich sein. Sie werden die M?glichkeit haben, selektive 
Zugangs-Kontrollen auf der Konfigurations-Seite einzurichten, wenn der 
Assistent beendet ist.
 FirstTimeWizardToadlet.memoryLimit=Arbeitsspeicher-Benutzung
 FirstTimeWizardToadlet.memoryLimitLong=Wie viel (Arbeits-)Speicher m?chten Sie 
Freenet erlauben zu benutzen? Wenn Sie viele Downloads oder Uploads in der 
Warteschlange haben, wird Freenet mehr Speicher brauchen. Wir empfehlen Ihnen 
dies nicht auf weniger als 128MB zu setzen, es sei denn Sie haben wirklich 
wenig RAM. Wenn Sie 1GB oder mehr haben, sollten Sie dies wahrscheinlich auf 
mindestens 256MB setzen. Diese Einstellung wird nach einem Neustart von Freenet 
wirksam.
+FirstTimeWizardToadlet.networkSecurityPageTitle=Freenet-Einrichtungs-Assistent!
 - Netzwerk Sicherheitseinstellungen
 FirstTimeWizardToadlet.noNetworkIF=Keine zus?tzliche Netzwerk-Schnittstelle 
gefunden
 FirstTimeWizardToadlet.noNetworkIFLong=Freenet hat keine zus?tzliche 
Netzwerk-Schnittstelle gefunden. Es wird annehmen, dass Sie sich von Ihrem 
Computer (und nur von Ihrem Computer) mit ihm verbinden.
 FirstTimeWizardToadlet.opennetNo=Ich habe mindestens 5 Freunde, die bereits 
Freenet benutzen und werde Ihre Kontaktdaten auf der Freunde-Seite eintragen.
 FirstTimeWizardToadlet.opennetWarning=Wenn Freenet dort wo Sie leben illegal 
ist oder wenn Sie es benutzen um Inhalte abzurufen, die Sie in Schwierigkeiten 
bringen k?nnten, kann es sein, dass dem Knoten zu sagen, dass er sich 
automatisch mit Fremden verbinden soll, gef?hrlich ist, da es das Leben eines 
Angreifers deutlich erleichtert. Freenet ist immer noch experimentell und wir 
geben keine Garantie f?r die Sicherheit.
 FirstTimeWizardToadlet.opennetYes=Ich m?chte, dass der Knoten automatisch 
Fremde findet mit denen er sich verbinden kann.
+FirstTimeWizardToadlet.physicalSecurityPageTitle=Freenet-Einrichtungs-Assistent!
 - Physikalische Sicherheitseinstellungen
 FirstTimeWizardToadlet.skipWizard=Ich bin kein Neuling, bitte ?berspringe den 
Assistenten!
 FirstTimeWizardToadlet.step1Title=Freenet-Einrichtungs-Assistent! - Freunde 
und Fremde
 FirstTimeWizardToadlet.step2Title=Freenet-Einrichtungs-Assistent! - W?hlen Sie 
einen Knoten-Namen
@@ -649,6 +656,8 @@
 Node.dropPacketEveryLong=Frequenz mit der Pakete vernichtet werden. 
Test-Option die von den Entwicklern genutzt wird um Paket-Verlust zu 
simulieren. 0 bedeutet, dass kein Paket k?nstlich "verloren" wird. Bitte nicht 
ver?ndern!
 Node.enableARKs=ARKs aktivieren? (DEAKTIVIEREN SIE DIES NICHT!)
 Node.enableARKsLong=ARKs aktivieren? (DEAKTIVIEREN SIE DIES NICHT!).
+Node.enableOpennetFailed=Der Knoten konnte Opennet nicht aktivieren und kann 
nicht zu Fremden verbinden. Sie k?nnen entweder den Fehler beheben, den Fehler 
melden oder sich nur zu Freunden verbinden. Details: ${message}
+Node.enableOpennetFailedTitle=Die Aktivierung von Opennet schlug fehl
 Node.enablePacketCoalescing=Aktiviere Paketb?ndelung?
 Node.enablePacketCoalescingLong=Paketb?ndelung aktivieren? Durch die 
Paketb?ndelung  wird die Bandbreite efizienter genutzt, weniger Rechenzeit 
genutzt und die Analyse der Paketdaten etwas erschwert. Im Gegenzug brauchen 
Nachrichten ein wenig l?nger. Deaktivieren Sie dies nicht, wenn sie nicht 
wissen, was sie tun.
 Node.enablePerNodeFailureTables=Aktiviere nachbarknotenspezifische 
Fehlertabellen?
@@ -702,6 +711,8 @@
 Node.publishOurPeersLocationLong=Sollen wir die Positionen unserer Partner an 
unsere Partner weitergeben? Dies zu tun, hilft dem Routing gibt aber 
Informationen an potenzielle Angreifer preis.
 Node.routeAccordingToOurPeersLocation=Sollen wir die Positionen der Partner 
unserer Partner zu Routing-Zwecken ber?cksichtigen?
 Node.routeAccordingToOurPeersLocationLong=Sollen wir die Positionen der 
Partner unserer Partner zu Routing-Zwecken ber?cksichtigen? Dies zu tun 
verbessert das Routing, k?nnte aber einem potenziellen Angreifer helfen.
+Node.storeBloomFilterSize=Bloom Filter Gr??e (insgesamt) in Bytes
+Node.storeBloomFilterSizeLong=Bloom filter Gr??e (total) in Bytes. 
Normalerweise ist 1/1500 der Gr??e des Datenspeichers mehr als genug. Setzen 
sie diesen Wert auf null, um den  bloom filter zu deaktivieren.
 Node.storeDirectory=Speicher-Verzeichnis
 Node.storeDirectoryLong=Name des Verzeichnisses in welchem die 
Speicher-Dateien platziert werden
 Node.storeMaxMemTooHigh=Mehr als 80% Ihres RAMs (Hauptspeichers) an BDB 
(Datenbank) abzugeben ist wahrscheinlich nicht das was Sie tun wollen!
@@ -1044,6 +1055,62 @@
 SSL.keyStorePassLong=Passwort f?r den Zugriff auf die Schl?sseldatei
 SSL.version=SSL-Version
 SSL.versionLong=SSL-Version: SSLv3 oder TLSv1 (Standard: SSLv3)
+SaltedHashFreenetStore.longResizeProgress=Das ver?ndern der Gr??e von 
Datenbank(${name}) l?uft grade: ${processed}/${total}. Der Knoten k?nnte 
w?hrenddessen etwas langsamer als normal sein. Bitte vermeiden sie Neustarts 
w?hrend dieser Zeit.
+SecurityLevels.fewConnectedFriendsCheckbox=Ich bin sicher. Ich werde mehr 
Freunde hinzuf?gen und/oder akzeptieren, dass die Geschwindigkeit nicht so hoch 
sein wird und Freenet sich nicht verbinden kann, wenn alle Freunde offline sind.
+SecurityLevels.fewConnectedFriendsWarning=Sie sind aktuell nur mit 
${connected} Freunden verbunden und sie haben insgesamt ${added} Freunde in der 
Liste. Wenn sie das Netzwerk Sicherheitslevel auf hoch oder maximum setzen, 
wird sich Freenet nur noch mit ihren Freunden verbinden. Die Geschwindigkeit 
von Freenet k?nnte deutlich sinken und wenn alle ihre Freunde offline sind, 
werden sie sich gar nicht mit Freenet verbinden k?nnen. Beachten sie, dass 
Freunde Menschen sein m?ssen, denen sie zumindest etwas trauen, um eine h?here 
Sicherheit zu bekommen. Sie ben?tigen au?erdem mindestens 5-10 verbundene 
Freunde f?r eine gute Geschwindigkeit. Sind sie sicher?
+SecurityLevels.friendsThreatLevel=Wie besorgt sind sie dar?ber, dass ihre 
hinzugef?gten Freunde versuchen k?nnten, ihre Aktivit?ten zu verfolgen, 
entweder mit Absicht oder da ihr Computer kompromittiert wurde? (Dies ist ein 
Standardlevel, die meisten Punkte k?nnen f?r jeden Freund individuell angepasst 
werden.) Wenn sie das Netzwerk Sicherheitslevel oben auf HOCH (oder MAXIMUM) 
gesetzt haben, bestimmt das Freunde Sicherheitslevel zusammen mit der Anzahl 
der Freunde die Geschwindigkeit.
+SecurityLevels.friendsThreatLevelConfirmTitle=WARNUNG: Setze Freundes 
Sicherheitslevel auf ${mode}
+SecurityLevels.friendsThreatLevelShort=Schutz gegen Freunde, die ihre 
Anonymit?t angreifen
+SecurityLevels.highFriendsThreatLevelCheckbox=Ich bin sicher, dass ich einen 
hohen Schutz gegen kompromitierte oder betr?gerische Knoten meiner Freunde 
brauche.
+SecurityLevels.highFriendsThreatLevelWarning=Sie sind dabei, dass Freunde 
Sicherheitslevel auf hoch zu setzen. Dies wird die Geschwindigkeit von Freenet 
verringern und sollte die meiste Zeit nicht n?tig sein. Wenn sie diese 
Einstellung setzen wollen, weil sie unbekannte Menschen zu ihrer Freundesliste 
hinzugef?gt haben, sollten sie besser ?berlegen, ob sie diese Menschen nicht 
wieder aus der Liste entfernen und stattdessen das Netzwerk Sicherheitslevel 
auf NORMAL setzen, wenn n?tig. Wenn sie allerdings bef?rchten, dass ein 
Angreifer den Computer ihrer Freunde ?bernehmen k?nnte oder ihre Freunde dazu 
bewegen k?nnte, sich gegen sie zu wenden, k?nnte dies eine gute 
Vorsichtsma?nahme sein.
+SecurityLevels.maxSecurityYouNeedFriends=${bold}Sie m?ssen mindestens eine 
Person kennen, die Freenet schon benutzt, ${/bold}, besser 3 Personen, 5-10 f?r 
eine gute Geschwindigkeit. Sie k?nnen sie auf der Freunde-Seite hinzuf?gen. Es 
sollten aber Menschen sein, die sie kennen und denen sie zumindest etwas trauen.
+SecurityLevels.maximumNetworkThreatLevelCheckbox=Ja, ich will wirklich die 
maximale Sicherheit aktivieren. Ich verstehe, dass Freenet immer noch 
experimentelle Software ist und dass es immer noch m?glich sein kann, meine 
Spuren zu verfolgen. Ich verstehe auch, dass diese Einstellung die 
Geschwindigkeit von Freenet stark verringern kann.
+SecurityLevels.maximumNetworkThreatLevelWarning=${bold}WARNUNG:${/bold} Sie 
sind dabei, das Netzwerk Sicherheitslevel auf maximum zu setzen! Dies wird die 
Geschwindigkeit von Freenet ${bold}deutlich${/bold} verringern! Bitte machen 
sie dies nur, wenn sie die zus?tzliche Sicherheit wirklich ben?tigen.
+SecurityLevels.networkThreatLevel=Wie viel Schutz ben?tigen sie gegen Internet 
Provider, Firmen, Regierungen, gelangweilten Kindern usw, welche versuchen, 
ihre Aktivit?ten in Freenet zu verfolgen?
+SecurityLevels.networkThreatLevelConfirmTitle=WARNUNG: Setze das Netzwerk 
Sicherheitslevel auf ${mode}
+SecurityLevels.networkThreatLevelLowCheckbox=Ich bin mir sicher, ich m?chte 
mehr Geschwindigkeit und ich f?rchte mich nicht davor, was andere ?ber meine 
Aktivit?ten in Freenet erfahren.
+SecurityLevels.networkThreatLevelLowWarning=Sie sind dabei, das Netzwerk 
Sicherheitslevel auf niedrig zu setzen. Dies bedeutet, es wird f?r Fremde 
einfach sein, ihre Anonymit?t ?ber das Internet anzugreifen. Sind sie sicher?
+SecurityLevels.networkThreatLevelShort=Schutz gegen einen Unbekannten, der sie 
?ber das Internet angreift.
+SecurityLevels.noConnectedFriendsCheckbox=Ich bin sicher. Ich werde mehr 
Freunde hinzuf?gen und/oder akzeptieren, dass Freenet nur dann eine Verbindung 
aufbauen kann, wenn mindestens ein Freund online ist.
+SecurityLevels.noConnectedFriendsWarning=Sie haben keine verbundenen Freunde, 
obwohl sie ${added} Freunde hinzugef?gt haben.Wenn sie das Netzwerk 
Sicherheitslevel auf hoch oder maxmum setzen, werden sie sich nur mit Freenet 
verbinden k?nnen, wenn ihre Freunde online sind (was sie im Moment nicht sind). 
Sie sollten zus?tzliche Freunde hinzuf?gen, Freenet nur benutzen, wenn ihre 
Freunde verbunden sind oder das Netzwerk Sicherheitslevel nicht auf hoch oder 
maximum setzen. Beachten sie, dass f?r eine erh?hte Sicherheit ihre Freunde 
Menschen sein m?ssen, die sie kennen und denen sie zumindest ein wenig 
vertrauen. F?r eine gute Geschwindigkeit ben?tigen sie mindestens 5-10 
verbundene Freunde. Sind sie sicher??
+SecurityLevels.noFriendsCheckbox=Ich bin mir sicher, setze das Netzwerk 
Sicherheitslevel auf hoch, ich werde sobald wie m?glich einige Freunde 
hinzuf?gen.
+SecurityLevels.noFriendsWarning=Sie haben keine Freunde hinzugef?gt. Wenn sie 
das Netzwerk Sicherheitslevel auf hoch oder maximum setzen, werden sie sich 
nicht mit Freenet verbinden k?nnen, bis sie nicht mit mindestens einem Freund 
verbunden sind! Beachten sie, dass sie f?r eine erh?hte Sicherheit die 
hinzugef?gten Freunde kennen sollten und ihnen zumindest etwas vertrauen 
sollten. F?r eine gute Geschwindigkeit ben?tigen sie mindestens 5-10 
gleichzeitig verbundene Freunde. Sind sie sicher?
+SecurityLevels.physicalThreatLevel=Wie besorgt sind sie, dass ihr Computer 
physikalisch beschlagnahmt und durchsucht werden k?nnte?
+SecurityLevels.physicalThreatLevelShort=Sicherheitslevel f?r Situationen, wo 
der Computer beschlagnahmt oder gestohlen werden k?nnte
+SecurityLevels.title=Sicherheitslevel
+SecurityLevels.tooltip=Konfiguration der Sicherheitslevel des Knotens
+SecurityLevels.userAlertExtro=Sie k?nnen diese Einstellungen auf der 
${link}Konfigurationsseite${/link} ?ndern.
+SecurityLevels.userAlertFriendsThreatLevel=Schutz gegen Angriffe ihrer Freunde 
auf ihre Anonymit?t: ${level}
+SecurityLevels.userAlertNetworkThreatLevel=Schutz gegen einen Fremden, der sie 
?ber das Internet angreift: ${level}
+SecurityLevels.userAlertPhysicalThreatLevel=Schutz f?r den Fall, dass ihr 
Computer beschlagnahmt oder gestohlen wird:: ${level}
+SecurityLevels.userAlertShortText=Sicherheitslevel:: Netzwerk: ${network}, 
Freunde: ${friends}, Physikalisch: ${physical}
+SecurityLevels.friendsThreatLevel.choice.HIGH=Ich m?chte, dass Freenet 
besondere Schutzma?nahmen gegen Angriffe meiner Freunde ergreift.
+SecurityLevels.friendsThreatLevel.choice.LOW=Ich bin nicht besorgt ?ber 
Angriffe von meinen Freunden. Ich vertraue ihnen und ihren F?higkeiten 
bez?glich Computersicherheit.
+SecurityLevels.friendsThreatLevel.choice.NORMAL=Ich bin nicht besonders 
besorgt ?ber Angriffe von Freunden, aber ich m?chte, dass Freenet ein gesundes 
Ma? an Vorsicht walten l?sst.
+SecurityLevels.friendsThreatLevel.desc.HIGH=Freenet wird das teilen von 
Informationen mit ihren Freunden vermeiden und wird deshalb etwas langsamer 
sein als im Modus NORMAL.
+SecurityLevels.friendsThreatLevel.desc.LOW=Freenet wird viele Informationen 
mit den Knoten ihrer Freunde teilen, um die bestm?gliche Geschwindigkeit zu 
erreichen.
+SecurityLevels.friendsThreatLevel.desc.NORMAL=Freenet wird eine beschr?nkte 
Menge an Informationen mit ihren Freunden teilen und wird langsamer sein als im 
Modus NIEDRIG.
+SecurityLevels.friendsThreatLevel.name.HIGH=HOCH
+SecurityLevels.friendsThreatLevel.name.LOW=NIEDRIG
+SecurityLevels.friendsThreatLevel.name.NORMAL=NORMAL
+SecurityLevels.networkThreatLevel.choice.HIGH=Ich m?chte es f?r andere 
deutlich schwerer machen, meine Kommunikation zu beobachten oder ich bef?rchte, 
dass mein Provider versuchen k?nnte, Freenet zu blockieren.
+SecurityLevels.networkThreatLevel.choice.LOW=Ich mache mir keine Gedanken ?ber 
?berwachung und will maximale Geschwindigkeit.
+SecurityLevels.networkThreatLevel.choice.MAXIMUM=Ich plane, auf Informationen 
zuzugreifen, die dazu f?hren k?nnen, dass ich verhaftet oder gefangen genommen 
werde oder schlimmeres. Ich verstehe, dass Freenet experimentell ist und keine 
Sicherheit gegen bestimmte (bekannte) Angriffe bieten kann. Aber ich akzeptiere 
die Riskien verglichen mit den Alternativen.
+SecurityLevels.networkThreatLevel.choice.NORMAL=Ich lebe in einem relativ 
freien Land, aber ich m?chte es Anderen schwerer machen, meine Kommunikation zu 
?berwachen.
+SecurityLevels.networkThreatLevel.desc.HIGH=Freenet wird sich nur zu ihren 
Freunden verbinden, also  ${bold}m?ssen sie Freunde haben, die bereits Freenet 
benutzen, wenn sie diesen Modus ausw?hen${/bold}. Freenet wird langsam sein, 
wenn sie nicht mindestens 5-10 Freunde hinzuf?gen und wird gar nicht 
funktionieren, wenn nicht mindestens eine Verbindung zu einem Freund besteht.
+SecurityLevels.networkThreatLevel.desc.LOW=Es kann ziemlich einfach f?r Andere 
sein, ihre Identit?t herauszufinden!
+SecurityLevels.networkThreatLevel.desc.MAXIMUM=Freenet wird 
${bold}deutlich${/bold} langsamer sein als im Modus HOCH und ${bold}sie m?ssen 
Freunde haben, die Freenet benutzen, um diesen Modus nutzen zu k?nnen${/bold}.
+SecurityLevels.networkThreatLevel.desc.NORMAL=Freenet wird eine gesunde 
Vorsicht walten lassen, um ihrer Anonymit?t zu sch?tzen, daf?r wird die 
Geschwindigkeit etwas geringer sein. Freenet wird automatisch zu fremden Knoten 
verbinden. Wir empfehlen, dass sie Referenzen von Freunden hinzuf?gen, die 
bereits Freenet nutzen und anschlie?end ein Upgrade auf den Modus HOCH machen.
+SecurityLevels.networkThreatLevel.name.HIGH=HOCH
+SecurityLevels.networkThreatLevel.name.LOW=NIEDRIG
+SecurityLevels.networkThreatLevel.name.MAXIMUM=MAXIMUM
+SecurityLevels.networkThreatLevel.name.NORMAL=NORMAL
+SecurityLevels.physicalThreatLevel.choice.LOW=Ich bin nicht besorgt.
+SecurityLevels.physicalThreatLevel.choice.NORMAL=Ich bin besorgt.
+SecurityLevels.physicalThreatLevel.desc.LOW=Freenet wird ein verschl?sseln der 
Daten auf der Festplatte vermeiden und wird Spuren ihrer Aktivit?ten auf ihrer 
Festplatte hinterlassen. Erh?ht die Geschwindigkeit auf Kosten der Sicherheit, 
wenn ihr Computer beschlagnahmt wird.
+SecurityLevels.physicalThreatLevel.desc.NORMAL=Freenet wird temor?re Dateien 
usw verschl?ssen (mit der Folge einer etwas geringeren Geschwindigkeit). 
Allerdings sollten sie zus?tzliche Vorsichtsma?nahmen wie das deaktivieren 
ihres Browsercaches ergreifen, wenn sie das Webinterface benutzen. Wenn sie 
best?ndige Downloads nutzen (die meisten Programme machen dies), sollten sie 
die Festplatte verschl?sseln, auf der Freenet l?uft.
+SecurityLevels.physicalThreatLevel.name.LOW=NIEDRIG
+SecurityLevels.physicalThreatLevel.name.NORMAL=NORMAL
 ShortOption.parseError=Kann den Wert nicht als String-Array 
(Zeichenfolgen-Feld) erkennen: ${error}
 SimpleToadletServer.advancedMode=Erweiterten Modus aktivieren?
 SimpleToadletServer.advancedModeLong=Aktiviert die standardm??ige Anzeige von 
erweiterten Einstellungen und Informationen in der Web-Oberfl?che. Diese 
Einstellung sollte in den meisten F?llen auf "nein" stehen.
@@ -1189,6 +1256,7 @@
 TranslationToadlet.contributingToLabelWithLang=Sie tragen gerade zur ${lang} 
?bersetzung bei:
 TranslationToadlet.currentTranslationLabel=Aktuelle ?bersetzung
 TranslationToadlet.downloadTranslationsFile=Ihre ?bersetzungs-Datei 
herunterladen
+TranslationToadlet.gotoNext=Gehe zur n?chsten nicht ?bersetzten Folge?
 TranslationToadlet.hideAlreadyTranslated=Bereits ?bersetzte Zeichenketten 
verstecken
 TranslationToadlet.noCustomTranslations=Es ist keine spezielle ?bersetzung 
verf?gbar.
 TranslationToadlet.originalVersionLabel=Original (Englische Version)

Modified: branches/db4o/freenet/src/freenet/l10n/freenet.l10n.en.properties
===================================================================
--- branches/db4o/freenet/src/freenet/l10n/freenet.l10n.en.properties   
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/l10n/freenet.l10n.en.properties   
2008-09-24 23:54:07 UTC (rev 22829)
@@ -1,5 +1,5 @@
 testing.test=test$(test1)test$(test2)test
-Announcer.announceAlertIntro=Freenet is connecting to the network - this may 
take a few minutes. Performance will continue to improve during the next few 
hours. This will happen each time you restart Freenet, so try to leave it 
running 24 hours a day if possible.
+Announcer.announceAlertIntro=Freenet is connecting to the network - this may 
take a few minutes. Performance will continue to improve during the next few 
hours. This will happen each time you shut down Freenet for more than a few 
minutes, so try to leave it running 24 hours a day if possible.
 Announcer.announceAlertTitle=Node Announcing
 Announcer.announceDetails=We have recently sent ${recentSentAnnouncements} 
announcements, ${runningAnnouncements} of which are still running, and added 
${addedNodes} nodes (${refusedNodes} nodes have rejected us). We are currently 
connected to ${connectedSeednodes} seednodes and trying to connect to another 
${disconnectedSeednodes}.
 Announcer.announceAlertNoSeednodes=There is no seednodes.fref file found, so 
the node will not be able to automatically bootstrap itself onto the opennet. 
Please add some nodes manually, or download the seednodes file from 
http://downloads.freenetproject.org/alpha/opennet/ .
@@ -9,6 +9,7 @@
 Announcer.announceDisabledTooOldShort=The node has tried to connect to the 
network but your copy of Freenet is too old. You should upgrade.
 Announcer.announceAlertShort=The node is trying to connect to the network, it 
will be slow for a while.
 Announcer.coolingOff=For the next ${time} seconds, the node is waiting for the 
nodes that it just announced to to connect, if there are not enough nodes it 
will try a different node.
+Announcer.dontKnowAddress=Freenet has not yet been able to determine our IP 
address, we cannot announce until we know what it is.
 Bookmark.noName=no name
 BookmarkEditorToadlet.addBookmark=Add Bookmark
 BookmarkEditorToadlet.addCategory=Add Category
@@ -274,6 +275,8 @@
 FirstTimeWizardToadlet.continueEnd=Click here to start using Freenet!
 FirstTimeWizardToadlet.datastoreSize=Datastore size
 FirstTimeWizardToadlet.datastoreSizeLong=Please select a size for your 
datastore. The datastore acts like a cache; storing data for the network will 
help you to get better throughput when requesting popular files. The more space 
you can afford the better it is for the community and the faster your node and 
especially your downloads will go.
+FirstTimeWizardToadlet.highNetworkThreatLevelWarning=${bold}WARNING${/bold}: 
You are about to set the network security level to high. This means your node 
will not be able to connect unless ${bold}you add some connections to 
Friends${/bold}. These should be people you already know and at least 
marginally trust. If you don't know anyone already using Freenet, please use 
the NORMAL network security level so that Freenet will setup connections 
automatically. Adding people you don't know as Friends will not significantly 
improve security and will harm performance. Also note that HIGH security level 
is slower, especially if you don't have many Friends (you need 5-10 for 
adequate performance).
+FirstTimeWizardToadlet.highNetworkThreatLevelCheckbox=I know at least one 
person already using Freenet (3 preferably, 5-10 for good performance). I will 
add them on the Friends page. I understand that Freenet will not work unless 
some of my Friends are online.
 FirstTimeWizardToadlet.isNetworkTrusted=Is your local network trusted?
 FirstTimeWizardToadlet.isNetworkTrustedLong=Is your local network trusted? If 
you answer yes here all the services provided by your node will be wide open to 
everyone willing to access them on the given network. You will be able to do 
selective access controls from the configuration page when the wizard is over.
 FirstTimeWizardToadlet.noNetworkIF=No additional network interface found
@@ -288,6 +291,9 @@
 FirstTimeWizardToadlet.memory.512M=512MiB - if you have lots of RAM
 FirstTimeWizardToadlet.memoryLimit=Memory usage
 FirstTimeWizardToadlet.memoryLimitLong=How much memory would you like to allow 
Freenet to use? If you have many downloads or uploads queued, Freenet will need 
more memory. We suggest you not set this below 128MB unless you are really 
short of RAM. If you have 1GB or more, you should probably set this to at least 
256MB. This will take effect after restarting Freenet.
+FirstTimeWizardToadlet.networkSecurityPageTitle=Freenet first time wizard! - 
Network security settings
+FirstTimeWizardToadlet.friendsSecurityPageTitle=Freenet first time wizard! - 
Friends security settings
+FirstTimeWizardToadlet.physicalSecurityPageTitle=Freenet first time wizard! - 
Physical security settings
 FirstTimeWizardToadlet.step1Title=Freenet first time wizard! - Friends and 
strangers
 FirstTimeWizardToadlet.step2Title=Freenet first time wizard! - Choose a node 
name
 FirstTimeWizardToadlet.step3Title=Freenet first time wizard! - Bandwidth limits
@@ -341,6 +347,7 @@
 FProxyToadlet.openRSSForce=${link}Click here${/link} to open the file as 
${mime} (this ${bold}may be dangerous${/bold} on IE7 or FF2).
 FProxyToadlet.opennet=manage untrusted connections
 FProxyToadlet.opennetTitle=Strangers
+FProxyToadlet.openWithKeyExplorer=${link}Click here${/link} to open the 
freenet uri with key explorer.
 FProxyToadlet.options=Your options are:
 FProxyToadlet.pathNotFound=The specified path does not exist.
 FProxyToadlet.pathNotFoundTitle=Path Not Found
@@ -503,11 +510,11 @@
 IPDetectorPluginManager.seriousConnectionProblems=Serious connection problems:
 IPDetectorPluginManager.connectionProblems=Connection problems:
 IPDetectorPluginManager.forwardPortShortMaybeForwarded=Please forward UDP port 
${port} (you may have already done this).
-IPDetectorPluginManager.forwardPortShortNotForwarded=Please forward UDP port 
${port} (it appears not to be forwarded).
+IPDetectorPluginManager.forwardPortShortNotForwarded=Please forward UDP port 
${port} (it is probably not forwarded).
 IPDetectorPluginManager.forwardTwoPortsShortMaybeForwarded=Please forward UDP 
ports ${port1} and ${port2} (you may have already done this).
 IPDetectorPluginManager.forwardTwoPortsShortNotForwarded=Please forward UDP 
ports ${port1} and ${port2} (they appear not to be forwarded).
 IPDetectorPluginManager.forwardPortMaybeForwarded=Your node appears to be 
behind some sort of NAT (see the connectivity page for details). You should 
forward UDP (not TCP) port ${port} if possible to improve connectivity. It is 
possible you have already done this; it takes a while for Freenet to detect a 
port forward. See ${link}here${/link} for some more information.
-IPDetectorPluginManager.forwardPortNotForwarded=Your node appears to be behind 
some sort of NAT (see the connectivity page for details). You should forward 
UDP (not TCP) port ${port} if possible to improve connectivity. It appears that 
the port has not been forwarded, although Freenet cannot be sure. See 
${link}here${/link} for some more information.
+IPDetectorPluginManager.forwardPortNotForwarded=Your node appears to be behind 
some sort of NAT (see the connectivity page for details). You should forward 
UDP (not TCP) port ${port} if possible to improve connectivity. It appears that 
the port has not been forwarded, although Freenet cannot be sure. See 
${link}here${/link} for some more information. It may take up to 24 hours for 
Freenet to recognise that you have successfully forwarded the ports.
 IPDetectorPluginManager.maybeAlreadyForwarded=You may have already done this 
(it is hard for Freenet to detect).
 IPDetectorPluginManager.forwardTwoPortsMaybeForwarded=Your node appears to be 
behind some sort of NAT (see the connectivity page for details). You should 
forward UDP (not TCP) ports ${port1} and ${port2} if possible to improve 
connectivity. It is possible you have already done this; it takes a while for 
Freenet to detect a port forward. See ${link}here${/link} for some more 
information.
 IPDetectorPluginManager.forwardTwoPortsNotForwarded=Your node appears to be 
behind some sort of NAT (see the connectivity page for details). You should 
forward UDP (not TCP) ports ${port1} and ${port2} if possible to improve 
connectivity. It appears that the ports have not been forwarded, although 
Freenet cannot be sure. See ${link}here${/link} for some more information.
@@ -648,6 +655,8 @@
 Node.dropPacketEveryLong=Frequency of dropping packets. Testing option used by 
devs to simulate packet loss. 0 means never artificially drop a packet. Don't 
touch this!
 Node.enableARKs=Enable ARKs? (DON'T TURN THIS OFF!)
 Node.enableARKsLong=Enable ARKs? (DON'T TURN THIS OFF!).
+Node.enableOpennetFailedTitle=Enabling opennet failed
+Node.enableOpennetFailed=The node failed to enable opennet, and cannot connect 
to strangers. You will need to fix this, report a bug, or stick with connecting 
only to Friends. Details: ${message}
 Node.enablePacketCoalescing=Enable packet coalescing?
 Node.enablePacketCoalescingLong=Enable packet coalescing? Packet coalescing 
increases bandwidth efficiency, reduces CPU usage and gains some resistance to 
traffic analysis at a small cost in message latency. Don't turn this off unless 
you know what you're doing.
 Node.enablePerNodeFailureTables=Enable per-node failure tables?
@@ -707,7 +716,11 @@
 Node.storeSize=Store size in bytes
 Node.storeSizeLong=Store size in bytes
 Node.storeType=Store type (LEAVE THIS ALONE)
-Node.storeTypeLong=Datastore type. Currently this can be bdb-index (use a 
BerkeleyDBFreenetStore to store the index, and keep the data in files on disk), 
or ram (keep the index and the data in RAM). Only use ram if you know what you 
are doing and have enough RAM to store all your data (and note it will not be 
saved on shutdown)!
+Node.storeTypeLong=Datastore type. Currently this can be salt-hash (use a 
salted on-disk hashtable with bloom filter), bdb-index (use a 
BerkeleyDBFreenetStore to store the index, and keep the data in files on disk), 
or ram (keep the index and the data in RAM). Only use ram if you know what you 
are doing and have enough RAM to store all your data (and note it will not be 
saved on shutdown)! Changes will not take effect until Freenet has been 
restarted.
+Node.storeBloomFilterSize=Bloom filter size (total) in bytes
+Node.storeBloomFilterSizeLong=Bloom filter size (total) in bytes. Usually 
1/2048th the size of data store is more than enough. Set this to zero to 
disable bloom filter.
+Node.storeBloomFilterCounting=Use counting bloom filter?
+Node.storeBloomFilterCountingLong=Use 2-bit counting bloom filter? (don't 
touch this unless you know what you are doing) 
 Node.swapRInterval=Swap request send interval (ms)
 Node.swapRIntervalLong=Interval between swap attempting to send swap requests 
in milliseconds. Leave this alone!
 Node.throttleLocalTraffic=Throttle local traffic?
@@ -922,6 +935,11 @@
 PproxyToadlet.unloadPluginWithName=Are you sure you wish to unload ${name}?
 PproxyToadlet.unloadPurge=Remove plugin from cache
 PproxyToadlet.versionTitle=Version
+SaltedHashFreenetStore.shortResizeProgress=Datastore(${name}) resize in 
progress: ${processed}/${total}
+SaltedHashFreenetStore.shortRebuildProgress=Datastore(${name}) maintenance in 
progress: ${processed}/${total}
+SaltedHashFreenetStore.longResizeProgress=Datastore(${name}) resize in 
progress: ${processed}/${total}. The node may be a little bit slower then usual 
during the process. Avoid restarting the node during this.
+SaltedHashFreenetStore.longRebuildProgress=Datastore(${name}) maintenance in 
progress: ${processed}/${total}. The node may be a little bit slower then usual 
during the process. Avoid restarting the node during this.
+SaltedHashFreenetStore.cleanerAlertTitle=Datastore maintenance task running 
 QueueToadlet.DUinProgress=Directory uploads in progress (${size})
 QueueToadlet.DinProgress=Downloads in progress (${size})
 QueueToadlet.UinProgress=Uploads in progress (${size})
@@ -1031,6 +1049,61 @@
 RequestStarterGroup.schedulerLong=Set the priority policy scheme used by the 
scheduler.
 RevocationKeyFoundUserAlert.text=Your node has found the auto-updater's 
revocation key on the network. It means that our auto-updating system is likely 
to have been COMPROMIZED! Consequently, it has been disabled on your node to 
prevent "bad things" to be installed. We strongly advise you to check the 
project's website for updates. Please take care of verifying that the website 
hasn't been spoofed either. The revocation message is the following : 
${message}.
 RevocationKeyFoundUserAlert.title=The private key of the project has been 
compromized!
+SecurityLevels.title=Security levels
+SecurityLevels.tooltip=Configure the node's degree of security
+SecurityLevels.networkThreatLevelShort=Protection against a stranger attacking 
you over the Internet
+SecurityLevels.networkThreatLevel=How much security do you need against 
Internet providers, corporations, governments, bored kids etc attempting to 
monitor your use of Freenet?
+SecurityLevels.networkThreatLevel.name.MAXIMUM=MAXIMUM
+SecurityLevels.networkThreatLevel.name.HIGH=HIGH
+SecurityLevels.networkThreatLevel.name.NORMAL=NORMAL
+SecurityLevels.networkThreatLevel.name.LOW=LOW
+SecurityLevels.networkThreatLevel.choice.MAXIMUM=I intend to access 
information that could get me arrested, imprisoned, or worse. I understand that 
Freenet is experimental and cannot ensure security against certain known 
attacks, but I accept the risks compared to the alternatives.
+SecurityLevels.networkThreatLevel.desc.MAXIMUM=Freenet will be 
${bold}significantly${/bold} slower than in HIGH, and ${bold}you must have 
friends running Freenet to use this mode${/bold}.
+SecurityLevels.networkThreatLevel.choice.HIGH=I would like to make it much 
more difficult for others to monitor my communications, or I am worried about 
ISPs trying to block Freenet.
+SecurityLevels.networkThreatLevel.desc.HIGH=Freenet will only connect to your 
friends, so ${bold}you must have friends already using Freenet to select this 
mode${/bold}. Freenet will be slow unless you add at least 5-10 friends, and 
won't work at all if you don't have at least 1.
+SecurityLevels.networkThreatLevel.choice.NORMAL=I live in a relatively free 
country, but I would like to make it more difficult for others to monitor my 
communications.
+SecurityLevels.networkThreatLevel.desc.NORMAL=Freenet will be reasonably 
careful to protect your anonymity, at some performance cost. Freenet will 
automatically connect to unknown nodes.  We recommend that you add friends 
running Freenet and upgrade to HIGH.
+SecurityLevels.networkThreatLevel.choice.LOW=I do not care about monitoring 
and want maximum performance.
+SecurityLevels.networkThreatLevel.desc.LOW=It may be quite easy for others to 
discover your identity!
+SecurityLevels.noFriendsWarning=You have not added any Friends. If you set the 
network security level to high or maximum, you will be unable to connect to 
Freenet until you have at least one connected Friend! Note that for there to be 
any meaningful security benefit, these must be people you actually know and at 
least marginally trust, and for good performance you will need at least 5-10 of 
them connected at any time. Are you sure?
+SecurityLevels.noFriendsCheckbox=I am sure, enable high network security 
level, I will add some Friends ASAP.
+SecurityLevels.noConnectedFriendsWarning=You do not have any connected 
Friends, although you have added ${added} friends. If you set the network 
security level to high or maximum, you will only be able to connect to Freenet 
when your friends are online, which they are not at the moment. You should add 
additional Friends, only use Freenet when your friends are connected, or not 
upgrade to high security. Note that for there to be any meaningful security 
benefit, your Friends must be people you actually know and at least marginally 
trust, and for good performance you will need at least 5-10 of them connected 
at any time. Are you sure?
+SecurityLevels.noConnectedFriendsCheckbox=I am sure, I will add more Friends 
and/or I accept that Freenet will only be online when my existing Friends are 
online.
+SecurityLevels.fewConnectedFriendsWarning=You only have ${connected} connected 
Friends right now, and you have added ${added} friends in total. If you set the 
network security level to high or maximum, Freenet will only connect to your 
Friends, so your performance may be significantly reduced, and if all your 
Friends are offline then it will not be able to connect at all. Note that 
Friends must be people you know and at least marginally trust for there to be 
any real security benefit, and you will need at least 5-10 connected Friends 
for good performance. Are you sure?
+SecurityLevels.fewConnectedFriendsCheckbox=I am sure, I will add more Friends 
and/or I accept the performance cost and the fact that Freenet may not connect 
when my Friends are offline.
+SecurityLevels.networkThreatLevelLowWarning=You are about to downgrade your 
node's network security level to low. This means that it will be easy for 
strangers to attack your anonymity over the Internet. Are you sure?
+SecurityLevels.networkThreatLevelLowCheckbox=I am sure, I want more speed and 
I don't care who can tell what I'm doing with Freenet!
+SecurityLevels.networkThreatLevelConfirmTitle=WARNING: Setting network 
security level to ${mode}
+SecurityLevels.maximumNetworkThreatLevelWarning=${bold}WARNING:${/bold} You 
are about to set the maximum network security level! This will 
${bold}significantly${/bold} slow down Freenet for you! Please do not do this 
unless you really need the security!
+SecurityLevels.maxSecurityYouNeedFriends=${bold}You must know at least one 
person already running Freenet${/bold}, preferably 3, 5-10 for good 
performance. You must add them on the Friends page. These must be people you 
already know and at least marginally trust.
+SecurityLevels.maximumNetworkThreatLevelCheckbox=Yes I really want to enable 
maximum security, I understand that Freenet is still experimental and it may 
still be possible to trace me, and that this setting may dramatically reduce 
Freenet's performance!
+SecurityLevels.friendsThreatLevelShort=Protection if your friends attack your 
anonymity
+SecurityLevels.friendsThreatLevel=How concerned are you about those you add as 
friends attempting to monitor your activities, either deliberately or as a 
result of their computers being compromised? (This is a default level and for 
most purposes can be overridden on a per-friend basis.) If you set the network 
security level to HIGH above, then the friends security level determines 
performance, along with the number of friends added.
+SecurityLevels.friendsThreatLevelConfirmTitle=WARNING: Setting friends 
security level to ${mode}
+SecurityLevels.friendsThreatLevel.name.HIGH=HIGH
+SecurityLevels.friendsThreatLevel.name.NORMAL=NORMAL
+SecurityLevels.friendsThreatLevel.name.LOW=LOW
+SecurityLevels.friendsThreatLevel.choice.HIGH=I would like Freenet to take 
extra precautions to avoid attacks from friends.
+SecurityLevels.friendsThreatLevel.desc.HIGH=Freenet will avoid sharing 
information with friends and so will be somewhat slower than in NORMAL mode.
+SecurityLevels.friendsThreatLevel.choice.NORMAL=I am not overly concerned 
about attacks from friends, but I would like Freenet to take reasonable 
precautions.
+SecurityLevels.friendsThreatLevel.desc.NORMAL=Freenet will share a limited 
amount of information with friends, and be slower than in LOW mode.
+SecurityLevels.friendsThreatLevel.choice.LOW=I am not concerned about attacks 
from friends. I trust my friends and their computer security abilities.
+SecurityLevels.friendsThreatLevel.desc.LOW=Freenet will share a lot of 
information with your friends' nodes to maximize performance.
+SecurityLevels.highFriendsThreatLevelWarning=You are about to set your friends 
threat level to high. This will reduce Freenet's performance, and shouldn't be 
necessary most of the time. If the reason you are setting this is that you have 
added people you don't know as Friends, you should consider whether you would 
be better off disconnecting from them and downgrading your network level to 
NORMAL if necessary. On the other hand if you expect an attacker to compromize 
your friends' computers or actively seek to turn them against you, this may be 
a prudent precaution.
+SecurityLevels.highFriendsThreatLevelCheckbox=I am sure I need high level 
protection against compromised or treacherous friends' nodes.
+SecurityLevels.physicalThreatLevelShort=Protection if your computer is seized 
or stolen
+SecurityLevels.physicalThreatLevel=How concerned are you about your computer 
being physically seized and examined?
+SecurityLevels.physicalThreatLevel.name.NORMAL=NORMAL
+SecurityLevels.physicalThreatLevel.name.LOW=LOW
+SecurityLevels.physicalThreatLevel.choice.NORMAL=I am concerned.
+SecurityLevels.physicalThreatLevel.desc.NORMAL=Freenet will encrypt temporary 
files etc, at a small performance cost, but you should take additional 
precautions such as disabling your browser cache when using the web interface. 
If you use persistent downloads (most tools do), you should encrypt the drive 
Freenet is running on.
+SecurityLevels.physicalThreatLevel.choice.LOW=I am not concerned.
+SecurityLevels.physicalThreatLevel.desc.LOW=Freenet will avoid disk encryption 
and leave traces of what you have visited on your hard disk, improving 
performance at the expense of lower security if your computer is seized.
+SecurityLevels.userAlertShortText=Security levels: Network: ${network}, 
Friends: ${friends}, Physical: ${physical}
+SecurityLevels.userAlertNetworkThreatLevel=Protection against a stranger 
attacking you over the Internet: ${level}
+SecurityLevels.userAlertFriendsThreatLevel=Protection if your friends attack 
your anonymity: ${level}
+SecurityLevels.userAlertPhysicalThreatLevel=Protection if your computer is 
seized or stolen: ${level}
+SecurityLevels.userAlertExtro=You can change these settings on ${link}the 
config page${/link}.
 ShortOption.parseError=Cannot parse value as a string array: ${error}
 ShortOption.parseError=The value specified can't be parsed as a 16-bit integer 
: ${val}
 SimpleToadletServer.advancedMode=Enable Advanced Mode?
@@ -1192,6 +1265,7 @@
 TranslationToadlet.contributingToLabelWithLang=You are currently contributing 
to the ${lang} translation:
 TranslationToadlet.currentTranslationLabel=Current translation
 TranslationToadlet.downloadTranslationsFile=Download your translations file
+TranslationToadlet.gotoNext=Go to next untranslated String?
 TranslationToadlet.hideAlreadyTranslated=Hide already translated strings
 TranslationToadlet.noCustomTranslations=There is no custom translation 
available.
 TranslationToadlet.originalVersionLabel=Original (English version)
@@ -1246,7 +1320,7 @@
 UserAlertsToadlet.titleWithName=Status alerts for ${name}
 WelcomeToadlet.activityTitle=Current Activity
 WelcomeToadlet.arkFetchCount=ARK Fetchers: ${total}
-WelcomeToadlet.alertsSummary=Status alerts summary
+WelcomeToadlet.alertsSummary=Status alerts summary (click for details or to 
change something)
 WelcomeToadlet.confirmAddBookmarkSubTitle=Confirm Bookmark Addition
 WelcomeToadlet.confirmAddBookmarkTitle=Add a Bookmark
 WelcomeToadlet.confirmAddBookmarkWithKey=Please confirm that you want to add 
the key ${key}  to your bookmarks and enter the description that you would 
prefer:

Modified: branches/db4o/freenet/src/freenet/l10n/freenet.l10n.fi.properties
===================================================================
--- branches/db4o/freenet/src/freenet/l10n/freenet.l10n.fi.properties   
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/l10n/freenet.l10n.fi.properties   
2008-09-24 23:54:07 UTC (rev 22829)
@@ -1,5 +1,6 @@
 BookmarkEditorToadlet.addBookmark=Lis?? kirjanmerkki
 BookmarkEditorToadlet.addCategory=Lis?? kategoria
+BookmarkEditorToadlet.addDefaultBookmarks=Uudelleenlis?? alkuper?iset 
kirjanmerkit
 BookmarkEditorToadlet.addNewBookmark=Lis?? uusi kirjanmerkki
 BookmarkEditorToadlet.addNewCategory=Lis?? uusi kategoria
 BookmarkEditorToadlet.addedNewBookmark=Uusi kirjanmerkki on lis?tty 
onnistuneesti
@@ -9,7 +10,6 @@
 BookmarkEditorToadlet.changesSaved=Muutokset ovat tallennettu onnistuneesti
 BookmarkEditorToadlet.changesSavedTitle=Muutokset tallennettu
 BookmarkEditorToadlet.confirmDelete=Poista
-BookmarkEditorToadlet.addDefaultBookmarks=Uudelleenlis?? alkuper?iset 
kirjanmerkit
 BookmarkEditorToadlet.cut=Leikkaa
 BookmarkEditorToadlet.delete=Poista
 BookmarkEditorToadlet.deleteBookmark=Poista kirjanmerkki
@@ -24,9 +24,9 @@
 BookmarkEditorToadlet.editCategoryTitle=Muokkaa kategoriaa
 BookmarkEditorToadlet.error=Virhe
 BookmarkEditorToadlet.hasAnActivelinkLabel=Onko ?vapaasivulla? 
activelink-kuvaa?
+BookmarkEditorToadlet.invalidKey=Freenet-avain on ep?kelpo.
 BookmarkEditorToadlet.invalidKeyTitle=Ep?kelpo avain
 BookmarkEditorToadlet.invalidKeyWithReason=Ep?kelpo freenet-avain
-BookmarkEditorToadlet.invalidKey=Freenet-avain on ep?kelpo.
 BookmarkEditorToadlet.keyLabel=Avain:
 BookmarkEditorToadlet.moveDown=Alas
 BookmarkEditorToadlet.moveUp=Yl?s
@@ -37,7 +37,7 @@
 BookmarkEditorToadlet.pasteTitle=Leikkaa/Liit?
 BookmarkEditorToadlet.save=Tallenna
 BookmarkEditorToadlet.title=Kirjanmerkkieditori
-BookmarkEditorToadlet.urlDecodeError=URL-dekoodausvirhe
+BookmarkEditorToadlet.urlDecodeError=Osoitteen purkuvirhe
 BookmarkItem.bookmarkUpdated=Sivusto ${name} on p?ivittynyt uudempaan 
versioon, ${edition}.
 BookmarkItem.bookmarkUpdatedTitle=Kirjanmerkki p?ivitetty: ${name}
 BookmarkItem.bookmarkUpdatedWithLink=Sivusto ${link}${name}${/link} on 
p?ivittynyt uudempaan versioon, ${edition}.
@@ -47,16 +47,18 @@
 BookmarkManager.listLong=merkittyjen ?vapaasivujen? lista
 BookmarkManager.malformedBookmark=V??r?nlainen kirjanmerkki
 BooleanOption.parseError=Tunnistamaton totuusarvo ${val} - kokeile arvoa true 
tai false
+BuildOldAgeUserAlert.tooOld=T?m?n solmun ohjelmisto on vanhempi kuin vanhin 
sallittu(Build #${lastgood}). P?ivit? solmusi mahdollisimman pian, sill? et 
muutoin pysty yhdist?m??n solmuihin, jotka on merkkitty ?LIIAN UUSI?. (Freenet 
saattaa j?tt?? solmusi menneisyyden tomuihin, ellet p?ivit? solmuasi.)
+BuildOldAgeUserAlert.tooOldShort=T?m?n solmun Freenet-versio on niin vanha, 
ettei se en?? saa yhteytt? solmuihinsa. P?ivit? se!
 BuildOldAgeUserAlert.tooOldTitle=Liian vanha versio
-ClockProblemDetectedUserAlert.text=Freenet on huomannut, ett? tietokoneesi 
kello (sek? kello ett? p?iv?m??r?) ei ole ajassa. Freenet ei toimi kunnolla, 
ennen kuin korjaat aika-asetuksesi ja uudelleenk?ynnist?t solmun.
-ClockProblemDetectedUserAlert.title=Tietokoneesi kello ei ole ajassa.
 CSSTokenizerFilter.deletedDisallowedString=Vaarallinen rivi poistettu
 CSSTokenizerFilter.deletedUnmatchedChar=t?sm??m?t?n merkki ohitettu:
 CSSTokenizerFilter.deletedUnofficialIdent=Ep?virallinen tunniste poistettu
-CSSTokenizerFilter.deletedUnofficialIdentWithURL=Ep?virallinen 
tunniste(URL:ll?) poistettu
+CSSTokenizerFilter.deletedUnofficialIdentWithURL=Ep?virallinen osoitteellinen 
tunnus poistettu
 CSSTokenizerFilter.invalidURLContents=Ep?kelpoa sis?lt?? kohdassa url()
 CSSTokenizerFilter.supplementalCharsNotSupported=UCS-4 MERKIT KOHDAN 0xFFFF 
YL?PUOLELLA EI TUETTU!
 CSSTokenizerFilter.unknownAtIdentifierLabel=Tuntematon @identifier:
+ClockProblemDetectedUserAlert.text=Freenet on huomannut, ett? tietokoneesi 
kello (sek? kello ett? p?iv?m??r?) ei ole ajassa. Freenet ei toimi kunnolla, 
ennen kuin korjaat aika-asetuksesi ja uudelleenk?ynnist?t solmun.
+ClockProblemDetectedUserAlert.title=Tietokoneesi kello ei ole ajassa.
 ConfigToadlet.appliedFailureExceptions=Asetuksesi hyv?ksyttiin seuraavilla 
poikkeuksilla:
 ConfigToadlet.appliedFailureTitle=Asetuksiasi ei hyv?ksytty.
 ConfigToadlet.appliedSuccess=Asetusmuutokset tallennettu onnistuneesti.
@@ -70,11 +72,6 @@
 ConfigToadlet.fullTitle=Freenet-solmun asetukset ${name}:lle
 ConfigToadlet.logger=logger
 ConfigToadlet.node=node
-ConfigToadlet.node.load=node.load
-ConfigToadlet.node.opennet=node.opennet
-ConfigToadlet.node.scheduler=node.scheduler
-ConfigToadlet.node.testnet=node.testnet
-ConfigToadlet.node.updater=node.updater
 ConfigToadlet.pluginmanager=pluginmanager
 ConfigToadlet.pluginmanager2=pluginmanager2
 ConfigToadlet.reset=Nollaa
@@ -84,30 +81,39 @@
 ConfigToadlet.title=Freenet-solmun asetukset
 ConfigToadlet.toadletsymlinker=toadletsymlinker
 ConfigToadlet.true=tosi
+ConfigToadlet.node.load=node.load
+ConfigToadlet.node.opennet=node.opennet
+ConfigToadlet.node.scheduler=node.scheduler
+ConfigToadlet.node.testnet=node.testnet
+ConfigToadlet.node.updater=node.updater
 ConfigurablePersister.doesNotExistCannotCreate=Tiedostoa ei ole olemassa, eik? 
sit? voida luoda
 ConfigurablePersister.existsCannotReadWrite=Tiedosto on olemassa, mutta siihen 
ei voida kirjoittaa
-ConnectivityToadlet.addressTitle=Osoite
-ConnectivityToadlet.sentReceivedTitle=L?hetetyt/Vastaanotetut paketit
-ConnectivityToadlet.local=PAIKALLINEN
-ConnectivityToadlet.remote=ET?
-ConnectivityToadlet.noreply=EI VASTAUSTA
-ConnectivityToadlet.summaryTitle=Yhdistett?vyys
-ConnectionsToadlet.nodeStatus.CONNECTED=YHDISTETTY
 ConnectionsToadlet.nodeStatus.BACKED OFF=SAAVUTTAMATTOMISSA
-ConnectionsToadlet.nodeStatus.TOO NEW=LIIAN UUSI
-ConnectionsToadlet.nodeStatus.TOO OLD=LIIAN VANHA
-ConnectionsToadlet.nodeStatus.DISCONNECTED=KATKENNUT
-ConnectionsToadlet.nodeStatus.NEVER CONNECTED=EI IKIN? YHDISTETTY
-ConnectionsToadlet.nodeStatus.DISABLED=POIS K?YT?ST?
-ConnectionsToadlet.nodeStatus.LISTEN ONLY=VAIN KUUNNELTAVA
-ConnectionsToadlet.nodeStatus.LISTENING=KUUNTELEE
 ConnectionsToadlet.nodeStatus.BURSTING=HALKEILEE
+ConnectionsToadlet.nodeStatus.BUSY=VARATTU
 ConnectionsToadlet.nodeStatus.CLOCK PROBLEM=KELLO-ONGELMA
+ConnectionsToadlet.nodeStatus.CONNECTED=YHDISTETTY
 ConnectionsToadlet.nodeStatus.CONNECTION ERROR=YHTEYSVIRHE
+ConnectionsToadlet.nodeStatus.DISABLED=POIS K?YT?ST?
+ConnectionsToadlet.nodeStatus.DISCONNECTED=KATKENNUT
 ConnectionsToadlet.nodeStatus.DISCONNECTING=SULKEE YHTEYTT?
+ConnectionsToadlet.nodeStatus.LISTEN ONLY=VAIN KUUNNELTAVA
+ConnectionsToadlet.nodeStatus.LISTENING=KUUNTELEE
+ConnectionsToadlet.nodeStatus.NEVER CONNECTED=EI IKIN? YHDISTETTY
+ConnectionsToadlet.nodeStatus.ROUTING DISABLED=EI REITIT? LIIKENNETT?
+ConnectionsToadlet.nodeStatus.TOO NEW=LIIAN UUSI
+ConnectionsToadlet.nodeStatus.TOO OLD=LIIAN VANHA
 ConnectionsToadlet.nodeStatus.UNKNOWN STATUS=TUNTEMATON TILA
-ConnectionsToadlet.nodeStatus.BUSY=VARATTU
-ConnectionsToadlet.nodeStatus.ROUTING DISABLED=EI REITIT? LIIKENNETT?
+ConnectivityToadlet.addressTitle=Osoite
+ConnectivityToadlet.connectivity=Internet-yhdistett?vyys
+ConnectivityToadlet.connectivityTitle=Yhdistett?vyys
+ConnectivityToadlet.local=PAIKALLINEN
+ConnectivityToadlet.noreply=EI VASTAUSTA
+ConnectivityToadlet.remote=ET?
+ConnectivityToadlet.sentReceivedTitle=L?hetetyt/Vastaanotetut paketit
+ConnectivityToadlet.summaryTitle=Yhdistett?vyys
+ConnectivityToadlet.title=Internet-yhdistett?vyys ${nodeName}:lle
+ContentDataFilter.unknownCharset=Sivula, jota olet aikeissa n?ytt??, k?ytet??n 
tunnistamatonta merkist??. T?m? tarkoittaa, ettemme kykene suodattamaan sivua, 
ja se voi vahingoittaa yksityisyytt?si.
 ContentDataFilter.unknownCharsetTitle=Tuntematon merkist?!
 ContentDataFilter.warningUnknownCharsetTitle=Varoitus: Tuntematon merkist? 
(${charset})
 ContentFilter.applicationPdfReadAdvice=Adobe(R) PDF-dokumentti - Eritt?in 
vaarallinen!
@@ -132,61 +138,60 @@
 DarknetConnectionsToadlet.alreadyInReferences=Meill? on jo annettu referenssi.
 DarknetConnectionsToadlet.backedOff=Yhdistetty mutta saavuttamattomissa: 
N?ihin vertaisiin on yhteys, mutta he ovat saavuttamattomissa, joten solmu ei 
ohjaa pyynt?j? heille.
 DarknetConnectionsToadlet.backedOffShort=Saavuttamattomissa
+DarknetConnectionsToadlet.busyShort=Varattu
 DarknetConnectionsToadlet.confirmRemoveNodeWarningTitle=Solmun poisto
+DarknetConnectionsToadlet.connError=Yhteys ep?onnistui(buginen solmu?)
+DarknetConnectionsToadlet.connErrorShort=Yhteysongelma
 DarknetConnectionsToadlet.connectedShort=Yhdistetty
+DarknetConnectionsToadlet.darknetFnpPort=Darknet FNP: ${port}/UDP (k?ytet??n 
yhdist?misess? tunnettuihin vertaisiin, kuten yst?viin; edelleenohjaa t?m? 
portti jos vain voit)
 DarknetConnectionsToadlet.disabledShort=Poissa k?yt?st?
 DarknetConnectionsToadlet.enterDescription=Sy?t? kuvaus:
-DarknetConnectionsToadlet.connError=Yhteys ep?onnistui(buginen solmu?)
-DarknetConnectionsToadlet.connErrorShort=Yhteysongelma
 DarknetConnectionsToadlet.failedToAddNodeTitle=Solmun lis?ys ep?onnistui
+DarknetConnectionsToadlet.fcpDisabled=FCP on pois k?yt?st? 
(Freenet-klienteille, kuten Frostille ja Thawille)
+DarknetConnectionsToadlet.fcpPort=FCP: ${port}/TCP (Freenet-klienteille, kuten 
Frostille ja Thawille)
+DarknetConnectionsToadlet.fileReference=Tiedosto, joka sis?lt?? referenssin:
 DarknetConnectionsToadlet.forceRemove=Pakota poisto
+DarknetConnectionsToadlet.fproxyDisabled=FProxy on pois k?yt?st? (t?m? 
webbik?ytt?liittym?)
+DarknetConnectionsToadlet.fproxyPort=FProxy: ${port}/TCP (t?m? 
webbik?ytt?liittym?)
+DarknetConnectionsToadlet.fullTitle=${name}:n yst?v?t (luotetut vertaiset)
 DarknetConnectionsToadlet.go=Mene
 DarknetConnectionsToadlet.idleTimeTitle=Yhdistetty / Lep??
 DarknetConnectionsToadlet.ipAddress=Solmun verkko-osoite muodossa IP:Port
 DarknetConnectionsToadlet.ipAddressTitle=Osoite
 DarknetConnectionsToadlet.listenOnlyShort=Vain kuunneltava
+DarknetConnectionsToadlet.myFriends=Yst?v?ni (lis??m?ni luotetut vertaiset)
+DarknetConnectionsToadlet.myReferenceHeader=${linkref}Solmureferenssini${/linkref}
 (${linktext}tekstimuodossa${/linktext})
 DarknetConnectionsToadlet.nameTitle=Nimi
 DarknetConnectionsToadlet.neverConnectedShort=Ei ikin? yhdistetty
 DarknetConnectionsToadlet.nodePortsTitle=Solmun k?ytt?m?t portit
 DarknetConnectionsToadlet.notConnectedShort=Katkennut
+DarknetConnectionsToadlet.opennetFnpPort=Opennet FNP: ${port}/UDP (k?ytet??n 
yhdist?misess? ep?luotettaviin vertaisiin, kuten muukalaisiin; edelleenohjaa 
t?m? portti jos vain voit)
+DarknetConnectionsToadlet.pasteReference=Liit? referenssi t?h?n (solmu osaa 
usein automaattisesti parsia esim. IRC-timestampit)
 DarknetConnectionsToadlet.privateNoteTitle=Yksityismerkint?
+DarknetConnectionsToadlet.referenceCopyWarning=Solmureferenssi t?ytyy kopioida 
${bold}SELLAISENAAN${/bold}. Muokkaaminen tekee siit? hy?dytt?m?n.
 DarknetConnectionsToadlet.remove=Poista se!
 DarknetConnectionsToadlet.removePeers=Poista valitut vertaiset
+DarknetConnectionsToadlet.routingDisabledShort=Ei reitit? liikennett?
+DarknetConnectionsToadlet.seedClients=Solmut, joille me olemme l?hdesolmuna
+DarknetConnectionsToadlet.seedClientsShort=Seeding for
 DarknetConnectionsToadlet.seedServers=Solmut, joita k?yt?mme l?hdesolmuina
 DarknetConnectionsToadlet.seedServersShort=L?hdesolmut
-DarknetConnectionsToadlet.seedClients=Solmut, joille me olemme l?hdesolmuna
-DarknetConnectionsToadlet.seedClientsShort=Seeding for
 DarknetConnectionsToadlet.selectAction=-- Valitse toiminto --
 DarknetConnectionsToadlet.sendMessageTitle=L?het? Solmulta Solmulle(N2NTM) 
-viesti
 DarknetConnectionsToadlet.sendMessageToPeers=L?het? N2NTM valituille 
vertaisille.
 DarknetConnectionsToadlet.separator=-- -- --
 DarknetConnectionsToadlet.statusTitle=Tila
+DarknetConnectionsToadlet.tmciDisabled=TMCI on pois k?yt?st? (yksinkertainen 
telnet-pohjainen komentorivik?ytt?liittym?)
+DarknetConnectionsToadlet.tmciPort=TMCI: ${port}/TCP (yksinkertainen 
telnet-pohjainen komentorivik?ytt?liittym?)
 DarknetConnectionsToadlet.tooNewShort=Liian uusi
+DarknetConnectionsToadlet.tooOldShort=Liian vanha
 DarknetConnectionsToadlet.unknownAddress=(tuntematon osoite)
 DarknetConnectionsToadlet.updateChangedPrivnotes=P?ivit? muutetut 
yksityismerkinn?t
+DarknetConnectionsToadlet.urlReference=Referenssin osoite:
 DarknetConnectionsToadlet.versionTitle=Versio
 ExtOldAgeUserAlert.extTooOldTitle=Freenet-ext on liian vanha
-FirstTimeWizardToadlet.homepageTitle=Freenetin ensimm?isen kerran velho
-FirstTimeWizardToadlet.chooseNodeName=Solmun nimi on pakollinen!
-FirstTimeWizardToadlet.connectToStrangers=Yhdist? tuntemattomiin?
-FirstTimeWizardToadlet.enableOpennet=Tunnetko ket??n, joka k?ytt?? freenetti??
-FirstTimeWizardToadlet.warningTitle=Varoitus!
-FirstTimeWizardToadlet.welcomeInfoboxTitle=Tervetuloa Freenetin ensimm?isen 
kerran velhoon!
-FirstTimeWizardToadlet.bandwidthLimit=Nopeusrajoitukset
-FirstTimeWizardToadlet.clickContinue=Klikkaa t?st? jatkaaksesi
-FirstTimeWizardToadlet.continue=Jatka
-FirstTimeWizardToadlet.continueEnd=Klikkaa t?st? aloittaaksesi Freenetin 
k?yt?n!
-FirstTimeWizardToadlet.datastoreSize=Datavaraston koko
-FirstTimeWizardToadlet.isNetworkTrusted=Onko paikallinen verkkosi luotettava?
-FirstTimeWizardToadlet.congratz=Tervetuloa laivaan!
-FirstTimeWizardToadlet.step1Title=Freenetin ensimm?isen kerran velho! - 
Yst?v?t ja muukalaiset
-FirstTimeWizardToadlet.step2Title=Freenetin ensimm?isen kerran velho! - 
Valitse solmun nimi
-FirstTimeWizardToadlet.step3Title=Freenetin ensimm?isen kerran velho! - 
Nopeusrajoitukset
-FirstTimeWizardToadlet.step4Title=Freenetin ensimm?isen kerran velho! - 
Datavaraston koko
-FirstTimeWizardToadlet.step5Title=Freenetin ensimm?isen kerran velho! - Verkon 
asetukset
-FirstTimeWizardToadlet.step6Title=Freenetin ensimm?isen kerran velho! - 
Onnitteluni, solmusi on nyt konfiguroitu!
-FirstTimeWizardToadlet.skipWizard=En ole ensikertalainen, haluan j?tt?? velhon 
v?liin!
 FProxyToadlet.abortToHomepage=Peru ja siirry FProxyn etusivulle.
+FProxyToadlet.alertsTitle=H?lytykset
 FProxyToadlet.cantBindPort=FProxya ei voida sitoa tuohon porttiin.
 FProxyToadlet.config=konfiguroi solmusi
 FProxyToadlet.configTitle=Asetukset
@@ -243,28 +248,65 @@
 FetchException.longError.6=Lohkon purku ep?onnistui
 FetchException.shortError.10=Ei ole arkistossa
 FetchException.shortError.11=Liian monta polkukomponenttia
+FileOffer.acceptTransferButton=Hyv?ksy siirto
 FileOffer.askUserTitle=Suora tiedostonsiirto
+FileOffer.commentLabel=Kommentti:
+FileOffer.failedReceiveHeader=Tiedoston ${filename} siirto solmulta ${node} 
ep?onnistui.
+FileOffer.failedReceiveTitle=Tiedoston vastaanotto ep?onnistui
+FileOffer.fileLabel=Tiedosto:
+FileOffer.mimeLabel=MIME-tyyppi:
 FileOffer.offeredFileHeader=Solmu ${name} tarjosi tiedostoa:
-FileOffer.fileLabel=Tiedosto:
+FileOffer.rejectTransferButton=Hylk?? siirto
 FileOffer.senderLabel=L?hett?j?:
-FileOffer.commentLabel=Kommentti:
-FileOffer.mimeLabel=MIME-tyyppi:
 FileOffer.sizeLabel=Koko:
-FileOffer.acceptTransferButton=Hyv?ksy siirto
-FileOffer.rejectTransferButton=Hylk?? siirto
-FileOffer.failedReceiveHeader=Tiedoston ${filename} siirto solmulta ${node} 
ep?onnistui.
-FileOffer.failedReceiveTitle=Tiedoston vastaanotto ep?onnistui
+FileOffer.succeededReceiveHeader=Tiedoston ${filename} siirto solmulta ${node} 
onnistui.
 FileOffer.succeededReceiveTitle=Tiedoston vastaanotto onnistui
-FileOffer.succeededReceiveHeader=Tiedoston ${filename} siirto solmulta ${node} 
onnistui.
+FirstTimeWizardToadlet.bandwidthLimit=Nopeusrajoitukset
+FirstTimeWizardToadlet.chooseNodeName=Solmun nimi on pakollinen!
+FirstTimeWizardToadlet.clickContinue=Klikkaa t?st? jatkaaksesi
+FirstTimeWizardToadlet.congratz=Tervetuloa laivaan!
+FirstTimeWizardToadlet.connectToStrangers=Yhdist? tuntemattomiin?
+FirstTimeWizardToadlet.continue=Jatka
+FirstTimeWizardToadlet.continueEnd=Klikkaa t?st? aloittaaksesi Freenetin 
k?yt?n!
+FirstTimeWizardToadlet.datastoreSize=Datavaraston koko
+FirstTimeWizardToadlet.enableOpennet=Tunnetko ket??n, joka k?ytt?? freenetti??
+FirstTimeWizardToadlet.homepageTitle=Freenetin ensimm?isen kerran velho
+FirstTimeWizardToadlet.isNetworkTrusted=Onko paikallinen verkkosi luotettava?
+FirstTimeWizardToadlet.skipWizard=En ole ensikertalainen, haluan j?tt?? velhon 
v?liin!
+FirstTimeWizardToadlet.step1Title=Freenetin ensimm?isen kerran velho! - 
Yst?v?t ja muukalaiset
+FirstTimeWizardToadlet.step2Title=Freenetin ensimm?isen kerran velho! - 
Valitse solmun nimi
+FirstTimeWizardToadlet.step3Title=Freenetin ensimm?isen kerran velho! - 
Nopeusrajoitukset
+FirstTimeWizardToadlet.step4Title=Freenetin ensimm?isen kerran velho! - 
Datavaraston koko
+FirstTimeWizardToadlet.step5Title=Freenetin ensimm?isen kerran velho! - Verkon 
asetukset
+FirstTimeWizardToadlet.step6Title=Freenetin ensimm?isen kerran velho! - 
Onnitteluni, solmusi on nyt konfiguroitu!
+FirstTimeWizardToadlet.tenPercentDisk=(= 10% vapaasta levytilasta)
+FirstTimeWizardToadlet.warningTitle=Varoitus!
+FirstTimeWizardToadlet.welcomeInfoboxTitle=Tervetuloa Freenetin ensimm?isen 
kerran velhoon!
 GIFFilter.invalidHeader=Tiedostolla ei ole kelvollista GIF-otsikkotietoa.
 GIFFilter.invalidHeaderTitle=Ep?kelpo otsikkotieto
 GIFFilter.tooShortTitle=Liian lyhyt
+GenericReadFilterCallback.couldNotParseAbsoluteFreenetURI=Ei voitu tulkita 
t?sm?llist? Freenet URIa.
+GenericReadFilterCallback.couldNotParseFormURIWithError=Suodatin ei kyennyt 
tulkitsemaan URI-muotoa: ${error}
+GenericReadFilterCallback.couldNotParseRelativeFreenetURI=Suhteellista Freenet 
URIa ei voitu tulkita
+GenericReadFilterCallback.couldNotParseURIWithError=Ei voitu tulkita URIa: 
${error}
+GenericReadFilterCallback.invalidFormURI=Ep?kelpo URI: osoittaa ulkopuoliseen 
resurssiin
+GenericReadFilterCallback.invalidFormURIAttemptToEscape=Yritys paeta 
hakemistorakennetta
+GenericReadFilterCallback.malformedAbsoluteURL=Ep?kelpo osoite (ehdoton): 
${error}
+GenericReadFilterCallback.malformedRelativeURL=Ep?muodostunut osoite 
(suhteellinen): ${error}
+GenericReadFilterCallback.protocolNotEscaped=Tuntematon protokolla: ${protocol}
 HTMLFilter.deletedUnknownStyle=tuntematon tyyli poistettu
 JPEGFilter.tooShort=Tiedosto on liian lyhyt ollakseen JPEG.
 JPEGFilter.tooShortTitle=Liian lyhyt
 LocalFileInsertToadlet.fileHeader=Tiedosto
 LocalFileInsertToadlet.insert=Lis??
 LocalFileInsertToadlet.sizeHeader=Koko
+LogConfigHandler.minLoggingPriority=Pienin prioriteetti lokiviesteille
+LogConfigHandler.minLoggingPriorityLong=Pienin prioriteetti, jolla viestit 
kirjoitetaan lokiin. Vaihtoehdot ovat debug(testaus), minor(v?h?inen), 
normal(vakio), error(virheet), ??nekk?imm?st? hiljaisimpaan.
+LoggerHook.unrecognizedPriority=Tunnistamaton prioriteettinimi: ${name}.
+LongOption.parseError=Arvoa ei voida parsia 64-bittiseksi kokonaisluvuksi: 
${val}
+MeaningfulNodeNameUserAlert.noNodeNick=Ilmeisesti solmullasi ei ole 
lempinime?. S?hk?postiosoitteen tai IRC-nimimerkin pist?minen t?h?n on 
yleisesti ottaen hyv? idea, ja auttaa yst?vi?si tunnistamaan solmusi(huomaa, 
ett? vain darknet-vertaiset, jotka ovat listattuna yst?v?t-sivulla voivat n?hd? 
solmusi nimen, se ei n?y tuntemattomille).
+MeaningfulNodeNameUserAlert.noNodeNickShort=Solmullesi ei ole m??ritetty nime?.
+MeaningfulNodeNameUserAlert.noNodeNickTitle=Solmullesi ei ole m??ritetty nime?.
 N2NTMToadlet.delayedTitle=Viiv?stetty
 N2NTMToadlet.failedTitle=Ep?onnistui
 N2NTMToadlet.friends=Yst?v?t
@@ -279,6 +321,17 @@
 N2NTMToadlet.tooLongTitle=Liian pitk?
 N2NTMUserAlert.delete=Poista
 N2NTMUserAlert.reply=Vastaa
+Node.acceptSeedConnectionsShort=Ole l?hdesolmu
+Node.inBWLimit=Latausnopeuden rajoitus (tavua / sekunti)
+Node.inBWLimitLong=Latausnopeuden rajoitus (tavua / sekunti). Solmun ei 
pit?isi k?yt?nn?ss? ikin? ylitt?? t?t?. -1 tarkoittaa 4 x l?hetysnopeus.
+Node.l10nLanguage=Kieli, jolla solmu n?ytt?? viestit
+Node.l10nLanguageLong=T?m? asetus muuttaa solmun k?ytt?m?n kielen viestien 
n?ytt?miseen. Pid? kuitenkin mieless?, ett? jotkin viestit eiv?t ole 
k??nnettyin? ennen seuraavaa solmun uudelleenk?ynnistyst?.
+Node.nodeName=Freenet-solmun lempinimi
+Node.nodeNameLong=Solmun lempinimi. T?m? n?kyy vain yst?ville.
+Node.opennetEnabled=K?yt? turvatonta tilaa (yhdist? automaattisesti 
turvattomiin solmuihin)
+Node.opennetEnabledLong=K?yt? turvatonta tilaa (tunnetaan nimell? opennet). 
Jos t?m? on k?yt?ss?, solmu automaattisesti vaihtaa solmureferenssej? muiden 
turvattomien solmujen kanssa (muukalaiset ja yst?v?t). Mutta t?m? tarkoittaa, 
ettei yll?pit?m?si solmu ole en?? yksityinen, ja monet hy?kk?ykset ovat paljon 
helpompia. Jos tunnet tarpeeksi Freenetin k?ytt?ji?, sinun kannattaa pysytell? 
luotettuissa(yst?v?t) yhteyksiss? ja kytke? t?m? pois.
+Node.outBWLimit=L?hetysnopeuden rajoitus (tavua / sekunti)
+Node.outBWLimitLong=Kova rajoitus l?hetysnopeudelle (tavua / sekunti). solmun 
ei pit?isi k?yt?nn?ss? koskaan ylitt?? t?t?.
 Node.storeSize=Varaston koko tavuissa
 Node.storeSizeLong=Varaston koko tavuissa
 NodeIPDectector.inclLocalAddress=Sis?llyt? paikalliset osoitteet 
solmuviitteeseen
@@ -287,48 +340,101 @@
 NodeIPDectector.ipOverrideLong=IP-osoitteen korvaus (yleens? turha) - aseta 
t?m?, jos sinulla on *staattinen* IP-osoite tai domain-nimi (esim. dyndns:n 
kautta) ja olet palomuurin takana.
 NodeIPDectector.tempAddressHint=V?liaikainen IP-osoitteen vihje
 NodeIPDectector.tempAddressHintLong=V?liaikainen vihje omasta IP:st?; 
poistetaan k?yt?n j?lkeen
+NodeUpdateManager.installNewVersions=Asenna automaattisesti uudet versiot.
+NodeUpdateManager.installNewVersionsLong=M??ritt??, asentaako solmu 
p?ivitykset automaattisesti, kysym?tt? sinulta.
+NotEnoughNiceLevelsUserAlert.content=Solmusi on huomannut, ett? se py?rii 
tavallista korkeammalla ?nice?-arvolla. Se ei voi suoriutua kunnolla, ellei 
sill? ole tarpeeksi tasoja j?ljell?. (Katso PRIORITY run.sh-tiedostosta ja 
alenna t?t? arvoa)! T?ll? hetkell? solmulla on ${available} tasoa j?ljell? kun 
se tarvitsisi ${required} tasoa.
+NotEnoughNiceLevelsUserAlert.short=Ei tarpeeksi ?nice?-tasoja j?ljell?! Aja 
Freenetti? alemmalla ?nice?-tasolla korjaaksesi ongelman.
+NotEnoughNiceLevelsUserAlert.title=Ei tarpeeksi ?nice?-tasoja j?ljell?!
+OpennetConnectionsToadlet.fullTitle=${name}:lla on ${counts} muukalaista 
(ep?luotettavaa vertaista)
+OpennetConnectionsToadlet.peersListTitle=Opennet-vertaiseni (ep?luotettavat 
vertaiset, jotka on lis?tty solmulle umpim?hk?isesti)
+OpennetUserAlert.warning=Freenet py?rii parhaillaan turvattomassa tilassa. On 
helppoa saada selville, ett? sin? py?rit?t Freenetti?, ja yhdist?? solmu 
solmuusi hy?k?t?kseen sinua vastaan. Yrit? saada joitakin yhteyksi? 
luottamiltasi henkil?ilt? ja lis?? heid?t Yst?v?t-sivulle mahdollisimman pian. 
N?in olet paljon v?hemm?n haavoittuvainen. Kun olet lis?nnyt v?hint??n kymmenen 
yst?v?? (henkil?iden lis??minen, joita et tunne, ei lis?? turvallisuuttasi), 
kytke turvaton tila pois ja Freenet-yhteytesi on n?kym?t?n ulkomaailmalle.
+OpennetUserAlert.warningShort=Turvaton tila on k?yt?ss?.
+OpennetUserAlert.warningTitle=Varoitus: turvaton tila on k?yt?ss?. Solmusi 
yhdist?? muukalaisiin.
+PageMaker.modeAdvanced=Kehittynyt rajapinta
+PageMaker.modeAdvancedTooltip=Kehittynyt rajapinta, jota vain kokeneet 
k?ytt?j?t ja kehitt?j?t tarvitsevat
+PageMaker.modeSimple=Yksinkertainen rajapinta
+PageMaker.modeSimpleTooltip=Yksinkertainen rajapinta, jota kaikki k?ytt?j?t 
voivat k?ytt??
+PluginManager.cannotSetOnceLoaded=Liit?nn?islistaa ei voida asettaa 
k?ytt??noton j?lkeen
+PluginManager.loadedOnStartup=K?ynnistyksen yhteydess? k?ynnistett?v?t 
liit?nn?iset
+PluginManager.loadedOnStartupLong=Luokkapolku, nimi ja sijainti liit?nn?isille 
solmun k?ynnistyksen yhteyteen.
+PluginManager.loadedPlugins=K?ynnistyksess? ladattavat liit?nn?iset
+PluginManager.loadedPluginsLong=Lista liit?nn?isist?, jotka otetaan k?ytt??n 
solmun k?ynnistyksen yhteydess?
+PluginManager.pluginLoadingFailed=M??ritetty? liit?nn?ist? ${name} ei voitu 
ottaa k?ytt??n
+PluginManager.pluginLoadingFailedShort=Liit?nn?ist? ${name} ei voitu ottaa 
k?ytt??n!
+PluginManager.pluginLoadingFailedTitle=Liit?nn?ist? ei voitu ottaa k?ytt??n!
+PluginManager.pluginLoadingFailedWithMessage=M??ritetty? liit?nn?ist? ${name} 
ei voitu ottaa k?ytt??n: ${message}
+PluginManager.pluginReqNewerJVM=Liit?nn?inen ${name} n?ytt?isi vaativan 
uudempaa JVM:??. Asenna v?hint??n Sun Java 1.5, tai poista kyseinen 
liit?nn?inen.
+PluginManager.pluginReqNewerJVMTitle=Uudempi JVM vaaditaan liit?nn?isen 
${name} toimesta.
 PluginToadlet.addPluginTitle=Lis?? liit?nn?inen
 PluginToadlet.failedToLoadPlugin=Liit?nn?isen lis?ys ep?onnistui.
+PluginToadlet.failedToLoadPluginCheckClass=Haluamaasi liit?nn?ist? ei voitu 
ottaa k?ytt??n. Varmista liit?nn?isen nimi, luokka ja osoite, jos sy?tit arvot.
 PluginToadlet.failedToLoadPluginTitle=Liit?nn?isen lataus ep?onnistui
 PluginToadlet.internalNameTitle=Sis?inen nimi
 PluginToadlet.loadPluginCommand=Lataa liit?nn?inen
 PluginToadlet.noWebInterfaceTitle=Liit?nn?isell? ei ole web-liittym??
 PluginToadlet.pluginList=Liit?nn?islista
-PluginToadlet.pluginListTitle=Lista liit?nn?isist?
+PluginToadlet.pluginListTitle=Liit?nn?islista
 PluginToadlet.pluginNameTitle=Liit?nn?isen nimi
 PluginToadlet.pluginNotFoundTitle=Liit?nn?ist? ei l?ytynyt
 PluginToadlet.visit=Vieraile
+PproxyToadlet.Error=Virhe
+PproxyToadlet.Load=Lataa
 PproxyToadlet.changeReloadOnStartup=Muuta
 PproxyToadlet.classNameTitle=Luokan nimi
-PproxyToadlet.Error=Virhe
+PproxyToadlet.downloadNotAllowedFromRemoteServer=Liit?nn?isten lataus on 
sallittua vain kehitt?jien omalta serverilt?.
+PproxyToadlet.fileonly=vain paikalliset tiedostot
 PproxyToadlet.internalIDTitle=Sis?inen ID
-PproxyToadlet.Load=Lataa
+PproxyToadlet.loadFreenetPlugin=Lis?? ep?virallinen liit?nn?inen Freenetist?
+PproxyToadlet.loadFreenetPluginText=T?h?n voit sy?tt?? Freenet URIn 
liit?nn?isest?, jonka haluat ottaa k?ytt??n. N?m? liit?nn?iset eiv?t ole edes 
et?isesti tuettuja tai tarkastettuja yksityisyysvuotojen varalta Freenetin 
kehitt?jien toimesta, joten jos haluat hakea liit?nn?isen muualta, olet 
k?yt?nn?ss? omillasi.
+PproxyToadlet.loadFreenetURLLabel=Liit?nn?isen avain
 PproxyToadlet.loadOfficialPlugin=Lis?? virallinen liit?nn?inen
 PproxyToadlet.loadOfficialPluginLabel=Lataa virallinen liit?nn?inen
+PproxyToadlet.loadOfficialPluginText=N?m? liit?nn?iset ovat The Freenet 
Projectin palvelimilla. Uskomme, ett? n?m? liit?nn?iset ovat vapaita 
yksityisyysvuodoista, joskin emme takaa sit?.
+PproxyToadlet.loadOfficialPluginWarning=VAROITUS: Virallisen liit?nn?isen 
ottaminen k?ytt??n edellytt?? sen hakemista Internetist? (ei Freenetist?). ?l? 
ota k?ytt??n liit?nn?isi? t?ss?, jos se on ongelmaksi.
 PproxyToadlet.loadOtherPlugin=Lis?? ep?virallinen liit?nn?inen
-PproxyToadlet.loadOtherURLLabel=Liit?nn?isen URL
+PproxyToadlet.loadOtherPluginText=T?h?n voit sy?tt?? sen liit?nn?isen 
osoitteen, jonka haluat hakea. Muut liit?nn?iset kuin yl?puolen listassa 
olevat, eiv?t ole edes et?isesti tuettuja tai tarkastettuja yksityisyysvuotojen 
varalta Freenetin kehitt?jien toimesta, joten jos haluat hakea liit?nn?isen 
muualta, olet k?yt?nn?ss? omillasi.
+PproxyToadlet.loadOtherURLLabel=Liit?nn?isen osoite
 PproxyToadlet.noPlugins=Ei liit?nn?isi? ladattu
+PproxyToadlet.pluginDirectoryNotCreated=Liit?nn?ishakemistoa ei voitu luoda.
+PproxyToadlet.pluginNotDownloaded=Liit?nn?ist? ei voitu hakea.
+PproxyToadlet.pluginNotFoundReload=M??ritetty? liit?nn?ist? ei voitu paikantaa 
uudelleenlataamista varten.
+PproxyToadlet.pluginNotFoundReloadTitle=Liit?nn?ist? ei 
l?ydetty(uudelleenladataan)
+PproxyToadlet.pluginStopping=Liit?nn?ist? pys?ytet??n...
 PproxyToadlet.pluginUnloaded=Liit?nn?inen poistettu k?yt?st?
+PproxyToadlet.pluginUnloadedWithName=Liit?nn?inen ${name} on poistettu 
k?yt?st?.
 PproxyToadlet.plugins=Liit?nn?iset
+PproxyToadlet.pluginsWithNodeName=${name}:n liit?nn?iset
+PproxyToadlet.refreshOnStartup=P?ivit? palvelimelta k?ynnistyksen yhteydess?
+PproxyToadlet.reload=Uudelleenlataa
+PproxyToadlet.reloadOnStartupShort=Uudelleenlataa k?ynnistett?ess?
+PproxyToadlet.reloadPluginTitle=Uudelleenlataa liit?nn?inen
+PproxyToadlet.returnToPluginPage=Palaa liit?nn?issivulle
+PproxyToadlet.startedAtTitle=K?ynnistetty
 PproxyToadlet.startingPluginName=Liit?nn?isen nimi
 PproxyToadlet.startingPluginStatus=Nykyinen tila
-PproxyToadlet.startingPluginStatus.downloading=luodaan paikallista kopiota...
-PproxyToadlet.startingPluginStatus.starting=k?ynnistet??n
 PproxyToadlet.startingPluginTime=Aikaa tuhlattu
-PproxyToadlet.pluginStopping=Liit?nn?ist? pys?ytet??n...
+PproxyToadlet.startingPluginsTitle=K?ynnistyv?t liit?nn?iset
+PproxyToadlet.unauthorized=Et ole oikeutettu t?m?n sivun katsomiseen.
 PproxyToadlet.unload=Poista k?yt?st?
 PproxyToadlet.unloadPluginTitle=Poista liit?nn?inen k?yt?st??
+PproxyToadlet.unloadPluginWithName=Haluatko varmasti poistaa liit?nn?isen 
${name} pois k?yt?st??
 PproxyToadlet.unloadPurge=Poista liit?nn?inen v?limuistista?
+PproxyToadlet.versionTitle=Versio
+PproxyToadlet.startingPluginStatus.downloading=luodaan paikallista kopiota...
+PproxyToadlet.startingPluginStatus.starting=k?ynnistet??n
 QueueToadlet.DUinProgress=Aktiiviset kansion l?hetykset
 QueueToadlet.DinProgress=Aktiiviset lataukset
 QueueToadlet.UinProgress=Aktiiviset l?hetykset
 QueueToadlet.change=Vaihda
 QueueToadlet.completedDU=Onnistuneet kansion l?hetykset
+QueueToadlet.completedDinDownloadDirectory=Valmistuneet lataukset 
lataushakemistossa (${size})
 QueueToadlet.completedDtoDisk=Onnistuneet lataukset levylle
 QueueToadlet.completedDtoTemp=Onnistuneet lataukset v?limuistiin
 QueueToadlet.completedU=Onnistuneet: L?hetykset (${size})
 QueueToadlet.completedUDirectory=Onnistuneet: Kansion l?hetykset (${size})
 QueueToadlet.download=Lataa
+QueueToadlet.downloadFiles=Pakettilataukset
+QueueToadlet.downloadFilesInstructions=Voit liitt?? listan avaimista 
ladataksesi ne (yksi / rivi)
 QueueToadlet.errorAccessDenied=Virhe: Ei oikeuksia!
 QueueToadlet.errorDToDisk=Ei voida ladata levylle
 QueueToadlet.errorDownloadNotCompleted=Lataus ei valmis
@@ -339,24 +445,23 @@
 QueueToadlet.errorNoKey=Ei avainta annettu ladattavaksi
 QueueToadlet.errorNoKeyToD=Et m??ritt?nyt ladattavaa avainta
 QueueToadlet.failedD=Ep?onnistuneet lataukset
-QueueToadlet.failedD=Ep?onnistunut: Lataukset (${size})
 QueueToadlet.failedDU=Ep?onnistuneet hakemiston l?hetykset
-QueueToadlet.failedDU=Ep?onnistunut: Hakemiston l?hetykset (${size})
 QueueToadlet.failedU=Ep?onnistuneet l?hetykset
-QueueToadlet.failedU=Ep?onnistunut: L?hetykset (${size})
 QueueToadlet.fcpIsMissing=FCP-serveri puuttuu
 QueueToadlet.fileName=Tiedostonimi
 QueueToadlet.files=Tiedostoja
 QueueToadlet.follow=Seuraa uudelleenohjausta
 QueueToadlet.globalQueueIsEmpty=Globaali jono on tyhj?
 QueueToadlet.identifier=Tunniste
+QueueToadlet.insertAs=Sy?t?...
 QueueToadlet.insertFile=Sy?t? tiedosto
-QueueToadlet.insertFileLabel=Tiedosto
+QueueToadlet.insertFileBrowseLabel=Selaa
 QueueToadlet.insertFileCompressLabel=Pakkaa
 QueueToadlet.insertFileInsertFileLabel=Sy?t? tiedosto
-QueueToadlet.insertFileBrowseLabel=Selaa
+QueueToadlet.insertFileLabel=Tiedosto
 QueueToadlet.insertFileResetForm=Nollaa lomake
 QueueToadlet.key=Avain
+QueueToadlet.legend=Selite
 QueueToadlet.mimeType=MIME-tyyppi
 QueueToadlet.none=tyhj?
 QueueToadlet.panicButton=Paniikkinappula
@@ -364,6 +469,7 @@
 QueueToadlet.persistenceForever=loppumaton
 QueueToadlet.persistenceNone=olematon
 QueueToadlet.persistenceReboot=uudelleenk?ynnist?
+QueueToadlet.priority=Prioriteetti
 QueueToadlet.priority0=h?t?tapaus
 QueueToadlet.priority1=eritt?in suuri
 QueueToadlet.priority2=korkea
@@ -371,34 +477,86 @@
 QueueToadlet.priority4=matala
 QueueToadlet.priority5=eritt?in matala
 QueueToadlet.priority6=ei tule valmistumaan
-QueueToadlet.priority=Prioriteetti
 QueueToadlet.progress=Edistyminen
 QueueToadlet.reason=Syy
 QueueToadlet.remove=Poista
-QueueToadlet.requestNavigation=Request Navigation
+QueueToadlet.requestNavigation=Pyynt?valikko
 QueueToadlet.restart=Uudelleenk?ynnist?
 QueueToadlet.size=Koko
 QueueToadlet.starting=K?YNNISTET??N
+QueueToadlet.title=${nodeName}:n julkinen jono
 QueueToadlet.totalSize=Kokonaiskoko
 QueueToadlet.unknown=Tuntematon
 QueueToadlet.warningUnsafeContent=Mahdollisesti turvatonta sis?lt??
+QueueToadlet.wipD=Kesken: lataukset (${size})
+QueueToadlet.wipU=Kesken: l?hetykset (${size})
+RevocationKeyFoundUserAlert.title=Projektin yksityisen avaimen turvallisuus on 
heikentynyt!
 SimpleToadletServer.advancedMode=K?yt? edistynytt? tilaa?
+SimpleToadletServer.cssName=K?ytt?liittym?n teema
+SimpleToadletServer.cssNameLong=Valitse teema Freenetin webbik?ytt?liittym?lle
+StatisticsToadlet.ackOnlyBytes=Vain tunnistamiseen k?ytetyt paketit: ${total}
+StatisticsToadlet.activityInserts=Lis?ykset: ${totalSenders} kaikki 
l?hett?j?t, ${CHKhandlers} CHK-k?sittelij?t, ${SSKhandlers} SSK-k?sittelij?t 
(${local} local)
+StatisticsToadlet.activityRequests=Pyynn?t: ${totalSenders} kaikki l?hett?j?t, 
${CHKhandlers} CHK-k?sittelij?t, ${SSKhandlers} SSK-k?sittelij?t (${local} 
local)
+StatisticsToadlet.adminBytes=Yll?pitobiti: ${initial} yhteyden avaamiset, 
${changedIP} IP:n vaihtoviestit, ${disconn} katkaisuviestit, ${routingStatus} 
reititystiedon muutokset
+StatisticsToadlet.allocMemory=Javalle varattu muisti: ${memory}
+StatisticsToadlet.announceBytes=Tiedotuksen l?hetysm??r?: ${total}
+StatisticsToadlet.authBytes=Yhteyden asennus: ${total} ulosmenev??
 StatisticsToadlet.bandwidthTitle=Kaistanleveys
 StatisticsToadlet.cpus=K?ytett?viss? olevat prosessorit: ${count}
+StatisticsToadlet.debuggingBytes=testausbitit: ${netColoring} verkon v?ritys, 
${ping} viive, ${probe} tutkintapyynn?t, ${routed} reititetyt testiviestit.
 StatisticsToadlet.fullTitle=Tilastot ${name}:lle
 StatisticsToadlet.getLogs=Nappaa edellisen solmun lokitiedosto
+StatisticsToadlet.inputRate=latausnopeus: ${rate}/s (of ${max})
+StatisticsToadlet.insertOutput=Sis?ll?n sy?tt?misen l?hetysm??r?t (poislukien 
hy?tykuorma): CHK ${chk} SSK ${ssk}.
+StatisticsToadlet.javaVersion=Java-versio: ${version}
+StatisticsToadlet.jeDumpButton=Muodosta JE-raportti.
+StatisticsToadlet.jvmInfoTitle=JVM-info
+StatisticsToadlet.jvmVendor=JVM-toimittaja: ${vendor}
+StatisticsToadlet.jvmVersion=JVM-versio: ${version}
+StatisticsToadlet.maxMemory=Maksimi Javan muisti: ${memory}
+StatisticsToadlet.noRequests=Solmusi ei k?sittele yht??n pyynt?? juuri nyt.
+StatisticsToadlet.nodeToNodeBytes=solmulta solmulle -viestej?: ${total}
+StatisticsToadlet.offerReplys=T?ll? hetkell? ajettavat tarjousvastaukset: 
${chk} CHK, ${ssk} SSK.
+StatisticsToadlet.offeredKeyOutput=tarjotut avaimet: l?hetett?v?t avaimet 
${total}, l?hetett?v?t tarjoukset ${offered}
+StatisticsToadlet.osArch=k?ytt?j?rjestelm?arkkitehtuuri: ${arch}
+StatisticsToadlet.osName=K?ytt?j?rjestelm?n nimi: ${name}
+StatisticsToadlet.osVersion=K?ytt?j?rjestelm?versio: ${version}
+StatisticsToadlet.outputRate=L?hetysliikenne: ${rate}/s (of ${max})
+StatisticsToadlet.payloadOutput=L?hetyksen hy?tykuorma: ${total} 
(${rate}/s)(${percent}%)
+StatisticsToadlet.peerStatsTitle=Vertaisstatistiikat
+StatisticsToadlet.priority=Prioriteetti
+StatisticsToadlet.requestOutput=Pyynt?jen l?hetysnopeus (poislukien 
hy?tykuorma): CHK ${chk} SSK ${ssk}.
+StatisticsToadlet.resendBytes=Uudelleenl?hetetyt tavut: ${total}
+StatisticsToadlet.routingDisabled=Reititt?m?t?n liikenne (olemme parhaillaan 
yhdistettyn? solmuun, mutta joko me  tai se kielt?ydyt??n reititt?m?st? 
liikennett?)
+StatisticsToadlet.routingDisabledShort=Reititt?m?t?n liikenne
+StatisticsToadlet.running=P??ll?
+StatisticsToadlet.statisticGatheringTitle=Statistiikkakokoelmat
+StatisticsToadlet.swapOutput=Vaihtotietojen l?hetysm??r?: ${total}.
+StatisticsToadlet.threadDumpButton=Muodosta s?ieraportti
+StatisticsToadlet.threads=Elossa olevat s?ikeet: ${running}/${max}
+StatisticsToadlet.threadsByPriority=Allastetut s?ikeet prioriteetin mukaan
+StatisticsToadlet.totalInput=Latausm??r?: ${total} (${rate}/s)
+StatisticsToadlet.totalOutput=L?hetysnopeus: ${total} (${rate}/sec)
+StatisticsToadlet.totalOverhead=Muiden kuin pyynt?jen ylij??m?: ${rate}/s 
(${percent}%).
+StatisticsToadlet.transferringRequests=Siirrett?v?t pyynn?t: l?hetett?v?t 
${senders}, vastaanotettavat ${receivers}
+StatisticsToadlet.unaccountedBytes=Muu l?hetys: ${total} (${percent}%)
+StatisticsToadlet.uomBytes=P?ivitt?j?n l?hetysm??r?: ${total}
+StatisticsToadlet.usedMemory=Javan k?ytt?m? muisti: ${memory}
+StatisticsToadlet.versionTitle=Solmun versiotieto
+StatisticsToadlet.waiting=Odottaa
 TestnetHandler.port=Testnetin portti
 TextModeClientInterfaceServer.enabled=Salli TCMI
 TextModeClientInterfaceServer.enabledLong=M??ritt??, halutaanko TCMI sallia
-Toadlet.yes=Kyll?
-Toadlet.no=Ei
 Toadlet.cancel=Peruuta
 Toadlet.clickHere=Napsauta t?h?n
+Toadlet.homepage=Kotisivu
 Toadlet.internalErrorPleaseReport=Sis?inen virhe: raportoi siit?, kiitoksia
 Toadlet.internalErrorTitle=Sis?inen virhe
+Toadlet.no=Ei
 Toadlet.nodeHomepage=Solmun kotisivu
 Toadlet.notSupportedTitle=Ei tuettu
-Toadlet.homepage=Kotisivu
+Toadlet.yes=Kyll?
+TranslationToadlet.contributingToLabelWithLang=Muokkaat parhaillaan kielen 
${lang} k??nn?st?:
 TranslationToadlet.currentTranslationLabel=Nykyinen k??nn?s
 TranslationToadlet.downloadTranslationsFile=Lataa nykyinen k??nn?stiedosto
 TranslationToadlet.hideAlreadyTranslated=Piilota jo k??nnetyt rivit
@@ -407,6 +565,7 @@
 TranslationToadlet.returnToTranslations=Palaa k??nn?ssivulle
 TranslationToadlet.showEverything=N?yt? kaikki, mukaanlukien k??nnetyt rivit
 TranslationToadlet.translationKeyLabel=K??nn?ksen avain
+UpdatedVersionAvailableUserAlert.clickToUpdateNow=Klikkaa t?st? p?ivitt??ksesi 
solmusi heti.
 UpdatedVersionAvailableUserAlert.title=Uusi vakaa versio Freenetist? on 
julkaista, sinun kannattaisi p?ivitt?? mahdollisimman nopeasti
 UpdatedVersionAvailableUserAlert.updateASAPButton=P?ivit? mahdollisimman 
nopeasti
 UpdatedVersionAvailableUserAlert.updateASAPQuestion=Haluaisitko solmun 
k?ynnist?v?n itsens? uudelleen heti kun se on ladannut uusimman version?
@@ -414,4 +573,19 @@
 UserAlert.apply=Hyv?ksy
 UserAlert.hide=Piilota
 UserAlert.reset=Nollaa
+UserAlertManager.alertsTitle=Ohittamattomat huomautukset
+UserAlertManager.clickForMore=Klikkaa kohdetta p??st??ksesi siit? eroon.
+UserAlertsToadlet.titleWithName=Tilah?lytykset ${name}:lle
+WelcomeToadlet.activityTitle=Freenetin t?m?nhetkinen aktiivisuus
+WelcomeToadlet.alertsSummary=H?lytysten yhteenveto
+WelcomeToadlet.extVersion=Freenet-ext (Build #${build} r${rev})
+WelcomeToadlet.fetchKeyLabel=Nouda avain
+WelcomeToadlet.homepageFullTitleWithName=${name}:n Freenetin 
webbik?ytt?liittym?n kotisivu
+WelcomeToadlet.insertedTitle=L?hetys
+WelcomeToadlet.publicKeyHeader=Julkinen avain
+WelcomeToadlet.restartNode=Uudelleenk?ynnist? solmu
+WelcomeToadlet.shutdownNode=Sammuta solmu
+WelcomeToadlet.update=P?ivit?
+WelcomeToadlet.version=Freenet-${fullVersion} (Build #${build} r${rev})
+WelcomeToadlet.versionHeader=Versiotieto ja solmun hallintaty?kalut
 End

Modified: branches/db4o/freenet/src/freenet/l10n/freenet.l10n.it.properties
===================================================================
--- branches/db4o/freenet/src/freenet/l10n/freenet.l10n.it.properties   
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/l10n/freenet.l10n.it.properties   
2008-09-24 23:54:07 UTC (rev 22829)
@@ -1,13 +1,13 @@
-Announcer.announceAlertIntro=Il nodo sta cercando di connettersi con i 
seednode ed annunciare s? stesso all' OpenNet (network di Sconosciuti). Possono 
essere necessari alcuni minuti per completare l'operazione.
-Announcer.announceAlertNoSeednodes=Non e' stato trovato il file seednodes.fref 
e quindi il nodo non pu? connettersi automaticamente ad Opennet. Aggiungere 
alcuni nodi manualmente o scaricare il file seednodes da 
http://downloads.freenetproject.org/alpha/opennet/ .
-Announcer.announceAlertShort=Il nodo sta cercando di connettersi alla rete, 
nel frattempo sar? pi? lento.
+Announcer.announceAlertIntro=Il nodo sta cercando di connettersi con i 
seednode ed annunciare s? stesso all' OpenNet (network di Sconosciuti). Possono 
essere necessari alcuni minuti per completare l'operazione.
+Announcer.announceAlertNoSeednodes=Non e' stato trovato il file seednodes.fref 
e quindi il nodo non pu? connettersi automaticamente ad Opennet. Aggiungere 
alcuni nodi manualmente o scaricare il file seednodes da 
http://downloads.freenetproject.org/alpha/opennet/ .
+Announcer.announceAlertShort=Il nodo sta cercando di connettersi alla rete, 
nel frattempo sar? pi? lento.
 Announcer.announceAlertTitle=Annuncio Nodo in corso
-Announcer.announceDetails=Il nodo ha recentemente inoltrato 
${recentSentAnnouncements} annunci, ${runningAnnouncements} dei quali ancora in 
corso, ed aggiunto ${addedNodes} nodi (${refusedNodes} nodi hanno rifiutato la 
connessione). In questo momento il nodo ? connesso a ${connectedSeednodes} 
seednode e sta cercando di connettersi ad altri ${disconnectedSeednodes}.
-Announcer.announceDisabledTooOld=Il software utilizzato dal nodo ? obsoleto ed 
inadatto alla connessione con la version corrente della rete Freenet. 
L'annuncio ? stato diabilitato in quanto comunque inutile. Si prega di 
aggiornare il nodo appena possibile (auto-aggiornamento potrebbe essere in 
attesa di input o disabilitato)
-Announcer.announceDisabledTooOldShort=Il nodo non riesce a connettersi alla 
rete perch? la versione di Freenet utilizzata ? obsoleta. Si prega di eseguire 
l'aggiornamento.
+Announcer.announceDetails=Il nodo ha recentemente inoltrato 
${recentSentAnnouncements} annunci, ${runningAnnouncements} dei quali ancora in 
corso, ed aggiunto ${addedNodes} nodi (${refusedNodes} nodi hanno rifiutato la 
connessione). In questo momento il nodo ? connesso a ${connectedSeednodes} 
seednode e sta cercando di connettersi ad altri ${disconnectedSeednodes}.
+Announcer.announceDisabledTooOld=Il software utilizzato dal nodo ? obsoleto ed 
inadatto alla connessione con la version corrente della rete Freenet. 
L'annuncio ? stato diabilitato in quanto comunque inutile. Si prega di 
aggiornare il nodo appena possibile (auto-aggiornamento potrebbe essere in 
attesa di input o disabilitato)
+Announcer.announceDisabledTooOldShort=Il nodo non riesce a connettersi alla 
rete perch? la versione di Freenet utilizzata ? obsoleta. Si prega di eseguire 
l'aggiornamento.
 Announcer.announceDisabledTooOldTitle=Annuncio disabilitato (obsoleto)
 Announcer.announceLoading=Il nodo sta caricando il file seednodes per 
annunciarsi al resto della rete. Il completamento dell' operazione potrebbe 
richiedere diversi minuti.
-Announcer.coolingOff=per i prossimi ${time} secondi, il nodo aspetter? che i 
nodi che ha annunciato si connettano; se non ci saranno abbastanza nodi prover? 
con un altro nodo.
+Announcer.coolingOff=per i prossimi ${time} secondi, il nodo aspetter? che i 
nodi che ha annunciato si connettano; se non ci saranno abbastanza nodi prover? 
con un altro nodo.
 Bookmark.noName=nessun nome
 BookmarkEditorToadlet.addBookmark=Aggiungi Segnalibro
 BookmarkEditorToadlet.addCategory=Aggiungi Categoria
@@ -36,11 +36,11 @@
 BookmarkEditorToadlet.editCategoryTitle=Modifica Categoria
 BookmarkEditorToadlet.error=Errore
 BookmarkEditorToadlet.hasAnActivelinkLabel=Il freesite ha un activelink?
-BookmarkEditorToadlet.invalidKey=La chiave Freenet non ? valida.
+BookmarkEditorToadlet.invalidKey=La chiave Freenet non ? valida.
 BookmarkEditorToadlet.invalidKeyTitle=Chiave non valida
 BookmarkEditorToadlet.invalidKeyWithReason=Chiave Freenet non valida.
 BookmarkEditorToadlet.keyLabel=Chiave :
-BookmarkEditorToadlet.moveDown=Gi?
+BookmarkEditorToadlet.moveDown=Gi?
 BookmarkEditorToadlet.moveUp=Su
 BookmarkEditorToadlet.myBookmarksTitle=I Miei Segnalibri
 BookmarkEditorToadlet.nameLabel=Nome :
@@ -50,18 +50,18 @@
 BookmarkEditorToadlet.save=Salva
 BookmarkEditorToadlet.title=Modifica Preferiti
 BookmarkEditorToadlet.urlDecodeError=Errore nella decodifica della URL
-BookmarkItem.bookmarkUpdated=Il sito ${name} ? stato aggiornato all'edizione 
${edition}.
+BookmarkItem.bookmarkUpdated=Il sito ${name} ? stato aggiornato all'edizione 
${edition}.
 BookmarkItem.bookmarkUpdatedShort=Freesite aggiornato: ${name}
 BookmarkItem.bookmarkUpdatedTitle=${name}: link aggiornato
-BookmarkItem.bookmarkUpdatedWithLink=Il Sito ${link}${name}${/link} ? stato 
aggiornato all'edizione ${edition}.
+BookmarkItem.bookmarkUpdatedWithLink=Il Sito ${link}${name}${/link} ? stato 
aggiornato all'edizione ${edition}.
 BookmarkItem.deleteBookmarkUpdateNotification=Elimina notifica
 BookmarkItem.unnamedBookmark=Segnalibro Senza Nome
 BookmarkManager.list=Segnalibri
 BookmarkManager.listLong=Lista dei freesite preferiti
 BookmarkManager.malformedBookmark=Segnalibro malformato
 BooleanOption.parseError=Booleano non riconosciuto: ${val} - prova "vero o 
falso"
-BuildOldAgeUserAlert.tooOld=Il software di questo nodo ? antecedente alla pi? 
vecchia versione (Build #${lastgood}) utilizzabile dai peer aggiornati ai quali 
si cerca di connettersi.  E' necessario aggiornare il nodo al pi? presto 
possibile; non sar? possibile connettersi ai peer etichettati "TROPPO RECENTE" 
finch? il nodo non sar? stato aggiornato (il nodo va tenuto aggiornato o si 
rischia di essere esclusi dalla rete Freenet)
-BuildOldAgeUserAlert.tooOldShort=Il nodo sta utilizzando una versione  di 
Freenet obsoleta al punto da rendere impossibile il collegamento alla rete. Si 
prega di eseguire l'aggiornamento al pi? presto possibile.
+BuildOldAgeUserAlert.tooOld=Il software di questo nodo ? antecedente alla pi? 
vecchia versione (Build #${lastgood}) utilizzabile dai peer aggiornati ai quali 
si cerca di connettersi.  E' necessario aggiornare il nodo al pi? presto 
possibile; non sar? possibile connettersi ai peer etichettati "TROPPO RECENTE" 
finch? il nodo non sar? stato aggiornato (il nodo va tenuto aggiornato o si 
rischia di essere esclusi dalla rete Freenet)
+BuildOldAgeUserAlert.tooOldShort=Il nodo sta utilizzando una versione  di 
Freenet obsoleta al punto da rendere impossibile il collegamento alla rete. Si 
prega di eseguire l'aggiornamento al pi? presto possibile.
 BuildOldAgeUserAlert.tooOldTitle=Versione obsoleta
 CSSTokenizerFilter.deletedDisallowedString=Stringa non permessa eliminata
 CSSTokenizerFilter.deletedUnmatchedChar=Ignorato char non corrispondente:
@@ -70,9 +70,9 @@
 CSSTokenizerFilter.invalidURLContents=Contenuto della url() non valido
 CSSTokenizerFilter.supplementalCharsNotSupported=CARATTERI UCS-4 OLTRE 0xFFFF 
NON SUPPORTATI!
 CSSTokenizerFilter.unknownAtIdentifierLabel=@identifier sconosciuto:
-ClockProblemDetectedUserAlert.shortText=Freenet non pu? connettersi perch? 
l'orologio del computer non ? sincronizzato.
-ClockProblemDetectedUserAlert.text=Freenet ha rilevato che l'orologio di 
sistema (ora e data) non ? regolato correttamente. Il nodo non potr? funzionare 
correttamente finch? non sar? stato riavviato dopo aver regolato l'orologio.
-ClockProblemDetectedUserAlert.title=L'orologio del computer non ? regolato 
correttamente.
+ClockProblemDetectedUserAlert.shortText=Freenet non pu? connettersi perch? 
l'orologio del computer non ? sincronizzato.
+ClockProblemDetectedUserAlert.text=Freenet ha rilevato che l'orologio di 
sistema (ora e data) non ? regolato correttamente. Il nodo non potr? funzionare 
correttamente finch? non sar? stato riavviato dopo aver regolato l'orologio.
+ClockProblemDetectedUserAlert.title=L'orologio del computer non ? regolato 
correttamente.
 ConfigToadlet.appliedFailureExceptions=Le modifiche alla configurazione sono 
state applicate con le seguenti eccezioni:
 ConfigToadlet.appliedFailureTitle=Configurazione Non Applicata!
 ConfigToadlet.appliedSuccess=Le modifiche alla configurazione sono state 
applicate.
@@ -81,22 +81,18 @@
 ConfigToadlet.configNavTitle=Esplora Configurazione
 ConfigToadlet.console=console
 ConfigToadlet.contributeTranslation=Contribuisci alla traduzione
-ConfigToadlet.defaultIs=Il valore predefinito per l'opzione di configurazione 
?: '${default}'.
+ConfigToadlet.defaultIs=Il valore predefinito per l'opzione di configurazione 
?: '${default}'.
 ConfigToadlet.false=falso
 ConfigToadlet.fcp=fcp
 ConfigToadlet.fproxy=fproxy
 ConfigToadlet.fullTitle=Configurazione del nodo Freenet: ${name}
 ConfigToadlet.homepage=Homepage del Nodo
 ConfigToadlet.logger=log
-ConfigToadlet.needRestart=Per attivare dei cambiamenti nella configurazione e' 
necessario il riavvio. Si prega di riavviare il nodo.
-ConfigToadlet.needRestartShort=Per attivare dei cambiamenti nella 
configurazione e' necessario il riavvio. Si prega di riavviare il nodo.
-ConfigToadlet.needRestartTitle=Necessario riavvio del nodo
 ConfigToadlet.node=nodo
 ConfigToadlet.pluginmanager=pluginmanager
 ConfigToadlet.pluginmanager2=pluginmanager2
 ConfigToadlet.possibilitiesTitle=Scegli Azione:
 ConfigToadlet.reset=Annulla
-ConfigToadlet.restartNode=Riavvia Adesso
 ConfigToadlet.returnToNodeConfig=Torna alla configurazione del nodo
 ConfigToadlet.returnToNodeHomepage=Torna alla homepage del nodo
 ConfigToadlet.shortTitle=Configurazione
@@ -112,8 +108,8 @@
 ConfigToadlet.node.scheduler=nodo.schedulatore
 ConfigToadlet.node.testnet=nodo.testnet
 ConfigToadlet.node.updater=nodo.aggiornamento
-ConfigurablePersister.doesNotExistCannotCreate=Il file non esiste e non pu? 
essere creato
-ConfigurablePersister.existsCannotReadWrite=Il file esiste ma non pu? essere 
letto/scritto
+ConfigurablePersister.doesNotExistCannotCreate=Il file non esiste e non pu? 
essere creato
+ConfigurablePersister.existsCannotReadWrite=Il file esiste ma non pu? essere 
letto/scritto
 ConnectionsToadlet.nodeStatus.BACKED OFF=RESPINTO
 ConnectionsToadlet.nodeStatus.BURSTING=BURST
 ConnectionsToadlet.nodeStatus.BUSY=OCCUPATO
@@ -133,8 +129,8 @@
 ConnectivityToadlet.addressTitle=Indirizzo
 ConnectivityToadlet.byIPTitle=Pachetti per ${ip} per indirizzo IP - ${status} 
(lunghezza minima tunnel ${tunnelLength})
 ConnectivityToadlet.byPortTitle=Pacchetti per ${port} per porta - ${status} 
(lunghezza minima tunnel ${tunnelLength})
-ConnectivityToadlet.connectivity=Connettivit? Internet
-ConnectivityToadlet.connectivityTitle=Connettivit?
+ConnectivityToadlet.connectivity=Connettivit? Internet
+ConnectivityToadlet.connectivityTitle=Connettivit?
 ConnectivityToadlet.firstReceiveLeadTime=Da online a prima ricezione
 ConnectivityToadlet.firstSendLeadTime=Da start a prima trasmissione
 ConnectivityToadlet.local=LOCALE
@@ -142,9 +138,9 @@
 ConnectivityToadlet.noreply=NESSUNA RISPOSTA
 ConnectivityToadlet.remote=REMOTO
 ConnectivityToadlet.sentReceivedTitle=Pacchetti ricevuti/trasmessi
-ConnectivityToadlet.summaryTitle=Connettivit?
-ConnectivityToadlet.title=Connettivit? internet di ${nodeName}
-ContentDataFilter.unknownCharset=La pagina che sta per essere visualizzata 
utilizza un formato di caratteri (charset) di tipo sconosciuto. Ci? rende 
impossibile filtrare la pagina, il che potrebbe a sua volta compromettere 
l'anonimato dell'utente.
+ConnectivityToadlet.summaryTitle=Connettivit?
+ConnectivityToadlet.title=Connettivit? internet di ${nodeName}
+ContentDataFilter.unknownCharset=La pagina che sta per essere visualizzata 
utilizza un formato di caratteri (charset) di tipo sconosciuto. Ci? rende 
impossibile filtrare la pagina, il che potrebbe a sua volta compromettere 
l'anonimato dell'utente.
 ContentDataFilter.unknownCharsetTitle=Charset sconosciuto!
 ContentDataFilter.warningUnknownCharsetTitle=Attenzione: charset sconosciuto 
(${charset})
 ContentFilter.applicationPdfReadAdvice=Documento Adobe(R) PDF - MOLTO 
PERICOLOSO!
@@ -154,90 +150,90 @@
 ContentFilter.imageIcoReadAdvice=File icona: probabilmente non pericoloso
 ContentFilter.imageIcoWriteAdvice=File icona - probabilmente non pericoloso 
(ma potrebbe contenere altri dati)
 ContentFilter.imageJpegReadAdvice=Immagine JPEG - probabilmente non pericoloso
-ContentFilter.imageJpegWriteAdvice=Immagine JPEG - probabilmente non 
pericoloso ma pu? contenere dati EXIF
+ContentFilter.imageJpegWriteAdvice=Immagine JPEG - probabilmente non 
pericoloso ma pu? contenere dati EXIF
 ContentFilter.imagePngReadAdvice=Immagine PNG - probabilmente non pericoloso
 ContentFilter.imagePngWriteAdvice=Immagine PNG -  probabilmente non pericoloso 
ma sarebbe opportuno eliminare eventuali commenti e porzioni di testo
-ContentFilter.textCssReadAdvice=CSS (cascading style sheet, di solito ? usato 
in combinazione con HTML) - probabilmente non pericoloso se filtrato, ma il 
filtro non ? del tipo "whitelist" quindi fare attenzione
-ContentFilter.textCssWriteAdvice=CSS (cascading style sheet, solitamente usato 
con HTML) - pu? contenere metadati, controllare manualmente
+ContentFilter.textCssReadAdvice=CSS (cascading style sheet, di solito ? usato 
in combinazione con HTML) - probabilmente non pericoloso se filtrato, ma il 
filtro non ? del tipo "whitelist" quindi fare attenzione
+ContentFilter.textCssWriteAdvice=CSS (cascading style sheet, solitamente usato 
con HTML) - pu? contenere metadati, controllare manualmente
 ContentFilter.textHtmlReadAdvice=HTML - Non pericoloso se filtrato
-ContentFilter.textHtmlWriteAdvice=HTML - pu? contenere metadati di tipo 
pericoloso, ecc; si consiglia di controllare manualmente
-ContentFilter.textPlainReadAdvice=Formato testo semplice (plain text)- non ? 
pericoloso a meno che il browser utilizzato non sia particolarmente "stupido" 
(per esempio Internet Explorer)
+ContentFilter.textHtmlWriteAdvice=HTML - pu? contenere metadati di tipo 
pericoloso, ecc; si consiglia di controllare manualmente
+ContentFilter.textPlainReadAdvice=Formato testo semplice (plain text)- non ? 
pericoloso a meno che il browser utilizzato non sia particolarmente "stupido" 
(per esempio Internet Explorer)
 ContentFilter.textPlainWriteAdvice=Testo semplice (plain text) - non 
pericoloso a meno che l'utente vi includa informazioni compromettenti
 DarknetConnectionsToadlet.activityInserts=Inserzioni: ${totalSenders} totale 
senders, ${CHKhandlers} CHK handlers, ${SSKhandlers} SSK handlers
 DarknetConnectionsToadlet.activityRequests=Richieste: ${totalSenders} totale 
senders, ${CHKhandlers} CHK handlers, ${SSKhandlers} SSK handlers
-DarknetConnectionsToadlet.activityTitle=Attivit? Corrente
+DarknetConnectionsToadlet.activityTitle=Attivit? Corrente
 DarknetConnectionsToadlet.add=Aggiungi
 DarknetConnectionsToadlet.addPeerTitle=Aggiungi un peer
-DarknetConnectionsToadlet.alreadyInReferences=La referenza data ? gi? presente 
in lista.
-DarknetConnectionsToadlet.backedOff=Connesso ma respinto: Il nodo ? connesso a 
questi peer ma la la connessione viene rifiutata e quindi i peer in questione 
non vengono al momento utilizzati per l'instradamento delle richieste
+DarknetConnectionsToadlet.alreadyInReferences=La referenza data ? gi? presente 
in lista.
+DarknetConnectionsToadlet.backedOff=Connesso ma respinto: Il nodo ? connesso a 
questi peer ma la la connessione viene rifiutata e quindi i peer in questione 
non vengono al momento utilizzati per l'instradamento delle richieste
 DarknetConnectionsToadlet.backedOffShort=Respinti
-DarknetConnectionsToadlet.bursting=Non connesso e bursting: per un breve 
periodo, il nodo sta tentando di connettersi a questi peer perch? l'utenete ha 
impostato burstOnly su di essi
+DarknetConnectionsToadlet.bursting=Non connesso e bursting: per un breve 
periodo, il nodo sta tentando di connettersi a questi peer perch? l'utenete ha 
impostato burstOnly su di essi
 DarknetConnectionsToadlet.burstingShort=Bursting
-DarknetConnectionsToadlet.busy=Occupati: Questi peer sono connessi ma ci 
comunicano di essere troppo occupati per poter aggiungere le nostre richieste a 
quelle gi? presenti quindi non vengono temporaneamente utilizzati per 
l'instradamento.
+DarknetConnectionsToadlet.busy=Occupati: Questi peer sono connessi ma ci 
comunicano di essere troppo occupati per poter aggiungere le nostre richieste a 
quelle gi? presenti quindi non vengono temporaneamente utilizzati per 
l'instradamento.
 DarknetConnectionsToadlet.busyShort=Occupati
 DarknetConnectionsToadlet.cancel=Cancella
-DarknetConnectionsToadlet.cantFetchNoderefURL=Non ? stato possibile richiamare 
la referenza di un nodo da ${url}. Riprovare.
-DarknetConnectionsToadlet.cantParseTryAgain=Non ? stato possibile interpretare 
it testo dato come refernza di un nodo: (${error}).
-DarknetConnectionsToadlet.cantParseWrongEnding=Non ? stato possibile 
interpretare le referenza: L'ultimo rigo dovrebbe contenere solo la parola End, 
esso contiene invece: ${end}
-DarknetConnectionsToadlet.clockProblem=L'orologio di sitema e l'orologio del 
nodo differiscono di oltre 24 ore.  Ci? potrebbe causare problemi con 
l'aggiornamento e con i client. La connessione ? stata pertanto disabilitata,
+DarknetConnectionsToadlet.cantFetchNoderefURL=Non ? stato possibile richiamare 
la referenza di un nodo da ${url}. Riprovare.
+DarknetConnectionsToadlet.cantParseTryAgain=Non ? stato possibile interpretare 
it testo dato come refernza di un nodo: (${error}).
+DarknetConnectionsToadlet.cantParseWrongEnding=Non ? stato possibile 
interpretare le referenza: L'ultimo rigo dovrebbe contenere solo la parola End, 
esso contiene invece: ${end}
+DarknetConnectionsToadlet.clockProblem=L'orologio di sitema e l'orologio del 
nodo differiscono di oltre 24 ore.  Ci? potrebbe causare problemi con 
l'aggiornamento e con i client. La connessione ? stata pertanto disabilitata,
 DarknetConnectionsToadlet.clockProblemShort=Problema di sincronizzazione 
orologio
-DarknetConnectionsToadlet.confirmRemoveNode=Conferma rimozione di "${name}" ? 
Rimuovere un nodo che ? stato disconnesso per meno di una settimana non ? 
consigliabile. L'azione pi? appropriata sarebbe di attendere ancora un po', 
considerando che potrebbe trattarsi di un problema temporaneo, e che ci sono 
utenti che non hanno la possibilit? lasciar girare il proprio nodo giorno e 
notte.
+DarknetConnectionsToadlet.confirmRemoveNode=Conferma rimozione di "${name}" ? 
Rimuovere un nodo che ? stato disconnesso per meno di una settimana non ? 
consigliabile. L'azione pi? appropriata sarebbe di attendere ancora un po', 
considerando che potrebbe trattarsi di un problema temporaneo, e che ci sono 
utenti che non hanno la possibilit? lasciar girare il proprio nodo giorno e 
notte.
 DarknetConnectionsToadlet.confirmRemoveNodeTitle=Conferma
 DarknetConnectionsToadlet.confirmRemoveNodeWarningTitle=Rimozione Nodo
 DarknetConnectionsToadlet.connError=Connessione fallita (il nodo ha un 'bug'?)
 DarknetConnectionsToadlet.connErrorShort=Errore di Connessione
-DarknetConnectionsToadlet.connected=Connesso: Il nodo ? connesso a questi peer:
+DarknetConnectionsToadlet.connected=Connesso: Il nodo ? connesso a questi peer:
 DarknetConnectionsToadlet.connectedShort=Connessi
 DarknetConnectionsToadlet.darknetFnpPort=Darknet FNP: ${port}/UDP (usata per 
connessioni a peer affidabili. Forwardare se possibile)
 DarknetConnectionsToadlet.disabled=Non connesso e disabilitato: L'utente ha 
configurato il nodo in maniera da non connettersi a questo peer.
 DarknetConnectionsToadlet.disabledShort=Disabilitato
-DarknetConnectionsToadlet.disconnecting=Disconnessione in corso (si sta 
procedendo alla rimozione del nodo; ? necessario informare il nodo in questione 
e ci? potrebbe richiedere un po' di tempo)
+DarknetConnectionsToadlet.disconnecting=Disconnessione in corso (si sta 
procedendo alla rimozione del nodo; ? necessario informare il nodo in questione 
e ci? potrebbe richiedere un po' di tempo)
 DarknetConnectionsToadlet.disconnectingShort=Disconnessione in corso
 DarknetConnectionsToadlet.enterDescription=Inserisci descrizione:
 DarknetConnectionsToadlet.failedToAddNodeInternalError=Impossibile 
interpretare il testo dato comereferenza di un nodo Freenet. Si prega di 
riportare agli sviluppatori quanto segue:
 DarknetConnectionsToadlet.failedToAddNodeInternalErrorTitle=Aggiunta nuovo 
nodo fallita: Errore interno.
 DarknetConnectionsToadlet.failedToAddNodeTitle=Aggiunta Nodo Fallita
-DarknetConnectionsToadlet.fcpDisabled=FCP non ? abilitato (per applicazioni 
client di Freenet come Frost e Thaw)
+DarknetConnectionsToadlet.fcpDisabled=FCP non ? abilitato (per applicazioni 
client di Freenet come Frost e Thaw)
 DarknetConnectionsToadlet.fcpPort=FCP: ${port}/tcp (per le applicazioni client 
di Freenet, per esempio Frost e Thaw)
 DarknetConnectionsToadlet.fileReference=Seleziona il file contenente la 
referenza:
-DarknetConnectionsToadlet.fnpPort=FNP: ${port}/udp (Comunicazione tra nodi. Di 
solito questa ? l'unica porta che si potrebbe aver bisogno di forwardare)
+DarknetConnectionsToadlet.fnpPort=FNP: ${port}/udp (Comunicazione tra nodi. Di 
solito questa ? l'unica porta che si potrebbe aver bisogno di forwardare)
 DarknetConnectionsToadlet.forceRemove=Rimozione Forzata
-DarknetConnectionsToadlet.fproxyDisabled=FProxy non ? abilitato (questa 
interfaccia web)
+DarknetConnectionsToadlet.fproxyDisabled=FProxy non ? abilitato (questa 
interfaccia web)
 DarknetConnectionsToadlet.fproxyPort=FProxy: ${port}/tcp (questa interfaccia 
web)
 DarknetConnectionsToadlet.fullTitle=${counts} Amici (peer affidabili) di 
${name}
 DarknetConnectionsToadlet.go=Vai
-DarknetConnectionsToadlet.idleTime=Tempo trascorso da quando il nodo ? 
connesso o da quando lo ? stato per l'ultima volta
+DarknetConnectionsToadlet.idleTime=Tempo trascorso da quando il nodo ? 
connesso o da quando lo ? stato per l'ultima volta
 DarknetConnectionsToadlet.idleTimeTitle=Connesso / Inattivo
-DarknetConnectionsToadlet.invalidSignature=Non ? stato possibile verificare le 
firma elettronica della refernza (${error}).
+DarknetConnectionsToadlet.invalidSignature=Non ? stato possibile verificare le 
firma elettronica della refernza (${error}).
 DarknetConnectionsToadlet.ipAddress=Indirizzo del nodo in formato IP:porta
 DarknetConnectionsToadlet.ipAddressTitle=Indirizzo
-DarknetConnectionsToadlet.listenOnly=Non connesso e solo ascolto: il nodo non 
cercher? di connettersi a questo peer perch? l'utente l'ha impostato su solo 
ascolto (listenOnly)
+DarknetConnectionsToadlet.listenOnly=Non connesso e solo ascolto: il nodo non 
cercher? di connettersi a questo peer perch? l'utente l'ha impostato su solo 
ascolto (listenOnly)
 DarknetConnectionsToadlet.listenOnlyShort=Solo ascolto
-DarknetConnectionsToadlet.listening=Non connesso ma in ascolto: il nodo non 
cercher? spesso di connettersi con questo peer perch? l'utente l'ha impostato 
su burstOnly
+DarknetConnectionsToadlet.listening=Non connesso ma in ascolto: il nodo non 
cercher? spesso di connettersi con questo peer perch? l'utente l'ha impostato 
su burstOnly
 DarknetConnectionsToadlet.listeningShort=Ascolto
 DarknetConnectionsToadlet.myFriends=I Miei Amici (peer affidabili aggiunti da 
me)
 DarknetConnectionsToadlet.myReferenceHeader=${linkref}Referenza del 
Nodo${/linkref} (${linktext}testo${/linktext})
 DarknetConnectionsToadlet.nameClickToMessage=Nome del nodo. Clicca sul nome 
per mandare un messaggio a questo peer:
 DarknetConnectionsToadlet.nameTitle=Nome
-DarknetConnectionsToadlet.neverConnected=Mai Connesso. Questo peer non ? mai 
stato connesso al nostro nodo.
+DarknetConnectionsToadlet.neverConnected=Mai Connesso. Questo peer non ? mai 
stato connesso al nostro nodo.
 DarknetConnectionsToadlet.neverConnectedShort=Mai connesso
-DarknetConnectionsToadlet.noPeersFirstHalf=Freenet non pu? funzionare perch? 
non sono stati ancora aggiunti dei peer ai quali connettersi.
+DarknetConnectionsToadlet.noPeersFirstHalf=Freenet non pu? funzionare perch? 
non sono stati ancora aggiunti dei peer ai quali connettersi.
 DarknetConnectionsToadlet.noPeersSecondHalf=Leggi l'infobox in alto per vedere 
come si fa.
-DarknetConnectionsToadlet.noPeersWithHomepageLink=Freenet non pu? funzionare 
perch? non sono ancora stati aggiunti dei peer ai quali collegarsi. Alla pagina 
${link}node homepage${/link}, in alto, si pu? leggere come fare.
-DarknetConnectionsToadlet.noRefOrURL=Non ? stato possibile rilevare una 
referenza nodo o una URL. Si prega di riprovare.
+DarknetConnectionsToadlet.noPeersWithHomepageLink=Freenet non pu? funzionare 
perch? non sono ancora stati aggiunti dei peer ai quali collegarsi. Alla pagina 
${link}node homepage${/link}, in alto, si pu? leggere come fare.
+DarknetConnectionsToadlet.noRefOrURL=Non ? stato possibile rilevare una 
referenza nodo o una URL. Si prega di riprovare.
 DarknetConnectionsToadlet.noRequests=Al momento, il nodo non sta elaborando 
alcuna richiesta.
 DarknetConnectionsToadlet.nodeHomepage=homepage del nodo
 DarknetConnectionsToadlet.nodePortsTitle=Porte utilizzate dal Nodo
 DarknetConnectionsToadlet.notConnected=Non connesso: Finora non ci sono state 
connessioni ma il nodo cerca continuamente di connettersi
 DarknetConnectionsToadlet.notConnectedShort=Disconnessi
-DarknetConnectionsToadlet.opennetFnpPort=Opennet FNP: ${port}/UDP (usata per 
connessioni a peer non affidabili, cio? Sconosciuti. Forwardare se possibile)
-DarknetConnectionsToadlet.pasteReference=Incolla la referenza qui (il nodo 
elliminer? automaticamente le parti aggiunte da chat clients, p.es. <toad_>) :
+DarknetConnectionsToadlet.opennetFnpPort=Opennet FNP: ${port}/UDP (usata per 
connessioni a peer non affidabili, cio? Sconosciuti. Forwardare se possibile)
+DarknetConnectionsToadlet.pasteReference=Incolla la referenza qui (il nodo 
elliminer? automaticamente le parti aggiunte da chat clients, p.es. <toad_>) :
 DarknetConnectionsToadlet.privateNote=Un commento privato relativo a questo 
nodo:
 DarknetConnectionsToadlet.privateNoteTitle=Nota Privata
-DarknetConnectionsToadlet.referenceCopyWarning=La referenza del nodo va 
copiata ${bold}SENZA VARIAZIONI${/bold}. Qualsiasi modificazione la render? 
${bold}inutilizzabile${/bold}..
+DarknetConnectionsToadlet.referenceCopyWarning=La referenza del nodo va 
copiata ${bold}SENZA VARIAZIONI${/bold}. Qualsiasi modificazione la render? 
${bold}inutilizzabile${/bold}..
 DarknetConnectionsToadlet.remove=Elimina
 DarknetConnectionsToadlet.removePeers=Elimina peer selezionati
-DarknetConnectionsToadlet.routingDisabled=Non sta instradando traffico: (la 
connessione tra nodo locale e remoto ? attiva ma uno dei due rifiuta di 
instradare traffico)
+DarknetConnectionsToadlet.routingDisabled=Non sta instradando traffico: (la 
connessione tra nodo locale e remoto ? attiva ma uno dei due rifiuta di 
instradare traffico)
 DarknetConnectionsToadlet.routingDisabledShort=Non instrada traffico
 DarknetConnectionsToadlet.seedClients=Nodi per i quali il nodo locale sta 
facendo da seednode.
 DarknetConnectionsToadlet.seedClientsShort=Seeding per
@@ -248,38 +244,38 @@
 DarknetConnectionsToadlet.sendMessageToPeers=Manda messaggio ai peer 
selezionati
 DarknetConnectionsToadlet.separator=-- -- --
 DarknetConnectionsToadlet.statusTitle=Status
-DarknetConnectionsToadlet.tmciDisabled=TMCI non ? abilitato (semplice 
interfaccia a comandi testuali simile a telnet)
+DarknetConnectionsToadlet.tmciDisabled=TMCI non ? abilitato (semplice 
interfaccia a comandi testuali simile a telnet)
 DarknetConnectionsToadlet.tmciPort=TMCI: ${port}/tcp (semplice interfaccia a 
comandi testuali simile a telnet)
 DarknetConnectionsToadlet.tooNew=Connesso ma troppo recente: La versione 
obbligatoria minima di questo peer e' maggiore della versione che stiamo 
utilizzando.
 DarknetConnectionsToadlet.tooNewShort=Troppo recente
-DarknetConnectionsToadlet.tooOld=Connesso ma obsoleto: Questo peer sta usando 
una versione obsoleta di Freenet. Esso non sar? utilizzato per l'instradamento 
delle richieste.
+DarknetConnectionsToadlet.tooOld=Connesso ma obsoleto: Questo peer sta usando 
una versione obsoleta di Freenet. Esso non sar? utilizzato per l'instradamento 
delle richieste.
 DarknetConnectionsToadlet.tooOldShort=Obsoleti
 DarknetConnectionsToadlet.transferringRequests=Richieste trasferimento: invio 
${senders}, ricezione ${receivers}
-DarknetConnectionsToadlet.triedToAddSelf=Non ? possibile aggiungere il proprio 
stesso nodo ad una lista di peer remoti.
-DarknetConnectionsToadlet.unauthorized=L'accesso a questa pagina ? interedetto.
+DarknetConnectionsToadlet.triedToAddSelf=Non ? possibile aggiungere il proprio 
stesso nodo ad una lista di peer remoti.
+DarknetConnectionsToadlet.unauthorized=L'accesso a questa pagina ? interedetto.
 DarknetConnectionsToadlet.unknownAddress=(indirizzo sconosciuto)
 DarknetConnectionsToadlet.updateChangedPrivnotes=Aggiorna commenti
 DarknetConnectionsToadlet.urlReference=Inserire qui la URL della referenza:
 DarknetConnectionsToadlet.versionTitle=Versione
 ExtOldAgeUserAlert.extTooOld=Il file freenet-ext.jar sembra essere corrotto od 
obsoleto: Per l'aggiornamento usare 
http://downloads.freenetproject.org/alpha/freenet-ext.jar
-ExtOldAgeUserAlert.extTooOldShort=Il file freenet-ext.jar ? obsoleto. Si prega 
di aggiornarlo.
+ExtOldAgeUserAlert.extTooOldShort=Il file freenet-ext.jar ? obsoleto. Si prega 
di aggiornarlo.
 ExtOldAgeUserAlert.extTooOldTitle=Freenet-ext obsoleto
 FProxyToadlet.abortToHomepage=Interrompi e ritorna alla homepage di FProxy
 FProxyToadlet.alerts=Messaggi dettagliati sullo stato del nodo
 FProxyToadlet.alertsTitle=Avvertenze
 FProxyToadlet.backToFProxy=${link}Clicca qui${/link} per andare alla homepage 
di FProxy
 FProxyToadlet.backToReferrer=${link}Clicca qui${/link} per tornare alla pagina 
referente.
-FProxyToadlet.cantBindPort=Non ? possibile abbinare FProxy a quella porta!
+FProxyToadlet.cantBindPort=Non ? possibile abbinare FProxy a quella porta!
 FProxyToadlet.config=configura il nodo
 FProxyToadlet.configTitle=Configurazione
 FProxyToadlet.dangerousContentTitle=Contenuto Potenzialmente Pericoloso
-FProxyToadlet.dangerousRSS=Il file richiesto potrebbe essere RSS. Questo tipo 
di file non pu? essere filtrato  da Freenet nel modo giusto, ed inoltre 
potrebbe contenere dei difetti (web-bugs) come immagini in-line ecc, che 
potrebbero esporre l'indirizzo IP del computer in uso ad eventuali 
siti-trappola e pertanto mettere a serio rischio l'anonimato dell'utente. 
Firefox 2.0 e Internet Explorer 7.0 aprono il file come RSS anche se la 
tipologia del contentuto (content type) ? "${type}".
+FProxyToadlet.dangerousRSS=Il file richiesto potrebbe essere RSS. Questo tipo 
di file non pu? essere filtrato  da Freenet nel modo giusto, ed inoltre 
potrebbe contenere dei difetti (web-bugs) come immagini in-line ecc, che 
potrebbero esporre l'indirizzo IP del computer in uso ad eventuali 
siti-trappola e pertanto mettere a serio rischio l'anonimato dell'utente. 
Firefox 2.0 e Internet Explorer 7.0 aprono il file come RSS anche se la 
tipologia del contentuto (content type) ? "${type}".
 FProxyToadlet.dangerousRSSSubtitle=I feed RSS possono costituire un pericolo
 FProxyToadlet.dangerousRSSTitle=Contentuto Potenzialmente Pericoloso (RSS)
 FProxyToadlet.downloadInBackgroundToDisk=Scarica in background e conserva 
nella directory dei download
-FProxyToadlet.errorIsFatal=Questo ? un errore grave (fatal error). Riprovare 
probabilmente non risolver? il problema.
+FProxyToadlet.errorIsFatal=Questo ? un errore grave (fatal error). Riprovare 
probabilmente non risolver? il problema.
 FProxyToadlet.errorWithReason=Errore: ${error}
-FProxyToadlet.expectedKeyButGot=Invece di una chiave Freenet, ? stato ricevuto:
+FProxyToadlet.expectedKeyButGot=Invece di una chiave Freenet, ? stato ricevuto:
 FProxyToadlet.expectedMimeType=MIME type che ci si aspettava: ${mime}
 FProxyToadlet.explanationTitle=Spiegazione
 FProxyToadlet.fetchLargeFileAnywayAndDisplay=Apri comunque e mostra il file 
nel browser
@@ -296,20 +292,20 @@
 FProxyToadlet.invalidKeyTitle=Chiave non valida
 FProxyToadlet.invalidKeyWithReason=Chiave non valida: ${reason}
 FProxyToadlet.largeFile=File di grosse dimensioni
-FProxyToadlet.largeFileExplanationAndOptions=La chiave Freenet richiesta fa 
riferimento a un file di grosse dimensioni.I file cos? grandi di solito non 
possono essere mandati direttamente al browser perch? il nodo avrebbe bisogno 
di troppo tempo per richiamarli. Le seguenti opzioni sono disponibili:
-FProxyToadlet.mayChange=(pu? cambiare)
+FProxyToadlet.largeFileExplanationAndOptions=La chiave Freenet richiesta fa 
riferimento a un file di grosse dimensioni.I file cos? grandi di solito non 
possono essere mandati direttamente al browser perch? il nodo avrebbe bisogno 
di troppo tempo per richiamarli. Le seguenti opzioni sono disponibili:
+FProxyToadlet.mayChange=(pu? cambiare)
 FProxyToadlet.mimeType=MIME type: ${mime}
 FProxyToadlet.notEnoughMetaStrings=Non ci sono abbastanza meta-strings
 FProxyToadlet.notFoundTitle=Non Trovato
-FProxyToadlet.openAsText=${link}Clicca qui${/link} per aprire il file come 
testo 'liscio' (plain text) . Questo non dovrebbe essere pericoloso ma la 
visualizzazione pu? risultare disturbata.
+FProxyToadlet.openAsText=${link}Clicca qui${/link} per aprire il file come 
testo 'liscio' (plain text) . Questo non dovrebbe essere pericoloso ma la 
visualizzazione pu? risultare disturbata.
 FProxyToadlet.openAsThawIndex=${link}Clicca qui${/link} per aprire un file con 
il browser di indici Thaw. (leggere l'avvertenza!)
 FProxyToadlet.openForce=${link}Clicca qui${/link} per aprire il file come 
${mime} (leggi l'avvertenza sopra!).
 FProxyToadlet.openForceDisk=${link}Clicca qui${/link} per scaricare il file su 
disco.
 FProxyToadlet.openPossRSSAsForceDisk=${link}Clicka qui${/link} per scaricare 
il file su disco (${bold}possibile pericolo${/bold} se si sta usando Firefox 
2.0.0.0; il problema dovrebbe essere stato risolto in 2.0.0.1
-FProxyToadlet.openPossRSSAsPlainText=${link}Clicca qui${/link} per aprire il 
file come testo 'liscio' (plain text) (ci? ${bold}pu? rappresentare un 
pericolo${/bold} se si sta usando IE7 o FF2).
-FProxyToadlet.openPossRSSForceDisk=${link}Clicca qui${/link} per cercare di 
costringere il browser a scaricare il file su disco (${bold}Pu? essere 
pericoloso se si sta usando Firefox 2.0.0${/bold} ; il problema dovrebbe essere 
risolto in 2.0.1).
-FProxyToadlet.openRSSAsRSS=${link}Clicca qui${/link} per aprire il file come 
RSS (ci? ${bold}rappresenta un pericolo${/bold} se l'autore del sito ? mal 
intenzionato, perch? il filtraggio di RSS in Freenet non ? ancora stato 
implementato).
-FProxyToadlet.openRSSForce=${link}Clicca qui${/link} per aprire il file come 
${mime} (ci? ${bold}pu? costituire un pericolo${/bold} se si usa IE7 o FF2).
+FProxyToadlet.openPossRSSAsPlainText=${link}Clicca qui${/link} per aprire il 
file come testo 'liscio' (plain text) (ci? ${bold}pu? rappresentare un 
pericolo${/bold} se si sta usando IE7 o FF2).
+FProxyToadlet.openPossRSSForceDisk=${link}Clicca qui${/link} per cercare di 
costringere il browser a scaricare il file su disco (${bold}Pu? essere 
pericoloso se si sta usando Firefox 2.0.0${/bold} ; il problema dovrebbe essere 
risolto in 2.0.1).
+FProxyToadlet.openRSSAsRSS=${link}Clicca qui${/link} per aprire il file come 
RSS (ci? ${bold}rappresenta un pericolo${/bold} se l'autore del sito ? mal 
intenzionato, perch? il filtraggio di RSS in Freenet non ? ancora stato 
implementato).
+FProxyToadlet.openRSSForce=${link}Clicca qui${/link} per aprire il file come 
${mime} (ci? ${bold}pu? costituire un pericolo${/bold} se si usa IE7 o FF2).
 FProxyToadlet.opennet=gestisci connessioni non affidabili
 FProxyToadlet.opennetTitle=Sconosciuti
 FProxyToadlet.options=Opzioni disponibili:
@@ -326,36 +322,36 @@
 FProxyToadlet.statsTitle=Statistiche
 FProxyToadlet.translation=helper per tradurre l'interfaccia del nodo nella tua 
lingua
 FProxyToadlet.translationTitle=Traduzione
-FProxyToadlet.unableToRetrieve=Non ? stato possibile richiamare questo file.
+FProxyToadlet.unableToRetrieve=Non ? stato possibile richiamare questo file.
 FProxyToadlet.unknownMIMEType=MIME type: sconosciuto
 FProxyToadlet.welcome=homepage
 FProxyToadlet.welcomeTitle=Home
 FcpServer.allowedHosts=Host abilitati (Leggere l'avvertenza)
-FcpServer.allowedHostsFullAccess=Host ai quali ? consentito accesso pieno
+FcpServer.allowedHostsFullAccess=Host ai quali ? consentito accesso pieno
 FcpServer.allowedHostsFullAccessLong=Indirizzi IP ai quali e' consentito pieno 
accesso al nodo. I client su questi IP possono riavviare il nodo, 
riconfigurarlo ecc. Attenzione: a *tutti* I client e' consentito di fare I/O 
diretto sul disco
-FcpServer.allowedHostsLong=Indirizzi IP ai quali ? consentito connettersi al 
server FCP. Pu? essere una lista di di IP singoli separati da virgole e 
indirizzi IP in formato CIDR come 192.168.0.0/24. AVVERTENZA! Chiunque abbia 
accesso a FCP potr? caricare su Freenet  qualsiasi file al quale il nodo abbia 
accesso e scaricare su disco qualsiasi file da Freenet (i file esistenti non 
verranno sovrascritti)
+FcpServer.allowedHostsLong=Indirizzi IP ai quali ? consentito connettersi al 
server FCP. Pu? essere una lista di di IP singoli separati da virgole e 
indirizzi IP in formato CIDR come 192.168.0.0/24. AVVERTENZA! Chiunque abbia 
accesso a FCP potr? caricare su Freenet  qualsiasi file al quale il nodo abbia 
accesso e scaricare su disco qualsiasi file da Freenet (i file esistenti non 
verranno sovrascritti)
 FcpServer.assumeDownloadDDAIsAllowed=Presumere che il download DDA sia 
permesso?
-FcpServer.assumeDownloadDDAIsAllowedLong=Presumere che il download DDA sia 
permesso? Se impostato su 'false' bisogner? fare una TestDDARequest prima di 
ogni accesso DDA
+FcpServer.assumeDownloadDDAIsAllowedLong=Presumere che il download DDA sia 
permesso? Se impostato su 'false' bisogner? fare una TestDDARequest prima di 
ogni accesso DDA
 FcpServer.assumeUploadDDAIsAllowed=Presumere che l'upload di DDA sia permesso?
-FcpServer.assumeUploadDDAIsAllowedLong=Presumere che l'upload DDA Sia 
permesso? Se impostato su 'falso', bisogner? fare una TestDDARequest prima di 
ogni accesso DDA.
+FcpServer.assumeUploadDDAIsAllowedLong=Presumere che l'upload DDA Sia 
permesso? Se impostato su 'falso', bisogner? fare una TestDDARequest prima di 
ogni accesso DDA.
 FcpServer.bindTo=Indirizzo IP collegato
 FcpServer.bindToLong=Indirizzo IP collegato al server FCP.
-FcpServer.cannotStartOrStopOnTheFly=Non ? possibile arrestare il server FCP 
"al volo"
-FcpServer.couldNotChangeBindTo=Non ? stato possibile modificare l'indirizzo 
FCP collegato: ${error}.
-FcpServer.downloadsFileCanCreateCannotReadOrWrite=Il file ? stato creato ma 
non ? possibile leggerlo e scriverlo
-FcpServer.downloadsFileDoesNotExistCannotCreate=Il file non esiste e non ? 
possibile crearlo
-FcpServer.downloadsFileExistsCannotReadOrWrite=Il file esiste ma non ? 
possibile leggerlo e scriverlo
+FcpServer.cannotStartOrStopOnTheFly=Non ? possibile arrestare il server FCP 
"al volo"
+FcpServer.couldNotChangeBindTo=Non ? stato possibile modificare l'indirizzo 
FCP collegato: ${error}.
+FcpServer.downloadsFileCanCreateCannotReadOrWrite=Il file ? stato creato ma 
non ? possibile leggerlo e scriverlo
+FcpServer.downloadsFileDoesNotExistCannotCreate=Il file non esiste e non ? 
possibile crearlo
+FcpServer.downloadsFileExistsCannotReadOrWrite=Il file esiste ma non ? 
possibile leggerlo e scriverlo
 FcpServer.downloadsFileIsDirectory=Nome non valido per una lista di download: 
si tratta di una directory
 FcpServer.downloadsFileParentDoesNotExist=La directory superiore non esiste
-FcpServer.downloadsFileUnreadable=Il file esiste ma non ? possibile leggerlo
+FcpServer.downloadsFileUnreadable=Il file esiste ma non ? possibile leggerlo
 FcpServer.enablePersistentDownload=Abilitare download persistenti?
-FcpServer.enablePersistentDownloadLong=Abilita Persistence=forever 
(persistenza illimitata) per le richieste FCP. Abilitando questa opzione si 
permette alle richieste di persistere attraverso il riavvio del nodo: tali 
richieste devono essere scritte sul disco rigido e questo in alcuni casi 
particolari pu? costituire un problema di sicurezza
+FcpServer.enablePersistentDownloadLong=Abilita Persistence=forever 
(persistenza illimitata) per le richieste FCP. Abilitando questa opzione si 
permette alle richieste di persistere attraverso il riavvio del nodo: tali 
richieste devono essere scritte sul disco rigido e questo in alcuni casi 
particolari pu? costituire un problema di sicurezza
 FcpServer.filenameToStorePData=File contenente download persistenti
 FcpServer.filenameToStorePDataLong=File contenente download persistenti.
 FcpServer.intervalBetweenWrites=Intervallo di scrittura dei download 
persistenti su disco
 FcpServer.intervalBetweenWritesLong=Intervallo tra le scritture di download 
persistenti su disco. (millisecondi)
-FcpServer.isEnabled=FCP server ? abilitato?
-FcpServer.isEnabledLong=FCP server ? abilitato?
+FcpServer.isEnabled=FCP server ? abilitato?
+FcpServer.isEnabledLong=FCP server ? abilitato?
 FcpServer.portNumber=Numero della porta FCP
 FcpServer.portNumberLong=Numero della porta FCP.
 FcpServer.ssl=Abilitare ssl?
@@ -365,31 +361,31 @@
 FetchException.longError.11=Troppe componenti di percorso. Prova a eliminarne 
uno
 FetchException.longError.12=Errore interno relativo ai file temporanei: 
potrebbe trattarsi di esaurimento dello spazio libero su disco rigido o di un 
problema relativo a permessi ed autorizzazioni
 FetchException.longError.13=Dati non trovati
-FetchException.longError.14=Percorso non trovato: non ? stato possobile 
trovare un numero di nodi sufficiente ad essere certi che i dati non esistono
-FetchException.longError.15=Un nodo ? stato sovraccaricato o ? uscito fuori 
tempo massimo
+FetchException.longError.14=Percorso non trovato: non ? stato possobile 
trovare un numero di nodi sufficiente ad essere certi che i dati non esistono
+FetchException.longError.15=Un nodo ? stato sovraccaricato o ? uscito fuori 
tempo massimo
 FetchException.longError.16=Troppi redirects - loop?
 FetchException.longError.17=Errore interno, probabilmente un bug
-FetchException.longError.18=Il file ? stato trovato ma ? andato perso durante 
la ricezione
+FetchException.longError.18=Il file ? stato trovato ma ? andato perso durante 
la ricezione
 FetchException.longError.19=Errore splitfile
 FetchException.longError.2=Il nodo non sa cosa fare dello splitfile
 FetchException.longError.20=URI non valida
 FetchException.longError.21=Troppo grande
 FetchException.longError.22=Volume dei metadati troppo grande
 FetchException.longError.23=Troppi blocchi per segmento
-FetchException.longError.24=Sono necessarie pi? metastringhe (componenti di 
percorso) nella URI
+FetchException.longError.24=Sono necessarie pi? metastringhe (componenti di 
percorso) nella URI
 FetchException.longError.25=Annullato
 FetchException.longError.26=Archivio riavviato
 FetchException.longError.27=Redirezione permanente: usare la nuova URI
-FetchException.longError.28=Non ? stato possibile raccogliere dati in quantit? 
sufficiente; dati parziali sono stati richiamati ma il redirect potrebbe 
puntare su localit? non valide
+FetchException.longError.28=Non ? stato possibile raccogliere dati in quantit? 
sufficiente; dati parziali sono stati richiamati ma il redirect potrebbe 
puntare su localit? non valide
 FetchException.longError.29=MIME Type non valido: chiave non presente in lista 
di MIME type permessi fornita dal client.
 FetchException.longError.3=Metadati non utilizzabili
-FetchException.longError.30=La richiesta ? stata terminata da un nodo perch? 
esso aveva da poco ricevuto un'altra richiesta per la stessa chiave e quella 
richiesta non era andata a buon fine.
-FetchException.longError.4=Non ? stato possibile interpretare i metadati.
+FetchException.longError.30=La richiesta ? stata terminata da un nodo perch? 
esso aveva da poco ricevuto un'altra richiesta per la stessa chiave e quella 
richiesta non era andata a buon fine.
+FetchException.longError.4=Non ? stato possibile interpretare i metadati.
 FetchException.longError.5=Fallimento durante l'estrazione di file da un 
archivio
-FetchException.longError.6=Non ? stato possibile decodificare un blocco
+FetchException.longError.6=Non ? stato possibile decodificare un blocco
 FetchException.longError.7=Metadati divisi in troppi livelli
-FetchException.longError.8=La richiesta ? stata riavviata troppe volte a causa 
di cambiamenti negli archivii
-FetchException.longError.9=Troppe redirezioni (troppa ricorsivit?)
+FetchException.longError.8=La richiesta ? stata riavviata troppe volte a causa 
di cambiamenti negli archivii
+FetchException.longError.9=Troppe redirezioni (troppa ricorsivit?)
 FetchException.shortError.1=Recursione archivio troppo profonda
 FetchException.shortError.10=Non in archivio
 FetchException.shortError.11=Troppe componenti nel percorso
@@ -406,14 +402,14 @@
 FetchException.shortError.21=Troppo grande
 FetchException.shortError.22=Volume metadati eccessivo
 FetchException.shortError.23=Troppi blocchi per segmento
-FetchException.shortError.24=Quantit? meta-strings insufficiente
+FetchException.shortError.24=Quantit? meta-strings insufficiente
 FetchException.shortError.25=Annullato da caller
 FetchException.shortError.26=Archivio riavviato
 FetchException.shortError.27=Nuova URI
 FetchException.shortError.28=Non sono stati trovati tutti i dati
 FetchException.shortError.29=Errore: MIME type sbagliato
 FetchException.shortError.3=Metadati sconosciuti
-FetchException.shortError.30=Non ? stato possibile trovare i dati richiesti 
(fallimento recente)
+FetchException.shortError.30=Non ? stato possibile trovare i dati richiesti 
(fallimento recente)
 FetchException.shortError.4=Metadati non validi
 FetchException.shortError.5=Fallimento archivio
 FetchException.shortError.6=Errore decodifica block
@@ -423,7 +419,7 @@
 FileOffer.acceptTransferButton=Accetta Trasferimento
 FileOffer.askUserTitle=Trasferimento file diretto.
 FileOffer.commentLabel=Commenti:
-FileOffer.failedReceiveHeader=Non ? stato possibile completare il 
trasferimento del file ${filename} da ${node}.
+FileOffer.failedReceiveHeader=Non ? stato possibile completare il 
trasferimento del file ${filename} da ${node}.
 FileOffer.failedReceiveShort=Trasferimento di ${filename} da ${node} fallito.
 FileOffer.failedReceiveTitle=Trasferimento fallito
 FileOffer.fileLabel=File:
@@ -433,36 +429,36 @@
 FileOffer.rejectTransferButton=Rifiuta trasferimento
 FileOffer.senderLabel=Mittente:
 FileOffer.sizeLabel=Dimensioni:
-FileOffer.succeededReceiveHeader=Il trasferimento del file ${filename} da 
${node} ? stato completato.
-FileOffer.succeededReceiveShort=${filename} ? stato ricevuto da ${node}.
+FileOffer.succeededReceiveHeader=Il trasferimento del file ${filename} da 
${node} ? stato completato.
+FileOffer.succeededReceiveShort=${filename} ? stato ricevuto da ${node}.
 FileOffer.succeededReceiveTitle=Trasferimento file completato
 FirstTimeWizardToadlet.bandwidthLimit=Limitazione banda
-FirstTimeWizardToadlet.bandwidthLimitLong=Scegliere il tipo di connessione e 
la velocit? dal drop-down menu.
-FirstTimeWizardToadlet.bwlimitHigherSpeed=Velocit? maggiore
-FirstTimeWizardToadlet.bwlimitLowerSpeed=Velocit? minore
-FirstTimeWizardToadlet.chooseNodeName=Il nome del nodo ? obbligatorio!
-FirstTimeWizardToadlet.chooseNodeNameLong=Inserire un nome per il nodo. Il 
nome sar? visibile ai peer darknet, quelli manualmente aggiunti dall'utente, e 
non sar? visibile dai peer opeennet (aggiunti automaticamente) . Si consiglia 
di usare il proprio nickname IRC possibilmente con un'informazione per il 
conctatto in modo da essere reperibili in caso di problemi ("Mario Rossi marior 
at sitodimario.com").
+FirstTimeWizardToadlet.bandwidthLimitLong=Scegliere il tipo di connessione e 
la velocit? dal drop-down menu.
+FirstTimeWizardToadlet.bwlimitHigherSpeed=Velocit? maggiore
+FirstTimeWizardToadlet.bwlimitLowerSpeed=Velocit? minore
+FirstTimeWizardToadlet.chooseNodeName=Il nome del nodo ? obbligatorio!
+FirstTimeWizardToadlet.chooseNodeNameLong=Inserire un nome per il nodo. Il 
nome sar? visibile ai peer darknet, quelli manualmente aggiunti dall'utente, e 
non sar? visibile dai peer opeennet (aggiunti automaticamente) . Si consiglia 
di usare il proprio nickname IRC possibilmente con un'informazione per il 
conctatto in modo da essere reperibili in caso di problemi ("Mario Rossi marior 
at sitodimario.com").
 FirstTimeWizardToadlet.clickContinue=Clicca qui per continuare.
 FirstTimeWizardToadlet.congratz=Benvenuto a bordo!
-FirstTimeWizardToadlet.congratzLong=Congratulazioni, la configurazione di base 
del nodo Freenet ? completa. E' possibile cambiare e modificare ognuno dei 
parametri appena impostati usando la pagina "configurazione" che ? 
raggiungibile attraverso il menu sulla sinistra dell'interfaccia. Vi auguriamo 
una piacevole esperienza con Freenet.
+FirstTimeWizardToadlet.congratzLong=Congratulazioni, la configurazione di base 
del nodo Freenet ? completa. E' possibile cambiare e modificare ognuno dei 
parametri appena impostati usando la pagina "configurazione" che ? 
raggiungibile attraverso il menu sulla sinistra dell'interfaccia. Vi auguriamo 
una piacevole esperienza con Freenet.
 FirstTimeWizardToadlet.connectToStrangers=Connetti a sconosciuti?
-FirstTimeWizardToadlet.connectToStrangersLong=In un mondo ideale, ogni utente 
Freenet si connetterebbe esclusivamente con nodi gestiti da persone fid?te. 
Qesto ? di gran lunga il sistema pi? sicuro, che rende molto difficile per un 
osservatore esterno determinare se un nodo stia o meno girando sul computer 
osservato. D'altra parte, non avendo a disposizione almeno cinque amici, 
parenti o conoscenti fid?ti che gi? usano Freenet, ai quali connettersi, come 
soluzione alternativa ? possibile lasciare che il nodo si connetta 
automaticamente a nodi gestiti da sconosciuti. Questa opzione pu? essere 
disattivata in qualsiasi momento.
+FirstTimeWizardToadlet.connectToStrangersLong=In un mondo ideale, ogni utente 
Freenet si connetterebbe esclusivamente con nodi gestiti da persone fid?te. 
Qesto ? di gran lunga il sistema pi? sicuro, che rende molto difficile per un 
osservatore esterno determinare se un nodo stia o meno girando sul computer 
osservato. D'altra parte, non avendo a disposizione almeno cinque amici, 
parenti o conoscenti fid?ti che gi? usano Freenet, ai quali connettersi, come 
soluzione alternativa ? possibile lasciare che il nodo si connetta 
automaticamente a nodi gestiti da sconosciuti. Questa opzione pu? essere 
disattivata in qualsiasi momento.
 FirstTimeWizardToadlet.continue=Continua
 FirstTimeWizardToadlet.continueEnd=Clicca qui per cominciare ad usare Freenet!
 FirstTimeWizardToadlet.datastoreSize=Dimensioni magazzino dati (datastore)
-FirstTimeWizardToadlet.datastoreSizeLong=Selezionare le dimensione desiderata 
per il file di immagazzinaggio dati (datastore). Il datastore funziona come una 
cache. Immagazzinare dati per il network aumenta il volume di scambio quando i 
file sono molto richiesti. Pi? spazio ci si pu? permettere di dedicare a 
Freenet e meglio ? per la comunit?. Un datastore di grosse dimensioni aumenta 
notevolmente la velocit? del nodo.
+FirstTimeWizardToadlet.datastoreSizeLong=Selezionare le dimensione desiderata 
per il file di immagazzinaggio dati (datastore). Il datastore funziona come una 
cache. Immagazzinare dati per il network aumenta il volume di scambio quando i 
file sono molto richiesti. Pi? spazio ci si pu? permettere di dedicare a 
Freenet e meglio ? per la comunit?. Un datastore di grosse dimensioni aumenta 
notevolmente la velocit? del nodo.
 FirstTimeWizardToadlet.enableOpennet=Connettersi automaticamente a nodi non 
affidabili gestiti da sconosciuti?
 FirstTimeWizardToadlet.fivePercentDisk=(= 5% di spazio libero su disco)
 FirstTimeWizardToadlet.homepageTitle=Configurazione Automatica Freenet
 FirstTimeWizardToadlet.iDoTrust=Possiamo fidarci degli utenti connessi a 
${interface} (${ip}) ?
-FirstTimeWizardToadlet.isNetworkTrusted=La rete locale ? affidabile?
-FirstTimeWizardToadlet.isNetworkTrustedLong=La rete locale ? affidabile? 
Rispondendo di si a questa domanda, tutti i servizii forniti dal nodo Freenet 
saranno pienamente accessibili da chiunque sul network suddetto. E' possibile 
configurare un accesso pi? selettivo attraverso la pagina "configurazione" dopo 
aver completato questo wizard.
+FirstTimeWizardToadlet.isNetworkTrusted=La rete locale ? affidabile?
+FirstTimeWizardToadlet.isNetworkTrustedLong=La rete locale ? affidabile? 
Rispondendo di si a questa domanda, tutti i servizii forniti dal nodo Freenet 
saranno pienamente accessibili da chiunque sul network suddetto. E' possibile 
configurare un accesso pi? selettivo attraverso la pagina "configurazione" dopo 
aver completato questo wizard.
 FirstTimeWizardToadlet.memoryLimit=Utilizzo memoria
-FirstTimeWizardToadlet.memoryLimitLong=Specifica il valore massimo della 
memoria utilizzabile da Freenet. Il nodo ha bisogno di pi? memoria se ci sono 
molti file in coda per il download/upload. Si raccomanda di non impostare 
questa opzione per un valore inferiore a 128MB tranne nel caso in cui la 
memoria totale a disposizione sia veramente poca. Se il computer ha 1GB di 
memoria RAM o pi?, si consiglia di usare almeno 256MB. Il cambiamento avr? 
effetto dopo aver riavviato Freenet.
-FirstTimeWizardToadlet.noNetworkIF=Non ? stata trovata nessuna interfaccia di 
rete addizionale
-FirstTimeWizardToadlet.noNetworkIFLong=Freenet non ha trovato altre interfacce 
di rete, quindi dar? per scontato che l'utente si connetter? dal computer 
locale e solo da quello.
-FirstTimeWizardToadlet.opennetNo=Si, ho almeno 5 amici che usano Freenet e 
aggiunger? i loro dati alla pagina degli Amici.
-FirstTimeWizardToadlet.opennetWarning=In Paesi dove networking anonimo ? 
illegale e/o se usa Freenet per accedere a materiale che potrebbe mettere nei 
guai chi ne fosse trovato in possesso, un serio pericolo pu? risultare dal 
configurare il nodo in modo da connettersi automaticamente a nodi gestiti da 
sconosciuti, facilitando il il compito ad un avversario determinato. Freenet ? 
ancora in fase sperimentale, gli autori non sono in grado di garatire sicurezza 
assoluta.
+FirstTimeWizardToadlet.memoryLimitLong=Specifica il valore massimo della 
memoria utilizzabile da Freenet. Il nodo ha bisogno di pi? memoria se ci sono 
molti file in coda per il download/upload. Si raccomanda di non impostare 
questa opzione per un valore inferiore a 128MB tranne nel caso in cui la 
memoria totale a disposizione sia veramente poca. Se il computer ha 1GB di 
memoria RAM o pi?, si consiglia di usare almeno 256MB. Il cambiamento avr? 
effetto dopo aver riavviato Freenet.
+FirstTimeWizardToadlet.noNetworkIF=Non ? stata trovata nessuna interfaccia di 
rete addizionale
+FirstTimeWizardToadlet.noNetworkIFLong=Freenet non ha trovato altre interfacce 
di rete, quindi dar? per scontato che l'utente si connetter? dal computer 
locale e solo da quello.
+FirstTimeWizardToadlet.opennetNo=Si, ho almeno 5 amici che usano Freenet e 
aggiunger? i loro dati alla pagina degli Amici.
+FirstTimeWizardToadlet.opennetWarning=In Paesi dove networking anonimo ? 
illegale e/o se usa Freenet per accedere a materiale che potrebbe mettere nei 
guai chi ne fosse trovato in possesso, un serio pericolo pu? risultare dal 
configurare il nodo in modo da connettersi automaticamente a nodi gestiti da 
sconosciuti, facilitando il il compito ad un avversario determinato. Freenet ? 
ancora in fase sperimentale, gli autori non sono in grado di garatire sicurezza 
assoluta.
 FirstTimeWizardToadlet.opennetYes=No, voglio che il nodo trovi automaticamente 
degli sconosciuti ai quali connettersi.
 FirstTimeWizardToadlet.selectLanguage=Lingua
 FirstTimeWizardToadlet.selectLanguageLong=Selezionare una lingua dalla lista 
qui sotto:
@@ -472,93 +468,93 @@
 FirstTimeWizardToadlet.step3Title=Configurazione automatica di Freenet - 
Limiti ampiezza di banda
 FirstTimeWizardToadlet.step4Title=Freenet first time wizard! - Dimensioni 
magazzino dati (datastore)
 FirstTimeWizardToadlet.step5Title=Configurazione Automatica Freenet - 
Configurazione rete
-FirstTimeWizardToadlet.step6Title=Configurazione Automatica Freenet - 
Congratulazioni, il nodo ? ora configurato.
-FirstTimeWizardToadlet.step7Title=Configurazione Automatica Freenet - 
Congratulazioni, il nodo ? ora configurato.
+FirstTimeWizardToadlet.step6Title=Configurazione Automatica Freenet - 
Congratulazioni, il nodo ? ora configurato.
+FirstTimeWizardToadlet.step7Title=Configurazione Automatica Freenet - 
Congratulazioni, il nodo ? ora configurato.
 FirstTimeWizardToadlet.tenPercentDisk=(= 10% di spazio libero su disco)
 FirstTimeWizardToadlet.warningTitle=Avvertenza!
-FirstTimeWizardToadlet.welcomeInfoboxContent1=Benvenuti nella Configurazione 
Automatica Freenet, che vi permetter? di configurare Freenet e cominciare ad 
usarlo velocemente e facilmente.
+FirstTimeWizardToadlet.welcomeInfoboxContent1=Benvenuti nella Configurazione 
Automatica Freenet, che vi permetter? di configurare Freenet e cominciare ad 
usarlo velocemente e facilmente.
 FirstTimeWizardToadlet.welcomeInfoboxTitle=Benevenuti in Configurazione 
Automatica Freenet
 FirstTimeWizardToadlet.memory.128M=128Mb - Il minimo indispensabile
 FirstTimeWizardToadlet.memory.192M=192Mb - Default ragionevole.
 FirstTimeWizardToadlet.memory.256M=256Mb - Per computer con almeno 1GB di RAM
 FirstTimeWizardToadlet.memory.512M=512Mb - per computer con molta memoria RAM
-FirstTimeWizardToadlet.memory.64M=64MB - Usare solo in caso di estrema 
necessit?
+FirstTimeWizardToadlet.memory.64M=64MB - Usare solo in caso di estrema 
necessit?
 FproxyToadlet.dangerousRSSTitle=Contenuto potenzialmente pericoloso (RSS)
 GIFFilter.invalidHeader=Il file non contiene un header GIF valido.
 GIFFilter.invalidHeaderTitle=Header non valido
-GIFFilter.notGif=Il file che si sta cercando di richiamare non ? una GIF. 
Potrebbe trattarsi di un file in un altro formato, ed il browser potrebbe fare 
qualcosa di pericoloso a cause della confusione generata dalla mancata 
corrispondenza; il file ? stato pertanto bloccato.
-GIFFilter.tooShort=Il file ? troppo piccolo per essere una GIF.
+GIFFilter.notGif=Il file che si sta cercando di richiamare non ? una GIF. 
Potrebbe trattarsi di un file in un altro formato, ed il browser potrebbe fare 
qualcosa di pericoloso a cause della confusione generata dalla mancata 
corrispondenza; il file ? stato pertanto bloccato.
+GIFFilter.tooShort=Il file ? troppo piccolo per essere una GIF.
 GIFFilter.tooShortTitle=Troppo corto
-GenericReadFilterCallback.couldNotParseAbsoluteFreenetURI=Non ? stato 
possibile interpretare come URI Freenet assoluta.
-GenericReadFilterCallback.couldNotParseFormURIWithError=Il filtro non ? 
riuscito ad interpretare ${error} dalla URI.
-GenericReadFilterCallback.couldNotParseRelativeFreenetURI=Non ? stato 
possibile interpretare come Freenet URI relativa.
+GenericReadFilterCallback.couldNotParseAbsoluteFreenetURI=Non ? stato 
possibile interpretare come URI Freenet assoluta.
+GenericReadFilterCallback.couldNotParseFormURIWithError=Il filtro non ? 
riuscito ad interpretare ${error} dalla URI.
+GenericReadFilterCallback.couldNotParseRelativeFreenetURI=Non ? stato 
possibile interpretare come Freenet URI relativa.
 GenericReadFilterCallback.couldNotParseURIWithError=Il filtro ha fallito 
nell'analisi della URI: ${error}
 GenericReadFilterCallback.invalidFormURI=URI form non valida: punta a risorsa 
esterna
 GenericReadFilterCallback.invalidFormURIAttemptToEscape=Tentativo di evasione 
dalla struttura delle directory
 GenericReadFilterCallback.malformedAbsoluteURL=URL malformata (assoluto): 
${error}
 GenericReadFilterCallback.malformedRelativeURL=URL malformata (relativa): 
${error}
-GenericReadFilterCallback.protocolNotEscaped=Non ? un protocollo fuggitivo: 
${protocol}
-HTMLFilter.couldNotParseStyle=Non ? stato possibile abbinare lo stile 
dell'input
+GenericReadFilterCallback.protocolNotEscaped=Non ? un protocollo fuggitivo: 
${protocol}
+HTMLFilter.couldNotParseStyle=Non ? stato possibile abbinare lo stile 
dell'input
 HTMLFilter.deletedUnknownStyle=stile sconosciuto eliminato
-HTMLFilter.failedToParseLabel=Il filtro HTML non ? riuscito a interpretare la 
pagina
+HTMLFilter.failedToParseLabel=Il filtro HTML non ? riuscito a interpretare la 
pagina
 HTMLFilter.tooManyNestedStyleOrScriptTags=Troppi tag 'style' annidati e/o 
troppi tag di scripting: analisi ambigua o non valida
-HTMLFilter.tooManyNestedStyleOrScriptTagsLong=Troppi tag </style> annidati - 
analisi ambigua o non valida. Non ? possibile filtrare in modo affidabile 
quindi i tag interni sono stai rimossi: questo pu? causare al browser qualche 
inconveniente nella visuallizzazione
+HTMLFilter.tooManyNestedStyleOrScriptTagsLong=Troppi tag </style> annidati - 
analisi ambigua o non valida. Non ? possibile filtrare in modo affidabile 
quindi i tag interni sono stai rimossi: questo pu? causare al browser qualche 
inconveniente nella visuallizzazione
 HTMLFilter.unknownTag=tag sconosciuto ${tag}
 IPDetectorPluginManager.connectionProblems=Problemi di connessione:
 IPDetectorPluginManager.direct=Il computer sembra essere direttamente connesso 
a Internet, dovrebbe essere quindi possibile connettersi con qualunque nodo 
Freenet.
 IPDetectorPluginManager.directTitle=Rilevata connessione diretta a Internet
-IPDetectorPluginManager.forwardPort=Il tuo nodo sembra essere dietro qualche 
tipo di NAT (vedi la pagina connettivit? per dettagli). Se possibile, dovresti 
forwardare le porte UDP (not TCP) ${port} per migliorare la connettivit?. E' 
possibile comunque che tu abbia gi? provveduto; Serve del tempo a Freenet per 
rilevare il port forward. Leggi ${link}qui${/link} per ulteriori informazioni.
-IPDetectorPluginManager.forwardPortMaybeForwarded=Sembra che il nodo si trovi 
dietro una NAT di qualche tipo (vedi pagina connettivit? per i dettaglil). Se 
possibile, bigognerebbe configurare il forward per la porta ${port} UDP (non 
TCP) allo scopo di migliorare la connettivit?. E' possibile comunque che ci? 
sia gi? stato fatto: occorre un po' di tempo perch? Freenet rilevi il port 
forward. Clicca ${link}qui${/link} per maggiori informazioni.
-IPDetectorPluginManager.forwardPortNotForwarded=Sembra che il nodo si trovi 
dietro una NAT di qualche tipo (vedi pagina connettivit? per i dettaglil). Se 
possibile, bigognerebbe configurare il forward per la porta ${port} UDP (non 
TCP) allo scopo di migliorare la connettivit?. Sembra che ci? non sia stato 
fatto, anche occorre un po' di tempo perch? Freenet rilevi il port forward. 
Clicca ${link}qui${/link} per maggiori informazioni
+IPDetectorPluginManager.forwardPort=Il tuo nodo sembra essere dietro qualche 
tipo di NAT (vedi la pagina connettivit? per dettagli). Se possibile, dovresti 
forwardare le porte UDP (not TCP) ${port} per migliorare la connettivit?. E' 
possibile comunque che tu abbia gi? provveduto; Serve del tempo a Freenet per 
rilevare il port forward. Leggi ${link}qui${/link} per ulteriori informazioni.
+IPDetectorPluginManager.forwardPortMaybeForwarded=Sembra che il nodo si trovi 
dietro una NAT di qualche tipo (vedi pagina connettivit? per i dettaglil). Se 
possibile, bigognerebbe configurare il forward per la porta ${port} UDP (non 
TCP) allo scopo di migliorare la connettivit?. E' possibile comunque che ci? 
sia gi? stato fatto: occorre un po' di tempo perch? Freenet rilevi il port 
forward. Clicca ${link}qui${/link} per maggiori informazioni.
+IPDetectorPluginManager.forwardPortNotForwarded=Sembra che il nodo si trovi 
dietro una NAT di qualche tipo (vedi pagina connettivit? per i dettaglil). Se 
possibile, bigognerebbe configurare il forward per la porta ${port} UDP (non 
TCP) allo scopo di migliorare la connettivit?. Sembra che ci? non sia stato 
fatto, anche occorre un po' di tempo perch? Freenet rilevi il port forward. 
Clicca ${link}qui${/link} per maggiori informazioni
 IPDetectorPluginManager.forwardPortShort=Per favore, forwardare la porta UDP 
${port}.
-IPDetectorPluginManager.forwardPortShortMaybeForwarded=Si prega di configurare 
il forward della porta ${port} UDP (questo potrebbe essere gi? stato fatto, ma 
non ancora rilevato)
+IPDetectorPluginManager.forwardPortShortMaybeForwarded=Si prega di configurare 
il forward della porta ${port} UDP (questo potrebbe essere gi? stato fatto, ma 
non ancora rilevato)
 IPDetectorPluginManager.forwardPortShortNotForwarded=Si prega di configurare 
il forward per la porta ${port} UDP .
-IPDetectorPluginManager.forwardTwoPorts=Il tuo nodo sembra essere dietro 
quanlche tipo di NAT (vedi la pagina connettivit? per dettagli). Se possibile, 
dovresti eseguire il forward UDP (non TCP) delle porte ${port1} e ${port2} per 
migliorare la connettivit?. E' possibile comunque che tu abbia gi? provveduto; 
serve del tempo a Freenet per determinare l'avvenuto forward. Leggi 
${link}qui${/link} per ulteriori informazioni.
-IPDetectorPluginManager.forwardTwoPortsMaybeForwarded=Sembra che il nodo si 
trovi dietro una NAt di qualche tipo (vedi pagina connettivit? per i 
dettaglil). Se possibile, bigognerebbe configurare il forward per la porta 
${port} UDP (non TCP) allo scopo di migliorare la connettivit?. E' possibile 
comunque che ci? sia gi? stato fatto: occorre un po' di tempo perch? Freenet 
rilevi il port forward. Clicca ${link}qui${/link} per maggiori informazioni
-IPDetectorPluginManager.forwardTwoPortsNotForwarded=Pare che il nodo sia 
dietro una  NAT (controllare la pagina connettivit? per i dettagli). PSe 
possibile si dovrebbe configurare il forward per le porte ${port1} e ${port2} 
UDP (non TCP), allo scopo di migliorare la connettivit?. Sembra che il forward 
delle porte non sia attivo, anche se Freenet non pu? determinarlo per certo. 
Controllare ${link}qui${/link} per ulteriori informazioni.
+IPDetectorPluginManager.forwardTwoPorts=Il tuo nodo sembra essere dietro 
quanlche tipo di NAT (vedi la pagina connettivit? per dettagli). Se possibile, 
dovresti eseguire il forward UDP (non TCP) delle porte ${port1} e ${port2} per 
migliorare la connettivit?. E' possibile comunque che tu abbia gi? provveduto; 
serve del tempo a Freenet per determinare l'avvenuto forward. Leggi 
${link}qui${/link} per ulteriori informazioni.
+IPDetectorPluginManager.forwardTwoPortsMaybeForwarded=Sembra che il nodo si 
trovi dietro una NAt di qualche tipo (vedi pagina connettivit? per i 
dettaglil). Se possibile, bigognerebbe configurare il forward per la porta 
${port} UDP (non TCP) allo scopo di migliorare la connettivit?. E' possibile 
comunque che ci? sia gi? stato fatto: occorre un po' di tempo perch? Freenet 
rilevi il port forward. Clicca ${link}qui${/link} per maggiori informazioni
+IPDetectorPluginManager.forwardTwoPortsNotForwarded=Pare che il nodo sia 
dietro una  NAT (controllare la pagina connettivit? per i dettagli). PSe 
possibile si dovrebbe configurare il forward per le porte ${port1} e ${port2} 
UDP (non TCP), allo scopo di migliorare la connettivit?. Sembra che il forward 
delle porte non sia attivo, anche se Freenet non pu? determinarlo per certo. 
Controllare ${link}qui${/link} per ulteriori informazioni.
 IPDetectorPluginManager.forwardTwoPortsShort=Per favore, forwardare le porte 
UDP ${port1} e ${port2}.
-IPDetectorPluginManager.forwardTwoPortsShortMaybeForwarded=Configurare il 
forward  per porte ${port1} e ${port2} UDP (potrebbe essere gi? stato fatto).
+IPDetectorPluginManager.forwardTwoPortsShortMaybeForwarded=Configurare il 
forward  per porte ${port1} e ${port2} UDP (potrebbe essere gi? stato fatto).
 IPDetectorPluginManager.forwardTwoPortsShortNotForwarded=Si prega di 
configurare il forward per le porte ${port1} e ${port2} UDP.
 IPDetectorPluginManager.fullCone=La connessione a Internet sembra avvenire 
attraverso una "full cone" NAT. Il nodo dovrebbe riuscire connettersi con 
qualunque altro nodo Freenet.
 IPDetectorPluginManager.fullConeTitle=Rilevata full cone NAT
-IPDetectorPluginManager.maybeAlreadyForwarded=Potrebbe essere gi? stato fatto 
(? difficile per Freenet determinarlo).
-IPDetectorPluginManager.noConnectivity=La connessione a Internet non sembra 
essere provvista di supporto UDP. A meno che non si tratti di un rilevamento 
erroneo, non ? probabile che Freenet possa funzionare al momento.
-IPDetectorPluginManager.noConnectivityTitle=Mancanza di connettivit? UDP
-IPDetectorPluginManager.noConnectivityshort=Gravi problemi di connessione: 
Nessuna connettivit? UDP, Freenet non pu? funzionare!
+IPDetectorPluginManager.maybeAlreadyForwarded=Potrebbe essere gi? stato fatto 
(? difficile per Freenet determinarlo).
+IPDetectorPluginManager.noConnectivity=La connessione a Internet non sembra 
essere provvista di supporto UDP. A meno che non si tratti di un rilevamento 
erroneo, non ? probabile che Freenet possa funzionare al momento.
+IPDetectorPluginManager.noConnectivityTitle=Mancanza di connettivit? UDP
+IPDetectorPluginManager.noConnectivityshort=Gravi problemi di connessione: 
Nessuna connettivit? UDP, Freenet non pu? funzionare!
 
IPDetectorPluginManager.portForwardHelpURL=http://wiki.freenetproject.org/FirewallAndRouterIssues
-IPDetectorPluginManager.portRestricted=La connessione a Internet sembra 
avvenire attraverso una NAT a porte ristrette (router). Il nodo potr? 
connettersi a quasi tutti gli altri nodi ma non a quelli dietro NAT simmetrica.
+IPDetectorPluginManager.portRestricted=La connessione a Internet sembra 
avvenire attraverso una NAT a porte ristrette (router). Il nodo potr? 
connettersi a quasi tutti gli altri nodi ma non a quelli dietro NAT simmetrica.
 IPDetectorPluginManager.portRestrictedTitle=Port restricted cone NAT rilevata
 IPDetectorPluginManager.restricted=La connessione a Internet sembra avvenire 
attraverso una "restricted cone" NAT (router). Dovrebbe essere comunque 
possibile connettersi alla maggior parte dei nodi Freenet.
 IPDetectorPluginManager.restrictedTitle=E' stata rilevata una restricted cone 
NAT
 IPDetectorPluginManager.seriousConnectionProblems=Gravi problemi di 
connessione:
 IPDetectorPluginManager.suggestForwardPort=Potrebbe essere necessario 
configurare  manualmente il 'port forwarding'  per la porta UDP numero ${port}. 
Vedi: http://wiki.freenetproject.org/FirewallAndRouterIssues (disponibile solo 
in inglese, per ora).
-IPDetectorPluginManager.suggestForwardPortWithLink=Potrebbe essere necessario 
${link}configurare il port forwarding${/link} (porta UDP numero ${port}) 
manualmente (oppure ci? ? gi? stato fatto: Freenet pu? avere delle difficolt? 
in questo tipo di rilevazione).
+IPDetectorPluginManager.suggestForwardPortWithLink=Potrebbe essere necessario 
${link}configurare il port forwarding${/link} (porta UDP numero ${port}) 
manualmente (oppure ci? ? gi? stato fatto: Freenet pu? avere delle difficolt? 
in questo tipo di rilevazione).
 IPDetectorPluginManager.suggestForwardTwoPorts=Sarebbe opportuno configurare 
manualmente il port forward sul router per le porte ${port1} e ${port2} (UDP). 
vedi http://wiki.freenetproject.org/FirewallAndRouterIssues (disponibile solo 
in inglese, per ora).
-IPDetectorPluginManager.suggestForwardTwoPortsWithLink=Potrebbe essere 
necessario configurare manualmente ${link}il forward delle porte${/link} Per 
porte nummero ${port1} e ${port2}, UDP. (questo messaggio pu? in alcuni casi 
continuare ad apparire per un po' di tempo dopo aver configurato il forward)
-IPDetectorPluginManager.symmetric=Dai rilevamenti appare che il nodo potrebbe 
trovarsi dietro una NAT simmetrica o un firewall. Probabilmente, sar? possibile 
connettersi ad utenti connessi direttamente a internet o dietro restricted cone 
NAT
-IPDetectorPluginManager.symmetricPS=Il nodo si trova dietro una NAT 
simmetrica. Queta ? una situazione particolarmente  particolarmente 
problematica: ? necessario configurare il forward delle porte. In caso 
contrario potrebbe risultare impossibile connettersi alla maggioranza dei nodi.
+IPDetectorPluginManager.suggestForwardTwoPortsWithLink=Potrebbe essere 
necessario configurare manualmente ${link}il forward delle porte${/link} Per 
porte nummero ${port1} e ${port2}, UDP. (questo messaggio pu? in alcuni casi 
continuare ad apparire per un po' di tempo dopo aver configurato il forward)
+IPDetectorPluginManager.symmetric=Dai rilevamenti appare che il nodo potrebbe 
trovarsi dietro una NAT simmetrica o un firewall. Probabilmente, sar? possibile 
connettersi ad utenti connessi direttamente a internet o dietro restricted cone 
NAT
+IPDetectorPluginManager.symmetricPS=Il nodo si trova dietro una NAT 
simmetrica. Queta ? una situazione particolarmente  particolarmente 
problematica: ? necessario configurare il forward delle porte. In caso 
contrario potrebbe risultare impossibile connettersi alla maggioranza dei nodi.
 IPDetectorPluginManager.symmetricTitle=Rilevato firewall simmetrico
-IPUndetectedUserAlert.detecting=Freenet sta cercando in questo momento di 
rilevare l'indirizzo IP esterno. Il protrarsi della durata di questa operazione 
oltre il limite di pochi minuti ? indicativo di problemi.
+IPUndetectedUserAlert.detecting=Freenet sta cercando in questo momento di 
rilevare l'indirizzo IP esterno. Il protrarsi della durata di questa operazione 
oltre il limite di pochi minuti ? indicativo di problemi.
 IPUndetectedUserAlert.detectingShort=Indirizzo IP esterno in corso di 
rilevamento.
-IPUndetectedUserAlert.detectingWithConfigLink=Freenet sta rilevando 
l'indirizzo IP esterno. Se l'operazione dura pi? di qualche minuto si pu? 
presumere che qualcosa non stia andando come dovrebbe e si pu? provare ad usare 
il Suggerimento Temporaneo per l'Indirizzo IP ${link}parametro di 
configurazione${/link}.
+IPUndetectedUserAlert.detectingWithConfigLink=Freenet sta rilevando 
l'indirizzo IP esterno. Se l'operazione dura pi? di qualche minuto si pu? 
presumere che qualcosa non stia andando come dovrebbe e si pu? provare ad usare 
il Suggerimento Temporaneo per l'Indirizzo IP ${link}parametro di 
configurazione${/link}.
 IPUndetectedUserAlert.suggestForwardPort=Sarebbe opportuno configurare il port 
forward sul router per le porte ${port1} e ${port2} (UDP) in modo da facilitare 
le connessioni.
 IPUndetectedUserAlert.suggestForwardTwoPorts=Sarebbe opportuno configurare il 
port forward sul router per le porte ${port1} e ${port2} (UDP) in modo da 
facilitare le connessioni.
-IPUndetectedUserAlert.unknownAddress=Non ? stato possibile rilevare 
l'indirizzo IP esterno (o l'indirizzo IP del NAT box o del firewall). Si pu? 
comunque scambiare refs con altri utenti, ma sar? possibile connettersi 
solamente a nodi che non si trovino a loro volta dietro NAT o firewall. Non 
appaena ci si sar? connessi in questo modo ad almeno un altro utente, sar? 
possibile determinare l'indirizzo IP esterno. Si pu? suggerire al nodo 
l'indirizzo IP esterno usando 'Suggerimento Temporaneo per l'Indirizzo IP' 
${link}parametro di configurazione${/link}
-IPUndetectedUserAlert.unknownAddressShort=Non ? stato possibile rilevare 
l'indirizzo IP. Potrebbero verificarsi problemi di connessione.
+IPUndetectedUserAlert.unknownAddress=Non ? stato possibile rilevare 
l'indirizzo IP esterno (o l'indirizzo IP del NAT box o del firewall). Si pu? 
comunque scambiare refs con altri utenti, ma sar? possibile connettersi 
solamente a nodi che non si trovino a loro volta dietro NAT o firewall. Non 
appaena ci si sar? connessi in questo modo ad almeno un altro utente, sar? 
possibile determinare l'indirizzo IP esterno. Si pu? suggerire al nodo 
l'indirizzo IP esterno usando 'Suggerimento Temporaneo per l'Indirizzo IP' 
${link}parametro di configurazione${/link}
+IPUndetectedUserAlert.unknownAddressShort=Non ? stato possibile rilevare 
l'indirizzo IP. Potrebbero verificarsi problemi di connessione.
 IPUndetectedUserAlert.unknownAddressTitle=Indirizzo esterno sconosciuto
-IPUndetectedUserAlert.unknownAddressWithConfigLink=Freenet non ha potuto 
rilevare l'indirizzo IP esterno (o l'indirizzo IP del NAT box o firewall). E' 
comunque possibile scambiare referenze con altri utenti, ma la connessione 
avverr? soltanto se l'altra parte non ? a sua volta dietro NAT o firewall. 
Appena connesso ad almeno un utente in questo modo, Freenet riuscit? a 
determinare l'indirizzo IP esterno.E' possibile suggerire al nodo l'IP esterno 
usando il campo 'suggerimento provvisorio per l'indirizzo IP'  ${link}parametro 
di configurazione${/link}. Sarebbe inlotre auspicabile configurare il forward 
UDP per la porta ${port} sul router, in modo da rendere pi? facili le 
connessioni
-InsertException.longError.1=Caller ha fornito una URI che non ? possibile 
utilizzare"
+IPUndetectedUserAlert.unknownAddressWithConfigLink=Freenet non ha potuto 
rilevare l'indirizzo IP esterno (o l'indirizzo IP del NAT box o firewall). E' 
comunque possibile scambiare referenze con altri utenti, ma la connessione 
avverr? soltanto se l'altra parte non ? a sua volta dietro NAT o firewall. 
Appena connesso ad almeno un utente in questo modo, Freenet riuscit? a 
determinare l'indirizzo IP esterno.E' possibile suggerire al nodo l'IP esterno 
usando il campo 'suggerimento provvisorio per l'indirizzo IP'  ${link}parametro 
di configurazione${/link}. Sarebbe inlotre auspicabile configurare il forward 
UDP per la porta ${port} sul router, in modo da rendere pi? facili le 
connessioni
+InsertException.longError.1=Caller ha fornito una URI che non ? possibile 
utilizzare"
 InsertException.longError.10=Annullato dall'utente
 InsertException.longError.11=Meta string (probabilmente '/') usata nella URI
 InsertException.longError.12=Errore di formattazione nel blob binario
 InsertException.longError.2=Errore bucket interno: potrebbe trattarsi di 
mancanza di spazio sufficiente su disco rigido o di mancanza di autorizzazione.
 InsertException.longError.3=Errore interno
-InsertException.longError.4=Un nodo 'a valle' (downstream) ? andato in time 
out o ? stato gravemente sovraccaricato
-InsertException.longError.5=Non ? stato possibile propagare questa inserzione 
su un numero sufficiente di nodi (questo e' normale su network di piccole 
dimensioni: si pu? provare a richiamare il file comunque)
+InsertException.longError.4=Un nodo 'a valle' (downstream) ? andato in time 
out o ? stato gravemente sovraccaricato
+InsertException.longError.5=Non ? stato possibile propagare questa inserzione 
su un numero sufficiente di nodi (questo e' normale su network di piccole 
dimensioni: si pu? provare a richiamare il file comunque)
 InsertException.longError.6=Errori fatali in un'inserzione di splitfiles
-InsertException.longError.7=Non ? stato possibile inserire splitfile: numero 
di tentativi esaurito (errori nonfatali)
-InsertException.longError.8=Non ? stato possibile far partire l'inserzione dal 
nodo locale.
-InsertException.longError.9=L' inserzione ? in conflitto con dati 
pre-esistenti e differenti alla stessa chiave
+InsertException.longError.7=Non ? stato possibile inserire splitfile: numero 
di tentativi esaurito (errori nonfatali)
+InsertException.longError.8=Non ? stato possibile far partire l'inserzione dal 
nodo locale.
+InsertException.longError.9=L' inserzione ? in conflitto con dati 
pre-esistenti e differenti alla stessa chiave
 InsertException.shortError.1=URI non valida
 InsertException.shortError.10=Annullato
 InsertException.shortError.11=Meta string usata nella chiave
@@ -569,39 +565,39 @@
 InsertException.shortError.5=Percorso non trovato
 InsertException.shortError.6=Alcuni block sono falliti in modo fatale
 InsertException.shortError.7=Alcuni block hanno esaurito il numero di 
tentativi a disposizione
-InsertException.shortError.8=Non ? stato possibile inoltrare la richiesta
+InsertException.shortError.8=Non ? stato possibile inoltrare la richiesta
 InsertException.shortError.9=Conflitto con dati esistenti
-IntOption.parseError=Il valore specificato non pu? essere interpretato come 
32-bit integer : ${val}
-InvalidAddressOverrideUserAlert.unknownAddress=Freenet ha rilevato che il 
valore attualmente in uso per ipAddessOverride non ? valido in quanto non 
conforme alla sintassi appropriata per un hostname n? per un indirizzo IPv4 o 
IPv6 (in accordo con l'implementazione corrente della funzione che controlla la 
sintassi per indirizzi IPv6)
+IntOption.parseError=Il valore specificato non pu? essere interpretato come 
32-bit integer : ${val}
+InvalidAddressOverrideUserAlert.unknownAddress=Freenet ha rilevato che il 
valore attualmente in uso per ipAddessOverride non ? valido in quanto non 
conforme alla sintassi appropriata per un hostname n? per un indirizzo IPv4 o 
IPv6 (in accordo con l'implementazione corrente della funzione che controlla la 
sintassi per indirizzi IPv6)
 InvalidAddressOverrideUserAlert.unknownAddressShort=L' indirizzo IP impostato 
manualmente (ipAddressOverride) non funziona. si prega di correggerlo.
 InvalidAddressOverrideUserAlert.unknownAddressTitle=Valore Override Indirizzo 
non Valido
-InvalidAddressOverrideUserAlert.unknownAddressWithConfigLink=Freenet ha 
rilevato che il valore attualmente in uso per ipAddessOverride non ? valido in 
quanto non conforme alla sintassi appropriata per un hostname n? per un 
indirizzo IPv4 o IPv6 (in accordo con l'implementazione corrente della funzione 
che controlla la sintassi per indirizzi IPv6) E' possibile correggere l' 
Override indirizzo IP ${link}configuration parameter${/link}.
-JPEGFilter.notJpeg=Le dimensioni del file che si sta cercando di richiamare 
sono troppo ridotte perch? possa trattarsi di un'immagine JPEG. Potrebbe essere 
un file in un altro formato e il browser potrebbe fare qualcosa di sbagliato a 
causa della mancata corrispondenza; il file ? stato pertanto bloccato.
+InvalidAddressOverrideUserAlert.unknownAddressWithConfigLink=Freenet ha 
rilevato che il valore attualmente in uso per ipAddessOverride non ? valido in 
quanto non conforme alla sintassi appropriata per un hostname n? per un 
indirizzo IPv4 o IPv6 (in accordo con l'implementazione corrente della funzione 
che controlla la sintassi per indirizzi IPv6) E' possibile correggere l' 
Override indirizzo IP ${link}configuration parameter${/link}.
+JPEGFilter.notJpeg=Le dimensioni del file che si sta cercando di richiamare 
sono troppo ridotte perch? possa trattarsi di un'immagine JPEG. Potrebbe essere 
un file in un altro formato e il browser potrebbe fare qualcosa di sbagliato a 
causa della mancata corrispondenza; il file ? stato pertanto bloccato.
 JPEGFilter.tooShort=File troppo piccolo per un JPEG.
 JPEGFilter.tooShortTitle=Troppo corto
-KnownUnsafeContentTypeException.dangerousInlines=Contenuto di questo tipo pu? 
includere immagini o video che vengono caricati direttamente da internet, 
esponendo l'indirizzo IP dell'utente e quindi compromettendone gravemente 
l'anonimato.
+KnownUnsafeContentTypeException.dangerousInlines=Contenuto di questo tipo pu? 
includere immagini o video che vengono caricati direttamente da internet, 
esponendo l'indirizzo IP dell'utente e quindi compromettendone gravemente 
l'anonimato.
 KnownUnsafeContentTypeException.dangerousInlinesLabel=Collegamenti esterni 
pericolosi:
-KnownUnsafeContentTypeException.dangerousLinks=Contenuto di questo tipo pu? 
includere dei link a pagine pubblicate al di fuori di Freenet. Cliccando su 
tali link (e possono essere camuffati) si espone il proprio indirizzo IP, 
compromettendo l'anonimato.
+KnownUnsafeContentTypeException.dangerousLinks=Contenuto di questo tipo pu? 
includere dei link a pagine pubblicate al di fuori di Freenet. Cliccando su 
tali link (e possono essere camuffati) si espone il proprio indirizzo IP, 
compromettendo l'anonimato.
 KnownUnsafeContentTypeException.dangerousLinksLabel=Link pericolosi:
-KnownUnsafeContentTypeException.dangerousMetadata=Contenuto di questo tipo pu? 
includere metadati, i quali possono essere visualizzati da alcuni browser o con 
l'aiuto di altri programmi: i metadati possono contenere link o immagini 
caricate direttamente da internet, che possono compromettere l'anonimato.
+KnownUnsafeContentTypeException.dangerousMetadata=Contenuto di questo tipo pu? 
includere metadati, i quali possono essere visualizzati da alcuni browser o con 
l'aiuto di altri programmi: i metadati possono contenere link o immagini 
caricate direttamente da internet, che possono compromettere l'anonimato.
 KnownUnsafeContentTypeException.dangerousMetadataLabel=Metadati pericolosi:
-KnownUnsafeContentTypeException.dangerousScripts=Contenuto di questo tipo pu? 
includere script pericolosi che quando eseguiti possono compromettere 
l'anonimato dell'utente connettendosi direttamente al web o compromettere la 
sicurezza in altro modo.
+KnownUnsafeContentTypeException.dangerousScripts=Contenuto di questo tipo pu? 
includere script pericolosi che quando eseguiti possono compromettere 
l'anonimato dell'utente connettendosi direttamente al web o compromettere la 
sicurezza in altro modo.
 KnownUnsafeContentTypeException.dangerousScriptsLabel=Scripting pericoloso:
 KnownUnsafeContentTypeException.knownUnsafe=Questo e' un MIME type 
potenzialmente pericoloso. Se il nodo lo lascia passare, il browser potrebbe 
fare qualcosa capace di compromettere l'anonimato dell'utente, esponendone 
l'indirizzo IP in relazione a questa pagina. In particolare:
-KnownUnsafeContentTypeException.noFilter=Non ? disponibile alcun filtro per 
questo tipo di dati; ? necessario quindi prendere tutte le possibili 
precauzioni.
+KnownUnsafeContentTypeException.noFilter=Non ? disponibile alcun filtro per 
questo tipo di dati; ? necessario quindi prendere tutte le possibili 
precauzioni.
 KnownUnsafeContentTypeException.title=Conosciuto come pericoloso: Tipo ${type}
 LocalFileInsertToadlet.checkPathExist=Accerta l'esistenza del percorso 
specificato.
 LocalFileInsertToadlet.checkPathIsDir=Controlla che il percorso specificato 
sia una directory
 LocalFileInsertToadlet.checkPathReadable=Controlla che il percorso specificato 
sia leggibile dall'utente che sta utilizzando il nodo.
-LocalFileInsertToadlet.dirAccessDenied=L'accesso a questa directory ? 
interdetto
-LocalFileInsertToadlet.dirCannotBeRead=Non ? stato possibile leggere dalla 
directory "${path}".
+LocalFileInsertToadlet.dirAccessDenied=L'accesso a questa directory ? 
interdetto
+LocalFileInsertToadlet.dirCannotBeRead=Non ? stato possibile leggere dalla 
directory "${path}".
 LocalFileInsertToadlet.fileHeader=File
 LocalFileInsertToadlet.insert=Inserisci
 LocalFileInsertToadlet.listing=Elenco directory ${path}
 LocalFileInsertToadlet.listingTitle=Listing di ${path}
 LocalFileInsertToadlet.sizeHeader=Dimensioni
-LogConfigHandler.detaildPriorityThreshold=Soglie di priorit? dettagliate
-LogConfigHandler.detaildPriorityThresholdLong=Soglie di priorit? dettagliate. 
Esempio: freenet:normal,freenet.node:minor
+LogConfigHandler.detaildPriorityThreshold=Soglie di priorit? dettagliate
+LogConfigHandler.detaildPriorityThresholdLong=Soglie di priorit? dettagliate. 
Esempio: freenet:normal,freenet.node:minor
 LogConfigHandler.dirName=Directory dei log
 LogConfigHandler.dirNameLong=Directory contenente i log files
 LogConfigHandler.enabled=Abilita Log
@@ -612,28 +608,28 @@
 LogConfigHandler.maxCachedLinesLong=Numero massimo di righe nella RAM cache
 LogConfigHandler.maxZippedLogsSize=Spazio massimo per vecchi log
 LogConfigHandler.maxZippedLogsSizeLong=Spazio massimo su disco utilizzabile da 
vecchi log.
-LogConfigHandler.minLoggingPriority=Priorit? minima dei messaggi da iscrivere 
nei log.
-LogConfigHandler.minLoggingPriorityLong=Minima priorit? dei messaggi che 
vengono iscritti nel log file. Le opzioni sono: minor, normal, error, 
nell'ordine dalla meno alla pi? verbosa.
+LogConfigHandler.minLoggingPriority=Priorit? minima dei messaggi da iscrivere 
nei log.
+LogConfigHandler.minLoggingPriorityLong=Minima priorit? dei messaggi che 
vengono iscritti nel log file. Le opzioni sono: minor, normal, error, 
nell'ordine dalla meno alla pi? verbosa.
 LogConfigHandler.rotationInterval=Intervallo di rotazione dei log
 LogConfigHandler.rotationIntervalLong=Intervallo di rotazione dei log - 
Periodo di tempo allo scadere del quale i log vengono ruotati. Gli ultimi due 
log files vengono conservati (current.log e prev.log) insieme a diversi log 
file compressi fino al massimo impostato in maxZippedLogsSize
-LoggerHook.unrecognizedPriority=Nome di priorit? non riconosciuto: ${name}.
-LongOption.parseError=Il valore specificato non pu? essere interpretato come 
64-bit integer : ${val}
-MeaningfulNodeNameUserAlert.noNodeNick=Non ? stato possibile trovare il 
nickname da utilizzare. Usare qui un indirizzo e-mail o un nickname IRC ? 
generalmente una buona idea in quanto consente ai peer di identificare il nodo. 
(nota che soltanto i peer darknet elencati alla pagina Amici potranno vedere il 
nome del nodo, che resta invece invisibile ai peer Opennet)
+LoggerHook.unrecognizedPriority=Nome di priorit? non riconosciuto: ${name}.
+LongOption.parseError=Il valore specificato non pu? essere interpretato come 
64-bit integer : ${val}
+MeaningfulNodeNameUserAlert.noNodeNick=Non ? stato possibile trovare il 
nickname da utilizzare. Usare qui un indirizzo e-mail o un nickname IRC ? 
generalmente una buona idea in quanto consente ai peer di identificare il nodo. 
(nota che soltanto i peer darknet elencati alla pagina Amici potranno vedere il 
nome del nodo, che resta invece invisibile ai peer Opennet)
 MeaningfulNodeNameUserAlert.noNodeNickShort=Nome nodo non definito.
 MeaningfulNodeNameUserAlert.noNodeNickTitle=Nome nodo non definito.
 N2NTMToadlet.composingMessageLabel=Messaggio N2NTM  da inviare ai seguenti 
nodi:
 N2NTMToadlet.delayed=Il nodo interressato sta temporaneamente respingendo 
richieste; il messaggio potrebbe giungere in lieve ritardo.
 N2NTMToadlet.delayedTitle=Differito
-N2NTMToadlet.failed=Il peer interessato non ? connesso in questo momento: non 
? stato possibile inviare il messaggio
+N2NTMToadlet.failed=Il peer interessato non ? connesso in questo momento: non 
? stato possibile inviare il messaggio
 N2NTMToadlet.failedTitle=Fallito
 N2NTMToadlet.friends=Amici
 N2NTMToadlet.homepage=Homepage
 N2NTMToadlet.noSuchFileOrCannotRead=Trasferimento fallito:File inesistente o 
illegibile.
 N2NTMToadlet.peerName=Nome del Peer
 N2NTMToadlet.peerNotFoundTitle=Peer non trovato
-N2NTMToadlet.peerNotFoundWithHash=Non ? stato possibile trovare il peer con 
hash code \u201c${hash}\u201d
+N2NTMToadlet.peerNotFoundWithHash=Non ? stato possibile trovare il peer con 
hash code \u201c${hash}\u201d
 N2NTMToadlet.processingSend=Invio messaggio in corso
-N2NTMToadlet.queued=In attesa: Il peer interessato non ? connesso in questo 
momento. Il messaggio ? stato posto in attesa e verr? spedito al pi? presto 
possibile
+N2NTMToadlet.queued=In attesa: Il peer interessato non ? connesso in questo 
momento. Il messaggio ? stato posto in attesa e verr? spedito al pi? presto 
possibile
 N2NTMToadlet.queuedTitle=Aggiunto alla Coda
 N2NTMToadlet.returnToFriends=Torna alla lista degli Amici
 N2NTMToadlet.returnToNodeHomepage=Torna alla homepage del nodo
@@ -644,30 +640,30 @@
 N2NTMToadlet.sentTitle=Inviato
 N2NTMToadlet.tooLong=I messaggi N2NTM possono contenere fino a un massimo di 
1024 caratteri
 N2NTMToadlet.tooLongTitle=Troppo Lungo
-N2NTMToadlet.unauthorized=L'accesso a questa pagina ? interdetto
+N2NTMToadlet.unauthorized=L'accesso a questa pagina ? interdetto
 N2NTMUserAlert.delete=Elimina
 N2NTMUserAlert.header=Da: ${from} (scritto ${composed} | inviato ${sent} | 
ricevuto ${received})
 N2NTMUserAlert.headerShort=Messaggio da ${from}
 N2NTMUserAlert.reply=Rispondi
 N2NTMUserAlert.title=Messaggio di testo da nodo a nodo (N2NTM) ${number} da: 
${peername} (${peer})
-Node.acceptSeedConnections=Selezionando "vero" il nodo accetter? connessioni 
da nodi che intendono usare la modalit? insicura (opennet) e li aiuter? a 
connettersi alla rete Freenet. Ci? rende possibile la connessione a qualsiasi 
nodo in possesso della referenza ma limitata dall'annuncio: le richieste di 
connessione sono indirizzate solo ai nodi aggiunti tramite annuncio. Il nodo 
locale potrebbe essere incluso a meno che non abbia gi? molti peer opennet 
(visibili alla pagina "Sconosciuti")
+Node.acceptSeedConnections=Selezionando "vero" il nodo accetter? connessioni 
da nodi che intendono usare la modalit? insicura (opennet) e li aiuter? a 
connettersi alla rete Freenet. Ci? rende possibile la connessione a qualsiasi 
nodo in possesso della referenza ma limitata dall'annuncio: le richieste di 
connessione sono indirizzate solo ai nodi aggiunti tramite annuncio. Il nodo 
locale potrebbe essere incluso a meno che non abbia gi? molti peer opennet 
(visibili alla pagina "Sconosciuti")
 Node.acceptSeedConnectionsShort=Abilita seednode
 Node.alwaysAllowLocalAddresses=Permettere sempre la connessione a nodi via 
indirizzi locali?
-Node.alwaysAllowLocalAddressesLong=Se impostato su "vero" il nodo cercher? di 
connettersi ad altri nodi usando il loro indirizzo locale (localhost, LAN) 
oltre al loro indirizzo IP pubblico. Se questa opzione non e' impostata, si pu? 
comunque abilitarla separatamente per singoli peer darknet (ma non per i peer 
opennet). Impostare questa opzione se ci si vuole connettere ad altri nodi 
sulla stessa rete locale (LAN) o che girano sullo stesso computer, e non far 
caso alle referenze "bogus" ("scr?use") che possono far mandare al nodo 
pacchetti UDP alle macchine sulla rete locale.
+Node.alwaysAllowLocalAddressesLong=Se impostato su "vero" il nodo cercher? di 
connettersi ad altri nodi usando il loro indirizzo locale (localhost, LAN) 
oltre al loro indirizzo IP pubblico. Se questa opzione non e' impostata, si pu? 
comunque abilitarla separatamente per singoli peer darknet (ma non per i peer 
opennet). Impostare questa opzione se ci si vuole connettere ad altri nodi 
sulla stessa rete locale (LAN) o che girano sullo stesso computer, e non far 
caso alle referenze "bogus" ("scr?use") che possono far mandare al nodo 
pacchetti UDP alle macchine sulla rete locale.
 Node.assumeNATed=Presumere che la porta non sia forwardata.
-Node.assumeNATedLong=Dare per scontato che la porta sia dietro NAT e non 
forwardata? In questo caso il nodo mander? handshake ogni 10-30 secondi.
+Node.assumeNATedLong=Dare per scontato che la porta sia dietro NAT e non 
forwardata? In questo caso il nodo mander? handshake ogni 10-30 secondi.
 Node.bandwidthLimitMustBePositiveOrMinusOne=Il valore dell'ampiezza di banda 
deve essere positivo o -1
 Node.bindTo=Indirizzo IP
 Node.bindToLong=Indirizzo IP
-Node.buggyJVM=La JVM attualmente in uso (${version}) ? una versione 
notoriamente afflitta da 'bug' che pu? produrre OutOfMemoryError anche con 
molta memoria ancora a disposizione. Si raccomanda di aggiornare Java. La 
versione consigliata ? Sun Java 1.6, ma ? possibile usare anche 1.4.2 o 1.5.
-Node.buggyJVMShort=Freenet sta attualmente utilizzando Java versione 
${version}, che ? notoriamente afflitta da p'bug' pericolosi. Si prega di 
aggiornare Java al pi? presto possibile.
+Node.buggyJVM=La JVM attualmente in uso (${version}) ? una versione 
notoriamente afflitta da 'bug' che pu? produrre OutOfMemoryError anche con 
molta memoria ancora a disposizione. Si raccomanda di aggiornare Java. La 
versione consigliata ? Sun Java 1.6, ma ? possibile usare anche 1.4.2 o 1.5.
+Node.buggyJVMShort=Freenet sta attualmente utilizzando Java versione 
${version}, che ? notoriamente afflitta da p'bug' pericolosi. Si prega di 
aggiornare Java al pi? presto possibile.
 Node.buggyJVMTitle=Avvertennza JVM soggetta a 'bug'
-Node.buggyJVMWithLink=La JVM in uso (${version}) ? notoriamente 
${link}difettosa${/link}. Pu? produrre errori tipo OutOfMemoryError anche con 
molta memoria ancora disponibile. Sarebbe auspicabile aggiornare almeno a Sun 
Java 1.4.2_13, 1.5.0_10 o 1.6 (quest'ultima ? la versione consigliata).
+Node.buggyJVMWithLink=La JVM in uso (${version}) ? notoriamente 
${link}difettosa${/link}. Pu? produrre errori tipo OutOfMemoryError anche con 
molta memoria ancora disponibile. Sarebbe auspicabile aggiornare almeno a Sun 
Java 1.4.2_13, 1.5.0_10 o 1.6 (quest'ultima ? la versione consigliata).
 Node.bwlimitMustBePositive=Il limite dell'ampiezza di banda deve essere 
positivo
 Node.databaseMemory=Memoria massima utilizzabile dal datastore
 Node.databaseMemoryLong=Uso massimo della memoria del database contenente 
indici del magazzino dati (datastore). 0 significa nessun limite (non supera 
comunque il 30% circa della memoria massima)
 Node.deadlockTitle=Deadlocking probabilmente dovuto ad una combinazione di JVM 
e kernel che da luogo a "bug".
-Node.deadlockWarning=ATTENZIONE: E' stato rilevato l'uso di Sun JVM con NPTL. 
Ci? pu? produrre il "congelamento" del nodo a causa della JVM che perde un 
lock. Per ovviare a tale inconveniente ? necessatio disabilitare NPTL 
impostando la variabile ambientale LD_ASSUME_KERNEL=2.4.1. Le versioni pi? 
recenti di Freenet installer dovrebbero gi? esserne provviste; reinstallare, o 
modificare il file run.sh 
(https://emu.freenetproject.org/svn/trunk/apps/installer/installclasspath/run.sh).
 Su alcuni sistemi pu? essere necessario installare le pthreads libraries 
perch? questo funzioni. Nota che il nodo cercherebbe di riavviarsi 
automaticamente se un tale deadlock occorresse, ma questa funzione non ? ancora 
pienamente affidabile, e richiede tempo.
+Node.deadlockWarning=ATTENZIONE: E' stato rilevato l'uso di Sun JVM con NPTL. 
Ci? pu? produrre il "congelamento" del nodo a causa della JVM che perde un 
lock. Per ovviare a tale inconveniente ? necessatio disabilitare NPTL 
impostando la variabile ambientale LD_ASSUME_KERNEL=2.4.1. Le versioni pi? 
recenti di Freenet installer dovrebbero gi? esserne provviste; reinstallare, o 
modificare il file run.sh 
(https://emu.freenetproject.org/svn/trunk/apps/installer/installclasspath/run.sh).
 Su alcuni sistemi pu? essere necessario installare le pthreads libraries 
perch? questo funzioni. Nota che il nodo cercherebbe di riavviarsi 
automaticamente se un tale deadlock occorresse, ma questa funzione non ? ancora 
pienamente affidabile, e richiede tempo.
 Node.disableHangCheckers=Disabilita tutti gli hang checker
 Node.disableHangCheckersLong=Disabilita tutte le funzioni hang 
checkers/watchdog. Impostare per fare il profiling di Fred.
 Node.disablePHTLS=Disabilita HTL probabilistico
@@ -686,17 +682,17 @@
 Node.enableSwappingLong=Abilita scambio di locazione? (NON DISABILITARE! Utile 
solo in alcune simulazioni).
 Node.enableULPRDataPropagation=Abilita propagazione dati ULPR?
 Node.enableULPRDataPropagationLong=Abilita propagazione rapida di chiavi 
richieste recentemente ai nodi che le hanno richieste quando i dati sono stati 
finalmente trovati? (Richieste Persistenti Ultra-Leggere)
-Node.errorApplyingConfig=Si ? verificato un errore durante l'applicazione 
della nuova configurazione : ${error}
+Node.errorApplyingConfig=Si ? verificato un errore durante l'applicazione 
della nuova configurazione : ${error}
 Node.extraPeerDir=Directory dei dati extra peer
 Node.extraPeerDirLong=Directory dove conservare dati extra
 Node.forceBigShrink=Esegui immediatamente grosse riduzioni di dimensione dello 
store
-Node.forceBigShrinkLong=Determina se eseguire immediatamente le riduzioni di 
dimensione in misura superiore al 10% del magazzino (store), piuttosto che 
aspettare il prossimo riavvio del nodo. Le riduzioni on-line non preservano i 
dati utilizzati per ultimi quindi l'uso di questa opzione non ? raccomandato; 
da usarsi solo nel caso in cui sia desiderabile un risultato immediato.
+Node.forceBigShrinkLong=Determina se eseguire immediatamente le riduzioni di 
dimensione in misura superiore al 10% del magazzino (store), piuttosto che 
aspettare il prossimo riavvio del nodo. Le riduzioni on-line non preservano i 
dati utilizzati per ultimi quindi l'uso di questa opzione non ? raccomandato; 
da usarsi solo nel caso in cui sia desiderabile un risultato immediato.
 Node.inBWLimit=Limite ampiezza di banda in entrata (bytes per secondo)
 Node.inBWLimitLong=Limite dell'ampiezza di banda in entrata (bytes/sec); il 
nodo cerca di non eccedere tale limite; -1 siglifica quattro volte il limite 
impostato per l'ampiezza di banda in uscita (outputBandwidthLimit)
 Node.invalidStoreSize=Il datastore (magazzino dati) deve essere di dimensioni 
uguali o superiori a 32MB
-Node.java14ShortText=Tra breve non sara pi? possibile operare un nodo Freenet 
su Java 1.4. Si prega di aggiornare a 1.5 o 1.6
+Node.java14ShortText=Tra breve non sara pi? possibile operare un nodo Freenet 
su Java 1.4. Si prega di aggiornare a 1.5 o 1.6
 Node.java14Text=Freenet sta girando su una versione 1.4 di Java. Si prega di 
aggiornare almeno a Java 1.5. Gli aggiornamenti automatici di Freenet sono 
stati temporaneamente disabilitati in quanto versioni future potrebbero non non 
girare del tutto.
-Node.java14Title=Freenet non ? pi? compatibile con Java 1.4
+Node.java14Title=Freenet non ? pi? compatibile con Java 1.4
 Node.l10nLanguage=Lingua dell' interfaccia grafica
 Node.l10nLanguageLong=Cambia la lingua in cui messaggi sono visualizzati. 
Alcune frasi e messaggi saranno visibili in versione tradotta solo dopo il 
prossimo riavvio del nodo.
 Node.maxHTL=HTL massimo
@@ -710,80 +706,70 @@
 Node.nodeName=Nome del nodo
 Node.nodeNameLong=Nome del nodo. E' visibile solo agli Amici (darknet peer), 
mentre gli Sconosciuti (opennet peer) non potranno vederlo.
 Node.notUsingSunVM=E' stata rilevata una JVM ${vendor} ${version} che potrebbe 
influire sul corretto funzionamento del nodo. Se possibile, installare Sun java 
disponibile presso http://www.java.com/getjava
-Node.notUsingSunVMShort=Freenet sta attualmente utilizzando JVM (Java Virtual 
Machine) diversa da Sun, che ? quella raccomandata. Si prega di scaricare ed 
installare la versione corrente di Sun Java JRE (Java Runtime Environment)
+Node.notUsingSunVMShort=Freenet sta attualmente utilizzando JVM (Java Virtual 
Machine) diversa da Sun, che ? quella raccomandata. Si prega di scaricare ed 
installare la versione corrente di Sun Java JRE (Java Runtime Environment)
 Node.notUsingSunVMTitle=Il nodo non sta usando una JVM della Sun
-Node.notUsingWrapper=Il nodo sta girando senza il wrapper. Ci? ? generalmente 
sconsigliabile. Il nodo non potr? riavviare s? stesso e quindi l'aggiornamento 
automatico non potr? funzionare. Inoltre, se la JVM se ne dovesse andare nel 
"limbo" non sar? possibile riavviare automaticamente nemmeno qiuella. Non 
verranno generati stack dump in alcuni posti e quindi debugging sar? pi? 
difficile.
-Node.notUsingWrapperShort=Freenet sta girando senza wrapper. Questo non ? 
raccomandato.
+Node.notUsingWrapper=Il nodo sta girando senza il wrapper. Ci? ? generalmente 
sconsigliabile. Il nodo non potr? riavviare s? stesso e quindi l'aggiornamento 
automatico non potr? funzionare. Inoltre, se la JVM se ne dovesse andare nel 
"limbo" non sar? possibile riavviare automaticamente nemmeno qiuella. Non 
verranno generati stack dump in alcuni posti e quindi debugging sar? pi? 
difficile.
+Node.notUsingWrapperShort=Freenet sta girando senza wrapper. Questo non ? 
raccomandato.
 Node.notUsingWrapperTitle=Il nodo non sta usando il wrapper!
 Node.oneConnectionPerIP=Limita ad una connessione per indirizzo?
-Node.oneConnectionPerIPLong=Non permettere pi? di una connessione per 
indirizzo? Ci? rende leggermente pi? difficile un attacco eseguito 
connettendosi al nodo pi? volte con diverse identit? in modo da dominarne il 
routing (instradamento) e rendere pi? facile raccogliere dati con lo 
"harvesting" (lett: "il raccolto", in agricoltura). Questa opzione impedisce 
che un peer sia connesso al nodo sia su darknet che su opennet.
-Node.opennetEnabled=Abilita Modalit? Insicura (connette automaticamente a nodi 
gestiti da Sconosciuti)
-Node.opennetEnabledLong=Abilita Modalit? Insicura? (detta anche Opennet) 
Abilitando questa opzione il nodo scambier? automaticamente referenze on altri 
nodi. Ci? rende facilmente osservabile dall'esterno il fatto che su questo 
computer sta girando un nodo Freenet, facilitando attacchi di diversi tipi. 
Avendone la possibilit?, l'opzione migiore ? quella di connettersi soltanto ad 
utenti conosciuti ed addifabili (Darknet peer, vedi pagina Amici)
+Node.oneConnectionPerIPLong=Non permettere pi? di una connessione per 
indirizzo? Ci? rende leggermente pi? difficile un attacco eseguito 
connettendosi al nodo pi? volte con diverse identit? in modo da dominarne il 
routing (instradamento) e rendere pi? facile raccogliere dati con lo 
"harvesting" (lett: "il raccolto", in agricoltura). Questa opzione impedisce 
che un peer sia connesso al nodo sia su darknet che su opennet.
+Node.opennetEnabled=Abilita Modalit? Insicura (connette automaticamente a nodi 
gestiti da Sconosciuti)
+Node.opennetEnabledLong=Abilita Modalit? Insicura? (detta anche Opennet) 
Abilitando questa opzione il nodo scambier? automaticamente referenze on altri 
nodi. Ci? rende facilmente osservabile dall'esterno il fatto che su questo 
computer sta girando un nodo Freenet, facilitando attacchi di diversi tipi. 
Avendone la possibilit?, l'opzione migiore ? quella di connettersi soltanto ad 
utenti conosciuti ed addifabili (Darknet peer, vedi pagina Amici)
 Node.outBWLimit=Limite dell'ampiezza di banda in uscita (bytes per secondo)
 Node.outBWLimitLong=Limite "duro" dell' ampiezza di banda in uscita 
(bytes/sec); di solito il nodo non eccede questo limite
 Node.passOpennetPeersThroughDarknet=Trasmetti referenze opennet attraverso 
darknet peer
-Node.passOpennetPeersThroughDarknetLong=Se impostata su "vero" referenze 
opennet verranno trasmesse attraverso peer darknet (ma MAI la referenza del 
nodo locale). In questo modo un nodo (nodo locale, o i suoi peer) pu? ottenere 
peer opennet dai suoi peer darknet. Questo ? utile perch? permette di 
riconnettersi in caso di perdita dei peer, per esempio dopo una lunga 
disconnessione, ma rende l'analisi del traffico leggermente pi? facile, quindi 
chi ? paranoico dovrebbe disabilitare questa opzione.
+Node.passOpennetPeersThroughDarknetLong=Se impostata su "vero" referenze 
opennet verranno trasmesse attraverso peer darknet (ma MAI la referenza del 
nodo locale). In questo modo un nodo (nodo locale, o i suoi peer) pu? ottenere 
peer opennet dai suoi peer darknet. Questo ? utile perch? permette di 
riconnettersi in caso di perdita dei peer, per esempio dopo una lunga 
disconnessione, ma rende l'analisi del traffico leggermente pi? facile, quindi 
chi ? paranoico dovrebbe disabilitare questa opzione.
 Node.port=Numero della porta FNP (UDP)
 Node.portLong=Porta UDP per le comunicazioni da nodo a nodo (Freenet Node 
Protocol)
 Node.publishOurPeersLocation=Trasmettere ai peer la locazione dei nostri peer?
-Node.publishOurPeersLocationLong=Trasmettere ai peer la locazione dei nostri 
peer? Ci? facilita il routing ma fornisce informazioni ad un potenziale 
avversario.
+Node.publishOurPeersLocationLong=Trasmettere ai peer la locazione dei nostri 
peer? Ci? facilita il routing ma fornisce informazioni ad un potenziale 
avversario.
 Node.routeAccordingToOurPeersLocation=Tenere conto nel routing della locazione 
dei peer dei nostri peer?
-Node.routeAccordingToOurPeersLocationLong=Usare per il routing la locazione 
dei peer dei nostri peer? Ci? facilita il routing ma potrebbe essere utile ad 
un potenziale avversario.
+Node.routeAccordingToOurPeersLocationLong=Usare per il routing la locazione 
dei peer dei nostri peer? Ci? facilita il routing ma potrebbe essere utile ad 
un potenziale avversario.
 Node.storeDirectory=Directory magazzino dati (store)
 Node.storeDirectoryLong=Directory contenente gli store file
-Node.storeMaxMemTooHigh=Impostare un valore superiore ad 80% della memoria RAM 
da destinare a BDB ? generalmente una pessima idea.
+Node.storeMaxMemTooHigh=Impostare un valore superiore ad 80% della memoria RAM 
da destinare a BDB ? generalmente una pessima idea.
 Node.storeSize=Dimensioni in bytes del magazzino dati (store)
 Node.storeSizeLong=Dimensioni del magazzino (store) in bytes
 Node.storeType=Tipo di magazzino dati (store). NON TOCCARE!!
-Node.storeTypeLong=Tipo di datastore. Attualmente pu? essere un indice bdb 
(usa un BerkeleyDBFreenetStore per l'indice, e mette i dati in dei file su 
disco), o ram (indice e dati in RAM). L'uso di ram ? riservato a persone 
competenti, e solo se c'e' memoria sufficiente a disposizione per tutti i dati 
(NOTA: in questo caso i dati NON verranno salvati all'arresto del nodo)
+Node.storeTypeLong=Tipo di datastore. Attualmente pu? essere un indice bdb 
(usa un BerkeleyDBFreenetStore per l'indice, e mette i dati in dei file su 
disco), o ram (indice e dati in RAM). L'uso di ram ? riservato a persone 
competenti, e solo se c'e' memoria sufficiente a disposizione per tutti i dati 
(NOTA: in questo caso i dati NON verranno salvati all'arresto del nodo)
 Node.swapRInterval=Intervallo tra le richieste di scambio (swap) in 
millisecondi
 Node.swapRIntervalLong=Intervallo tra richieste di scambio (swap) in 
millisecondi. Non toccare!
 Node.throttleLocalTraffic=Limitazione di banda su traffico locale
-Node.throttleLocalTrafficLong=Abilita limitazione di banda su traffico locale? 
Abilitando questa opzione,  la limitazione di banda avr? effetto anche sulla 
rete locale (LAN) e su localhost.
+Node.throttleLocalTrafficLong=Abilita limitazione di banda su traffico locale? 
Abilitando questa opzione,  la limitazione di banda avr? effetto anche sulla 
rete locale (LAN) e su localhost.
 Node.tooSmallMTU=MTU insufficiente
-Node.tooSmallMTULong=L' MTU della connessione sembra essere ${mtu} bytes. 
Freenet non pu? funzionare bene con un MTU minore di ${minMTU} bytes: le 
connessioni saranno inaffidabili e forse rallentate. Se possibile, si dovrebbe 
provvedere a risolvere il problema.
+Node.tooSmallMTULong=L' MTU della connessione sembra essere ${mtu} bytes. 
Freenet non pu? funzionare bene con un MTU minore di ${minMTU} bytes: le 
connessioni saranno inaffidabili e forse rallentate. Se possibile, si dovrebbe 
provvedere a risolvere il problema.
 Node.tooSmallMTUShort=Problema di connessione: MTU di connessione troppo basso 
per consentire a Freenet di funzionare correttamente. Potranno verificarsi dei 
problemi.
 Node.withAnnouncement=Permettere l'inserimento nella rete usando seednodes?
-Node.withAnnouncementLong=Permettere che il nodo si auto-inserisca nella rete 
Freenet usando seednodes? Questa opzione ? abilitata di default per motivi 
tecnici ma ? intrinsecamente insicura
-NodeClientCore.couldNotFindOrCreateDir=Non ? stato possibile trovare o creare 
la directory
-NodeClientCore.downloadAllowedDirs=Directory dove il download ? consentito
-NodeClientCore.downloadAllowedDirsLong=Si pu? usare una lista di directory 
dove dove il download e' permesso, separate da 'punto e virgola' (;). 
"downloads" significa downloadsDir, vuoto (nessuna directory specificata) 
significa che il download su disco non e' permesso, "all" significa download 
permessi in tutte le directory AVVERTENZA; Se impostato su "all" ("tutte"), 
ogni utente potr? scaricare files  in qualsiasi directory.
+Node.withAnnouncementLong=Permettere che il nodo si auto-inserisca nella rete 
Freenet usando seednodes? Questa opzione ? abilitata di default per motivi 
tecnici ma ? intrinsecamente insicura
+NodeClientCore.couldNotFindOrCreateDir=Non ? stato possibile trovare o creare 
la directory
+NodeClientCore.downloadAllowedDirs=Directory dove il download ? consentito
+NodeClientCore.downloadAllowedDirsLong=Si pu? usare una lista di directory 
dove dove il download e' permesso, separate da 'punto e virgola' (;). 
"downloads" significa downloadsDir, vuoto (nessuna directory specificata) 
significa che il download su disco non e' permesso, "all" significa download 
permessi in tutte le directory AVVERTENZA; Se impostato su "all" ("tutte"), 
ogni utente potr? scaricare files  in qualsiasi directory.
 NodeClientCore.downloadDir=Directory predefinita per i download
 NodeClientCore.downloadDirLong=Directory predefinita dove salvare i file 
scaricati
-NodeClientCore.encryptPersistentTempBuckets=Codifica i bucket di dati 
temporanei persistenti? NON MODIFICARE!
-NodeClientCore.encryptPersistentTempBucketsLong=Codifica i bucket di dati 
temporanei? In alcuni casi (p.es. se si usa HDD e swap encryption)potrebbe non 
essere necessario codificare (encrypting) i bucket di dati temporanei. IN CASO 
DI DUBBIO NON MODIFICARE
-NodeClientCore.encryptTempBuckets=Codifica buckets di dati temporanei? NON 
MODIFICARE!
-NodeClientCore.encryptTempBucketsLong=Codifica i bucket di dati temporanei? In 
alcuni casi (p.es. se si usa HDD e swap encryption)potrebbe non essere 
necessario codificare (encrypting) i bucket di dati temporanei. IN CASO DI 
DUBBIO NON MODIFICARE
 NodeClientCore.fileForClientStats=File contenente statistiche del client
 NodeClientCore.fileForClientStatsLong=File dove conservare le statistiche 
relative al client throttling (utilizzato per stabilire l'intervallo tra le 
richieste)
-NodeClientCore.lazyResume=Caricare completamente le richieste persistenti dopo 
aver completato l'avvio del nodo? (Fa maggiore uso di memoria ma avvia il nodo 
pi? velocemente)
-NodeClientCore.lazyResumeLong=Le richieste persistenti possono essere caricate 
durante l'avvio del nodo, oppure si possono scrivere i dati in memoria e 
caricarli completamente solo dopo che il processo di avvio ? terminato. Ci? 
riduce tempo di avviamento ma fa maggior uso di memoria.
-NodeClientCore.maxArchiveSize=Dimensione massima di ogni archivio
-NodeClientCore.maxArchiveSizeLong=Dimensione massima di ogni archivio
-NodeClientCore.maxRAMBucketSize=Dimensione massima di un RAMbucket
-NodeClientCore.maxRAMBucketSizeLong=Dimensione massima di un RAMBucket (i 
bucket di dimensioni maggiori verranno immagazzinati sul disco rigido come file)
+NodeClientCore.lazyResume=Caricare completamente le richieste persistenti dopo 
aver completato l'avvio del nodo? (Fa maggiore uso di memoria ma avvia il nodo 
pi? velocemente)
+NodeClientCore.lazyResumeLong=Le richieste persistenti possono essere caricate 
durante l'avvio del nodo, oppure si possono scrivere i dati in memoria e 
caricarli completamente solo dopo che il processo di avvio ? terminato. Ci? 
riduce tempo di avviamento ma fa maggior uso di memoria.
 NodeClientCore.maxUSKFetchers=Numero massimo di USK fetchers ammessi
 NodeClientCore.maxUSKFetchersLong=Numero massimo di USK fetchers ammessi
 NodeClientCore.maxUSKFetchersMustBeGreaterThanZero=Deve essere maggiore di zero
-NodeClientCore.movingTempDirOnTheFlyNotSupported=Non ? possible cambiare la 
directory dei file temporanei mentre il nodo ? in funzione
+NodeClientCore.movingTempDirOnTheFlyNotSupported=Non ? possible cambiare la 
directory dei file temporanei mentre il nodo ? in funzione
 NodeClientCore.persistentTempDir=Directory dei file temporanei persistenti
 NodeClientCore.persistentTempDirLong=Nome della directory dei file temporanei 
persistenti
-NodeClientCore.ramBucketPoolSize=Quantit? di RAM da dedicare ai bucket di dati 
temporanei
-NodeClientCore.ramBucketPoolSizeLong=Ammontare di memoria RAM da dedicare ai 
bucket di dati temporanei che sarebbero altrimenti immagazzinati su disco 
rigido. In cambio di pi? uso di memoria si ottiene pi? I/O.
-NodeClientCore.startingUp=Si prega di concedere a Freenet alcuni minuti per 
completare il processo di avviamento. Nel frattempo alcune funzioni non saranno 
disponibili e il nodo potr? risultare pi? lento del normale.
-NodeClientCore.startingUpShort=L'avviamento di Freenet ? ancora in corso: 
alcune funzioni potrebbero non essere ancora disponibili e il nodo potrebbe 
operare ad una velocit? inferiore al normale.
+NodeClientCore.startingUp=Si prega di concedere a Freenet alcuni minuti per 
completare il processo di avviamento. Nel frattempo alcune funzioni non saranno 
disponibili e il nodo potr? risultare pi? lento del normale.
+NodeClientCore.startingUpShort=L'avviamento di Freenet ? ancora in corso: 
alcune funzioni potrebbero non essere ancora disponibili e il nodo potrebbe 
operare ad una velocit? inferiore al normale.
 NodeClientCore.startingUpTitle=Avviamento di Freenet in corso
 NodeClientCore.tempDir=Directory file temporanei
 NodeClientCore.tempDirLong=Nome della directory dei file temporanei
 NodeClientCore.uploadAllowedDirs=Directory dalle quali l'upload e' consentito
-NodeClientCore.uploadAllowedDirsLong=Si pu? usare una lista di directory dove 
l'upload e' consentito, separate da 'punto e virgola' (;). Vuoto (nessuna 
directory specificata) significa che l'upload non e' permesso, "all" significa 
upload permesso da tutte le directory AVVERTENZA; Se impostato su "all" 
("tutte"), ogni utente potr? inserire qualunque file da qualsiasi directory.
+NodeClientCore.uploadAllowedDirsLong=Si pu? usare una lista di directory dove 
l'upload e' consentito, separate da 'punto e virgola' (;). Vuoto (nessuna 
directory specificata) significa che l'upload non e' permesso, "all" significa 
upload permesso da tutte le directory AVVERTENZA; Se impostato su "all" 
("tutte"), ogni utente potr? inserire qualunque file da qualsiasi directory.
 NodeIPDectector.inclLocalAddress=Includi indirizzi locali nella referenza del 
nodo
-NodeIPDectector.inclLocalAddressLong=Specifica se includere l'indirizzo locale 
(LAN e localhost) nella referenza del nodo. Ci? non ? necessario a meno che 
entrambi i nodi che si vogliono collegare abbiano impostato 
allowLocalAddresses=true per le rispettive referenze (per impostare questa 
opzione, abilitare la modalit? avanzata e usare le opzioni disponibili alla 
pagina Amici).
+NodeIPDectector.inclLocalAddressLong=Specifica se includere l'indirizzo locale 
(LAN e localhost) nella referenza del nodo. Ci? non ? necessario a meno che 
entrambi i nodi che si vogliono collegare abbiano impostato 
allowLocalAddresses=true per le rispettive referenze (per impostare questa 
opzione, abilitare la modalit? avanzata e usare le opzioni disponibili alla 
pagina Amici).
 NodeIPDectector.ipOverride=Impostazione manuale indirizzo IP
-NodeIPDectector.ipOverrideLong=Impostazione manuale dell'indirizzo IP (di 
solito non ? necessario) - Utilizzare questa opzione se si ha un indirizzo IP 
statico o un domain name  (es. dyndns), e ci si trova dietro un firewall.
+NodeIPDectector.ipOverrideLong=Impostazione manuale dell'indirizzo IP (di 
solito non ? necessario) - Utilizzare questa opzione se si ha un indirizzo IP 
statico o un domain name  (es. dyndns), e ci si trova dietro un firewall.
 NodeIPDectector.tempAddressHint=Suggerimento temporaneo indirizzo IP
 NodeIPDectector.tempAddressHintLong=Suggerisce temporaneamente l'indirizzo IP; 
viene eliminato dopo l'uso
-NodeIPDetector.maybeSymmetric=Sembra che il nodo sia dietro una NAT 
simmetrica. Potrebbe trattarsi di problemi di connessione: se ci si trova 
dietro una NAT simmetrica ci si potr? probabilmente connettere soltanto con i 
nodi che sono raggiungibili da interenet.
+NodeIPDetector.maybeSymmetric=Sembra che il nodo sia dietro una NAT 
simmetrica. Potrebbe trattarsi di problemi di connessione: se ci si trova 
dietro una NAT simmetrica ci si potr? probabilmente connettere soltanto con i 
nodi che sono raggiungibili da interenet.
 NodeIPDetector.maybeSymmetricShort=Problema di connessione: il nodo potrebbe 
trovarsi dietro una NAT simmetrica.
 NodeIPDetector.maybeSymmetricTitle=Problemi di connessione
 NodeIPDetector.unknownHostErrorInIPOverride=Host sconosciuto: ${error}
@@ -793,8 +779,8 @@
 NodeStat.freeHeapBytesThresholdLong=Il nodo respinge richieste per mantenere 
la quota di free heap bytes impostata
 NodeStat.freeHeapPercentThreshold=Soglia percentuale free heap
 NodeStat.freeHeapPercentThresholdLong=Respingendo nuove richieste, il nodo 
mantiene la  percentuale di di free heap (in rapporto a max heap bytes ammessi) 
 al di sopra della soglia
-NodeStat.ignoreLocalVsRemoteBandwidthLiability=Gestisi richieste locali allo 
come quelle remote per limitazioni della disponibilit? di banda
-NodeStat.ignoreLocalVsRemoteBandwidthLiabilityLong=Abilitando questa opzione 
si riduce notevolmente la banda utilizzata e si aumenta leggermente la 
sicurezza nei confronti di attacchi di timing. Generalmente non c'? di che 
preoccuparsi per questo tipo di attacchi in quanto gli attacchi di correlazione 
sono pi? facili da eseguire.
+NodeStat.ignoreLocalVsRemoteBandwidthLiability=Gestisi richieste locali allo 
come quelle remote per limitazioni della disponibilit? di banda
+NodeStat.ignoreLocalVsRemoteBandwidthLiabilityLong=Abilitando questa opzione 
si riduce notevolmente la banda utilizzata e si aumenta leggermente la 
sicurezza nei confronti di attacchi di timing. Generalmente non c'? di che 
preoccuparsi per questo tipo di attacchi in quanto gli attacchi di correlazione 
sono pi? facili da eseguire.
 NodeStat.memCheck=Abilita Verifica di Memoria
 NodeStat.memCheckLong=Abilita verifica della memoria (scrive un messaggio nel 
log file. La verifica della memoria deve essere abilitata perche' 
aggressiveGCModificator abbia effetto)
 NodeStat.statsPersister=File contenente le statistiche del nodo
@@ -802,8 +788,8 @@
 NodeStat.threadLimit=Limite thread
 NodeStat.threadLimitLong=Il nodo respinge richieste per limitare l'uso di 
thread al valore specificato.
 NodeStats.mustBePercentValueNotFull=Questo valore deve essere espresso in 
precentuale, compresa tra 0 e 99.
-NodeStats.valueTooLow=Valore troppo basso per questa impostazione: ? 
necessario aumentarlo.
-NodeUpdateManager.enabled=Verifica disponibilit? e scarica nuove versioni
+NodeStats.valueTooLow=Valore troppo basso per questa impostazione: ? 
necessario aumentarlo.
+NodeUpdateManager.enabled=Verifica disponibilit? e scarica nuove versioni
 NodeUpdateManager.enabledLong=Verifica e scarica automaticamente nuove 
versioni di Freenet. Se impostatos su 'vero', le nuove versioni verranno 
scaricate ma non necessariamente installate. L'impostazione torna sempre su 
'falso' se il nodo non gira all'interno del wrapper.
 NodeUpdateManager.extURI=Dove cercare versioni aggiornate di freenet-ext.jar?
 NodeUpdateManager.extURILong=Dove cercare aggiornamenti per freenet-ext.jar?
@@ -812,7 +798,7 @@
 NodeUpdateManager.invalidExtURI=Ext URI non valida: ${error}
 NodeUpdateManager.invalidRevocationURI=URI di revoca non valida: ${error}
 NodeUpdateManager.invalidUpdateURI=URI di aggiornamento non valida: ${error}
-NodeUpdateManager.noUpdateWithoutWrapper=Non ? stato possibile completare 
l'aggiornamento perch? il nodo non sta girando nel wrapper
+NodeUpdateManager.noUpdateWithoutWrapper=Non ? stato possibile completare 
l'aggiornamento perch? il nodo non sta girando nel wrapper
 NodeUpdateManager.revocationURI=Dove cercare la chiave di revoca?
 NodeUpdateManager.revocationURILong=URI per la chiave di revoca. Se viene 
trovata il nodo ne mostra il contenuto e disabilita l'aggiornamento automatico.
 NodeUpdateManager.updateCatastropheTitle=Fallimento Catastrofico dell' 
Aggiornamento!
@@ -821,32 +807,32 @@
 NodeUpdateManager.updateFailedTitle=Aggiornamento Fallito!
 NodeUpdateManager.updateURI=Dove cercare aggiornamenti?
 NodeUpdateManager.updateURILong=Dove cercare aggiornamenti?
-NotEnoughNiceLevelsUserAlert.content=Il nodo ha rilevato di stare operando ad 
un Nice level alto. In mancanza di un numero sufficiente di livelli di nice, il 
nodo non potr? operare a pieno regime. Si prega di ridurre il livello di nice. 
(cercare PRIORITY nel file run.sh e ridurne il valore). Attualmente il nodo ha 
${available} livelli a disposizione mentre avrebbe bisogno di ${required} 
livelli.
+NotEnoughNiceLevelsUserAlert.content=Il nodo ha rilevato di stare operando ad 
un Nice level alto. In mancanza di un numero sufficiente di livelli di nice, il 
nodo non potr? operare a pieno regime. Si prega di ridurre il livello di nice. 
(cercare PRIORITY nel file run.sh e ridurne il valore). Attualmente il nodo ha 
${available} livelli a disposizione mentre avrebbe bisogno di ${required} 
livelli.
 NotEnoughNiceLevelsUserAlert.short=Non ci sono abbastanza Nice level 
disponibili. si prega di assegnare a Freenet un Nice level inferiore.
 NotEnoughNiceLevelsUserAlert.title=Numero di Nice level insufficiente!
-OpennetConnectionsToadlet.fullTitle=${counts} Sconosciuti (Peer non fid?ti) 
del nodo: ${name}
-OpennetConnectionsToadlet.peersListTitle=Peer Opennet (peer non fid?ti 
aggiunti automaticamente dal nodo)
-OpennetConnectionsToadlet.successTime=L'ultima volta che si ? riusciti a 
richiamare una CHK dal nodo.
+OpennetConnectionsToadlet.fullTitle=${counts} Sconosciuti (Peer non fid?ti) 
del nodo: ${name}
+OpennetConnectionsToadlet.peersListTitle=Peer Opennet (peer non fid?ti 
aggiunti automaticamente dal nodo)
+OpennetConnectionsToadlet.successTime=L'ultima volta che si ? riusciti a 
richiamare una CHK dal nodo.
 OpennetConnectionsToadlet.successTimeTitle=Ultimo successo
-OpennetUserAlert.warning=Il nodo sta funzionando in modo "promiscuo". Ci? 
significa che il nodo si connetter? con nodi operati da sconosiuti, e quindi 
chiunque potr? facilmente determinare che l'utente Tal dei Tali sta usando 
Freenet. Molti attacchi vengono facilitati da questa modalit?, bloccare il nodo 
(per esempio con un firewall nazionale) diventa molto pi? facile, ed intoltre 
l'utente non ha controllo su chi si connette al suo nodo. Si raccomanda 
vivamente di procurarsi qualche connessione ad Amici (nodi operati da persone 
conosciute); il modo promiscuo va considerato una misura temporanea da 
utilizzarsi temporaneamente, in attesa di connessioni ad amici. Connettendosi 
esclusivamente a nodi gestiti da persone conosciute, pur non essendo impossibli 
degli attacchi da parte loro, risulter? comunque meno probabile l'esposizione 
ad agenzie governative (tipo servizi segreti o che so io) o altri "cattivi". 
Nota che aggiungere un peer alla sezione Amici non cambia molto la situazione, 
a meno che tale nodo non sia gestito da qualcuno di consciuto e di cui ci si 
fida (per ragioni sia di routing [instradamento] che di sicurezza)!
-OpennetUserAlert.warningShort=Modalit? insicura abilitata.
-OpennetUserAlert.warningTitle=Avvertenza: Modo Promiscuo Attivato: Il nodo si 
connetter? a degli sconosciuti
-PNGFilter.invalidHeader=Il file che si sta cercando di richiamare non e' un 
PNG: esso non include un header PNG valido. Potrebbe trattarsi di un file in 
altro formato e il browser potrebbe fare qualcosa di pericoloso a causa della 
confusione creata dalla mancata corrispondenza; il file ? stato pertanto 
bloccato.
+OpennetUserAlert.warning=Il nodo sta funzionando in modo "promiscuo". Ci? 
significa che il nodo si connetter? con nodi operati da sconosiuti, e quindi 
chiunque potr? facilmente determinare che l'utente Tal dei Tali sta usando 
Freenet. Molti attacchi vengono facilitati da questa modalit?, bloccare il nodo 
(per esempio con un firewall nazionale) diventa molto pi? facile, ed intoltre 
l'utente non ha controllo su chi si connette al suo nodo. Si raccomanda 
vivamente di procurarsi qualche connessione ad Amici (nodi operati da persone 
conosciute); il modo promiscuo va considerato una misura temporanea da 
utilizzarsi temporaneamente, in attesa di connessioni ad amici. Connettendosi 
esclusivamente a nodi gestiti da persone conosciute, pur non essendo impossibli 
degli attacchi da parte loro, risulter? comunque meno probabile l'esposizione 
ad agenzie governative (tipo servizi segreti o che so io) o altri "cattivi". 
Nota che aggiungere un peer alla sezione Amici non cambia molto la situazione, 
a meno che tale nodo non sia gestito da qualcuno di consciuto e di cui ci si 
fida (per ragioni sia di routing [instradamento] che di sicurezza)!
+OpennetUserAlert.warningShort=Modalit? insicura abilitata.
+OpennetUserAlert.warningTitle=Avvertenza: Modo Promiscuo Attivato: Il nodo si 
connetter? a degli sconosciuti
+PNGFilter.invalidHeader=Il file che si sta cercando di richiamare non e' un 
PNG: esso non include un header PNG valido. Potrebbe trattarsi di un file in 
altro formato e il browser potrebbe fare qualcosa di pericoloso a causa della 
confusione creata dalla mancata corrispondenza; il file ? stato pertanto 
bloccato.
 PNGFilter.invalidHeaderTitle=Header PNG non valido
 PageMaker.modeAdvanced=Interfaccia avanzata
-PageMaker.modeAdvancedTooltip=Un'interfaccia pi? complessa, utile soltanto 
agli utenti esperti
+PageMaker.modeAdvancedTooltip=Un'interfaccia pi? complessa, utile soltanto 
agli utenti esperti
 PageMaker.modeSimple=Interfaccia semplice
-PageMaker.modeSimpleTooltip=Un'interfaccia semplice che pu? essere usata da 
ogni utente
-PeerManagerUserAlert.clockProblem=${count} peer non riescono a connettersi 
perch? il loro orologio di sistema differisce di oltre 24 ore da quello locale. 
Si prega di verificare che l'orologio di sistema del computer sia regolato 
sull'ora esatta. Regolazioni inaccurate dell'orologio causano molti problemi 
nel funzionamento dei meccanismi tra nodo e client.
+PageMaker.modeSimpleTooltip=Un'interfaccia semplice che pu? essere usata da 
ogni utente
+PeerManagerUserAlert.clockProblem=${count} peer non riescono a connettersi 
perch? il loro orologio di sistema differisce di oltre 24 ore da quello locale. 
Si prega di verificare che l'orologio di sistema del computer sia regolato 
sull'ora esatta. Regolazioni inaccurate dell'orologio causano molti problemi 
nel funzionamento dei meccanismi tra nodo e client.
 PeerManagerUserAlert.clockProblemTitle=Problema di sincronizzazione.
 PeerManagerUserAlert.connError=${count} peer non riescono a connettersi per 
motivi sconosciuti, forse per causa di 'bug' nel nodo o di una referenza di un 
nodo che e' corrotta.
 PeerManagerUserAlert.connErrorTitle=Alcuni peer non riescono a connettersi
-PeerManagerUserAlert.noConns=Non ? stato finora possibile connettersi ad alcun 
nodo. Forse qualcuno dei peer si connettera entro breve. in caso contrario sar? 
necessario aggiungere altri peer; c'e' bisogno di almeno tre peer connessi in 
ogni momento, meglio 5-10.
+PeerManagerUserAlert.noConns=Non ? stato finora possibile connettersi ad alcun 
nodo. Forse qualcuno dei peer si connettera entro breve. in caso contrario sar? 
necessario aggiungere altri peer; c'e' bisogno di almeno tre peer connessi in 
ogni momento, meglio 5-10.
 PeerManagerUserAlert.noConnsTitle=Nessuna connessione aperta
-PeerManagerUserAlert.noPeersDarknet=Questo nodo non ha peers ai quale 
connettersi e non pu? quindi funzionare normalmente. In teoria ci si dovrebbe 
connettere esclusivamente a persone che si conosce (per i paranoici: persone di 
cui ci si fida, per i non paranoici: persone con le quali si ha parlato). Per 
un corretto funzionamento c'e' bisogno di almeno tre peer connessi in ogni 
momento, idealmente 5-10. Ci si pu? connettere a irc.freenode.net canale 
#freenet-refs e chiedere chi vuole connettersi, ma ? bene tenere presente che 
si ? vulnerabili ad attacchi da parte dei peer (Speciamente in queste prime 
versioni alfa di Freenet 0.7...) VERIFICARE CHE L'ATRA PARTE AGGIUNGA LA 
REFERENZA ALLA SUA LISTA: LE CONNESSIONI "A SENSO UNICO" NON FUNZIONANO!
-PeerManagerUserAlert.noPeersTestnet=Questo nodo non ha peer ai quale 
connettersi e non pu? quindi funzionare normalmente. In teoria ci si dovrebbe 
connettere esclusivamente a persone che si conosce (per i paranoici: persone di 
cui ci si fida, per i non paranoici: persone con le quali si ha parlato). Per 
un corretto funzionamento c'e' bisogno di almeno tre peer connessi in ogni 
momento, idealmente 5-10. Trattandosi di un nodo testnet, ci si pu? connettere 
a irc.freenode.net canale #freenet-refs e chiedere chi vuole connettersi.
+PeerManagerUserAlert.noPeersDarknet=Questo nodo non ha peers ai quale 
connettersi e non pu? quindi funzionare normalmente. In teoria ci si dovrebbe 
connettere esclusivamente a persone che si conosce (per i paranoici: persone di 
cui ci si fida, per i non paranoici: persone con le quali si ha parlato). Per 
un corretto funzionamento c'e' bisogno di almeno tre peer connessi in ogni 
momento, idealmente 5-10. Ci si pu? connettere a irc.freenode.net canale 
#freenet-refs e chiedere chi vuole connettersi, ma ? bene tenere presente che 
si ? vulnerabili ad attacchi da parte dei peer (Speciamente in queste prime 
versioni alfa di Freenet 0.7...) VERIFICARE CHE L'ATRA PARTE AGGIUNGA LA 
REFERENZA ALLA SUA LISTA: LE CONNESSIONI "A SENSO UNICO" NON FUNZIONANO!
+PeerManagerUserAlert.noPeersTestnet=Questo nodo non ha peer ai quale 
connettersi e non pu? quindi funzionare normalmente. In teoria ci si dovrebbe 
connettere esclusivamente a persone che si conosce (per i paranoici: persone di 
cui ci si fida, per i non paranoici: persone con le quali si ha parlato). Per 
un corretto funzionamento c'e' bisogno di almeno tre peer connessi in ogni 
momento, idealmente 5-10. Trattandosi di un nodo testnet, ci si pu? connettere 
a irc.freenode.net canale #freenet-refs e chiedere chi vuole connettersi.
 PeerManagerUserAlert.noPeersTitle=Nessun peer trovato
-PeerManagerUserAlert.oneConn=Questo nodo ha una sola connessione. Il 
rendimento ne risentir? in modo notevole, e l'utente non disporr? di anonimato 
e "negabilit? plausibile" se quell' unico nodo al quale si ? conessi dovesse 
essere operato da un avversario. Il nodo risulter? attaccato al network come 
una "foglia all' albero" e non contribuir? alla salute generale del network 
stesso. Per un corretto funzionamento del nodo ? necessario che almeno tre peer 
e (idealmente 5-10) siano connessi in qualsiasi momento.
+PeerManagerUserAlert.oneConn=Questo nodo ha una sola connessione. Il 
rendimento ne risentir? in modo notevole, e l'utente non disporr? di anonimato 
e "negabilit? plausibile" se quell' unico nodo al quale si ? conessi dovesse 
essere operato da un avversario. Il nodo risulter? attaccato al network come 
una "foglia all' albero" e non contribuir? alla salute generale del network 
stesso. Per un corretto funzionamento del nodo ? necessario che almeno tre peer 
e (idealmente 5-10) siano connessi in qualsiasi momento.
 PeerManagerUserAlert.onlyFewConnsTitle=Soltanto ${count} connessione/i aperta/e
 PeerManagerUserAlert.tooHighBwlimitDelayTime=Questo nodo deve aspettare troppo 
a lungo la banda disponibile (${delay}ms > ${max}ms). Aumentare l'ampiezza di 
banda in uscita e/o rimuovere alcuni peer migliorerebbe la situazione.
 PeerManagerUserAlert.tooHighBwlimitDelayTimeTitle=bwlimitDelayTime troppo alto
@@ -854,51 +840,51 @@
 PeerManagerUserAlert.tooHighPingTimeTitle=nodeAveragePingTime troppo alto
 PeerManagerUserAlert.tooManyConns=Questo nodo ha troppe connessioni (${count} 
> ${max}). Aggiungere troppi peer non produce un topologia mondo-piccolo, 
danneggia l'instradamento, e rischia di produrre punti di fallimento singoli.
 PeerManagerUserAlert.tooManyConnsTitle=Troppe connessioni aperte
-PeerManagerUserAlert.tooManyDisconnected=Questo nodo ha troppi peer 
disconnessi (${count} > ${max}). Questo pu? avere un leggero impatto sul 
rendimento perch? anche i peer disconnessi usano una piccola quantit? di banda 
e CPU. Potrebbe essere necessario "ripulire" la lista dei peer. Nota che almeno 
in teoria, bisognerebbe connettersi esclusivamente ad utenti che si conosce. 
Anche in caso contrario, aggiungere troppi nodi automaticamente produce un 
risultato negativo in quanto la topologia risultante non ? ottimale.
+PeerManagerUserAlert.tooManyDisconnected=Questo nodo ha troppi peer 
disconnessi (${count} > ${max}). Questo pu? avere un leggero impatto sul 
rendimento perch? anche i peer disconnessi usano una piccola quantit? di banda 
e CPU. Potrebbe essere necessario "ripulire" la lista dei peer. Nota che almeno 
in teoria, bisognerebbe connettersi esclusivamente ad utenti che si conosce. 
Anche in caso contrario, aggiungere troppi nodi automaticamente produce un 
risultato negativo in quanto la topologia risultante non ? ottimale.
 PeerManagerUserAlert.tooManyDisconnectedTitle=Troppi peer disconnessi
-PeerManagerUserAlert.tooManyNeverConnected=Ben ${count} tra i peer di questo 
nodo non sono mai stati connessi, nemmeno una volta sola: . Non bisognerebbe 
aggiungere peer a meno che la propria referenza venga aggiunta a sua volta. In 
caso contrario sar? impossibile connettersi.
+PeerManagerUserAlert.tooManyNeverConnected=Ben ${count} tra i peer di questo 
nodo non sono mai stati connessi, nemmeno una volta sola: . Non bisognerebbe 
aggiungere peer a meno che la propria referenza venga aggiunta a sua volta. In 
caso contrario sar? impossibile connettersi.
 PeerManagerUserAlert.tooManyNeverConnectedTitle=Molti peers non sono ancora 
stati connessi nemmeno una volta
-PeerManagerUserAlert.tooManyNeverConnectedWithLink=${count} peer di questo 
nodo non sono mai stati connessi, nemmeno una volta sola. Non bisognerebbe 
aggiungere nuovi peers a meno che essi non aggiungano a loro volta ${link}your 
reference${/link}. Se ci? non avviene non sar? possibile stabilire una 
connessione.
-PeerManagerUserAlert.tooManyPeers=Il nodo ha troppi peer (${count} > ${max}). 
Non si raccomanda di far girare "ubernodes" con l'aggiunta automatica di peer; 
questo non produce una topologia mondo-piccolo. Ci? influisce negativamente sul 
rendimento perch? anche i peer disconnessi usano un po' di banda e di CPU. 
Potrebbe essere necessario "ripulire" la lista dei peer.
+PeerManagerUserAlert.tooManyNeverConnectedWithLink=${count} peer di questo 
nodo non sono mai stati connessi, nemmeno una volta sola. Non bisognerebbe 
aggiungere nuovi peers a meno che essi non aggiungano a loro volta ${link}your 
reference${/link}. Se ci? non avviene non sar? possibile stabilire una 
connessione.
+PeerManagerUserAlert.tooManyPeers=Il nodo ha troppi peer (${count} > ${max}). 
Non si raccomanda di far girare "ubernodes" con l'aggiunta automatica di peer; 
questo non produce una topologia mondo-piccolo. Ci? influisce negativamente sul 
rendimento perch? anche i peer disconnessi usano un po' di banda e di CPU. 
Potrebbe essere necessario "ripulire" la lista dei peer.
 PeerManagerUserAlert.tooManyPeersTitle=Troppi peer
-PeerManagerUserAlert.tooOldNeverConnectedPeers=Uno o pi? peer non si sono mai 
connessi nelle due settimane trascorse da quando sono stati aggiunti.  E' da 
prendere in considerazione l'idea di rimuoverli in quanto essi stanno 
marginalmente compromettendo il rendimento (pacchetti sprecati cencando di 
comunicare con nodi che non ci sono).
+PeerManagerUserAlert.tooOldNeverConnectedPeers=Uno o pi? peer non si sono mai 
connessi nelle due settimane trascorse da quando sono stati aggiunti.  E' da 
prendere in considerazione l'idea di rimuoverli in quanto essi stanno 
marginalmente compromettendo il rendimento (pacchetti sprecati cencando di 
comunicare con nodi che non ci sono).
 PeerManagerUserAlert.tooOldNeverConnectedPeersTitle=Peer mai connesso/i 
obsoleto/i
-PeerManagerUserAlert.twoConns=Il nodo ha solo due connessioni. Rendimento e 
sicurezza risulteranno di qualit? inferiore, e non sara possibile provvedere 
instradamento (routing) per altri nodi. Il nodo ? collegato al network come un 
"anello di catena" e non contribuisce (molto) alla salute generale del network 
stesso. Per un corretto funzionamento del nodo, ? necessario che almeno tre 
peers (e idealmente 5-10) siano connessi in ogni momento.
+PeerManagerUserAlert.twoConns=Il nodo ha solo due connessioni. Rendimento e 
sicurezza risulteranno di qualit? inferiore, e non sara possibile provvedere 
instradamento (routing) per altri nodi. Il nodo ? collegato al network come un 
"anello di catena" e non contribuisce (molto) alla salute generale del network 
stesso. Per un corretto funzionamento del nodo, ? necessario che almeno tre 
peers (e idealmente 5-10) siano connessi in ogni momento.
 PeersSayKeyBlownAlert.connectedSayBlownLabel=I seguenti nodi hanno rilevato un 
problema con la chiave  (si cerca attualmente di ottenere il certificato di 
revoca da loro):
-PeersSayKeyBlownAlert.disconnectedSayBlownLabel=I seguenti nodi si sono 
disconnessi dopo aver comunicato che la chiave ? saltata, quindi non ? stato 
possibile richiamare il certificato di revoca:
-PeersSayKeyBlownAlert.failedFetch=Non ? stato possibile scaricare il 
certificato di revoca. Le possibili cause di tale evento includono la 
possibilit? di un attacco sul nodo locale volto a fargli scaricare ed 
installare un aggiornamento nonostante la chiave sia saltata, o la possibilit? 
che dei nodi stiano "mentendo" circa la chiave di revoca. Si prega di 
contattare gli sviluppatori di Freenet per cercare di mettere ordine in questo 
casino.
-PeersSayKeyBlownAlert.failedTransferSayBlownLabel=Questi nodi hanno comunicato 
che la chiave di revoca ? saltata ma poi non hanno completato il trasferimento 
del certificato di revoca:
-PeersSayKeyBlownAlert.fetching=Il nodo sta scaricando il certificato di revoca 
contentnte spiegazioni pi? dettagliate.
-PeersSayKeyBlownAlert.intro=Uno o pi? peers ci comunicano che la chiave di 
revoca per l'aggiornamento automatico ? saltata. Questo significa che qualcuno 
potrebbe essere venuto a conoscenza della chiave privata del sistema di 
autoaggiornamento, cosa che potrebbe far eseguire al nodo il codice che 
l'attaccante volesse fargli eseguire (se l'aggiornamento venisse eseguito): per 
prevenire tale eventualit?, il sistema di autoaggiornamento ? stato 
disabilitato. E' anche possibile che dei peers stiano deliberatamente mentendo 
a proposito della chiave di revoca.
-PeersSayKeyBlownAlert.short=Alcuni peer avvertono che la chiave di auto 
aggiornamento ? saltata!
-PeersSayKeyBlownAlert.titleWithCount=La chiave di Auto-aggiornamento ? 
saltata! L' evento ? stato confermato da ${count} peer!
+PeersSayKeyBlownAlert.disconnectedSayBlownLabel=I seguenti nodi si sono 
disconnessi dopo aver comunicato che la chiave ? saltata, quindi non ? stato 
possibile richiamare il certificato di revoca:
+PeersSayKeyBlownAlert.failedFetch=Non ? stato possibile scaricare il 
certificato di revoca. Le possibili cause di tale evento includono la 
possibilit? di un attacco sul nodo locale volto a fargli scaricare ed 
installare un aggiornamento nonostante la chiave sia saltata, o la possibilit? 
che dei nodi stiano "mentendo" circa la chiave di revoca. Si prega di 
contattare gli sviluppatori di Freenet per cercare di mettere ordine in questo 
casino.
+PeersSayKeyBlownAlert.failedTransferSayBlownLabel=Questi nodi hanno comunicato 
che la chiave di revoca ? saltata ma poi non hanno completato il trasferimento 
del certificato di revoca:
+PeersSayKeyBlownAlert.fetching=Il nodo sta scaricando il certificato di revoca 
contentnte spiegazioni pi? dettagliate.
+PeersSayKeyBlownAlert.intro=Uno o pi? peers ci comunicano che la chiave di 
revoca per l'aggiornamento automatico ? saltata. Questo significa che qualcuno 
potrebbe essere venuto a conoscenza della chiave privata del sistema di 
autoaggiornamento, cosa che potrebbe far eseguire al nodo il codice che 
l'attaccante volesse fargli eseguire (se l'aggiornamento venisse eseguito): per 
prevenire tale eventualit?, il sistema di autoaggiornamento ? stato 
disabilitato. E' anche possibile che dei peers stiano deliberatamente mentendo 
a proposito della chiave di revoca.
+PeersSayKeyBlownAlert.short=Alcuni peer avvertono che la chiave di auto 
aggiornamento ? saltata!
+PeersSayKeyBlownAlert.titleWithCount=La chiave di Auto-aggiornamento ? 
saltata! L' evento ? stato confermato da ${count} peer!
 PluginConfig.configFile=File di configurazione dei plugin
 PluginConfig.configFileLong=Percorso/Nome del file che contiene la 
configurazione del plugin
 PluginConfig.installDir=Directory di installazione dei plugin
 PluginConfig.installDirLong=Directory dove installare i plugin
-PluginManager.cannotSetOnceLoaded=Una volta caricata, non ? pi? possibile 
impostare la lista dei plugin
+PluginManager.cannotSetOnceLoaded=Una volta caricata, non ? pi? possibile 
impostare la lista dei plugin
 PluginManager.loadedOnStartup=Plugin da caricare all'avvio
 PluginManager.loadedOnStartupLong=Classpath, nome e locazione dei plugin da 
caricare all'avvio
 PluginManager.loadedPlugins=Plugin da caricare all'avvio
 PluginManager.loadedPluginsLong=Lista dei plugin da caricare all'avvio del nodo
-PluginManager.pluginLoadingFailed=Non ? stato possibile caricare il plugin 
specificato ${name}.
+PluginManager.pluginLoadingFailed=Non ? stato possibile caricare il plugin 
specificato ${name}.
 PluginManager.pluginLoadingFailedShort=Impossibile caricare il plugin ${name}!
-PluginManager.pluginLoadingFailedTitle=Non ? stato possibile caricare il plugin
-PluginManager.pluginLoadingFailedWithMessage=Non ? stato possibile caricare il 
plugin specificato ${name}: ${message}
-PluginManager.pluginReqNewerJVM=Per usare il plugin ${name} ? necessario 
installare una JVM pi? recente di quella attualmente in uso. Installare Sun 
Java 1.5 o superiore, o rimuovere il plugin.
-PluginManager.pluginReqNewerJVMTitle=Il plugin ${name} richiede l'uso di una 
JVM pi? aggiornata
+PluginManager.pluginLoadingFailedTitle=Non ? stato possibile caricare il plugin
+PluginManager.pluginLoadingFailedWithMessage=Non ? stato possibile caricare il 
plugin specificato ${name}: ${message}
+PluginManager.pluginReqNewerJVM=Per usare il plugin ${name} ? necessario 
installare una JVM pi? recente di quella attualmente in uso. Installare Sun 
Java 1.5 o superiore, o rimuovere il plugin.
+PluginManager.pluginReqNewerJVMTitle=Il plugin ${name} richiede l'uso di una 
JVM pi? aggiornata
 PluginToadlet.addPluginTitle=Aggiungi plugin
 PluginToadlet.failedToLoadPlugin=Caricamento plugin fallito.
-PluginToadlet.failedToLoadPluginCheckClass=Non ? stato possibile caricare il 
plugin richiesto. Verificare il nome del plugin, class, e URL se se ne ? usata 
una.
+PluginToadlet.failedToLoadPluginCheckClass=Non ? stato possibile caricare il 
plugin richiesto. Verificare il nome del plugin, class, e URL se se ne ? usata 
una.
 PluginToadlet.failedToLoadPluginTitle=Caricamento plugin fallito
 PluginToadlet.internalNameTitle=Nome Interno
 PluginToadlet.loadPluginCommand=Carica Plugin
-PluginToadlet.noWebInterface=Questo plugin non ha interfaccia web e pertanto 
non c'? nulla da mostrare
+PluginToadlet.noWebInterface=Questo plugin non ha interfaccia web e pertanto 
non c'? nulla da mostrare
 PluginToadlet.noWebInterfaceTitle=Plugin non provvisto di interfaccia web
 PluginToadlet.pluginList=Lista plugin
 PluginToadlet.pluginListTitle=Lista Plugin
 PluginToadlet.pluginNameTitle=Nome Plugin
-PluginToadlet.pluginNotFound=Non ? stato possibile trovare il plugin richiesto
+PluginToadlet.pluginNotFound=Non ? stato possibile trovare il plugin richiesto
 PluginToadlet.pluginNotFoundTitle=Plugin non trovato
 PluginToadlet.returnToPluginsWithLinks=${link}return${/link} alla lista di 
plugins.
 PluginToadlet.unsupportedMethod=Metodo non supportato
@@ -909,37 +895,37 @@
 PproxyToadlet.cancel=Cancella
 PproxyToadlet.changeReloadOnStartup=Cambia
 PproxyToadlet.classNameTitle=Class Name
-PproxyToadlet.downloadNotAllowedFromRemoteServer=Donload dei plugins ? ammesso 
solo dal server di Freenet.
+PproxyToadlet.downloadNotAllowedFromRemoteServer=Donload dei plugins ? ammesso 
solo dal server di Freenet.
 PproxyToadlet.fileonly=accetta solo file locali
 PproxyToadlet.internalIDTitle=ID interna
 PproxyToadlet.loadFreenetPlugin=Carica un Plugin non ufficiale da freenet
-PproxyToadlet.loadFreenetPluginText=Inserire la URI del plugin che si vuole 
caricare. I plugin disponibili si Freenet non godono di alcun supporto 
ufficiale e non vengono controllati dagli sviluppatori di Freenet. Non ? quindi 
possibile quindi garantire la privacy e la sicurezza di chi decidesse di 
utilizzarli.
+PproxyToadlet.loadFreenetPluginText=Inserire la URI del plugin che si vuole 
caricare. I plugin disponibili si Freenet non godono di alcun supporto 
ufficiale e non vengono controllati dagli sviluppatori di Freenet. Non ? quindi 
possibile quindi garantire la privacy e la sicurezza di chi decidesse di 
utilizzarli.
 PproxyToadlet.loadFreenetURLLabel=Chiave del plugin
 PproxyToadlet.loadOfficialPlugin=Aggiungi un Plugin Ufficiale
 PproxyToadlet.loadOfficialPluginLabel=Carica Plugin Ufficiale
-PproxyToadlet.loadOfficialPluginText=Plugin ufficialy disponibili per download 
dai server del Progetto Freenet. I programmatori di Freenet hanno esaminato i 
plugin ufficiali e trovato che essi appaiono esenti da difetti che possano 
compromettere la privacy; non ? tuttavia possibile garantire con il 100% di 
sicurezza che ci? corrisponda a realt?.
-PproxyToadlet.loadOfficialPluginWarning=AVVERTENZA: Caricando un plugin 
ufficiale lo si scarica da internet, (NON da Freenet). Se ci? dovesse 
rappresentare un problema, si consiglia di non caricare plugin.
+PproxyToadlet.loadOfficialPluginText=Plugin ufficialy disponibili per download 
dai server del Progetto Freenet. I programmatori di Freenet hanno esaminato i 
plugin ufficiali e trovato che essi appaiono esenti da difetti che possano 
compromettere la privacy; non ? tuttavia possibile garantire con il 100% di 
sicurezza che ci? corrisponda a realt?.
+PproxyToadlet.loadOfficialPluginWarning=AVVERTENZA: Caricando un plugin 
ufficiale lo si scarica da internet (non da Freenet). Se ci? pu? effettivamente 
rappresentare un un problema, si consiglia di non caricare plugins.
 PproxyToadlet.loadOtherPlugin=Aggiungi Plugin Non Ufficiale
-PproxyToadlet.loadOtherPluginText=Inserire qui la URL del plugin che si vuole 
caricare. ATTENZIONE! I Plugin non ufficiali non ricevono alcuna assistenza e 
non vengono controllati dai programmatory di Freenet, pertanto chi volesse 
utilizzarli lo far? A PROPRIO RISCHIO.
+PproxyToadlet.loadOtherPluginText=Inserire qui la URL del plugin che si vuole 
caricare. ATTENZIONE! I Plugin non ufficiali non ricevono alcuna assistenza e 
non vengono controllati dai programmatory di Freenet, pertanto chi volesse 
utilizzarli lo far? A PROPRIO RISCHIO.
 PproxyToadlet.loadOtherURLLabel=URL del plugin
 PproxyToadlet.loadPluginLabel=Carica Plugin:
 PproxyToadlet.noPlugins=Nessun plugin caricato
 PproxyToadlet.noVersion=N/A
-PproxyToadlet.pluginDirectoryNotCreated=Non ? stato possibile creare una 
directory per i plugin.
-PproxyToadlet.pluginNotDownloaded=Non ? stato possibile scaricare il plugin
-PproxyToadlet.pluginNotFoundReload=Non ? stato possibile localizzare il plugin 
specificato per poterlo ricaricare.
+PproxyToadlet.pluginDirectoryNotCreated=Non ? stato possibile creare una 
directory per i plugin.
+PproxyToadlet.pluginNotDownloaded=Non ? stato possibile scaricare il plugin
+PproxyToadlet.pluginNotFoundReload=Non ? stato possibile localizzare il plugin 
specificato per poterlo ricaricare.
 PproxyToadlet.pluginNotFoundReloadTitle=Plugin non trovato (ricaricamento in 
corso)
 PproxyToadlet.pluginStopping=Disconnessione plugin in corso
 PproxyToadlet.pluginUnloaded=Plugin terminato
-PproxyToadlet.pluginUnloadedWithName=Il plugin ${name} ? stato terminato.
+PproxyToadlet.pluginUnloadedWithName=Il plugin ${name} ? stato terminato.
 PproxyToadlet.plugins=Plugin
 PproxyToadlet.pluginsWithNodeName=Plugin di ${name}
 PproxyToadlet.refreshOnStartup=Ricarica da server all'avvio
 PproxyToadlet.reload=Ricarica
-PproxyToadlet.reloadExplanation=Ricaricare un plugin ? come scaricarlo e 
ricaricarlo.
+PproxyToadlet.reloadExplanation=Ricaricare un plugin ? come scaricarlo e 
ricaricarlo.
 PproxyToadlet.reloadOnStartupShort=Ricarica all'avvio
 PproxyToadlet.reloadPluginTitle=Ricarica Plugin
-PproxyToadlet.reloadPurgeWarning=Rimuovi il plugin dalla cache prima di 
ricaricarlo. Se il plugin era stato scaricato da internet, sar? scaricato 
nuovamente.
+PproxyToadlet.reloadPurgeWarning=Rimuovi il plugin dalla cache prima di 
ricaricarlo. Se il plugin era stato scaricato da internet, sar? scaricato 
nuovamente.
 PproxyToadlet.reloadWarning=Attenzione: alcuni plugin non reagiscono in modo 
ottimale a un reload.
 PproxyToadlet.returnToPluginPage=Torna alla pagina dei plugin
 PproxyToadlet.startedAtTitle=Avviato:
@@ -947,7 +933,7 @@
 PproxyToadlet.startingPluginStatus=Stato attuale
 PproxyToadlet.startingPluginTime=tempo trascorso
 PproxyToadlet.startingPluginsTitle=Avvio plugins in corso
-PproxyToadlet.unauthorized=L'accesso a questa pagina non ? autorizzato.
+PproxyToadlet.unauthorized=L'accesso a questa pagina non ? autorizzato.
 PproxyToadlet.unauthorizedTitle=Accesso Non Autorizzato
 PproxyToadlet.unload=Termina
 PproxyToadlet.unloadPluginTitle=Termina plugin?
@@ -971,39 +957,39 @@
 QueueToadlet.download=Scarica
 QueueToadlet.downloadFiles=Download multipli
 QueueToadlet.downloadFilesInstructions=E' possibile incollare una serie di 
chiavi da scaricare nello spazio sottostante (una per rigo)
-QueueToadlet.downloadSucceeded=Il file ${origlink}${filename}${/origlink} ? 
stato scaricato. ${link}Click qui${/link} per aprile il file (${size}).
+QueueToadlet.downloadSucceeded=Il file ${origlink}${filename}${/origlink} ? 
stato scaricato. ${link}Click qui${/link} per aprile il file (${size}).
 QueueToadlet.downloadSucceededTitle=Download completato: ${filename}
 QueueToadlet.emergency=urgenza estrema
-QueueToadlet.enqueuedFailure=Non ? stato possibile agguingere alla coda le 
${number} chiavi qui elencate:
+QueueToadlet.enqueuedFailure=Non ? stato possibile agguingere alla coda le 
${number} chiavi qui elencate:
 QueueToadlet.enqueuedSuccessfully=Le ${number} chiavi elencate di seguito sono 
state aggiunte alla coda con successo:
 QueueToadlet.errorAccessDenied=Errore: Accesso Negato
 QueueToadlet.errorAccessDeniedFile=L'attuale configurazione del nodo non 
consente l'upload del file "${file}".
-QueueToadlet.errorDToDisk=Non ? stato possibile scaricare su disco
+QueueToadlet.errorDToDisk=Non ? stato possibile scaricare su disco
 QueueToadlet.errorDToDiskConfig=L'attuale configurazione del nodo non consente 
di scaricare file nella directory dei download
 QueueToadlet.errorDownloadNotCompleted=Download Non Completato
-QueueToadlet.errorDownloadNotFound=Non ? stato possibile localizzare il 
download richiesto
-QueueToadlet.errorDownloadNotFoundExplanation=Non ? stato possibile trovare il 
download specificato. Potrebbe essere stato eliminato in precedenza.
+QueueToadlet.errorDownloadNotFound=Non ? stato possibile localizzare il 
download richiesto
+QueueToadlet.errorDownloadNotFoundExplanation=Non ? stato possibile trovare il 
download specificato. Potrebbe essere stato eliminato in precedenza.
 QueueToadlet.errorInvalidURI=URI non valida
-QueueToadlet.errorInvalidURIToD=La URI non ? valida e pertanto non pu? essere 
scaricata.
-QueueToadlet.errorInvalidURIToU=Non ? stata specificata alcuna URI valida dove 
inserire il file
+QueueToadlet.errorInvalidURIToD=La URI non ? valida e pertanto non pu? essere 
scaricata.
+QueueToadlet.errorInvalidURIToU=Non ? stata specificata alcuna URI valida dove 
inserire il file
 QueueToadlet.errorNoFileOrCannotRead=File inesistente o illegibile
 QueueToadlet.errorNoFileSelected=Nessun file selezionato
 QueueToadlet.errorNoFileSelectedU=Non e' stato selezionato alcun file per 
l'upload
-QueueToadlet.errorNoKey=Non ? stata specificata alcuna chiave per il download
-QueueToadlet.errorNoKeyToD=Non ? stata specificata una chiave per il download
+QueueToadlet.errorNoKey=Non ? stata specificata alcuna chiave per il download
+QueueToadlet.errorNoKeyToD=Non ? stata specificata una chiave per il download
 QueueToadlet.failedD=Download falliti
 QueueToadlet.failedDU=Upload di directory falliti
-QueueToadlet.failedToRemove=Non ? stato possibile rimuovere ${id}: ${message}
-QueueToadlet.failedToRemoveId=Non ? stato possibile eliminare: ${id}
-QueueToadlet.failedToRemoveRequest=Non ? stato possibile eliminare la richiesta
-QueueToadlet.failedToRestart=Non ? stato possibile riavviare: ${id}
+QueueToadlet.failedToRemove=Non ? stato possibile rimuovere ${id}: ${message}
+QueueToadlet.failedToRemoveId=Non ? stato possibile eliminare: ${id}
+QueueToadlet.failedToRemoveRequest=Non ? stato possibile eliminare la richiesta
+QueueToadlet.failedToRestart=Non ? stato possibile riavviare: ${id}
 QueueToadlet.failedToRestartRequest=Non e' stato possibile riavviare la 
richiesta
 QueueToadlet.failedU=Upload falliti
 QueueToadlet.fcpIsMissing=Server FCP non trovato
 QueueToadlet.fileName=File
 QueueToadlet.files=File
 QueueToadlet.follow=Segui Redirect
-QueueToadlet.globalQueueIsEmpty=La coda globale ? vuota
+QueueToadlet.globalQueueIsEmpty=La coda globale ? vuota
 QueueToadlet.high=alta
 QueueToadlet.identifier=Identificazione
 QueueToadlet.insertAs=Inserisci come:
@@ -1014,22 +1000,22 @@
 QueueToadlet.insertFileLabel=File
 QueueToadlet.insertFileResetForm=Annulla
 QueueToadlet.key=Chiave
-QueueToadlet.legend=Significato dei colori: Priorit?...
+QueueToadlet.legend=Significato dei colori: Priorit?...
 QueueToadlet.low=bassa
 QueueToadlet.medium=media
 QueueToadlet.mimeType=MIME type
 QueueToadlet.noTaskOnGlobalQueue=Nessuna operazione in attesa nella coda 
globale in questo momento.
 QueueToadlet.none=nessuna
 QueueToadlet.notLoadedYet=Il nodo sta ancora caricando la lista delle 
richieste persistenti. Si prega di pazientare.
-QueueToadlet.notLoadedYetTitle=La Coda non ? stata ancora caricata.
+QueueToadlet.notLoadedYetTitle=La Coda non ? stata ancora caricata.
 QueueToadlet.panicButton=Bottone Emergenza
 QueueToadlet.panicButtonConfirmation=Elimina tutte le richieste senza chiedere 
conferma
 QueueToadlet.persistence=Persistenza
 QueueToadlet.persistenceForever=illimitata
 QueueToadlet.persistenceNone=nessuna
 QueueToadlet.persistenceReboot=reboot
-QueueToadlet.pleaseEnableFCP=Per accedere a questa pagina ? necessario 
abilitare il server FCP
-QueueToadlet.priority=Priorit?
+QueueToadlet.pleaseEnableFCP=Per accedere a questa pagina ? necessario 
abilitare il server FCP
+QueueToadlet.priority=Priorit?
 QueueToadlet.priority0=emergenza
 QueueToadlet.priority1=molto alta
 QueueToadlet.priority2=alta
@@ -1039,7 +1025,7 @@
 QueueToadlet.priority6=campa cavallo
 QueueToadlet.progress=Completato
 QueueToadlet.progressbarAccurate=Questo valore e' accurato
-QueueToadlet.progressbarNotAccurate=I valori possono essere imprecisi perch? 
il processo di download del file non e' stato finalizzato
+QueueToadlet.progressbarNotAccurate=I valori possono essere imprecisi perch? 
il processo di download del file non e' stato finalizzato
 QueueToadlet.reason=Motivo
 QueueToadlet.remove=Elimina
 QueueToadlet.requestNavigation=Esplora Richieste
@@ -1051,25 +1037,25 @@
 QueueToadlet.title=Coda globale del nodo: ${nodeName}
 QueueToadlet.totalSize=Dimensioni Totali
 QueueToadlet.unknown=Non Disp.
-QueueToadlet.uploadProgressbarNotAccurate=Il valore di questo indicatore di 
progresso pu? essere falsato quando l'upload codifica ulteriori blocchi.
-QueueToadlet.uploadSucceeded=Il file ${filename} (size ${size}) ? stato 
correttamente caricato su Freenet. ${link}Click qui${/link} per aprire il file.
+QueueToadlet.uploadProgressbarNotAccurate=Il valore di questo indicatore di 
progresso pu? essere falsato quando l'upload codifica ulteriori blocchi.
+QueueToadlet.uploadSucceeded=Il file ${filename} (size ${size}) ? stato 
correttamente caricato su Freenet. ${link}Click qui${/link} per aprire il file.
 QueueToadlet.uploadSucceededTitle=Inserzione completata: ${filename}
 QueueToadlet.veryhigh=molto alta
 QueueToadlet.verylow=bassissima
 QueueToadlet.warningUnsafeContent=Contenuto Potenzialmente Pericoloso
-QueueToadlet.warningUnsafeContentExplanation=Il file richiesto ? di un tipo 
non ancora supportato dal filtro contenuti di Freenet e pertanto non sar? 
possibile filtrarlo. Ci? significa che aprire tale file potrebbe compromettere 
l'anonimato dell'utente
+QueueToadlet.warningUnsafeContentExplanation=Il file richiesto ? di un tipo 
non ancora supportato dal filtro contenuti di Freenet e pertanto non sar? 
possibile filtrarlo. Ci? significa che aprire tale file potrebbe compromettere 
l'anonimato dell'utente
 QueueToadlet.willneverfinish=campa cavallo
 QueueToadlet.wipD=Download in corso (${size})
 QueueToadlet.wipDU=Upload directory in corso (${size})
 QueueToadlet.wipU=Upload in corso: (${size})
-RequestStarterGroup.scheduler=Policy di priorit? dello schedulatore
-RequestStarterGroup.schedulerCHKInserts=Policy di priorit? dello scheduler 
(inserzioni CHK)
-RequestStarterGroup.schedulerCHKRequests=Policy di priorit? dello scheduler 
(richieste CHK)
-RequestStarterGroup.schedulerLong=Imposta lo schema delle policy di priorit? 
usate dallo schedulatore.
-RequestStarterGroup.schedulerSSKInserts=Policy di priorit? dello scheduler 
(inserzioni SSK)
-RequestStarterGroup.schedulerSSKRequests=Policy di priorit? dello scheduler 
(richieste SSK)
-RevocationKeyFoundUserAlert.text=E' stata rilevata la presenza sul network 
della chiave di revoca dell' aggiornamento automatico. Questo significa che il 
nostro sistema di aggiornamento automatico ? stato probabilmente COMPROMESSO. 
L'aggiornamento automatico ? stato conseguentemente disabilitato onde prevenire 
l'intallazione automatica di "robaccia". Si raccomanda di controllare la 
disponibilit? di nuovi aggiornamenti al sito del progetto. Controllare che il 
sito non sia stato falsificato!. Il messaggio di revoca ? il seguente: 
${message}.
-RevocationKeyFoundUserAlert.title=La chiave privata del progetto ? stata 
compromessa!
+RequestStarterGroup.scheduler=Policy di priorit? dello schedulatore
+RequestStarterGroup.schedulerCHKInserts=Policy di priorit? dello scheduler 
(inserzioni CHK)
+RequestStarterGroup.schedulerCHKRequests=Policy di priorit? dello scheduler 
(richieste CHK)
+RequestStarterGroup.schedulerLong=Imposta lo schema delle policy di priorit? 
usate dallo schedulatore.
+RequestStarterGroup.schedulerSSKInserts=Policy di priorit? dello scheduler 
(inserzioni SSK)
+RequestStarterGroup.schedulerSSKRequests=Policy di priorit? dello scheduler 
(richieste SSK)
+RevocationKeyFoundUserAlert.text=E' stata rilevata la presenza sul network 
della chiave di revoca dell' aggiornamento automatico. Questo significa che il 
nostro sistema di aggiornamento automatico ? stato probabilmente COMPROMESSO. 
L'aggiornamento automatico ? stato conseguentemente disabilitato onde prevenire 
l'intallazione automatica di "robaccia". Si raccomanda di controllare la 
disponibilit? di nuovi aggiornamenti al sito del progetto. Controllare che il 
sito non sia stato falsificato!. Il messaggio di revoca ? il seguente: 
${message}.
+RevocationKeyFoundUserAlert.title=La chiave privata del progetto ? stata 
compromessa!
 SSL.enable=Attiva supporto SSL?
 SSL.enableLong=Attiva supporto SSL?
 SSL.keyPass=Password di private key access
@@ -1080,43 +1066,41 @@
 SSL.keyStorePassLong=Password per l'accesso di key store file
 SSL.version=Versione di SSL
 SSL.versionLong=Versione di SSL, SSLv3 o TLSv1 (default SSLv3)
-ShortOption.parseError=Il valore specificato non pu? essere interpretato come 
16-bit integer : ${val}
-SimpleToadletServer.advancedMode=Abilita modalit? avanzata
+ShortOption.parseError=Il valore specificato non pu? essere interpretato come 
16-bit integer : ${val}
+SimpleToadletServer.advancedMode=Abilita modalit? avanzata
 SimpleToadletServer.advancedModeLong=Mostra informazioni cho possono 
interessare solo utenti avanzati o sviluppatori. Nella maggioranza dei casi 
dovrebbe essere impostata su 'falso'
-SimpleToadletServer.allowedFullAccess=Host ai quali ? consentito pieno accesso 
a FProxy (leggere l'avvertenza)
-SimpleToadletServer.allowedFullAccessLong=Host ai quali ? consentito accesso 
pieno al nodo (cambiare impostazioni di configurazione, riavviare, ecc). 
AVVERTENZA: Usare cautela nel decidere a chi consentire accesso pieno!
+SimpleToadletServer.allowedFullAccess=Host ai quali ? consentito pieno accesso 
a FProxy (leggere l'avvertenza)
+SimpleToadletServer.allowedFullAccessLong=Host ai quali ? consentito accesso 
pieno al nodo (cambiare impostazioni di configurazione, riavviare, ecc). 
AVVERTENZA: Usare cautela nel decidere a chi consentire accesso pieno!
 SimpleToadletServer.allowedHosts=Nomi host o indirizzi IP ai quali e' 
consentito connettersi a FProxy
-SimpleToadletServer.allowedHostsLong=Pu? essere una lista di IP separati da 
virgole e IP in formato CIDR come 192.168.0.0/24. Tutti possono accedere al 
disco rigido nei limiti definiti dalle altre opzioni di configurazione.
+SimpleToadletServer.allowedHostsLong=Pu? essere una lista di IP separati da 
virgole e IP in formato CIDR come 192.168.0.0/24. Tutti possono accedere al 
disco rigido nei limiti definiti dalle altre opzioni di configurazione.
 SimpleToadletServer.bindTo=Indirizzo IP collegato
 SimpleToadletServer.bindToLong=Indirizzo IP collegato
-SimpleToadletServer.cannotChangePortOnTheFly=Non ? possibile cambiare il 
numero della porta FProxy "al volo"
-SimpleToadletServer.couldNotChangeBindTo=Non ? stato possibile cambiare 
l'indirizzo abbinato a FProxy: ${error}.
+SimpleToadletServer.cannotChangePortOnTheFly=Non ? possibile cambiare il 
numero della porta FProxy "al volo"
+SimpleToadletServer.couldNotChangeBindTo=Non ? stato possibile cambiare 
l'indirizzo abbinato a FProxy: ${error}.
 SimpleToadletServer.cssName=Nome del CSS
 SimpleToadletServer.cssNameLong=Nome del CSS utilizzato da FProxy
 SimpleToadletServer.cssOverride=Usa un CSS personalizzato al posto di quello 
regolare (ATTENZIONE!)
-SimpleToadletServer.cssOverrideCantRead=Non ? stato possibile leggere il file 
di sovrascrittura CSS fornito: ${filename}
+SimpleToadletServer.cssOverrideCantRead=Non ? stato possibile leggere il file 
di sovrascrittura CSS fornito: ${filename}
 SimpleToadletServer.cssOverrideLong=Questa impostazione permette di utilizzare 
un CSS personalizzato invece di quello normalmente usato. AVVERTENZA: i CSS 
possono essere pericolosi, e *non* vengono filtrati: utilizzare a proprio 
rischio. Per includerli nella distribuzione principale e-mail devl at 
freenetroject.org
-SimpleToadletServer.cssOverrideNotInUploads=Non ? possibile usare questa 
impostazione: "${filename} non ? una directory dalla quale sono permessi gli 
upload.
+SimpleToadletServer.cssOverrideNotInUploads=Non ? possibile usare questa 
impostazione: "${filename} non ? una directory dalla quale sono permessi gli 
upload.
 SimpleToadletServer.doRobots=Usare robots.txt per escludere i robot?
 SimpleToadletServer.doRobotsLong=Pubblica un file /robots.txt allo scopo di 
tenere lontano Google, spiders, Wget, etc.
 SimpleToadletServer.enableInlinePrefetch=Abilita pre-ricezione (prefetching) 
di immagini inlinea (inline)?
 SimpleToadletServer.enableInlinePrefetchLong=Questo potrebbe essere utile se 
il browser utilizza un numero ridotto di connessioni per comunicare con il 
nodo. D'altra parte potrebbe non esserlo.
 SimpleToadletServer.enableJS=Permetti a FProxy di usare Javascript
-SimpleToadletServer.enableJSLong=Determina se FProxy pu? o meno fare uso di 
Javascript. Questa impostazione di solito va tenuta su 'falso'. Nota che i 
freesite non fanno uso di javascript nemmeno se qui abilitata.
+SimpleToadletServer.enableJSLong=Determina se FProxy pu? o meno fare uso di 
Javascript. Questa impostazione di solito va tenuta su 'falso'. Nota che i 
freesite non fanno uso di javascript nemmeno se qui abilitata.
 SimpleToadletServer.enablePersistentConnections=Abilita connessioni 
persistenti HTTP? (Leggere la descrizione)
 SimpleToadletServer.enablePersistentConnectionsLong=Non abilitare questa 
opzione tranne nel caso in cui il browser sia configurato per usare molte 
connessioni anche se sono persistenti.
 SimpleToadletServer.enabled=Abilita FProxy
 SimpleToadletServer.enabledLong=Abilita FProxy e relativi servizi HTTP
-SimpleToadletServer.illegalCSSName=Il nome CSS non pu? contenere i catarreri 
"barra" (/ slash) e "due punti" ( : colon)
+SimpleToadletServer.illegalCSSName=Il nome CSS non pu? contenere i catarreri 
"barra" (/ slash) e "due punti" ( : colon)
 SimpleToadletServer.panicButton=Mostra bottone Emergenza
 SimpleToadletServer.panicButtonLong=Mostra il bottone Emergenza nella pagina 
della Coda. Se usato, Il bottone Emergenza rimuove tutte le richieste che non 
hanno ricevuto conferma.
-SimpleToadletServer.passthroughMaxSize=Dimensione massima per pass-through 
trasparente in fproxy
-SimpleToadletServer.passthroughMaxSizeLong=Dimensione massima file per 
pass-through trasparente in fproxy
 SimpleToadletServer.port=Numero della porta FProxy
 SimpleToadletServer.portLong=Numero della porta FProxy
 SimpleToadletServer.ssl=Abilitare ssl?
 SimpleToadletServer.sslLong=Abilitare ssl?
-StartupToadlet.entropyErrorContent=Non c'? abbastanza entropia disponibile nel 
sistema... Freenet non si avvier? finch? non ne avr? racimolata abbastanza.
+StartupToadlet.entropyErrorContent=Non c'? abbastanza entropia disponibile nel 
sistema... Freenet non si avvier? finch? non ne avr? racimolata abbastanza.
 StartupToadlet.entropyErrorTitle=Entropia insufficiente!
 StartupToadlet.isStartingUp=Avviamento del nodo Freenet in corso, si prega di 
attendere.
 StartupToadlet.title=Avvio di Freenet in corso
@@ -1153,17 +1137,17 @@
 StatisticsToadlet.outputRate=Output: ${rate} al secondo (di ${max} al secondo)
 StatisticsToadlet.payloadOutput=Output Carico Utile: ${total} (${rate}/second) 
(${percent}%)
 StatisticsToadlet.peerStatsTitle=Statistiche peer
-StatisticsToadlet.priority=Priorit?
+StatisticsToadlet.priority=Priorit?
 StatisticsToadlet.requestOutput=Output richieste (carico utile escluso): CHK 
${chk} SSK ${ssk}.
 StatisticsToadlet.resendBytes=Bytes rispediti: ${total}
-StatisticsToadlet.routingDisabled=Indirizzamento traffico sospeso (il nodo ? 
attualmente connesso ma una delle due parti non accetta indirizzamento di 
traffico)
+StatisticsToadlet.routingDisabled=Indirizzamento traffico sospeso (il nodo ? 
attualmente connesso ma una delle due parti non accetta indirizzamento di 
traffico)
 StatisticsToadlet.routingDisabledShort=Indirizzamento Traffico Sospeso
 StatisticsToadlet.running=In funzione
 StatisticsToadlet.statisticGatheringTitle=Raccolta Statistiche
 StatisticsToadlet.swapOutput=Output Scambio: ${total}.
 StatisticsToadlet.threadDumpButton=Genera Thread Dump
 StatisticsToadlet.threads=Threads correnti: ${running}/${max}
-StatisticsToadlet.threadsByPriority=Thread in ordine di prorit?
+StatisticsToadlet.threadsByPriority=Thread in ordine di prorit?
 StatisticsToadlet.totalInput=Input Totale: ${total} (${rate}/second)
 StatisticsToadlet.totalOutput=Output Totale: ${total} (${rate}/second)
 StatisticsToadlet.totalOverhead=Totale overhead di non-richieste: ${rate}/sec 
(${percent}%).
@@ -1175,13 +1159,13 @@
 StatisticsToadlet.waiting=In attesa
 SymlinkerToadlet.symlinks=Link simbolici in ToadletServer
 SymlinkerToadlet.symlinksLong=Lista di "alias#target" che va a formare un 
gruppo di link simbolici
-TestnetHandler.cannotEnableDisableOnTheFly=Non ? possibile abilitare o 
disabilitare la modalit? testnet "al volo";  ? necessario riavviare il nodo ed 
ottenere nuove connessioni.
-TestnetHandler.enable=Abilita modalit? testnet (PERICOLO)
-TestnetHandler.enableLong=Abilita la modalit? testnet (PERICOLO). La modalit? 
testnet elimina l'anonimato per poter permettere agli sviluppatori di fare il 
debugging del nodo
+TestnetHandler.cannotEnableDisableOnTheFly=Non ? possibile abilitare o 
disabilitare la modalit? testnet "al volo";  ? necessario riavviare il nodo ed 
ottenere nuove connessioni.
+TestnetHandler.enable=Abilita modalit? testnet (PERICOLO)
+TestnetHandler.enableLong=Abilita la modalit? testnet (PERICOLO). La modalit? 
testnet elimina l'anonimato per poter permettere agli sviluppatori di fare il 
debugging del nodo
 TestnetHandler.port=Porta testnet
 TestnetHandler.portLong=Numero della porta testnet (-1 = listenPort+1000)
 TextModeClientInterfaceServer.allowedHosts=Host consentiti
-TextModeClientInterfaceServer.allowedHostsLong=Nomi host o indirizzi IP ai 
quali ? consentito connettersi a TMCI. Pu? essere una lista di nomi host e 
indirizzi IP separati da virgole, o anche IP in formato CIDR come 192.168.0.0/24
+TextModeClientInterfaceServer.allowedHostsLong=Nomi host o indirizzi IP ai 
quali ? consentito connettersi a TMCI. Pu? essere una lista di nomi host e 
indirizzi IP separati da virgole, o anche IP in formato CIDR come 192.168.0.0/24
 TextModeClientInterfaceServer.bindTo=Indirizzo IP collegato
 TextModeClientInterfaceServer.bindToLong=Indirizzo IP collegato
 TextModeClientInterfaceServer.enableInputOutput=Abilita stdout/stdin
@@ -1193,7 +1177,7 @@
 TextModeClientInterfaceServer.telnetPortNumber=Porta telnet
 TextModeClientInterfaceServer.telnetPortNumberLong=Porta TCP utlizzata dal 
server TMCI
 TimeSkewDetectedUserAlert.shortText=Il nodo ha rilevato una discrepanza 
temporale. Freenet potrebbe bloccarsi in strani modi!
-TimeSkewDetectedUserAlert.text=Una discrepanza temporale ? stata rilevata dal 
nodo. Questo ? un inconveniente grave; il nodo non potr? funzionare 
correttamente finch? non vi si sar? ovviato. Tra le cause pi? comuni, la 
modalit? powersafe mal configurata, cattiva sincronizzazione tra i client in 
rete, problemi di hardware.
+TimeSkewDetectedUserAlert.text=Una discrepanza temporale ? stata rilevata dal 
nodo. Questo ? un inconveniente grave; il nodo non potr? funzionare 
correttamente finch? non vi si sar? ovviato. Tra le cause pi? comuni, la 
modalit? powersafe mal configurata, cattiva sincronizzazione tra i client in 
rete, problemi di hardware.
 TimeSkewDetectedUserAlert.title=Discrepanza temporale rilevata!
 Toadlet.cancel=Cancella
 Toadlet.clickHere=Clicca qui
@@ -1211,9 +1195,9 @@
 Toadlet.returnToPrevPage=Torna alla pagina precedente
 Toadlet.returnToQueuepage=Torna alla pagina della coda
 Toadlet.tempRedirectWithReason=Redirect temporaneo: ${reason}
-Toadlet.unauthorized=L'accesso a questa pagina ? interdetto.
+Toadlet.unauthorized=L'accesso a questa pagina ? interdetto.
 Toadlet.unauthorizedTitle=Non Autorizzato
-Toadlet.yes=S?
+Toadlet.yes=S?
 ToadletContextImpl.cannotParseContentLength=errore nell' analisi 
contenuto-lunghezza: ${error}
 ToadletContextImpl.cannotParseContentLengthWithError=Impossibile interpretare 
contenuto-lunghezza: ${error}
 ToadletContextImpl.headersLineTooLong=Rigo troppo lungo dalla ricostruzione di 
headers
@@ -1235,23 +1219,23 @@
 TranslationToadlet.reEdit=Ri-modifica la traduzione
 TranslationToadlet.remove=Elimina
 TranslationToadlet.removeOverrideTitle=Elimina una chiave di traduzione
-TranslationToadlet.removeOverrideWarningTitle=Attenzione: la chiave di 
traduzione verr? eliminata!
+TranslationToadlet.removeOverrideWarningTitle=Attenzione: la chiave di 
traduzione verr? eliminata!
 TranslationToadlet.returnToTranslations=Torna alla pagina della traduzione
-TranslationToadlet.showEverything=Mostra tutto, incluse stringhe gi? tradotte
+TranslationToadlet.showEverything=Mostra tutto, incluse stringhe gi? tradotte
 TranslationToadlet.translationKeyLabel=Chiave di traduzione
 TranslationToadlet.translationUpdateTitle=Aggiornamento traduzione
 TranslationToadlet.translationUpdatedTitle=Traduzione aggiornata!
 TranslationToadlet.updateTranslationCommand=Aggiorna traduzione
-UnknownContentTypeException.explanation=Il nodo non ha informazioni su questo 
MIME type. Ci? potrebbe comportare una reazione pericolosa da parte del browser 
in risposta al download di questo file. Per esempio, molti formati possono 
contenere immagini o video inclusi (embedded) che vengono scaricati dal web: 
ci? espone l'utente al rischio di rivelare il proprio indirizzo IP ad un 
eventuale avversario (per esempio un avversario che gestisca il il sito web dal 
quale le immagini o video ecc. vengono scaricati, o uno che abbia in qualche 
modo ottenuto accesso ai log del sito stesso). Hyperlinks e scripting sono 
entrambi ugualmente pericolosi, per lo stesso motivo, ed anche per alcuni altri.
+UnknownContentTypeException.explanation=Il nodo non ha informazioni su questo 
MIME type. Ci? potrebbe comportare una reazione pericolosa da parte del browser 
in risposta al download di questo file. Per esempio, molti formati possono 
contenere immagini o video inclusi (embedded) che vengono scaricati dal web: 
ci? espone l'utente al rischio di rivelare il proprio indirizzo IP ad un 
eventuale avversario (per esempio un avversario che gestisca il il sito web dal 
quale le immagini o video ecc. vengono scaricati, o uno che abbia in qualche 
modo ottenuto accesso ai log del sito stesso). Hyperlinks e scripting sono 
entrambi ugualmente pericolosi, per lo stesso motivo, ed anche per alcuni altri.
 UnknownContentTypeException.title=Tipo di contenuto (content type) sconosciuto 
e pertanto potenzialmente pericoloso: ${type}
 UpdateDeployContext.cannotUpdateNoExtJar=Freenet-ext.jar non trovata in 
wrapper.conf: (freenet.jar trovata: ${mainFilename})
-UpdateDeployContext.cannotUpdateNoJars=Non ? stato possibile trovare i file 
jar di Freenet in wrapper.conf
-UpdateDeployContext.cannotUpdateNoMainJar=Non ? stato possibile trovare 
freenet.jar in wrapper.conf (freenet-ext.jar non trovata: ${extFilename})
+UpdateDeployContext.cannotUpdateNoJars=Non ? stato possibile trovare i file 
jar di Freenet in wrapper.conf
+UpdateDeployContext.cannotUpdateNoMainJar=Non ? stato possibile trovare 
freenet.jar in wrapper.conf (freenet-ext.jar non trovata: ${extFilename})
 UpdateDeployContext.updateCatastrophe=ERRORE CATASTROFICO: Eliminato ${old} ma 
impossibile rinominare ${new} in ${old} quindi IL NODO NON SI AVVIERA'! La 
soluzione consiste nel rinominare ${new}  in ${old} manualmente
-UpdateDeployContext.updateFailedCannotDeleteOldConfig=Non ? stato possibile 
eliminare ${old} quindi non ? possibile sovrascrivere. Aggiornamento fallito.
-UpdateDeployContext.updateFailedNonStandardConfig=Non ? stato possibile 
completare l'aggiornamento a causa della configurazione non-standard: written 
main=${main} ext=${ext} - Questo non dovrebbe accadere! Si prega di riportare 
l'accaduto agli sviluppatori includendo il file wrapper.conf
+UpdateDeployContext.updateFailedCannotDeleteOldConfig=Non ? stato possibile 
eliminare ${old} quindi non ? possibile sovrascrivere. Aggiornamento fallito.
+UpdateDeployContext.updateFailedNonStandardConfig=Non ? stato possibile 
completare l'aggiornamento a causa della configurazione non-standard: written 
main=${main} ext=${ext} - Questo non dovrebbe accadere! Si prega di riportare 
l'accaduto agli sviluppatori includendo il file wrapper.conf
 UpdatedVersionAvailableUserAlert.alsoDownloadedNewExtJar=Il nodo ha anche 
scaricato una nuova versione della extra jar di Freenet, versione ${version}
-UpdatedVersionAvailableUserAlert.armed=Il nodo verr? riavviato automaticamente 
dopo aver completato il download e verificato la nuova versione di Freenet.
+UpdatedVersionAvailableUserAlert.armed=Il nodo verr? riavviato automaticamente 
dopo aver completato il download e verificato la nuova versione di Freenet.
 UpdatedVersionAvailableUserAlert.clickToUpdateASAP=Clicca qui sotto per 
aggiornare il nodo dopo la verifica dell'aggiornamento.
 UpdatedVersionAvailableUserAlert.clickToUpdateNow=Clicca qui sotto per 
aggiornare il nodo immediatamente.
 UpdatedVersionAvailableUserAlert.downloadedNewExtJar=Il nodo ha scaricato una 
nuova versione della extra jar di Freenet, versione ${version}.
@@ -1261,12 +1245,12 @@
 UpdatedVersionAvailableUserAlert.fetchingNewNode=Il nodo sta scaricando una 
versione aggiornata di Freenet (versione nodo ${nodeVersion}).
 UpdatedVersionAvailableUserAlert.finalCheck=Il nodo sta eseguendo un controllo 
finale per verificare la sicurezza dell'aggiornamento (${count} of ${max}).
 UpdatedVersionAvailableUserAlert.notLatest=Sembra che il nodo non stia usando 
una versione aggiornata del software.
-UpdatedVersionAvailableUserAlert.shortArmed=In nodo sta scaricando una nuova 
versione di Freenet e si riavvier? una volta terminato il download.
-UpdatedVersionAvailableUserAlert.shortNotReadyNotArmed=Il nodo sta scaricando 
una nuova versione di Freenet, ma per poterla utilizzare ? necessaria la 
conferma da parte dell'utente.
-UpdatedVersionAvailableUserAlert.shortReadyNotArmed=Il nodo ha scaricato una 
nuova versione di Freenet ma potr? usarla solo dopo la conferma da parte dell' 
utente.
+UpdatedVersionAvailableUserAlert.shortArmed=In nodo sta scaricando una nuova 
versione di Freenet e si riavvier? una volta terminato il download.
+UpdatedVersionAvailableUserAlert.shortNotReadyNotArmed=Il nodo sta scaricando 
una nuova versione di Freenet, ma per poterla utilizzare ? necessaria la 
conferma da parte dell'utente.
+UpdatedVersionAvailableUserAlert.shortReadyNotArmed=Il nodo ha scaricato una 
nuova versione di Freenet ma potr? usarla solo dopo la conferma da parte dell' 
utente.
 UpdatedVersionAvailableUserAlert.title=E' disponibile una nuova versione 
stabile di Freenet
-UpdatedVersionAvailableUserAlert.updateASAPButton=Si prega di aggiornare al 
pi? presto possibile
-UpdatedVersionAvailableUserAlert.updateASAPQuestion=Riavviare il nodo dopo che 
l'aggiornamento ? stato completato?
+UpdatedVersionAvailableUserAlert.updateASAPButton=Si prega di aggiornare al 
pi? presto possibile
+UpdatedVersionAvailableUserAlert.updateASAPQuestion=Riavviare il nodo dopo che 
l'aggiornamento ? stato completato?
 UpdatedVersionAvailableUserAlert.updateNowButton=Aggiorna Adesso!
 UserAlert.apply=Conferma
 UserAlert.hide=Nascondi
@@ -1282,7 +1266,7 @@
 UserAlertManager.totalLabel=Totale:
 UserAlertManager.warningCountLabel=Avvertenze:
 UserAlertsToadlet.titleWithName=Avvertenze per ${name}
-WelcomeToadlet.activityTitle=Attivit? in corso
+WelcomeToadlet.activityTitle=Attivit? in corso
 WelcomeToadlet.alertsSummary=Sommario avvertenze
 WelcomeToadlet.arkFetchCount=ARK Fetchers: ${total}
 WelcomeToadlet.confirmAddBookmarkSubTitle=Conferma Aggiunta Sgnalibro
@@ -1299,20 +1283,20 @@
 WelcomeToadlet.extVersionWithRecommended=Freenet-ext Build #${build} (si 
raccomanda ${recbuild}) r${rev}
 WelcomeToadlet.fetch=Richiama
 WelcomeToadlet.fetchKeyLabel=Richiama una chiave
-WelcomeToadlet.finInsertSuccessWithKey=Il messaggio ? stato inserito in ${key}.
+WelcomeToadlet.finInsertSuccessWithKey=Il messaggio ? stato inserito in ${key}.
 WelcomeToadlet.finInsertedTitle=Inserzione
 WelcomeToadlet.finTitle=Inserzione Nota  Istantanea di Frost
 WelcomeToadlet.fromHeader=Da
 WelcomeToadlet.goToExternalLink=Vai al link specificato
 WelcomeToadlet.homepageFullTitleWithName=Homepage FProxy di ${name}
-WelcomeToadlet.ieWarning=E' stato rilevato l'uso di Microsoft Internet 
Explorer. Ci? potrebbe costituire un pericolo per l'anonimato dell'utente.
+WelcomeToadlet.ieWarning=E' stato rilevato l'uso di Microsoft Internet 
Explorer. Ci? potrebbe costituire un pericolo per l'anonimato dell'utente.
 WelcomeToadlet.ieWarningTitle=Rischio Sicurezza!
 WelcomeToadlet.insertCount=Inserzioni: ${total}
 WelcomeToadlet.insertFailedTitle=Inserzione fallita
-WelcomeToadlet.insertFailedWithMessage=L'inserzione ? fallita con il 
messaggio: ${message}
+WelcomeToadlet.insertFailedWithMessage=L'inserzione ? fallita con il 
messaggio: ${message}
 WelcomeToadlet.insertSucceededTitle=Inserzione Completata
 WelcomeToadlet.insertedTitle=Inserzione
-WelcomeToadlet.keyInsertedSuccessfullyWithKeyAndName=La chiave 
${link}${name}${/link} ? stata inserita.
+WelcomeToadlet.keyInsertedSuccessfullyWithKeyAndName=La chiave 
${link}${name}${/link} ? stata inserita.
 WelcomeToadlet.keyRequestLabel=Chiave:
 WelcomeToadlet.messageHeader=Messaggio
 WelcomeToadlet.nodeUpdateConfirm=Conferma: aggiornare il nodo Freenet?
@@ -1325,7 +1309,7 @@
 WelcomeToadlet.restartConfirm=Conferma: Riavvia nodo Freenet?
 WelcomeToadlet.restartConfirmTitle=Riavvia Nodo
 WelcomeToadlet.restartNode=Riavvia nodo
-WelcomeToadlet.restarting=Si prega di attendere durante il riavvio del nodo. 
Questa schermata  si aggiorner? automaticamente, fino a mostrare la pagina 
iniziale fi Freenet. Grazie di aver scelto Freenet.
+WelcomeToadlet.restarting=Si prega di attendere durante il riavvio del nodo. 
Questa schermata  si aggiorner? automaticamente, fino a mostrare la pagina 
iniziale fi Freenet. Grazie di aver scelto Freenet.
 WelcomeToadlet.restartingTitle=Riavvio del nodo Freenet in corso.
 WelcomeToadlet.shutdown=Arresta
 WelcomeToadlet.shutdownConfirm=Conferma: Arresta nodo Freenet?
@@ -1336,24 +1320,24 @@
 WelcomeToadlet.startIndexHeader=Indice dal quale iniziare
 WelcomeToadlet.subjectHeader=Oggetto
 WelcomeToadlet.targetBoardHeader=Target Board
-WelcomeToadlet.testnetWarning=gira in modalit? testnet. DISTRUGGE l'anonimato!
-WelcomeToadlet.testnetWarningTitle=Modalit? Testnet
+WelcomeToadlet.testnetWarning=gira in modalit? testnet. DISTRUGGE l'anonimato!
+WelcomeToadlet.testnetWarningTitle=Modalit? Testnet
 WelcomeToadlet.thanks=Grazie di aver scelto Freenet.
-WelcomeToadlet.threadDumpNotUsingWrapper=Non ? possibile generare un thread 
dump se il nodo non sta girando nel wrapper
+WelcomeToadlet.threadDumpNotUsingWrapper=Non ? possibile generare un thread 
dump se il nodo non sta girando nel wrapper
 WelcomeToadlet.threadDumpSubTitle=Generazione di Thread Dump
 WelcomeToadlet.threadDumpTitle=Genera Thread Dump
-WelcomeToadlet.threadDumpWithFilename=E' stato generato un thread dump, esso ? 
disponibile in ${filename}.
+WelcomeToadlet.threadDumpWithFilename=E' stato generato un thread dump, esso ? 
disponibile in ${filename}.
 WelcomeToadlet.transferringRequestCount=Richieste in corso di trasferimento: 
${total}
 WelcomeToadlet.update=Aggiorna
-WelcomeToadlet.updating=Il nodo Freenet ? stato aggiornato e sar? ora 
riavviato automaticamente. Il processo di riavvio pu? durare fino a dieci 
minuti perch? il nodo prima di aggiornare deve controllare se sia presente una 
chiave di revoca.
+WelcomeToadlet.updating=Il nodo Freenet ? stato aggiornato e sar? ora 
riavviato automaticamente. Il processo di riavvio pu? durare fino a dieci 
minuti perch? il nodo prima di aggiornare deve controllare se sia presente una 
chiave di revoca.
 WelcomeToadlet.updatingThanks=Grazie per usare Freenet
 WelcomeToadlet.updatingTitle=Aggiornamento del nodo in corso
 WelcomeToadlet.uriWouldHaveBeen=La URI sarebbe stata: ${uri}
 WelcomeToadlet.version=Freenet ${fullVersion} Build ${build} r${rev}
 WelcomeToadlet.versionHeader=Informazioni sulla Versione e Controllo del Nodo
 WelcomeToadlet.writtenDatabaseStats=Le statistiche di runtime del database 
sono state scritte nel file di log del wrapper
-WrapperConfig.wrapper.java.maxmemory.long=Limita la quantit? massima di 
memoria utilizzabile da Freenet. Freenet ha bisogno di molta pi? memoria se si 
hanno molti e/o grossi file in coda di dowload/upload,  ed in misura minore se 
il nodo ? dotato di un datastore di dimensioni abbondanti.  I cambiamenti 
saranno effettivi dopo il riavvio del nodo.
+WrapperConfig.wrapper.java.maxmemory.long=Limita la quantit? massima di 
memoria utilizzabile da Freenet. Freenet ha bisogno di molta pi? memoria se si 
hanno molti e/o grossi file in coda di dowload/upload,  ed in misura minore se 
il nodo ? dotato di un datastore di dimensioni abbondanti.  I cambiamenti 
saranno effettivi dopo il riavvio del nodo.
 WrapperConfig.wrapper.java.maxmemory.short=Memoria massima (in megabytes)
 testing.test=test${test1}test${test2}test
-?BookmarkEditorToadlet.pasteOrCancel=Click su un'icona incolla o cancella.
+?BookmarkEditorToadlet.pasteOrCancel=Click su un'icona incolla o cancella.
 End

Modified: branches/db4o/freenet/src/freenet/l10n/freenet.l10n.se.properties
===================================================================
--- branches/db4o/freenet/src/freenet/l10n/freenet.l10n.se.properties   
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/l10n/freenet.l10n.se.properties   
2008-09-24 23:54:07 UTC (rev 22829)
@@ -1,3 +1,5 @@
+Announcer.announceAlertShort=Noden f?rs?ker kontakta Freenet n?tverket, under 
tiden kommer vissa saker att g? sakta.
+Bookmark.noName=inget namn
 BookmarkEditorToadlet.addBookmark=L?gg till bokm?rke
 BookmarkEditorToadlet.addCategory=L?gg till kategori
 BookmarkEditorToadlet.addNewBookmark=L?gg till bokm?rke
@@ -23,9 +25,10 @@
 BookmarkEditorToadlet.editBookmarkTitle=Redigera bokm?rke
 BookmarkEditorToadlet.editCategoryTitle=Redigera kategori
 BookmarkEditorToadlet.error=Fel
-BookmarkEditorToadlet.invalidKey=Freenet nyckeln ?r ogiltig.
+BookmarkEditorToadlet.hasAnActivelinkLabel=Har Freesidan en aktiv l?nk (Bild)?
+BookmarkEditorToadlet.invalidKey=Freenetnyckeln ?r ogiltig.
 BookmarkEditorToadlet.invalidKeyTitle=Felaktig nyckel
-BookmarkEditorToadlet.invalidKeyWithReason=Felaktig Freenet nyckel.
+BookmarkEditorToadlet.invalidKeyWithReason=Felaktig Freenetnyckel.
 BookmarkEditorToadlet.keyLabel=Nyckel :
 BookmarkEditorToadlet.moveDown=Ner
 BookmarkEditorToadlet.moveUp=Upp
@@ -37,6 +40,7 @@
 BookmarkEditorToadlet.save=Spara
 BookmarkEditorToadlet.title=Inst?llningar f?r bokm?rken
 BookmarkItem.bookmarkUpdated=Den bokm?rkta sidan ${name} har uppdaterats till 
utg?va ${edition}.
+BookmarkItem.bookmarkUpdatedShort=Freesite uppdaterad: ${name}
 BookmarkItem.bookmarkUpdatedTitle=Bokm?rke uppdaterat: ${name}
 BookmarkItem.bookmarkUpdatedWithLink=Den bokm?rkta sidan 
${link}${name}${/link} har uppdaterats till utg?va ${edition}.
 BookmarkItem.deleteBookmarkUpdateNotification=Radera meddelande
@@ -44,9 +48,13 @@
 BookmarkManager.list=Bokm?rken
 BookmarkManager.listLong=En lista med dina bokm?rken.
 BookmarkManager.malformedBookmark=Felaktigt bokm?rke
+BuildOldAgeUserAlert.tooOldShort=Noden anv?nder en f?r gammal version av 
Freenet och kan d?rf?r inte ansluta till n?gra peers! V?nligen uppdatera noden!
 BuildOldAgeUserAlert.tooOldTitle=F?r gammal version
+CSSTokenizerFilter.deletedUnofficialIdent=Radera inofficiell identitet
 CSSTokenizerFilter.deletedUnofficialIdentWithURL=Raderade inofficiell 
identitet med url
 CSSTokenizerFilter.unknownAtIdentifierLabel=Ok?nd @identifierare:
+ClockProblemDetectedUserAlert.shortText=Din dators klocka verkar inte g? 
korrekt, s? Freenet kan inte ansluta.
+ClockProblemDetectedUserAlert.title=Din dators klocka verkar inte g? korrekt.
 ConfigToadlet.appliedFailureExceptions=Inst?llningarna ?ndrades med f?ljande 
undantag:
 ConfigToadlet.appliedFailureTitle=Inst?llningarna kan inte till?mpas
 ConfigToadlet.appliedSuccess=?ndringarna sparades.
@@ -59,16 +67,20 @@
 ConfigToadlet.fullTitle=Freenets Nod inst?llningar f?r ${name}
 ConfigToadlet.homepage=Nod hemsida
 ConfigToadlet.logger=loggning
+ConfigToadlet.node=nod
 ConfigToadlet.pluginmanager=Pluginhanterare
 ConfigToadlet.pluginmanager2=pluginhanterare2
 ConfigToadlet.possibilitiesTitle=Vad vill du g?ra nu?
 ConfigToadlet.reset=?terst?ll
+ConfigToadlet.restartNode=Starta om
 ConfigToadlet.returnToNodeConfig=?terv?nd till inst?llningar
 ConfigToadlet.returnToNodeHomepage=?terv?nd till nodens hemsida
 ConfigToadlet.shortTitle=Inst?llningar
 ConfigToadlet.title=Freenets Nod inst?llningar
 ConfigToadlet.true=ja
 ConfigToadlet.unauthorized=Du har inte r?ttigheter att bes?ka den h?r sidan.
+ConfigToadlet.wrapperSettingsTitle=Wrapper inst?llningar
+ConfigToadlet.node.load=nod.belastning
 ConfigurablePersister.doesNotExistCannotCreate=Filen existerar redan och kan 
inte skapas
 ConfigurablePersister.existsCannotReadWrite=Filen existerar och kan inte 
l?sas/skrivas
 ConnectionsToadlet.nodeStatus.BACKED OFF=UPPTAGEN
@@ -76,7 +88,9 @@
 ConnectionsToadlet.nodeStatus.CLOCK PROBLEM=KLOCK PROBLEM
 ConnectionsToadlet.nodeStatus.CONNECTED=ANSLUTEN
 ConnectionsToadlet.nodeStatus.CONNECTION ERROR=ANSLUTNINGS FEL
+ConnectionsToadlet.nodeStatus.DISABLED=AVST?NGD
 ConnectionsToadlet.nodeStatus.DISCONNECTED=ICKE ANSLUTEN
+ConnectionsToadlet.nodeStatus.DISCONNECTING=KOPPLAR NER
 ConnectionsToadlet.nodeStatus.LISTEN ONLY=ENDAST LYSSNA
 ConnectionsToadlet.nodeStatus.LISTENING=LYSSNAR
 ConnectionsToadlet.nodeStatus.NEVER CONNECTED=ALDRIG ANSLUTEN
@@ -84,9 +98,13 @@
 ConnectionsToadlet.nodeStatus.TOO OLD=F?R GAMMAL
 ConnectionsToadlet.nodeStatus.UNKNOWN STATUS=OK?ND STATUS
 ConnectivityToadlet.addressTitle=Adress
+ConnectivityToadlet.connectivity=Internetanslutningar
+ConnectivityToadlet.connectivityTitle=Anslutningar
 ConnectivityToadlet.local=LOKAL
 ConnectivityToadlet.noreply=INGET SVAR
 ConnectivityToadlet.sentReceivedTitle=Skickade / Mottagna paket
+ConnectivityToadlet.summaryTitle=Anslutningar
+ConnectivityToadlet.title=Internet anslutningar f?r ${nodeName}
 ContentDataFilter.unknownCharset=Sidan som ska visas anv?nder en ok?nd 
teckenupps?ttning och kommer d?rf?r inte att kunna filtreras, detta kan 
?ventyra din anonymitet.
 ContentDataFilter.unknownCharsetTitle=Ok?nd teckenupps?ttning!
 ContentDataFilter.warningUnknownCharsetTitle=Varning: Ok?nd teckenupps?ttning 
(${charset})
@@ -118,6 +136,8 @@
 DarknetConnectionsToadlet.confirmRemoveNode=?r du s?ker p? att du vill ta bort 
"${name}"? Innan noden har haft  minst en veckas nedtid s? ?r det inte 
rekommenderat att ta bort den d? anv?ndaren kanska bara ?r tillf?lligt inaktiv, 
v?nta g?rna n?gra dagar till innan du tar bort den.
 DarknetConnectionsToadlet.confirmRemoveNodeTitle=Godk?nn
 DarknetConnectionsToadlet.confirmRemoveNodeWarningTitle=Nod borttagning
+DarknetConnectionsToadlet.connError=Anslutningen misslyckades (buggig nod?)
+DarknetConnectionsToadlet.connErrorShort=Anslutnings Fel
 DarknetConnectionsToadlet.connected=Anslutna: Noder som tar emot f?rfr?gningar.
 DarknetConnectionsToadlet.connectedShort=Ansluten
 DarknetConnectionsToadlet.disabled=Inaktiverad: Denna nod ?r inaktiverad och 
anslutning till den kommer ej ske.
@@ -181,6 +201,8 @@
 DarknetConnectionsToadlet.versionTitle=Version
 ExtOldAgeUserAlert.extTooOldTitle=Freenet-ext ?r f?r gammal
 FProxyToadlet.abortToHomepage=Avbryt och ?terv?nd till FProxys startsida
+FProxyToadlet.alerts=Detaljerade upplysningar
+FProxyToadlet.alertsTitle=Upplysningar
 FProxyToadlet.backToFProxy=${link}Klicka h?r${/link} f?r att g? till FProxys 
startsida.
 FProxyToadlet.backToReferrer=${link}Klicka h?r${/link} f?r att g? tillbaka.
 FProxyToadlet.cantBindPort=Kan inte knyta FProxy till porten!
@@ -192,7 +214,7 @@
 FProxyToadlet.downloadInBackgroundToDisk=Ladda ner i bakgrunden och spara i 
downloads mappen
 FProxyToadlet.errorIsFatal=Det h?r ?r ett fatalt fel. Det ?r osannolikt att 
ett nytt f?rs?k kommer l?sa problemet.
 FProxyToadlet.errorWithReason=Fel: ${error}
-FProxyToadlet.expectedKeyButGot=Noden f?rv?ntade sig en Freenet nyckel, men 
fick :
+FProxyToadlet.expectedKeyButGot=Noden f?rv?ntade sig en Freenetnyckel, men 
fick :
 FProxyToadlet.expectedMimeType=F?rv?ntad MIME typ: ${mime}
 FProxyToadlet.explanationTitle=F?rklaring
 FProxyToadlet.fetchLargeFileAnywayAndDisplay=H?mta ?nd? och visa filen i 
webbl?saren
@@ -209,7 +231,7 @@
 FProxyToadlet.invalidKeyTitle=Ogiltig nyckel
 FProxyToadlet.invalidKeyWithReason=Ogiltig nyckel: ${reason}
 FProxyToadlet.largeFile=Stor fil
-FProxyToadlet.largeFileExplanationAndOptions=Freenet nyckeln du efterfr?gar ?r 
en stor fil. Filer i den h?r storleken kan oftast inte skickas direkt till din 
webbl?sare d? det tar f?r l?nge f?r Freenet att h?mta dem. F?ljande val finns:
+FProxyToadlet.largeFileExplanationAndOptions=Freenetnyckeln du efterfr?gar ?r 
en stor fil. Filer i den h?r storleken kan oftast inte skickas direkt till din 
webbl?sare d? det tar f?r l?nge f?r Freenet att h?mta dem. F?ljande val finns:
 FProxyToadlet.mimeType=MIME typ: ${mime}
 FProxyToadlet.notEnoughMetaStrings=Inte tillr?ckligt med meta-str?ngar
 FProxyToadlet.notFoundTitle=Ej hittad
@@ -220,6 +242,7 @@
 FProxyToadlet.openPossRSSAsPlainText=${link}Klicka h?r${/link} f?r att ?ppna 
filen som ren text (Detta kan vara ${bold}farligt${/bold} om du anv?nder IE7 
eller FF2).
 FProxyToadlet.openRSSAsRSS=${link}Klicka h?r${/link} f?r att ?ppna filen som 
RSS (detta ?r ${bold}farligt${/bold} ifall upphovsmannen ?r ondsint d? Freenet 
inte filtrerar RSS ?nnu).
 FProxyToadlet.openRSSForce=${link}Klicka h?r${/link} f?r att ?ppna filen som 
${mime} (Detta kan vara ${bold}farligt${/bold} om du anv?nder IE7 eller FF2).
+FProxyToadlet.opennet=Hantera anslutningar till fr?mlingar
 FProxyToadlet.opennetTitle=Fr?mlingar
 FProxyToadlet.options=Dina valm?jligheter ?r:
 FProxyToadlet.pathNotFound=S?kv?gen finns inte.
@@ -260,6 +283,8 @@
 FcpServer.isEnabledLong=FCP (Freenet Client Protocol) anv?nds av externa 
program s?som Frost, Thaw och FreeMulET.
 FcpServer.portNumber=FCP port
 FcpServer.portNumberLong=FCP port nummer.
+FcpServer.ssl=Aktivera ssl?
+FcpServer.sslLong=Aktivera ssl?
 FetchException.longError.10=Filen kunde inte hittas i arkivet
 FetchException.longError.13=Datan kunde inte hittas
 FetchException.longError.15=En nod var ?verbelastad eller tog f?r l?ng tid p? 
sig
@@ -269,7 +294,9 @@
 FetchException.longError.22=Metadatan ?r f?r stor
 FetchException.longError.23=F?r m?nga block per segment
 FetchException.longError.25=Avbruten
+FetchException.longError.27=Permanent omdirigering: anv?nd den nya URI;n
 FetchException.shortError.13=Datan kunde inte hittas
+FetchException.shortError.14=S?kv?gen kunde inte hittas
 FetchException.shortError.17=Internt fel
 FetchException.shortError.18=?verf?ringen misslyckades
 FetchException.shortError.20=Felaktig URI
@@ -286,34 +313,53 @@
 FileOffer.fileLabel=Fil:
 FileOffer.mimeLabel=MIME Typ:
 FileOffer.offeredFileHeader=${name} f?rs?ker skicka en fil till dig:
+FileOffer.offeredFileShort=Din v?n ${node} f?rs?ker skicka filen ${filename}.
 FileOffer.rejectTransferButton=Avvisa ?verf?ring
 FileOffer.senderLabel=Avs?ndare:
 FileOffer.sizeLabel=Storlek:
 FileOffer.succeededReceiveHeader=?verf?ringen av ${filename} fr?n ${node} 
lyckades.
 FileOffer.succeededReceiveTitle=Filen togs emot utan problem
+FirstTimeWizardToadlet.bandwidthLimit=Bandbreddsbegr?nsning
+FirstTimeWizardToadlet.clickContinue=Klicka h?r f?r att forts?tta.
 FirstTimeWizardToadlet.congratz=V?lkommen till Freenet!
 FirstTimeWizardToadlet.connectToStrangers=Anslut till fr?mlingar?
 FirstTimeWizardToadlet.continue=Forts?tt
+FirstTimeWizardToadlet.datastoreSize=Storlek f?r datalagring
+FirstTimeWizardToadlet.enableOpennet=K?nner du n?gon som redan anv?nder 
Freenet?
+FirstTimeWizardToadlet.fivePercentDisk=(= 5% av ledigt h?rddisk utrymme)
+FirstTimeWizardToadlet.memoryLimit=Minnesanv?ndning
 FirstTimeWizardToadlet.noNetworkIF=Inget extra n?tverkskort kunde hittas
+FirstTimeWizardToadlet.opennetNo=Ja, Jag har minst 5 v?nner som redan anv?nder 
Freenet och kommer l?gga till dem som v?nner.
+FirstTimeWizardToadlet.opennetYes=Jag vill att noden automatiskt ska hitta 
fr?mlingar att ansluta till.
+FirstTimeWizardToadlet.tenPercentDisk=(= 10% av ledigt h?rddisk utrymme)
+FirstTimeWizardToadlet.warningTitle=Varning!
 FproxyToadlet.dangerousRSSTitle=Potentionellt farligt ineh?ll (RSS)
 GIFFilter.notGif=Filen du f?rs?ker h?mta ?r inte en GIF. Det kan vara n?got 
annat filformat som din webbl?sare kanske hanterar p? ett farligt s?tt s? 
d?rf?r har vi blockerat den.
 GIFFilter.tooShort=Filen ?r f?r kort f?r att vara en GIF.
 GIFFilter.tooShortTitle=F?r kort
 HTMLFilter.deletedUnknownStyle=Raderade ok?nd stil
 HTMLFilter.unknownTag=ok?nd tagg ${tag}
+IPDetectorPluginManager.connectionProblems=Problem att ansluta:
 IPDetectorPluginManager.direct=Du verkar vara direkt ansluten till internet. 
Anslutningar till andra Freenet noder b?r ske utan n?gra problem.
 IPDetectorPluginManager.noConnectivity=Din internet anslutning verkar inte 
st?dja UPD.Om inte detta ?r en felbed?mmning s? ?r det inte troligt att du kan 
anv?nda Freenet.
+IPDetectorPluginManager.noConnectivityTitle=Ingen UDP anslutning
+IPDetectorPluginManager.noConnectivityshort=Allvarliga anslutningsproblem: 
Ingen UDP anslutning, Freenet kommer inte att fungera.
 IPUndetectedUserAlert.detecting=Freenet f?rs?ker f?r tillf?llet detektera din 
externa IP adress. Om detta tar mer ?n n?gra minuter s? ?r n?got fel.
+IPUndetectedUserAlert.detectingShort=Freenet f?rs?ker att detektera din 
externa IP adress.
+IPUndetectedUserAlert.detectingWithConfigLink=Freenet f?rs?ker att uppt?cka 
din externa IP adress, om detta tar mer ?n n?gra minuter s? ?r n?got fel och du 
kan d? tempor?rt ange din IP adress ${link}configuration parameter${/link}.
 IPUndetectedUserAlert.suggestForwardPort=Det ?r ocks? en god ide att 
vidarebefodra porten ${port} (UDP) i din router f?r att g?ra det l?tt att 
ansluta till din nod.
 IPUndetectedUserAlert.suggestForwardTwoPorts=Det ?r ocks? en god ide att 
vidarebefodra portarna ${port1} och ${port2} (UDP) i din router f?r att g?ra 
det l?tt att ansluta till din nod.
+IPUndetectedUserAlert.unknownAddressShort=Din IP adress kunde inte 
fastst?llas. Du kan f? problem att ansluta till Freenet.
 IPUndetectedUserAlert.unknownAddressTitle=Ok?nd extern adress
 InsertException.longError.10=Avbruten av anv?ndaren
 InsertException.longError.3=Internt fel
 InsertException.shortError.1=Felaktig URI
 InsertException.shortError.10=Avbruten
 InsertException.shortError.3=Internt fel
+InsertException.shortError.5=s?kv?gen kunde inte hittas
 JPEGFilter.notJpeg=Filen du f?rs?ker h?mta ?r inte en JPEG. Det kan vara n?got 
annat filformat som din webbl?sare kanske hanterar p? ett farligt s?tt s? 
d?rf?r har vi blockerat den.
 JPEGFilter.tooShort=Filen ?r f?r liten f?r att vara en JPEG bild.
+JPEGFilter.tooShortTitle=F?r kort
 KnownUnsafeContentTypeException.dangerousLinksLabel=Farliga l?nkar:
 KnownUnsafeContentTypeException.dangerousMetadataLabel=Farlig metadata:
 KnownUnsafeContentTypeException.dangerousScriptsLabel=Farligt skript:
@@ -344,6 +390,7 @@
 LogConfigHandler.rotationInterval=Tidsintervall f?r logg rotation
 LogConfigHandler.rotationIntervalLong=Logg rotations intervall - Tidsintervall 
f?r logg rotation. Vi sparar de senaste 2 logg filerna (Nuvarande och 
f?reg?ende) ?ldre logg filer komprimeras och sparas. Max disk utrymme f?r 
sparade logg filer st?lls in separat.
 LoggerHook.unrecognizedPriority=Ok?nd prioritet: ${name}.
+MeaningfulNodeNameUserAlert.noNodeNickShort=Du har inte namngett din nod.
 MeaningfulNodeNameUserAlert.noNodeNickTitle=Du har inte angett ett namn till 
din nod.
 N2NTMToadlet.composingMessageLabel=Skriv meddelande som ska skickas till 
f?ljande:
 N2NTMToadlet.delayed=Upptagen: S?ndning av meddelande kan vara f?rsenad
@@ -352,6 +399,7 @@
 N2NTMToadlet.failedTitle=Misslyckades
 N2NTMToadlet.friends=V?nner
 N2NTMToadlet.homepage=Hemsida
+N2NTMToadlet.noSuchFileOrCannotRead=Kan inte skicka filen: L?sfel eller s? 
finns den inte.
 N2NTMToadlet.peerName=Nod namn
 N2NTMToadlet.peerNotFoundTitle=Noden hittades inte
 N2NTMToadlet.peerNotFoundWithHash=Noden med f?ljande hash kod 
\u201c${hash}\u201d kunde inte hittas.
@@ -370,6 +418,7 @@
 N2NTMToadlet.unauthorized=Du har inte r?ttigheter att bes?ka den h?r sidan.
 N2NTMUserAlert.delete=Radera
 N2NTMUserAlert.header=Avs?ndare : ${from} | Skrivet : ${composed} | Skickat : 
${sent} | Mottaget : ${received}
+N2NTMUserAlert.headerShort=Meddelande fr?n ${from}
 N2NTMUserAlert.reply=Svara
 N2NTMUserAlert.title=Nod till Nod Text meddelande nummer ${number} fr?n 
${peername} (${peer})
 Node.bandwidthLimitMustBePositiveOrMinusOne=Bandbreddsbegr?nsningen till noden 
m?ste vara ?ver 0 eller -1 som betyder 4 * uppladdningshastigheten
@@ -380,6 +429,8 @@
 Node.bwlimitMustBePositive=Bandbreddsbegr?nsningen m?ste vara h?gre ?n 0
 Node.databaseMemory=Max utrymme f?r freenets databas
 Node.disableHangCheckers=Avativera alla h?ngningskontroller
+Node.enableARKs=Aktivera ARKs? (ST?NG EJ AV!)
+Node.enableARKsLong=Aktivera ARKs? (ST?NG EJ AV!).
 Node.errorApplyingConfig=Ett fel uppstod n?r de nya inst?llningarna skulle 
anv?ndas : ${error}
 Node.extraPeerDir=mapp till extra peer data
 Node.extraPeerDirLong=Mapp f?r extra peer data
@@ -390,7 +441,7 @@
 Node.l10nLanguageLong=Den h?r inst?llningen ?ndrar spr?ket i din nods 
web-gr?nssnitt. Vissa ?vers?ttningar kan beh?va en omstart f?r att fungera.
 Node.maxHTL=Max HTL
 Node.maxOpennetPeers=Maximalt antal Opennet noder
-Node.maxOpennetPeersLong=Maximalt antal Opennet noder (ska vara mellan 0 till 
och med 20)
+Node.maxOpennetPeersLong=Maximalt antal Opennet noder (ska vara mellan 0 till 
och med 20, antalet anslutningar till v?nner kommer dras bort fr?n det 
inst?llda v?rdet)
 Node.maxOpennetPeersMustBeTwentyOrLess=F?r ej vara ?ver 20
 Node.mustBePositive=V?rdet m?ste vara positivt
 Node.nodeDir=Nod mapp
@@ -400,6 +451,7 @@
 Node.oneConnectionPerIP=Begr?nsa till en anslutning per adress?
 Node.outBWLimit=Maximal uppladningshastighet (bytes per sekund)
 Node.outBWLimitLong=Maximal uppladningshastighet (bytes per sekund), noden ska 
n?stan aldrig ?verskrida detta v?rde.
+Node.passOpennetPeersThroughDarknet=Skicka opennet referenser genom darknet 
noder?
 Node.port=FNP port (UDP)
 Node.portLong=UDP port f?r nod-till-nod kommunikation (Freenet Node Protocol)
 Node.storeDirectory=Mapp f?r datalagring
@@ -411,11 +463,14 @@
 NodeClientCore.downloadAllowedDirs=Mapp/ar dit nedladdning ?r till?ten
 NodeClientCore.downloadDir=Nedladdningsmapp
 NodeClientCore.downloadDirLong=f?rvald nedladdningsmapp
+NodeClientCore.encryptTempBuckets=Kryptera de tempor?ra filerna? L?T VARA!
 NodeClientCore.fileForClientStats=Fil d?r klient statistik lagras
 NodeClientCore.maxUSKFetchers=Maximalt antal USK h?mtare
 NodeClientCore.maxUSKFetchersLong=Maximalt antal USK h?mtare
 NodeClientCore.maxUSKFetchersMustBeGreaterThanZero=V?rdet m?ste vara st?rre ?n 
noll
 NodeClientCore.movingTempDirOnTheFlyNotSupported=Flytt av temp mappen kan inte 
g?ras n?r noden ?r ig?ng
+NodeClientCore.startingUpShort=Freenet startas, vissa saker kanske inte 
fungerar ?nnu och andra kan g? sakta.
+NodeClientCore.startingUpTitle=Freenet startas
 NodeClientCore.tempDir=Mapp f?r tempor?ra filer
 NodeClientCore.tempDirLong=Mapp f?r tempor?ra filer.
 NodeClientCore.uploadAllowedDirs=Mappar som uppladdning till?ts fr?n
@@ -447,10 +502,18 @@
 NodeUpdateManager.noUpdateWithoutWrapper=Kan inte uppdatera eftersom Freenet 
inte k?rs med wrappern
 NodeUpdateManager.updateCatastropheTitle=Katastrofalt fel vid uppdatering!
 NodeUpdateManager.updateFailed=Uppdateringen misslyckades: ${reason}
+NodeUpdateManager.updateFailedShort=Uppdateringen misslyckades: ${reason}
 NodeUpdateManager.updateFailedTitle=Uppdateringen misslyckades!
 NodeUpdateManager.updateURI=Adress d?r noden letar efter uppdateringar
 NodeUpdateManager.updateURILong=Adress d?r noden letar efter uppdateringar
+OpennetUserAlert.warningShort=Os?kert l?ge ?r aktiverat.
+OpennetUserAlert.warningTitle=Varning: Os?kert l?ge ?r aktiverat: Din nod 
kommer att ansluta till fr?mlingar
 PNGFilter.invalidHeader=Filen du f?rs?ker h?mta ?r inte en PNG. Det kan vara 
n?got annat filformat som din webbl?sare kanske hanterar p? ett farligt s?tt s? 
d?rf?r har vi blockerat den.
+PNGFilter.invalidHeaderTitle=Ingen PNG - ogiltigt filhuvud
+PageMaker.modeAdvanced=Avancerat gr?nssnitt
+PageMaker.modeAdvancedTooltip=Ett avancerat gr?nssnitt som bara erfarna 
Freenet anv?ndare och utvecklare beh?ver anv?nda
+PageMaker.modeSimple=Enkelt gr?nssnitt
+PageMaker.modeSimpleTooltip=Ett enkelt gr?nssnitt som alla kan anv?nda
 PeerManagerUserAlert.connErrorTitle=Vissa noder kan inte ansluta
 PeerManagerUserAlert.noConnsTitle=Inga ?ppna anslutningar
 PeerManagerUserAlert.noPeersTitle=Inga peers hittades
@@ -465,6 +528,7 @@
 PluginManager.loadedPlugins=Plugins som ska laddas vid uppstart
 PluginManager.loadedPluginsLong=En lista med plugins som ska startas samtidigt 
som noden.
 PluginManager.pluginLoadingFailed=${name} kunde inte laddas
+PluginManager.pluginLoadingFailedShort=Kunde inte ladda pluginen ${name}!
 PluginManager.pluginLoadingFailedTitle=Kunde inte ladda plugin!
 PluginManager.pluginLoadingFailedWithMessage=${name} kunde inte laddas: 
${message}
 PluginManager.pluginReqNewerJVM=Pluginen ${name} verkar kr?va en nyare JVM. 
V?nligen installera minst Sun java 1.5, eller ta bort pluginen.
@@ -490,10 +554,13 @@
 PproxyToadlet.cancel=Avbryt
 PproxyToadlet.changeReloadOnStartup=?ndra
 PproxyToadlet.classNameTitle=Klass namn
+PproxyToadlet.downloadNotAllowedFromRemoteServer=Nedladdning av plugins ?r 
endast till?ten fr?n v?r server.
 PproxyToadlet.internalIDTitle=Internt ID
 PproxyToadlet.loadOfficialPlugin=Starta en officiell plugin
+PproxyToadlet.loadOtherPlugin=L?gg till en inofficiell plugin
 PproxyToadlet.loadPluginLabel=Plugin att ladda:
 PproxyToadlet.noPlugins=Inga plugins laddade
+PproxyToadlet.pluginNotDownloaded=Pluginen kunde inte laddas.
 PproxyToadlet.pluginNotFoundReloadTitle=Pluginen kunde inte hittas (laddar om)
 PproxyToadlet.pluginStopping=Pluginen stoppas
 PproxyToadlet.pluginUnloaded=Plugin stoppad
@@ -508,11 +575,14 @@
 PproxyToadlet.startedAtTitle=Startad vid
 PproxyToadlet.startingPluginName=Plugin namn
 PproxyToadlet.startingPluginStatus=Status
+PproxyToadlet.startingPluginTime=?tg?ngen tid
 PproxyToadlet.startingPluginsTitle=Startar Plugin
 PproxyToadlet.unauthorized=Du har inte beh?righet att bes?ka den h?r sidan.
+PproxyToadlet.unauthorizedTitle=Obeh?rig ?tkomst
 PproxyToadlet.unload=Stoppa
 PproxyToadlet.unloadPluginTitle=Stoppa plugin?
 PproxyToadlet.unloadPluginWithName=Vill du verkligen stoppa ${name}?
+PproxyToadlet.versionTitle=Version
 PproxyToadlet.startingPluginStatus.downloading=Laddar ner
 PproxyToadlet.startingPluginStatus.starting=startar
 QueueToadlet.DUinProgress=P?g?ende mapp uppladdningar
@@ -528,6 +598,9 @@
 QueueToadlet.completedUDirectory=Slutf?rda mapp uppladdningar (${size})
 QueueToadlet.delete=Ta bort
 QueueToadlet.download=Ladda ner
+QueueToadlet.downloadFiles=Mass nedladdningar
+QueueToadlet.downloadFilesInstructions=Du kan klistra in en lista med nycklar 
att ladda ner i boxen nedanf?r (en per linje)
+QueueToadlet.downloadSucceededTitle=Nedladdning klar: ${filename}
 QueueToadlet.emergency=N?dfall
 QueueToadlet.errorAccessDenied=Fel: ?tkomst nekad!
 QueueToadlet.errorAccessDeniedFile=De nuvarande inst?llningarna medger inte 
uppladdning av "${file}".
@@ -566,12 +639,13 @@
 QueueToadlet.insertFileInsertFileLabel=Ladda upp fil
 QueueToadlet.insertFileLabel=Fil
 QueueToadlet.key=Nyckel
-QueueToadlet.legend=Historia
+QueueToadlet.legend=Prioritet
 QueueToadlet.low=L?g
 QueueToadlet.medium=Medium
 QueueToadlet.mimeType=MIME Typ
 QueueToadlet.noTaskOnGlobalQueue=Den globala k?n ?r tom.
 QueueToadlet.none=ingen
+QueueToadlet.notLoadedYetTitle=K?n ?r inte laddad ?nnu
 QueueToadlet.panicButton=Panik knapp
 QueueToadlet.panicButtonConfirmation=Radera allt utan att fr?ga!\u00a0
 QueueToadlet.persistenceForever=F?revigt
@@ -598,6 +672,7 @@
 QueueToadlet.title=Global k? f?r ${nodeName}
 QueueToadlet.totalSize=Total storlek
 QueueToadlet.unknown=Ok?nd
+QueueToadlet.uploadSucceededTitle=Uppladdning klar: ${filename}
 QueueToadlet.veryhigh=V?ldigt h?g
 QueueToadlet.verylow=V?ldigt l?g
 QueueToadlet.warningUnsafeContent=Potentionellt farligt ineh?ll
@@ -606,6 +681,7 @@
 QueueToadlet.wipD=P?g?ende nedladdningar (${size})
 QueueToadlet.wipDU=P?g?ende mapp uppladdningar (${size})
 QueueToadlet.wipU=P?g?ende uppladdningar (${size})
+SSL.version=SSL version
 SimpleToadletServer.advancedMode=Aktivera avancerat l?ge?
 SimpleToadletServer.advancedModeLong=Ska information och inst?llningar avsedda 
f?r avancerade anv?ndare/utvecklare visas?   Denna inst?llning ska normalt vara 
avst?ngd.
 SimpleToadletServer.allowedFullAccess=V?rdar med full tillg?ng til  Fproxy 
(L?s Varning)
@@ -628,6 +704,9 @@
 SimpleToadletServer.panicButtonLong=Ska panik knappen synas p? /queue/ sidan.
 SimpleToadletServer.port=FProxy port
 SimpleToadletServer.portLong=FProxy port nummer
+SimpleToadletServer.ssl=Aktivera ssl?
+SimpleToadletServer.sslLong=Aktivera ssl?
+StartupToadlet.isStartingUp=Din freenet nod startas, v?nligen v?nta.
 StaticToadlet.pathInvalidChars=URI;n ineh?ller ogiltiga tecken.
 StaticToadlet.pathNotFoundTitle=S?kv?gen kunde inte hittas
 StatisticsToadlet.allocMemory=Allokerat Java minne: ${memory}
@@ -636,25 +715,31 @@
 StatisticsToadlet.fullTitle=Statistik f?r ${name}
 StatisticsToadlet.getLogs=Visa nodens senaste loggfil
 StatisticsToadlet.inputRate=Inkommande: ${rate}/sekund (av ${max}/sekund)
-StatisticsToadlet.jeDumpButton=Generera en JE Dump
-StatisticsToadlet.jvmInfoTitle=JVM Information
+StatisticsToadlet.javaVersion=Java Version: ${version}
+StatisticsToadlet.jeDumpButton=Generera en JE-dump
+StatisticsToadlet.jvmInfoTitle=JVM-information
 StatisticsToadlet.jvmVendor=JVM utvecklare: ${vendor}
 StatisticsToadlet.jvmVersion=JVM Version: ${version}
 StatisticsToadlet.maxMemory=Max Java minne: ${memory}
 StatisticsToadlet.noRequests=Din nod hanterar inga f?rfr?gningar f?r 
tillf?llet.
+StatisticsToadlet.nodeToNodeBytes=Nod till nod meddelande/n: ${total}
 StatisticsToadlet.osArch=OS Arkitektur: ${arch}
 StatisticsToadlet.osName=OS Namn: ${name}
 StatisticsToadlet.osVersion=OS Version: ${version}
 StatisticsToadlet.outputRate=Utg?ende: ${rate}/sekund (av ${max}/sekund)
 StatisticsToadlet.payloadOutput=Nyttolast utg?ende: ${total} (${rate}/sekund) 
(${percent}%)
 StatisticsToadlet.peerStatsTitle=Peer statistik
+StatisticsToadlet.priority=Prioritet
+StatisticsToadlet.resendBytes=Oms?nda bytes: ${total}
+StatisticsToadlet.running=K?r
 StatisticsToadlet.statisticGatheringTitle=Statistik samling
-StatisticsToadlet.threadDumpButton=Generera en tr?d Dump
+StatisticsToadlet.threadDumpButton=Generera en tr?d-dump
 StatisticsToadlet.threads=Aktiva tr?dar: ${running}/${max}
 StatisticsToadlet.totalInput=Total inkommande: ${total} (${rate}/sekund)
 StatisticsToadlet.totalOutput=Total utg?ende: ${total} (${rate}/sekund)
 StatisticsToadlet.usedMemory=Anv?nt Java minne: ${memory}
-StatisticsToadlet.versionTitle=Versions Information
+StatisticsToadlet.versionTitle=Versionsinformation
+StatisticsToadlet.waiting=V?ntar
 SymlinkerToadlet.symlinks=Syml?nkar i ToadletServer
 TestnetHandler.enable=Aktivera testnet L?ge? (FARLIGT)
 TestnetHandler.enableLong=Ska testnet aktiveras (FARLIGT!). Testnet eliminerar 
din anonymitet i utbyte mot att du hj?lper utvecklarna att debugga din nod.
@@ -667,6 +752,8 @@
 TextModeClientInterfaceServer.enableInputOutput=Aktivera vid stdout/stdin?
 TextModeClientInterfaceServer.enabled=Aktivera TMCI
 TextModeClientInterfaceServer.enabledLong=Ska TMCI (Text Mode Client 
Interface) aktiveras
+TextModeClientInterfaceServer.ssl=Aktivera ssl?
+TextModeClientInterfaceServer.sslLong=Aktivera ssl?
 TextModeClientInterfaceServer.telnetPortNumber=Telnet port
 TextModeClientInterfaceServer.telnetPortNumberLong=Telnet port nummer
 Toadlet.cancel=Avbryt
@@ -678,12 +765,14 @@
 Toadlet.nodeHomepage=Startsidan
 Toadlet.notSupportedTitle=St?ds ej
 Toadlet.notSupportedWithClass=Din webb l?sare skickade en f?rfr?gan som 
Freenet (${class}) inte f?rstod.
+Toadlet.ok=Ok
 Toadlet.permRedirectWithReason=Permanent omdirigering: ${reason}
 Toadlet.returnToHomepage=?terg? till nodens hemsida
 Toadlet.returnToNodeHomepage=?terg? till nodens hemsida
 Toadlet.returnToPrevPage=?terg? till f?rra sidan
 Toadlet.tempRedirectWithReason=Tempor?r omdirigering: ${reason}
 Toadlet.unauthorized=Du har inte r?ttigheter att bes?ka den h?r sidan.
+Toadlet.unauthorizedTitle=Obeh?rig
 Toadlet.yes=Ja
 ToadletContextImpl.methodNotAllowed=HTTP Metoden ?r inte till?ten
 TranslationToadlet.bracketRemoveOverride=(Radera ?vers?ttningen!)
@@ -693,6 +782,7 @@
 TranslationToadlet.contributingToLabelWithLang=Valt spr?k ${lang} :
 TranslationToadlet.currentTranslationLabel=Nuvarande ?vers?ttning
 TranslationToadlet.downloadTranslationsFile=Ladda ner ?vers?ttningsfilen
+TranslationToadlet.gotoNext=G? till n?sta, ej ?versatta str?ng?
 TranslationToadlet.hideAlreadyTranslated=G?m str?ngar som redan ?versatts
 TranslationToadlet.originalVersionLabel=Original (engelsk version)
 TranslationToadlet.reEdit=?ndra ?vers?ttningen
@@ -721,6 +811,8 @@
 UpdatedVersionAvailableUserAlert.fetchingNewExt=Din nod laddar f?r tillf?llet 
ner en ny version av Freenet (extra jar version ${extVersion}).
 UpdatedVersionAvailableUserAlert.fetchingNewNode=Noden laddar nu ner en ny 
version av Freenet (nod version ${nodeVersion}).
 UpdatedVersionAvailableUserAlert.notLatest=Det verkar som att din nod inte k?r 
den senaste versionen av mjukvaran.
+UpdatedVersionAvailableUserAlert.shortArmed=Din nod laddar ner en version av 
Freenet och komer att starta om n?r det ?r klart.
+UpdatedVersionAvailableUserAlert.shortNotReadyNotArmed=Din nod laddar ner en 
ny version av Freenet men beh?ver till?telse att uppdatera.
 UpdatedVersionAvailableUserAlert.title=En ny stabil version av Freenet finns 
tillg?nglig
 UpdatedVersionAvailableUserAlert.updateASAPButton=Uppdatera
 UpdatedVersionAvailableUserAlert.updateNowButton=Uppdatera Nu!
@@ -728,12 +820,16 @@
 UserAlert.hide=G?m
 UserAlert.reset=?terst?ll
 UserAlertManager.alertsOnHomepage=| Mer information finns p? 
${link}startsidan${/link}.
-UserAlertManager.alertsTitle=Kritiska fel
+UserAlertManager.alertsTitle=Upplysningar
 UserAlertManager.criticalErrorCountLabel=Kritiska fel:
+UserAlertManager.dumpEventsButton=Radera triviala meddelanden
 UserAlertManager.errorCountLabel=Fel:
+UserAlertManager.minorCountLabel=Icke kritiska:
 UserAlertManager.totalLabel=Totalt:
 UserAlertManager.warningCountLabel=Varningar:
+UserAlertsToadlet.titleWithName=Upplysningar f?r ${name}
 WelcomeToadlet.activityTitle=Nuvarande aktivitet
+WelcomeToadlet.alertsSummary=Sammanst?llning av upplysningar
 WelcomeToadlet.arkFetchCount=ARK H?mtare: ${total}
 WelcomeToadlet.confirmAddBookmarkSubTitle=Godk?nn att bokm?rket l?ggs till
 WelcomeToadlet.confirmAddBookmarkTitle=L?gg till bokm?rke
@@ -747,7 +843,7 @@
 WelcomeToadlet.extVersion=Freenet-ext Build #${build} r${rev}
 WelcomeToadlet.extVersionWithRecommended=Freenet-ext Build #${build} 
(${recbuild} ?r rekommenderad) r${rev}
 WelcomeToadlet.fetch=H?mta
-WelcomeToadlet.fetchKeyLabel=H?mta en Freenet nyckel
+WelcomeToadlet.fetchKeyLabel=H?mta en Freenetnyckel
 WelcomeToadlet.finInsertSuccessWithKey=Meddelandet har laddats upp till ${key}.
 WelcomeToadlet.finInsertedTitle=Uppladdning
 WelcomeToadlet.fromHeader=Fr?n
@@ -755,6 +851,10 @@
 WelcomeToadlet.homepageFullTitleWithName=Freenet FProxys startsida f?r ${name}
 WelcomeToadlet.ieWarning=Du verkar anv?nda Microsoft Internet Explorer. 
Ondsint skrivna Freenet sidor kan vara en fara f?r din anonymitet!
 WelcomeToadlet.ieWarningTitle=S?kerhetsrisk!
+WelcomeToadlet.insertCount=Uppladdningar: ${total}
+WelcomeToadlet.insertFailedTitle=Uppladdningen misslyckades
+WelcomeToadlet.insertFailedWithMessage=Uppladdningen misslyckades med 
meddelandet: ${message}
+WelcomeToadlet.insertSucceededTitle=Uppladdningen lyckades
 WelcomeToadlet.keyRequestLabel=Nyckel:
 WelcomeToadlet.messageHeader=Meddelande
 WelcomeToadlet.nodeUpdateConfirm=Vill du uppdatera Freenet noden?
@@ -773,10 +873,14 @@
 WelcomeToadlet.shutdownDone=Freenet noden st?ngs ner.
 WelcomeToadlet.shutdownNode=St?ng av noden
 WelcomeToadlet.subjectHeader=?mne
+WelcomeToadlet.targetBoardHeader=M?l Forum
 WelcomeToadlet.testnetWarning=K?r i testnet l?ge. Detta kommer allvarligt att 
?ventyra din anonymitet!
+WelcomeToadlet.testnetWarningTitle=Testn?t l?ge
 WelcomeToadlet.thanks=Tack f?r att du anv?nder Freenet.
 WelcomeToadlet.threadDumpTitle=Skapa en tr?d dump
+WelcomeToadlet.threadDumpWithFilename=En tr?d dump har genererats och sparats 
som ${filename}.
 WelcomeToadlet.update=Uppdatera
 WelcomeToadlet.updatingTitle=Noden uppdateras
-WelcomeToadlet.versionHeader=Versions information & nod kontrol
+WelcomeToadlet.versionHeader=Versionsinformation & nodkontrol
+WrapperConfig.wrapper.java.maxmemory.short=Maximalt minne (skrivs i megabytes)
 WelcomeToadlet.insertCount

Modified: branches/db4o/freenet/src/freenet/l10n/freenet.l10n.zh-cn.properties
===================================================================
--- branches/db4o/freenet/src/freenet/l10n/freenet.l10n.zh-cn.properties        
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/l10n/freenet.l10n.zh-cn.properties        
2008-09-24 23:54:07 UTC (rev 22829)
@@ -303,6 +303,7 @@
 FProxyToadlet.openPossRSSForceDisk=${link}???${/link}????????????????(????? 
Firefox 2.0.0, ${bold}??????????${/bold}, 2.0.1 ???????????).
 FProxyToadlet.openRSSAsRSS=${link}???${/link}?? RSS ?????? 
(?????????????${bold}????${/bold}, Freenet ???????? RSS ????).
 FProxyToadlet.openRSSForce=${link}????${/link}?? ${mime} ??????(? IE7 ?? FF2 
?${bold}??????${/bold}).
+FProxyToadlet.openWithKeyExplorer=${link}???${/link}????????? Freenet URI.
 FProxyToadlet.opennet=????????
 FProxyToadlet.opennetTitle=???
 FProxyToadlet.options=?????:
@@ -1204,6 +1205,7 @@
 TranslationToadlet.contributingToLabelWithLang=????${lang}?????:
 TranslationToadlet.currentTranslationLabel=????
 TranslationToadlet.downloadTranslationsFile=????????
+TranslationToadlet.gotoNext=?????????????
 TranslationToadlet.hideAlreadyTranslated=???????????
 TranslationToadlet.noCustomTranslations=????????.
 TranslationToadlet.originalVersionLabel=?????(????)

Modified: branches/db4o/freenet/src/freenet/l10n/freenet.l10n.zh-tw.properties
===================================================================
--- branches/db4o/freenet/src/freenet/l10n/freenet.l10n.zh-tw.properties        
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/l10n/freenet.l10n.zh-tw.properties        
2008-09-24 23:54:07 UTC (rev 22829)
@@ -302,6 +302,7 @@
 FProxyToadlet.openPossRSSForceDisk=${link}???${/link}????????????????(????? 
Firefox 2.0.0, ${bold}??????????${/bold}, 2.0.1 ???????????).
 FProxyToadlet.openRSSAsRSS=${link}???${/link}?? RSS ?????? 
(?????????????${bold}????${/bold}, Freenet ???????? RSS ????).
 FProxyToadlet.openRSSForce=${link}????${/link}?? ${mime} ??????(? IE7 ?? FF2 
?${bold}??????${/bold}).
+FProxyToadlet.openWithKeyExplorer=${link}???${/link}????????? Freenet URI.
 FProxyToadlet.opennet=????????
 FProxyToadlet.opennetTitle=???
 FProxyToadlet.options=?????:
@@ -1203,6 +1204,7 @@
 TranslationToadlet.contributingToLabelWithLang=????${lang}?????:
 TranslationToadlet.currentTranslationLabel=????
 TranslationToadlet.downloadTranslationsFile=????????
+TranslationToadlet.gotoNext=?????????????
 TranslationToadlet.hideAlreadyTranslated=??????????
 TranslationToadlet.noCustomTranslations=???????.
 TranslationToadlet.originalVersionLabel=????(????)

Modified: branches/db4o/freenet/src/freenet/node/Announcer.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/Announcer.java       2008-09-24 
23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/node/Announcer.java       2008-09-24 
23:54:07 UTC (rev 22829)
@@ -78,7 +78,10 @@
        public void start() {
                if(!node.isOpennetEnabled()) return;
                registerAlert();
-               if(node.peers.getDarknetPeers().length + 
node.peers.getOpennetPeers().length + om.countOldOpennetPeers() == 0) {
+               int darkPeers = node.peers.getDarknetPeers().length;
+               int openPeers = node.peers.getOpennetPeers().length;
+               int oldOpenPeers = om.countOldOpennetPeers();
+               if(darkPeers + openPeers + oldOpenPeers == 0) {
                        // We know opennet is enabled.
                        // We have no peers AT ALL.
                        // So lets connect to a few seednodes, and attempt an 
announcement.
@@ -88,6 +91,7 @@
                        }
                        connectSomeSeednodes();
                } else {
+                       System.out.println("Not attempting immediate 
announcement: dark peers="+darkPeers+" open peers="+openPeers+" old open 
peers="+oldOpenPeers+" - will wait 1 minute...");
                        // Wait a minute, then check whether we need to seed.
                        node.getTicker().queueTimedJob(new Runnable() {
                                public void run() {
@@ -302,6 +306,9 @@
        static final int RETRY_DELAY = 60*1000;
        private boolean started = false;

+       private long toldUserNoIP = -1;
+       private boolean dontKnowOurIPAddress;
+       
        public void maybeSendAnnouncement() {
                started = true;
                logMINOR = Logger.shouldLog(Logger.MINOR, this);
@@ -339,6 +346,11 @@
                }
                if((!ignoreIPUndetected) && (!node.ipDetector.hasValidIP())) {
                        if(node.ipDetector.ipDetectorManager.hasDetectors()) {
+                               if(now - toldUserNoIP > 60*1000)
+                                       System.out.println("Don't know our IP 
address, waiting for another 2 minutes...");
+                               synchronized(this) {
+                                       dontKnowOurIPAddress = true;
+                               }
                                // Wait a bit
                                node.getTicker().queueTimedJob(new Runnable() {
                                        public void run() {
@@ -353,6 +365,7 @@
                        }
                }
                synchronized(this) {
+                       dontKnowOurIPAddress = false;
                        // Double check after taking the lock.
                        if(enoughPeers()) return;
                        // Second, do we have many announcements running?
@@ -467,10 +480,12 @@
                                Logger.normal(this, "Announcement to 
"+seed.userToString()+" got bogus noderef: "+reason, new Exception("debug"));
                        }
                        public void completed() {
+                               boolean announceNow = false;
                                synchronized(Announcer.this) {
                                        runningAnnouncements--;
                                        Logger.normal(this, "Announcement to 
"+seed.userToString()+" completed, now running "+runningAnnouncements+" 
announcements");
-                                       if(runningAnnouncements == 0) {
+                                       if(runningAnnouncements == 0 && 
announcementAddedNodes > 0) {
+                                               // No point waiting if no nodes 
have been added!
                                                startTime = 
System.currentTimeMillis() + COOLING_OFF_PERIOD;
                                                sentAnnouncements = 0;
                                                // Wait for COOLING_OFF_PERIOD 
before trying again
@@ -481,6 +496,9 @@
                                                        }

                                                }, COOLING_OFF_PERIOD);
+                                       } else if(runningAnnouncements == 0) {
+                                               sentAnnouncements = 0;
+                                               announceNow = true;
                                        }
                                }
                                // If it takes more than COOLING_OFF_PERIOD to 
disconnect, we might not be able to reannounce to this
@@ -488,6 +506,8 @@
                                // be more than that period in the future.
                                node.peers.disconnect(seed, true, false);
                                System.out.println("Announcement to 
"+seed.userToString()+" completed.");
+                               if(announceNow)
+                                       maybeSendAnnouncement();
                        }

                        public void nodeFailed(PeerNode pn, String reason) {
@@ -525,11 +545,13 @@
                }

                public String getText() {
-                       StringBuffer sb = new StringBuffer();
+                       StringBuilder sb = new StringBuilder();
                        sb.append(l10n("announceAlertIntro"));
                        int status;
+                       boolean dontKnowAddress;
                        synchronized(this) {
                                status = Announcer.this.status;
+                               dontKnowAddress = dontKnowOurIPAddress;
                        }
                        if(status == STATUS_NO_SEEDNODES) {
                                return l10n("announceAlertNoSeednodes");
@@ -562,16 +584,20 @@
                                        else
                                                disconnectedSeednodes++;
                                }
-                               sb.append(l10n("announceDetails", 
-                                               new String[] { "addedNodes", 
"refusedNodes", "recentSentAnnouncements", "runningAnnouncements", 
"connectedSeednodes", "disconnectedSeednodes" },
-                                               new String[] {
-                                               Integer.toString(addedNodes),
-                                               Integer.toString(refusedNodes),
-                                               
Integer.toString(recentSentAnnouncements),
-                                               
Integer.toString(runningAnnouncements),
-                                               
Integer.toString(connectedSeednodes),
-                                               
Integer.toString(disconnectedSeednodes)
-                               }));
+                               if(dontKnowAddress) {
+                                       sb.append(l10n("dontKnowAddress"));
+                               } else {
+                                       sb.append(l10n("announceDetails", 
+                                                       new String[] { 
"addedNodes", "refusedNodes", "recentSentAnnouncements", 
"runningAnnouncements", "connectedSeednodes", "disconnectedSeednodes" },
+                                                       new String[] {
+                                                       
Integer.toString(addedNodes),
+                                                       
Integer.toString(refusedNodes),
+                                                       
Integer.toString(recentSentAnnouncements),
+                                                       
Integer.toString(runningAnnouncements),
+                                                       
Integer.toString(connectedSeednodes),
+                                                       
Integer.toString(disconnectedSeednodes)
+                                       }));
+                               }
                                if(coolingOffSeconds > 0) {
                                        sb.append(' ');
                                        sb.append(l10n("coolingOff", "time", 
Long.toString(coolingOffSeconds)));
@@ -589,7 +615,7 @@
                }

                public boolean isValid() {
-                       return started && (!enoughPeers()) && 
node.isOpennetEnabled();
+                       return (!enoughPeers()) && node.isOpennetEnabled();
                }

                public void isValid(boolean validity) {

Modified: branches/db4o/freenet/src/freenet/node/DarknetPeerNode.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/DarknetPeerNode.java 2008-09-24 
23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/node/DarknetPeerNode.java 2008-09-24 
23:54:07 UTC (rev 22829)
@@ -870,9 +870,10 @@
                }

                protected void remove() {
+                       Long l = uid;
                        synchronized(DarknetPeerNode.this) {
-                               myFileOffersByUID.remove(uid);
-                               hisFileOffersByUID.remove(uid);
+                               myFileOffersByUID.remove(l);
+                               hisFileOffersByUID.remove(l);
                        }
                        data.close();
                }
@@ -954,7 +955,7 @@
                                }

                                public String getText() {
-                                       StringBuffer sb = new StringBuffer();
+                                       StringBuilder sb = new StringBuilder();
                                        sb.append(l10n("failedReceiveHeader", 
new String[] { "filename", "node" },
                                                        new String[] { 
filename, getName() }));
                                        sb.append('\n');
@@ -1056,7 +1057,7 @@
                                }

                                public String getText() {
-                                       StringBuffer sb = new StringBuffer();
+                                       StringBuilder sb = new StringBuilder();
                                        
sb.append(l10n("succeededReceiveHeader", new String[] { "filename", "node" },
                                                        new String[] { 
filename, getName() }));
                                        sb.append('\n');
@@ -1172,7 +1173,7 @@
                                        return UserAlert.MINOR;
                                }
                                public String getText() {
-                                       StringBuffer sb = new StringBuffer();
+                                       StringBuilder sb = new StringBuilder();
                                        sb.append(l10n("offeredFileHeader", 
"name", getName()));
                                        sb.append('\n');
                                        sb.append(l10n("fileLabel"));

Modified: branches/db4o/freenet/src/freenet/node/IPDetectorPluginManager.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/IPDetectorPluginManager.java 
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/node/IPDetectorPluginManager.java 
2008-09-24 23:54:07 UTC (rev 22829)
@@ -205,7 +205,7 @@

                public String getText() {
                        if(!suggestPortForward) return super.getText();
-                       StringBuffer sb = new StringBuffer();
+                       StringBuilder sb = new StringBuilder();
                        sb.append(super.getText());
                        if(portsNotForwarded.length == 1) {
                                sb.append(l10n("suggestForwardPort", "port", 
Integer.toString(Math.abs(portsNotForwarded[0]))));
@@ -272,25 +272,25 @@
        }

        /**
-        * Use MAYBE_PORT_FORWARDED as the threshold, because most people 
either are behind a NAT with
-        * a low timeout (e.g. a home router), know what they're doing, or 
can't forward ports anyway.
+        * Return all the ports that we have reason to believe are not 
forwarded. E.g. for the user-alert, which only
+        * shows if what we return is of nonzero length.
         */
        public int[] getUDPPortsNotForwarded() {
                OpennetManager om = node.getOpennet();
-               int darknetStatus = (node.peers.anyDarknetPeers() ? 
node.darknetCrypto.getDetectedConnectivityStatus() : 
AddressTracker.MAYBE_PORT_FORWARDED);
+               int darknetStatus = (node.peers.anyDarknetPeers() ? 
node.darknetCrypto.getDetectedConnectivityStatus() : AddressTracker.DONT_KNOW);
                int opennetStatus = om == null ? AddressTracker.DONT_KNOW : 
om.crypto.getDetectedConnectivityStatus();
-               if(om == null || opennetStatus > AddressTracker.DONT_KNOW) {
-                       if(darknetStatus > AddressTracker.DONT_KNOW) {
+               if(om == null || opennetStatus >= AddressTracker.DONT_KNOW) {
+                       if(darknetStatus >= AddressTracker.DONT_KNOW) {
                                return new int[] { };
                        } else {
-                               return new int[] { (darknetStatus < 
AddressTracker.DONT_KNOW ? -1 : 1) * node.getDarknetPortNumber() };
+                               return new int[] { (darknetStatus < 
AddressTracker.MAYBE_NATED ? -1 : 1) * node.getDarknetPortNumber() };
                        }
                } else {
-                       if(darknetStatus > AddressTracker.DONT_KNOW) {
-                               return new int[] { (opennetStatus < 
AddressTracker.DONT_KNOW ? -1 : 1 ) * om.crypto.portNumber };
+                       if(darknetStatus >= AddressTracker.DONT_KNOW) {
+                               return new int[] { (opennetStatus < 
AddressTracker.MAYBE_NATED ? -1 : 1 ) * om.crypto.portNumber };
                        } else {
-                               return new int[] { ((darknetStatus < 
AddressTracker.DONT_KNOW) ? -1 : 1 ) * node.getDarknetPortNumber(), 
-                                               (opennetStatus < 
AddressTracker.DONT_KNOW ? -1 : 1 ) * om.crypto.portNumber };
+                               return new int[] { ((darknetStatus < 
AddressTracker.MAYBE_NATED) ? -1 : 1 ) * node.getDarknetPortNumber(), 
+                                               (opennetStatus < 
AddressTracker.MAYBE_NATED ? -1 : 1 ) * om.crypto.portNumber };
                        }
                }
        }
@@ -423,7 +423,7 @@
                PeerNode[] peers = node.getPeerNodes();
                PeerNode[] conns = node.getConnectedPeers();
                int peerCount = node.peers.countValidPeers();
-               FreenetInetAddress[] nodeAddrs = detector.getPrimaryIPAddress();
+               FreenetInetAddress[] nodeAddrs = 
detector.getPrimaryIPAddress(true);
                long now = System.currentTimeMillis();
                synchronized(this) {
                        if(plugins.length == 0) {

Modified: branches/db4o/freenet/src/freenet/node/LocationManager.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/LocationManager.java 2008-09-24 
23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/node/LocationManager.java 2008-09-24 
23:54:07 UTC (rev 22829)
@@ -49,11 +49,13 @@
             this.item = item;
         }

+               @Override
         public void disconnected() {
             super.disconnected();
             removeRecentlyForwardedItem(item);
         }

+               @Override
         public void acknowledged() {
             item.successfullyForwarded = true;
         }
@@ -157,7 +159,7 @@
                         int sleepTime = getSendSwapInterval();
                         sleepTime *= nextRandom;
                         sleepTime = Math.min(sleepTime, Integer.MAX_VALUE);
-                        long endTime = startTime + (int)sleepTime;
+                        long endTime = startTime + sleepTime;
                         long now = System.currentTimeMillis();
                         long diff = endTime - now;
                         try {
@@ -735,7 +737,7 @@
        if(Math.abs(hisLoc - myLoc) <= Double.MIN_VALUE * 2)
                return false; // Probably swapping with self

-        StringBuffer sb = new StringBuffer();
+        StringBuilder sb = new StringBuilder();

         sb.append("my: ").append(myLoc).append(", his: 
").append(hisLoc).append(", myFriends: ");
         sb.append(friendLocs.length).append(", hisFriends: 
").append(hisFriendLocs.length).append(" mine:\n");

Modified: branches/db4o/freenet/src/freenet/node/Node.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/Node.java    2008-09-24 23:18:12 UTC 
(rev 22828)
+++ branches/db4o/freenet/src/freenet/node/Node.java    2008-09-24 23:54:07 UTC 
(rev 22829)
@@ -83,6 +83,8 @@
 import freenet.keys.SSKVerifyException;
 import freenet.l10n.L10n;
 import freenet.node.NodeDispatcher.NodeDispatcherCallback;
+import freenet.node.SecurityLevels.FRIENDS_THREAT_LEVEL;
+import freenet.node.SecurityLevels.NETWORK_THREAT_LEVEL;
 import freenet.node.updater.NodeUpdateManager;
 import freenet.node.useralerts.AbstractUserAlert;
 import freenet.node.useralerts.BuildOldAgeUserAlert;
@@ -90,7 +92,6 @@
 import freenet.node.useralerts.ExtOldAgeUserAlert;
 import freenet.node.useralerts.MeaningfulNodeNameUserAlert;
 import freenet.node.useralerts.NotEnoughNiceLevelsUserAlert;
-import freenet.node.useralerts.OpennetUserAlert;
 import freenet.node.useralerts.SimpleUserAlert;
 import freenet.node.useralerts.TimeSkewDetectedUserAlert;
 import freenet.node.useralerts.UserAlert;
@@ -103,6 +104,8 @@
 import freenet.store.PubkeyStore;
 import freenet.store.RAMFreenetStore;
 import freenet.store.SSKStore;
+import freenet.store.saltedhash.SaltedHashFreenetStore;
+import freenet.support.ByteArrayWrapper;
 import freenet.support.DoubleTokenBucket;
 import freenet.support.Executor;
 import freenet.support.Fields;
@@ -110,7 +113,6 @@
 import freenet.support.HTMLEncoder;
 import freenet.support.HTMLNode;
 import freenet.support.HexUtil;
-import freenet.support.ImmutableByteArrayWrapper;
 import freenet.support.LRUHashtable;
 import freenet.support.LRUQueue;
 import freenet.support.Logger;
@@ -205,7 +207,7 @@
                }

                public String[] getPossibleValues() {
-                       return new String[] { "bdb-index", "ram" };
+                       return new String[] { "bdb-index", "salt-hash", "ram" };
                }

                public void setPossibleValues(String[] val) {
@@ -319,7 +321,10 @@
        /** Datastore directory */
        private final File storeDir;

+       /** Datastore properties */
        private final String storeType;
+       private final int storeBloomFilterSize;
+       private final boolean storeBloomFilterCounting;

        /** The number of bytes per key total in all the different datastores. 
All the datastores
         * are always the same size in number of keys. */
@@ -362,13 +367,13 @@
         * everything that passes through this node. */
        private final PubkeyStore pubKeyDatacache;
        /** RequestSender's currently running, by KeyHTLPair */
-       private final HashMap requestSenders;
+       private final HashMap<KeyHTLPair, RequestSender> requestSenders;
        /** RequestSender's currently transferring, by key */
-       private final HashMap transferringRequestSenders;
+       private final HashMap<NodeCHK, RequestSender> 
transferringRequestSenders;
        /** UIDs of RequestHandler's currently transferring */
-       private final HashSet transferringRequestHandlers;
+       private final HashSet<Long> transferringRequestHandlers;
        /** CHKInsertSender's currently running, by KeyHTLPair */
-       private final HashMap insertSenders;
+       private final HashMap<KeyHTLPair, AnyInsertSender> insertSenders;
        /** FetchContext for ARKs */
        public final FetchContext arkFetcherContext;

@@ -381,17 +386,17 @@
        public boolean disableHangCheckers;

        /** HashSet of currently running request UIDs */
-       private final HashSet runningUIDs;
-       private final HashSet runningCHKGetUIDs;
-       private final HashSet runningLocalCHKGetUIDs;
-       private final HashSet runningSSKGetUIDs;
-       private final HashSet runningLocalSSKGetUIDs;
-       private final HashSet runningCHKPutUIDs;
-       private final HashSet runningLocalCHKPutUIDs;
-       private final HashSet runningSSKPutUIDs;
-       private final HashSet runningLocalSSKPutUIDs;
-       private final HashSet runningCHKOfferReplyUIDs;
-       private final HashSet runningSSKOfferReplyUIDs;
+       private final HashSet<Long> runningUIDs;
+       private final HashSet<Long> runningCHKGetUIDs;
+       private final HashSet<Long> runningLocalCHKGetUIDs;
+       private final HashSet<Long> runningSSKGetUIDs;
+       private final HashSet<Long> runningLocalSSKGetUIDs;
+       private final HashSet<Long> runningCHKPutUIDs;
+       private final HashSet<Long> runningLocalCHKPutUIDs;
+       private final HashSet<Long> runningSSKPutUIDs;
+       private final HashSet<Long> runningLocalSSKPutUIDs;
+       private final HashSet<Long> runningCHKOfferReplyUIDs;
+       private final HashSet<Long> runningSSKOfferReplyUIDs;

        /** Semi-unique ID for swap requests. Used to identify us so that the
         * topology can be reconstructed. */
@@ -432,7 +437,7 @@
        final NodeDispatcher dispatcher;
        public final UptimeEstimator uptime;
        static final int MAX_MEMORY_CACHED_PUBKEYS = 1000;
-       final LRUHashtable cachedPubKeys;
+       final LRUHashtable<ByteArrayWrapper, DSAPublicKey> cachedPubKeys;
        final boolean testnetEnabled;
        final TestnetHandler testnetHandler;
        public final DoubleTokenBucket outputThrottle;
@@ -490,6 +495,8 @@
        /** NodeUpdater **/
        public final NodeUpdateManager nodeUpdater;

+       public final SecurityLevels securityLevels;
+       
        // Things that's needed to keep track of
        public final PluginManager pluginManager;

@@ -746,7 +753,7 @@
                nodeNameUserAlert = new MeaningfulNodeNameUserAlert(this);
                recentlyCompletedIDs = new LRUQueue();
                this.config = config;
-               cachedPubKeys = new LRUHashtable();
+               cachedPubKeys = new LRUHashtable<ByteArrayWrapper, 
DSAPublicKey>();
                lm = new LocationManager(random, this);

                try {
@@ -756,22 +763,24 @@
                        throw new Error(e3);
                }
                fLocalhostAddress = new FreenetInetAddress(localhostAddress);
-               requestSenders = new HashMap();
-               transferringRequestSenders = new HashMap();
-               transferringRequestHandlers = new HashSet();
-               insertSenders = new HashMap();
-               runningUIDs = new HashSet();
-               runningCHKGetUIDs = new HashSet();
-               runningLocalCHKGetUIDs = new HashSet();
-               runningSSKGetUIDs = new HashSet();
-               runningLocalSSKGetUIDs = new HashSet();
-               runningCHKPutUIDs = new HashSet();
-               runningLocalCHKPutUIDs = new HashSet();
-               runningSSKPutUIDs = new HashSet();
-               runningLocalSSKPutUIDs = new HashSet();
-               runningCHKOfferReplyUIDs = new HashSet();
-               runningSSKOfferReplyUIDs = new HashSet();
+               requestSenders = new HashMap<KeyHTLPair, RequestSender>();
+               transferringRequestSenders = new HashMap<NodeCHK, 
RequestSender>();
+               transferringRequestHandlers = new HashSet<Long>();
+               insertSenders = new HashMap<KeyHTLPair, AnyInsertSender>();
+               runningUIDs = new HashSet<Long>();
+               runningCHKGetUIDs = new HashSet<Long>();
+               runningLocalCHKGetUIDs = new HashSet<Long>();
+               runningSSKGetUIDs = new HashSet<Long>();
+               runningLocalSSKGetUIDs = new HashSet<Long>();
+               runningCHKPutUIDs = new HashSet<Long>();
+               runningLocalCHKPutUIDs = new HashSet<Long>();
+               runningSSKPutUIDs = new HashSet<Long>();
+               runningLocalSSKPutUIDs = new HashSet<Long>();
+               runningCHKOfferReplyUIDs = new HashSet<Long>();
+               runningSSKOfferReplyUIDs = new HashSet<Long>();

+               this.securityLevels = new SecurityLevels(this, config);
+               
                // Directory for node-related files other than store

                nodeConfig.register("nodeDir", ".", sortOrder++, true, true /* 
because can't be changed on the fly, also for packages */, "Node.nodeDir", 
"Node.nodeDirLong", 
@@ -1020,7 +1029,17 @@
                });
                enableSwapping = nodeConfig.getBoolean("enableSwapping");

-               nodeConfig.register("publishOurPeersLocation", false, 
sortOrder++, true, false, "Node.publishOurPeersLocation", 
"Node.publishOurPeersLocationLong", new BooleanCallback() {
+               /*
+                * Publish our peers' locations is enabled, even in MAXIMUM 
network security and/or HIGH friends security,
+                * because a node which doesn't publish its peers' locations 
will get dramatically less traffic.
+                * 
+                * Publishing our peers' locations does make us slightly more 
vulnerable to some attacks, but I don't think
+                * it's a big difference: swapping reveals the same 
information, it just doesn't update as quickly. This 
+                * may help slightly, but probably not dramatically against a 
clever attacker.
+                * 
+                * FIXME review this decision.
+                */
+               nodeConfig.register("publishOurPeersLocation", true, 
sortOrder++, true, false, "Node.publishOurPeersLocation", 
"Node.publishOurPeersLocationLong", new BooleanCallback() {

                        public Boolean get() {
                                return publishOurPeersLocation;
@@ -1032,7 +1051,7 @@
                });
                publishOurPeersLocation = 
nodeConfig.getBoolean("publishOurPeersLocation");

-               nodeConfig.register("routeAccordingToOurPeersLocation", false, 
sortOrder++, true, false, "Node.routeAccordingToOurPeersLocation", 
"Node.routeAccordingToOurPeersLocationLong", new BooleanCallback() {
+               nodeConfig.register("routeAccordingToOurPeersLocation", true, 
sortOrder++, true, false, "Node.routeAccordingToOurPeersLocation", 
"Node.routeAccordingToOurPeersLocationLong", new BooleanCallback() {

                        public Boolean get() {
                                return routeAccordingToOurPeersLocation;
@@ -1044,6 +1063,39 @@
                });
                routeAccordingToOurPeersLocation = 
nodeConfig.getBoolean("routeAccordingToOurPeersLocation");

+               securityLevels.addNetworkThreatLevelListener(new 
SecurityLevelListener<NETWORK_THREAT_LEVEL>() {
+
+                       public void onChange(NETWORK_THREAT_LEVEL oldLevel, 
NETWORK_THREAT_LEVEL newLevel) {
+                               synchronized(Node.this) {
+                                       boolean wantFOAF = true;
+                                       if(newLevel == 
NETWORK_THREAT_LEVEL.MAXIMUM || newLevel == NETWORK_THREAT_LEVEL.HIGH) {
+                                               // Opennet is disabled.
+                                               
if(securityLevels.friendsThreatLevel == FRIENDS_THREAT_LEVEL.HIGH)
+                                                       wantFOAF = false;
+                                       }
+                                       routeAccordingToOurPeersLocation = 
wantFOAF;
+                               }
+                       }
+                       
+               });
+               
+               securityLevels.addFriendsThreatLevelListener(new 
SecurityLevelListener<FRIENDS_THREAT_LEVEL>() {
+
+                       public void onChange(FRIENDS_THREAT_LEVEL oldLevel, 
FRIENDS_THREAT_LEVEL newLevel) {
+                               synchronized(Node.this) {
+                                       boolean wantFOAF = true;
+                                       NETWORK_THREAT_LEVEL networkLevel = 
securityLevels.networkThreatLevel;
+                                       if(networkLevel == 
NETWORK_THREAT_LEVEL.MAXIMUM || networkLevel == NETWORK_THREAT_LEVEL.HIGH) {
+                                               // Opennet is disabled.
+                                               if(newLevel == 
FRIENDS_THREAT_LEVEL.HIGH)
+                                                       wantFOAF = false;
+                                       }
+                                       routeAccordingToOurPeersLocation = 
wantFOAF;
+                               }
+                       }
+                       
+               });
+               
                nodeConfig.register("enableSwapQueueing", true, sortOrder++, 
true, false, "Node.enableSwapQueueing", "Node.enableSwapQueueingLong", new 
BooleanCallback() {
                        public Boolean get() {
                                return enableSwapQueueing;
@@ -1072,7 +1124,7 @@
                // @see #191
                if(oldConfig != null && 
"-1".equals(oldConfig.get("node.listenPort")))
                        throw new 
NodeInitException(NodeInitException.EXIT_COULD_NOT_BIND_USM, "Your freenet.ini 
file is corrupted! 'listenPort=-1'");
-               NodeCryptoConfig darknetConfig = new 
NodeCryptoConfig(nodeConfig, sortOrder++, false);
+               NodeCryptoConfig darknetConfig = new 
NodeCryptoConfig(nodeConfig, sortOrder++, false, securityLevels);
                sortOrder += NodeCryptoConfig.OPTION_COUNT;

                darknetCrypto = new NodeCrypto(this, false, darknetConfig, 
startupTime, enableARKs);
@@ -1334,7 +1386,7 @@
                        maxOpennetPeers = 20;
                }

-               opennetCryptoConfig = new NodeCryptoConfig(opennetConfig, 2 /* 
0 = enabled */, true);
+               opennetCryptoConfig = new NodeCryptoConfig(opennetConfig, 2 /* 
0 = enabled */, true, securityLevels);

                if(opennetEnabled) {
                        opennet = new OpennetManager(this, opennetCryptoConfig, 
System.currentTimeMillis(), isAllowedToConnectToSeednodes);
@@ -1343,8 +1395,47 @@
                        opennet = null;
                }

-               opennetConfig.register("acceptSeedConnections", true, 2, true, 
true, "Node.acceptSeedConnectionsShort", "Node.acceptSeedConnections", new 
BooleanCallback() {
+               securityLevels.addNetworkThreatLevelListener(new 
SecurityLevelListener<NETWORK_THREAT_LEVEL>() {

+                       public void onChange(NETWORK_THREAT_LEVEL oldLevel, 
NETWORK_THREAT_LEVEL newLevel) {
+                               if(newLevel == NETWORK_THREAT_LEVEL.HIGH
+                                               || newLevel == 
NETWORK_THREAT_LEVEL.MAXIMUM) {
+                                       OpennetManager om;
+                                       synchronized(Node.this) {
+                                               om = opennet;
+                                               if(om != null)
+                                                       opennet = null;
+                                       }
+                                       if(om != null) {
+                                               om.stop(true);
+                                               
ipDetector.ipDetectorManager.notifyPortChange(getPublicInterfacePorts());
+                                       }
+                               } else if(newLevel == 
NETWORK_THREAT_LEVEL.NORMAL
+                                               || newLevel == 
NETWORK_THREAT_LEVEL.LOW) {
+                                       OpennetManager o = null;
+                                       synchronized(Node.this) {
+                                               if(opennet == null) {
+                                                       try {
+                                                               o = opennet = 
new OpennetManager(Node.this, opennetCryptoConfig, System.currentTimeMillis(), 
isAllowedToConnectToSeednodes);
+                                                       } catch 
(NodeInitException e) {
+                                                               opennet = null;
+                                                               
Logger.error(this, "UNABLE TO ENABLE OPENNET: "+e, e);
+                                                               
clientCore.alerts.register(new SimpleUserAlert(false, 
l10n("enableOpennetFailedTitle"), l10n("enableOpennetFailed", "message", 
e.getLocalizedMessage()), l10n("enableOpennetFailed", "message", 
e.getLocalizedMessage()), UserAlert.ERROR));
+                                                       }
+                                               }
+                                       }
+                                       if(o != null) {
+                                               o.start();
+                                               
ipDetector.ipDetectorManager.notifyPortChange(getPublicInterfacePorts());
+                                       }
+                               }
+                               Node.this.config.store();
+                       }
+                       
+               });
+               
+               opennetConfig.register("acceptSeedConnections", false, 2, true, 
true, "Node.acceptSeedConnectionsShort", "Node.acceptSeedConnections", new 
BooleanCallback() {
+
                        public Boolean get() {
                                return acceptSeedConnections;
                        }
@@ -1404,8 +1495,7 @@
                                                new NodeNameCallback(this));    
 
                myName = nodeConfig.getString("name");   

-               // Datastore
-               
+               // Datastore            
                nodeConfig.register("storeForceBigShrinks", false, sortOrder++, 
true, false, "Node.forceBigShrink", "Node.forceBigShrinkLong",
                                new BooleanCallback() {

@@ -1422,7 +1512,7 @@
                                        }

                });
-               
+
                nodeConfig.register("storeType", "bdb-index", sortOrder++, 
true, false, "Node.storeType", "Node.storeTypeLong", new StoreTypeCallback());

                storeType = nodeConfig.getString("storeType");
@@ -1477,6 +1567,50 @@

                maxTotalKeys = maxTotalDatastoreSize / sizePerKey;

+               nodeConfig.register("storeBloomFilterSize", (int) 
Math.min(maxTotalDatastoreSize / 2048, 268435456), sortOrder++, true, false, 
"Node.storeBloomFilterSize",
+                       "Node.storeBloomFilterSizeLong", new IntCallback() {
+                               private Integer cachedBloomFilterSize;
+
+                               public Integer get() {
+                                       if (cachedBloomFilterSize == null)
+                                               cachedBloomFilterSize = 
storeBloomFilterSize;
+                                       return cachedBloomFilterSize;
+                               }
+
+                               public void set(Integer val) throws 
InvalidConfigValueException, NodeNeedRestartException {
+                                       cachedBloomFilterSize = val;
+                                       throw new 
NodeNeedRestartException("Store bloom filter size cannot be changed on the 
fly");
+                               }
+
+                               public boolean isReadOnly() {
+                                       return !("salt-hash".equals(storeType));
+                               }
+                       });
+
+               storeBloomFilterSize = 
nodeConfig.getInt("storeBloomFilterSize");
+
+               nodeConfig.register("storeBloomFilterCounting", true, 
sortOrder++, true, false,
+                       "Node.storeBloomFilterCounting", 
"Node.storeBloomFilterCountingLong", new BooleanCallback() {
+                               private Boolean cachedBloomFilterCounting;
+
+                               public Boolean get() {
+                                       if (cachedBloomFilterCounting == null)
+                                               cachedBloomFilterCounting = 
storeBloomFilterCounting;
+                                       return cachedBloomFilterCounting;
+                               }
+
+                               public void set(Boolean val) throws 
InvalidConfigValueException, NodeNeedRestartException {
+                                       cachedBloomFilterCounting = val;
+                                       throw new 
NodeNeedRestartException("Store bloom filter type cannot be changed on the 
fly");
+                               }
+
+                               public boolean isReadOnly() {
+                                       return !("salt-hash".equals(storeType));
+                               }
+                       });
+
+               storeBloomFilterCounting = 
nodeConfig.getBoolean("storeBloomFilterCounting");
+               
                nodeConfig.register("storeDir", "datastore", sortOrder++, true, 
true, "Node.storeDirectory", "Node.storeDirectoryLong", 
                                new StringCallback() {
                                        public String get() {
@@ -1503,7 +1637,80 @@
                maxStoreKeys = maxTotalKeys / 2;
                maxCacheKeys = maxTotalKeys - maxStoreKeys;

-               if(storeType.equals("bdb-index")) {
+               if (storeType.equals("salt-hash")) {
+                       storeEnvironment = null;
+                       envMutableConfig = null;
+                       try {
+                               int bloomFilterSizeInM = 
storeBloomFilterCounting ? storeBloomFilterSize / 6 * 4
+                                       : (storeBloomFilterSize + 6) / 6 * 8; 
// + 6 to make size different, trigger rebuild 
+                               
+                               Logger.normal(this, "Initializing CHK 
Datastore");
+                               System.out.println("Initializing CHK Datastore 
(" + maxStoreKeys + " keys)");
+                               chkDatastore = new CHKStore();
+                               SaltedHashFreenetStore chkDataFS = 
SaltedHashFreenetStore.construct(storeDir, "CHK-store",
+                                       chkDatastore, random, maxStoreKeys, 
bloomFilterSizeInM, storeBloomFilterCounting,
+                                       shutdownHook);
+                               Logger.normal(this, "Initializing CHK 
Datacache");
+                               System.out.println("Initializing CHK Datacache 
(" + maxCacheKeys + ':' + maxCacheKeys + " keys)");
+                               chkDatacache = new CHKStore();
+                               SaltedHashFreenetStore chkCacheFS = 
SaltedHashFreenetStore.construct(storeDir, "CHK-cache",
+                                       chkDatacache, random, maxCacheKeys, 
bloomFilterSizeInM, storeBloomFilterCounting,
+                                       shutdownHook);
+                               Logger.normal(this, "Initializing pubKey 
Datastore");
+                               System.out.println("Initializing pubKey 
Datastore");
+                               pubKeyDatastore = new PubkeyStore();
+                               SaltedHashFreenetStore pubkeyDataFS = 
SaltedHashFreenetStore.construct(storeDir, "PUBKEY-store",
+                                       pubKeyDatastore, random, maxStoreKeys, 
bloomFilterSizeInM, storeBloomFilterCounting,
+                                       shutdownHook);
+                               Logger.normal(this, "Initializing pubKey 
Datacache");
+                               System.out.println("Initializing pubKey 
Datacache (" + maxCacheKeys + " keys)");
+                               pubKeyDatacache = new PubkeyStore();
+                               SaltedHashFreenetStore pubkeyCacheFS = 
SaltedHashFreenetStore.construct(storeDir, "PUBKEY-cache",
+                                       pubKeyDatacache, random, maxCacheKeys, 
bloomFilterSizeInM, storeBloomFilterCounting,
+                                       shutdownHook);
+                               Logger.normal(this, "Initializing SSK 
Datastore");
+                               System.out.println("Initializing SSK 
Datastore");
+                               sskDatastore = new SSKStore(this);
+                               SaltedHashFreenetStore sskDataFS = 
SaltedHashFreenetStore.construct(storeDir, "SSK-store",
+                                       sskDatastore, random, maxStoreKeys, 
bloomFilterSizeInM, storeBloomFilterCounting,
+                                       shutdownHook);
+                               Logger.normal(this, "Initializing SSK 
Datacache");
+                               System.out.println("Initializing SSK Datacache 
(" + maxCacheKeys + " keys)");
+                               sskDatacache = new SSKStore(this);
+                               SaltedHashFreenetStore sskCacheFS = 
SaltedHashFreenetStore.construct(storeDir, "SSK-cache",
+                                       sskDatacache, random, maxCacheKeys, 
bloomFilterSizeInM, storeBloomFilterCounting,
+                                       shutdownHook);
+                               
+                               File migrationFile = new File(storeDir, 
"migrated");
+                               if (!migrationFile.exists()) {
+                                       chkDataFS.migrationFrom(//
+                                               new File(storeDir, "chk" + 
suffix + ".store"), // 
+                                               new File(storeDir, "chk" + 
suffix + ".store.keys"));
+                                       chkCacheFS.migrationFrom(//
+                                               new File(storeDir, "chk" + 
suffix + ".cache"), // 
+                                               new File(storeDir, "chk" + 
suffix + ".cache.keys"));
+
+                                       pubkeyDataFS.migrationFrom(//
+                                               new File(storeDir, "pubkey" + 
suffix + ".store"), // 
+                                               new File(storeDir, "pubkey" + 
suffix + ".store.keys"));
+                                       pubkeyCacheFS.migrationFrom(//
+                                               new File(storeDir, "pubkey" + 
suffix + ".cache"), // 
+                                               new File(storeDir, "pubkey" + 
suffix + ".cache.keys"));
+
+                                       sskDataFS.migrationFrom(//
+                                               new File(storeDir, "ssk" + 
suffix + ".store"), // 
+                                               new File(storeDir, "ssk" + 
suffix + ".store.keys"));
+                                       sskCacheFS.migrationFrom(//
+                                               new File(storeDir, "ssk" + 
suffix + ".cache"), // 
+                                               new File(storeDir, "ssk" + 
suffix + ".cache.keys"));
+                                       migrationFile.createNewFile();
+                               }
+                       } catch (IOException e) {
+                               System.err.println("Could not open store: " + 
e);
+                               e.printStackTrace();
+                               throw new 
NodeInitException(NodeInitException.EXIT_STORE_OTHER, e.getMessage());
+                       }
+               } else if (storeType.equals("bdb-index")) {
                // Setup datastores

                EnvironmentConfig envConfig = 
BerkeleyDBFreenetStore.getBDBConfig();
@@ -1708,7 +1915,18 @@
                clientCore = new NodeClientCore(this, config, nodeConfig, 
nodeDir, getDarknetPortNumber(), sortOrder, oldConfig, fproxyConfig, toadlets, 
db);

                netid = new NetworkIDManager(this);
-                
+               
+               if (storeType.equals("salt-hash")) {
+                       ((SaltedHashFreenetStore) 
chkDatastore.getStore()).setUserAlertManager(clientCore.alerts);
+                       ((SaltedHashFreenetStore) 
chkDatacache.getStore()).setUserAlertManager(clientCore.alerts);
+                       ((SaltedHashFreenetStore) 
pubKeyDatastore.getStore()).setUserAlertManager(clientCore.alerts);
+                       ((SaltedHashFreenetStore) 
pubKeyDatacache.getStore()).setUserAlertManager(clientCore.alerts);
+                       ((SaltedHashFreenetStore) 
sskDatastore.getStore()).setUserAlertManager(clientCore.alerts);
+                       ((SaltedHashFreenetStore) 
sskDatacache.getStore()).setUserAlertManager(clientCore.alerts);
+               }
+               
+               securityLevels.registerUserAlert(clientCore.alerts);
+               
                nodeConfig.register("disableHangCheckers", false, sortOrder++, 
true, false, "Node.disableHangCheckers", "Node.disableHangCheckersLong", new 
BooleanCallback() {

                        public Boolean get() {
@@ -1822,8 +2040,6 @@
                if(!NativeThread.HAS_ENOUGH_NICE_LEVELS)
                        clientCore.alerts.register(new 
NotEnoughNiceLevelsUserAlert());

-               clientCore.alerts.register(new OpennetUserAlert(this));
-               
                this.clientCore.start(config);

                // After everything has been created, write the config file 
back to disk.
@@ -2058,7 +2274,7 @@
                // Transfer coalescing - match key only as HTL irrelevant
                RequestSender sender = null;
                synchronized(transferringRequestSenders) {
-                       sender = (RequestSender) 
transferringRequestSenders.get(key);
+                       sender = transferringRequestSenders.get(key);
                }
                if(sender != null) {
                        if(logMINOR) Logger.minor(this, "Data already being 
transferred: "+sender);
@@ -2122,7 +2338,7 @@
                synchronized(requestSenders) {
                        KeyHTLPair kh = new KeyHTLPair(key, htl, sender.uid);
                        if(requestSenders.containsKey(kh)) {
-                               RequestSender rs = (RequestSender) 
requestSenders.get(kh);
+                               RequestSender rs = requestSenders.get(kh);
                                Logger.error(this, "addRequestSender(): 
KeyHTLPair '"+kh+"' already in requestSenders as "+rs+" and you want to add 
"+sender);
                                return;
                        }
@@ -2137,7 +2353,7 @@
                synchronized(insertSenders) {
                        KeyHTLPair kh = new KeyHTLPair(key, htl, 
sender.getUID());
                        if(insertSenders.containsKey(kh)) {
-                               AnyInsertSender is = (AnyInsertSender) 
insertSenders.get(kh);
+                               AnyInsertSender is = insertSenders.get(kh);
                                Logger.error(this, "addInsertSender(): 
KeyHTLPair '"+kh+"' already in insertSenders as "+is+" and you want to add 
"+sender);
                                return;
                        }
@@ -2390,7 +2606,7 @@
        public void removeInsertSender(Key key, short htl, AnyInsertSender 
sender) {
                synchronized(insertSenders) {
                        KeyHTLPair kh = new KeyHTLPair(key, htl, 
sender.getUID());
-                       AnyInsertSender is = (AnyInsertSender) 
insertSenders.remove(kh);
+                       AnyInsertSender is = insertSenders.remove(kh);
                        if(is != sender) {
                                Logger.error(this, "Removed "+is+" should be 
"+sender+" for "+key+ ',' +htl+" in removeInsertSender");
                        }
@@ -2504,7 +2720,7 @@
                        }
                }
                // If these are switched around, we must remember to remove 
from both.
-               HashSet set = getUIDTracker(ssk, insert, offerReply, local);
+               HashSet<Long> set = getUIDTracker(ssk, insert, offerReply, 
local);
                synchronized(set) {
                        if(logMINOR) Logger.minor(this, "Locking "+uid+" 
ssk="+ssk+" insert="+insert+" offerReply="+offerReply+" local="+local+" 
size="+set.size());
                        set.add(uid);
@@ -2515,7 +2731,7 @@

        public void unlockUID(long uid, boolean ssk, boolean insert, boolean 
canFail, boolean offerReply, boolean local) {
                completed(uid);
-               HashSet set = getUIDTracker(ssk, insert, offerReply, local);
+               HashSet<Long> set = getUIDTracker(ssk, insert, offerReply, 
local);
                synchronized(set) {
                        if(logMINOR) Logger.minor(this, "Unlocking "+uid+" 
ssk="+ssk+" insert="+insert+" offerReply="+offerReply+", local="+local+" 
size="+set.size());
                        set.remove(uid);
@@ -2527,7 +2743,7 @@
                }
        }

-       HashSet getUIDTracker(boolean ssk, boolean insert, boolean offerReply, 
boolean local) {
+       private HashSet<Long> getUIDTracker(boolean ssk, boolean insert, 
boolean offerReply, boolean local) {
                if(ssk) {
                        if(offerReply)
                                return runningSSKOfferReplyUIDs;
@@ -2549,7 +2765,7 @@
         * @return Some status information.
         */
        public String getStatus() {
-               StringBuffer sb = new StringBuffer();
+               StringBuilder sb = new StringBuilder();
                if (peers != null)
                        sb.append(peers.getStatus());
                else
@@ -2557,16 +2773,16 @@
                sb.append("\nInserts: ");
                AnyInsertSender[] senders;
                synchronized(insertSenders) {
-                       senders = (AnyInsertSender[]) 
insertSenders.values().toArray(new AnyInsertSender[insertSenders.size()]);
+                       senders = insertSenders.values().toArray(new 
AnyInsertSender[insertSenders.size()]);
                }
                int x = senders.length;
                sb.append(x);
                if((x < 5) && (x > 0)) {
                        sb.append('\n');
                        // Dump
-                       Iterator i = insertSenders.values().iterator();
+                       Iterator<AnyInsertSender> i = 
insertSenders.values().iterator();
                        while(i.hasNext()) {
-                               AnyInsertSender s = (AnyInsertSender) i.next();
+                               AnyInsertSender s = i.next();
                                sb.append(s.getUID());
                                sb.append(": ");
                                sb.append(s.getStatusString());
@@ -2585,7 +2801,7 @@
         * @return TMCI peer list
         */
        public String getTMCIPeerList() {
-               StringBuffer sb = new StringBuffer();
+               StringBuilder sb = new StringBuilder();
                if (peers != null)
                        sb.append(peers.getTMCIPeerList());
                else
@@ -2677,7 +2893,7 @@
         * @return Data String for freeviz.
         */
        public String getFreevizOutput() {
-               StringBuffer sb = new StringBuffer();
+               StringBuilder sb = new StringBuilder();
                sb.append("\nrequests=");
                sb.append(getNumRequestSenders());

@@ -2724,11 +2940,11 @@
         * @see freenet.node.GetPubkey#getKey(byte[])
         */
        public DSAPublicKey getKey(byte[] hash) {
-               ImmutableByteArrayWrapper w = new 
ImmutableByteArrayWrapper(hash);
+               ByteArrayWrapper w = new ByteArrayWrapper(hash);
                if(logMINOR) Logger.minor(this, "Getting pubkey: 
"+HexUtil.bytesToHex(hash));
                if(USE_RAM_PUBKEYS_CACHE) {
                        synchronized(cachedPubKeys) {
-                               DSAPublicKey key = (DSAPublicKey) 
cachedPubKeys.get(w);
+                               DSAPublicKey key = cachedPubKeys.get(w);
                                if(key != null) {
                                        cachedPubKeys.push(w, key);
                                        if(logMINOR) Logger.minor(this, "Got 
"+HexUtil.bytesToHex(hash)+" from cache");
@@ -2758,9 +2974,9 @@
         */
        public void cacheKey(byte[] hash, DSAPublicKey key, boolean deep) {
                if(logMINOR) Logger.minor(this, "Cache key: 
"+HexUtil.bytesToHex(hash)+" : "+key);
-               ImmutableByteArrayWrapper w = new 
ImmutableByteArrayWrapper(hash);
+               ByteArrayWrapper w = new ByteArrayWrapper(hash);
                synchronized(cachedPubKeys) {
-                       DSAPublicKey key2 = (DSAPublicKey) cachedPubKeys.get(w);
+                       DSAPublicKey key2 = cachedPubKeys.get(w);
                        if((key2 != null) && !key2.equals(key)) {
                                // FIXME is this test really needed?
                                // SHA-256 inside synchronized{} is a bad idea
@@ -3352,8 +3568,8 @@
         * ports, not necessarily external - they may be rewritten by the NAT.
         * @return A Set of ForwardPort's to be fed to port forward plugins.
         */
-       public Set getPublicInterfacePorts() {
-               HashSet set = new HashSet();
+       public Set<ForwardPort> getPublicInterfacePorts() {
+               HashSet<ForwardPort> set = new HashSet<ForwardPort>();
                // FIXME IPv6 support
                set.add(new ForwardPort("darknet", false, 
ForwardPort.PROTOCOL_UDP_IPV4, darknetCrypto.portNumber));
                if(opennet != null) {
@@ -3441,7 +3657,7 @@
                }
        }

-       public void addRunningUIDs(Vector list) {
+       public void addRunningUIDs(Vector<Long> list) {
                synchronized(runningUIDs) {
                        list.addAll(runningUIDs);
                }
@@ -3489,6 +3705,6 @@
        }

        public boolean shallWeRouteAccordingToOurPeersLocation() {
-               return routeAccordingToOurPeersLocation;
+               return routeAccordingToOurPeersLocation && 
Version.lastGoodBuild() >= 1160;
        }
 }

Modified: branches/db4o/freenet/src/freenet/node/NodeClientCore.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/NodeClientCore.java  2008-09-24 
23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/node/NodeClientCore.java  2008-09-24 
23:54:07 UTC (rev 22829)
@@ -31,7 +31,6 @@
 import freenet.clients.http.filter.GenericReadFilterCallback;
 import freenet.config.Config;
 import freenet.config.InvalidConfigValueException;
-import freenet.config.NodeNeedRestartException;
 import freenet.config.SubConfig;
 import freenet.crypt.RandomSource;
 import freenet.io.xfer.AbortedException;
@@ -52,6 +51,7 @@
 import freenet.keys.SSKBlock;
 import freenet.keys.SSKVerifyException;
 import freenet.l10n.L10n;
+import freenet.node.SecurityLevels.PHYSICAL_THREAT_LEVEL;
 import freenet.node.fcp.FCPServer;
 import freenet.node.useralerts.SimpleUserAlert;
 import freenet.node.useralerts.UserAlert;
@@ -293,6 +293,28 @@
                                                0, 2, 1, 0, 0, new 
SimpleEventProducer(),
                                                
!Node.DONT_CACHE_LOCAL_REQUESTS), RequestStarter.PREFETCH_PRIORITY_CLASS, 512 
/* FIXME make configurable */);

+               node.securityLevels.addPhysicalThreatLevelListener(new 
SecurityLevelListener<PHYSICAL_THREAT_LEVEL>() {
+
+                       public void onChange(PHYSICAL_THREAT_LEVEL oldLevel, 
PHYSICAL_THREAT_LEVEL newLevel) {
+                               if(newLevel == PHYSICAL_THREAT_LEVEL.LOW) {
+                                       if(tempBucketFactory.isEncrypting()) {
+                                               
tempBucketFactory.setEncryption(false);
+                                       }
+                                       
if(persistentTempBucketFactory.isEncrypting()) {
+                                               
persistentTempBucketFactory.setEncryption(false);
+                                       }
+                               } else { // newLevel == 
PHYSICAL_THREAT_LEVEL.NORMAL
+                                       if(!tempBucketFactory.isEncrypting()) {
+                                               
tempBucketFactory.setEncryption(true);
+                                       }
+                                       
if(!persistentTempBucketFactory.isEncrypting()) {
+                                               
persistentTempBucketFactory.setEncryption(true);
+                                       }
+                               }
+                       }
+                       
+               });
+               
                // Downloads directory

                nodeConfig.register("downloadsDir", "downloads", sortOrder++, 
true, true, "NodeClientCore.downloadDir", "NodeClientCore.downloadDirLong", new 
StringCallback() {
@@ -362,23 +384,8 @@
                                }
                        });
                
setUploadAllowedDirs(nodeConfig.getStringArr("uploadAllowedDirs"));
-
-               nodeConfig.register("maxArchiveSize", "2MiB", sortOrder++, 
true, false, "NodeClientCore.maxArchiveSize", 
"NodeClientCore.maxArchiveSizeLong", new LongCallback() {
-
-                       @Override
-                       public Long get() {
-                               return archiveManager.getMaxArchiveSize();
-                       }
-
-                       @Override
-                       public void set(Long val) throws 
InvalidConfigValueException, NodeNeedRestartException {
-                               if (get().equals(val))
-                                               return;
-                               archiveManager.setMaxArchiveSize(val);
-                       }
-               });

-               archiveManager = new ArchiveManager(MAX_ARCHIVE_HANDLERS, 
MAX_CACHED_ARCHIVE_DATA, nodeConfig.getLong("maxArchiveSize"), 
MAX_ARCHIVED_FILE_SIZE, MAX_CACHED_ELEMENTS, tempBucketFactory);
+               archiveManager = new ArchiveManager(MAX_ARCHIVE_HANDLERS, 
MAX_CACHED_ARCHIVE_DATA, MAX_ARCHIVED_FILE_SIZE, MAX_CACHED_ELEMENTS, 
tempBucketFactory);
                Logger.normal(this, "Initializing USK Manager");
                System.out.println("Initializing USK Manager");
                uskManager.init(container, clientContext);

Modified: branches/db4o/freenet/src/freenet/node/NodeCryptoConfig.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/NodeCryptoConfig.java        
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/node/NodeCryptoConfig.java        
2008-09-24 23:54:07 UTC (rev 22829)
@@ -8,6 +8,8 @@
 import freenet.config.InvalidConfigValueException;
 import freenet.config.SubConfig;
 import freenet.io.comm.FreenetInetAddress;
+import freenet.node.SecurityLevels.FRIENDS_THREAT_LEVEL;
+import freenet.node.SecurityLevels.NETWORK_THREAT_LEVEL;
 import freenet.support.Logger;
 import freenet.support.api.BooleanCallback;
 import freenet.support.api.IntCallback;
@@ -22,6 +24,8 @@
  */
 public class NodeCryptoConfig {

+       private final boolean isOpennet;
+       
        /** Port number. -1 = choose a random available port number at 
activation time. */
        private int portNumber;

@@ -47,7 +51,11 @@
         * aggressive handshakes (every 10-30 seconds). */
        private boolean assumeNATed;

-       NodeCryptoConfig(SubConfig config, int sortOrder, boolean onePerIP) 
throws NodeInitException {
+       /** If true, include local addresses on noderefs */
+       public boolean includeLocalAddressesInNoderefs;
+       
+       NodeCryptoConfig(SubConfig config, int sortOrder, boolean isOpennet, 
SecurityLevels securityLevels) throws NodeInitException {
+               this.isOpennet = isOpennet;

                config.register("listenPort", -1 /* means random */, 
sortOrder++, true, true, "Node.port", "Node.portLong",     new IntCallback() {
                        public Integer get() {
@@ -119,7 +127,7 @@
                });
                dropProbability = config.getInt("testingDropPacketsEvery"); 

-               config.register("oneConnectionPerIP", onePerIP, sortOrder++, 
true, false, "Node.oneConnectionPerIP", "Node.oneConnectionPerIPLong",
+               config.register("oneConnectionPerIP", isOpennet, sortOrder++, 
true, false, "Node.oneConnectionPerIP", "Node.oneConnectionPerIPLong",
                                new BooleanCallback() {

                                        public Boolean get() {
@@ -137,7 +145,23 @@
                });
                oneConnectionPerAddress = 
config.getBoolean("oneConnectionPerIP");

-               config.register("alwaysAllowLocalAddresses", false, 
sortOrder++, true, false, "Node.alwaysAllowLocalAddresses", 
"Node.alwaysAllowLocalAddressesLong",
+               if(isOpennet) {
+                       securityLevels.addNetworkThreatLevelListener(new 
SecurityLevelListener<NETWORK_THREAT_LEVEL>() {
+
+                               public void onChange(NETWORK_THREAT_LEVEL 
oldLevel, NETWORK_THREAT_LEVEL newLevel) {
+                                       // Might be useful for nodes on the 
same NAT etc, so turn it off for LOW. Otherwise is sensible.
+                                       // It's always off on darknet, since we 
can reasonably expect to know our peers, even if we are paranoid
+                                       // about them!
+                                       if(newLevel == NETWORK_THREAT_LEVEL.LOW)
+                                               oneConnectionPerAddress = false;
+                                       if(oldLevel == NETWORK_THREAT_LEVEL.LOW)
+                                               oneConnectionPerAddress = true;
+                               }
+                               
+                       });
+               }
+               
+               config.register("alwaysAllowLocalAddresses", !isOpennet, 
sortOrder++, true, false, "Node.alwaysAllowLocalAddresses", 
"Node.alwaysAllowLocalAddressesLong",
                                new BooleanCallback() {

                                        public Boolean get() {
@@ -154,6 +178,19 @@
                });
                alwaysAllowLocalAddresses = 
config.getBoolean("alwaysAllowLocalAddresses");

+               if(!isOpennet) {
+                       securityLevels.addFriendsThreatLevelListener(new 
SecurityLevelListener<FRIENDS_THREAT_LEVEL>() {
+
+                               public void onChange(FRIENDS_THREAT_LEVEL 
oldLevel, FRIENDS_THREAT_LEVEL newLevel) {
+                                       if(newLevel == 
FRIENDS_THREAT_LEVEL.HIGH)
+                                               alwaysAllowLocalAddresses = 
false;
+                                       if(oldLevel == 
FRIENDS_THREAT_LEVEL.HIGH)
+                                               alwaysAllowLocalAddresses = 
false;
+                               }
+                               
+                       });
+               }
+               
                config.register("assumeNATed", true, sortOrder++, true, true, 
"Node.assumeNATed", "Node.assumeNATedLong", new BooleanCallback() {

                        public Boolean get() {
@@ -165,6 +202,22 @@
                        }               
                });
                assumeNATed = config.getBoolean("assumeNATed");
+               
+               // Include local IPs in noderef file
+               
+               config.register("includeLocalAddressesInNoderefs", !isOpennet, 
sortOrder++, true, false, "NodeIPDectector.inclLocalAddress", 
"NodeIPDectector.inclLocalAddressLong", new BooleanCallback() {
+
+                       public Boolean get() {
+                               return includeLocalAddressesInNoderefs;
+                       }
+
+                       public void set(Boolean val) throws 
InvalidConfigValueException {
+                               includeLocalAddressesInNoderefs = val;
+                       }
+               });
+               
+               includeLocalAddressesInNoderefs = 
config.getBoolean("includeLocalAddressesInNoderefs");
+               
        }

        /** The number of config options i.e. the amount to increment sortOrder 
by */
@@ -230,4 +283,9 @@
        public boolean alwaysHandshakeAggressively() {
                return assumeNATed;
        }
+       
+       public boolean includeLocalAddressesInNoderefs() {
+               return includeLocalAddressesInNoderefs;
+       }
+
 }

Modified: branches/db4o/freenet/src/freenet/node/NodeDispatcher.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/NodeDispatcher.java  2008-09-24 
23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/node/NodeDispatcher.java  2008-09-24 
23:54:07 UTC (rev 22829)
@@ -153,14 +153,22 @@
                         * @see 
http://archives.freenetproject.org/message/20080718.144240.359e16d3.en.html
                         */
                        if((OpennetManager.MAX_PEERS_FOR_SCALING < locs.length) 
&& (source.isOpennet())) {
-                               Logger.error(this, "We received "+locs.length+ 
" locations from "+source.toString()+"! That should *NOT* happen!");
-                               source.forceDisconnect(true);
-                               return true;
-                       } else {
-                               // We are on darknet and we trust our peers OR 
we are on opennet
-                               // and the amount of locations sent to us seems 
reasonable
-                               source.updateLocation(newLoc, locs);
+                               if(locs.length > 
OpennetManager.MAX_PEERS_FOR_SCALING * 2) {
+                                       // This can't happen by accident
+                                       Logger.error(this, "We received 
"+locs.length+ " locations from "+source.toString()+"! That should *NOT* 
happen! Possible attack!");
+                                       source.forceDisconnect(true);
+                                       return true;
+                               } else {
+                                       // A few extra can happen by accident. 
Just use the first 20.
+                                       Logger.normal(this, "Too many locations 
from "+source.toString()+" : "+locs.length+" could be an accident, using the 
first "+OpennetManager.MAX_PEERS_FOR_SCALING);
+                                       double[] firstLocs = new 
double[OpennetManager.MAX_PEERS_FOR_SCALING];
+                                       System.arraycopy(locs, 0, firstLocs, 0, 
OpennetManager.MAX_PEERS_FOR_SCALING);
+                                       locs = firstLocs;
+                               }
                        }
+                       // We are on darknet and we trust our peers OR we are 
on opennet
+                       // and the amount of locations sent to us seems 
reasonable
+                       source.updateLocation(newLoc, locs);

                        return true;
                }
@@ -524,14 +532,14 @@
                }
        }

-       final Hashtable routedContexts = new Hashtable();
+       final Hashtable<Long, RoutedContext> routedContexts = new 
Hashtable<Long, RoutedContext>();

        static class RoutedContext {
                long createdTime;
                long accessTime;
                PeerNode source;
-               final HashSet routedTo;
-               final HashSet notIgnored;
+               final HashSet<PeerNode> routedTo;
+               final HashSet<PeerNode> notIgnored;
                Message msg;
                short lastHtl;
                final byte[] identity;
@@ -539,8 +547,8 @@
                RoutedContext(Message msg, PeerNode source, byte[] identity) {
                        createdTime = accessTime = System.currentTimeMillis();
                        this.source = source;
-                       routedTo = new HashSet();
-                       notIgnored = new HashSet();
+                       routedTo = new HashSet<PeerNode>();
+                       notIgnored = new HashSet<PeerNode>();
                        this.msg = msg;
                        lastHtl = msg.getShort(DMT.HTL);
                        this.identity = identity;
@@ -557,9 +565,9 @@
        public void run() {
                long now=System.currentTimeMillis();
                synchronized (routedContexts) {
-                       Iterator i=routedContexts.values().iterator();
+                       Iterator<RoutedContext> i = 
routedContexts.values().iterator();
                        while (i.hasNext()) {
-                               RoutedContext rc = (RoutedContext)i.next();
+                               RoutedContext rc = i.next();
                                if (now-rc.createdTime > STALE_CONTEXT) {
                                        i.remove();
                                }
@@ -574,7 +582,7 @@
        private boolean handleRoutedRejected(Message m) {
                long id = m.getLong(DMT.UID);
                Long lid = new Long(id);
-               RoutedContext rc = (RoutedContext) routedContexts.get(lid);
+               RoutedContext rc = routedContexts.get(lid);
                if(rc == null) {
                        // Gah
                        Logger.error(this, "Unrecognized FNPRoutedRejected");
@@ -617,10 +625,10 @@
                byte[] identity = ((ShortBuffer) 
m.getObject(DMT.NODE_IDENTITY)).getData();
                if(source != null) htl = source.decrementHTL(htl);
                RoutedContext ctx;
-               ctx = (RoutedContext)routedContexts.get(lid);
+               ctx = routedContexts.get(lid);
                if(ctx != null) {
                        try {
-                               
source.sendAsync(DMT.createFNPRoutedRejected(id, (short)htl), null, 0, 
nodeStats.routedMessageCtr);
+                               
source.sendAsync(DMT.createFNPRoutedRejected(id, htl), null, 0, 
nodeStats.routedMessageCtr);
                        } catch (NotConnectedException e) {
                                if(logMINOR) Logger.minor(this, "Lost 
connection rejecting "+m);
                        }
@@ -656,7 +664,7 @@
                long id = m.getLong(DMT.UID);
                if(logMINOR) Logger.minor(this, "Got reply: "+m);
                Long lid = new Long(id);
-               RoutedContext ctx = (RoutedContext) routedContexts.get(lid);
+               RoutedContext ctx = routedContexts.get(lid);
                if(ctx == null) {
                        Logger.error(this, "Unrecognized routed reply: "+m);
                        return false;
@@ -748,7 +756,7 @@
        }

        public static String peersUIDsToString(long[] peerUIDs, double[] 
peerLocs) {
-               StringBuffer sb = new 
StringBuffer(peerUIDs.length*23+peerLocs.length*26);
+               StringBuilder sb = new 
StringBuilder(peerUIDs.length*23+peerLocs.length*26);
                int min=Math.min(peerUIDs.length, peerLocs.length);
                for(int i=0;i<min;i++) {
                        double loc = peerLocs[i];

Modified: branches/db4o/freenet/src/freenet/node/NodeIPDetector.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/NodeIPDetector.java  2008-09-24 
23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/node/NodeIPDetector.java  2008-09-24 
23:54:07 UTC (rev 22829)
@@ -2,6 +2,7 @@

 import java.net.InetAddress;
 import java.net.UnknownHostException;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.Iterator;
@@ -61,8 +62,6 @@
        private static IPUndetectedUserAlert primaryIPUndetectedAlert;
        // FIXME redundant? see lastIPAddress
        FreenetInetAddress[] lastIP;
-       /** If true, include local addresses on noderefs */
-       public boolean includeLocalAddressesInNoderefs;
        /** Set when we have grounds to believe that we may be behind a 
symmetric NAT. */
        boolean maybeSymmetric;
        private boolean hasDetectedPM;
@@ -97,7 +96,7 @@
         * 
         * Will warn the user with a UserAlert if we don't have sufficient 
information.
         */
-       FreenetInetAddress[] detectPrimaryIPAddress() {
+       FreenetInetAddress[] detectPrimaryIPAddress(boolean dumpLocalAddresses) 
{
                boolean addedValidIP = false;
                Logger.minor(this, "Redetecting IPs...");
                Vector addresses = new Vector();
@@ -131,6 +130,14 @@
                        hasValidIP = addedValidIP;
                }
                lastIPAddress = (FreenetInetAddress[]) addresses.toArray(new 
FreenetInetAddress[addresses.size()]);
+               if(dumpLocalAddresses) {
+                       ArrayList filtered = new 
ArrayList(lastIPAddress.length);
+                       for(int i=0;i<lastIPAddress.length;i++) {
+                               
if(IPUtil.isValidAddress(lastIPAddress[i].getAddress(), false))
+                                       filtered.add(lastIPAddress[i]);
+                       }
+                       return (FreenetInetAddress[]) filtered.toArray(new 
FreenetInetAddress[filtered.size()]);
+               }
                return lastIPAddress;
        }

@@ -195,10 +202,16 @@

                // Try to pick it up from our connections
                if(node.peers != null) {
-                       PeerNode[] peerList = node.peers.connectedPeers;
+                       PeerNode[] peerList = node.peers.myPeers;
                        HashMap countsByPeer = new HashMap();
                        // FIXME use a standard mutable int object, we have one 
somewhere
                        for(int i=0;i<peerList.length;i++) {
+                               if(!peerList[i].isConnected()) continue;
+                               if(!peerList[i].isRealConnection()) {
+                                       // Only let seed server connections 
through.
+                                       // We have to trust them anyway.
+                                       if(!(peerList[i] instanceof 
SeedServerPeerNode)) continue;
+                               }
                                Peer p = peerList[i].getRemoteDetectedPeer();
                                if(p == null || p.isNull()) continue;
                                FreenetInetAddress addr = p.getFreenetAddress();
@@ -242,7 +255,12 @@
                                        }
                                }
                                if(best != null) {
-                                       if((bestPopularity > 1) || 
(detectedAddrs.length == 0)) {
+                                       boolean hasRealDetectedAddress = false;
+                                       for(int i=0;i<detectedAddrs.length;i++) 
{
+                                               
if(IPUtil.isValidAddress(detectedAddrs[i], false))
+                                                       hasRealDetectedAddress 
= true;
+                                       }
+                                       if((bestPopularity > 1) || 
!hasRealDetectedAddress) {
                                                if(!addresses.contains(best)) {
                                                        Logger.minor(this, 
"Adding best peer "+best+" ("+bestPopularity+ ')');
                                                        addresses.add(best);
@@ -272,8 +290,8 @@
                return L10n.getString("NodeIPDetector."+key, pattern, value);
        }

-       FreenetInetAddress[] getPrimaryIPAddress() {
-               if(lastIPAddress == null) return detectPrimaryIPAddress();
+       FreenetInetAddress[] getPrimaryIPAddress(boolean dumpLocal) {
+               if(lastIPAddress == null) return 
detectPrimaryIPAddress(dumpLocal);
                return lastIPAddress;
        }

@@ -310,7 +328,7 @@
        }

        public void redetectAddress() {
-               FreenetInetAddress[] newIP = detectPrimaryIPAddress();
+               FreenetInetAddress[] newIP = detectPrimaryIPAddress(false);
                NodeIPPortDetector[] detectors;
                synchronized(this) {
                        if(Arrays.equals(newIP, lastIP)) return;
@@ -326,10 +344,6 @@
                this.oldIPAddress = freenetAddress;
        }

-       public boolean includeLocalAddressesInNoderefs() {
-               return includeLocalAddressesInNoderefs;
-       }
-
        public int registerConfigs(SubConfig nodeConfig, int sortOrder) {
                // IP address override
                nodeConfig.register("ipAddressOverride", "", sortOrder++, true, 
false, "NodeIPDectector.ipOverride", 
@@ -433,23 +447,6 @@
                        }
                }

-               // Include local IPs in noderef file
-               
-               nodeConfig.register("includeLocalAddressesInNoderefs", false, 
sortOrder++, true, false, "NodeIPDectector.inclLocalAddress", 
"NodeIPDectector.inclLocalAddressLong", new BooleanCallback() {
-
-                       public Boolean get() {
-                               return includeLocalAddressesInNoderefs;
-                       }
-
-                       public void set(Boolean val) throws 
InvalidConfigValueException {
-                               includeLocalAddressesInNoderefs = val;
-                               lastIPAddress = null;
-                               ipDetector.clearCached();
-                       }
-               });
-               
-               includeLocalAddressesInNoderefs = 
nodeConfig.getBoolean("includeLocalAddressesInNoderefs");
-               
                return sortOrder;
        }


Modified: branches/db4o/freenet/src/freenet/node/NodeIPPortDetector.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/NodeIPPortDetector.java      
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/node/NodeIPPortDetector.java      
2008-09-24 23:54:07 UTC (rev 22829)
@@ -49,7 +49,7 @@
                        // he is on a multi-homed box where only one IP can be 
used for Freenet.
                        return new FreenetInetAddress[] { addr };
                }
-               return ipDetector.detectPrimaryIPAddress();
+               return 
ipDetector.detectPrimaryIPAddress(!crypto.config.includeLocalAddressesInNoderefs);
        }

        /**

Modified: branches/db4o/freenet/src/freenet/node/NodeStarter.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/NodeStarter.java     2008-09-24 
23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/node/NodeStarter.java     2008-09-24 
23:54:07 UTC (rev 22829)
@@ -337,7 +337,7 @@
                long storeSize, boolean ramStore, boolean enableSwapping, 
boolean enableARKs,
                boolean enableULPRs, boolean enablePerNodeFailureTables,
                boolean enableSwapQueueing, boolean enablePacketCoalescing,
-               int outputBandwidthLimit, boolean enableFOAF, boolean 
connectToSeednodes) throws NodeInitException {
+               int outputBandwidthLimit, boolean enableFOAF, boolean 
connectToSeednodes, String ipAddressOverride) throws NodeInitException {

                File baseDir = new File(testName);
                File portDir = new File(baseDir, Integer.toString(port));
@@ -395,6 +395,8 @@
                configFS.put("node.opennet.connectToSeednodes", 
connectToSeednodes);
                configFS.put("node.encryptTempBuckets", false);
                configFS.put("node.encryptPersistentTempBuckets", false);
+               if(ipAddressOverride != null)
+                       configFS.putSingle("node.ipAddressOverride", 
ipAddressOverride);

                PersistentConfig config = new PersistentConfig(configFS);


Modified: branches/db4o/freenet/src/freenet/node/NodeStats.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/NodeStats.java       2008-09-24 
23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/node/NodeStats.java       2008-09-24 
23:54:07 UTC (rev 22829)
@@ -12,6 +12,7 @@
 import freenet.io.comm.ByteCounter;
 import freenet.io.comm.DMT;
 import freenet.l10n.L10n;
+import freenet.node.SecurityLevels.NETWORK_THREAT_LEVEL;
 import freenet.support.HTMLNode;
 import freenet.support.Logger;
 import freenet.support.SimpleFieldSet;
@@ -274,7 +275,22 @@
                                }
                        }
                });
+               
+               // This is a *network* level setting, because it affects the 
rate at which we initiate local
+               // requests, which could be seen by distant nodes.
+               
+               node.securityLevels.addNetworkThreatLevelListener(new 
SecurityLevelListener<NETWORK_THREAT_LEVEL>() {

+                       public void onChange(NETWORK_THREAT_LEVEL oldLevel, 
NETWORK_THREAT_LEVEL newLevel) {
+                               if(newLevel == NETWORK_THREAT_LEVEL.MAXIMUM)
+                                       ignoreLocalVsRemoteBandwidthLiability = 
true;
+                               if(oldLevel == NETWORK_THREAT_LEVEL.MAXIMUM)
+                                       ignoreLocalVsRemoteBandwidthLiability = 
false;
+                               // Otherwise leave it as it was. It defaults to 
false.
+                       }
+                       
+               });
+               
                persister = new ConfigurablePersister(this, statsConfig, 
"nodeThrottleFile", "node-throttle.dat", sortOrder++, true, false, 
                                "NodeStat.statsPersister", 
"NodeStat.statsPersisterLong", node.ps, nodeDir);

@@ -418,12 +434,12 @@
                long totalSent = total[0];
                long totalOverhead = getSentOverhead();
                long uptime = node.getUptime();
-               double sentOverheadPerSecond = ((double)totalOverhead*1000.0) / 
((double)uptime);
+               double sentOverheadPerSecond = (totalOverhead*1000.0) / 
(uptime);
                /** The fraction of output bytes which are used for requests */
                double overheadFraction = ((double)(totalSent - totalOverhead)) 
/ totalSent;
                long timeFirstAnyConnections = peers.timeFirstAnyConnections;
                long now = System.currentTimeMillis();
-               if(logMINOR) Logger.minor(this, "Output rate: 
"+((double)totalSent*1000.0)/uptime+" overhead rate "+sentOverheadPerSecond+" 
non-overhead fraction "+overheadFraction);
+               if(logMINOR) Logger.minor(this, "Output rate: 
"+(totalSent*1000.0)/uptime+" overhead rate "+sentOverheadPerSecond+" 
non-overhead fraction "+overheadFraction);
                if(timeFirstAnyConnections > 0) {
                        long time = now - timeFirstAnyConnections;
                        if(time < DEFAULT_ONLY_PERIOD) {
@@ -454,7 +470,7 @@
                                        return ">MAX_PING_TIME 
("+TimeUtil.formatTime((long)pingTime, 2, true)+ ')';
                                }
                        } else if(pingTime > SUB_MAX_PING_TIME) {
-                               double x = ((double)(pingTime - 
SUB_MAX_PING_TIME)) / (MAX_PING_TIME - SUB_MAX_PING_TIME);
+                               double x = ((pingTime - SUB_MAX_PING_TIME)) / 
(MAX_PING_TIME - SUB_MAX_PING_TIME);
                                if(hardRandom.nextDouble() < x) {
                                        pInstantRejectIncoming.report(1.0);
                                        rejected(">SUB_MAX_PING_TIME", isLocal);
@@ -472,7 +488,7 @@
                                        return ">MAX_THROTTLE_DELAY 
("+TimeUtil.formatTime((long)bwlimitDelayTime, 2, true)+ ')';
                                }
                        } else if(bwlimitDelayTime > SUB_MAX_THROTTLE_DELAY) {
-                               double x = ((double)(bwlimitDelayTime - 
SUB_MAX_THROTTLE_DELAY)) / (MAX_THROTTLE_DELAY - SUB_MAX_THROTTLE_DELAY);
+                               double x = ((bwlimitDelayTime - 
SUB_MAX_THROTTLE_DELAY)) / (MAX_THROTTLE_DELAY - SUB_MAX_THROTTLE_DELAY);
                                if(hardRandom.nextDouble() < x) {
                                        pInstantRejectIncoming.report(1.0);
                                        rejected(">SUB_MAX_THROTTLE_DELAY", 
isLocal);
@@ -888,10 +904,8 @@

                /* gather connection statistics */
                DarknetPeerNodeStatus[] peerNodeStatuses = 
peers.getDarknetPeerNodeStatuses(true);
-               Arrays.sort(peerNodeStatuses, new Comparator() {
-                       public int compare(Object first, Object second) {
-                               DarknetPeerNodeStatus firstNode = 
(DarknetPeerNodeStatus) first;
-                               DarknetPeerNodeStatus secondNode = 
(DarknetPeerNodeStatus) second;
+               Arrays.sort(peerNodeStatuses, new 
Comparator<DarknetPeerNodeStatus>() {
+                       public int compare(DarknetPeerNodeStatus firstNode, 
DarknetPeerNodeStatus secondNode) {
                                int statusDifference = 
firstNode.getStatusValue() - secondNode.getStatusValue();
                                if (statusDifference != 0) {
                                        return statusDifference;
@@ -961,9 +975,9 @@
                        }
                }

-               double swaps = (double)node.getSwaps();
-               double noSwaps = (double)node.getNoSwaps();
-               double numberOfRemotePeerLocationsSeenInSwaps = 
(double)node.getNumberOfRemotePeerLocationsSeenInSwaps();
+               double swaps = node.getSwaps();
+               double noSwaps = node.getNoSwaps();
+               double numberOfRemotePeerLocationsSeenInSwaps = 
node.getNumberOfRemotePeerLocationsSeenInSwaps();
                fs.putSingle("numberOfRemotePeerLocationsSeenInSwaps", 
Double.toString(numberOfRemotePeerLocationsSeenInSwaps));
                double avgConnectedPeersPerNode = 0.0;
                if ((numberOfRemotePeerLocationsSeenInSwaps > 0.0) && ((swaps > 
0.0) || (noSwaps > 0.0))) {
@@ -987,13 +1001,13 @@
                        locationChangePerSwap = locationChangePerSession/swaps;
                }
                if ((swaps > 0.0) && (nodeUptimeSeconds >= 60)) {
-                       locationChangePerMinute = 
locationChangePerSession/(double)(nodeUptimeSeconds/60.0);
+                       locationChangePerMinute = 
locationChangePerSession/(nodeUptimeSeconds/60.0);
                }
                if ((swaps > 0.0) && (nodeUptimeSeconds >= 60)) {
-                       swapsPerMinute = swaps/(double)(nodeUptimeSeconds/60.0);
+                       swapsPerMinute = swaps/(nodeUptimeSeconds/60.0);
                }
                if ((noSwaps > 0.0) && (nodeUptimeSeconds >= 60)) {
-                       noSwapsPerMinute = 
noSwaps/(double)(nodeUptimeSeconds/60.0);
+                       noSwapsPerMinute = noSwaps/(nodeUptimeSeconds/60.0);
                }
                if ((swaps > 0.0) && (noSwaps > 0.0)) {
                        swapsPerNoSwaps = swaps/noSwaps;
@@ -1057,9 +1071,9 @@
                fs.put("avgStoreAccessRate", avgStoreAccessRate);

                Runtime rt = Runtime.getRuntime();
-               float freeMemory = (float) rt.freeMemory();
-               float totalMemory = (float) rt.totalMemory();
-               float maxMemory = (float) rt.maxMemory();
+               float freeMemory = rt.freeMemory();
+               float totalMemory = rt.totalMemory();
+               float maxMemory = rt.maxMemory();

                long usedJavaMem = (long)(totalMemory - freeMemory);
                long allocatedJavaMem = (long)totalMemory;
@@ -1666,7 +1680,7 @@
         */
        public double getSentOverheadPerSecond() {
                long uptime = node.getUptime();
-               return ((double)getSentOverhead() * 1000.0) / ((double) uptime);
+               return (getSentOverhead() * 1000.0) / uptime;
        }

        public synchronized void successfulBlockReceive() {

Modified: branches/db4o/freenet/src/freenet/node/OpennetManager.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/OpennetManager.java  2008-09-24 
23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/node/OpennetManager.java  2008-09-24 
23:54:07 UTC (rev 22829)
@@ -236,6 +236,7 @@
                crypto.stop();
                if(purge)
                        node.peers.removeOpennetPeers();
+               crypto.socket.getAddressTracker().setPresumedInnocent();
        }

        public OpennetPeerNode addNewOpennetNode(SimpleFieldSet fs) throws 
FSParseException, PeerParseException, ReferenceSignatureVerificationException {

Modified: branches/db4o/freenet/src/freenet/node/OpennetPeerNode.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/OpennetPeerNode.java 2008-09-24 
23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/node/OpennetPeerNode.java 2008-09-24 
23:54:07 UTC (rev 22829)
@@ -102,4 +102,8 @@
                return false;
        }

+       protected void onConnect() {
+               
opennet.crypto.socket.getAddressTracker().setPresumedGuiltyAt(System.currentTimeMillis()+60*60*1000);
+       }
+       
 }

Modified: branches/db4o/freenet/src/freenet/node/PeerManager.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/PeerManager.java     2008-09-24 
23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/node/PeerManager.java     2008-09-24 
23:54:07 UTC (rev 22829)
@@ -95,13 +95,6 @@
                }
        };

-       /**
-        * Track the number of times a PeerNode has been selected by the 
routing algorithm
-        * @see PeerNode.numberOfSelections
-        */
-       private SortedSet<Long> numberOfSelectionSamples = new TreeSet<Long>();
-       private final Object numberOfSelectionSamplesSync = new Object();
-       
        public static final int PEER_NODE_STATUS_CONNECTED = 1;
        public static final int PEER_NODE_STATUS_ROUTING_BACKED_OFF = 2;
        public static final int PEER_NODE_STATUS_TOO_NEW = 3;
@@ -881,6 +874,15 @@

                long now = System.currentTimeMillis();
                int count = 0;
+               
+               Long selectionSamplesTimestamp = now - 
PeerNode.SELECTION_SAMPLING_PERIOD;
+               double[] selectionRates = new double[peers.length];
+               double totalSelectionRate = 0.0;
+               for(int i=0;i<peers.length;i++) {
+                       selectionRates[i] = peers[i].selectionRate();
+                       totalSelectionRate += selectionRates[i];
+               }
+               boolean enableFOAFMitigationHack = (peers.length >= 
PeerNode.SELECTION_MIN_PEERS) && (totalSelectionRate > 0.0);
                for(int i = 0; i < peers.length; i++) {
                        PeerNode p = peers[i];
                        if(routedTo.contains(p)) {
@@ -903,6 +905,16 @@
                                        Logger.minor(this, "Skipping old 
version: " + p.getPeer());
                                continue;
                        }
+                       if(enableFOAFMitigationHack) {
+                               double selectionRate = selectionRates[i];
+                               double selectionSamplesPercentage = 
selectionRate / totalSelectionRate;
+                               if(PeerNode.SELECTION_PERCENTAGE_WARNING < 
selectionSamplesPercentage) {
+                                       if(logMINOR)
+                                               Logger.minor(this, "Skipping 
over-selectionned peer(" + selectionSamplesPercentage + "%): " + p.getPeer());
+                                       continue;
+                               }
+                       }
+                       
                        long timeout = -1;
                        if(entry != null)
                                timeout = entry.getTimeoutTime(p);
@@ -912,7 +924,7 @@
                        double diff = Location.distance(loc, target);

                        double[] peersLocation = p.getPeersLocation();
-                       if((node.shallWeRouteAccordingToOurPeersLocation()) && 
(peersLocation != null)) {
+                       if((peersLocation != null) && 
(node.shallWeRouteAccordingToOurPeersLocation())) {
                                for(double l : peersLocation) {
                                        double newDiff = Location.distance(l, 
target);
                                        if(newDiff < diff) {
@@ -1022,7 +1034,7 @@
         * @return Some status information
         */
        public String getStatus() {
-               StringBuffer sb = new StringBuffer();
+               StringBuilder sb = new StringBuilder();
                PeerNode[] peers;
                synchronized(this) {
                        peers = myPeers;
@@ -1044,7 +1056,7 @@
         * @return TMCI peer list
         */
        public String getTMCIPeerList() {
-               StringBuffer sb = new StringBuffer();
+               StringBuilder sb = new StringBuilder();
                PeerNode[] peers;
                synchronized(this) {
                        peers = myPeers;
@@ -1063,7 +1075,7 @@
        }

        public String getFreevizOutput() {
-               StringBuffer sb = new StringBuffer();
+               StringBuilder sb = new StringBuilder();
                PeerNode[] peers;
                synchronized(this) {
                        peers = myPeers;
@@ -1876,19 +1888,8 @@
                return null;
        }

-       public SortedSet<Long> getNumberOfSelectionSamples() {
-               synchronized (numberOfSelectionSamplesSync) {
-                       return new TreeSet<Long>(numberOfSelectionSamples);
-               }
-       }
-               
        private void incrementSelectionSamples(long now, PeerNode pn) {
                // TODO: reimplement with a bit field to spare memory
-               synchronized (numberOfSelectionSamplesSync) {
-                       if(numberOfSelectionSamples.size() > 
PeerNode.SELECTION_MAX_SAMPLES * OpennetManager.MAX_PEERS_FOR_SCALING)
-                               numberOfSelectionSamples = 
numberOfSelectionSamples.tailSet(now - PeerNode.SELECTION_SAMPLING_PERIOD);
-                       numberOfSelectionSamples.add(now);
-                       pn.incrementNumberOfSelections(now);
-               }
+               pn.incrementNumberOfSelections(now);
        }
 }

Modified: branches/db4o/freenet/src/freenet/node/PeerNode.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/PeerNode.java        2008-09-24 
23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/node/PeerNode.java        2008-09-24 
23:54:07 UTC (rev 22829)
@@ -153,16 +153,13 @@
        /** Time added or restarted (reset on startup unlike peerAddedTime) */
        private long timeAddedOrRestarted;

-       /**
-        * Track the number of times this PeerNode has been selected by
-        * the routing algorithm over a given period of time
-        */
-       private SortedSet<Long> numberOfSelections = new TreeSet<Long>();
-       private final Object numberOfSelectionsSync = new Object();
+       private long countSelectionsSinceConnected = 0;
        // 5mins; yes it's alchemy!
        public static final int SELECTION_SAMPLING_PERIOD = 5 * 60 * 1000;
        // 30%; yes it's alchemy too! and probably *way* too high to serve any 
purpose
        public static final int SELECTION_PERCENTAGE_WARNING = 30;
+       // Minimum number of routable peers to have for the selection code to 
have any effect
+       public static final int SELECTION_MIN_PEERS = 5;
        // Should be good enough provided we don't get selected more than 10 
times per/sec
        // Lower the following value if you want to spare memory... or better 
switch from a TreeSet to a bit field.
        public static final int SELECTION_MAX_SAMPLES = 10 * 
SELECTION_SAMPLING_PERIOD / 1000; 
@@ -780,7 +777,7 @@
                }
                if(localHandshakeIPs == null)
                        return "null";
-               StringBuffer toOutputString = new StringBuffer(1024);
+               StringBuilder toOutputString = new StringBuilder(1024);
                boolean needSep = false;
                toOutputString.append("[ ");
                for(int i = 0; i < localHandshakeIPs.length; i++) {
@@ -1467,7 +1464,7 @@
        public boolean isBurstOnly() {
                int status = outgoingMangler.getConnectivityStatus();
                if(status == AddressTracker.DONT_KNOW) return false;
-               if(status == AddressTracker.DEFINITELY_NATED) return false;
+               if(status == AddressTracker.DEFINITELY_NATED || status == 
AddressTracker.MAYBE_NATED) return false;

                // For now. FIXME try it with a lower probability when we're 
sure that the packet-deltas mechanisms works.
                if(status == AddressTracker.MAYBE_PORT_FORWARDED) return false;
@@ -1895,6 +1892,7 @@
                        // Don't reset the uptime if we rekey
                        if(!isConnected) {
                                connectedTime = now;
+                               countSelectionsSinceConnected = 0;
                                sentInitialMessages = false;
                        } else
                                wasARekey = true;
@@ -3611,95 +3609,118 @@
         * Handle an FNPSentPackets message
         */
        public void handleSentPackets(Message m) {
-               long now = System.currentTimeMillis();
-               synchronized(this) {
-                       if(forceDisconnectCalled)
-                               return;
-                       if(now - this.timeLastConnected < 
SENT_PACKETS_MAX_TIME_AFTER_CONNECT)
-                               return;
-               }
-               long baseTime = m.getLong(DMT.TIME);
-               baseTime += this.clockDelta;
-               // Should be a reasonable approximation now
-               int[] timeDeltas = Fields.bytesToInts(((ShortBuffer) 
m.getObject(DMT.TIME_DELTAS)).getData());
-               long[] packetHashes = Fields.bytesToLongs(((ShortBuffer) 
m.getObject(DMT.HASHES)).getData());
-               long[] times = new long[timeDeltas.length];
-               for(int i = 0; i < times.length; i++)
-                       times[i] = baseTime - timeDeltas[i];
-               long tolerance = 60 * 1000 + (Math.abs(timeDeltas[0]) / 20); // 
1 minute or 5% of full interval
-               synchronized(this) {
-                       // They are in increasing order
-                       // Loop backwards
-                       long otime = Long.MAX_VALUE;
-                       long[][] sent = getSentPacketTimesHashes();
-                       long[] sentTimes = sent[0];
-                       long[] sentHashes = sent[1];
-                       short sentPtr = (short) (sent.length - 1);
-                       short notFoundCount = 0;
-                       short consecutiveNotFound = 0;
-                       short longestConsecutiveNotFound = 0;
-                       //The arrays are constructed from received data, don't 
throw an ArrayIndexOutOfBoundsException if they are different sizes.
-                       int shortestArray=times.length;
-                       if (shortestArray > packetHashes.length)
-                               shortestArray = packetHashes.length;
-                       for(short i = (short) (shortestArray-1); i >= 0; i--) { 
-                               long time = times[i];
-                               if(time > otime) {
-                                       Logger.error(this, "Inconsistent time 
order: [" + i + "]=" + time + " but [" + (i + 1) + "] is " + otime);
-                                       return;
-                               } else
-                                       otime = time;
-                               long hash = packetHashes[i];
-                               // Search for the hash.
-                               short match = -1;
-                               // First try forwards
-                               for(short j = sentPtr; j < sentTimes.length; 
j++) {
-                                       long ttime = sentTimes[j];
-                                       if(sentHashes[j] == hash) {
-                                               match = j;
-                                               sentPtr = j;
-                                               break;
-                                       }
-                                       if(ttime - time > tolerance)
-                                               break;
-                               }
-                               if(match == -1)
-                                       for(short j = (short) (sentPtr - 1); j 
>= 0; j--) {
-                                               long ttime = sentTimes[j];
-                                               if(sentHashes[j] == hash) {
-                                                       match = j;
-                                                       sentPtr = j;
-                                                       break;
-                                               }
-                                               if(time - ttime > tolerance)
-                                                       break;
-                                       }
-                               if(match == -1) {
-                                       // Not found
-                                       consecutiveNotFound++;
-                                       notFoundCount++;
-                               } else {
-                                       if(consecutiveNotFound > 
longestConsecutiveNotFound)
-                                               longestConsecutiveNotFound = 
consecutiveNotFound;
-                                       consecutiveNotFound = 0;
-                               }
-                       }
-                       if(consecutiveNotFound > longestConsecutiveNotFound)
-                               longestConsecutiveNotFound = 
consecutiveNotFound;
-                       if(consecutiveNotFound > TRACK_PACKETS / 2) {
-                               manyPacketsClaimedSentNotReceived = true;
-                               Logger.error(this, "" + consecutiveNotFound + " 
consecutive packets not found on " + userToString());
-                               SocketHandler handler = 
outgoingMangler.getSocketHandler();
-                               if(handler instanceof 
PortForwardSensitiveSocketHandler) {
-                                       ((PortForwardSensitiveSocketHandler) 
handler).rescanPortForward();
-                               }
-                       }
-               }
-               if(manyPacketsClaimedSentNotReceived) {
-                       outgoingMangler.setPortForwardingBroken();
-               }
+               
+               // IMHO it's impossible to make this work reliably on lossy 
connections, especially highly saturated upstreams.
+               // If it was possible it would likely involve a lot of work, 
refactoring, voting between peers, marginal results,
+               // very slow accumulation of data etc.
+               
+//             long now = System.currentTimeMillis();
+//             synchronized(this) {
+//                     if(forceDisconnectCalled)
+//                             return;
+//                     /*
+//                      * I've had some very strange results from seed clients!
+//                      * One showed deltas of over 10 minutes... how is that 
possible? The PN wouldn't reconnect?!
+//                      */
+//                     if(!isRealConnection())
+//                             return; // The packets wouldn't have been 
assigned to this PeerNode!
+////                   if(now - this.timeLastConnected < 
SENT_PACKETS_MAX_TIME_AFTER_CONNECT)
+////                           return;
+//             }
+//             long baseTime = m.getLong(DMT.TIME);
+//             baseTime += this.clockDelta;
+//             // Should be a reasonable approximation now
+//             int[] timeDeltas = Fields.bytesToInts(((ShortBuffer) 
m.getObject(DMT.TIME_DELTAS)).getData());
+//             long[] packetHashes = Fields.bytesToLongs(((ShortBuffer) 
m.getObject(DMT.HASHES)).getData());
+//             long[] times = new long[timeDeltas.length];
+//             for(int i = 0; i < times.length; i++)
+//                     times[i] = baseTime - timeDeltas[i];
+//             long tolerance = 60 * 1000 + (Math.abs(timeDeltas[0]) / 20); // 
1 minute or 5% of full interval
+//             synchronized(this) {
+//                     // They are in increasing order
+//                     // Loop backwards
+//                     long otime = Long.MAX_VALUE;
+//                     long[][] sent = getRecvPacketTimesHashes();
+//                     long[] sentTimes = sent[0];
+//                     long[] sentHashes = sent[1];
+//                     short sentPtr = (short) (sent.length - 1);
+//                     short notFoundCount = 0;
+//                     short consecutiveNotFound = 0;
+//                     short longestConsecutiveNotFound = 0;
+//                     short ignoredUptimeCount = 0;
+//                     short found = 0;
+//                     //The arrays are constructed from received data, don't 
throw an ArrayIndexOutOfBoundsException if they are different sizes.
+//                     int shortestArray=times.length;
+//                     if (shortestArray > packetHashes.length)
+//                             shortestArray = packetHashes.length;
+//                     for(short i = (short) (shortestArray-1); i >= 0; i--) { 
+//                             long time = times[i];
+//                             if(time > otime) {
+//                                     Logger.error(this, "Inconsistent time 
order: [" + i + "]=" + time + " but [" + (i + 1) + "] is " + otime);
+//                                     return;
+//                             } else
+//                                     otime = time;
+//                             long hash = packetHashes[i];
+//                             // Search for the hash.
+//                             short match = -1;
+//                             // First try forwards
+//                             for(short j = sentPtr; j < sentTimes.length; 
j++) {
+//                                     long ttime = sentTimes[j];
+//                                     if(sentHashes[j] == hash) {
+//                                             match = j;
+//                                             sentPtr = j;
+//                                             break;
+//                                     }
+//                                     if(ttime - time > tolerance)
+//                                             break;
+//                             }
+//                             if(match == -1)
+//                                     for(short j = (short) (sentPtr - 1); j 
>= 0; j--) {
+//                                             long ttime = sentTimes[j];
+//                                             if(sentHashes[j] == hash) {
+//                                                     match = j;
+//                                                     sentPtr = j;
+//                                                     break;
+//                                             }
+//                                             if(time - ttime > tolerance)
+//                                                     break;
+//                                     }
+//                             if(match == -1) {
+//                                     long mustHaveBeenUpAt = now - 
(int)(timeDeltas[i] * 1.1) - 100;
+//                                     if(this.crypto.socket.getStartTime() > 
mustHaveBeenUpAt) {
+//                                             ignoredUptimeCount++;
+//                                     } else {
+//                                             // Not found
+//                                             consecutiveNotFound++;
+//                                             notFoundCount++;
+//                                     }
+//                             } else {
+//                                     if(consecutiveNotFound > 
longestConsecutiveNotFound)
+//                                             longestConsecutiveNotFound = 
consecutiveNotFound;
+//                                     consecutiveNotFound = 0;
+//                                     found++;
+//                             }
+//                     }
+//                     if(consecutiveNotFound > longestConsecutiveNotFound)
+//                             longestConsecutiveNotFound = 
consecutiveNotFound;
+//                     Logger.error(this, "Packets: "+packetHashes.length+" 
not found "+notFoundCount+" consecutive not found "+consecutiveNotFound+" 
longest consecutive not found "+longestConsecutiveNotFound+" ignored due to 
uptime: "+ignoredUptimeCount+" found: "+found);
+//                     if(longestConsecutiveNotFound > TRACK_PACKETS / 2) {
+//                             manyPacketsClaimedSentNotReceived = true;
+//                             timeManyPacketsClaimedSentNotReceived = now;
+//                             Logger.error(this, "" + consecutiveNotFound + " 
consecutive packets not found on " + userToString());
+//                             SocketHandler handler = 
outgoingMangler.getSocketHandler();
+//                             if(handler instanceof 
PortForwardSensitiveSocketHandler) {
+//                                     ((PortForwardSensitiveSocketHandler) 
handler).rescanPortForward();
+//                             }
+//                     }
+//             }
+//             if(manyPacketsClaimedSentNotReceived) {
+//                     outgoingMangler.setPortForwardingBroken();
+//             }
        }
        private boolean manyPacketsClaimedSentNotReceived = false;
+       
+       private long timeManyPacketsClaimedSentNotReceived;

        synchronized boolean manyPacketsClaimedSentNotReceived() {
                return manyPacketsClaimedSentNotReceived;
@@ -3993,22 +4014,23 @@
                return (short)(((int)uptime) & 0xFF);
        }

-       public SortedSet<Long> getNumberOfSelections() {
-               // FIXME: returning a copy is not an option: find a smarter way 
of dealing with the synchronization
-               synchronized(numberOfSelectionsSync) {
-                       return numberOfSelections;
-               }
-       }
-       
        public void incrementNumberOfSelections(long time) {
                // TODO: reimplement with a bit field to spare memory
-               synchronized(numberOfSelectionsSync) {
-                       if(numberOfSelections.size() > SELECTION_MAX_SAMPLES)
-                               numberOfSelections = 
numberOfSelections.tailSet(time - SELECTION_SAMPLING_PERIOD);
-                       numberOfSelections.add(time);
+               synchronized(this) {
+                       countSelectionsSinceConnected++;
                }
        }

+       /**
+        * @return The rate at which this peer has been selected since it 
connected.
+        */
+       public synchronized double selectionRate() {
+               long uptime = System.currentTimeMillis() - this.connectedTime;
+               // Avoid bias due to short uptime.
+               if(uptime < 10*1000) return 0.0;
+               return countSelectionsSinceConnected / (double) uptime;
+       }
+
        private long offeredMainJarVersion;

        public void setMainJarOfferedVersion(long mainJarVersion) {

Modified: branches/db4o/freenet/src/freenet/node/PeerNodeStatus.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/PeerNodeStatus.java  2008-09-24 
23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/node/PeerNodeStatus.java  2008-09-24 
23:54:07 UTC (rev 22829)
@@ -95,7 +95,7 @@

        private final int reportedUptimePercentage;

-       private final SortedSet<Long> numberOfSelections;
+       private final double selectionRate;

        PeerNodeStatus(PeerNode peerNode, boolean noHeavy) {
                if(Logger.shouldLog(Logger.MINOR, this)) {
@@ -109,7 +109,7 @@
                        peerAddress = p.getFreenetAddress().toString();
                        peerPort = p.getPort();
                }
-               this.numberOfSelections = peerNode.getNumberOfSelections();
+               this.selectionRate = peerNode.selectionRate();
                this.statusValue = peerNode.getPeerNodeStatus();
                this.statusName = peerNode.getPeerNodeStatusString();
                this.statusCSSName = peerNode.getPeerNodeStatusCSSClassName();
@@ -398,7 +398,7 @@
                return reportedUptimePercentage;
        }

-       public SortedSet<Long> getNumberOfSelections() {
-               return numberOfSelections;
+       public double getSelectionRate() {
+               return selectionRate;
        }
 }

Modified: branches/db4o/freenet/src/freenet/node/RequestStarterGroup.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/RequestStarterGroup.java     
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/node/RequestStarterGroup.java     
2008-09-24 23:54:07 UTC (rev 22829)
@@ -193,7 +193,7 @@
        }

        public String statsPageLine(boolean isSSK, boolean isInsert) {
-               StringBuffer sb = new StringBuffer(100);
+               StringBuilder sb = new StringBuilder(100);
                sb.append(isSSK ? "SSK" : "CHK");
                sb.append(' ');
                sb.append(isInsert ? "Insert" : "Request");
@@ -209,7 +209,7 @@
        }

        public String diagnosticThrottlesLine(boolean mode) {
-               StringBuffer sb = new StringBuffer();
+               StringBuilder sb = new StringBuilder();
                if(mode) {
                        sb.append("Request window: ");
                        sb.append(throttleWindowRequest.toString());

Copied: branches/db4o/freenet/src/freenet/node/SecurityLevelListener.java (from 
rev 22484, trunk/freenet/src/freenet/node/SecurityLevelListener.java)
===================================================================
--- branches/db4o/freenet/src/freenet/node/SecurityLevelListener.java           
                (rev 0)
+++ branches/db4o/freenet/src/freenet/node/SecurityLevelListener.java   
2008-09-24 23:54:07 UTC (rev 22829)
@@ -0,0 +1,7 @@
+package freenet.node;
+
+public interface SecurityLevelListener<T> {
+       
+       public void onChange(T oldLevel, T newLevel);
+
+}

Copied: branches/db4o/freenet/src/freenet/node/SecurityLevels.java (from rev 
22484, trunk/freenet/src/freenet/node/SecurityLevels.java)
===================================================================
--- branches/db4o/freenet/src/freenet/node/SecurityLevels.java                  
        (rev 0)
+++ branches/db4o/freenet/src/freenet/node/SecurityLevels.java  2008-09-24 
23:54:07 UTC (rev 22829)
@@ -0,0 +1,456 @@
+/* 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.node;
+
+import java.util.ArrayList;
+
+import freenet.clients.http.ConfigToadlet;
+import freenet.config.EnumerableOptionCallback;
+import freenet.config.InvalidConfigValueException;
+import freenet.config.NodeNeedRestartException;
+import freenet.config.PersistentConfig;
+import freenet.config.SubConfig;
+import freenet.l10n.L10n;
+import freenet.node.useralerts.UserAlert;
+import freenet.node.useralerts.UserAlertManager;
+import freenet.support.HTMLNode;
+import freenet.support.Logger;
+import freenet.support.api.StringCallback;
+
+/**
+ * We have 3 basic security settings. The user chooses these in the first-time 
+ * wizard, and can reconfigure them at any time. Each impacts on many other
+ * config settings, changing their defaults and changing their values when the
+ * security level changes, but the user can change those options independantly 
if
+ * they do not change the security level. These options are important, and 
there
+ * are explanations of every option for each setting. They have their own 
+ * sub-page on the config toadlet. And the security levels are displayed on the
+ * homepage as a useralert (instead of the opennet warning).
+ * @author Matthew Toseland <toad at amphibian.dyndns.org> (0xE43DA450)
+ */
+public class SecurityLevels {
+       
+       private final Node node;
+       
+       public enum NETWORK_THREAT_LEVEL {
+               LOW, // turn off every performance impacting security measure
+               NORMAL, // normal setting, darknet/opennet hybrid
+               HIGH, // darknet only, normal settings otherwise
+               MAXIMUM, // paranoid - darknet only, turn off FOAF etc etc
+       }
+       
+       public enum FRIENDS_THREAT_LEVEL {
+               LOW, // Friends are ultimately trusted
+               NORMAL, // Share some information
+               HIGH, // Share no/minimal information and take measures to 
reduce harm if Friends are compromized
+       }
+       
+       public enum PHYSICAL_THREAT_LEVEL {
+               LOW, // Don't encrypt temp files etc etc
+               NORMAL, // Encrypt temp files etc etc
+       }
+       
+       NETWORK_THREAT_LEVEL networkThreatLevel;
+       FRIENDS_THREAT_LEVEL friendsThreatLevel;
+       PHYSICAL_THREAT_LEVEL physicalThreatLevel;
+       
+       private MyCallback<NETWORK_THREAT_LEVEL> networkThreatLevelCallback;
+       private MyCallback<FRIENDS_THREAT_LEVEL> friendsThreatLevelCallback;
+       private MyCallback<PHYSICAL_THREAT_LEVEL> physicalThreatLevelCallback;
+       
+       public SecurityLevels(Node node, PersistentConfig config) {
+               this.node = node;
+               SubConfig myConfig = new SubConfig("security-levels", config);
+               int sortOrder = 0;
+               networkThreatLevelCallback = new 
MyCallback<NETWORK_THREAT_LEVEL>() {
+
+                       @Override
+                       public String get() {
+                               synchronized(SecurityLevels.this) {
+                                       return networkThreatLevel.name();
+                               }
+                       }
+
+                       public String[] getPossibleValues() {
+                               NETWORK_THREAT_LEVEL[] values = 
NETWORK_THREAT_LEVEL.values();
+                               String[] names = new String[values.length];
+                               for(int i=0;i<names.length;i++)
+                                       names[i] = values[i].name();
+                               return names;
+                       }
+
+                       @Override
+                       protected NETWORK_THREAT_LEVEL getValue() {
+                               return networkThreatLevel;
+                       }
+
+                       @Override
+                       protected void setValue(String val) throws 
InvalidConfigValueException {
+                               NETWORK_THREAT_LEVEL newValue = 
parseNetworkThreatLevel(val);
+                               if(newValue != null)
+                                       throw new 
InvalidConfigValueException("Invalid value for network threat level: "+val);
+                               synchronized(SecurityLevels.this) {
+                                       networkThreatLevel = newValue;
+                               }
+                       }
+
+               };
+               myConfig.register("networkThreatLevel", "NORMAL", sortOrder++, 
false, true, "SecurityLevels.networkThreatLevelShort", 
"SecurityLevels.networkThreatLevel", networkThreatLevelCallback);
+               networkThreatLevel = 
NETWORK_THREAT_LEVEL.valueOf(myConfig.getString("networkThreatLevel"));
+               friendsThreatLevelCallback = new 
MyCallback<FRIENDS_THREAT_LEVEL>() {
+
+                       @Override
+                       public String get() {
+                               synchronized(SecurityLevels.this) {
+                                       return friendsThreatLevel.name();
+                               }
+                       }
+
+                       public String[] getPossibleValues() {
+                               FRIENDS_THREAT_LEVEL[] values = 
FRIENDS_THREAT_LEVEL.values();
+                               String[] names = new String[values.length];
+                               for(int i=0;i<names.length;i++)
+                                       names[i] = values[i].name();
+                               return names;
+                       }
+
+                       @Override
+                       protected FRIENDS_THREAT_LEVEL getValue() {
+                               return friendsThreatLevel;
+                       }
+
+                       @Override
+                       protected void setValue(String val) throws 
InvalidConfigValueException {
+                               FRIENDS_THREAT_LEVEL newValue = 
FRIENDS_THREAT_LEVEL.valueOf(val);
+                               if(newValue != null)
+                                       throw new 
InvalidConfigValueException("Invalid value for friends threat level: "+val);
+                               synchronized(SecurityLevels.this) {
+                                       friendsThreatLevel = newValue;
+                               }
+                       }
+
+               };
+               myConfig.register("friendsThreatLevel", "NORMAL", sortOrder++, 
false, true, "SecurityLevels.friendsThreatLevelShort", 
"SecurityLevels.friendsThreatLevel", friendsThreatLevelCallback);
+               friendsThreatLevel = 
FRIENDS_THREAT_LEVEL.valueOf(myConfig.getString("friendsThreatLevel"));
+               physicalThreatLevelCallback = new 
MyCallback<PHYSICAL_THREAT_LEVEL>() {
+
+                       @Override
+                       public String get() {
+                               synchronized(SecurityLevels.this) {
+                                       return physicalThreatLevel.name();
+                               }
+                       }
+
+                       public String[] getPossibleValues() {
+                               PHYSICAL_THREAT_LEVEL[] values = 
PHYSICAL_THREAT_LEVEL.values();
+                               String[] names = new String[values.length];
+                               for(int i=0;i<names.length;i++)
+                                       names[i] = values[i].name();
+                               return names;
+                       }
+
+                       @Override
+                       protected PHYSICAL_THREAT_LEVEL getValue() {
+                               return physicalThreatLevel;
+                       }
+
+                       @Override
+                       protected void setValue(String val) throws 
InvalidConfigValueException {
+                               PHYSICAL_THREAT_LEVEL newValue = 
PHYSICAL_THREAT_LEVEL.valueOf(val);
+                               if(newValue != null)
+                                       throw new 
InvalidConfigValueException("Invalid value for physical threat level: "+val);
+                               synchronized(SecurityLevels.this) {
+                                       physicalThreatLevel = newValue;
+                               }
+                       }
+
+               };
+               myConfig.register("physicalThreatLevel", "NORMAL", sortOrder++, 
false, true, "SecurityLevels.physicalThreatLevelShort", 
"SecurityLevels.physicalThreatLevel", physicalThreatLevelCallback);
+               physicalThreatLevel = 
PHYSICAL_THREAT_LEVEL.valueOf(myConfig.getString("physicalThreatLevel"));
+               myConfig.finishedInitialization();
+       }
+       
+       public synchronized void 
addNetworkThreatLevelListener(SecurityLevelListener<NETWORK_THREAT_LEVEL> 
listener) {
+               networkThreatLevelCallback.addListener(listener);
+       }
+       
+       public synchronized void 
addFriendsThreatLevelListener(SecurityLevelListener<FRIENDS_THREAT_LEVEL> 
listener) {
+               friendsThreatLevelCallback.addListener(listener);
+       }
+       
+       public synchronized void 
addPhysicalThreatLevelListener(SecurityLevelListener<PHYSICAL_THREAT_LEVEL> 
listener) {
+               physicalThreatLevelCallback.addListener(listener);
+       }
+       
+       private abstract class MyCallback<T> extends StringCallback implements 
EnumerableOptionCallback {
+
+               private final ArrayList<SecurityLevelListener<T>> listeners;
+               
+               MyCallback() {
+                       listeners = new ArrayList<SecurityLevelListener<T>>();
+               }
+               
+               public void addListener(SecurityLevelListener<T> listener) {
+                       if(listeners.contains(listener)) {
+                               Logger.error(this, "Already have listener 
"+listener+" in "+this);
+                               return;
+                       }
+                       listeners.add(listener);
+               }
+               
+               public void setPossibleValues(String[] val) {
+                       throw new UnsupportedOperationException();
+               }
+               
+               @Override
+               public void set(String val) throws InvalidConfigValueException, 
NodeNeedRestartException {
+                       T oldLevel = getValue();
+                       setValue(val);
+                       T newLevel = getValue();
+                       onSet(oldLevel, newLevel);
+               }
+
+               void onSet(T oldLevel, T newLevel) {
+                       for(SecurityLevelListener<T> listener : listeners) {
+                               listener.onChange(oldLevel, newLevel);
+                       }
+               }
+
+               protected abstract void setValue(String val) throws 
InvalidConfigValueException;
+
+               protected abstract T getValue();
+               
+       }
+
+       public NETWORK_THREAT_LEVEL getNetworkThreatLevel() {
+               return networkThreatLevel;
+       }
+       
+       public FRIENDS_THREAT_LEVEL getFriendsThreatLevel() {
+               return friendsThreatLevel;
+       }
+
+       public PHYSICAL_THREAT_LEVEL getPhysicalThreatLevel() {
+               return physicalThreatLevel;
+       }
+       
+       public static NETWORK_THREAT_LEVEL parseNetworkThreatLevel(String arg) {
+               try {
+                       return NETWORK_THREAT_LEVEL.valueOf(arg);
+               } catch (IllegalArgumentException e) {
+                       return null;
+               }
+       }
+       
+       public static FRIENDS_THREAT_LEVEL parseFriendsThreatLevel(String arg) {
+               try {
+                       return FRIENDS_THREAT_LEVEL.valueOf(arg);
+               } catch (IllegalArgumentException e) {
+                       return null;
+               }
+       }
+       
+       public static PHYSICAL_THREAT_LEVEL parsePhysicalThreatLevel(String 
arg) {
+               try {
+                       return PHYSICAL_THREAT_LEVEL.valueOf(arg);
+               } catch (IllegalArgumentException e) {
+                       return null;
+               }
+       }
+
+       /**
+        * If changing to the new threat level is a potential problem, warn the 
user,
+        * and include a checkbox for confirmation.
+        * @param newThreatLevel
+        * @return
+        */
+       public HTMLNode getConfirmWarning(NETWORK_THREAT_LEVEL newThreatLevel, 
String checkboxName) {
+               if(newThreatLevel == networkThreatLevel)
+                       return null; // Not going to be changed.
+               HTMLNode parent = new HTMLNode("div");
+               if((newThreatLevel == NETWORK_THREAT_LEVEL.HIGH && 
networkThreatLevel != NETWORK_THREAT_LEVEL.MAXIMUM) || 
+                               newThreatLevel == NETWORK_THREAT_LEVEL.MAXIMUM) 
{
+                       if(node.peers.getDarknetPeers().length == 0) {
+                               parent.addChild("p", l10n("noFriendsWarning"));
+                               if(newThreatLevel == 
NETWORK_THREAT_LEVEL.MAXIMUM) {
+                                       HTMLNode p = parent.addChild("p");
+                                       L10n.addL10nSubstitution(p, 
"SecurityLevels.maximumNetworkThreatLevelWarning", new String[] { "bold", 
"/bold" }, new String[] { "<b>", "</b>" });
+                               }
+                               parent.addChild("input", new String[] { "type", 
"name", "value" }, new String[] { "checkbox", checkboxName, "off" }, 
l10n("noFriendsCheckbox"));
+                               return parent;
+                       } else if(node.peers.countConnectedDarknetPeers() == 0) 
{
+                               parent.addChild("p", 
l10n("noConnectedFriendsWarning", "added", 
Integer.toString(node.peers.getDarknetPeers().length)));
+                               if(newThreatLevel == 
NETWORK_THREAT_LEVEL.MAXIMUM) {
+                                       HTMLNode p = parent.addChild("p");
+                                       L10n.addL10nSubstitution(p, 
"SecurityLevels.maximumNetworkThreatLevelWarning", new String[] { "bold", 
"/bold" }, new String[] { "<b>", "</b>" });
+                               }
+                               parent.addChild("input", new String[] { "type", 
"name", "value" }, new String[] { "checkbox", checkboxName, "off" }, 
l10n("noConnectedFriendsCheckbox"));
+                               return parent;
+                       } else if(node.peers.countConnectedDarknetPeers() < 10) 
{
+                               parent.addChild("p", 
l10n("fewConnectedFriendsWarning", new String[] { "connected", "added" }, new 
String[] { Integer.toString(node.peers.countConnectedDarknetPeers()), 
Integer.toString(node.peers.getDarknetPeers().length)}));
+                               if(newThreatLevel == 
NETWORK_THREAT_LEVEL.MAXIMUM) {
+                                       HTMLNode p = parent.addChild("p");
+                                       L10n.addL10nSubstitution(p, 
"SecurityLevels.maximumNetworkThreatLevelWarning", new String[] { "bold", 
"/bold" }, new String[] { "<b>", "</b>" });
+                               }
+                               parent.addChild("input", new String[] { "type", 
"name", "value" }, new String[] { "checkbox", checkboxName, "off" }, 
l10n("fewConnectedFriendsCheckbox"));
+                               return parent;
+                       }
+               } else if(newThreatLevel == NETWORK_THREAT_LEVEL.LOW) {
+                       parent.addChild("p", 
l10n("networkThreatLevelLowWarning"));
+                       parent.addChild("input", new String[] { "type", "name", 
"value" }, new String[] { "checkbox", checkboxName, "off" }, 
l10n("networkThreatLevelLowCheckbox"));
+                       return parent;
+               } // Don't warn on switching to NORMAL.
+               if(newThreatLevel == NETWORK_THREAT_LEVEL.MAXIMUM) {
+                       HTMLNode p = parent.addChild("p");
+                       L10n.addL10nSubstitution(p, 
"SecurityLevels.maximumNetworkThreatLevelWarning", new String[] { "bold", 
"/bold" }, new String[] { "<b>", "</b>" });
+                       p.addChild("#", " ");
+                       L10n.addL10nSubstitution(p, 
"SecurityLevels.maxSecurityYouNeedFriends", new String[] { "bold", "/bold" }, 
new String[] { "<b>", "</b>" });
+                       parent.addChild("input", new String[] { "type", "name", 
"value" }, new String[] { "checkbox", checkboxName, "off" }, 
l10n("maximumNetworkThreatLevelCheckbox"));
+                       return parent;
+               }
+               return null;
+       }
+       
+       public HTMLNode getConfirmWarning(FRIENDS_THREAT_LEVEL newFriendsLevel, 
String checkboxName) {
+               if(newFriendsLevel == friendsThreatLevel)
+                       return null; // Not going to be changed.
+               if(newFriendsLevel == FRIENDS_THREAT_LEVEL.HIGH) {
+                       HTMLNode parent = new HTMLNode("div");
+                       parent.addChild("p", 
l10n("highFriendsThreatLevelWarning"));
+                       parent.addChild("input", new String[] { "type", "name", 
"value" }, new String[] { "checkbox", checkboxName, "off" }, 
l10n("highFriendsThreatLevelCheckbox"));
+                       return parent;
+               }
+               return null;
+       }
+
+       private String l10n(String string) {
+               return L10n.getString("SecurityLevels."+string);
+       }
+
+       private String l10n(String string, String pattern, String value) {
+               return L10n.getString("SecurityLevels."+string, pattern, value);
+       }
+
+       private String l10n(String string, String[] patterns, String[] values) {
+               return L10n.getString("SecurityLevels."+string, patterns, 
values);
+       }
+
+       public void setThreatLevel(NETWORK_THREAT_LEVEL newThreatLevel) {
+               if(newThreatLevel == null) throw new NullPointerException();
+               NETWORK_THREAT_LEVEL oldLevel;
+               synchronized(this) {
+                       oldLevel = networkThreatLevel;
+                       networkThreatLevel = newThreatLevel;
+               }
+               networkThreatLevelCallback.onSet(oldLevel, newThreatLevel);
+       }
+
+       public void setThreatLevel(FRIENDS_THREAT_LEVEL newThreatLevel) {
+               if(newThreatLevel == null) throw new NullPointerException();
+               FRIENDS_THREAT_LEVEL oldLevel;
+               synchronized(this) {
+                       oldLevel = friendsThreatLevel;
+                       friendsThreatLevel = newThreatLevel;
+               }
+               friendsThreatLevelCallback.onSet(oldLevel, newThreatLevel);
+       }
+       
+       public void setThreatLevel(PHYSICAL_THREAT_LEVEL newThreatLevel) {
+               if(newThreatLevel == null) throw new NullPointerException();
+               PHYSICAL_THREAT_LEVEL oldLevel;
+               synchronized(this) {
+                       oldLevel = physicalThreatLevel;
+                       physicalThreatLevel = newThreatLevel;
+               }
+               physicalThreatLevelCallback.onSet(oldLevel, newThreatLevel);
+       }
+
+       public static String localisedName(NETWORK_THREAT_LEVEL newThreatLevel) 
{
+               return 
L10n.getString("SecurityLevels.networkThreatLevel.name."+newThreatLevel.name());
+       }
+       
+       public static String localisedName(FRIENDS_THREAT_LEVEL 
newFriendsLevel) {
+               return 
L10n.getString("SecurityLevels.friendsThreatLevel.name."+newFriendsLevel.name());
+       }
+       
+       public static String localisedName(PHYSICAL_THREAT_LEVEL 
newPhysicalLevel) {
+               return 
L10n.getString("SecurityLevels.physicalThreatLevel.name."+newPhysicalLevel.name());
+       }
+
+       public void registerUserAlert(UserAlertManager alerts) {
+               alerts.register(new UserAlert() {
+
+                       public String anchor() {
+                               return "seclevels";
+                       }
+
+                       public String dismissButtonText() {
+                               return L10n.getString("UserAlert.hide");
+                       }
+
+                       public HTMLNode getHTMLText() {
+                               HTMLNode div = new HTMLNode("div");
+                               HTMLNode ul = div.addChild("ul");
+                               ul.addChild("li", 
l10n("userAlertNetworkThreatLevel", "level", 
localisedName(networkThreatLevel)));
+                               ul.addChild("li", 
l10n("userAlertFriendsThreatLevel", "level", 
localisedName(friendsThreatLevel)));
+                               ul.addChild("li", 
l10n("userAlertPhysicalThreatLevel", "level", 
localisedName(physicalThreatLevel)));
+                               div.addChild("br");
+                               L10n.addL10nSubstitution(div, 
"SecurityLevels.userAlertExtro",
+                                               new String[] { "link", "/link" 
},
+                                               new String[] { "<a 
href=\"/config/?mode="+ConfigToadlet.MODE_SECURITY_LEVELS+"\">", "</a>" });
+                               return div;
+                       }
+
+                       public short getPriorityClass() {
+                               return UserAlert.WARNING;
+                       }
+
+                       public String getShortText() {
+                               return l10n("userAlertShortText", new String[] 
{ "network", "friends", "physical" },
+                                               new String[] {
+                                                       
localisedName(networkThreatLevel),
+                                                       
localisedName(friendsThreatLevel),
+                                                       
localisedName(physicalThreatLevel)} );
+                       }
+
+                       public String getText() {
+                               return getHTMLText().getContent();
+                       }
+
+                       public String getTitle() {
+                               return l10n("title");
+                       }
+
+                       public Object getUserIdentifier() {
+                               return null;
+                       }
+
+                       public boolean isEventNotification() {
+                               return false;
+                       }
+
+                       public boolean isValid() {
+                               return true;
+                       }
+
+                       public void isValid(boolean validity) {
+                               // Ignore
+                       }
+
+                       public void onDismiss() {
+                               // Ignore
+                       }
+
+                       public boolean shouldUnregisterOnDismiss() {
+                               return true;
+                       }
+
+                       public boolean userCanDismiss() {
+                               return true;
+                       }
+                       
+               });
+       }
+
+}

Modified: branches/db4o/freenet/src/freenet/node/TextModeClientInterface.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/TextModeClientInterface.java 
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/node/TextModeClientInterface.java 
2008-09-24 23:54:07 UTC (rev 22829)
@@ -139,7 +139,7 @@
        }

        private void printHeader(OutputStream s) throws IOException {
-       StringBuffer sb = new StringBuffer();
+       StringBuilder sb = new StringBuilder();

         sb.append("Trivial Text Mode Client Interface\r\n");
         sb.append("---------------------------------------\r\n");
@@ -205,7 +205,7 @@
      */
     private boolean processLine(BufferedReader reader, final OutputStream out) 
throws IOException {
         String line;
-        StringBuffer outsb = new StringBuffer();
+        StringBuilder outsb = new StringBuilder();
         try {
             line = reader.readLine();
         } catch (IOException e) {
@@ -380,25 +380,25 @@
        out.flush();
        return false;
        } else if(uline.startsWith("SHUTDOWN")) {
-               StringBuffer sb = new StringBuffer();
+               StringBuilder sb = new StringBuilder();
                sb.append("Shutting node down.\r\n");
                out.write(sb.toString().getBytes());
                out.flush();
                n.exit("Shutdown from console");
        } else if(uline.startsWith("RESTART")) {
-               StringBuffer sb = new StringBuffer();
+               StringBuilder sb = new StringBuilder();
                sb.append("Restarting the node.\r\n");
                out.write(sb.toString().getBytes());
                out.flush();
                n.getNodeStarter().restart();
        } else if(uline.startsWith("QUIT") && (core.directTMCI == this)) {
-               StringBuffer sb = new StringBuffer();
+               StringBuilder sb = new StringBuilder();
                sb.append("QUIT command not available in console mode.\r\n");
                out.write(sb.toString().getBytes());
                out.flush();
                return false;
         } else if(uline.startsWith("QUIT")) {
-               StringBuffer sb = new StringBuffer();
+               StringBuilder sb = new StringBuilder();
                sb.append("Closing connection.\r\n");
                out.write(sb.toString().getBytes());
                out.flush();
@@ -419,7 +419,7 @@
                while(tg.getParent() != null) tg = tg.getParent();
                int threadCount = tg.activeCount();

-               StringBuffer sb = new StringBuffer();
+               StringBuilder sb = new StringBuilder();
                sb.append("Used Java memory:\u00a0" + 
SizeUtil.formatSize(usedJavaMem, true)+"\r\n");
                sb.append("Allocated Java memory:\u00a0" + 
SizeUtil.formatSize(allocatedJavaMem, true)+"\r\n");
                sb.append("Maximum Java memory:\u00a0" + 
SizeUtil.formatSize(maxJavaMem, true)+"\r\n");
@@ -1029,7 +1029,7 @@
      * isFieldSet. 
      */
     private String readLines(BufferedReader reader, boolean isFieldSet) {
-        StringBuffer sb = new StringBuffer(1000);
+        StringBuilder sb = new StringBuilder(1000);
         boolean breakflag = false;
         while(true) {
             String line;
@@ -1224,7 +1224,7 @@

     private String sanitize(String fnam) {
        if(fnam == null) return "";
-        StringBuffer sb = new StringBuffer(fnam.length());
+        StringBuilder sb = new StringBuilder(fnam.length());
         for(int i=0;i<fnam.length();i++) {
             char c = fnam.charAt(i);
             if(Character.isLetterOrDigit(c) || (c == '-') || (c == '.'))

Modified: branches/db4o/freenet/src/freenet/node/Version.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/Version.java 2008-09-24 23:18:12 UTC 
(rev 22828)
+++ branches/db4o/freenet/src/freenet/node/Version.java 2008-09-24 23:54:07 UTC 
(rev 22829)
@@ -24,17 +24,17 @@
        public static final String protocolVersion = "1.0";

        /** The build number of the current revision */
-       private static final int buildNumber = 1158;
+       private static final int buildNumber = 1161;

        /** Oldest build of Fred we will talk to */
-       private static final int oldLastGoodBuild = 1154;
-       private static final int newLastGoodBuild = 1158;
+       private static final int oldLastGoodBuild = 1160;
+       private static final int newLastGoodBuild = 1161;
        static final long transitionTime;

        static {
                final Calendar _cal = 
Calendar.getInstance(TimeZone.getTimeZone("GMT"));
                // year, month - 1 (or constant), day, hour, minute, second
-               _cal.set( 2008, Calendar.AUGUST, 20, 0, 0, 0 );
+               _cal.set( 2008, Calendar.SEPTEMBER, 13, 0, 0, 0 );
                transitionTime = _cal.getTimeInMillis();
        }


Modified: branches/db4o/freenet/src/freenet/node/fcp/AddPeer.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/fcp/AddPeer.java     2008-09-24 
23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/node/fcp/AddPeer.java     2008-09-24 
23:54:07 UTC (rev 22829)
@@ -52,7 +52,7 @@
                }
                String urlString = fs.get("URL");
                String fileString = fs.get("File");
-               StringBuffer ref = null;
+               StringBuilder ref = null;
                BufferedReader in;
                if(urlString != null) {
                        try {
@@ -60,7 +60,7 @@
                                URLConnection uc = url.openConnection();
                                // FIXME get charset from uc.getContentType()
                                in = new BufferedReader( new 
InputStreamReader(uc.getInputStream()));
-                               ref = new StringBuffer(1024);
+                               ref = new StringBuilder(1024);
                                String line;
                                while((line = in.readLine()) != null) {
                                        line = line.trim();
@@ -72,7 +72,7 @@
                        } catch (IOException e) {
                                throw new 
MessageInvalidException(ProtocolErrorMessage.URL_PARSE_ERROR, "IO error while 
retrieving ref URL <"+urlString+">: "+e.getMessage(), identifier, false);
                        }
-                       ref = new StringBuffer(ref.toString().trim());
+                       ref = new StringBuilder(ref.toString().trim());
                        if(ref == null) {
                                throw new 
MessageInvalidException(ProtocolErrorMessage.REF_PARSE_ERROR, "Error parsing 
ref from URL <"+urlString+ '>', identifier, false);
                        }
@@ -91,7 +91,7 @@
                        }
                        try {
                                in = new BufferedReader(new FileReader(f));
-                               ref = new StringBuffer(1024);
+                               ref = new StringBuilder(1024);
                                String line;
                                while((line = in.readLine()) != null) {
                                        line = line.trim();
@@ -103,7 +103,7 @@
                        } catch (IOException e) {
                                throw new 
MessageInvalidException(ProtocolErrorMessage.FILE_PARSE_ERROR, "IO error while 
retrieving ref file <"+fileString+">: "+e.getMessage(), identifier, false);
                        }
-                       ref = new StringBuffer(ref.toString().trim());
+                       ref = new StringBuilder(ref.toString().trim());
                        if(ref == null) {
                                throw new 
MessageInvalidException(ProtocolErrorMessage.REF_PARSE_ERROR, "Error parsing 
ref from file <"+fileString+ '>', identifier, false);
                        }

Modified: branches/db4o/freenet/src/freenet/node/fcp/FCPClient.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/fcp/FCPClient.java   2008-09-24 
23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/node/fcp/FCPClient.java   2008-09-24 
23:54:07 UTC (rev 22829)
@@ -218,18 +218,16 @@
                return !(runningPersistentRequests.isEmpty() && 
completedUnackedRequests.isEmpty());
        }

-       public void addPersistentRequests(Vector v, boolean onlyForever, 
ObjectContainer container) {
+       public void addPersistentRequests(List<ClientRequest> v, boolean 
onlyForever, ObjectContainer container) {
                assert((persistenceType == ClientRequest.PERSIST_FOREVER) == 
(container != null));
                synchronized(this) {
-                       Iterator i = runningPersistentRequests.iterator();
+                       Iterator<ClientRequest> i = 
runningPersistentRequests.iterator();
                        while(i.hasNext()) {
                                ClientRequest req = (ClientRequest) i.next();
                                if(req.isPersistentForever() || !onlyForever)
                                        v.add(req);
                        }
-                       Object[] unacked = completedUnackedRequests.toArray();
-                       for(int j=0;j<unacked.length;j++)
-                               v.add(unacked[j]);
+                       v.addAll(completedUnackedRequests);
                }
        }


Modified: branches/db4o/freenet/src/freenet/node/fcp/FCPServer.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/fcp/FCPServer.java   2008-09-24 
23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/node/fcp/FCPServer.java   2008-09-24 
23:54:07 UTC (rev 22829)
@@ -11,8 +11,10 @@
 import java.io.InputStream;
 import java.io.InputStreamReader;
 import java.net.Socket;
+import java.util.ArrayList;
+import java.util.Iterator;
 import java.util.LinkedList;
-import java.util.Vector;
+import java.util.List;
 import java.util.WeakHashMap;
 import java.util.zip.GZIPInputStream;

@@ -71,7 +73,7 @@
        String bindTo;
        private String allowedHosts;
        AllowedHosts allowedHostsFullAccess;
-       final WeakHashMap clientsByName;
+       final WeakHashMap<String, FCPClient> clientsByName;
        final FCPClient globalRebootClient;
        final FCPClient globalForeverClient;
        private boolean enablePersistentDownloads;
@@ -102,7 +104,7 @@
                this.core = core;
                this.assumeDownloadDDAIsAllowed = assumeDDADownloadAllowed;
                this.assumeUploadDDAIsAllowed = assumeDDAUploadAllowed;
-               clientsByName = new WeakHashMap();
+               clientsByName = new WeakHashMap<String, FCPClient>();

                // This one is only used to get the default settings. 
Individual FCP conns
                // will make their own.
@@ -480,7 +482,7 @@
        public FCPClient registerRebootClient(String name, NodeClientCore core, 
FCPConnectionHandler handler) {
                FCPClient oldClient;
                synchronized(this) {
-                       oldClient = (FCPClient) clientsByName.get(name);
+                       oldClient = clientsByName.get(name);
                        if(oldClient == null) {
                                // Create new client
                                FCPClient client = new FCPClient(name, handler, 
false, null, ClientRequest.PERSIST_REBOOT, null, null);
@@ -588,7 +590,7 @@
        }

        public ClientRequest[] getGlobalRequests(ObjectContainer container) {
-               Vector v = new Vector();
+               List<ClientRequest> v = new ArrayList<ClientRequest>();
                globalRebootClient.addPersistentRequests(v, false, null);
                globalForeverClient.addPersistentRequests(v, false, container);
                return (ClientRequest[]) v.toArray(new ClientRequest[v.size()]);
@@ -844,7 +846,7 @@
                File f = new File(core.getDownloadDir(), preferredWithExt);
                File f1 = new File(core.getDownloadDir(), preferredWithExt + 
".freenet-tmp");
                int x = 0;
-               StringBuffer sb = new StringBuffer();
+               StringBuilder sb = new StringBuilder();
                for(;f.exists() || f1.exists();sb.setLength(0)) {
                        sb.append(preferred);
                        sb.append('-');
@@ -877,7 +879,7 @@

                FCPClient[] clients;
                synchronized(this) {
-                       clients = (FCPClient[]) 
clientsByName.values().toArray(new FCPClient[clientsByName.size()]);
+                       clients = clientsByName.values().toArray(new 
FCPClient[clientsByName.size()]);
                }

                for(int i=0;i<clients.length;i++) {

Modified: 
branches/db4o/freenet/src/freenet/node/simulator/BootstrapPullTest.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/simulator/BootstrapPullTest.java     
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/node/simulator/BootstrapPullTest.java     
2008-09-24 23:54:07 UTC (rev 22829)
@@ -54,6 +54,9 @@
         * @throws InterruptedException 
         */
        public static void main(String[] args) throws 
InvalidThresholdException, IOException, NodeInitException, InterruptedException 
{
+               String ipOverride = null;
+               if(args.length > 0)
+                       ipOverride = args[0];
         File dir = new File("bootstrap-pull-test");
         FileUtil.removeAll(dir);
         RandomSource random = NodeStarter.globalTestInit(dir.getPath(), false, 
Logger.ERROR, "");
@@ -94,7 +97,7 @@
         FileUtil.writeTo(fis, new File(secondInnerDir, "seednodes.fref"));
         fis.close();
         PooledExecutor executor = new PooledExecutor();
-        Node secondNode = NodeStarter.createTestNode(DARKNET_PORT, 
OPENNET_PORT, dir.getPath(), true, false, false, Node.DEFAULT_MAX_HTL, 0, 
random, executor, 1000, 5*1024*1024, true, true, true, true, true, true, true, 
12*1024, false, true);        
+        Node secondNode = NodeStarter.createTestNode(DARKNET_PORT, 
OPENNET_PORT, dir.getPath(), true, false, false, Node.DEFAULT_MAX_HTL, 0, 
random, executor, 1000, 5*1024*1024, true, true, true, true, true, true, true, 
12*1024, false, true, ipOverride);        
         secondNode.start(true);
         waitForTenNodes(secondNode);


Modified: 
branches/db4o/freenet/src/freenet/node/simulator/BootstrapPushPullTest.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/simulator/BootstrapPushPullTest.java 
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/node/simulator/BootstrapPushPullTest.java 
2008-09-24 23:54:07 UTC (rev 22829)
@@ -34,6 +34,9 @@
        public static int EXIT_FETCH_FAILED = 260;

        public static void main(String[] args) throws 
InvalidThresholdException, IOException, NodeInitException, InterruptedException 
{
+               String ipOverride = null;
+               if(args.length > 0)
+                       ipOverride = args[0];
         File dir = new File("bootstrap-push-pull-test");
         FileUtil.removeAll(dir);
         RandomSource random = NodeStarter.globalTestInit(dir.getPath(), false, 
Logger.ERROR, "");
@@ -49,7 +52,7 @@
         fis.close();
         // Create one node
         Executor executor = new PooledExecutor();
-        Node node = NodeStarter.createTestNode(5000, 5001, dir.getPath(), 
true, false, false, Node.DEFAULT_MAX_HTL, 0, random, executor, 1000, 
5*1024*1024, true, true, true, true, true, true, true, 12*1024, false, true);
+        Node node = NodeStarter.createTestNode(5000, 5001, dir.getPath(), 
true, false, false, Node.DEFAULT_MAX_HTL, 0, random, executor, 1000, 
5*1024*1024, true, true, true, true, true, true, true, 12*1024, false, true, 
ipOverride);
         //NodeCrypto.DISABLE_GROUP_STRIP = true;
        //Logger.setupStdoutLogging(Logger.MINOR, 
"freenet:NORMAL,freenet.node.NodeDispatcher:MINOR,freenet.node.FNPPacketMangler:MINOR");
        Logger.getChain().setThreshold(Logger.ERROR); // kill logging
@@ -91,7 +94,7 @@
         FileUtil.writeTo(fis, new File(secondInnerDir, "seednodes.fref"));
         fis.close();
         executor = new PooledExecutor();
-        Node secondNode = NodeStarter.createTestNode(5002, 5003, 
dir.getPath(), true, false, false, Node.DEFAULT_MAX_HTL, 0, random, executor, 
1000, 5*1024*1024, true, true, true, true, true, true, true, 12*1024, false, 
true);        
+        Node secondNode = NodeStarter.createTestNode(5002, 5003, 
dir.getPath(), true, false, false, Node.DEFAULT_MAX_HTL, 0, random, executor, 
1000, 5*1024*1024, true, true, true, true, true, true, true, 12*1024, false, 
true, ipOverride);        
         secondNode.start(true);
         waitForTenNodes(secondNode);


Modified: 
branches/db4o/freenet/src/freenet/node/simulator/BootstrapSeedTest.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/simulator/BootstrapSeedTest.java     
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/node/simulator/BootstrapSeedTest.java     
2008-09-24 23:54:07 UTC (rev 22829)
@@ -29,6 +29,9 @@
         * @throws IOException 
         */
        public static void main(String[] args) throws 
InvalidThresholdException, NodeInitException, InterruptedException, IOException 
{
+               String ipOverride = null;
+               if(args.length > 0)
+                       ipOverride = args[0];
         File dir = new File("bootstrap-test");
         FileUtil.removeAll(dir);
         RandomSource random = NodeStarter.globalTestInit(dir.getPath(), false, 
Logger.ERROR, "");
@@ -44,7 +47,7 @@
         fis.close();
         // Create one node
         Executor executor = new PooledExecutor();
-        Node node = NodeStarter.createTestNode(5000, 5001, "bootstrap-test", 
true, false, false, Node.DEFAULT_MAX_HTL, 0, random, executor, 1000, 
5*1024*1024, true, true, true, true, true, true, true, 12*1024, false, true);
+        Node node = NodeStarter.createTestNode(5000, 5001, "bootstrap-test", 
true, false, false, Node.DEFAULT_MAX_HTL, 0, random, executor, 1000, 
5*1024*1024, true, true, true, true, true, true, true, 12*1024, false, true, 
ipOverride);
         //NodeCrypto.DISABLE_GROUP_STRIP = true;
        //Logger.setupStdoutLogging(Logger.MINOR, 
"freenet:NORMAL,freenet.node.NodeDispatcher:MINOR,freenet.node.FNPPacketMangler:MINOR");
        Logger.getChain().setThreshold(Logger.ERROR); // kill logging

Modified: 
branches/db4o/freenet/src/freenet/node/simulator/RealNodeBusyNetworkTest.java
===================================================================
--- 
branches/db4o/freenet/src/freenet/node/simulator/RealNodeBusyNetworkTest.java   
    2008-09-24 23:18:12 UTC (rev 22828)
+++ 
branches/db4o/freenet/src/freenet/node/simulator/RealNodeBusyNetworkTest.java   
    2008-09-24 23:54:07 UTC (rev 22829)
@@ -75,7 +75,7 @@
         Executor executor = new PooledExecutor();
         for(int i=0;i<NUMBER_OF_NODES;i++) {
             nodes[i] = 
-               NodeStarter.createTestNode(5001+i, 0, name, false, true, false, 
MAX_HTL, 20 /* 5% */, random, executor, 500*NUMBER_OF_NODES, 
(CHKBlock.DATA_LENGTH+CHKBlock.TOTAL_HEADERS_LENGTH)*100, true, 
ENABLE_SWAPPING, false, ENABLE_ULPRS, ENABLE_PER_NODE_FAILURE_TABLES, 
ENABLE_SWAP_QUEUEING, ENABLE_PACKET_COALESCING, 8000, ENABLE_FOAF, false);
+               NodeStarter.createTestNode(5001+i, 0, name, false, true, false, 
MAX_HTL, 20 /* 5% */, random, executor, 500*NUMBER_OF_NODES, 
(CHKBlock.DATA_LENGTH+CHKBlock.TOTAL_HEADERS_LENGTH)*100, true, 
ENABLE_SWAPPING, false, ENABLE_ULPRS, ENABLE_PER_NODE_FAILURE_TABLES, 
ENABLE_SWAP_QUEUEING, ENABLE_PACKET_COALESCING, 8000, ENABLE_FOAF, false, null);
             Logger.normal(RealNodeRoutingTest.class, "Created node "+i);
         }


Modified: 
branches/db4o/freenet/src/freenet/node/simulator/RealNodeNetworkColoringTest.java
===================================================================
--- 
branches/db4o/freenet/src/freenet/node/simulator/RealNodeNetworkColoringTest.java
   2008-09-24 23:18:12 UTC (rev 22828)
+++ 
branches/db4o/freenet/src/freenet/node/simulator/RealNodeNetworkColoringTest.java
   2008-09-24 23:54:07 UTC (rev 22829)
@@ -79,21 +79,21 @@
         for(int i=0;i<NUMBER_OF_NODES;i++) {
                        allNodes[totalNodes] =
             subnetA[i] = 
-               NodeStarter.createTestNode(5001+totalNodes, 0, wd, false, true, 
true, MAX_HTL, 0 /* no dropped packets */, random, executor, 
500*NUMBER_OF_NODES, storeSize, true, true, false, false, false, false, true, 
0, ENABLE_FOAF, false);
+               NodeStarter.createTestNode(5001+totalNodes, 0, wd, false, true, 
true, MAX_HTL, 0 /* no dropped packets */, random, executor, 
500*NUMBER_OF_NODES, storeSize, true, true, false, false, false, false, true, 
0, ENABLE_FOAF, false, null);
                        totalNodes++;
             Logger.normal(RealNodeRoutingTest.class, "Created 'A' node 
"+totalNodes);
         }
         for(int i=0;i<NUMBER_OF_NODES;i++) {
                        allNodes[totalNodes] =
             subnetB[i] = 
-                       NodeStarter.createTestNode(5001+totalNodes, 0, wd, 
false, true, true, MAX_HTL, 0 /* no dropped packets */, random, executor, 
500*NUMBER_OF_NODES, storeSize, true, true, false, false, false, false, true, 
0, ENABLE_FOAF, false);
+                       NodeStarter.createTestNode(5001+totalNodes, 0, wd, 
false, true, true, MAX_HTL, 0 /* no dropped packets */, random, executor, 
500*NUMBER_OF_NODES, storeSize, true, true, false, false, false, false, true, 
0, ENABLE_FOAF, false, null);
                        totalNodes++;
             Logger.normal(RealNodeRoutingTest.class, "Created 'B' node 
"+totalNodes);
         }
                for(int i=0;i<BRIDGES;i++) {
                        allNodes[totalNodes] =
             bridges[i] = 
-                       NodeStarter.createTestNode(5001+totalNodes, 0, wd, 
false, true, true, MAX_HTL, 0 /* no dropped packets */, random, executor, 
500*NUMBER_OF_NODES, storeSize, true, true, false, false, false, false, true, 
0,ENABLE_FOAF, false);
+                       NodeStarter.createTestNode(5001+totalNodes, 0, wd, 
false, true, true, MAX_HTL, 0 /* no dropped packets */, random, executor, 
500*NUMBER_OF_NODES, storeSize, true, true, false, false, false, false, true, 
0,ENABLE_FOAF, false, null);
                        totalNodes++;
             Logger.normal(RealNodeRoutingTest.class, "Created bridge node 
"+totalNodes);
         }
@@ -243,7 +243,7 @@
                //Print out the number which are non-zero & display the 
distinct ones if a few...
                int size=ids.size();
                int MAX=6;
-               StringBuffer sb=new 
StringBuffer(Integer.toString(size)).append("/").append(Integer.toString(targetNum));
+               StringBuilder sb=new 
StringBuilder(Integer.toString(size)).append("/").append(Integer.toString(targetNum));
                sb.append(" ids (").append(group).append(") = ");
                Iterator iter=ids.iterator();
                for (int i=0; i<=MAX && i<size; i++) {

Modified: branches/db4o/freenet/src/freenet/node/simulator/RealNodePingTest.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/simulator/RealNodePingTest.java      
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/node/simulator/RealNodePingTest.java      
2008-09-24 23:54:07 UTC (rev 22829)
@@ -33,8 +33,8 @@
         RandomSource random = NodeStarter.globalTestInit("pingtest", false, 
Logger.ERROR, "");
         // Create 2 nodes
         Executor executor = new PooledExecutor();
-        Node node1 = NodeStarter.createTestNode(5001, 0, "pingtest", false, 
false, true, Node.DEFAULT_MAX_HTL, 0, random, executor, 1000, 65536, true, 
false, false, false, false, false, true, 0, false, false);
-        Node node2 = NodeStarter.createTestNode(5002, 0, "pingtest", false, 
false, true, Node.DEFAULT_MAX_HTL, 0, random, executor, 1000, 65536, true, 
false, false, false, false, false, true, 0, false, false);
+        Node node1 = NodeStarter.createTestNode(5001, 0, "pingtest", false, 
false, true, Node.DEFAULT_MAX_HTL, 0, random, executor, 1000, 65536, true, 
false, false, false, false, false, true, 0, false, false, null);
+        Node node2 = NodeStarter.createTestNode(5002, 0, "pingtest", false, 
false, true, Node.DEFAULT_MAX_HTL, 0, random, executor, 1000, 65536, true, 
false, false, false, false, false, true, 0, false, false, null);
         // Connect
         node1.connect(node2);
         node2.connect(node1);

Modified: 
branches/db4o/freenet/src/freenet/node/simulator/RealNodeRequestInsertTest.java
===================================================================
--- 
branches/db4o/freenet/src/freenet/node/simulator/RealNodeRequestInsertTest.java 
    2008-09-24 23:18:12 UTC (rev 22828)
+++ 
branches/db4o/freenet/src/freenet/node/simulator/RealNodeRequestInsertTest.java 
    2008-09-24 23:54:07 UTC (rev 22829)
@@ -74,7 +74,7 @@
         Executor executor = new PooledExecutor();
         for(int i=0;i<NUMBER_OF_NODES;i++) {
             nodes[i] = 
-               NodeStarter.createTestNode(5001+i, 0, name, false, true, false, 
MAX_HTL, 20 /* 5% */, random, executor, 500*NUMBER_OF_NODES, 256*1024, true, 
ENABLE_SWAPPING, false, ENABLE_ULPRS, ENABLE_PER_NODE_FAILURE_TABLES, 
ENABLE_SWAP_QUEUEING, ENABLE_PACKET_COALESCING, 12000, ENABLE_FOAF, false);
+               NodeStarter.createTestNode(5001+i, 0, name, false, true, false, 
MAX_HTL, 20 /* 5% */, random, executor, 500*NUMBER_OF_NODES, 256*1024, true, 
ENABLE_SWAPPING, false, ENABLE_ULPRS, ENABLE_PER_NODE_FAILURE_TABLES, 
ENABLE_SWAP_QUEUEING, ENABLE_PACKET_COALESCING, 12000, ENABLE_FOAF, false, 
null);
             Logger.normal(RealNodeRoutingTest.class, "Created node "+i);
         }

@@ -184,7 +184,7 @@
                         System.exit(EXIT_BAD_DATA);
                     }
                 }
-                StringBuffer load = new StringBuffer("Running UIDs for nodes: 
");
+                StringBuilder load = new StringBuilder("Running UIDs for 
nodes: ");
                 int totalRunningUIDs = 0;
                 int totalRunningUIDsAlt = 0;
                 Vector runningUIDsList = new Vector(); // <Long>

Modified: 
branches/db4o/freenet/src/freenet/node/simulator/RealNodeRoutingTest.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/simulator/RealNodeRoutingTest.java   
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/node/simulator/RealNodeRoutingTest.java   
2008-09-24 23:54:07 UTC (rev 22829)
@@ -56,7 +56,7 @@
                Executor executor = new PooledExecutor();
                for(int i = 0; i < NUMBER_OF_NODES; i++) {
                        System.err.println("Creating node " + i);
-                       nodes[i] = NodeStarter.createTestNode(5001 + i, 0, dir, 
false, true, true, MAX_HTL, 0 /* no dropped packets */, random, executor, 500 * 
NUMBER_OF_NODES, 65536, true, ENABLE_SWAPPING, false, false, false, 
ENABLE_SWAP_QUEUEING, true, 0, ENABLE_FOAF, false);
+                       nodes[i] = NodeStarter.createTestNode(5001 + i, 0, dir, 
false, true, true, MAX_HTL, 0 /* no dropped packets */, random, executor, 500 * 
NUMBER_OF_NODES, 65536, true, ENABLE_SWAPPING, false, false, false, 
ENABLE_SWAP_QUEUEING, true, 0, ENABLE_FOAF, false, null);
                        Logger.normal(RealNodeRoutingTest.class, "Created node 
" + i);
                }
                Logger.normal(RealNodeRoutingTest.class, "Created " + 
NUMBER_OF_NODES + " nodes");

Modified: 
branches/db4o/freenet/src/freenet/node/simulator/RealNodeSecretPingTest.java
===================================================================
--- 
branches/db4o/freenet/src/freenet/node/simulator/RealNodeSecretPingTest.java    
    2008-09-24 23:18:12 UTC (rev 22828)
+++ 
branches/db4o/freenet/src/freenet/node/simulator/RealNodeSecretPingTest.java    
    2008-09-24 23:54:07 UTC (rev 22829)
@@ -66,7 +66,7 @@

         for(int i=0;i<NUMBER_OF_NODES;i++) {
             nodes[i] = 
-               NodeStarter.createTestNode(5001+i, 0, wd, false, true, true, 
MAX_HTL, 0 /* no dropped packets */, random, executor, 500*NUMBER_OF_NODES, 
storeSize, true, true, false, false, false, true, true, 0, true, false);
+               NodeStarter.createTestNode(5001+i, 0, wd, false, true, true, 
MAX_HTL, 0 /* no dropped packets */, random, executor, 500*NUMBER_OF_NODES, 
storeSize, true, true, false, false, false, true, true, 0, true, false, null);
             Logger.normal(RealNodeRoutingTest.class, "Created node "+i);
         }
         Logger.normal(RealNodeRoutingTest.class, "Created "+NUMBER_OF_NODES+" 
nodes");

Modified: branches/db4o/freenet/src/freenet/node/simulator/RealNodeULPRTest.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/simulator/RealNodeULPRTest.java      
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/node/simulator/RealNodeULPRTest.java      
2008-09-24 23:54:07 UTC (rev 22829)
@@ -93,7 +93,7 @@
         Executor executor = new PooledExecutor();
         for(int i=0;i<NUMBER_OF_NODES;i++) {
             nodes[i] = 
-               NodeStarter.createTestNode(5000+i, 0, testName, false, true, 
true, MAX_HTL, 20 /* 5% */, random, executor, 500*NUMBER_OF_NODES, 1024*1024, 
true, ENABLE_SWAPPING, false, ENABLE_ULPRS, ENABLE_PER_NODE_FAILURE_TABLES, 
true, true, 0, ENABLE_FOAF, false);
+               NodeStarter.createTestNode(5000+i, 0, testName, false, true, 
true, MAX_HTL, 20 /* 5% */, random, executor, 500*NUMBER_OF_NODES, 1024*1024, 
true, ENABLE_SWAPPING, false, ENABLE_ULPRS, ENABLE_PER_NODE_FAILURE_TABLES, 
true, true, 0, ENABLE_FOAF, false, null);
             Logger.normal(RealNodeRoutingTest.class, "Created node "+i);
         }
         SimpleFieldSet refs[] = new SimpleFieldSet[NUMBER_OF_NODES];
@@ -220,7 +220,7 @@
         // Now we should have a good web of subscriptions set up.

         int visitedCount = 0;
-        StringBuffer sb = new StringBuffer(3*nodes.length+1);
+        StringBuilder sb = new StringBuilder(3*nodes.length+1);
         boolean first = true;
         for(int i=0;i<visited.length;i++) {
                if(!visited[i]) continue;

Modified: branches/db4o/freenet/src/freenet/node/simulator/SeednodePingTest.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/simulator/SeednodePingTest.java      
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/node/simulator/SeednodePingTest.java      
2008-09-24 23:54:07 UTC (rev 22829)
@@ -22,8 +22,14 @@
 import freenet.support.LoggerHook.InvalidThresholdException;
 import freenet.support.SimpleFieldSet;
 import freenet.support.TimeUtil;
+
+import java.io.BufferedReader;
 import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
 import java.util.EnumMap;
 import java.util.Map;
 import java.util.Vector;
@@ -33,11 +39,16 @@
  */
 public class SeednodePingTest extends RealNodeTest {

+       static File STATUS_DIR = new 
File("/var/www/freenet/tests/seednodes/status/");
+       static final long COUNT_SUCCESSES_PERIOD = 7*24*60*60*1000; // 1 week
+
     public static void main(String[] args) throws FSParseException, 
IOException, OpennetDisabledException, PeerParseException, 
InterruptedException, ReferenceSignatureVerificationException, 
NodeInitException, InvalidThresholdException {
+       if(args.length == 1)
+               STATUS_DIR = new File(args[0]);
         RandomSource random = NodeStarter.globalTestInit("seednode-pingtest", 
false, Logger.ERROR, "");
         // Create one node
         Executor executor = new PooledExecutor();
-       Node node = NodeStarter.createTestNode(5000, 5001, "seednode-pingtest", 
true, false, false, Node.DEFAULT_MAX_HTL, 0, random, executor, 1000, 
5*1024*1024, true, false, false, false, false, false, false, 0, false, false);
+       Node node = NodeStarter.createTestNode(5000, 5001, "seednode-pingtest", 
true, false, false, Node.DEFAULT_MAX_HTL, 0, random, executor, 1000, 
5*1024*1024, true, false, false, false, false, false, false, 0, false, false, 
null);
        // Connect & ping
        Vector<SeedServerTestPeerNode> seedNodes = new 
Vector<SeedServerTestPeerNode>();
        Vector<SimpleFieldSet> seedNodesAsSFS = Announcer.readSeednodes(new 
File("/tmp/"));
@@ -106,7 +117,67 @@
                System.out.println("################## 
("+node.peers.countConnectedPeers()+") 
"+countConnectedSeednodes+'/'+node.peers.countSeednodes());
                Thread.sleep(5000);
        }
+       Map<FATE, Integer> totals = new 
EnumMap(SeedServerTestPeerNode.FATE.class);
+       for(SeedServerTestPeerNode seednode : seedNodes) {
+               FATE fate = seednode.getFate();
+               Integer x = totals.get(fate);
+               if(x == null)
+                       totals.put(fate, 1);
+               else
+                       totals.put(fate, x+1);
+               System.out.println(seednode.getIdentityString() + " : "+fate+ " 
: "+seednode.getPeerNodeStatusString());
+       }
+       System.out.println("RESULT:TOTALS:");
+       for(FATE fate : totals.keySet()) {
+               System.out.println("RESULT:"+fate + " : "+totals.get(fate));
+       }
     System.out.println("Completed seednodes scan.");
+    // Record statuses.
+    System.out.println("FINAL STATUS:");
+    long writeTime = System.currentTimeMillis();
+    for(SeedServerTestPeerNode peer : seedNodes) {
+       String status = writeTime+" : "+peer.getIdentityString()+" : 
"+peer.getFate();
+       System.out.println(status);
+       File logFile = new File(STATUS_DIR, peer.getIdentityString());
+       FileOutputStream fos = new FileOutputStream(logFile, true);
+       OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF-8");
+       osw.write(status+"\n");
+       osw.close();
+       FileInputStream fis = new FileInputStream(logFile);
+       InputStreamReader isr = new InputStreamReader(fis, "UTF-8");
+       BufferedReader br = new BufferedReader(isr);
+       String line;
+       int successes = 0;
+       int failures = 0;
+       long lastSuccess = 0;
+       long firstSample = 0;
+       long countSince = writeTime - COUNT_SUCCESSES_PERIOD;
+       do {
+               line = br.readLine();
+               if(line == null) break;
+               String[] results = line.split(" : ");
+               if(results.length != 3) {
+                       System.err.println("Unable to parse line in "+logFile+" 
: wrong number of fields : "+results.length+" : "+line);
+                       continue;
+               }
+               long time = Long.parseLong(results[0]);
+               FATE fate = FATE.valueOf(results[2]);
+               if(firstSample == 0) firstSample = time;
+               if(fate == FATE.CONNECTED_SUCCESS) {
+                       if(time >= countSince)
+                               successes++;
+                       lastSuccess = time;
+               } else {
+                       if(time >= countSince)
+                               failures++;
+               }
+       } while(line != null);
+       br.close();
+       if(firstSample < countSince && successes == 0)
+               System.err.println("RESULT:"+peer.getIdentityString()+" NOT 
CONNECTED IN LAST WEEK! LAST CONNECTED: "+(lastSuccess > 0 ? 
TimeUtil.formatTime(writeTime - lastSuccess) : "NEVER"));
+       System.out.println(peer.getIdentityString()+" : last success 
"+(lastSuccess > 0 ? TimeUtil.formatTime(writeTime - lastSuccess) : "NEVER")+" 
failures in last week: "+failures+" successes in last week: "+successes);
+    }
+    node.park();
     System.exit(0);
     }
 }

Modified: branches/db4o/freenet/src/freenet/node/updater/NodeUpdater.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/updater/NodeUpdater.java     
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/node/updater/NodeUpdater.java     
2008-09-24 23:54:07 UTC (rev 22829)
@@ -135,7 +135,7 @@
                                        tempBlobFile = 
                                                
File.createTempFile(blobFilenamePrefix+availableVersion+"-", ".fblob.tmp", 
manager.node.clientCore.getPersistentTempDir());
                                        cg = new ClientGetter(this, 
core.requestStarters.chkFetchScheduler, core.requestStarters.sskFetchScheduler, 
-                                                       
URI.setSuggestedEdition(availableVersion), ctx, 
RequestStarter.UPDATE_PRIORITY_CLASS, 
+                                                       
URI.setSuggestedEdition(availableVersion), ctx, 
RequestStarter.IMMEDIATE_SPLITFILE_PRIORITY_CLASS, 
                                                        this, null, new 
FileBucket(tempBlobFile, false, false, false, false, false));
                                        toStart = cg;
                                }
@@ -352,11 +352,11 @@
        }

        public short getPollingPriorityNormal() {
-               return RequestStarter.UPDATE_PRIORITY_CLASS;
+               return RequestStarter.IMMEDIATE_SPLITFILE_PRIORITY_CLASS;
        }

        public short getPollingPriorityProgress() {
-               return RequestStarter.IMMEDIATE_SPLITFILE_PRIORITY_CLASS;
+               return RequestStarter.INTERACTIVE_PRIORITY_CLASS;
        }

        public boolean persistent() {

Modified: 
branches/db4o/freenet/src/freenet/node/updater/UpdateOverMandatoryManager.java
===================================================================
--- 
branches/db4o/freenet/src/freenet/node/updater/UpdateOverMandatoryManager.java  
    2008-09-24 23:18:12 UTC (rev 22828)
+++ 
branches/db4o/freenet/src/freenet/node/updater/UpdateOverMandatoryManager.java  
    2008-09-24 23:54:07 UTC (rev 22829)
@@ -442,7 +442,7 @@

                @Override
                public String getText() {
-                       StringBuffer sb = new StringBuffer();
+                       StringBuilder sb = new StringBuilder();
                        sb.append(l10n("intro")).append("\n\n");
                        PeerNode[][] nodes = getNodesSayBlown();
                        PeerNode[] nodesSayBlownConnected = nodes[0];

Modified: 
branches/db4o/freenet/src/freenet/node/useralerts/PeerManagerUserAlert.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/useralerts/PeerManagerUserAlert.java 
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/node/useralerts/PeerManagerUserAlert.java 
2008-09-24 23:54:07 UTC (rev 22829)
@@ -161,7 +161,7 @@

        static public String replaceCareful(String text, String find, String 
replace) {
                String[] split = text.split(find, -1);
-               StringBuffer sb = new StringBuffer(); // FIXME calculate size
+               StringBuilder sb = new StringBuilder(); // FIXME calculate size
                for(int i=0;i<split.length;i++) {
                        sb.append(split[i]);
                        if(i < split.length - 1)

Modified: 
branches/db4o/freenet/src/freenet/node/useralerts/UpdatedVersionAvailableUserAlert.java
===================================================================
--- 
branches/db4o/freenet/src/freenet/node/useralerts/UpdatedVersionAvailableUserAlert.java
     2008-09-24 23:18:12 UTC (rev 22828)
+++ 
branches/db4o/freenet/src/freenet/node/useralerts/UpdatedVersionAvailableUserAlert.java
     2008-09-24 23:54:07 UTC (rev 22829)
@@ -37,7 +37,7 @@

                UpdateThingy ut = createUpdateThingy();

-               StringBuffer sb = new StringBuffer();
+               StringBuilder sb = new StringBuilder();

                sb.append(ut.firstBit);

@@ -87,7 +87,7 @@
        }

        private UpdateThingy createUpdateThingy() {
-               StringBuffer sb = new StringBuffer();
+               StringBuilder sb = new StringBuilder();
                sb.append(l10n("notLatest"));
                sb.append(' ');


Modified: 
branches/db4o/freenet/src/freenet/node/useralerts/UserAlertManager.java
===================================================================
--- branches/db4o/freenet/src/freenet/node/useralerts/UserAlertManager.java     
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/node/useralerts/UserAlertManager.java     
2008-09-24 23:54:07 UTC (rev 22829)
@@ -16,14 +16,13 @@
 /**
  * Collection of UserAlert's.
  */
-public class UserAlertManager implements Comparator {
-
-       private final HashSet alerts;
+public class UserAlertManager implements Comparator<UserAlert> {
+       private final HashSet<UserAlert> alerts;
        private final NodeClientCore core;

        public UserAlertManager(NodeClientCore core) {
                this.core = core;
-               alerts = new LinkedHashSet();
+               alerts = new LinkedHashSet<UserAlert>();
        }

        public void register(UserAlert alert) {
@@ -67,15 +66,13 @@
        public UserAlert[] getAlerts() {
                UserAlert[] a;
                synchronized (alerts) {
-                       a = (UserAlert[]) alerts.toArray(new 
UserAlert[alerts.size()]);
+                       a = alerts.toArray(new UserAlert[alerts.size()]);
                }
                Arrays.sort(a, this);
                return a;
        }

-       public int compare(Object arg0, Object arg1) {
-               UserAlert a0 = (UserAlert) arg0;
-               UserAlert a1 = (UserAlert) arg1;
+       public int compare(UserAlert a0, UserAlert a1) {
                if(a0 == a1) return 0; // common case, also we should be 
consistent with == even with proxyuseralert's
                short prio0 = a0.getPriorityClass();
                short prio1 = a1.getPriorityClass();
@@ -158,7 +155,7 @@
                if(drawDumpEventsForm) {
                        HTMLNode dumpFormNode = contentNode.addChild("form", 
new String[] { "action", "method" }, new String[] { "/", "post" 
}).addChild("div");
                        dumpFormNode.addChild("input", new String[] { "type", 
"name", "value" }, new String[] { "hidden", "formPassword", core.formPassword 
});
-                       StringBuffer sb = new StringBuffer();
+                       StringBuilder sb = new StringBuilder();
                        for(int i=0;i<currentAlerts.length;i++) {
                                if(!currentAlerts[i].isEventNotification()) 
continue;
                                if(sb.length() != 0)
@@ -211,7 +208,7 @@
        }

        /**
-        * Write the alert summary as HTML to a StringBuffer
+        * Write the alert summary as HTML to a StringBuilder
         */
        public HTMLNode createSummary() {
                short highestLevel = 99;
@@ -244,7 +241,7 @@

                boolean separatorNeeded = false;
                int messageTypes=0;
-               StringBuffer alertSummaryString = new StringBuffer(1024);
+               StringBuilder alertSummaryString = new StringBuilder(1024);
                if (numberOfCriticalError != 0) {
                        
alertSummaryString.append(l10n("criticalErrorCountLabel")).append(' 
').append(numberOfCriticalError);
                        separatorNeeded = true;
@@ -298,7 +295,7 @@
                return L10n.getString("UserAlertManager."+key);
        }

-       public void dumpEvents(HashSet toDump) {
+       public void dumpEvents(HashSet<String> toDump) {
                // An iterator might be faster, but we don't want to call 
methods on the alert within the lock.
                UserAlert[] alerts = getAlerts();
                for(int i=0;i<alerts.length;i++) {

Copied: branches/db4o/freenet/src/freenet/pluginmanager/FredPluginToadlet.java 
(from rev 22484, trunk/freenet/src/freenet/pluginmanager/FredPluginToadlet.java)
===================================================================
--- branches/db4o/freenet/src/freenet/pluginmanager/FredPluginToadlet.java      
                        (rev 0)
+++ branches/db4o/freenet/src/freenet/pluginmanager/FredPluginToadlet.java      
2008-09-24 23:54:07 UTC (rev 22829)
@@ -0,0 +1,13 @@
+/* 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.pluginmanager;
+
+/**
+ * Meta Interface for plugins to be well integrated in to node ui look &amp; 
feel
+ * 
+ * @author saces
+ */
+public interface FredPluginToadlet extends FredPluginHTTP, FredPluginL10n, 
FredPluginThemed, FredPluginVersioned {
+       
+}

Copied: branches/db4o/freenet/src/freenet/pluginmanager/FredPluginUoF.java 
(from rev 22484, trunk/freenet/src/freenet/pluginmanager/FredPluginUoF.java)
===================================================================
--- branches/db4o/freenet/src/freenet/pluginmanager/FredPluginUoF.java          
                (rev 0)
+++ branches/db4o/freenet/src/freenet/pluginmanager/FredPluginUoF.java  
2008-09-24 23:54:07 UTC (rev 22829)
@@ -0,0 +1,29 @@
+/* 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.pluginmanager;
+
+import freenet.keys.FreenetURI;
+
+/**
+ * Interface for plugins thats can be updated over freenet
+ * 
+ * 
+ * @author saces
+ */
+public interface FredPluginUoF {
+       
+       /**
+        * If the uri fetches any data the plugin is revoked<ul><li>plugin will 
be stopped and disabled</li>
+        * <li>stop updater</li></ul>
+        * 
+        * @return FreenetURI to watch
+        */
+       public FreenetURI getRevokeURI();
+       
+       /**
+        * an uri that points to plugin jarfile
+        * @return FreenetURI to look for next edition
+        */
+       public FreenetURI getUpdaterURI();
+}

Modified: branches/db4o/freenet/src/freenet/pluginmanager/PluginManager.java
===================================================================
--- branches/db4o/freenet/src/freenet/pluginmanager/PluginManager.java  
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/pluginmanager/PluginManager.java  
2008-09-24 23:54:07 UTC (rev 22829)
@@ -58,7 +58,7 @@
         * TODO: Synchronize
         *
         */
-       private final HashMap toadletList;
+       private final HashMap<String, FredPlugin> toadletList;

        /* All currently starting plugins. */
        private final Set<PluginProgress> startingPlugins = new 
HashSet<PluginProgress>();
@@ -81,8 +81,8 @@
                logDEBUG = Logger.shouldLog(Logger.DEBUG, this);
                // config 

-               toadletList = new HashMap();
-               pluginWrappers = new Vector();
+               toadletList = new HashMap<String, FredPlugin>();
+               pluginWrappers = new Vector<PluginInfoWrapper>();
                this.node = node;
                this.core = node.clientCore;

@@ -130,10 +130,12 @@
                pmconfig.register("loadplugin", null, 0, true, false, 
"PluginManager.loadedOnStartup", "PluginManager.loadedOnStartupLong",
                        new StringArrCallback() {

+                               @Override
                                public String[] get() {
                                        return getConfigLoadString();
                                }

+                               @Override
                                public void set(String[] val) throws 
InvalidConfigValueException {
                                        //if(storeDir.equals(new File(val))) 
return;
                                        // FIXME
@@ -174,9 +176,9 @@
         * 
         * @return All currently starting plugins
         */
-       public Set/* <PluginProgess> */ getStartingPlugins() {
+       public Set<PluginProgress> getStartingPlugins() {
                synchronized(startingPlugins) {
-                       return new HashSet/* <PluginProgress> 
*/(startingPlugins);
+                       return new HashSet<PluginProgress>(startingPlugins);
                }
        }
        // try to guess around...
@@ -408,7 +410,7 @@
        }

        public String dumpPlugins() {
-               StringBuffer out = new StringBuffer();
+               StringBuilder out = new StringBuilder();
                synchronized(pluginWrappers) {
                        for(int i = 0; i < pluginWrappers.size(); i++) {
                                PluginInfoWrapper pi = pluginWrappers.get(i);
@@ -419,8 +421,8 @@
                return out.toString();
        }

-       public Set getPlugins() {
-               HashSet out = new HashSet();
+       public Set<PluginInfoWrapper> getPlugins() {
+               HashSet<PluginInfoWrapper> out = new 
HashSet<PluginInfoWrapper>();
                synchronized(pluginWrappers) {
                        for(int i = 0; i < pluginWrappers.size(); i++) {
                                PluginInfoWrapper pi = pluginWrappers.get(i);
@@ -481,7 +483,7 @@
        public String handleHTTPGet(String plugin, HTTPRequest request) throws 
PluginHTTPException {
                FredPlugin handler = null;
                synchronized(toadletList) {
-                       handler = (FredPlugin) toadletList.get(plugin);
+                       handler = toadletList.get(plugin);
                }
                /*if (handler == null)
                return null;
@@ -496,7 +498,7 @@
        public String handleHTTPPost(String plugin, HTTPRequest request) throws 
PluginHTTPException {
                FredPlugin handler = null;
                synchronized(toadletList) {
-                       handler = (FredPlugin) toadletList.get(plugin);
+                       handler = toadletList.get(plugin);
                }
                /*if (handler == null)
                return null;
@@ -702,7 +704,7 @@

                try {
                        JarClassLoader jarClassLoader = new 
JarClassLoader(pluginFile);
-                       Class pluginMainClass = 
jarClassLoader.loadClass(pluginMainClassName);
+                       Class<?> pluginMainClass = 
jarClassLoader.loadClass(pluginMainClassName);
                        Object object = pluginMainClass.newInstance();
                        if(!(object instanceof FredPlugin)) {
                                Logger.error(this, "plugin main class is not a 
plugin");

Modified: branches/db4o/freenet/src/freenet/store/BerkeleyDBFreenetStore.java
===================================================================
--- branches/db4o/freenet/src/freenet/store/BerkeleyDBFreenetStore.java 
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/store/BerkeleyDBFreenetStore.java 
2008-09-24 23:54:07 UTC (rev 22829)
@@ -65,7 +65,7 @@
        private final RandomSource random;

        private final Environment environment;
-       private final TupleBinding storeBlockTupleBinding;
+       private final TupleBinding<StoreBlock> storeBlockTupleBinding;
        private final File fixSecondaryFile;

        private long blocksInStore = 0;
@@ -445,11 +445,11 @@
        }

        private void maybeSlowShrink(boolean dontCheckForHoles, boolean 
inStartUp) throws DatabaseException, IOException {
-               List wantedKeep = new ArrayList(); // keep; content is wanted, 
and is in the right place
-               List unwantedIgnore = new ArrayList(); // ignore; content is 
not wanted, and is not in the right place
-               List wantedMove = new ArrayList(); // content is wanted, but is 
in the wrong part of the store
-               List unwantedMove = new ArrayList(); // content is not wanted, 
but is in the part of the store we will keep
-               List alreadyDropped = new ArrayList(); // any blocks past the 
end which have already been truncated, but which there are still database 
blocks pointing to
+               List<Integer> wantedKeep = new ArrayList<Integer>(); // keep; 
content is wanted, and is in the right place
+               List<Integer> unwantedIgnore = new ArrayList<Integer>(); // 
ignore; content is not wanted, and is not in the right place
+               List<Integer> wantedMove = new ArrayList<Integer>(); // content 
is wanted, but is in the wrong part of the store
+               List<Integer> unwantedMove = new ArrayList<Integer>(); // 
content is not wanted, but is in the part of the store we will keep
+               List<Integer> alreadyDropped = new ArrayList<Integer>(); // any 
blocks past the end which have already been truncated, but which there are 
still database blocks pointing to

                Cursor c = null;
                Transaction t = null;
@@ -486,7 +486,7 @@
                        //Logger.minor(this, "Found first key");
                        int x = 0;
                        while(true) {
-                               StoreBlock storeBlock = (StoreBlock) 
storeBlockTupleBinding.entryToObject(blockDBE);
+                               StoreBlock storeBlock = 
storeBlockTupleBinding.entryToObject(blockDBE);
                                long block = storeBlock.offset;
                                if(block > highestBlock) highestBlock = block;
                                if(storeBlock.offset > Integer.MAX_VALUE) {
@@ -547,10 +547,10 @@
                                c.close();
                }

-               Integer[] wantedKeepNums = (Integer[]) wantedKeep.toArray(new 
Integer[wantedKeep.size()]);
-               Integer[] unwantedIgnoreNums = (Integer[]) 
unwantedIgnore.toArray(new Integer[unwantedIgnore.size()]);
-               Integer[] wantedMoveNums = (Integer[]) wantedMove.toArray(new 
Integer[wantedMove.size()]);
-               Integer[] unwantedMoveNums = (Integer[]) 
unwantedMove.toArray(new Integer[unwantedMove.size()]);
+               Integer[] wantedKeepNums = wantedKeep.toArray(new 
Integer[wantedKeep.size()]);
+               Integer[] unwantedIgnoreNums = unwantedIgnore.toArray(new 
Integer[unwantedIgnore.size()]);
+               Integer[] wantedMoveNums = wantedMove.toArray(new 
Integer[wantedMove.size()]);
+               Integer[] unwantedMoveNums = unwantedMove.toArray(new 
Integer[unwantedMove.size()]);
                long[] freeEarlySlots = freeBlocks.toArray();
                Arrays.sort(wantedKeepNums);
                Arrays.sort(unwantedIgnoreNums);
@@ -565,7 +565,7 @@
                        if(Arrays.binarySearch(unwantedMoveNums, ii) >= 0) 
continue;
                        unwantedMove.add(ii);
                }
-               unwantedMoveNums = (Integer[]) unwantedMove.toArray(new 
Integer[unwantedMove.size()]);
+               unwantedMoveNums = unwantedMove.toArray(new 
Integer[unwantedMove.size()]);

                System.err.println("Keys to keep where they are:     
"+wantedKeepNums.length);
                System.err.println("Keys which will be wiped anyway: 
"+unwantedIgnoreNums.length);
@@ -586,7 +586,7 @@
                        if(alreadyDropped.size() > 0) {
                                System.err.println("Deleting 
"+alreadyDropped.size()+" blocks beyond the length of the file");
                                for(int i=0;i<alreadyDropped.size();i++) {
-                                       int unwantedBlock = ((Integer) 
alreadyDropped.get(i)).intValue();
+                                       int unwantedBlock = 
(alreadyDropped.get(i)).intValue();
                                        DatabaseEntry unwantedBlockEntry = new 
DatabaseEntry();
                                        LongBinding.longToEntry(unwantedBlock, 
unwantedBlockEntry);
                                        blockNumDB.delete(t, 
unwantedBlockEntry);
@@ -670,7 +670,7 @@
                                DatabaseEntry routingKeyDBE = new 
DatabaseEntry();
                                DatabaseEntry blockDBE = new DatabaseEntry();
                                blockNumDB.get(t, wantedBlockEntry, 
routingKeyDBE, blockDBE, LockMode.RMW);
-                               StoreBlock block = (StoreBlock) 
storeBlockTupleBinding.entryToObject(blockDBE);
+                               StoreBlock block = 
storeBlockTupleBinding.entryToObject(blockDBE);
                                block.offset = unwantedBlock.longValue();
                                storeBlockTupleBinding.objectToEntry(block, 
blockDBE);
                                keysDB.put(t, routingKeyDBE, blockDBE);
@@ -1205,7 +1205,7 @@
                                return null;
                        }

-                       StoreBlock storeBlock = (StoreBlock) 
storeBlockTupleBinding.entryToObject(blockDBE);
+                       StoreBlock storeBlock = 
storeBlockTupleBinding.entryToObject(blockDBE);

                        StorableBlock block = null;

@@ -1448,7 +1448,7 @@
                                return false;
                        }

-                       StoreBlock storeBlock = (StoreBlock) 
storeBlockTupleBinding.entryToObject(blockDBE);
+                       StoreBlock storeBlock = 
storeBlockTupleBinding.entryToObject(blockDBE);

                        fcWriteStore(storeBlock.offset, header, data);
                        if (keysRAF != null) {
@@ -1565,7 +1565,7 @@
                        DatabaseEntry keyDBE = new DatabaseEntry();
                        DatabaseEntry dataDBE = new DatabaseEntry();
                        c.getFirst(keyDBE,dataDBE,LockMode.RMW);
-                       oldStoreBlock = (StoreBlock) 
storeBlockTupleBinding.entryToObject(dataDBE);
+                       oldStoreBlock = 
storeBlockTupleBinding.entryToObject(dataDBE);
                        c.delete();
                } finally {
                        c.close();
@@ -1771,16 +1771,16 @@
        /**
        * Convert StoreBlock's to the format used by the database
        */
-       private class StoreBlockTupleBinding extends TupleBinding {
+       private class StoreBlockTupleBinding extends TupleBinding<StoreBlock> {

-               public void objectToEntry(Object object, TupleOutput to)  {
-                       StoreBlock myData = (StoreBlock)object;
-
+               @Override
+        public void objectToEntry(StoreBlock myData, TupleOutput to) {
                        to.writeLong(myData.getOffset());
                        to.writeLong(myData.getRecentlyUsed());
                }

-               public Object entryToObject(TupleInput ti) {
+               @Override
+        public StoreBlock entryToObject(TupleInput ti) {
                        long offset = ti.readLong();
                        long lastAccessed = ti.readLong();

@@ -1793,9 +1793,9 @@
        * Used to create the secondary database sorted on accesstime
        */
        private static class AccessTimeKeyCreator implements 
SecondaryKeyCreator {
-               private final TupleBinding theBinding;
+               private final TupleBinding<StoreBlock> theBinding;

-               public AccessTimeKeyCreator(TupleBinding theBinding1) {
+               public AccessTimeKeyCreator(TupleBinding<StoreBlock> 
theBinding1) {
                        theBinding = theBinding1;
                }

@@ -1804,16 +1804,16 @@
                                DatabaseEntry dataEntry,
                                DatabaseEntry resultEntry) {

-                       StoreBlock storeblock = (StoreBlock) 
theBinding.entryToObject(dataEntry);
+                       StoreBlock storeblock = 
theBinding.entryToObject(dataEntry);
                        LongBinding.longToEntry(storeblock.getRecentlyUsed(), 
resultEntry);
                        return true;
                }
        }

        private static class BlockNumberKeyCreator implements 
SecondaryKeyCreator {
-               private final TupleBinding theBinding;
+               private final TupleBinding<StoreBlock> theBinding;

-               public BlockNumberKeyCreator(TupleBinding theBinding1) {
+               public BlockNumberKeyCreator(TupleBinding<StoreBlock> 
theBinding1) {
                        theBinding = theBinding1;
                }

@@ -1822,7 +1822,7 @@
                                DatabaseEntry dataEntry,
                                DatabaseEntry resultEntry) {

-                       StoreBlock storeblock = (StoreBlock) 
theBinding.entryToObject(dataEntry);
+                       StoreBlock storeblock = 
theBinding.entryToObject(dataEntry);
                        LongBinding.longToEntry(storeblock.offset, resultEntry);
                        return true;
                }
@@ -1830,7 +1830,8 @@
        }

        private class ShutdownHook extends Thread {
-               public void run() {
+               @Override
+        public void run() {
                        System.err.println("Closing database due to shutdown.");
                        close(true);
                }
@@ -1936,7 +1937,7 @@
                        DatabaseEntry keyDBE = new DatabaseEntry();
                        DatabaseEntry dataDBE = new DatabaseEntry();
                        
if(c.getLast(keyDBE,dataDBE,null)==OperationStatus.SUCCESS) {
-                               StoreBlock storeBlock = (StoreBlock) 
storeBlockTupleBinding.entryToObject(dataDBE);
+                               StoreBlock storeBlock = 
storeBlockTupleBinding.entryToObject(dataDBE);
                                return storeBlock.offset + 1;
                        }
                        c.close();
@@ -1968,7 +1969,7 @@
                        DatabaseEntry keyDBE = new DatabaseEntry();
                        DatabaseEntry dataDBE = new DatabaseEntry();
                        
if(c.getLast(keyDBE,dataDBE,null)==OperationStatus.SUCCESS) {
-                               StoreBlock storeBlock = (StoreBlock) 
storeBlockTupleBinding.entryToObject(dataDBE);
+                               StoreBlock storeBlock = 
storeBlockTupleBinding.entryToObject(dataDBE);
                                maxRecentlyUsed = storeBlock.getRecentlyUsed();
                        }
                        c.close();
@@ -1997,7 +1998,7 @@
                        DatabaseEntry keyDBE = new DatabaseEntry();
                        DatabaseEntry dataDBE = new DatabaseEntry();
                        
if(c.getFirst(keyDBE,dataDBE,null)==OperationStatus.SUCCESS) {
-                               StoreBlock storeBlock = (StoreBlock) 
storeBlockTupleBinding.entryToObject(dataDBE);
+                               StoreBlock storeBlock = 
storeBlockTupleBinding.entryToObject(dataDBE);
                                minRecentlyUsed = storeBlock.getRecentlyUsed();
                        }
                        c.close();
@@ -2303,8 +2304,17 @@
         return envConfig;
     }

+       public long getBloomFalsePositive() {
+               return -1;
+       }
+       
     public boolean probablyInStore(byte[] routingKey) {
-       DatabaseEntry routingkeyDBE = new DatabaseEntry(routingKey);
+       // This needs to be fast, so that it can be run from any thread.
+       // Accessing the bdbje database is often slow, involves many disk seeks,
+       // and can stall for long periods.
+       return true;
+               /*-
+               DatabaseEntry routingkeyDBE = new DatabaseEntry(routingKey);
                DatabaseEntry blockDBE = new DatabaseEntry();
                synchronized (this) {
                        if (closed)
@@ -2316,5 +2326,6 @@
                } catch (DatabaseException e) {
                        return false;
                } 
+                */
        }
 }

Modified: branches/db4o/freenet/src/freenet/store/FreenetStore.java
===================================================================
--- branches/db4o/freenet/src/freenet/store/FreenetStore.java   2008-09-24 
23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/store/FreenetStore.java   2008-09-24 
23:54:07 UTC (rev 22829)
@@ -53,6 +53,8 @@
        public long writes();

        public long keyCount();
+
+       public long getBloomFalsePositive();

        /**
         * Check if a routing key probably

Modified: branches/db4o/freenet/src/freenet/store/PubkeyStore.java
===================================================================
--- branches/db4o/freenet/src/freenet/store/PubkeyStore.java    2008-09-24 
23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/store/PubkeyStore.java    2008-09-24 
23:54:07 UTC (rev 22829)
@@ -14,7 +14,7 @@
                return false;
        }

-       StorableBlock construct(byte[] data, byte[] headers, byte[] routingKey,
+       public StorableBlock construct(byte[] data, byte[] headers, byte[] 
routingKey,
                        byte[] fullKey) throws KeyVerifyException {
                if(data == null) throw new PubkeyVerifyException("Need data to 
construct pubkey");
                try {

Modified: branches/db4o/freenet/src/freenet/store/RAMFreenetStore.java
===================================================================
--- branches/db4o/freenet/src/freenet/store/RAMFreenetStore.java        
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/store/RAMFreenetStore.java        
2008-09-24 23:54:07 UTC (rev 22829)
@@ -57,7 +57,7 @@
        }

        public synchronized long getMaxKeys() {
-               return (long) maxKeys;
+               return maxKeys;
        }

        public synchronized long hits() {
@@ -122,6 +122,10 @@
                return writes;
        }

+       public long getBloomFalsePositive() {
+               return -1;
+       }
+       
        public boolean probablyInStore(byte[] routingKey) {
                ByteArrayWrapper key = new ByteArrayWrapper(routingKey);
                return blocksByRoutingKey.get(key) != null;

Modified: branches/db4o/freenet/src/freenet/store/StoreCallback.java
===================================================================
--- branches/db4o/freenet/src/freenet/store/StoreCallback.java  2008-09-24 
23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/store/StoreCallback.java  2008-09-24 
23:54:07 UTC (rev 22829)
@@ -38,17 +38,22 @@
        protected FreenetStore store;

        /** Called once when first connecting to a FreenetStore. Package-local. 
*/
-       void setStore(FreenetStore store) {
+       public void setStore(FreenetStore store) {
                this.store = store;
        }

+       public FreenetStore getStore() {
+               return store;
+       }
+       
        // Reconstruction

        /** Construct a StorableBlock from the data, headers, and optionally 
routing key or full key.
         * IMPORTANT: Using the full key or routing key is OPTIONAL, and if we 
don't use them, WE DON'T
         * CHECK THEM EITHER! Caller MUST check that the key is the one 
expected.
         * @throws KeyVerifyException */
-       abstract StorableBlock construct(byte[] data, byte[] headers, byte[] 
routingKey, byte[] fullKey) throws KeyVerifyException;
+       public abstract StorableBlock construct(byte[] data, byte[] headers, 
byte[] routingKey, byte[] fullKey)
+               throws KeyVerifyException;

        public void setMaxKeys(long maxStoreKeys, boolean shrinkNow) throws 
DatabaseException, IOException {
                store.setMaxKeys(maxStoreKeys, shrinkNow);
@@ -73,6 +78,10 @@
        public long keyCount() {
                return store.keyCount();
        }
+       
+       public long getBloomFalsePositive() {
+               return store.getBloomFalsePositive();
+       }

        /** Generate a routing key from a full key */
        public abstract byte[] routingKeyFromFullKey(byte[] keyBuf);

Copied: branches/db4o/freenet/src/freenet/store/saltedhash (from rev 22484, 
trunk/freenet/src/freenet/store/saltedhash)

Deleted: branches/db4o/freenet/src/freenet/store/saltedhash/CipherManager.java
===================================================================
--- trunk/freenet/src/freenet/store/saltedhash/CipherManager.java       
2008-09-05 23:24:01 UTC (rev 22484)
+++ branches/db4o/freenet/src/freenet/store/saltedhash/CipherManager.java       
2008-09-24 23:54:07 UTC (rev 22829)
@@ -1,167 +0,0 @@
-/* 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.store.saltedhash;
-
-import java.security.MessageDigest;
-import java.util.Arrays;
-import java.util.LinkedHashMap;
-import java.util.Map;
-import java.util.Random;
-
-import freenet.crypt.BlockCipher;
-import freenet.crypt.PCFBMode;
-import freenet.crypt.SHA256;
-import freenet.crypt.UnsupportedCipherException;
-import freenet.crypt.ciphers.Rijndael;
-import freenet.support.ByteArrayWrapper;
-import freenet.support.Logger;
-
-/**
- * Cipher Manager
- * 
- * Manage all kind of digestion and encryption in store
- * 
- * @author sdiz
- */
-public class CipherManager {
-       /**
-        * <tt>0x10</tt> bytes of salt for better digestion, not too salty.
-        */
-       private byte[] salt;
-
-       CipherManager(byte[] salt) {
-               assert salt.length == 0x10;
-               this.salt = salt;
-       }
-
-       /**
-        * Get salt
-        * 
-        * @return salt
-        */
-       byte[] getSalt() {
-               return salt;
-       }
-
-       /**
-        * Cache for digested keys
-        */
-       @SuppressWarnings("serial")
-       private Map<ByteArrayWrapper, byte[]> digestRoutingKeyCache = new 
LinkedHashMap<ByteArrayWrapper, byte[]>() {
-               @Override
-               protected boolean removeEldestEntry(Map.Entry<ByteArrayWrapper, 
byte[]> eldest) {
-                       return size() > 128;
-               }
-       };
-
-       /**
-        * Get digested routing key
-        * 
-        * @param plainKey
-        * @return
-        */
-       byte[] getDigestedKey(byte[] plainKey) {
-               ByteArrayWrapper key = new ByteArrayWrapper(plainKey);
-               synchronized (digestRoutingKeyCache) {
-                       byte[] dk = digestRoutingKeyCache.get(key);
-                       if (dk != null)
-                               return dk;
-               }
-
-               MessageDigest digest = SHA256.getMessageDigest();
-               try {
-                       digest.update(plainKey);
-                       digest.update(salt);
-
-                       byte[] hashedRoutingKey = digest.digest();
-                       assert hashedRoutingKey.length == 0x20;
-
-                       synchronized (digestRoutingKeyCache) {
-                               digestRoutingKeyCache.put(key, 
hashedRoutingKey);
-                       }
-
-                       return hashedRoutingKey;
-               } finally {
-                       SHA256.returnMessageDigest(digest);
-               }
-       }
-
-       /**
-        * Encrypt this entry
-        */
-       void encrypt(SaltedHashFreenetStore.Entry entry, Random random) {
-               if (entry.isEncrypted)
-                       return;
-
-               entry.dataEncryptIV = new byte[16];
-               random.nextBytes(entry.dataEncryptIV);
-
-               PCFBMode cipher = makeCipher(entry.dataEncryptIV, 
entry.plainRoutingKey);
-               entry.header = cipher.blockEncipher(entry.header, 0, 
entry.header.length);
-               entry.data = cipher.blockEncipher(entry.data, 0, 
entry.data.length);
-
-               entry.getDigestedRoutingKey();
-               entry.isEncrypted = true;
-       }
-
-       /**
-        * Verify and decrypt this entry
-        * 
-        * @param routingKey
-        * @return <code>true</code> if the <code>routeKey</code> match and the 
entry is decrypted.
-        */
-       boolean decrypt(SaltedHashFreenetStore.Entry entry, byte[] routingKey) {
-               assert entry.header != null;
-               assert entry.data != null;
-
-               if (!entry.isEncrypted) {
-                       // Already decrypted
-                       if (Arrays.equals(entry.plainRoutingKey, routingKey))
-                               return true;
-                       else
-                               return false;
-               }
-
-               if (entry.plainRoutingKey != null) {
-                       // we knew the key
-                       if (!Arrays.equals(entry.plainRoutingKey, routingKey)) {
-                               return false;
-                       }
-               } else {
-                       // we do not know the plain key, let's check the digest
-                       if (!Arrays.equals(entry.digestedRoutingKey, 
getDigestedKey(routingKey)))
-                               return false;
-               }
-
-               entry.plainRoutingKey = routingKey;
-
-               PCFBMode cipher = makeCipher(entry.dataEncryptIV, 
entry.plainRoutingKey);
-               entry.header = cipher.blockDecipher(entry.header, 0, 
entry.header.length);
-               entry.data = cipher.blockDecipher(entry.data, 0, 
entry.data.length);
-
-               entry.isEncrypted = false;
-
-               return true;
-       }
-
-       /**
-        * Create PCFBMode object for this key
-        */
-       PCFBMode makeCipher(byte[] iv, byte[] key) {
-               byte[] iv2 = new byte[0x20]; // 256 bits
-
-               System.arraycopy(salt, 0, iv2, 0, 0x10);
-               System.arraycopy(iv, 0, iv2, 0x10, 0x10);
-
-               try {
-                       BlockCipher aes = new Rijndael(256, 256);
-                       aes.initialize(key);
-
-                       return PCFBMode.create(aes, iv2);
-               } catch (UnsupportedCipherException e) {
-                       Logger.error(this, "Rijndael not supported!", e);
-                       throw new Error("Rijndael not supported!", e);
-               }
-       }
-}

Copied: branches/db4o/freenet/src/freenet/store/saltedhash/CipherManager.java 
(from rev 22484, trunk/freenet/src/freenet/store/saltedhash/CipherManager.java)
===================================================================
--- branches/db4o/freenet/src/freenet/store/saltedhash/CipherManager.java       
                        (rev 0)
+++ branches/db4o/freenet/src/freenet/store/saltedhash/CipherManager.java       
2008-09-24 23:54:07 UTC (rev 22829)
@@ -0,0 +1,167 @@
+/* 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.store.saltedhash;
+
+import java.security.MessageDigest;
+import java.util.Arrays;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Random;
+
+import freenet.crypt.BlockCipher;
+import freenet.crypt.PCFBMode;
+import freenet.crypt.SHA256;
+import freenet.crypt.UnsupportedCipherException;
+import freenet.crypt.ciphers.Rijndael;
+import freenet.support.ByteArrayWrapper;
+import freenet.support.Logger;
+
+/**
+ * Cipher Manager
+ * 
+ * Manage all kind of digestion and encryption in store
+ * 
+ * @author sdiz
+ */
+public class CipherManager {
+       /**
+        * <tt>0x10</tt> bytes of salt for better digestion, not too salty.
+        */
+       private byte[] salt;
+
+       CipherManager(byte[] salt) {
+               assert salt.length == 0x10;
+               this.salt = salt;
+       }
+
+       /**
+        * Get salt
+        * 
+        * @return salt
+        */
+       byte[] getSalt() {
+               return salt;
+       }
+
+       /**
+        * Cache for digested keys
+        */
+       @SuppressWarnings("serial")
+       private Map<ByteArrayWrapper, byte[]> digestRoutingKeyCache = new 
LinkedHashMap<ByteArrayWrapper, byte[]>() {
+               @Override
+               protected boolean removeEldestEntry(Map.Entry<ByteArrayWrapper, 
byte[]> eldest) {
+                       return size() > 128;
+               }
+       };
+
+       /**
+        * Get digested routing key
+        * 
+        * @param plainKey
+        * @return
+        */
+       byte[] getDigestedKey(byte[] plainKey) {
+               ByteArrayWrapper key = new ByteArrayWrapper(plainKey);
+               synchronized (digestRoutingKeyCache) {
+                       byte[] dk = digestRoutingKeyCache.get(key);
+                       if (dk != null)
+                               return dk;
+               }
+
+               MessageDigest digest = SHA256.getMessageDigest();
+               try {
+                       digest.update(plainKey);
+                       digest.update(salt);
+
+                       byte[] hashedRoutingKey = digest.digest();
+                       assert hashedRoutingKey.length == 0x20;
+
+                       synchronized (digestRoutingKeyCache) {
+                               digestRoutingKeyCache.put(key, 
hashedRoutingKey);
+                       }
+
+                       return hashedRoutingKey;
+               } finally {
+                       SHA256.returnMessageDigest(digest);
+               }
+       }
+
+       /**
+        * Encrypt this entry
+        */
+       void encrypt(SaltedHashFreenetStore.Entry entry, Random random) {
+               if (entry.isEncrypted)
+                       return;
+
+               entry.dataEncryptIV = new byte[16];
+               random.nextBytes(entry.dataEncryptIV);
+
+               PCFBMode cipher = makeCipher(entry.dataEncryptIV, 
entry.plainRoutingKey);
+               entry.header = cipher.blockEncipher(entry.header, 0, 
entry.header.length);
+               entry.data = cipher.blockEncipher(entry.data, 0, 
entry.data.length);
+
+               entry.getDigestedRoutingKey();
+               entry.isEncrypted = true;
+       }
+
+       /**
+        * Verify and decrypt this entry
+        * 
+        * @param routingKey
+        * @return <code>true</code> if the <code>routeKey</code> match and the 
entry is decrypted.
+        */
+       boolean decrypt(SaltedHashFreenetStore.Entry entry, byte[] routingKey) {
+               assert entry.header != null;
+               assert entry.data != null;
+
+               if (!entry.isEncrypted) {
+                       // Already decrypted
+                       if (Arrays.equals(entry.plainRoutingKey, routingKey))
+                               return true;
+                       else
+                               return false;
+               }
+
+               if (entry.plainRoutingKey != null) {
+                       // we knew the key
+                       if (!Arrays.equals(entry.plainRoutingKey, routingKey)) {
+                               return false;
+                       }
+               } else {
+                       // we do not know the plain key, let's check the digest
+                       if (!Arrays.equals(entry.digestedRoutingKey, 
getDigestedKey(routingKey)))
+                               return false;
+               }
+
+               entry.plainRoutingKey = routingKey;
+
+               PCFBMode cipher = makeCipher(entry.dataEncryptIV, 
entry.plainRoutingKey);
+               entry.header = cipher.blockDecipher(entry.header, 0, 
entry.header.length);
+               entry.data = cipher.blockDecipher(entry.data, 0, 
entry.data.length);
+
+               entry.isEncrypted = false;
+
+               return true;
+       }
+
+       /**
+        * Create PCFBMode object for this key
+        */
+       PCFBMode makeCipher(byte[] iv, byte[] key) {
+               byte[] iv2 = new byte[0x20]; // 256 bits
+
+               System.arraycopy(salt, 0, iv2, 0, 0x10);
+               System.arraycopy(iv, 0, iv2, 0x10, 0x10);
+
+               try {
+                       BlockCipher aes = new Rijndael(256, 256);
+                       aes.initialize(key);
+
+                       return PCFBMode.create(aes, iv2);
+               } catch (UnsupportedCipherException e) {
+                       Logger.error(this, "Rijndael not supported!", e);
+                       throw new Error("Rijndael not supported!", e);
+               }
+       }
+}

Deleted: branches/db4o/freenet/src/freenet/store/saltedhash/LockManager.java
===================================================================
--- trunk/freenet/src/freenet/store/saltedhash/LockManager.java 2008-09-05 
23:24:01 UTC (rev 22484)
+++ branches/db4o/freenet/src/freenet/store/saltedhash/LockManager.java 
2008-09-24 23:54:07 UTC (rev 22829)
@@ -1,103 +0,0 @@
-/* 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.store.saltedhash;
-
-import java.util.HashMap;
-import java.util.Map;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.locks.Condition;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantLock;
-
-import freenet.support.Logger;
-
-/**
- * Lock Manager
- * 
- * Handle locking/unlocking of individual offsets.
- * 
- * @author sdiz
- */
-public class LockManager {
-       private static boolean logDEBUG;
-       private volatile boolean shutdown;
-       private Lock entryLock = new ReentrantLock();
-       private Map<Long, Condition> lockMap = new HashMap<Long, Condition>();
-
-       LockManager() {
-               logDEBUG = Logger.shouldLog(Logger.DEBUG, this);
-       }
-
-       /**
-        * Lock the entry
-        * 
-        * This lock is <strong>not</strong> re-entrance. No threads except 
Cleaner should hold more
-        * then one lock at a time (or deadlock may occur).
-        */
-       Condition lockEntry(long offset) {
-               if (logDEBUG)
-                       Logger.debug(this, "try locking " + offset, new 
Exception());
-
-               Condition condition;
-               try {
-                       entryLock.lock();
-                       try {
-                               do {
-                                       if (shutdown)
-                                               return null;
-
-                                       Condition lockCond = 
lockMap.get(offset);
-                                       if (lockCond != null)
-                                               lockCond.await(10, 
TimeUnit.SECONDS); // 10s for checking shutdown
-                                       else
-                                               break;
-                               } while (true);
-                               condition = entryLock.newCondition();
-                               lockMap.put(offset, condition);
-                       } finally {
-                               entryLock.unlock();
-                       }
-               } catch (InterruptedException e) {
-                       Logger.error(this, "lock interrupted", e);
-                       return null;
-               }
-
-               if (logDEBUG)
-                       Logger.debug(this, "locked " + offset, new Exception());
-               return condition;
-       }
-
-       /**
-        * Unlock the entry
-        */
-       void unlockEntry(long offset, Condition condition) {
-               if (logDEBUG)
-                       Logger.debug(this, "unlocking " + offset, new 
Exception("debug"));
-
-               entryLock.lock();
-               try {
-                       Condition cond = lockMap.remove(offset);
-                       assert cond == condition;
-                       cond.signal();
-               } finally {
-                       entryLock.unlock();
-               }
-       }
-
-       /**
-        * Shutdown and wait for all entries unlocked
-        */
-       void shutdown() {
-               shutdown = true;
-               entryLock.lock();
-               try {
-                       while (!lockMap.isEmpty()) {
-                               Condition cond = 
lockMap.values().iterator().next();
-                               cond.awaitUninterruptibly();
-                       }
-               } finally {
-                       entryLock.unlock();
-               }
-       }
-}

Copied: branches/db4o/freenet/src/freenet/store/saltedhash/LockManager.java 
(from rev 22484, trunk/freenet/src/freenet/store/saltedhash/LockManager.java)
===================================================================
--- branches/db4o/freenet/src/freenet/store/saltedhash/LockManager.java         
                (rev 0)
+++ branches/db4o/freenet/src/freenet/store/saltedhash/LockManager.java 
2008-09-24 23:54:07 UTC (rev 22829)
@@ -0,0 +1,103 @@
+/* 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.store.saltedhash;
+
+import java.util.HashMap;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+import freenet.support.Logger;
+
+/**
+ * Lock Manager
+ * 
+ * Handle locking/unlocking of individual offsets.
+ * 
+ * @author sdiz
+ */
+public class LockManager {
+       private static boolean logDEBUG;
+       private volatile boolean shutdown;
+       private Lock entryLock = new ReentrantLock();
+       private Map<Long, Condition> lockMap = new HashMap<Long, Condition>();
+
+       LockManager() {
+               logDEBUG = Logger.shouldLog(Logger.DEBUG, this);
+       }
+
+       /**
+        * Lock the entry
+        * 
+        * This lock is <strong>not</strong> re-entrance. No threads except 
Cleaner should hold more
+        * then one lock at a time (or deadlock may occur).
+        */
+       Condition lockEntry(long offset) {
+               if (logDEBUG)
+                       Logger.debug(this, "try locking " + offset, new 
Exception());
+
+               Condition condition;
+               try {
+                       entryLock.lock();
+                       try {
+                               do {
+                                       if (shutdown)
+                                               return null;
+
+                                       Condition lockCond = 
lockMap.get(offset);
+                                       if (lockCond != null)
+                                               lockCond.await(10, 
TimeUnit.SECONDS); // 10s for checking shutdown
+                                       else
+                                               break;
+                               } while (true);
+                               condition = entryLock.newCondition();
+                               lockMap.put(offset, condition);
+                       } finally {
+                               entryLock.unlock();
+                       }
+               } catch (InterruptedException e) {
+                       Logger.error(this, "lock interrupted", e);
+                       return null;
+               }
+
+               if (logDEBUG)
+                       Logger.debug(this, "locked " + offset, new Exception());
+               return condition;
+       }
+
+       /**
+        * Unlock the entry
+        */
+       void unlockEntry(long offset, Condition condition) {
+               if (logDEBUG)
+                       Logger.debug(this, "unlocking " + offset, new 
Exception("debug"));
+
+               entryLock.lock();
+               try {
+                       Condition cond = lockMap.remove(offset);
+                       assert cond == condition;
+                       cond.signal();
+               } finally {
+                       entryLock.unlock();
+               }
+       }
+
+       /**
+        * Shutdown and wait for all entries unlocked
+        */
+       void shutdown() {
+               shutdown = true;
+               entryLock.lock();
+               try {
+                       while (!lockMap.isEmpty()) {
+                               Condition cond = 
lockMap.values().iterator().next();
+                               cond.awaitUninterruptibly();
+                       }
+               } finally {
+                       entryLock.unlock();
+               }
+       }
+}

Deleted: 
branches/db4o/freenet/src/freenet/store/saltedhash/SaltedHashFreenetStore.java
===================================================================
--- trunk/freenet/src/freenet/store/saltedhash/SaltedHashFreenetStore.java      
2008-09-05 23:24:01 UTC (rev 22484)
+++ 
branches/db4o/freenet/src/freenet/store/saltedhash/SaltedHashFreenetStore.java  
    2008-09-24 23:54:07 UTC (rev 22829)
@@ -1,1687 +0,0 @@
-/* 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.store.saltedhash;
-
-import java.io.EOFException;
-import java.io.File;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-import java.nio.ByteBuffer;
-import java.nio.channels.FileChannel;
-import java.util.Arrays;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.ListIterator;
-import java.util.Map;
-import java.util.Random;
-import java.util.SortedSet;
-import java.util.TreeMap;
-import java.util.TreeSet;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicLong;
-import java.util.concurrent.locks.Condition;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReadWriteLock;
-import java.util.concurrent.locks.ReentrantLock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-
-import org.tanukisoftware.wrapper.WrapperManager;
-
-import freenet.keys.KeyVerifyException;
-import freenet.l10n.L10n;
-import freenet.node.SemiOrderedShutdownHook;
-import freenet.node.useralerts.UserAlert;
-import freenet.node.useralerts.UserAlertManager;
-import freenet.store.FreenetStore;
-import freenet.store.KeyCollisionException;
-import freenet.store.StorableBlock;
-import freenet.store.StoreCallback;
-import freenet.support.BloomFilter;
-import freenet.support.Fields;
-import freenet.support.HTMLNode;
-import freenet.support.HexUtil;
-import freenet.support.Logger;
-import freenet.support.io.FileUtil;
-import freenet.support.io.NativeThread;
-
-/**
- * Index-less data store based on salted hash
- * 
- * @author sdiz
- */
-public class SaltedHashFreenetStore implements FreenetStore {
-       /** Option for saving plainkey */
-       private static final boolean OPTION_SAVE_PLAINKEY = true;
-       private static final int OPTION_MAX_PROBE = 4;
-
-       private static final byte FLAG_DIRTY = 0x1;
-       private static final byte FLAG_REBUILD_BLOOM = 0x2;
-
-       private boolean checkBloom = true;
-       private int bloomFilterSize;
-       private int bloomFilterK;
-       private final BloomFilter bloomFilter;
-
-       private static boolean logMINOR;
-       private static boolean logDEBUG;
-
-       private final File baseDir;
-       private final String name;
-       private final StoreCallback callback;
-       private final boolean collisionPossible;
-       private final int headerBlockLength;
-       @SuppressWarnings("unused")
-       private final int routeKeyLength;
-       private final int fullKeyLength;
-       private final int dataBlockLength;
-       private final Random random;
-       @SuppressWarnings("unused")
-       private UserAlertManager userAlertManager;
-       
-       private long storeSize;
-       private int generation;
-       private int flags;
-
-       public static SaltedHashFreenetStore construct(File baseDir, String 
name, StoreCallback callback, Random random,
-               long maxKeys, int bloomFilterSize, boolean bloomCounting, 
SemiOrderedShutdownHook shutdownHook)
-               throws IOException {
-               return new SaltedHashFreenetStore(baseDir, name, callback, 
random, maxKeys, bloomFilterSize, bloomCounting,
-                       shutdownHook);
-       }
-
-       private SaltedHashFreenetStore(File baseDir, String name, StoreCallback 
callback, Random random, long maxKeys,
-               int bloomFilterSize, boolean bloomCounting, 
SemiOrderedShutdownHook shutdownHook) throws IOException {
-               logMINOR = Logger.shouldLog(Logger.MINOR, this);
-               logDEBUG = Logger.shouldLog(Logger.DEBUG, this);
-
-               this.baseDir = baseDir;
-               this.name = name;
-
-               this.callback = callback;
-               collisionPossible = callback.collisionPossible();
-               routeKeyLength = callback.routingKeyLength();
-               headerBlockLength = callback.headerLength();
-               fullKeyLength = callback.fullKeyLength();
-               dataBlockLength = callback.dataLength();
-
-               this.random = random;
-               storeSize = maxKeys;
-               this.bloomFilterSize = bloomFilterSize;
-
-               lockManager = new LockManager();
-
-               // Create a directory it not exist
-               this.baseDir.mkdirs();
-
-               configFile = new File(this.baseDir, name + ".config");
-               boolean newStore = loadConfigFile();
-
-               newStore |= openStoreFiles(baseDir, name);
-
-               File bloomFile = new File(this.baseDir, name + ".bloom");
-               bloomFilter = BloomFilter.createFilter(bloomFile, 
bloomFilterSize, bloomFilterK, bloomCounting);
-
-               if ((flags & FLAG_DIRTY) != 0)
-                       System.err.println("Datastore(" + name + ") is dirty.");
-
-               flags |= FLAG_DIRTY; // datastore is now dirty until 
flushAndClose()
-               writeConfigFile();
-
-               if (maxKeys != storeSize) {
-                       if (prevStoreSize != 0) {
-                               storeSize = Math.max(prevStoreSize, storeSize);
-                               prevStoreSize = 0;
-                       }
-                       setMaxKeys(maxKeys, true);
-               }
-
-               callback.setStore(this);
-               shutdownHook.addEarlyJob(new Thread(new ShutdownDB()));
-
-               cleanerThread = new Cleaner();
-               cleanerStatusUserAlert = new 
CleanerStatusUserAlert(cleanerThread);
-
-               // finish all resizing before continue
-               if (prevStoreSize != 0 && cleanerGlobalLock.tryLock()) {
-                       System.out.println("Resizing datastore (" + name + ")");
-                       try {
-                               cleanerThread.resizeStore(prevStoreSize, false);
-                       } finally {
-                               cleanerGlobalLock.unlock();
-                       }
-                       writeConfigFile();
-               } else if (bloomFilter.needRebuild() && !newStore) {
-                       // Bloom filter resized?
-                       flags |= FLAG_REBUILD_BLOOM;
-                       checkBloom = false;
-
-                       if (cleanerGlobalLock.tryLock()) {
-                               System.out.println("Bloom filter for datastore 
(" + name + ") missing/mismatch, rebuilding.");
-                               try {
-                                       cleanerThread.rebuildBloom(false);
-                               } finally {
-                                       cleanerGlobalLock.unlock();
-                               }
-                               writeConfigFile();
-                       }
-               }
-
-               cleanerThread.start();
-       }
-
-       public StorableBlock fetch(byte[] routingKey, byte[] fullKey, boolean 
dontPromote) throws IOException {
-               if (logMINOR)
-                       Logger.minor(this, "Fetch " + 
HexUtil.bytesToHex(routingKey) + " for " + callback);
-
-               configLock.readLock().lock();
-               try {
-                       Map<Long, Condition> lockMap = lockPlainKey(routingKey, 
true);
-                       if (lockMap == null) {
-                               if (logDEBUG)
-                                       Logger.debug(this, "cannot lock key: " 
+ HexUtil.bytesToHex(routingKey) + ", shutting down?");
-                               return null;
-                       }
-                       try {
-                               Entry entry = probeEntry(routingKey, true);
-
-                               if (entry == null) {
-                                       misses.incrementAndGet();
-                                       return null;
-                               }
-
-                               try {
-                                       StorableBlock block = 
entry.getStorableBlock(routingKey, fullKey);
-                                       if (block == null) {
-                                               misses.incrementAndGet();
-                                               return null;
-                                       }
-                                       hits.incrementAndGet();
-                                       return block;
-                               } catch (KeyVerifyException e) {
-                                       Logger.minor(this, "key verification 
exception", e);
-                                       misses.incrementAndGet();
-                                       return null;
-                               }
-                       } finally {
-                               unlockPlainKey(routingKey, true, lockMap);
-                       }
-               } finally {
-                       configLock.readLock().unlock();
-               }
-       }
-
-       /**
-        * Find and lock an entry with a specific routing key. This function 
would <strong>not</strong>
-        * lock the entries.
-        * 
-        * @param routingKey
-        * @param withData
-        * @return <code>Entry</code> object
-        * @throws IOException
-        */
-       private Entry probeEntry(byte[] routingKey, boolean withData) throws 
IOException {
-               if (checkBloom)
-                       if 
(!bloomFilter.checkFilter(cipherManager.getDigestedKey(routingKey)))
-                               return null;
-
-               Entry entry = probeEntry0(routingKey, storeSize, withData);
-
-               if (entry == null && prevStoreSize != 0)
-                       entry = probeEntry0(routingKey, prevStoreSize, 
withData);
-               if (checkBloom && entry == null)
-                       bloomFalsePos.incrementAndGet();
-
-               return entry;
-       }
-
-       private Entry probeEntry0(byte[] routingKey, long probeStoreSize, 
boolean withData) throws IOException {
-               Entry entry = null;
-               long[] offset = getOffsetFromPlainKey(routingKey, 
probeStoreSize);
-
-               for (int i = 0; i < offset.length; i++) {
-                       if (logDEBUG)
-                               Logger.debug(this, "probing for i=" + i + ", 
offset=" + offset[i]);
-
-                       try {
-                               entry = readEntry(offset[i], routingKey, 
withData);
-                               if (entry != null)
-                                       return entry;
-                       } catch (EOFException e) {
-                               if (prevStoreSize != 0) // may occur on store 
shrinking
-                                       Logger.error(this, "EOFException on 
probeEntry", e);
-                               continue;
-                       }
-               }
-               return null;
-       }
-
-       public void put(StorableBlock block, byte[] routingKey, byte[] fullKey, 
byte[] data, byte[] header,
-               boolean overwrite) throws IOException, KeyCollisionException {
-               if (logMINOR)
-                       Logger.minor(this, "Putting " + 
HexUtil.bytesToHex(routingKey) + " (" + name + ")");
-
-               configLock.readLock().lock();
-               try {
-                       Map<Long, Condition> lockMap = lockPlainKey(routingKey, 
false);
-                       if (lockMap == null) {
-                               if (logDEBUG)
-                                       Logger.debug(this, "cannot lock key: " 
+ HexUtil.bytesToHex(routingKey) + ", shutting down?");
-                               return;
-                       }
-                       try {
-                               /*
-                                * Use lazy loading here. This may lost data if 
digestedRoutingKey collide but
-                                * collisionPossible is false. Should be very 
rare as digestedRoutingKey is a
-                                * SHA-256 hash.
-                                */
-                               Entry oldEntry = probeEntry(routingKey, false);
-                               if (oldEntry != null && !oldEntry.isFree()) {
-                                       long oldOffset = oldEntry.curOffset;
-                                       try {
-                                               if (!collisionPossible)
-                                                       return;
-                                               
oldEntry.setData(readHeader(oldOffset), readData(oldOffset)); // read from disk
-                                               StorableBlock oldBlock = 
oldEntry.getStorableBlock(routingKey, fullKey);
-                                               if (block.equals(oldBlock)) {
-                                                       return; // already in 
store
-                                               } else if (!overwrite) {
-                                                       throw new 
KeyCollisionException();
-                                               }
-                                       } catch (KeyVerifyException e) {
-                                               // ignore
-                                       }
-
-                                       // Overwrite old offset with same key
-                                       Entry entry = new Entry(routingKey, 
header, data);
-                                       writeEntry(entry, oldOffset);
-                                       writes.incrementAndGet();
-                                       if (oldEntry.generation != generation)
-                                               keyCount.incrementAndGet();
-                                       return;
-                               }
-
-                               Entry entry = new Entry(routingKey, header, 
data);
-                               long[] offset = entry.getOffset();
-
-                               for (int i = 0; i < offset.length; i++) {
-                                       if (isFree(offset[i])) {
-                                               // write to free block
-                                               if (logDEBUG)
-                                                       Logger.debug(this, 
"probing, write to i=" + i + ", offset=" + offset[i]);
-                                               
bloomFilter.addKey(cipherManager.getDigestedKey(routingKey));
-                                               writeEntry(entry, offset[i]);
-                                               writes.incrementAndGet();
-                                               keyCount.incrementAndGet();
-
-                                               return;
-                                       }
-                               }
-
-                               // no free blocks, overwrite the first one
-                               if (logDEBUG)
-                                       Logger.debug(this, "collision, write to 
i=0, offset=" + offset[0]);
-                               
bloomFilter.addKey(cipherManager.getDigestedKey(routingKey));
-                               oldEntry = readEntry(offset[0], null, false);
-                               writeEntry(entry, offset[0]);
-                               writes.incrementAndGet();
-                               if (oldEntry.generation == generation)
-                                       
bloomFilter.removeKey(oldEntry.getDigestedRoutingKey());
-                               else
-                                       keyCount.incrementAndGet();
-                       } finally {
-                               unlockPlainKey(routingKey, false, lockMap);
-                       }
-               } finally {
-                       configLock.readLock().unlock();
-               }
-       }
-
-       // ------------- Entry I/O
-       // meta-data file
-       private File metaFile;
-       private RandomAccessFile metaRAF;
-       private FileChannel metaFC;
-       // header file
-       private File headerFile;
-       private RandomAccessFile headerRAF;
-       private FileChannel headerFC;
-       // data file
-       private File dataFile;
-       private RandomAccessFile dataRAF;
-       private FileChannel dataFC;
-
-       /**
-        * Data entry
-        * 
-        * <pre>
-        *  META-DATA BLOCK
-        *       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-        *       |0|1|2|3|4|5|6|7|8|9|A|B|C|D|E|F|
-        *  +----+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-        *  |0000|                               |
-        *  +----+     Digested Routing Key      |
-        *  |0010|                               |
-        *  +----+-------------------------------+
-        *  |0020|       Data Encrypt IV         |
-        *  +----+---------------+---------------+
-        *  |0030|     Flag      |  Store Size   |
-        *  +----+---------------+---------------+
-        *  |0040|       Plain Routing Key       |
-        *  |0050| (Only if ENTRY_FLAG_PLAINKEY) |
-        *  +----+-------+-----------------------+
-        *  |0060|  Gen  |    Reserved           |
-        *  +----+-------+-----------------------+
-        *  |0070|            Reserved           |
-        *  +----+-------------------------------+
-        *  
-        *  Gen = Generation
-        * </pre>
-        */
-       class Entry {
-               /** Flag for occupied space */
-               private final static long ENTRY_FLAG_OCCUPIED = 0x00000001L;
-               /** Flag for plain key available */
-               private final static long ENTRY_FLAG_PLAINKEY = 0x00000002L;
-
-               /** Control block length */
-               private static final int METADATA_LENGTH = 0x80;
-
-               byte[] plainRoutingKey;
-               byte[] digestedRoutingKey;
-               byte[] dataEncryptIV;
-               private long flag;
-               private long storeSize;
-               private int generation;
-               byte[] header;
-               byte[] data;
-
-               boolean isEncrypted;
-               private long curOffset = -1;
-
-               private Entry() {
-               }
-
-               private Entry(ByteBuffer metaDataBuf, ByteBuffer headerBuf, 
ByteBuffer dataBuf) {
-                       assert metaDataBuf.remaining() == METADATA_LENGTH;
-
-                       digestedRoutingKey = new byte[0x20];
-                       metaDataBuf.get(digestedRoutingKey);
-
-                       dataEncryptIV = new byte[0x10];
-                       metaDataBuf.get(dataEncryptIV);
-
-                       flag = metaDataBuf.getLong();
-                       storeSize = metaDataBuf.getLong();
-
-                       if ((flag & ENTRY_FLAG_PLAINKEY) != 0) {
-                               plainRoutingKey = new byte[0x20];
-                               metaDataBuf.get(plainRoutingKey);
-                       }
-
-                       metaDataBuf.position(0x60);
-                       generation = metaDataBuf.getInt();
-
-                       isEncrypted = true;
-
-                       if (headerBuf != null && dataBuf != null)
-                               setData(headerBuf, dataBuf);
-               }
-
-               /**
-                * Set header/data after construction.
-                * 
-                * @param storeBuf
-                * @param store
-                */
-               private void setData(ByteBuffer headerBuf, ByteBuffer dataBuf) {
-                       assert headerBuf.remaining() == headerBlockLength;
-                       assert dataBuf.remaining() == dataBlockLength;
-                       assert isEncrypted;
-
-                       header = new byte[headerBlockLength];
-                       headerBuf.get(header);
-
-                       data = new byte[dataBlockLength];
-                       dataBuf.get(data);
-               }
-
-               /**
-                * Create a new entry
-                * 
-                * @param plainRoutingKey
-                * @param header
-                * @param data
-                */
-               private Entry(byte[] plainRoutingKey, byte[] header, byte[] 
data) {
-                       this.plainRoutingKey = plainRoutingKey;
-
-                       flag = ENTRY_FLAG_OCCUPIED;
-                       this.storeSize = SaltedHashFreenetStore.this.storeSize;
-                       this.generation = 
SaltedHashFreenetStore.this.generation;
-
-                       // header/data will be overwritten in 
encrypt()/decrypt(),
-                       // let's make a copy here
-                       this.header = new byte[headerBlockLength];
-                       System.arraycopy(header, 0, this.header, 0, 
headerBlockLength);
-                       this.data = new byte[dataBlockLength];
-                       System.arraycopy(data, 0, this.data, 0, 
dataBlockLength);
-
-                       if (OPTION_SAVE_PLAINKEY) {
-                               flag |= ENTRY_FLAG_PLAINKEY;
-                       }
-
-                       isEncrypted = false;
-               }
-
-               private ByteBuffer toMetaDataBuffer() {
-                       ByteBuffer out = ByteBuffer.allocate(METADATA_LENGTH);
-                       cipherManager.encrypt(this, random);
-
-                       out.put(getDigestedRoutingKey());
-                       out.put(dataEncryptIV);
-                       out.putLong(flag);
-                       out.putLong(storeSize);
-
-                       if ((flag & ENTRY_FLAG_PLAINKEY) != 0 && 
plainRoutingKey != null) {
-                               assert plainRoutingKey.length == 0x20;
-                               out.put(plainRoutingKey);
-                       }
-
-                       out.position(0x60);
-                       out.putInt(generation);
-
-                       out.position(0);
-                       return out;
-               }
-
-               private ByteBuffer toHeaderBuffer() {
-                       assert isEncrypted; // should have encrypted to get 
dataEncryptIV in control buffer
-
-                       if (header == null)
-                               return null;
-
-                       ByteBuffer out = ByteBuffer.allocate(headerBlockLength);
-                       out.put(header);
-                       assert out.remaining() == 0;
-
-                       out.position(0);
-                       return out;
-               }
-
-               private ByteBuffer toDataBuffer() {
-                       assert isEncrypted; // should have encrypted to get 
dataEncryptIV in control buffer
-
-                       if (data == null)
-                               return null;
-
-                       ByteBuffer out = ByteBuffer.allocate(dataBlockLength);
-                       out.put(data);
-                       assert out.remaining() == 0;
-
-                       out.position(0);
-                       return out;
-               }
-
-               private StorableBlock getStorableBlock(byte[] routingKey, 
byte[] fullKey) throws KeyVerifyException {
-                       if (isFree() || header == null || data == null)
-                               return null; // this is a free block
-                       if (!cipherManager.decrypt(this, routingKey))
-                               return null;
-
-                       StorableBlock block = callback.construct(data, header, 
routingKey, fullKey);
-                       byte[] blockRoutingKey = block.getRoutingKey();
-
-                       if (!Arrays.equals(blockRoutingKey, routingKey)) {
-                               // can't recover, as decrypt() depends on a 
correct route key
-                               return null;
-                       }
-
-                       return block;
-               }
-
-               private long[] getOffset() {
-                       if (digestedRoutingKey != null)
-                               return 
getOffsetFromDigestedKey(digestedRoutingKey, storeSize);
-                       else
-                               return getOffsetFromPlainKey(plainRoutingKey, 
storeSize);
-               }
-
-               private boolean isFree() {
-                       return (flag & ENTRY_FLAG_OCCUPIED) == 0;
-               }
-
-               byte[] getDigestedRoutingKey() {
-                       if (digestedRoutingKey == null)
-                               if (plainRoutingKey == null)
-                                       return null;
-                               else
-                                       digestedRoutingKey = 
cipherManager.getDigestedKey(plainRoutingKey);
-                       return digestedRoutingKey;
-               }
-       }
-
-       /**
-        * Open all store files
-        * 
-        * @param baseDir
-        * @param name
-        * @throws IOException
-        * @return <code>true</code> iff this is a new datastore
-        */
-       private boolean openStoreFiles(File baseDir, String name) throws 
IOException {
-               metaFile = new File(baseDir, name + ".metadata");
-               headerFile = new File(baseDir, name + ".header");
-               dataFile = new File(baseDir, name + ".data");
-
-               boolean newStore = !metaFile.exists() || !headerFile.exists() 
|| !dataFile.exists();
-               
-               metaRAF = new RandomAccessFile(metaFile, "rw");
-               metaFC = metaRAF.getChannel();
-               metaFC.lock();
-               
-               headerRAF = new RandomAccessFile(headerFile, "rw");
-               headerFC = headerRAF.getChannel();
-               headerFC.lock();
-
-               dataRAF = new RandomAccessFile(dataFile, "rw");
-               dataFC = dataRAF.getChannel();
-               dataFC.lock();
-
-               long storeFileSize = Math.max(storeSize, prevStoreSize);
-               WrapperManager.signalStarting(10 * 60 * 1000); // 10minutes, 
for filesystem that support no sparse file.
-               setStoreFileSize(storeFileSize);
-               
-               return newStore;
-       }
-
-       /**
-        * Read entry from disk. Before calling this function, you should 
acquire all required locks.
-        * 
-        * @return <code>null</code> if and only if <code>routingKey</code> is 
not <code>null</code> and
-        *         the key does not match the entry.
-        */
-       private Entry readEntry(long offset, byte[] routingKey, boolean 
withData) throws IOException {
-               ByteBuffer mbf = ByteBuffer.allocate(Entry.METADATA_LENGTH);
-
-               do {
-                       int status = metaFC.read(mbf, Entry.METADATA_LENGTH * 
offset + mbf.position());
-                       if (status == -1)
-                               throw new EOFException();
-               } while (mbf.hasRemaining());
-               mbf.flip();
-
-               Entry entry = new Entry(mbf, null, null);
-               entry.curOffset = offset;
-
-               if (routingKey != null) {
-                       if (entry.isFree())
-                               return null;
-                       if 
(!Arrays.equals(cipherManager.getDigestedKey(routingKey), 
entry.digestedRoutingKey))
-                               return null;
-
-                       if (withData) {
-                               ByteBuffer headerBuf = readHeader(offset);
-                               ByteBuffer dataBuf = readData(offset);
-                               entry.setData(headerBuf, dataBuf);
-                               boolean decrypted = 
cipherManager.decrypt(entry, routingKey);
-                               if (!decrypted)
-                                       return null;
-                       }
-               }
-
-               return entry;
-       }
-
-       /**
-        * Read header from disk
-        * 
-        * @param offset
-        * @throws IOException
-        */
-       private ByteBuffer readHeader(long offset) throws IOException {
-               ByteBuffer buf = ByteBuffer.allocate(headerBlockLength);
-
-               do {
-                       int status = headerFC.read(buf, headerBlockLength * 
offset + buf.position());
-                       if (status == -1)
-                               throw new EOFException();
-               } while (buf.hasRemaining());
-               buf.flip();
-               return buf;
-       }
-
-       /**
-        * Read data from disk
-        * 
-        * @param offset
-        * @throws IOException
-        */
-       private ByteBuffer readData(long offset) throws IOException {
-               ByteBuffer buf = ByteBuffer.allocate(dataBlockLength);
-
-               do {
-                       int status = dataFC.read(buf, dataBlockLength * offset 
+ buf.position());
-                       if (status == -1)
-                               throw new EOFException();
-               } while (buf.hasRemaining());
-               buf.flip();
-               return buf;
-       }
-
-       private boolean isFree(long offset) throws IOException {
-               Entry entry = readEntry(offset, null, false);
-               return entry.isFree();
-       }
-
-       private byte[] getDigestedKeyFromOffset(long offset) throws IOException 
{
-               Entry entry = readEntry(offset, null, false);
-               return entry.getDigestedRoutingKey();
-       }
-
-       /**
-        * Write entry to disk.
-        * 
-        * Before calling this function, you should:
-        * <ul>
-        * <li>acquire all required locks</li>
-        * <li>update the entry with latest store size</li>
-        * </ul>
-        */
-       private void writeEntry(Entry entry, long offset) throws IOException {
-               cipherManager.encrypt(entry, random);
-
-               ByteBuffer bf = entry.toMetaDataBuffer();
-               do {
-                       int status = metaFC.write(bf, Entry.METADATA_LENGTH * 
offset + bf.position());
-                       if (status == -1)
-                               throw new EOFException();
-               } while (bf.hasRemaining());
-
-               bf = entry.toHeaderBuffer();
-               if (bf != null) {
-                       do {
-                               int status = headerFC.write(bf, 
headerBlockLength * offset + bf.position());
-                               if (status == -1)
-                                       throw new EOFException();
-                       } while (bf.hasRemaining());
-
-                       bf = entry.toDataBuffer();
-                       do {
-                               int status = dataFC.write(bf, dataBlockLength * 
offset + bf.position());
-                               if (status == -1)
-                                       throw new EOFException();
-                       } while (bf.hasRemaining());
-               }
-
-               entry.curOffset = offset;
-       }
-
-       private void flushAndClose() {
-               try {
-                       metaFC.force(true);
-                       metaFC.close();
-               } catch (Exception e) {
-                       Logger.error(this, "error flusing store", e);
-               }
-               try {
-                       headerFC.force(true);
-                       headerFC.close();
-               } catch (Exception e) {
-                       Logger.error(this, "error flusing store", e);
-               }
-               try {
-                       dataFC.force(true);
-                       dataFC.close();
-               } catch (Exception e) {
-                       Logger.error(this, "error flusing store", e);
-               }
-
-               bloomFilter.force();
-       }
-
-       /**
-        * Change on disk store file size
-        * 
-        * @param storeFileSize
-        */
-       private void setStoreFileSize(long storeFileSize) {
-               try {
-                       metaRAF.setLength(Entry.METADATA_LENGTH * 
storeFileSize);
-                       headerRAF.setLength(headerBlockLength * storeFileSize);
-                       dataRAF.setLength(dataBlockLength * storeFileSize);
-               } catch (IOException e) {
-                       Logger.error(this, "error resizing store file", e);
-               }
-       }
-
-       // ------------- Configuration
-       /**
-        * Configuration File
-        * 
-        * <pre>
-        *       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-        *       |0|1|2|3|4|5|6|7|8|9|A|B|C|D|E|F|
-        *  +----+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
-        *  |0000|             Salt              |
-        *  +----+---------------+---------------+
-        *  |0010|   Store Size  | prevStoreSize |
-        *  +----+---------------+-------+-------+
-        *  |0020| Est Key Count |  Gen  | Flags |
-        *  +----+-------+-------+-------+-------+
-        *  |0030|   K   |                       |
-        *  +----+-------+-----------------------+
-        *  
-        *  Gen = Generation
-        *    K = K for bloom filter
-        * </pre>
-        */
-       private final File configFile;
-
-       /**
-        * Load config file
-        * 
-        * @return <code>true</code> iff this is a new datastore
-        */
-       private boolean loadConfigFile() throws IOException {
-               assert cipherManager == null; // never load the configuration 
twice
-
-               if (!configFile.exists()) {
-                       // create new
-                       byte[] newsalt = new byte[0x10];
-                       random.nextBytes(newsalt);
-                       cipherManager = new CipherManager(newsalt);
-
-                       writeConfigFile();
-                       return true;
-               } else {
-                       // try to load
-                       RandomAccessFile raf = new RandomAccessFile(configFile, 
"r");
-                       byte[] salt = new byte[0x10];
-                       raf.readFully(salt);
-                       cipherManager = new CipherManager(salt);
-
-                       storeSize = raf.readLong();
-                       prevStoreSize = raf.readLong();
-                       keyCount.set(raf.readLong());
-                       generation = raf.readInt();
-                       flags = raf.readInt();
-
-                       if ((flags & FLAG_DIRTY) != 0)
-                               flags |= FLAG_REBUILD_BLOOM;
-
-                       try {
-                               bloomFilterK = raf.readInt();
-                       } catch (IOException e) {
-                               flags |= FLAG_REBUILD_BLOOM;
-                       }
-
-                       raf.close();
-                       return false;
-               }
-       }
-
-       /**
-        * Write config file
-        */
-       private void writeConfigFile() {
-               configLock.writeLock().lock();
-               try {
-                       File tempConfig = new File(configFile.getPath() + 
".tmp");
-                       RandomAccessFile raf = new RandomAccessFile(tempConfig, 
"rw");
-                       raf.seek(0);
-                       raf.write(cipherManager.getSalt());
-
-                       raf.writeLong(storeSize);
-                       raf.writeLong(prevStoreSize);
-                       raf.writeLong(keyCount.get());
-                       raf.writeInt(generation);
-                       raf.writeInt(flags);
-                       raf.writeInt(bloomFilterK);
-                       raf.writeInt(0);
-                       raf.writeLong(0);
-
-                       raf.close();
-
-                       FileUtil.renameTo(tempConfig, configFile);
-               } catch (IOException ioe) {
-                       Logger.error(this, "error writing config file for " + 
name, ioe);
-               } finally {
-                       configLock.writeLock().unlock();
-               }
-       }
-
-       // ------------- Store resizing
-       private long prevStoreSize = 0;
-       private Lock cleanerLock = new ReentrantLock(); // local to this 
datastore
-       private Condition cleanerCondition = cleanerLock.newCondition();
-       private static Lock cleanerGlobalLock = new ReentrantLock(); // global 
across all datastore
-       private Cleaner cleanerThread;
-       private CleanerStatusUserAlert cleanerStatusUserAlert;
-       
-       private final Entry NOT_MODIFIED = new Entry();
-
-       private interface BatchProcessor {
-               // initialize
-               void init();
-
-               // call this after reading RESIZE_MEMORY_ENTRIES entries
-               // return false to abort
-               boolean batch(long entriesLeft);
-
-               // call this on abort (e.g. node shutdown)
-               void abort();
-
-               void finish();
-               
-               // return <code>null</code> to free the entry
-               // return NOT_MODIFIED to keep the old entry
-               Entry process(Entry entry);
-       }
-
-       private class Cleaner extends NativeThread {
-               /**
-                * How often the clean should run
-                */
-               private static final int CLEANER_PERIOD = 5 * 60 * 1000; // 5 
minutes
-               
-               private volatile boolean isRebuilding;
-               private volatile boolean isResizing;
-
-               public Cleaner() {
-                       super("Store-" + name + "-Cleaner", 
NativeThread.LOW_PRIORITY, false);
-                       setPriority(MIN_PRIORITY);
-                       setDaemon(true);
-               }
-
-               @Override
-               public void run() {
-                       super.run();
-                       
-                       try {
-                               Thread.sleep((int)(CLEANER_PERIOD / 2 + 
CLEANER_PERIOD * Math.random()));
-                       } catch (InterruptedException e){}
-                       
-                       if (shutdown)
-                               return;
-                       
-                       int loop = 0;
-                       while (!shutdown) {
-                               loop++;
-
-                               cleanerLock.lock();
-                               try {
-                                       long _prevStoreSize;
-                                       configLock.readLock().lock();
-                                       try {
-                                               _prevStoreSize = prevStoreSize;
-                                       } finally {
-                                               configLock.readLock().unlock();
-                                       }
-
-                                       if (_prevStoreSize != 0 && 
cleanerGlobalLock.tryLock()) {
-                                               try {
-                                                       isResizing = true;
-                                                       
resizeStore(_prevStoreSize, true);
-                                               } finally {
-                                                       isResizing = false;
-                                                       
cleanerGlobalLock.unlock();
-                                               }
-                                       }
-
-                                       boolean _rebuildBloom;
-                                       configLock.readLock().lock();
-                                       try {
-                                               _rebuildBloom = ((flags & 
FLAG_REBUILD_BLOOM) != 0);
-                                       } finally {
-                                               configLock.readLock().unlock();
-                                       }
-                                       if (_rebuildBloom && prevStoreSize == 0 
&& cleanerGlobalLock.tryLock()) {
-                                               try {
-                                                       isRebuilding = true;
-                                                       rebuildBloom(true);
-                                               } finally {
-                                                       isRebuilding = false;
-                                                       
cleanerGlobalLock.unlock();
-                                               }
-                                       }
-
-                                       try {
-                                               if (loop % 6 == 0)
-                                                       bloomFilter.force();
-                                       } catch (Exception e) { // may throw 
IOException (even if it is not defined)
-                                               Logger.error(this, "Can't force 
bloom filter", e);
-                                       }
-                                       writeConfigFile();
-
-                                       try {
-                                               
cleanerCondition.await(CLEANER_PERIOD, TimeUnit.MILLISECONDS);
-                                       } catch (InterruptedException e) {
-                                               Logger.debug(this, 
"interrupted", e);
-                                       }
-                               } finally {
-                                       cleanerLock.unlock();
-                               }
-                       }
-               }
-
-               private static final int RESIZE_MEMORY_ENTRIES = 128; // 
temporary memory store size (in # of entries)
-
-               /**
-                * Move old entries to new location and resize store
-                */
-               private void resizeStore(final long _prevStoreSize, final 
boolean sleep) {
-                       Logger.normal(this, "Starting datastore resize");
-
-                       BatchProcessor resizeProcesser = new BatchProcessor() {
-                               List<Entry> oldEntryList = new 
LinkedList<Entry>();
-                               int optimialK;
-
-                               public void init() {
-                                       if (storeSize > _prevStoreSize)
-                                               setStoreFileSize(storeSize);
-
-                                       optimialK = 
BloomFilter.optimialK(bloomFilterSize, storeSize);
-                                       configLock.writeLock().lock();
-                                       try {
-                                               generation++;
-                                               bloomFilter.fork(optimialK);
-                                               keyCount.set(0);
-                                       } finally {
-                                               configLock.writeLock().unlock();
-                                       }
-
-                                       
WrapperManager.signalStarting(RESIZE_MEMORY_ENTRIES * 30 * 1000 + 1000);
-                               }
-
-                               public Entry process(Entry entry) {
-                                       int oldGeneration = entry.generation;
-                                       if (oldGeneration != generation) {
-                                               entry.generation = generation;
-                                               keyCount.incrementAndGet();
-                                       }
-
-                                       if (entry.storeSize == storeSize) {
-                                               // new size, don't have to 
relocate
-                                               if (entry.generation != 
generation) {
-                                                       // update filter
-                                                       
bloomFilter.addKey(entry.getDigestedRoutingKey());
-                                                       return entry;
-                                               } else {
-                                                       return NOT_MODIFIED;
-                                               }
-                                       }
-
-                                       // remove from store, prepare for 
relocation
-                                       if (oldGeneration == generation) {
-                                               // should be impossible
-                                               Logger.error(this, //
-                                                       "new generation object 
with wrong storeSize. DigestedRoutingKey=" //
-                                                               + 
HexUtil.bytesToHex(entry.getDigestedRoutingKey()) //
-                                                               + ", Offset=" + 
entry.curOffset);
-                                               
bloomFilter.removeKey(entry.getDigestedRoutingKey());
-                                       }
-                                       try {
-                                               
entry.setData(readHeader(entry.curOffset), readData(entry.curOffset));
-                                               oldEntryList.add(entry);
-                                               if (oldEntryList.size() > 
RESIZE_MEMORY_ENTRIES)
-                                                       oldEntryList.remove(0);
-                                       } catch (IOException e) {
-                                               Logger.error(this, "error 
reading entry (offset=" + entry.curOffset + ")", e);
-                                       }
-                                       return null;
-                               }
-
-                               int i = 0;
-                               public boolean batch(long entriesLeft) {
-                                       
WrapperManager.signalStarting(RESIZE_MEMORY_ENTRIES * 30 * 1000 + 1000);
-
-                                       if (i++ % 16 == 0)
-                                               writeConfigFile();
-
-                                       // shrink data file to current size
-                                       if (storeSize < _prevStoreSize)
-                                               
setStoreFileSize(Math.max(storeSize, entriesLeft));
-
-                                       // try to resolve the list
-                                       ListIterator<Entry> it = 
oldEntryList.listIterator();
-                                       while (it.hasNext())
-                                               if (resolveOldEntry(it.next()))
-                                                       it.remove();
-
-                                       return _prevStoreSize == prevStoreSize;
-                               }
-
-                               public void abort() {
-                                       bloomFilter.discard();
-                               }
-
-                               public void finish() {
-                                       configLock.writeLock().lock();
-                                       try {
-                                               if (_prevStoreSize != 
prevStoreSize)
-                                                       return;
-                                               bloomFilter.merge();
-                                               prevStoreSize = 0;
-
-                                               flags &= ~FLAG_REBUILD_BLOOM;
-                                               checkBloom = true;
-                                               bloomFilterK = optimialK;
-                                       } finally {
-                                               configLock.writeLock().unlock();
-                                       }
-
-                                       Logger.normal(this, "Finish resizing (" 
+ name + ")");
-                               }
-                       };
-
-                       batchProcessEntries(resizeProcesser, _prevStoreSize, 
true, sleep);
-               }
-
-               /**
-                * Rebuild bloom filter
-                */
-               private void rebuildBloom(boolean sleep) {
-                       if (bloomFilter == null)
-                               return;
-                       Logger.normal(this, "Start rebuilding bloom filter (" + 
name + ")");
-
-                       BatchProcessor rebuildBloomProcessor = new 
BatchProcessor() {
-                               int optimialK;
-
-                               public void init() {
-                                       optimialK = 
BloomFilter.optimialK(bloomFilterSize, storeSize);
-
-                                       configLock.writeLock().lock();
-                                       try {
-                                               generation++;
-                                               bloomFilter.fork(bloomFilterK);
-                                               keyCount.set(0);
-                                       } finally {
-                                               configLock.writeLock().unlock();
-                                       }
-
-                                       
WrapperManager.signalStarting(RESIZE_MEMORY_ENTRIES * 5 * 1000 + 1000);
-                               }
-
-                               public Entry process(Entry entry) {
-                                       if (entry.generation != generation) {
-                                               
bloomFilter.addKey(entry.getDigestedRoutingKey());
-                                               keyCount.incrementAndGet();
-
-                                               entry.generation = generation;
-                                               return entry;
-                                       }
-                                       return NOT_MODIFIED;
-                               }
-
-                               int i = 0;
-                               public boolean batch(long entriesLeft) {
-                                       
WrapperManager.signalStarting(RESIZE_MEMORY_ENTRIES * 5 * 1000 + 1000);
-
-                                       if (i++ % 16 == 0)
-                                               writeConfigFile();
-                                       
-                                       return prevStoreSize == 0;
-                               }
-
-                               public void abort() {
-                                       bloomFilter.discard();
-                               }
-
-                               public void finish() {
-                                       bloomFilter.merge();
-                                       configLock.writeLock().lock();
-                                       try {
-                                               flags &= ~FLAG_REBUILD_BLOOM;
-                                               checkBloom = true;
-                                               bloomFilterK = optimialK;
-                                       } finally {
-                                               configLock.writeLock().unlock();
-                                       }
-
-                                       Logger.normal(this, "Finish rebuilding 
bloom filter (" + name + ")");
-                               }
-                       };
-
-                       batchProcessEntries(rebuildBloomProcessor, storeSize, 
false, sleep);
-               }
-
-               private volatile long entriesLeft;
-               private volatile long entriesTotal;
-               
-               private void batchProcessEntries(BatchProcessor processor, long 
storeSize, boolean reverse, boolean sleep) {
-                       entriesLeft = entriesTotal = storeSize;
-                       
-                       long startOffset, step;
-                       if (!reverse) {
-                               startOffset = 0;
-                               step = RESIZE_MEMORY_ENTRIES;
-                       } else {
-                               startOffset = ((storeSize - 1) / 
RESIZE_MEMORY_ENTRIES) * RESIZE_MEMORY_ENTRIES;
-                               step = -RESIZE_MEMORY_ENTRIES;
-                       }
-
-                       int i = 0;
-                       processor.init();
-                       try {
-                               for (long curOffset = startOffset; curOffset >= 
0 && curOffset < storeSize; curOffset += step) {
-                                       if (shutdown) {
-                                               processor.abort();
-                                               return;
-                                       }
-                                       
-                                       if (i++ % 64 == 0)
-                                               System.err.println(name + " 
cleaner in progress: " + (entriesTotal - entriesLeft) + "/"
-                                                       + entriesTotal);
-                                               
-                                       batchProcessEntries(curOffset, 
RESIZE_MEMORY_ENTRIES, processor);
-                                       entriesLeft = reverse ? curOffset : 
Math.max(storeSize - curOffset - RESIZE_MEMORY_ENTRIES, 0);
-                                       if (!processor.batch(entriesLeft)) {
-                                               processor.abort();
-                                               return;
-                                       }
-
-                                       try {
-                                               if (sleep) 
-                                                       Thread.sleep(500);
-                                       } catch (InterruptedException e) {
-                                               processor.abort();
-                                               return;
-                                       }
-                               }
-                               processor.finish();
-                       } catch (Exception e) {
-                               processor.abort();
-                       }
-               }
-
-               /**
-                * Read a list of items from store.
-                * 
-                * @param offset
-                *            start offset, must be multiple of {@link 
FILE_SPLIT}
-                * @param length
-                *            number of items to read, must be multiple of 
{@link FILE_SPLIT}. If this
-                *            excess store size, read as much as possible.
-                * @param processor
-                *            batch processor
-                * @return <code>true</code> if operation complete 
successfully; <code>false</code>
-                *         otherwise (e.g. can't acquire locks, node shutting 
down)
-                */
-               private boolean batchProcessEntries(long offset, int length, 
BatchProcessor processor) {
-                       Condition[] locked = new Condition[length];
-                       try {
-                               // acquire all locks in the region, will unlock 
in the finally block
-                               for (int i = 0; i < length; i++) {
-                                       locked[i] = 
lockManager.lockEntry(offset + i);
-                                       if (locked[i] == null)
-                                               return false;
-                               }
-
-                               long startFileOffset = offset * 
Entry.METADATA_LENGTH;
-                               long entriesToRead = length;
-                               long bufLen = Entry.METADATA_LENGTH * 
entriesToRead;
-
-                               ByteBuffer buf = ByteBuffer.allocate((int) 
bufLen);
-                               boolean dirty = false;
-                               try {
-                                       while (buf.hasRemaining()) {
-                                               int status = metaFC.read(buf, 
startFileOffset + buf.position());
-                                               if (status == -1)
-                                                       break;
-                                       }
-                               } catch (IOException ioe) {
-                                       if (shutdown)
-                                               return false;
-                                       Logger.error(this, "unexpected 
IOException", ioe);
-                               }
-                               buf.flip();
-
-                               try {
-                                       for (int j = 0; !shutdown && 
buf.limit() > j * Entry.METADATA_LENGTH; j++) {
-                                               buf.position(j * 
Entry.METADATA_LENGTH);
-                                               if (buf.remaining() < 
Entry.METADATA_LENGTH) // EOF
-                                                       break;
-
-                                               ByteBuffer enBuf = buf.slice();
-                                               
enBuf.limit(Entry.METADATA_LENGTH);
-
-                                               Entry entry = new Entry(enBuf, 
null, null);
-                                               entry.curOffset = offset + j;
-
-                                               if (entry.isFree())
-                                                       continue; // not 
occupied
-
-                                               Entry newEntry = 
processor.process(entry);
-                                               if (newEntry == null) {// free 
the offset
-                                                       buf.position(j * 
Entry.METADATA_LENGTH);
-                                                       
buf.put(ByteBuffer.allocate(Entry.METADATA_LENGTH));
-                                                       
keyCount.decrementAndGet();
-
-                                                       dirty = true;
-                                               } else if (newEntry == 
NOT_MODIFIED) {
-                                               } else {
-                                                       // write back
-                                                       buf.position(j * 
Entry.METADATA_LENGTH);
-                                                       
buf.put(newEntry.toMetaDataBuffer());
-
-                                                       assert newEntry.header 
== null; // not supported
-                                                       assert newEntry.data == 
null; // not supported
-
-                                                       dirty = true;
-                                               }
-                                       }
-                               } finally {
-                                       // write back.
-                                       if (dirty) {
-                                               buf.flip();
-
-                                               try {
-                                                       while 
(buf.hasRemaining()) {
-                                                               
metaFC.write(buf, startFileOffset + buf.position());
-                                                       }
-                                               } catch (IOException ioe) {
-                                                       Logger.error(this, 
"unexpected IOException", ioe);
-                                               }
-                                       }
-                               }
-
-                               return true;
-                       } finally {
-                               // unlock
-                               for (int i = 0; i < length; i++)
-                                       if (locked[i] != null)
-                                               lockManager.unlockEntry(offset 
+ i, locked[i]);
-                       }
-               }
-
-               /**
-                * Put back an old entry to store file
-                * 
-                * @param entry
-                * @return <code>true</code> if the entry have put back 
successfully.
-                */
-               private boolean resolveOldEntry(Entry entry) {
-                       Map<Long, Condition> lockMap = 
lockDigestedKey(entry.getDigestedRoutingKey(), false);
-                       if (lockMap == null)
-                               return false;
-                       try {
-                               entry.storeSize = storeSize;
-                               long[] offsets = entry.getOffset();
-
-                               // Check for occupied entry with same key
-                               for (long offset : offsets) {
-                                       try {
-                                               if (!isFree(offset)
-                                                       && 
Arrays.equals(getDigestedKeyFromOffset(offset), entry.getDigestedRoutingKey())) 
{
-                                                       // do nothing
-                                                       return true;
-                                               }
-                                       } catch (IOException e) {
-                                               Logger.debug(this, 
"IOExcception on resolveOldEntry", e);
-                                       }
-                               }
-
-                               // Check for free entry
-                               for (long offset : offsets) {
-                                       try {
-                                               if (isFree(offset)) {
-                                                       writeEntry(entry, 
offset);
-                                                       
bloomFilter.addKey(entry.getDigestedRoutingKey());
-                                                       
keyCount.incrementAndGet();
-                                                       return true;
-                                               }
-                                       } catch (IOException e) {
-                                               Logger.debug(this, 
"IOExcception on resolveOldEntry", e);
-                                       }
-                               }
-                               return false;
-                       } finally {
-                               
unlockDigestedKey(entry.getDigestedRoutingKey(), false, lockMap);
-                       }
-               }
-       }
-
-       private final class CleanerStatusUserAlert implements UserAlert {
-               private Cleaner cleaner;
-
-               private CleanerStatusUserAlert(Cleaner cleaner) {
-                       this.cleaner = cleaner;
-               }
-
-               public String anchor() {
-                       return "store-cleaner-" + name;
-               }
-
-               public String dismissButtonText() {
-                       return L10n.getString("UserAlert.hide");
-               }
-
-               public HTMLNode getHTMLText() {
-                       return new HTMLNode("#", getText());
-               }
-
-               public short getPriorityClass() {
-                       return UserAlert.MINOR;
-               }
-
-               public String getShortText() {
-                       if (cleaner.isResizing)
-                               return 
L10n.getString("SaltedHashFreenetStore.shortResizeProgress", //
-                                       new String[] { "name", "processed", 
"total" },// 
-                                       new String[] { name, 
(cleaner.entriesTotal - cleaner.entriesLeft) + "",
-                                               cleaner.entriesTotal + "" });
-                       else
-                               return 
L10n.getString("SaltedHashFreenetStore.shortRebuildProgress", //
-                                       new String[] { "name", "processed", 
"total" },// 
-                                       new String[] { name, 
(cleaner.entriesTotal - cleaner.entriesLeft) + "",
-                                               cleaner.entriesTotal + "" });
-               }
-
-               public String getText() {
-                       if (cleaner.isResizing)
-                               return 
L10n.getString("SaltedHashFreenetStore.longResizeProgress", //
-                                       new String[] { "name", "processed", 
"total" },// 
-                                       new String[] { name, 
(cleaner.entriesTotal - cleaner.entriesLeft) + "",
-                                               cleaner.entriesTotal + "" });
-                       else
-                               return 
L10n.getString("SaltedHashFreenetStore.longRebuildProgress", //
-                                       new String[] { "name", "processed", 
"total" },// 
-                                       new String[] { name, 
(cleaner.entriesTotal - cleaner.entriesLeft) + "",
-                                               cleaner.entriesTotal + "" });
-               }
-
-               public String getTitle() {
-                       return 
L10n.getString("SaltedHashFreenetStore.cleanerAlertTitle", //
-                               new String[] { "name" }, //
-                               new String[] { name });
-               }
-
-               public Object getUserIdentifier() {
-                       return null;
-               }
-
-               public boolean isValid() {
-                       return cleaner.isRebuilding || cleaner.isResizing;
-               }
-
-               public void isValid(boolean validity) {
-                       // Ignore
-               }
-
-               public void onDismiss() {
-                       // Ignore
-               }
-
-               public boolean shouldUnregisterOnDismiss() {
-                       return true;
-               }
-
-               public boolean userCanDismiss() {
-                       return false;
-               }
-
-               public boolean isEventNotification() {
-                       return false;
-               }
-       }
-       
-       public void setUserAlertManager(UserAlertManager userAlertManager) {
-               if (cleanerStatusUserAlert != null)
-                       userAlertManager.register(cleanerStatusUserAlert);
-               // TODO change useralertmanager? is this a valid case?
-               this.userAlertManager = userAlertManager;
-       }
-
-       public void setMaxKeys(long newStoreSize, boolean shrinkNow) throws 
IOException {
-               Logger.normal(this, "[" + name + "] Resize newStoreSize=" + 
newStoreSize + ", shinkNow=" + shrinkNow);
-
-               configLock.writeLock().lock();
-               try {
-                       if (newStoreSize == this.storeSize)
-                               return;
-
-                       if (prevStoreSize != 0) {
-                               Logger.normal(this, "[" + name + "] resize 
already in progress, ignore resize request");
-                               return;
-                       }
-
-                       prevStoreSize = storeSize;
-                       storeSize = newStoreSize;
-                       writeConfigFile();
-               } finally {
-                       configLock.writeLock().unlock();
-               }
-
-               if (cleanerLock.tryLock()) {
-                       cleanerCondition.signal();
-                       cleanerLock.unlock();
-               }
-       }
-
-       // ------------- Locking
-       volatile boolean shutdown = false;
-       private LockManager lockManager;
-       private ReadWriteLock configLock = new ReentrantReadWriteLock();
-
-       /**
-        * Lock all possible offsets of a key. This method would release the 
locks if any locking
-        * operation failed.
-        * 
-        * @param plainKey
-        * @return <code>true</code> if all the offsets are locked.
-        */
-       private Map<Long, Condition> lockPlainKey(byte[] plainKey, boolean 
usePrevStoreSize) {
-               return lockDigestedKey(cipherManager.getDigestedKey(plainKey), 
usePrevStoreSize);
-       }
-
-       private void unlockPlainKey(byte[] plainKey, boolean usePrevStoreSize, 
Map<Long, Condition> lockMap) {
-               unlockDigestedKey(cipherManager.getDigestedKey(plainKey), 
usePrevStoreSize, lockMap);
-       }
-
-       /**
-        * Lock all possible offsets of a key. This method would release the 
locks if any locking
-        * operation failed.
-        * 
-        * @param digestedKey
-        * @return <code>true</code> if all the offsets are locked.
-        */
-       private Map<Long, Condition> lockDigestedKey(byte[] digestedKey, 
boolean usePrevStoreSize) {
-               // use a set to prevent duplicated offsets,
-               // a sorted set to prevent deadlocks
-               SortedSet<Long> offsets = new TreeSet<Long>();
-               long[] offsetArray = getOffsetFromDigestedKey(digestedKey, 
storeSize);
-               for (long offset : offsetArray)
-                       offsets.add(offset);
-               if (usePrevStoreSize && prevStoreSize != 0) {
-                       offsetArray = getOffsetFromDigestedKey(digestedKey, 
prevStoreSize);
-                       for (long offset : offsetArray)
-                               offsets.add(offset);
-               }
-
-               Map<Long, Condition> locked = new TreeMap<Long, Condition>();
-               for (long offset : offsets) {
-                       Condition condition = lockManager.lockEntry(offset);
-                       if (condition == null)
-                               break;
-                       locked.put(offset, condition);
-               }
-
-               if (locked.size() == offsets.size()) {
-                       return locked;
-               } else {
-                       // failed, remove the locks
-                       for (Map.Entry<Long, Condition> e : locked.entrySet())
-                               lockManager.unlockEntry(e.getKey(), 
e.getValue());
-                       return null;
-               }
-       }
-
-       private void unlockDigestedKey(byte[] digestedKey, boolean 
usePrevStoreSize, Map<Long, Condition> lockMap) {
-               // use a set to prevent duplicated offsets
-               SortedSet<Long> offsets = new TreeSet<Long>();
-               long[] offsetArray = getOffsetFromDigestedKey(digestedKey, 
storeSize);
-               for (long offset : offsetArray)
-                       offsets.add(offset);
-               if (usePrevStoreSize && prevStoreSize != 0) {
-                       offsetArray = getOffsetFromDigestedKey(digestedKey, 
prevStoreSize);
-                       for (long offset : offsetArray)
-                               offsets.add(offset);
-               }
-
-               for (long offset : offsets) {
-                       lockManager.unlockEntry(offset, lockMap.get(offset));
-                       lockMap.remove(offset);
-               }
-       }
-
-       public class ShutdownDB implements Runnable {
-               public void run() {
-                       shutdown = true;
-                       lockManager.shutdown();
-
-                       cleanerLock.lock();
-                       try {
-                               cleanerCondition.signalAll();
-                               cleanerThread.interrupt();
-                       } finally {
-                               cleanerLock.unlock();
-                       }
-
-                       configLock.writeLock().lock();
-                       try {
-                               flushAndClose();
-                               flags &= ~FLAG_DIRTY; // clean shutdown
-                               writeConfigFile();
-                       } finally {
-                               configLock.writeLock().unlock();
-                       }
-               }
-       }
-
-       // ------------- Hashing
-       private CipherManager cipherManager;
-
-       /**
-        * Get offset in the hash table, given a plain routing key.
-        * 
-        * @param plainKey
-        * @param storeSize
-        * @return
-        */
-       private long[] getOffsetFromPlainKey(byte[] plainKey, long storeSize) {
-               return 
getOffsetFromDigestedKey(cipherManager.getDigestedKey(plainKey), storeSize);
-       }
-
-       /**
-        * Get offset in the hash table, given a digested routing key.
-        * 
-        * @param digestedKey
-        * @param storeSize
-        * @return
-        */
-       private long[] getOffsetFromDigestedKey(byte[] digestedKey, long 
storeSize) {
-               long keyValue = Fields.bytesToLong(digestedKey);
-               long[] offsets = new long[OPTION_MAX_PROBE];
-
-               for (int i = 0; i < OPTION_MAX_PROBE; i++) {
-                       // h + 141 i^2 + 13 i
-                       offsets[i] = ((keyValue + 141 * (i * i) + 13 * i) & 
Long.MAX_VALUE) % storeSize;
-               }
-
-               return offsets;
-       }
-
-       // ------------- Statistics (a.k.a. lies)
-       private AtomicLong hits = new AtomicLong();
-       private AtomicLong misses = new AtomicLong();
-       private AtomicLong writes = new AtomicLong();
-       private AtomicLong keyCount = new AtomicLong();
-       private AtomicLong bloomFalsePos = new AtomicLong();
-
-       public long hits() {
-               return hits.get();
-       }
-
-       public long misses() {
-               return misses.get();
-       }
-
-       public long writes() {
-               return writes.get();
-       }
-
-       public long keyCount() {
-               return keyCount.get();
-       }
-
-       public long getMaxKeys() {
-               configLock.readLock().lock();
-               long _storeSize = storeSize;
-               configLock.readLock().unlock();
-               return _storeSize;
-       }
-
-       public long getBloomFalsePositive() {
-               return bloomFalsePos.get();
-       }
-
-       // ------------- Migration
-       public void migrationFrom(File storeFile, File keyFile) {
-               try {
-                       System.out.println("Migrating from " + storeFile);
-
-                       RandomAccessFile storeRAF = new 
RandomAccessFile(storeFile, "r");
-                       RandomAccessFile keyRAF = keyFile.exists() ? new 
RandomAccessFile(keyFile, "r") : null;
-
-                       byte[] header = new byte[headerBlockLength];
-                       byte[] data = new byte[dataBlockLength];
-                       byte[] key = new byte[fullKeyLength];
-
-                       long maxKey = storeRAF.length() / (headerBlockLength + 
dataBlockLength);
-
-                       for (int l = 0; l < maxKey; l++) {
-                               if (l % 1024 == 0) {
-                                       System.out.println(" migrating key " + 
l + "/" + maxKey);
-                                       WrapperManager.signalStarting(10 * 60 * 
1000); // max 10 minutes for every 1024 keys  
-                               }
-
-                               boolean keyRead = false;
-                               storeRAF.readFully(header);
-                               storeRAF.readFully(data);
-                               try {
-                                       if (keyRAF != null) {
-                                               keyRAF.readFully(key);
-                                               keyRead = true;
-                                       }
-                               } catch (IOException e) {
-                               }
-
-                               try {
-                                       StorableBlock b = 
callback.construct(data, header, null, keyRead ? key : null);
-                                       put(b, b.getRoutingKey(), 
b.getFullKey(), data, header, true);
-                               } catch (KeyVerifyException e) {
-                                       System.out.println("kve at block " + l);
-                               } catch (KeyCollisionException e) {
-                                       System.out.println("kce at block " + l);
-                               }
-                       }
-               } catch (EOFException eof) {
-                       // done
-               } catch (IOException e) {
-                       e.printStackTrace();
-               }
-       }
-
-       public boolean probablyInStore(byte[] routingKey) {
-               configLock.readLock().lock();
-               try {
-                       if (!checkBloom)
-                               return true;
-                       return 
bloomFilter.checkFilter(cipherManager.getDigestedKey(routingKey));
-               } finally {
-                       configLock.readLock().unlock();
-               }
-    }
-}

Copied: 
branches/db4o/freenet/src/freenet/store/saltedhash/SaltedHashFreenetStore.java 
(from rev 22484, 
trunk/freenet/src/freenet/store/saltedhash/SaltedHashFreenetStore.java)
===================================================================
--- 
branches/db4o/freenet/src/freenet/store/saltedhash/SaltedHashFreenetStore.java  
                            (rev 0)
+++ 
branches/db4o/freenet/src/freenet/store/saltedhash/SaltedHashFreenetStore.java  
    2008-09-24 23:54:07 UTC (rev 22829)
@@ -0,0 +1,1687 @@
+/* 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.store.saltedhash;
+
+import java.io.EOFException;
+import java.io.File;
+import java.io.IOException;
+import java.io.RandomAccessFile;
+import java.nio.ByteBuffer;
+import java.nio.channels.FileChannel;
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+import java.util.Random;
+import java.util.SortedSet;
+import java.util.TreeMap;
+import java.util.TreeSet;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReadWriteLock;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+import org.tanukisoftware.wrapper.WrapperManager;
+
+import freenet.keys.KeyVerifyException;
+import freenet.l10n.L10n;
+import freenet.node.SemiOrderedShutdownHook;
+import freenet.node.useralerts.UserAlert;
+import freenet.node.useralerts.UserAlertManager;
+import freenet.store.FreenetStore;
+import freenet.store.KeyCollisionException;
+import freenet.store.StorableBlock;
+import freenet.store.StoreCallback;
+import freenet.support.BloomFilter;
+import freenet.support.Fields;
+import freenet.support.HTMLNode;
+import freenet.support.HexUtil;
+import freenet.support.Logger;
+import freenet.support.io.FileUtil;
+import freenet.support.io.NativeThread;
+
+/**
+ * Index-less data store based on salted hash
+ * 
+ * @author sdiz
+ */
+public class SaltedHashFreenetStore implements FreenetStore {
+       /** Option for saving plainkey */
+       private static final boolean OPTION_SAVE_PLAINKEY = true;
+       private static final int OPTION_MAX_PROBE = 4;
+
+       private static final byte FLAG_DIRTY = 0x1;
+       private static final byte FLAG_REBUILD_BLOOM = 0x2;
+
+       private boolean checkBloom = true;
+       private int bloomFilterSize;
+       private int bloomFilterK;
+       private final BloomFilter bloomFilter;
+
+       private static boolean logMINOR;
+       private static boolean logDEBUG;
+
+       private final File baseDir;
+       private final String name;
+       private final StoreCallback callback;
+       private final boolean collisionPossible;
+       private final int headerBlockLength;
+       @SuppressWarnings("unused")
+       private final int routeKeyLength;
+       private final int fullKeyLength;
+       private final int dataBlockLength;
+       private final Random random;
+       @SuppressWarnings("unused")
+       private UserAlertManager userAlertManager;
+       
+       private long storeSize;
+       private int generation;
+       private int flags;
+
+       public static SaltedHashFreenetStore construct(File baseDir, String 
name, StoreCallback callback, Random random,
+               long maxKeys, int bloomFilterSize, boolean bloomCounting, 
SemiOrderedShutdownHook shutdownHook)
+               throws IOException {
+               return new SaltedHashFreenetStore(baseDir, name, callback, 
random, maxKeys, bloomFilterSize, bloomCounting,
+                       shutdownHook);
+       }
+
+       private SaltedHashFreenetStore(File baseDir, String name, StoreCallback 
callback, Random random, long maxKeys,
+               int bloomFilterSize, boolean bloomCounting, 
SemiOrderedShutdownHook shutdownHook) throws IOException {
+               logMINOR = Logger.shouldLog(Logger.MINOR, this);
+               logDEBUG = Logger.shouldLog(Logger.DEBUG, this);
+
+               this.baseDir = baseDir;
+               this.name = name;
+
+               this.callback = callback;
+               collisionPossible = callback.collisionPossible();
+               routeKeyLength = callback.routingKeyLength();
+               headerBlockLength = callback.headerLength();
+               fullKeyLength = callback.fullKeyLength();
+               dataBlockLength = callback.dataLength();
+
+               this.random = random;
+               storeSize = maxKeys;
+               this.bloomFilterSize = bloomFilterSize;
+
+               lockManager = new LockManager();
+
+               // Create a directory it not exist
+               this.baseDir.mkdirs();
+
+               configFile = new File(this.baseDir, name + ".config");
+               boolean newStore = loadConfigFile();
+
+               newStore |= openStoreFiles(baseDir, name);
+
+               File bloomFile = new File(this.baseDir, name + ".bloom");
+               bloomFilter = BloomFilter.createFilter(bloomFile, 
bloomFilterSize, bloomFilterK, bloomCounting);
+
+               if ((flags & FLAG_DIRTY) != 0)
+                       System.err.println("Datastore(" + name + ") is dirty.");
+
+               flags |= FLAG_DIRTY; // datastore is now dirty until 
flushAndClose()
+               writeConfigFile();
+
+               if (maxKeys != storeSize) {
+                       if (prevStoreSize != 0) {
+                               storeSize = Math.max(prevStoreSize, storeSize);
+                               prevStoreSize = 0;
+                       }
+                       setMaxKeys(maxKeys, true);
+               }
+
+               callback.setStore(this);
+               shutdownHook.addEarlyJob(new Thread(new ShutdownDB()));
+
+               cleanerThread = new Cleaner();
+               cleanerStatusUserAlert = new 
CleanerStatusUserAlert(cleanerThread);
+
+               // finish all resizing before continue
+               if (prevStoreSize != 0 && cleanerGlobalLock.tryLock()) {
+                       System.out.println("Resizing datastore (" + name + ")");
+                       try {
+                               cleanerThread.resizeStore(prevStoreSize, false);
+                       } finally {
+                               cleanerGlobalLock.unlock();
+                       }
+                       writeConfigFile();
+               } else if (bloomFilter.needRebuild() && !newStore) {
+                       // Bloom filter resized?
+                       flags |= FLAG_REBUILD_BLOOM;
+                       checkBloom = false;
+
+                       if (cleanerGlobalLock.tryLock()) {
+                               System.out.println("Bloom filter for datastore 
(" + name + ") missing/mismatch, rebuilding.");
+                               try {
+                                       cleanerThread.rebuildBloom(false);
+                               } finally {
+                                       cleanerGlobalLock.unlock();
+                               }
+                               writeConfigFile();
+                       }
+               }
+
+               cleanerThread.start();
+       }
+
+       public StorableBlock fetch(byte[] routingKey, byte[] fullKey, boolean 
dontPromote) throws IOException {
+               if (logMINOR)
+                       Logger.minor(this, "Fetch " + 
HexUtil.bytesToHex(routingKey) + " for " + callback);
+
+               configLock.readLock().lock();
+               try {
+                       Map<Long, Condition> lockMap = lockPlainKey(routingKey, 
true);
+                       if (lockMap == null) {
+                               if (logDEBUG)
+                                       Logger.debug(this, "cannot lock key: " 
+ HexUtil.bytesToHex(routingKey) + ", shutting down?");
+                               return null;
+                       }
+                       try {
+                               Entry entry = probeEntry(routingKey, true);
+
+                               if (entry == null) {
+                                       misses.incrementAndGet();
+                                       return null;
+                               }
+
+                               try {
+                                       StorableBlock block = 
entry.getStorableBlock(routingKey, fullKey);
+                                       if (block == null) {
+                                               misses.incrementAndGet();
+                                               return null;
+                                       }
+                                       hits.incrementAndGet();
+                                       return block;
+                               } catch (KeyVerifyException e) {
+                                       Logger.minor(this, "key verification 
exception", e);
+                                       misses.incrementAndGet();
+                                       return null;
+                               }
+                       } finally {
+                               unlockPlainKey(routingKey, true, lockMap);
+                       }
+               } finally {
+                       configLock.readLock().unlock();
+               }
+       }
+
+       /**
+        * Find and lock an entry with a specific routing key. This function 
would <strong>not</strong>
+        * lock the entries.
+        * 
+        * @param routingKey
+        * @param withData
+        * @return <code>Entry</code> object
+        * @throws IOException
+        */
+       private Entry probeEntry(byte[] routingKey, boolean withData) throws 
IOException {
+               if (checkBloom)
+                       if 
(!bloomFilter.checkFilter(cipherManager.getDigestedKey(routingKey)))
+                               return null;
+
+               Entry entry = probeEntry0(routingKey, storeSize, withData);
+
+               if (entry == null && prevStoreSize != 0)
+                       entry = probeEntry0(routingKey, prevStoreSize, 
withData);
+               if (checkBloom && entry == null)
+                       bloomFalsePos.incrementAndGet();
+
+               return entry;
+       }
+
+       private Entry probeEntry0(byte[] routingKey, long probeStoreSize, 
boolean withData) throws IOException {
+               Entry entry = null;
+               long[] offset = getOffsetFromPlainKey(routingKey, 
probeStoreSize);
+
+               for (int i = 0; i < offset.length; i++) {
+                       if (logDEBUG)
+                               Logger.debug(this, "probing for i=" + i + ", 
offset=" + offset[i]);
+
+                       try {
+                               entry = readEntry(offset[i], routingKey, 
withData);
+                               if (entry != null)
+                                       return entry;
+                       } catch (EOFException e) {
+                               if (prevStoreSize != 0) // may occur on store 
shrinking
+                                       Logger.error(this, "EOFException on 
probeEntry", e);
+                               continue;
+                       }
+               }
+               return null;
+       }
+
+       public void put(StorableBlock block, byte[] routingKey, byte[] fullKey, 
byte[] data, byte[] header,
+               boolean overwrite) throws IOException, KeyCollisionException {
+               if (logMINOR)
+                       Logger.minor(this, "Putting " + 
HexUtil.bytesToHex(routingKey) + " (" + name + ")");
+
+               configLock.readLock().lock();
+               try {
+                       Map<Long, Condition> lockMap = lockPlainKey(routingKey, 
false);
+                       if (lockMap == null) {
+                               if (logDEBUG)
+                                       Logger.debug(this, "cannot lock key: " 
+ HexUtil.bytesToHex(routingKey) + ", shutting down?");
+                               return;
+                       }
+                       try {
+                               /*
+                                * Use lazy loading here. This may lost data if 
digestedRoutingKey collide but
+                                * collisionPossible is false. Should be very 
rare as digestedRoutingKey is a
+                                * SHA-256 hash.
+                                */
+                               Entry oldEntry = probeEntry(routingKey, false);
+                               if (oldEntry != null && !oldEntry.isFree()) {
+                                       long oldOffset = oldEntry.curOffset;
+                                       try {
+                                               if (!collisionPossible)
+                                                       return;
+                                               
oldEntry.setData(readHeader(oldOffset), readData(oldOffset)); // read from disk
+                                               StorableBlock oldBlock = 
oldEntry.getStorableBlock(routingKey, fullKey);
+                                               if (block.equals(oldBlock)) {
+                                                       return; // already in 
store
+                                               } else if (!overwrite) {
+                                                       throw new 
KeyCollisionException();
+                                               }
+                                       } catch (KeyVerifyException e) {
+                                               // ignore
+                                       }
+
+                                       // Overwrite old offset with same key
+                                       Entry entry = new Entry(routingKey, 
header, data);
+                                       writeEntry(entry, oldOffset);
+                                       writes.incrementAndGet();
+                                       if (oldEntry.generation != generation)
+                                               keyCount.incrementAndGet();
+                                       return;
+                               }
+
+                               Entry entry = new Entry(routingKey, header, 
data);
+                               long[] offset = entry.getOffset();
+
+                               for (int i = 0; i < offset.length; i++) {
+                                       if (isFree(offset[i])) {
+                                               // write to free block
+                                               if (logDEBUG)
+                                                       Logger.debug(this, 
"probing, write to i=" + i + ", offset=" + offset[i]);
+                                               
bloomFilter.addKey(cipherManager.getDigestedKey(routingKey));
+                                               writeEntry(entry, offset[i]);
+                                               writes.incrementAndGet();
+                                               keyCount.incrementAndGet();
+
+                                               return;
+                                       }
+                               }
+
+                               // no free blocks, overwrite the first one
+                               if (logDEBUG)
+                                       Logger.debug(this, "collision, write to 
i=0, offset=" + offset[0]);
+                               
bloomFilter.addKey(cipherManager.getDigestedKey(routingKey));
+                               oldEntry = readEntry(offset[0], null, false);
+                               writeEntry(entry, offset[0]);
+                               writes.incrementAndGet();
+                               if (oldEntry.generation == generation)
+                                       
bloomFilter.removeKey(oldEntry.getDigestedRoutingKey());
+                               else
+                                       keyCount.incrementAndGet();
+                       } finally {
+                               unlockPlainKey(routingKey, false, lockMap);
+                       }
+               } finally {
+                       configLock.readLock().unlock();
+               }
+       }
+
+       // ------------- Entry I/O
+       // meta-data file
+       private File metaFile;
+       private RandomAccessFile metaRAF;
+       private FileChannel metaFC;
+       // header file
+       private File headerFile;
+       private RandomAccessFile headerRAF;
+       private FileChannel headerFC;
+       // data file
+       private File dataFile;
+       private RandomAccessFile dataRAF;
+       private FileChannel dataFC;
+
+       /**
+        * Data entry
+        * 
+        * <pre>
+        *  META-DATA BLOCK
+        *       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+        *       |0|1|2|3|4|5|6|7|8|9|A|B|C|D|E|F|
+        *  +----+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+        *  |0000|                               |
+        *  +----+     Digested Routing Key      |
+        *  |0010|                               |
+        *  +----+-------------------------------+
+        *  |0020|       Data Encrypt IV         |
+        *  +----+---------------+---------------+
+        *  |0030|     Flag      |  Store Size   |
+        *  +----+---------------+---------------+
+        *  |0040|       Plain Routing Key       |
+        *  |0050| (Only if ENTRY_FLAG_PLAINKEY) |
+        *  +----+-------+-----------------------+
+        *  |0060|  Gen  |    Reserved           |
+        *  +----+-------+-----------------------+
+        *  |0070|            Reserved           |
+        *  +----+-------------------------------+
+        *  
+        *  Gen = Generation
+        * </pre>
+        */
+       class Entry {
+               /** Flag for occupied space */
+               private final static long ENTRY_FLAG_OCCUPIED = 0x00000001L;
+               /** Flag for plain key available */
+               private final static long ENTRY_FLAG_PLAINKEY = 0x00000002L;
+
+               /** Control block length */
+               private static final int METADATA_LENGTH = 0x80;
+
+               byte[] plainRoutingKey;
+               byte[] digestedRoutingKey;
+               byte[] dataEncryptIV;
+               private long flag;
+               private long storeSize;
+               private int generation;
+               byte[] header;
+               byte[] data;
+
+               boolean isEncrypted;
+               private long curOffset = -1;
+
+               private Entry() {
+               }
+
+               private Entry(ByteBuffer metaDataBuf, ByteBuffer headerBuf, 
ByteBuffer dataBuf) {
+                       assert metaDataBuf.remaining() == METADATA_LENGTH;
+
+                       digestedRoutingKey = new byte[0x20];
+                       metaDataBuf.get(digestedRoutingKey);
+
+                       dataEncryptIV = new byte[0x10];
+                       metaDataBuf.get(dataEncryptIV);
+
+                       flag = metaDataBuf.getLong();
+                       storeSize = metaDataBuf.getLong();
+
+                       if ((flag & ENTRY_FLAG_PLAINKEY) != 0) {
+                               plainRoutingKey = new byte[0x20];
+                               metaDataBuf.get(plainRoutingKey);
+                       }
+
+                       metaDataBuf.position(0x60);
+                       generation = metaDataBuf.getInt();
+
+                       isEncrypted = true;
+
+                       if (headerBuf != null && dataBuf != null)
+                               setData(headerBuf, dataBuf);
+               }
+
+               /**
+                * Set header/data after construction.
+                * 
+                * @param storeBuf
+                * @param store
+                */
+               private void setData(ByteBuffer headerBuf, ByteBuffer dataBuf) {
+                       assert headerBuf.remaining() == headerBlockLength;
+                       assert dataBuf.remaining() == dataBlockLength;
+                       assert isEncrypted;
+
+                       header = new byte[headerBlockLength];
+                       headerBuf.get(header);
+
+                       data = new byte[dataBlockLength];
+                       dataBuf.get(data);
+               }
+
+               /**
+                * Create a new entry
+                * 
+                * @param plainRoutingKey
+                * @param header
+                * @param data
+                */
+               private Entry(byte[] plainRoutingKey, byte[] header, byte[] 
data) {
+                       this.plainRoutingKey = plainRoutingKey;
+
+                       flag = ENTRY_FLAG_OCCUPIED;
+                       this.storeSize = SaltedHashFreenetStore.this.storeSize;
+                       this.generation = 
SaltedHashFreenetStore.this.generation;
+
+                       // header/data will be overwritten in 
encrypt()/decrypt(),
+                       // let's make a copy here
+                       this.header = new byte[headerBlockLength];
+                       System.arraycopy(header, 0, this.header, 0, 
headerBlockLength);
+                       this.data = new byte[dataBlockLength];
+                       System.arraycopy(data, 0, this.data, 0, 
dataBlockLength);
+
+                       if (OPTION_SAVE_PLAINKEY) {
+                               flag |= ENTRY_FLAG_PLAINKEY;
+                       }
+
+                       isEncrypted = false;
+               }
+
+               private ByteBuffer toMetaDataBuffer() {
+                       ByteBuffer out = ByteBuffer.allocate(METADATA_LENGTH);
+                       cipherManager.encrypt(this, random);
+
+                       out.put(getDigestedRoutingKey());
+                       out.put(dataEncryptIV);
+                       out.putLong(flag);
+                       out.putLong(storeSize);
+
+                       if ((flag & ENTRY_FLAG_PLAINKEY) != 0 && 
plainRoutingKey != null) {
+                               assert plainRoutingKey.length == 0x20;
+                               out.put(plainRoutingKey);
+                       }
+
+                       out.position(0x60);
+                       out.putInt(generation);
+
+                       out.position(0);
+                       return out;
+               }
+
+               private ByteBuffer toHeaderBuffer() {
+                       assert isEncrypted; // should have encrypted to get 
dataEncryptIV in control buffer
+
+                       if (header == null)
+                               return null;
+
+                       ByteBuffer out = ByteBuffer.allocate(headerBlockLength);
+                       out.put(header);
+                       assert out.remaining() == 0;
+
+                       out.position(0);
+                       return out;
+               }
+
+               private ByteBuffer toDataBuffer() {
+                       assert isEncrypted; // should have encrypted to get 
dataEncryptIV in control buffer
+
+                       if (data == null)
+                               return null;
+
+                       ByteBuffer out = ByteBuffer.allocate(dataBlockLength);
+                       out.put(data);
+                       assert out.remaining() == 0;
+
+                       out.position(0);
+                       return out;
+               }
+
+               private StorableBlock getStorableBlock(byte[] routingKey, 
byte[] fullKey) throws KeyVerifyException {
+                       if (isFree() || header == null || data == null)
+                               return null; // this is a free block
+                       if (!cipherManager.decrypt(this, routingKey))
+                               return null;
+
+                       StorableBlock block = callback.construct(data, header, 
routingKey, fullKey);
+                       byte[] blockRoutingKey = block.getRoutingKey();
+
+                       if (!Arrays.equals(blockRoutingKey, routingKey)) {
+                               // can't recover, as decrypt() depends on a 
correct route key
+                               return null;
+                       }
+
+                       return block;
+               }
+
+               private long[] getOffset() {
+                       if (digestedRoutingKey != null)
+                               return 
getOffsetFromDigestedKey(digestedRoutingKey, storeSize);
+                       else
+                               return getOffsetFromPlainKey(plainRoutingKey, 
storeSize);
+               }
+
+               private boolean isFree() {
+                       return (flag & ENTRY_FLAG_OCCUPIED) == 0;
+               }
+
+               byte[] getDigestedRoutingKey() {
+                       if (digestedRoutingKey == null)
+                               if (plainRoutingKey == null)
+                                       return null;
+                               else
+                                       digestedRoutingKey = 
cipherManager.getDigestedKey(plainRoutingKey);
+                       return digestedRoutingKey;
+               }
+       }
+
+       /**
+        * Open all store files
+        * 
+        * @param baseDir
+        * @param name
+        * @throws IOException
+        * @return <code>true</code> iff this is a new datastore
+        */
+       private boolean openStoreFiles(File baseDir, String name) throws 
IOException {
+               metaFile = new File(baseDir, name + ".metadata");
+               headerFile = new File(baseDir, name + ".header");
+               dataFile = new File(baseDir, name + ".data");
+
+               boolean newStore = !metaFile.exists() || !headerFile.exists() 
|| !dataFile.exists();
+               
+               metaRAF = new RandomAccessFile(metaFile, "rw");
+               metaFC = metaRAF.getChannel();
+               metaFC.lock();
+               
+               headerRAF = new RandomAccessFile(headerFile, "rw");
+               headerFC = headerRAF.getChannel();
+               headerFC.lock();
+
+               dataRAF = new RandomAccessFile(dataFile, "rw");
+               dataFC = dataRAF.getChannel();
+               dataFC.lock();
+
+               long storeFileSize = Math.max(storeSize, prevStoreSize);
+               WrapperManager.signalStarting(10 * 60 * 1000); // 10minutes, 
for filesystem that support no sparse file.
+               setStoreFileSize(storeFileSize);
+               
+               return newStore;
+       }
+
+       /**
+        * Read entry from disk. Before calling this function, you should 
acquire all required locks.
+        * 
+        * @return <code>null</code> if and only if <code>routingKey</code> is 
not <code>null</code> and
+        *         the key does not match the entry.
+        */
+       private Entry readEntry(long offset, byte[] routingKey, boolean 
withData) throws IOException {
+               ByteBuffer mbf = ByteBuffer.allocate(Entry.METADATA_LENGTH);
+
+               do {
+                       int status = metaFC.read(mbf, Entry.METADATA_LENGTH * 
offset + mbf.position());
+                       if (status == -1)
+                               throw new EOFException();
+               } while (mbf.hasRemaining());
+               mbf.flip();
+
+               Entry entry = new Entry(mbf, null, null);
+               entry.curOffset = offset;
+
+               if (routingKey != null) {
+                       if (entry.isFree())
+                               return null;
+                       if 
(!Arrays.equals(cipherManager.getDigestedKey(routingKey), 
entry.digestedRoutingKey))
+                               return null;
+
+                       if (withData) {
+                               ByteBuffer headerBuf = readHeader(offset);
+                               ByteBuffer dataBuf = readData(offset);
+                               entry.setData(headerBuf, dataBuf);
+                               boolean decrypted = 
cipherManager.decrypt(entry, routingKey);
+                               if (!decrypted)
+                                       return null;
+                       }
+               }
+
+               return entry;
+       }
+
+       /**
+        * Read header from disk
+        * 
+        * @param offset
+        * @throws IOException
+        */
+       private ByteBuffer readHeader(long offset) throws IOException {
+               ByteBuffer buf = ByteBuffer.allocate(headerBlockLength);
+
+               do {
+                       int status = headerFC.read(buf, headerBlockLength * 
offset + buf.position());
+                       if (status == -1)
+                               throw new EOFException();
+               } while (buf.hasRemaining());
+               buf.flip();
+               return buf;
+       }
+
+       /**
+        * Read data from disk
+        * 
+        * @param offset
+        * @throws IOException
+        */
+       private ByteBuffer readData(long offset) throws IOException {
+               ByteBuffer buf = ByteBuffer.allocate(dataBlockLength);
+
+               do {
+                       int status = dataFC.read(buf, dataBlockLength * offset 
+ buf.position());
+                       if (status == -1)
+                               throw new EOFException();
+               } while (buf.hasRemaining());
+               buf.flip();
+               return buf;
+       }
+
+       private boolean isFree(long offset) throws IOException {
+               Entry entry = readEntry(offset, null, false);
+               return entry.isFree();
+       }
+
+       private byte[] getDigestedKeyFromOffset(long offset) throws IOException 
{
+               Entry entry = readEntry(offset, null, false);
+               return entry.getDigestedRoutingKey();
+       }
+
+       /**
+        * Write entry to disk.
+        * 
+        * Before calling this function, you should:
+        * <ul>
+        * <li>acquire all required locks</li>
+        * <li>update the entry with latest store size</li>
+        * </ul>
+        */
+       private void writeEntry(Entry entry, long offset) throws IOException {
+               cipherManager.encrypt(entry, random);
+
+               ByteBuffer bf = entry.toMetaDataBuffer();
+               do {
+                       int status = metaFC.write(bf, Entry.METADATA_LENGTH * 
offset + bf.position());
+                       if (status == -1)
+                               throw new EOFException();
+               } while (bf.hasRemaining());
+
+               bf = entry.toHeaderBuffer();
+               if (bf != null) {
+                       do {
+                               int status = headerFC.write(bf, 
headerBlockLength * offset + bf.position());
+                               if (status == -1)
+                                       throw new EOFException();
+                       } while (bf.hasRemaining());
+
+                       bf = entry.toDataBuffer();
+                       do {
+                               int status = dataFC.write(bf, dataBlockLength * 
offset + bf.position());
+                               if (status == -1)
+                                       throw new EOFException();
+                       } while (bf.hasRemaining());
+               }
+
+               entry.curOffset = offset;
+       }
+
+       private void flushAndClose() {
+               try {
+                       metaFC.force(true);
+                       metaFC.close();
+               } catch (Exception e) {
+                       Logger.error(this, "error flusing store", e);
+               }
+               try {
+                       headerFC.force(true);
+                       headerFC.close();
+               } catch (Exception e) {
+                       Logger.error(this, "error flusing store", e);
+               }
+               try {
+                       dataFC.force(true);
+                       dataFC.close();
+               } catch (Exception e) {
+                       Logger.error(this, "error flusing store", e);
+               }
+
+               bloomFilter.force();
+       }
+
+       /**
+        * Change on disk store file size
+        * 
+        * @param storeFileSize
+        */
+       private void setStoreFileSize(long storeFileSize) {
+               try {
+                       metaRAF.setLength(Entry.METADATA_LENGTH * 
storeFileSize);
+                       headerRAF.setLength(headerBlockLength * storeFileSize);
+                       dataRAF.setLength(dataBlockLength * storeFileSize);
+               } catch (IOException e) {
+                       Logger.error(this, "error resizing store file", e);
+               }
+       }
+
+       // ------------- Configuration
+       /**
+        * Configuration File
+        * 
+        * <pre>
+        *       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+        *       |0|1|2|3|4|5|6|7|8|9|A|B|C|D|E|F|
+        *  +----+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+        *  |0000|             Salt              |
+        *  +----+---------------+---------------+
+        *  |0010|   Store Size  | prevStoreSize |
+        *  +----+---------------+-------+-------+
+        *  |0020| Est Key Count |  Gen  | Flags |
+        *  +----+-------+-------+-------+-------+
+        *  |0030|   K   |                       |
+        *  +----+-------+-----------------------+
+        *  
+        *  Gen = Generation
+        *    K = K for bloom filter
+        * </pre>
+        */
+       private final File configFile;
+
+       /**
+        * Load config file
+        * 
+        * @return <code>true</code> iff this is a new datastore
+        */
+       private boolean loadConfigFile() throws IOException {
+               assert cipherManager == null; // never load the configuration 
twice
+
+               if (!configFile.exists()) {
+                       // create new
+                       byte[] newsalt = new byte[0x10];
+                       random.nextBytes(newsalt);
+                       cipherManager = new CipherManager(newsalt);
+
+                       writeConfigFile();
+                       return true;
+               } else {
+                       // try to load
+                       RandomAccessFile raf = new RandomAccessFile(configFile, 
"r");
+                       byte[] salt = new byte[0x10];
+                       raf.readFully(salt);
+                       cipherManager = new CipherManager(salt);
+
+                       storeSize = raf.readLong();
+                       prevStoreSize = raf.readLong();
+                       keyCount.set(raf.readLong());
+                       generation = raf.readInt();
+                       flags = raf.readInt();
+
+                       if ((flags & FLAG_DIRTY) != 0)
+                               flags |= FLAG_REBUILD_BLOOM;
+
+                       try {
+                               bloomFilterK = raf.readInt();
+                       } catch (IOException e) {
+                               flags |= FLAG_REBUILD_BLOOM;
+                       }
+
+                       raf.close();
+                       return false;
+               }
+       }
+
+       /**
+        * Write config file
+        */
+       private void writeConfigFile() {
+               configLock.writeLock().lock();
+               try {
+                       File tempConfig = new File(configFile.getPath() + 
".tmp");
+                       RandomAccessFile raf = new RandomAccessFile(tempConfig, 
"rw");
+                       raf.seek(0);
+                       raf.write(cipherManager.getSalt());
+
+                       raf.writeLong(storeSize);
+                       raf.writeLong(prevStoreSize);
+                       raf.writeLong(keyCount.get());
+                       raf.writeInt(generation);
+                       raf.writeInt(flags);
+                       raf.writeInt(bloomFilterK);
+                       raf.writeInt(0);
+                       raf.writeLong(0);
+
+                       raf.close();
+
+                       FileUtil.renameTo(tempConfig, configFile);
+               } catch (IOException ioe) {
+                       Logger.error(this, "error writing config file for " + 
name, ioe);
+               } finally {
+                       configLock.writeLock().unlock();
+               }
+       }
+
+       // ------------- Store resizing
+       private long prevStoreSize = 0;
+       private Lock cleanerLock = new ReentrantLock(); // local to this 
datastore
+       private Condition cleanerCondition = cleanerLock.newCondition();
+       private static Lock cleanerGlobalLock = new ReentrantLock(); // global 
across all datastore
+       private Cleaner cleanerThread;
+       private CleanerStatusUserAlert cleanerStatusUserAlert;
+       
+       private final Entry NOT_MODIFIED = new Entry();
+
+       private interface BatchProcessor {
+               // initialize
+               void init();
+
+               // call this after reading RESIZE_MEMORY_ENTRIES entries
+               // return false to abort
+               boolean batch(long entriesLeft);
+
+               // call this on abort (e.g. node shutdown)
+               void abort();
+
+               void finish();
+               
+               // return <code>null</code> to free the entry
+               // return NOT_MODIFIED to keep the old entry
+               Entry process(Entry entry);
+       }
+
+       private class Cleaner extends NativeThread {
+               /**
+                * How often the clean should run
+                */
+               private static final int CLEANER_PERIOD = 5 * 60 * 1000; // 5 
minutes
+               
+               private volatile boolean isRebuilding;
+               private volatile boolean isResizing;
+
+               public Cleaner() {
+                       super("Store-" + name + "-Cleaner", 
NativeThread.LOW_PRIORITY, false);
+                       setPriority(MIN_PRIORITY);
+                       setDaemon(true);
+               }
+
+               @Override
+               public void run() {
+                       super.run();
+                       
+                       try {
+                               Thread.sleep((int)(CLEANER_PERIOD / 2 + 
CLEANER_PERIOD * Math.random()));
+                       } catch (InterruptedException e){}
+                       
+                       if (shutdown)
+                               return;
+                       
+                       int loop = 0;
+                       while (!shutdown) {
+                               loop++;
+
+                               cleanerLock.lock();
+                               try {
+                                       long _prevStoreSize;
+                                       configLock.readLock().lock();
+                                       try {
+                                               _prevStoreSize = prevStoreSize;
+                                       } finally {
+                                               configLock.readLock().unlock();
+                                       }
+
+                                       if (_prevStoreSize != 0 && 
cleanerGlobalLock.tryLock()) {
+                                               try {
+                                                       isResizing = true;
+                                                       
resizeStore(_prevStoreSize, true);
+                                               } finally {
+                                                       isResizing = false;
+                                                       
cleanerGlobalLock.unlock();
+                                               }
+                                       }
+
+                                       boolean _rebuildBloom;
+                                       configLock.readLock().lock();
+                                       try {
+                                               _rebuildBloom = ((flags & 
FLAG_REBUILD_BLOOM) != 0);
+                                       } finally {
+                                               configLock.readLock().unlock();
+                                       }
+                                       if (_rebuildBloom && prevStoreSize == 0 
&& cleanerGlobalLock.tryLock()) {
+                                               try {
+                                                       isRebuilding = true;
+                                                       rebuildBloom(true);
+                                               } finally {
+                                                       isRebuilding = false;
+                                                       
cleanerGlobalLock.unlock();
+                                               }
+                                       }
+
+                                       try {
+                                               if (loop % 6 == 0)
+                                                       bloomFilter.force();
+                                       } catch (Exception e) { // may throw 
IOException (even if it is not defined)
+                                               Logger.error(this, "Can't force 
bloom filter", e);
+                                       }
+                                       writeConfigFile();
+
+                                       try {
+                                               
cleanerCondition.await(CLEANER_PERIOD, TimeUnit.MILLISECONDS);
+                                       } catch (InterruptedException e) {
+                                               Logger.debug(this, 
"interrupted", e);
+                                       }
+                               } finally {
+                                       cleanerLock.unlock();
+                               }
+                       }
+               }
+
+               private static final int RESIZE_MEMORY_ENTRIES = 128; // 
temporary memory store size (in # of entries)
+
+               /**
+                * Move old entries to new location and resize store
+                */
+               private void resizeStore(final long _prevStoreSize, final 
boolean sleep) {
+                       Logger.normal(this, "Starting datastore resize");
+
+                       BatchProcessor resizeProcesser = new BatchProcessor() {
+                               List<Entry> oldEntryList = new 
LinkedList<Entry>();
+                               int optimialK;
+
+                               public void init() {
+                                       if (storeSize > _prevStoreSize)
+                                               setStoreFileSize(storeSize);
+
+                                       optimialK = 
BloomFilter.optimialK(bloomFilterSize, storeSize);
+                                       configLock.writeLock().lock();
+                                       try {
+                                               generation++;
+                                               bloomFilter.fork(optimialK);
+                                               keyCount.set(0);
+                                       } finally {
+                                               configLock.writeLock().unlock();
+                                       }
+
+                                       
WrapperManager.signalStarting(RESIZE_MEMORY_ENTRIES * 30 * 1000 + 1000);
+                               }
+
+                               public Entry process(Entry entry) {
+                                       int oldGeneration = entry.generation;
+                                       if (oldGeneration != generation) {
+                                               entry.generation = generation;
+                                               keyCount.incrementAndGet();
+                                       }
+
+                                       if (entry.storeSize == storeSize) {
+                                               // new size, don't have to 
relocate
+                                               if (entry.generation != 
generation) {
+                                                       // update filter
+                                                       
bloomFilter.addKey(entry.getDigestedRoutingKey());
+                                                       return entry;
+                                               } else {
+                                                       return NOT_MODIFIED;
+                                               }
+                                       }
+
+                                       // remove from store, prepare for 
relocation
+                                       if (oldGeneration == generation) {
+                                               // should be impossible
+                                               Logger.error(this, //
+                                                       "new generation object 
with wrong storeSize. DigestedRoutingKey=" //
+                                                               + 
HexUtil.bytesToHex(entry.getDigestedRoutingKey()) //
+                                                               + ", Offset=" + 
entry.curOffset);
+                                               
bloomFilter.removeKey(entry.getDigestedRoutingKey());
+                                       }
+                                       try {
+                                               
entry.setData(readHeader(entry.curOffset), readData(entry.curOffset));
+                                               oldEntryList.add(entry);
+                                               if (oldEntryList.size() > 
RESIZE_MEMORY_ENTRIES)
+                                                       oldEntryList.remove(0);
+                                       } catch (IOException e) {
+                                               Logger.error(this, "error 
reading entry (offset=" + entry.curOffset + ")", e);
+                                       }
+                                       return null;
+                               }
+
+                               int i = 0;
+                               public boolean batch(long entriesLeft) {
+                                       
WrapperManager.signalStarting(RESIZE_MEMORY_ENTRIES * 30 * 1000 + 1000);
+
+                                       if (i++ % 16 == 0)
+                                               writeConfigFile();
+
+                                       // shrink data file to current size
+                                       if (storeSize < _prevStoreSize)
+                                               
setStoreFileSize(Math.max(storeSize, entriesLeft));
+
+                                       // try to resolve the list
+                                       ListIterator<Entry> it = 
oldEntryList.listIterator();
+                                       while (it.hasNext())
+                                               if (resolveOldEntry(it.next()))
+                                                       it.remove();
+
+                                       return _prevStoreSize == prevStoreSize;
+                               }
+
+                               public void abort() {
+                                       bloomFilter.discard();
+                               }
+
+                               public void finish() {
+                                       configLock.writeLock().lock();
+                                       try {
+                                               if (_prevStoreSize != 
prevStoreSize)
+                                                       return;
+                                               bloomFilter.merge();
+                                               prevStoreSize = 0;
+
+                                               flags &= ~FLAG_REBUILD_BLOOM;
+                                               checkBloom = true;
+                                               bloomFilterK = optimialK;
+                                       } finally {
+                                               configLock.writeLock().unlock();
+                                       }
+
+                                       Logger.normal(this, "Finish resizing (" 
+ name + ")");
+                               }
+                       };
+
+                       batchProcessEntries(resizeProcesser, _prevStoreSize, 
true, sleep);
+               }
+
+               /**
+                * Rebuild bloom filter
+                */
+               private void rebuildBloom(boolean sleep) {
+                       if (bloomFilter == null)
+                               return;
+                       Logger.normal(this, "Start rebuilding bloom filter (" + 
name + ")");
+
+                       BatchProcessor rebuildBloomProcessor = new 
BatchProcessor() {
+                               int optimialK;
+
+                               public void init() {
+                                       optimialK = 
BloomFilter.optimialK(bloomFilterSize, storeSize);
+
+                                       configLock.writeLock().lock();
+                                       try {
+                                               generation++;
+                                               bloomFilter.fork(bloomFilterK);
+                                               keyCount.set(0);
+                                       } finally {
+                                               configLock.writeLock().unlock();
+                                       }
+
+                                       
WrapperManager.signalStarting(RESIZE_MEMORY_ENTRIES * 5 * 1000 + 1000);
+                               }
+
+                               public Entry process(Entry entry) {
+                                       if (entry.generation != generation) {
+                                               
bloomFilter.addKey(entry.getDigestedRoutingKey());
+                                               keyCount.incrementAndGet();
+
+                                               entry.generation = generation;
+                                               return entry;
+                                       }
+                                       return NOT_MODIFIED;
+                               }
+
+                               int i = 0;
+                               public boolean batch(long entriesLeft) {
+                                       
WrapperManager.signalStarting(RESIZE_MEMORY_ENTRIES * 5 * 1000 + 1000);
+
+                                       if (i++ % 16 == 0)
+                                               writeConfigFile();
+                                       
+                                       return prevStoreSize == 0;
+                               }
+
+                               public void abort() {
+                                       bloomFilter.discard();
+                               }
+
+                               public void finish() {
+                                       bloomFilter.merge();
+                                       configLock.writeLock().lock();
+                                       try {
+                                               flags &= ~FLAG_REBUILD_BLOOM;
+                                               checkBloom = true;
+                                               bloomFilterK = optimialK;
+                                       } finally {
+                                               configLock.writeLock().unlock();
+                                       }
+
+                                       Logger.normal(this, "Finish rebuilding 
bloom filter (" + name + ")");
+                               }
+                       };
+
+                       batchProcessEntries(rebuildBloomProcessor, storeSize, 
false, sleep);
+               }
+
+               private volatile long entriesLeft;
+               private volatile long entriesTotal;
+               
+               private void batchProcessEntries(BatchProcessor processor, long 
storeSize, boolean reverse, boolean sleep) {
+                       entriesLeft = entriesTotal = storeSize;
+                       
+                       long startOffset, step;
+                       if (!reverse) {
+                               startOffset = 0;
+                               step = RESIZE_MEMORY_ENTRIES;
+                       } else {
+                               startOffset = ((storeSize - 1) / 
RESIZE_MEMORY_ENTRIES) * RESIZE_MEMORY_ENTRIES;
+                               step = -RESIZE_MEMORY_ENTRIES;
+                       }
+
+                       int i = 0;
+                       processor.init();
+                       try {
+                               for (long curOffset = startOffset; curOffset >= 
0 && curOffset < storeSize; curOffset += step) {
+                                       if (shutdown) {
+                                               processor.abort();
+                                               return;
+                                       }
+                                       
+                                       if (i++ % 64 == 0)
+                                               System.err.println(name + " 
cleaner in progress: " + (entriesTotal - entriesLeft) + "/"
+                                                       + entriesTotal);
+                                               
+                                       batchProcessEntries(curOffset, 
RESIZE_MEMORY_ENTRIES, processor);
+                                       entriesLeft = reverse ? curOffset : 
Math.max(storeSize - curOffset - RESIZE_MEMORY_ENTRIES, 0);
+                                       if (!processor.batch(entriesLeft)) {
+                                               processor.abort();
+                                               return;
+                                       }
+
+                                       try {
+                                               if (sleep) 
+                                                       Thread.sleep(500);
+                                       } catch (InterruptedException e) {
+                                               processor.abort();
+                                               return;
+                                       }
+                               }
+                               processor.finish();
+                       } catch (Exception e) {
+                               processor.abort();
+                       }
+               }
+
+               /**
+                * Read a list of items from store.
+                * 
+                * @param offset
+                *            start offset, must be multiple of {@link 
FILE_SPLIT}
+                * @param length
+                *            number of items to read, must be multiple of 
{@link FILE_SPLIT}. If this
+                *            excess store size, read as much as possible.
+                * @param processor
+                *            batch processor
+                * @return <code>true</code> if operation complete 
successfully; <code>false</code>
+                *         otherwise (e.g. can't acquire locks, node shutting 
down)
+                */
+               private boolean batchProcessEntries(long offset, int length, 
BatchProcessor processor) {
+                       Condition[] locked = new Condition[length];
+                       try {
+                               // acquire all locks in the region, will unlock 
in the finally block
+                               for (int i = 0; i < length; i++) {
+                                       locked[i] = 
lockManager.lockEntry(offset + i);
+                                       if (locked[i] == null)
+                                               return false;
+                               }
+
+                               long startFileOffset = offset * 
Entry.METADATA_LENGTH;
+                               long entriesToRead = length;
+                               long bufLen = Entry.METADATA_LENGTH * 
entriesToRead;
+
+                               ByteBuffer buf = ByteBuffer.allocate((int) 
bufLen);
+                               boolean dirty = false;
+                               try {
+                                       while (buf.hasRemaining()) {
+                                               int status = metaFC.read(buf, 
startFileOffset + buf.position());
+                                               if (status == -1)
+                                                       break;
+                                       }
+                               } catch (IOException ioe) {
+                                       if (shutdown)
+                                               return false;
+                                       Logger.error(this, "unexpected 
IOException", ioe);
+                               }
+                               buf.flip();
+
+                               try {
+                                       for (int j = 0; !shutdown && 
buf.limit() > j * Entry.METADATA_LENGTH; j++) {
+                                               buf.position(j * 
Entry.METADATA_LENGTH);
+                                               if (buf.remaining() < 
Entry.METADATA_LENGTH) // EOF
+                                                       break;
+
+                                               ByteBuffer enBuf = buf.slice();
+                                               
enBuf.limit(Entry.METADATA_LENGTH);
+
+                                               Entry entry = new Entry(enBuf, 
null, null);
+                                               entry.curOffset = offset + j;
+
+                                               if (entry.isFree())
+                                                       continue; // not 
occupied
+
+                                               Entry newEntry = 
processor.process(entry);
+                                               if (newEntry == null) {// free 
the offset
+                                                       buf.position(j * 
Entry.METADATA_LENGTH);
+                                                       
buf.put(ByteBuffer.allocate(Entry.METADATA_LENGTH));
+                                                       
keyCount.decrementAndGet();
+
+                                                       dirty = true;
+                                               } else if (newEntry == 
NOT_MODIFIED) {
+                                               } else {
+                                                       // write back
+                                                       buf.position(j * 
Entry.METADATA_LENGTH);
+                                                       
buf.put(newEntry.toMetaDataBuffer());
+
+                                                       assert newEntry.header 
== null; // not supported
+                                                       assert newEntry.data == 
null; // not supported
+
+                                                       dirty = true;
+                                               }
+                                       }
+                               } finally {
+                                       // write back.
+                                       if (dirty) {
+                                               buf.flip();
+
+                                               try {
+                                                       while 
(buf.hasRemaining()) {
+                                                               
metaFC.write(buf, startFileOffset + buf.position());
+                                                       }
+                                               } catch (IOException ioe) {
+                                                       Logger.error(this, 
"unexpected IOException", ioe);
+                                               }
+                                       }
+                               }
+
+                               return true;
+                       } finally {
+                               // unlock
+                               for (int i = 0; i < length; i++)
+                                       if (locked[i] != null)
+                                               lockManager.unlockEntry(offset 
+ i, locked[i]);
+                       }
+               }
+
+               /**
+                * Put back an old entry to store file
+                * 
+                * @param entry
+                * @return <code>true</code> if the entry have put back 
successfully.
+                */
+               private boolean resolveOldEntry(Entry entry) {
+                       Map<Long, Condition> lockMap = 
lockDigestedKey(entry.getDigestedRoutingKey(), false);
+                       if (lockMap == null)
+                               return false;
+                       try {
+                               entry.storeSize = storeSize;
+                               long[] offsets = entry.getOffset();
+
+                               // Check for occupied entry with same key
+                               for (long offset : offsets) {
+                                       try {
+                                               if (!isFree(offset)
+                                                       && 
Arrays.equals(getDigestedKeyFromOffset(offset), entry.getDigestedRoutingKey())) 
{
+                                                       // do nothing
+                                                       return true;
+                                               }
+                                       } catch (IOException e) {
+                                               Logger.debug(this, 
"IOExcception on resolveOldEntry", e);
+                                       }
+                               }
+
+                               // Check for free entry
+                               for (long offset : offsets) {
+                                       try {
+                                               if (isFree(offset)) {
+                                                       writeEntry(entry, 
offset);
+                                                       
bloomFilter.addKey(entry.getDigestedRoutingKey());
+                                                       
keyCount.incrementAndGet();
+                                                       return true;
+                                               }
+                                       } catch (IOException e) {
+                                               Logger.debug(this, 
"IOExcception on resolveOldEntry", e);
+                                       }
+                               }
+                               return false;
+                       } finally {
+                               
unlockDigestedKey(entry.getDigestedRoutingKey(), false, lockMap);
+                       }
+               }
+       }
+
+       private final class CleanerStatusUserAlert implements UserAlert {
+               private Cleaner cleaner;
+
+               private CleanerStatusUserAlert(Cleaner cleaner) {
+                       this.cleaner = cleaner;
+               }
+
+               public String anchor() {
+                       return "store-cleaner-" + name;
+               }
+
+               public String dismissButtonText() {
+                       return L10n.getString("UserAlert.hide");
+               }
+
+               public HTMLNode getHTMLText() {
+                       return new HTMLNode("#", getText());
+               }
+
+               public short getPriorityClass() {
+                       return UserAlert.MINOR;
+               }
+
+               public String getShortText() {
+                       if (cleaner.isResizing)
+                               return 
L10n.getString("SaltedHashFreenetStore.shortResizeProgress", //
+                                       new String[] { "name", "processed", 
"total" },// 
+                                       new String[] { name, 
(cleaner.entriesTotal - cleaner.entriesLeft) + "",
+                                               cleaner.entriesTotal + "" });
+                       else
+                               return 
L10n.getString("SaltedHashFreenetStore.shortRebuildProgress", //
+                                       new String[] { "name", "processed", 
"total" },// 
+                                       new String[] { name, 
(cleaner.entriesTotal - cleaner.entriesLeft) + "",
+                                               cleaner.entriesTotal + "" });
+               }
+
+               public String getText() {
+                       if (cleaner.isResizing)
+                               return 
L10n.getString("SaltedHashFreenetStore.longResizeProgress", //
+                                       new String[] { "name", "processed", 
"total" },// 
+                                       new String[] { name, 
(cleaner.entriesTotal - cleaner.entriesLeft) + "",
+                                               cleaner.entriesTotal + "" });
+                       else
+                               return 
L10n.getString("SaltedHashFreenetStore.longRebuildProgress", //
+                                       new String[] { "name", "processed", 
"total" },// 
+                                       new String[] { name, 
(cleaner.entriesTotal - cleaner.entriesLeft) + "",
+                                               cleaner.entriesTotal + "" });
+               }
+
+               public String getTitle() {
+                       return 
L10n.getString("SaltedHashFreenetStore.cleanerAlertTitle", //
+                               new String[] { "name" }, //
+                               new String[] { name });
+               }
+
+               public Object getUserIdentifier() {
+                       return null;
+               }
+
+               public boolean isValid() {
+                       return cleaner.isRebuilding || cleaner.isResizing;
+               }
+
+               public void isValid(boolean validity) {
+                       // Ignore
+               }
+
+               public void onDismiss() {
+                       // Ignore
+               }
+
+               public boolean shouldUnregisterOnDismiss() {
+                       return true;
+               }
+
+               public boolean userCanDismiss() {
+                       return false;
+               }
+
+               public boolean isEventNotification() {
+                       return false;
+               }
+       }
+       
+       public void setUserAlertManager(UserAlertManager userAlertManager) {
+               if (cleanerStatusUserAlert != null)
+                       userAlertManager.register(cleanerStatusUserAlert);
+               // TODO change useralertmanager? is this a valid case?
+               this.userAlertManager = userAlertManager;
+       }
+
+       public void setMaxKeys(long newStoreSize, boolean shrinkNow) throws 
IOException {
+               Logger.normal(this, "[" + name + "] Resize newStoreSize=" + 
newStoreSize + ", shinkNow=" + shrinkNow);
+
+               configLock.writeLock().lock();
+               try {
+                       if (newStoreSize == this.storeSize)
+                               return;
+
+                       if (prevStoreSize != 0) {
+                               Logger.normal(this, "[" + name + "] resize 
already in progress, ignore resize request");
+                               return;
+                       }
+
+                       prevStoreSize = storeSize;
+                       storeSize = newStoreSize;
+                       writeConfigFile();
+               } finally {
+                       configLock.writeLock().unlock();
+               }
+
+               if (cleanerLock.tryLock()) {
+                       cleanerCondition.signal();
+                       cleanerLock.unlock();
+               }
+       }
+
+       // ------------- Locking
+       volatile boolean shutdown = false;
+       private LockManager lockManager;
+       private ReadWriteLock configLock = new ReentrantReadWriteLock();
+
+       /**
+        * Lock all possible offsets of a key. This method would release the 
locks if any locking
+        * operation failed.
+        * 
+        * @param plainKey
+        * @return <code>true</code> if all the offsets are locked.
+        */
+       private Map<Long, Condition> lockPlainKey(byte[] plainKey, boolean 
usePrevStoreSize) {
+               return lockDigestedKey(cipherManager.getDigestedKey(plainKey), 
usePrevStoreSize);
+       }
+
+       private void unlockPlainKey(byte[] plainKey, boolean usePrevStoreSize, 
Map<Long, Condition> lockMap) {
+               unlockDigestedKey(cipherManager.getDigestedKey(plainKey), 
usePrevStoreSize, lockMap);
+       }
+
+       /**
+        * Lock all possible offsets of a key. This method would release the 
locks if any locking
+        * operation failed.
+        * 
+        * @param digestedKey
+        * @return <code>true</code> if all the offsets are locked.
+        */
+       private Map<Long, Condition> lockDigestedKey(byte[] digestedKey, 
boolean usePrevStoreSize) {
+               // use a set to prevent duplicated offsets,
+               // a sorted set to prevent deadlocks
+               SortedSet<Long> offsets = new TreeSet<Long>();
+               long[] offsetArray = getOffsetFromDigestedKey(digestedKey, 
storeSize);
+               for (long offset : offsetArray)
+                       offsets.add(offset);
+               if (usePrevStoreSize && prevStoreSize != 0) {
+                       offsetArray = getOffsetFromDigestedKey(digestedKey, 
prevStoreSize);
+                       for (long offset : offsetArray)
+                               offsets.add(offset);
+               }
+
+               Map<Long, Condition> locked = new TreeMap<Long, Condition>();
+               for (long offset : offsets) {
+                       Condition condition = lockManager.lockEntry(offset);
+                       if (condition == null)
+                               break;
+                       locked.put(offset, condition);
+               }
+
+               if (locked.size() == offsets.size()) {
+                       return locked;
+               } else {
+                       // failed, remove the locks
+                       for (Map.Entry<Long, Condition> e : locked.entrySet())
+                               lockManager.unlockEntry(e.getKey(), 
e.getValue());
+                       return null;
+               }
+       }
+
+       private void unlockDigestedKey(byte[] digestedKey, boolean 
usePrevStoreSize, Map<Long, Condition> lockMap) {
+               // use a set to prevent duplicated offsets
+               SortedSet<Long> offsets = new TreeSet<Long>();
+               long[] offsetArray = getOffsetFromDigestedKey(digestedKey, 
storeSize);
+               for (long offset : offsetArray)
+                       offsets.add(offset);
+               if (usePrevStoreSize && prevStoreSize != 0) {
+                       offsetArray = getOffsetFromDigestedKey(digestedKey, 
prevStoreSize);
+                       for (long offset : offsetArray)
+                               offsets.add(offset);
+               }
+
+               for (long offset : offsets) {
+                       lockManager.unlockEntry(offset, lockMap.get(offset));
+                       lockMap.remove(offset);
+               }
+       }
+
+       public class ShutdownDB implements Runnable {
+               public void run() {
+                       shutdown = true;
+                       lockManager.shutdown();
+
+                       cleanerLock.lock();
+                       try {
+                               cleanerCondition.signalAll();
+                               cleanerThread.interrupt();
+                       } finally {
+                               cleanerLock.unlock();
+                       }
+
+                       configLock.writeLock().lock();
+                       try {
+                               flushAndClose();
+                               flags &= ~FLAG_DIRTY; // clean shutdown
+                               writeConfigFile();
+                       } finally {
+                               configLock.writeLock().unlock();
+                       }
+               }
+       }
+
+       // ------------- Hashing
+       private CipherManager cipherManager;
+
+       /**
+        * Get offset in the hash table, given a plain routing key.
+        * 
+        * @param plainKey
+        * @param storeSize
+        * @return
+        */
+       private long[] getOffsetFromPlainKey(byte[] plainKey, long storeSize) {
+               return 
getOffsetFromDigestedKey(cipherManager.getDigestedKey(plainKey), storeSize);
+       }
+
+       /**
+        * Get offset in the hash table, given a digested routing key.
+        * 
+        * @param digestedKey
+        * @param storeSize
+        * @return
+        */
+       private long[] getOffsetFromDigestedKey(byte[] digestedKey, long 
storeSize) {
+               long keyValue = Fields.bytesToLong(digestedKey);
+               long[] offsets = new long[OPTION_MAX_PROBE];
+
+               for (int i = 0; i < OPTION_MAX_PROBE; i++) {
+                       // h + 141 i^2 + 13 i
+                       offsets[i] = ((keyValue + 141 * (i * i) + 13 * i) & 
Long.MAX_VALUE) % storeSize;
+               }
+
+               return offsets;
+       }
+
+       // ------------- Statistics (a.k.a. lies)
+       private AtomicLong hits = new AtomicLong();
+       private AtomicLong misses = new AtomicLong();
+       private AtomicLong writes = new AtomicLong();
+       private AtomicLong keyCount = new AtomicLong();
+       private AtomicLong bloomFalsePos = new AtomicLong();
+
+       public long hits() {
+               return hits.get();
+       }
+
+       public long misses() {
+               return misses.get();
+       }
+
+       public long writes() {
+               return writes.get();
+       }
+
+       public long keyCount() {
+               return keyCount.get();
+       }
+
+       public long getMaxKeys() {
+               configLock.readLock().lock();
+               long _storeSize = storeSize;
+               configLock.readLock().unlock();
+               return _storeSize;
+       }
+
+       public long getBloomFalsePositive() {
+               return bloomFalsePos.get();
+       }
+
+       // ------------- Migration
+       public void migrationFrom(File storeFile, File keyFile) {
+               try {
+                       System.out.println("Migrating from " + storeFile);
+
+                       RandomAccessFile storeRAF = new 
RandomAccessFile(storeFile, "r");
+                       RandomAccessFile keyRAF = keyFile.exists() ? new 
RandomAccessFile(keyFile, "r") : null;
+
+                       byte[] header = new byte[headerBlockLength];
+                       byte[] data = new byte[dataBlockLength];
+                       byte[] key = new byte[fullKeyLength];
+
+                       long maxKey = storeRAF.length() / (headerBlockLength + 
dataBlockLength);
+
+                       for (int l = 0; l < maxKey; l++) {
+                               if (l % 1024 == 0) {
+                                       System.out.println(" migrating key " + 
l + "/" + maxKey);
+                                       WrapperManager.signalStarting(10 * 60 * 
1000); // max 10 minutes for every 1024 keys  
+                               }
+
+                               boolean keyRead = false;
+                               storeRAF.readFully(header);
+                               storeRAF.readFully(data);
+                               try {
+                                       if (keyRAF != null) {
+                                               keyRAF.readFully(key);
+                                               keyRead = true;
+                                       }
+                               } catch (IOException e) {
+                               }
+
+                               try {
+                                       StorableBlock b = 
callback.construct(data, header, null, keyRead ? key : null);
+                                       put(b, b.getRoutingKey(), 
b.getFullKey(), data, header, true);
+                               } catch (KeyVerifyException e) {
+                                       System.out.println("kve at block " + l);
+                               } catch (KeyCollisionException e) {
+                                       System.out.println("kce at block " + l);
+                               }
+                       }
+               } catch (EOFException eof) {
+                       // done
+               } catch (IOException e) {
+                       e.printStackTrace();
+               }
+       }
+
+       public boolean probablyInStore(byte[] routingKey) {
+               configLock.readLock().lock();
+               try {
+                       if (!checkBloom)
+                               return true;
+                       return 
bloomFilter.checkFilter(cipherManager.getDigestedKey(routingKey));
+               } finally {
+                       configLock.readLock().unlock();
+               }
+    }
+}

Modified: branches/db4o/freenet/src/freenet/support/BinaryBloomFilter.java
===================================================================
--- branches/db4o/freenet/src/freenet/support/BinaryBloomFilter.java    
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/support/BinaryBloomFilter.java    
2008-09-24 23:54:07 UTC (rev 22829)
@@ -21,7 +21,7 @@
         */
        protected BinaryBloomFilter(int length, int k) {
                super(length, k);
-               filter = ByteBuffer.allocate(length / 8);
+               filter = ByteBuffer.allocate(this.length / 8);
        }

        /**

Modified: branches/db4o/freenet/src/freenet/support/BitArray.java
===================================================================
--- branches/db4o/freenet/src/freenet/support/BitArray.java     2008-09-24 
23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/support/BitArray.java     2008-09-24 
23:54:07 UTC (rev 22829)
@@ -86,7 +86,7 @@
        }

        public String toString() {
-               StringBuffer sb = new StringBuffer(this._size);
+               StringBuilder sb = new StringBuilder(this._size);
                for (int x=0; x<_size; x++) {
                        if (bitAt(x)) {
                                sb.append('1');

Modified: branches/db4o/freenet/src/freenet/support/BloomFilter.java
===================================================================
--- branches/db4o/freenet/src/freenet/support/BloomFilter.java  2008-09-24 
23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/support/BloomFilter.java  2008-09-24 
23:54:07 UTC (rev 22829)
@@ -19,6 +19,15 @@

        protected ReadWriteLock lock = new ReentrantReadWriteLock();

+       public static BloomFilter createFilter(int length, int k, boolean 
counting) {
+               if (k == 0 || length == 0)
+                       return new NullBloomFilter(length, k);
+               if (counting)
+                       return new CountingBloomFilter(length, k);
+               else
+                       return new BinaryBloomFilter(length, k);
+       }
+       
        public static BloomFilter createFilter(File file, int length, int k, 
boolean counting) throws IOException {
                if (k == 0 || length == 0)
                        return new NullBloomFilter(length, k);
@@ -30,7 +39,7 @@

        protected BloomFilter(int length, int k) {
                if (length % 8 != 0)
-                       throw new IllegalArgumentException();
+                       length -= length % 8;

                this.length = length;
                this.k = k;

Modified: branches/db4o/freenet/src/freenet/support/Buffer.java
===================================================================
--- branches/db4o/freenet/src/freenet/support/Buffer.java       2008-09-24 
23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/support/Buffer.java       2008-09-24 
23:54:07 UTC (rev 22829)
@@ -114,7 +114,7 @@
                if (this._length > 50) {
                        return "Buffer {"+this._length+ '}';
                } else {
-                       StringBuffer b = new StringBuffer(this._length*3);
+                       StringBuilder b = new StringBuilder(this._length*3);
             b.append('{').append(this._length).append(':');
                        for (int x=0; x<this._length; x++) {
                                b.append(byteAt(x));

Modified: branches/db4o/freenet/src/freenet/support/CPUInformation/CPUID.java
===================================================================
--- branches/db4o/freenet/src/freenet/support/CPUInformation/CPUID.java 
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/support/CPUInformation/CPUID.java 
2008-09-24 23:54:07 UTC (rev 22829)
@@ -68,7 +68,7 @@
        private static String getCPUVendorID()
        {
                CPUIDResult c = doCPUID(0);
-               StringBuffer sb= new StringBuffer(13);
+               StringBuilder sb= new StringBuilder(13);
                sb.append((char)( c.EBX        & 0xFF));
                sb.append((char)((c.EBX >> 8)  & 0xFF));
                sb.append((char)((c.EBX >> 16) & 0xFF));

Modified: branches/db4o/freenet/src/freenet/support/CountingBloomFilter.java
===================================================================
--- branches/db4o/freenet/src/freenet/support/CountingBloomFilter.java  
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/support/CountingBloomFilter.java  
2008-09-24 23:54:07 UTC (rev 22829)
@@ -28,7 +28,7 @@
         */
        public CountingBloomFilter(int length, int k) {
                super(length, k);
-               filter = ByteBuffer.allocate(length / 8 * 2);
+               filter = ByteBuffer.allocate(this.length / 4);
        }

        /**
@@ -42,7 +42,7 @@
         */
        protected CountingBloomFilter(File file, int length, int k) throws 
IOException {
                super(length, k);
-               int fileLength = length / 8 * 2;
+               int fileLength = length / 4;
                if (!file.exists() || file.length() != fileLength)
                        needRebuild = true;


Modified: branches/db4o/freenet/src/freenet/support/Fields.java
===================================================================
--- branches/db4o/freenet/src/freenet/support/Fields.java       2008-09-24 
23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/support/Fields.java       2008-09-24 
23:54:07 UTC (rev 22829)
@@ -396,13 +396,8 @@
        /**
         * Compares byte arrays lexicographically.
         */
-       public static final class ByteArrayComparator implements Comparator {
-
-               public final int compare(Object o1, Object o2) {
-                       return compare((byte[]) o1, (byte[]) o2);
-               }
-
-               public static final int compare(byte[] o1, byte[] o2) {
+       public static final class ByteArrayComparator implements 
Comparator<byte[]> {
+               public final int compare(byte[] o1, byte[] o2) {
                        return compareBytes(o1, o2);
                }
        }
@@ -538,7 +533,7 @@
                for(int i = 0; i < ints.length; i++) {
                        int x = 0;
                        for(int j = 3; j >= 0; j--) {
-                               int y = (buf[j + offset] & 0xff);
+                               int y = (buf[j + offset + i * 4] & 0xff);
                                x = (x << 8) | y;
                        }
                        ints[i] = x;
@@ -560,7 +555,7 @@
        }

        public static byte[] intsToBytes(int[] ints) {
-               byte[] buf = new byte[ints.length * 8];
+               byte[] buf = new byte[ints.length * 4];
                for(int i = 0; i < ints.length; i++) {
                        long x = ints[i];
                        for(int j = 0; j < 4; j++) {
@@ -570,7 +565,16 @@
                }
                return buf;
        }
-
+       
+       public static byte[] intToBytes(int x) {
+               byte[] buf = new byte[4];
+                       for(int j = 0; j < 4; j++) {
+                               buf[j] = (byte) x;
+                               x >>>= 8;
+                       }
+               return buf;
+       }
+       
        public static long parseLong(String s, long defaultValue) {
                try {
                        return Long.parseLong(s);

Modified: branches/db4o/freenet/src/freenet/support/HTMLDecoder.java
===================================================================
--- branches/db4o/freenet/src/freenet/support/HTMLDecoder.java  2008-09-24 
23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/support/HTMLDecoder.java  2008-09-24 
23:54:07 UTC (rev 22829)
@@ -14,7 +14,7 @@
  */
 public class HTMLDecoder {

-       static Map charTable = HTMLEntities.decodeMap;
+       static Map<String, Character> charTable = HTMLEntities.decodeMap;

        public static String decode(String s) {
                String t;
@@ -22,7 +22,7 @@
                int tmpPos, i;

                int maxPos = s.length();
-               StringBuffer sb = new StringBuffer(maxPos);
+               StringBuilder sb = new StringBuilder(maxPos);
                int curPos = 0;
                while (curPos < maxPos) {
                        char c = s.charAt(curPos++);
@@ -92,7 +92,7 @@
                                                        if 
(!isLetterOrDigit(d)) {
                                                                if (d == ';') {
                                                                        t = 
s.substring(curPos, tmpPos - 1);
-                                                                       ch = 
(Character) charTable.get(t);
+                                                                       ch = 
charTable.get(t);
                                                                        if (ch 
!= null) {
                                                                                
c = ch.charValue();
                                                                                
curPos = tmpPos;
@@ -131,7 +131,7 @@

        public static String compact(String s) {
                int maxPos = s.length();
-               StringBuffer sb = new StringBuffer(maxPos);
+               StringBuilder sb = new StringBuilder(maxPos);
                int curPos = 0;
                while (curPos < maxPos) {
                        char c = s.charAt(curPos++);

Modified: branches/db4o/freenet/src/freenet/support/HTMLEncoder.java
===================================================================
--- branches/db4o/freenet/src/freenet/support/HTMLEncoder.java  2008-09-24 
23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/support/HTMLEncoder.java  2008-09-24 
23:54:07 UTC (rev 22829)
@@ -4,7 +4,6 @@
 package freenet.support;

 import java.util.HashMap;
-import java.util.Iterator;

 /**
  * Originally from com.websiteasp.ox pasckage.
@@ -53,9 +52,9 @@
                        int keyIndex = 0;

                        int max = 0;
-                       for(Iterator it = map.keySet().iterator();it.hasNext(); 
keyIndex++){
-                               int val = (int) 
((Character)it.next()).charValue();
-                               keys[keyIndex] = val;
+                       for (Character key : map.keySet()) {
+                               int val = key.charValue();
+                               keys[keyIndex++] = val;
                                if(val > max) max = val;
                        }

@@ -79,9 +78,7 @@

                        chars = new char[modulo];
                        strings = new String[modulo];
-                       Character character;
-                       for(Iterator it = map.keySet().iterator();it.hasNext(); 
keyIndex++){
-                               character = ((Character)it.next());
+                       for (Character character : map.keySet()) {
                                keyIndex = character.charValue()%modulo;
                                chars[keyIndex] = character.charValue();
                                strings[keyIndex] = map.get(character);

Modified: branches/db4o/freenet/src/freenet/support/HTMLEntities.java
===================================================================
--- branches/db4o/freenet/src/freenet/support/HTMLEntities.java 2008-09-24 
23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/support/HTMLEntities.java 2008-09-24 
23:54:07 UTC (rev 22829)
@@ -17,28 +17,22 @@

 import java.util.HashMap;

-
 /**
- * Class that provides data structures filled with
- * HTML Entities and correspondant char value
+ * Class that provides data structures filled with HTML Entities and 
correspondent char value
  * 
  * @author Alberto Bacchelli &lt;sback at freenetproject.org&gt;
  */
 public final class HTMLEntities {
-       
+
        /**
-        * a Map where the HTML Entity is the
-        * value and the correspondant char is
-        * the key
+        * a Map where the HTML Entity is the value and the correspondent char 
is the key
         */
-       public static final HashMap encodeMap;
-       
+       public static final HashMap<Character, String> encodeMap;
+
        /**
-        * a Map where the HTML Entity is the
-        * key and the correspondant char is
-        * the value
+        * a Map where the HTML Entity is the key and the correspondent char is 
the value
         */
-       public static final HashMap decodeMap;
+       public static final HashMap<String, Character> decodeMap;

        private static final Object[][] charArray = {
                {new Character((char)0), "#0"},
@@ -315,12 +309,12 @@


        static {
-               encodeMap = new HashMap();
-               decodeMap = new HashMap();
+               encodeMap = new HashMap<Character, String>();
+               decodeMap = new HashMap<String, Character>();

                for(int i=0; i<charArray.length; i++) {
-                       encodeMap.put(charArray[i][0],charArray[i][1]);
-                       decodeMap.put(charArray[i][1],charArray[i][0]);
+                       encodeMap.put((Character) charArray[i][0], (String) 
charArray[i][1]);
+                       decodeMap.put((String) charArray[i][1], (Character) 
charArray[i][0]);
                }

        }

Modified: branches/db4o/freenet/src/freenet/support/HTMLNode.java
===================================================================
--- branches/db4o/freenet/src/freenet/support/HTMLNode.java     2008-09-24 
23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/support/HTMLNode.java     2008-09-24 
23:54:07 UTC (rev 22829)
@@ -3,7 +3,6 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
@@ -177,11 +176,10 @@
                        return tagBuffer;
                }
                tagBuffer.append('<').append(name);
-               Set attributeSet = attributes.entrySet();
-               for (Iterator attributeIterator = attributeSet.iterator(); 
attributeIterator.hasNext();) {
-                       Map.Entry attributeEntry = (Map.Entry) 
attributeIterator.next();
-                       String attributeName = (String) attributeEntry.getKey();
-                       String attributeValue = (String) 
attributeEntry.getValue();
+               Set<Map.Entry<String, String>> attributeSet = 
attributes.entrySet();
+               for (Map.Entry<String, String> attributeEntry : attributeSet) {
+                       String attributeName = attributeEntry.getKey();
+                       String attributeValue = attributeEntry.getValue();
                        tagBuffer.append(' ');
                        HTMLEncoder.encodeToBuffer(attributeName, tagBuffer);
                        tagBuffer.append("=\"");
@@ -236,7 +234,7 @@
                }

                /**
-                * @see 
freenet.support.HTMLNode#generate(java.lang.StringBuffer)
+                * @see 
freenet.support.HTMLNode#generate(java.lang.StringBuilder)
                 */
                @Override
                public StringBuilder generate(StringBuilder tagBuffer) {

Modified: branches/db4o/freenet/src/freenet/support/HexUtil.java
===================================================================
--- branches/db4o/freenet/src/freenet/support/HexUtil.java      2008-09-24 
23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/support/HexUtil.java      2008-09-24 
23:54:07 UTC (rev 22829)
@@ -34,7 +34,7 @@
        public static final String bytesToHex(byte[] bs, int off, int length) {
                if (bs.length <= off || bs.length < off+length)
                        throw new IllegalArgumentException();
-               StringBuffer sb = new StringBuffer(length * 2);
+               StringBuilder sb = new StringBuilder(length * 2);
                bytesToHexAppend(bs, off, length, sb);
                return sb.toString();
        }
@@ -43,7 +43,7 @@
                byte[] bs,
                int off,
                int length,
-               StringBuffer sb) {
+               StringBuilder sb) {
                if (bs.length <= off || bs.length < off+length)
                        throw new IllegalArgumentException();
                sb.ensureCapacity(sb.length() + length * 2);
@@ -117,8 +117,8 @@
        public final static byte[] bitsToBytes(BitSet ba, int size) {
                int bytesAlloc = countBytesForBits(size);
                byte[] b = new byte[bytesAlloc];
-               StringBuffer sb =null;
-               if(logDEBUG) sb = new StringBuffer(8*bytesAlloc); //TODO: 
Should it be 2*8*bytesAlloc here?
+               StringBuilder sb =null;
+               if(logDEBUG) sb = new StringBuilder(8*bytesAlloc); //TODO: 
Should it be 2*8*bytesAlloc here?
                for(int i=0;i<b.length;i++) {
                        short s = 0;
                        for(int j=0;j<8;j++) {

Deleted: 
branches/db4o/freenet/src/freenet/support/ImmutableByteArrayWrapper.java
===================================================================
--- branches/db4o/freenet/src/freenet/support/ImmutableByteArrayWrapper.java    
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/support/ImmutableByteArrayWrapper.java    
2008-09-24 23:54:07 UTC (rev 22829)
@@ -1,30 +0,0 @@
-/**
- * 
- */
-package freenet.support;
-
-import java.util.Arrays;
-
-public class ImmutableByteArrayWrapper {
-       final byte[] data;
-       final int hashCode;
-       
-       public ImmutableByteArrayWrapper(byte[] data) {
-               this.data = data;
-               hashCode = Fields.hashCode(data);
-       }
-
-       public boolean equals(Object o) {
-               if(o instanceof ImmutableByteArrayWrapper) {
-                       ImmutableByteArrayWrapper w = 
(ImmutableByteArrayWrapper) o;
-                       if((w.hashCode == hashCode) &&
-                                       Arrays.equals(data, w.data))
-                               return true;
-               }
-               return false;
-       }
-       
-       public int hashCode() {
-               return hashCode;
-       }
-}
\ No newline at end of file

Modified: branches/db4o/freenet/src/freenet/support/JarClassLoader.java
===================================================================
--- branches/db4o/freenet/src/freenet/support/JarClassLoader.java       
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/support/JarClassLoader.java       
2008-09-24 23:54:07 UTC (rev 22829)
@@ -114,7 +114,7 @@
         * 
         * @see java.lang.ClassLoader#findClass(java.lang.String)
         */
-       protected Class findClass(String name) throws ClassNotFoundException {
+       protected Class<?> findClass(String name) throws ClassNotFoundException 
{
                try {
                        String pathName = transformName(name);
                        JarEntry jarEntry = tempJarFile.getJarEntry(pathName);
@@ -126,7 +126,7 @@
                                classBytesOutputStream.close();
                                jarEntryInputStream.close();
                                byte[] classBytes = 
classBytesOutputStream.toByteArray();
-                               Class clazz = defineClass(name, classBytes, 0, 
classBytes.length);
+                               Class<?> clazz = defineClass(name, classBytes, 
0, classBytes.length);
                                return clazz;
                        }
                        throw new ClassNotFoundException("could not find jar 
entry for class " + name);

Modified: branches/db4o/freenet/src/freenet/support/LimitedEnumeration.java
===================================================================
--- branches/db4o/freenet/src/freenet/support/LimitedEnumeration.java   
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/support/LimitedEnumeration.java   
2008-09-24 23:54:07 UTC (rev 22829)
@@ -6,15 +6,14 @@
 /** We kept remaking this everywhere so wtf.
   * @author tavin
   */
-public final class LimitedEnumeration implements Enumeration {
-
-    private Object next;
+public final class LimitedEnumeration<T> implements Enumeration<T> {
+       private T next;

     public LimitedEnumeration() {
         next = null;
     }

-    public LimitedEnumeration(Object loner) {
+    public LimitedEnumeration(T loner) {
         next = loner;
     }

@@ -22,7 +21,7 @@
         return next != null;
     }

-    public final Object nextElement() {
+    public final T nextElement() {
         if (next == null) throw new NoSuchElementException();
         try {
             return next;

Modified: 
branches/db4o/freenet/src/freenet/support/LimitedRangeIntByteArrayMap.java
===================================================================
--- branches/db4o/freenet/src/freenet/support/LimitedRangeIntByteArrayMap.java  
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/support/LimitedRangeIntByteArrayMap.java  
2008-09-24 23:54:07 UTC (rev 22829)
@@ -104,9 +104,10 @@
             minValue = index;
         }
         if(data == null) throw new NullPointerException();
-        LimitedRangeIntByteArrayMapElement le = contents.get(index);
+        Integer idx = index;
+               LimitedRangeIntByteArrayMapElement le = contents.get(idx);
         if(le == null)
-               contents.put(index, new 
LimitedRangeIntByteArrayMapElement(index, data, callbacks, priority));
+               contents.put(idx, new LimitedRangeIntByteArrayMapElement(idx, 
data, callbacks, priority));
         else
                le.reput();
         notifyAll();
@@ -206,10 +207,9 @@
     public synchronized byte[][] grabAllBytes() {
         int len = contents.size();
         byte[][] output = new byte[len][];
-        Iterator i = contents.values().iterator();
         int count = 0;
-        while(i.hasNext()) {
-            output[count++] = (byte[])i.next();
+        for (LimitedRangeIntByteArrayMapElement o : contents.values()) {
+                       output[count++] = o.data;
         }
         clear();
         return output;
@@ -218,10 +218,10 @@
     public synchronized LimitedRangeIntByteArrayMapElement[] grabAll() {
         int len = contents.size();
         LimitedRangeIntByteArrayMapElement[] output = new 
LimitedRangeIntByteArrayMapElement[len];
-        Iterator i = contents.values().iterator();
+        Iterator<LimitedRangeIntByteArrayMapElement> i = 
contents.values().iterator();
         int count = 0;
         while(i.hasNext()) {
-            output[count++] = (LimitedRangeIntByteArrayMapElement)i.next();
+            output[count++] = i.next();
         }
         clear();
         return output;

Modified: branches/db4o/freenet/src/freenet/support/Loader.java
===================================================================
--- branches/db4o/freenet/src/freenet/support/Loader.java       2008-09-24 
23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/support/Loader.java       2008-09-24 
23:54:07 UTC (rev 22829)
@@ -10,15 +10,15 @@

 public class Loader {

-    static final private Hashtable classes=new Hashtable();
+    static final private Hashtable<String, Class<?>> classes = new 
Hashtable<String, Class<?>>();
     //  static final public String prefix="freenet.message.";

     /**
      * This is a caching Class loader.
      * @param name The name of the class to load.
      **/
-    static public Class load(String name) throws ClassNotFoundException {
-       Class c=(Class)classes.get(name);
+    static public Class<?> load(String name) throws ClassNotFoundException {
+               Class<?> c = classes.get(name);
        if(c==null) {
            c=Class.forName(name);
            classes.put(name, c);
@@ -45,7 +45,7 @@
      * @param args       The arguments. Since this uses the reflect methods
      *                   it's ok to wrap primitives.
      **/
-    public static Object getInstance(String classname, Class[] argtypes, 
+    public static Object getInstance(String classname, Class<?>[] argtypes, 
                                     Object[] args) 
        throws InvocationTargetException, NoSuchMethodException, 
               InstantiationException, IllegalAccessException,
@@ -60,11 +60,11 @@
      * @param args       The arguments. Since this uses the reflect methods
      *                   it's ok to wrap primitives.
      **/
-    public static Object getInstance(Class c, Class[] argtypes, 
+    public static Object getInstance(Class<?> c, Class<?>[] argtypes, 
                                     Object[] args) 
        throws InvocationTargetException, NoSuchMethodException, 
               InstantiationException, IllegalAccessException {
-       Constructor con = c.getConstructor(argtypes);
+       Constructor<?> con = c.getConstructor(argtypes);
        return con.newInstance(args);
     }
 }

Modified: branches/db4o/freenet/src/freenet/support/LoggerHook.java
===================================================================
--- branches/db4o/freenet/src/freenet/support/LoggerHook.java   2008-09-24 
23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/support/LoggerHook.java   2008-09-24 
23:54:07 UTC (rev 22829)
@@ -2,7 +2,6 @@

 import java.util.ArrayList;
 import java.util.StringTokenizer;
-import java.util.Vector;

 import freenet.l10n.L10n;


Modified: branches/db4o/freenet/src/freenet/support/LoggerHookChain.java
===================================================================
--- branches/db4o/freenet/src/freenet/support/LoggerHookChain.java      
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/support/LoggerHookChain.java      
2008-09-24 23:54:07 UTC (rev 22829)
@@ -38,7 +38,7 @@
      * one logger receive events from another.
      * @implements LoggerHook.log()
      */
-    public synchronized void log(Object o, Class c, String msg, Throwable e, 
int priority){
+    public synchronized void log(Object o, Class<?> c, String msg, Throwable 
e, int priority) {
         LoggerHook[] myHooks = hooks;
         for(int i=0;i<myHooks.length;i++) {
             myHooks[i].log(o,c,msg,e,priority);

Modified: branches/db4o/freenet/src/freenet/support/NumberedItemComparator.java
===================================================================
--- branches/db4o/freenet/src/freenet/support/NumberedItemComparator.java       
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/support/NumberedItemComparator.java       
2008-09-24 23:54:07 UTC (rev 22829)
@@ -2,7 +2,7 @@

 import java.util.Comparator;

-public class NumberedItemComparator implements Comparator {
+public class NumberedItemComparator implements Comparator<Object> {

        public NumberedItemComparator(boolean wrap) {
                this.wrapAround = wrap;

Modified: branches/db4o/freenet/src/freenet/support/NumberedRecentItems.java
===================================================================
--- branches/db4o/freenet/src/freenet/support/NumberedRecentItems.java  
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/support/NumberedRecentItems.java  
2008-09-24 23:54:07 UTC (rev 22829)
@@ -14,7 +14,7 @@

     private NumberedItem[] items;
     private int count;
-    private Comparator myComparator;
+    private Comparator<Object> myComparator;
     /**
      * Create a NumberedRecentItems list.
      * @param maxSize The maximum number of NumberedItems to keep.

Modified: branches/db4o/freenet/src/freenet/support/PooledExecutor.java
===================================================================
--- branches/db4o/freenet/src/freenet/support/PooledExecutor.java       
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/support/PooledExecutor.java       
2008-09-24 23:54:07 UTC (rev 22829)
@@ -3,10 +3,11 @@
  * http://www.gnu.org/ for further details of the GPL. */
 package freenet.support;

+import java.util.ArrayList;
+
 import freenet.node.PrioRunnable;
 import freenet.node.Ticker;
 import freenet.support.io.NativeThread;
-import java.util.ArrayList;

 /**
  * Pooled Executor implementation. Create a thread when we need one, let them 
die
@@ -16,8 +17,10 @@
 public class PooledExecutor implements Executor {

        /** All threads running or waiting */
+       @SuppressWarnings("unchecked")
        private final ArrayList<MyThread>[] runningThreads = new 
ArrayList[NativeThread.JAVA_PRIORITY_RANGE + 1];
        /** Threads waiting for a job */
+       @SuppressWarnings("unchecked")
        private final ArrayList<MyThread>[] waitingThreads = new 
ArrayList[runningThreads.length];
        long[] threadCounter = new long[runningThreads.length];
        private long jobCount;
@@ -32,8 +35,8 @@

        public PooledExecutor() {
                for(int i = 0; i < runningThreads.length; i++) {
-                       runningThreads[i] = new ArrayList();
-                       waitingThreads[i] = new ArrayList();
+                       runningThreads[i] = new ArrayList<MyThread>();
+                       waitingThreads[i] = new ArrayList<MyThread>();
                        threadCounter[i] = 0;
                }
        }

Modified: branches/db4o/freenet/src/freenet/support/ReceivedPacketNumbers.java
===================================================================
--- branches/db4o/freenet/src/freenet/support/ReceivedPacketNumbers.java        
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/support/ReceivedPacketNumbers.java        
2008-09-24 23:54:07 UTC (rev 22829)
@@ -15,13 +15,13 @@
  */
 public class ReceivedPacketNumbers {

-    final LinkedList ranges;
+    final LinkedList<Range> ranges;
     int lowestSeqNumber;
     int highestSeqNumber;
     final int horizon;

     public ReceivedPacketNumbers(int horizon) {
-        ranges = new LinkedList();
+        ranges = new LinkedList<Range>();
         lowestSeqNumber = -1;
         highestSeqNumber = -1;
         this.horizon = horizon;
@@ -56,20 +56,20 @@
             ranges.addFirst(r);
             return true;
         } else {
-            ListIterator li = ranges.listIterator();
-            Range r = (Range)li.next();
+            ListIterator<Range> li = ranges.listIterator();
+                       Range r = li.next();
             int firstSeq = r.end;
             if(seqNumber - firstSeq > horizon) {
                 // Delete first item
                 li.remove();
-                r = (Range)li.next();
+                r = li.next();
                 lowestSeqNumber = r.start;
             }
             while(true) {
                 if(seqNumber == r.start-1) {
                     r.start--;
                     if(li.hasPrevious()) {
-                        Range r1 = (Range) li.previous();
+                        Range r1 = li.previous();
                         if(r1.end == seqNumber-1) {
                             r.start = r1.start;
                             li.remove();
@@ -99,7 +99,7 @@
                 if(seqNumber == r.end+1) {
                     r.end++;
                     if(li.hasNext()) {
-                        Range r1 = (Range) li.next();
+                        Range r1 = li.next();
                         if(r1.start == seqNumber+1) {
                             r.end = r1.end;
                             li.remove();
@@ -118,7 +118,7 @@
                         return true;
                     }
                 }
-                r = (Range) li.next();
+                r = li.next();
             }
         }
     }
@@ -137,10 +137,10 @@
             return true;
         if(highestSeqNumber - seqNumber > horizon)
             return true; // Assume we have since out of window
-        Iterator i = ranges.iterator();
+        Iterator<Range> i = ranges.iterator();
         Range last = null;
         for(;i.hasNext();) {
-            Range r = (Range)i.next();
+            Range r = i.next();
             if(r.start > r.end) {
                 Logger.error(this, "Bad Range: "+r);
             }
@@ -161,7 +161,7 @@
     }

     public String toString() {
-        StringBuffer sb = new StringBuffer();
+        StringBuilder sb = new StringBuilder();
         sb.append(super.toString());
         sb.append(": max=");
         synchronized(this) {
@@ -169,9 +169,9 @@
                        sb.append(", min=");
                        sb.append(lowestSeqNumber);
                        sb.append(", ranges=");
-            Iterator i = ranges.iterator();
+            Iterator<Range> i = ranges.iterator();
             while(i.hasNext()) {
-                Range r = (Range) i.next();
+                Range r = i.next();
                 sb.append(r.start);
                 sb.append('-');
                 sb.append(r.end);

Modified: branches/db4o/freenet/src/freenet/support/SerialExecutor.java
===================================================================
--- branches/db4o/freenet/src/freenet/support/SerialExecutor.java       
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/support/SerialExecutor.java       
2008-09-24 23:54:07 UTC (rev 22829)
@@ -7,7 +7,7 @@

 public class SerialExecutor implements Executor {

-       private final LinkedList jobs;
+       private final LinkedList<Runnable> jobs;
        private final int priority;
        private boolean waiting;

@@ -41,7 +41,7 @@
                                                        return;
                                                }
                                        }
-                                       job = (Runnable) jobs.removeFirst();
+                                       job = jobs.removeFirst();
                                }
                                try {
                                        job.run();
@@ -55,7 +55,7 @@
        };

        public SerialExecutor(int priority) {
-               jobs = new LinkedList();
+               jobs = new LinkedList<Runnable>();
                this.priority = priority;
        }


Modified: branches/db4o/freenet/src/freenet/support/Serializer.java
===================================================================
--- branches/db4o/freenet/src/freenet/support/Serializer.java   2008-09-24 
23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/support/Serializer.java   2008-09-24 
23:54:07 UTC (rev 22829)
@@ -22,7 +22,6 @@
 import java.io.DataInput;
 import java.io.DataOutputStream;
 import java.io.IOException;
-import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;

@@ -44,8 +43,8 @@
     public static final String VERSION = "$Id: Serializer.java,v 1.5 
2005/09/15 18:16:04 amphibian Exp $";
        public static final int MAX_BITARRAY_SIZE = 2048*8;

-       public static List readListFromDataInputStream(Class elementType, 
DataInput dis) throws IOException {
-               LinkedList ret = new LinkedList();
+       public static List<Object> readListFromDataInputStream(Class<?> 
elementType, DataInput dis) throws IOException {
+               LinkedList<Object> ret = new LinkedList<Object>();
                int length = dis.readInt();
                for (int x = 0; x < length; x++) {
                        ret.add(readFromDataInputStream(elementType, dis));
@@ -53,7 +52,7 @@
                return ret;
        }

-       public static Object readFromDataInputStream(Class type, DataInput dis) 
throws IOException {
+       public static Object readFromDataInputStream(Class<?> type, DataInput 
dis) throws IOException {
                if (type.equals(Boolean.class)) {
                        int bool = dis.readByte();
                        if (bool==1)
@@ -74,7 +73,7 @@
                    return dis.readDouble();
                } else if (type.equals(String.class)) {
                        int length = dis.readInt();
-                       StringBuffer sb = new StringBuffer(length);
+                       StringBuilder sb = new StringBuilder(length);
                        for (int x = 0; x < length; x++) {
                                sb.append(dis.readChar());
                        }
@@ -103,7 +102,7 @@
        }

        public static void writeToDataOutputStream(Object object, 
DataOutputStream dos, PeerContext ctx) throws IOException {   
-               Class type = object.getClass();
+               Class<?> type = object.getClass();
                if (type.equals(Long.class)) {
                        dos.writeLong(((Long) object).longValue());
                } else if (type.equals(Boolean.class)) {
@@ -124,11 +123,11 @@
                                dos.writeChar(s.charAt(x));
                        }
                } else if (type.equals(LinkedList.class)) {
-                       LinkedList ll = (LinkedList) object;
+                       LinkedList<?> ll = (LinkedList<?>) object;
                        dos.writeInt(ll.size());
                        synchronized (ll) {
-                               for (Iterator i = ll.iterator(); i.hasNext();) {
-                                       writeToDataOutputStream(i.next(), dos, 
ctx);
+                               for (Object o : ll) {
+                                       writeToDataOutputStream(o, dos, ctx);
                                }
                        }
                } else if (type.equals(Byte.class)) {

Modified: branches/db4o/freenet/src/freenet/support/ShortBuffer.java
===================================================================
--- branches/db4o/freenet/src/freenet/support/ShortBuffer.java  2008-09-24 
23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/support/ShortBuffer.java  2008-09-24 
23:54:07 UTC (rev 22829)
@@ -112,7 +112,7 @@
                if (this._length > 50) {
                        return "Buffer {"+this._length+ '}';
                } else {
-                       StringBuffer b = new StringBuffer(this._length*3);
+                       StringBuilder b = new StringBuilder(this._length*3);
             b.append('{').append(this._length).append(':');
                        for (int x=0; x<this._length; x++) {
                                b.append(byteAt(x));

Modified: branches/db4o/freenet/src/freenet/support/SimpleFieldSet.java
===================================================================
--- branches/db4o/freenet/src/freenet/support/SimpleFieldSet.java       
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/support/SimpleFieldSet.java       
2008-09-24 23:54:07 UTC (rev 22829)
@@ -1,13 +1,17 @@
 package freenet.support;

 import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
 import java.io.BufferedReader;
+import java.io.BufferedWriter;
 import java.io.EOFException;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
 import java.io.StringReader;
 import java.io.StringWriter;
 import java.io.UnsupportedEncodingException;
@@ -20,10 +24,6 @@
 import freenet.node.FSParseException;
 import freenet.support.io.Closer;
 import freenet.support.io.LineReader;
-import java.io.BufferedOutputStream;
-import java.io.BufferedWriter;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;

 /**
  * @author amphibian
@@ -224,17 +224,17 @@
      * Put contents of a fieldset, overwrite old values.
      */
     public void putAllOverwrite(SimpleFieldSet fs) {
-       Iterator i = fs.values.keySet().iterator();
+       Iterator<String> i = fs.values.keySet().iterator();
        while(i.hasNext()) {
-               String key = (String) i.next();
+               String key = i.next();
                String hisVal = fs.values.get(key);
                values.put(key, hisVal); // overwrite old
        }
        if(fs.subsets == null) return;
-       if(subsets == null) subsets = new HashMap();
+       if(subsets == null) subsets = new HashMap<String, SimpleFieldSet>();
        i = fs.subsets.keySet().iterator();
        while(i.hasNext()) {
-               String key = (String) i.next();
+               String key = i.next();
                SimpleFieldSet hisFS = fs.subsets.get(key);
                SimpleFieldSet myFS = subsets.get(key);
                if(myFS != null) {
@@ -308,7 +308,7 @@
                        String after = key.substring(idx+1);
                        SimpleFieldSet fs = null;
                        if(subsets == null)
-                               subsets = new HashMap();
+                               subsets = new HashMap<String, SimpleFieldSet>();
                        fs = subsets.get(before);
                        if(fs == null) {
                                fs = new SimpleFieldSet(shortLived);
@@ -365,10 +365,10 @@
      * @warning keep in mind that a Writer is not necessarily UTF-8!!
      */
     synchronized void writeTo(Writer w, String prefix, boolean noEndMarker) 
throws IOException {
-       for(Iterator i = values.entrySet().iterator();i.hasNext();) {
-            Map.Entry entry = (Map.Entry) i.next();
-            String key = (String) entry.getKey();
-            String value = (String) entry.getValue();
+       for (Iterator<Map.Entry<String, String>> i = 
values.entrySet().iterator(); i.hasNext();) {
+            Map.Entry<String, String> entry = i.next();
+                       String key = entry.getKey();
+                       String value = entry.getValue();
             w.write(prefix);
             w.write(key);
             w.write(KEYVALUE_SEPARATOR_CHAR);
@@ -376,10 +376,10 @@
             w.write('\n');
        }
        if(subsets != null) {
-               for(Iterator i = subsets.entrySet().iterator();i.hasNext();) {
-                       Map.Entry entry = (Map.Entry) i.next();
-                       String key = (String) entry.getKey();
-                       SimpleFieldSet subset = (SimpleFieldSet) 
entry.getValue();
+               for (Iterator<Map.Entry<String, SimpleFieldSet>> i = 
subsets.entrySet().iterator(); i.hasNext();) {
+                               Map.Entry<String, SimpleFieldSet> entry = 
i.next();
+                               String key = entry.getKey();
+                               SimpleFieldSet subset = entry.getValue();
                        if(subset == null) throw new NullPointerException();
                        subset.writeTo(w, prefix+key+MULTI_LEVEL_CHAR, true);
                }
@@ -480,7 +480,7 @@
                return fs;
        }

-       public Iterator keyIterator() {
+       public Iterator<String> keyIterator() {
                return new KeyIterator("");
        }

@@ -488,14 +488,13 @@
                return new KeyIterator(prefix);
        }

-        public Iterator toplevelKeyIterator() {
+        public Iterator<String> toplevelKeyIterator() {
             return values.keySet().iterator();
         }

-    public class KeyIterator implements Iterator {
-       
-       final Iterator valuesIterator;
-       final Iterator subsetIterator;
+    public class KeyIterator implements Iterator<String> {     
+       final Iterator<String> valuesIterator;
+       final Iterator<String> subsetIterator;
        KeyIterator subIterator;
        String prefix;

@@ -518,7 +517,7 @@
                        while(true) {
                                if(valuesIterator != null && 
valuesIterator.hasNext()) break;
                                if(subsetIterator == null || 
!subsetIterator.hasNext()) break;
-                               String name = (String) subsetIterator.next();
+                               String name = subsetIterator.next();
                                if(name == null) continue;
                                SimpleFieldSet fs = subsets.get(name);
                                if(fs == null) continue;
@@ -538,7 +537,7 @@
                                        if((subIterator != null) && 
subIterator.hasNext()) return true;
                                        if(subIterator != null) subIterator = 
null;
                                        if(subsetIterator != null && 
subsetIterator.hasNext()) {
-                                               String key = (String) 
subsetIterator.next();
+                                               String key = 
subsetIterator.next();
                                                SimpleFieldSet fs = 
subsets.get(key);
                                                String newPrefix = prefix + key 
+ MULTI_LEVEL_CHAR;
                                                subIterator = 
fs.keyIterator(newPrefix);
@@ -548,7 +547,7 @@
                        }
                }

-               public final Object next() {
+               public final String next() {
                        return nextKey();
                }

@@ -563,7 +562,7 @@
                                        if(subIterator != null && 
subIterator.hasNext()) {
                                                // If we have a retval, and we 
have a next value, return
                                                if(ret != null) return ret;
-                                               ret = (String) 
subIterator.next();
+                                               ret = subIterator.next();
                                                if(subIterator.hasNext())
                                                        // If we have a retval, 
and we have a next value, return
                                                        if(ret != null) return 
ret;
@@ -571,7 +570,7 @@
                                        // Otherwise, we need to get a new 
subIterator (or hasNext() will return false)
                                        subIterator = null;
                                        if(subsetIterator != null && 
subsetIterator.hasNext()) {
-                                               String key = (String) 
subsetIterator.next();
+                                               String key = 
subsetIterator.next();
                                                SimpleFieldSet fs = 
subsets.get(key);
                                                String newPrefix = prefix + key 
+ MULTI_LEVEL_CHAR;
                                                subIterator = 
fs.keyIterator(newPrefix);
@@ -601,7 +600,7 @@
                if(fs.isEmpty()) // can't just no-op, because caller might add 
the FS then populate it...
                        throw new IllegalArgumentException("Empty");
                if(subsets == null)
-                       subsets = new HashMap();
+                       subsets = new HashMap<String, SimpleFieldSet>();
                if(subsets.containsKey(key))
                        throw new IllegalArgumentException("Already contains 
"+key+" but trying to add a SimpleFieldSet!");
                if(!shortLived) key = key.intern();
@@ -665,7 +664,7 @@
                return values.isEmpty() && (subsets == null || 
subsets.isEmpty());
        }

-       public Iterator directSubsetNameIterator() {
+       public Iterator<String> directSubsetNameIterator() {
                return (subsets == null) ? null : subsets.keySet().iterator();
        }


Modified: branches/db4o/freenet/src/freenet/support/StringCounter.java
===================================================================
--- branches/db4o/freenet/src/freenet/support/StringCounter.java        
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/support/StringCounter.java        
2008-09-24 23:54:07 UTC (rev 22829)
@@ -13,7 +13,7 @@
  */
 public class StringCounter {

-       private final HashMap map;
+       private final HashMap<String, Item> map;

        private static class Item {
                public Item(String string2) {
@@ -24,11 +24,11 @@
        }

        public StringCounter() {
-               map = new HashMap();
+               map = new HashMap<String, Item>();
        }

        public synchronized void inc(String string) {
-               Item item = (Item) map.get(string);
+               Item item = map.get(string);
                if(item == null) {
                        item = new Item(string);
                        item.counter = 1;
@@ -38,21 +38,19 @@
        }

        public int get(String string) {
-               Item item = (Item) map.get(string);
+               Item item = map.get(string);
                if(item == null) return 0;
                return item.counter;
        }

        private synchronized Item[] items() {
-               return (Item[]) map.values().toArray(new Item[map.size()]);
+               return map.values().toArray(new Item[map.size()]);
        }

        private synchronized Item[] sortedItems(final boolean ascending) {
                Item[] items = items();
-               Arrays.sort(items, new Comparator() {
-                       public int compare(Object arg0, Object arg1) {
-                               Item it0 = (Item)arg0;
-                               Item it1 = (Item)arg1;
+               Arrays.sort(items, new Comparator<Item>() {
+                       public int compare(Item it0, Item it1) {
                                int ret;
                                if(it0.counter > it1.counter) ret = 1;
                                else if(it0.counter < it1.counter) ret = -1;
@@ -66,7 +64,7 @@

        public String toLongString() {
                Item[] items = sortedItems(false);
-               StringBuffer sb = new StringBuffer();
+               StringBuilder sb = new StringBuilder();
                for(int i=0;i<items.length;i++) {
                        if(i!=0) sb.append('\n');
                        Item it = items[i];

Modified: branches/db4o/freenet/src/freenet/support/TimeUtil.java
===================================================================
--- branches/db4o/freenet/src/freenet/support/TimeUtil.java     2008-09-24 
23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/support/TimeUtil.java     2008-09-24 
23:54:07 UTC (rev 22829)
@@ -42,7 +42,7 @@
        if (maxTerms > 6 )
                throw new IllegalArgumentException();

-       StringBuffer sb = new StringBuffer(64);
+       StringBuilder sb = new StringBuilder(64);
         long l = timeInterval;
         int termCount = 0;
         //

Modified: branches/db4o/freenet/src/freenet/support/URIPreEncoder.java
===================================================================
--- branches/db4o/freenet/src/freenet/support/URIPreEncoder.java        
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/support/URIPreEncoder.java        
2008-09-24 23:54:07 UTC (rev 22829)
@@ -1,6 +1,5 @@
 package freenet.support;

-import java.io.BufferedReader;
 import java.io.UnsupportedEncodingException;
 import java.net.URI;
 import java.net.URISyntaxException;
@@ -22,7 +21,7 @@
        public final static String allowedChars = 
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-!.~'()*,;:$&+=?/@%";

        public static String encode(String s) {
-               StringBuffer output = new StringBuffer(s.length()*2);
+               StringBuilder output = new StringBuilder(s.length()*2);
                for(int i=0;i<s.length();i++) {
                        char c = s.charAt(i);
                        if(allowedChars.indexOf(c) >= 0) {

Modified: branches/db4o/freenet/src/freenet/support/URLDecoder.java
===================================================================
--- branches/db4o/freenet/src/freenet/support/URLDecoder.java   2008-09-24 
23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/support/URLDecoder.java   2008-09-24 
23:54:07 UTC (rev 22829)
@@ -3,7 +3,6 @@
  * http://www.gnu.org/ for further details of the GPL. */
 package freenet.support;

-import java.io.BufferedReader;
 import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.io.UnsupportedEncodingException;

Modified: branches/db4o/freenet/src/freenet/support/URLEncoder.java
===================================================================
--- branches/db4o/freenet/src/freenet/support/URLEncoder.java   2008-09-24 
23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/support/URLEncoder.java   2008-09-24 
23:54:07 UTC (rev 22829)
@@ -3,7 +3,6 @@
  * http://www.gnu.org/ for further details of the GPL. */
 package freenet.support;

-import java.io.BufferedReader;
 import java.io.UnsupportedEncodingException;

 /**
@@ -25,7 +24,7 @@
         * @return      Encoded version of string
         */
        public final static String encode(String URL, String force, boolean 
ascii) {
-               StringBuffer enc = new StringBuffer(URL.length());
+               StringBuilder enc = new StringBuilder(URL.length());
                for (int i = 0; i < URL.length(); ++i) {
                        char c = URL.charAt(i);
                        if (((safeURLCharacters.indexOf(c) >= 0) || ((!ascii) 
&& c >= 0200))

Modified: branches/db4o/freenet/src/freenet/support/VoidLogger.java
===================================================================
--- branches/db4o/freenet/src/freenet/support/VoidLogger.java   2008-09-24 
23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/support/VoidLogger.java   2008-09-24 
23:54:07 UTC (rev 22829)
@@ -10,7 +10,7 @@
 public class VoidLogger extends Logger
 {

-       public void log(Object o, Class source, String message, Throwable e, 
int priority) {
+       public void log(Object o, Class<?> source, String message, Throwable e, 
int priority) {
        }

        public void log(Object source, String message, int priority) {
@@ -19,10 +19,10 @@
        public void log(Object o, String message, Throwable e, int priority) {
        }

-       public void log(Class c, String message, int priority) {
+       public void log(Class<?> c, String message, int priority) {
        }

-       public void log(Class c, String message, Throwable e, int priority) {
+       public void log(Class<?> c, String message, Throwable e, int priority) {
        }

        public long minFlags() {
@@ -37,7 +37,7 @@
                return 0;
        }

-       public boolean instanceShouldLog(int priority, Class c) {
+       public boolean instanceShouldLog(int priority, Class<?> c) {
                return false;
        }


Modified: branches/db4o/freenet/src/freenet/support/io/ArrayBucket.java
===================================================================
--- branches/db4o/freenet/src/freenet/support/io/ArrayBucket.java       
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/support/io/ArrayBucket.java       
2008-09-24 23:54:07 UTC (rev 22829)
@@ -21,7 +21,7 @@
  */
 public class ArrayBucket implements Bucket {

-       private final ArrayList data;
+       private final ArrayList<byte[]> data;
        private String name;
        private boolean readOnly;

@@ -35,7 +35,7 @@
        }

        public ArrayBucket(String name) {
-               data = new ArrayList();
+               data = new ArrayList<byte[]>();
                this.name = name;
        }

@@ -49,9 +49,8 @@
        }

        public String toString() {
-               StringBuffer s = new StringBuffer(250);
-               for (Iterator i = data.iterator(); i.hasNext();) {
-                       byte[] b = (byte[]) i.next();
+               StringBuilder s = new StringBuilder(250);
+               for (byte[] b : data) {
                        s.append(new String(b));
                }
                return s.toString();
@@ -69,8 +68,7 @@

        public long size() {
                long size = 0;
-               for (Iterator i = data.iterator(); i.hasNext();) {
-                       byte[] b = (byte[]) i.next();
+               for (byte[] b : data) {
                        size += b.length;
                }
                return size;
@@ -99,7 +97,7 @@

        private class ArrayBucketInputStream extends InputStream {

-               private Iterator i;
+               private Iterator<byte[]> i;
                private ByteArrayInputStream in;

                public ArrayBucketInputStream() {
@@ -113,7 +111,7 @@
                private int priv_read() {
                        if (in == null) {
                                if (i.hasNext()) {
-                                       in = new ByteArrayInputStream((byte[]) 
i.next());
+                                       in = new ByteArrayInputStream(i.next());
                                } else {
                                        return -1;
                                }
@@ -138,7 +136,7 @@
                private int priv_read(byte[] b, int off, int len) {
                        if (in == null) {
                                if (i.hasNext()) {
-                                       in = new ByteArrayInputStream((byte[]) 
i.next());
+                                       in = new ByteArrayInputStream(i.next());
                                } else {
                                        return -1;
                                }
@@ -155,7 +153,7 @@
                public int available() {
                        if (in == null) {
                                if (i.hasNext()) {
-                                       in = new ByteArrayInputStream((byte[]) 
i.next());
+                                       in = new ByteArrayInputStream(i.next());
                                } else {
                                        return 0;
                                }
@@ -183,8 +181,7 @@
                int size = (int)sz;
                byte[] buf = new byte[size];
                int index = 0;
-               for(Iterator i=data.iterator();i.hasNext();) {
-                       byte[] obuf = (byte[]) i.next();
+               for (byte[] obuf : data) {                      
                        System.arraycopy(obuf, 0, buf, index, obuf.length);
                        index += obuf.length;
                }

Modified: branches/db4o/freenet/src/freenet/support/io/BaseFileBucket.java
===================================================================
--- branches/db4o/freenet/src/freenet/support/io/BaseFileBucket.java    
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/support/io/BaseFileBucket.java    
2008-09-24 23:54:07 UTC (rev 22829)
@@ -7,6 +7,7 @@
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
+import java.util.Arrays;
 import java.util.Vector;

 import org.tanukisoftware.wrapper.WrapperManager;
@@ -15,7 +16,6 @@
 import freenet.support.Logger;
 import freenet.support.SimpleFieldSet;
 import freenet.support.api.Bucket;
-import java.util.Arrays;

 public abstract class BaseFileBucket implements Bucket, 
SerializableToFieldSetBucket {

@@ -28,7 +28,7 @@
        /** Vector of streams (FileBucketInputStream or FileBucketOutputStream) 
which 
         * are open to this file. So we can be sure they are all closed when we 
free it. 
         * Can be null. */
-       private transient Vector streams;
+       private transient Vector<Object> streams;

        protected static String tempDir = null;

@@ -80,7 +80,7 @@
                // BaseFileBucket is a very common object, and often very long 
lived,
                // so we need to minimize memory usage even at the cost of 
frequent allocations.
                if(streams == null)
-                       streams = new Vector(1,1);
+                       streams = new Vector<Object>(1, 1);
                streams.add(stream);
        }


Modified: branches/db4o/freenet/src/freenet/support/io/BucketChainBucket.java
===================================================================
--- branches/db4o/freenet/src/freenet/support/io/BucketChainBucket.java 
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/support/io/BucketChainBucket.java 
2008-09-24 23:54:07 UTC (rev 22829)
@@ -16,7 +16,7 @@

 public class BucketChainBucket implements Bucket {

-       private final Vector buckets;
+       private final Vector<Bucket> buckets;
        public final long bucketSize;
        private long size;
        private boolean freed;
@@ -25,7 +25,7 @@

        public BucketChainBucket(long bucketSize, BucketFactory bf) {
                this.bucketSize = bucketSize;
-               this.buckets = new Vector();
+               this.buckets = new Vector<Bucket>();
                this.bf = bf;
                size = 0;
                freed = false;
@@ -61,7 +61,7 @@
        }

        public synchronized Bucket[] getBuckets() {
-               return (Bucket[]) buckets.toArray(new Bucket[buckets.size()]);
+               return buckets.toArray(new Bucket[buckets.size()]);
        }

        public InputStream getInputStream() throws IOException {
@@ -167,7 +167,7 @@
        }

        protected synchronized InputStream getBucketInputStream(int i) throws 
IOException {
-               Bucket bucket = (Bucket) buckets.get(i);
+               Bucket bucket = buckets.get(i);
                if(bucket == null) return null;
                return bucket.getInputStream();
        }
@@ -266,9 +266,10 @@
        protected OutputStream makeBucketOutputStream(int i) throws IOException 
{
                Bucket bucket = bf.makeBucket(bucketSize);
                buckets.add(bucket);
-               if(buckets.size() != i+1)
-                       throw new IllegalStateException("Added bucket, size 
should be "+(i+1)+" but is "+buckets.size());
-               buckets.set(i, bucket);
+               if (buckets.size() != i + 1)
+                       throw new IllegalStateException("Added bucket, size 
should be " + (i + 1) + " but is " + buckets.size());
+               if (buckets.get(i) != bucket)
+                       throw new IllegalStateException("Bucket got replaced. 
Race condition?");
                return bucket.getOutputStream();
        }


Modified: branches/db4o/freenet/src/freenet/support/io/BucketTools.java
===================================================================
--- branches/db4o/freenet/src/freenet/support/io/BucketTools.java       
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/support/io/BucketTools.java       
2008-09-24 23:54:07 UTC (rev 22829)
@@ -141,7 +141,7 @@
        }

        public final static int[] nullIndices(Bucket[] array) {
-               List<Integer> list = new ArrayList();
+               List<Integer> list = new ArrayList<Integer>();
                for (int i = 0; i < array.length; i++) {
                        if (array[i] == null) {
                                list.add(i);
@@ -156,7 +156,7 @@
        }

        public final static int[] nonNullIndices(Bucket[] array) {
-               List<Integer> list = new ArrayList();
+               List<Integer> list = new ArrayList<Integer>();
                for (int i = 0; i < array.length; i++) {
                        if (array[i] != null) {
                                list.add(i);
@@ -171,7 +171,7 @@
        }

        public final static Bucket[] nonNullBuckets(Bucket[] array) {
-               List list = new ArrayList(array.length);
+               List<Bucket> list = new ArrayList<Bucket>(array.length);
                for (int i = 0; i < array.length; i++) {
                        if (array[i] != null) {
                                list.add(array[i]);
@@ -179,7 +179,7 @@
                }

                Bucket[] ret = new Bucket[list.size()];
-               return (Bucket[]) list.toArray(ret);
+               return list.toArray(ret);
        }

        /**

Modified: branches/db4o/freenet/src/freenet/support/io/FileUtil.java
===================================================================
--- branches/db4o/freenet/src/freenet/support/io/FileUtil.java  2008-09-24 
23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/support/io/FileUtil.java  2008-09-24 
23:54:07 UTC (rev 22829)
@@ -92,7 +92,7 @@
         }

        public static String readUTF(File file, long offset) throws 
FileNotFoundException, IOException {
-               StringBuffer result = new StringBuffer();
+               StringBuilder result = new StringBuilder();
                FileInputStream fis = null;
                BufferedInputStream bis = null;
                InputStreamReader isr = null;
@@ -234,7 +234,7 @@


        public static String sanitize(String s) {
-               StringBuffer sb = new StringBuffer(s.length());
+               StringBuilder sb = new StringBuilder(s.length());
                for(int i=0;i<s.length();i++) {
                        char c = s.charAt(i);
                        if((c == '/') || (c == '\\') || (c == '%') || (c == 
'>') || (c == '<') || (c == ':') || (c == '\'') || (c == '\"'))

Modified: branches/db4o/freenet/src/freenet/support/io/MultiReaderBucket.java
===================================================================
--- branches/db4o/freenet/src/freenet/support/io/MultiReaderBucket.java 
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/support/io/MultiReaderBucket.java 
2008-09-24 23:54:07 UTC (rev 22829)
@@ -22,7 +22,7 @@
        private final Bucket bucket;

        // Assume there will be relatively few readers
-       private ArrayList readers;
+       private ArrayList<Bucket> readers;

        private boolean closed;

@@ -35,7 +35,7 @@
                synchronized(this) {
                        if(closed) return null;
                        Bucket d = new ReaderBucket();
-                       if(readers == null) readers = new ArrayList();
+                       if(readers == null) readers = new ArrayList<Bucket>();
                        readers.add(d);
                        return d;
                }

Modified: 
branches/db4o/freenet/src/freenet/support/io/PaddedEphemerallyEncryptedBucket.java
===================================================================
--- 
branches/db4o/freenet/src/freenet/support/io/PaddedEphemerallyEncryptedBucket.java
  2008-09-24 23:18:12 UTC (rev 22828)
+++ 
branches/db4o/freenet/src/freenet/support/io/PaddedEphemerallyEncryptedBucket.java
  2008-09-24 23:54:07 UTC (rev 22829)
@@ -8,6 +8,7 @@
 import java.io.OutputStream;
 import java.lang.ref.WeakReference;
 import java.util.Random;
+import java.util.Random;

 import org.spaceroots.mantissa.random.MersenneTwister;

@@ -31,7 +32,7 @@

        private final Bucket bucket;
        private final int minPaddedSize;
-       private transient WeakReference /* <Rijndael> */ aesRef;
+       private transient WeakReference<Rijndael> aesRef;
        /** The decryption key. */
        private final byte[] key;
        private final byte[] randomSeed;
@@ -195,7 +196,8 @@
                        }
                }

-               @Override
+        @Override
+               @SuppressWarnings("cast")
                public void close() throws IOException {
                        if(closed) return;
                        try {
@@ -210,7 +212,7 @@
                                        byte[] buf = new byte[4096];
                                        long writtenPadding = 0;
                                        while(writtenPadding < padding) {
-                                               int left = (int) 
Math.min((padding - writtenPadding), (long)buf.length);
+                                               int left = (int) 
Math.min((long) (padding - writtenPadding), (long) buf.length);
                                                random.nextBytes(buf);
                                                out.write(buf, 0, left);
                                                writtenPadding += left;
@@ -320,7 +322,7 @@
        private synchronized Rijndael getRijndael() {
                Rijndael aes;
                if(aesRef != null) {
-                       aes = (Rijndael) aesRef.get();
+                       aes = aesRef.get();
                        if(aes != null) return aes;
                }
                try {
@@ -329,7 +331,7 @@
                        throw new Error(e);
                }
                aes.initialize(key);
-               aesRef = new WeakReference(aes);
+               aesRef = new WeakReference<Rijndael>(aes);
                return aes;
        }


Modified: 
branches/db4o/freenet/src/freenet/support/io/PersistentTempBucketFactory.java
===================================================================
--- 
branches/db4o/freenet/src/freenet/support/io/PersistentTempBucketFactory.java   
    2008-09-24 23:18:12 UTC (rev 22828)
+++ 
branches/db4o/freenet/src/freenet/support/io/PersistentTempBucketFactory.java   
    2008-09-24 23:54:07 UTC (rev 22829)
@@ -4,6 +4,7 @@
 package freenet.support.io;

 import java.io.File;
+import java.io.FileFilter;
 import java.io.IOException;
 import java.util.HashSet;
 import java.util.LinkedList;
@@ -17,7 +18,6 @@
 import freenet.support.Logger;
 import freenet.support.api.Bucket;
 import freenet.support.api.BucketFactory;
-import java.io.FileFilter;

 /**
  * Handles persistent temp files. These are used for e.g. persistent downloads.
@@ -31,7 +31,7 @@
 public class PersistentTempBucketFactory implements BucketFactory, 
PersistentFileTracker {

        /** Original contents of directory */
-       private HashSet originalFiles;
+       private HashSet<File> originalFiles;

        /** Filename generator */
        public final FilenameGenerator fg;
@@ -41,7 +41,7 @@
        private transient Random weakPRNG;

        /** Buckets to free */
-       private LinkedList bucketsToFree;
+       private LinkedList<Bucket> bucketsToFree;

        private final long nodeDBHandle;

@@ -62,7 +62,7 @@
                }
                if(!dir.isDirectory())
                        throw new IOException("Directory is not a directory: 
"+dir);
-               originalFiles = new HashSet();
+               originalFiles = new HashSet<File>();
                File[] files = dir.listFiles(new FileFilter() {

                        public boolean accept(File pathname) {
@@ -81,7 +81,7 @@
                        originalFiles.add(f);
                }

-               bucketsToFree = new LinkedList();
+               bucketsToFree = new LinkedList<Bucket>();
        }

        public void init(File dir, String prefix, RandomSource strongPRNG, 
Random weakPRNG) throws IOException {
@@ -109,7 +109,7 @@
                // So keep all the temp files for now.
                // FIXME: tidy up unwanted temp files.

-//             Iterator i = originalFiles.iterator();
+//             Iterator<File> i = originalFiles.iterator();
 //             while(i.hasNext()) {
 //                     File f = (File) (i.next());
 //                     if(Logger.shouldLog(Logger.MINOR, this))
@@ -134,10 +134,10 @@
                }
        }

-       public LinkedList grabBucketsToFree() {
+       public LinkedList<Bucket> grabBucketsToFree() {
                synchronized(this) {
-                       LinkedList toFree = bucketsToFree;
-                       bucketsToFree = new LinkedList();
+                       LinkedList<Bucket> toFree = bucketsToFree;
+                       bucketsToFree = new LinkedList<Bucket>();
                        return toFree;
                }
        }

Modified: 
branches/db4o/freenet/src/freenet/support/io/SerializableToFieldSetBucketUtil.java
===================================================================
--- 
branches/db4o/freenet/src/freenet/support/io/SerializableToFieldSetBucketUtil.java
  2008-09-24 23:18:12 UTC (rev 22828)
+++ 
branches/db4o/freenet/src/freenet/support/io/SerializableToFieldSetBucketUtil.java
  2008-09-24 23:54:07 UTC (rev 22829)
@@ -3,11 +3,7 @@
  * http://www.gnu.org/ for further details of the GPL. */
 package freenet.support.io;

-import java.io.File;
-import java.io.IOException;
-
 import freenet.crypt.RandomSource;
-import freenet.support.HexUtil;
 import freenet.support.Logger;
 import freenet.support.SimpleFieldSet;
 import freenet.support.api.Bucket;

Modified: branches/db4o/freenet/src/freenet/support/io/TempBucketFactory.java
===================================================================
--- branches/db4o/freenet/src/freenet/support/io/TempBucketFactory.java 
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/src/freenet/support/io/TempBucketFactory.java 
2008-09-24 23:54:07 UTC (rev 22829)
@@ -147,6 +147,7 @@
                }

                private class TempBucketOutputStream extends OutputStream {
+                       @SuppressWarnings("unused")
                        private final short idx;

                        TempBucketOutputStream(short idx) throws IOException {

Modified: 
branches/db4o/freenet/src/freenet/support/math/SimpleBinaryRunningAverage.java
===================================================================
--- 
branches/db4o/freenet/src/freenet/support/math/SimpleBinaryRunningAverage.java  
    2008-09-24 23:18:12 UTC (rev 22828)
+++ 
branches/db4o/freenet/src/freenet/support/math/SimpleBinaryRunningAverage.java  
    2008-09-24 23:54:07 UTC (rev 22829)
@@ -179,7 +179,7 @@
     }

        private synchronized void calculateTotalOnesZeros() {
-               StringBuffer sb = new StringBuffer();
+               StringBuilder sb = new StringBuilder();
                int tones = 0;
                int tzeros = 0;
                for(int i=0;i<baSize();i++) {
@@ -199,7 +199,7 @@
        }

        protected String checkOnesZeros() {
-           StringBuffer sb = new StringBuffer();
+           StringBuilder sb = new StringBuilder();
                int tones = 0;
                int tzeros = 0;
                for(int i=0;i<baSize();i++) {

Modified: 
branches/db4o/freenet/src/freenet/support/transport/ip/IPAddressDetector.java
===================================================================
--- 
branches/db4o/freenet/src/freenet/support/transport/ip/IPAddressDetector.java   
    2008-09-24 23:18:12 UTC (rev 22828)
+++ 
branches/db4o/freenet/src/freenet/support/transport/ip/IPAddressDetector.java   
    2008-09-24 23:54:07 UTC (rev 22829)
@@ -1,15 +1,16 @@
 /* -*- Mode: java; c-basic-indent: 4; tab-width: 4 -*- */
 package freenet.support.transport.ip;

-import freenet.io.AddressIdentifier;
 import java.net.DatagramSocket;
 import java.net.InetAddress;
 import java.net.SocketException;
 import java.net.UnknownHostException;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Enumeration;
-import java.util.Vector;
+import java.util.List;

+import freenet.io.AddressIdentifier;
 import freenet.node.NodeIPDetector;
 import freenet.support.Logger;

@@ -67,13 +68,13 @@

        /**
         * Execute a checkpoint - detect our internet IP address and log it
-        * @param preferedAddress An address that for some reason is prefered 
above others. Might be null
+        * @param preferedAddress An address that for some reason is preferred 
above others. Might be null
         */
        protected synchronized void checkpoint() {
                boolean logDEBUG = Logger.shouldLog(Logger.DEBUG, this);
-               Vector addrs = new Vector();
+               List<InetAddress> addrs = new ArrayList<InetAddress>();

-               Enumeration interfaces = null;
+               Enumeration<java.net.NetworkInterface> interfaces = null;
                try {
                        interfaces = 
java.net.NetworkInterface.getNetworkInterfaces();
                } catch (SocketException e) {
@@ -87,16 +88,15 @@

                if (!old) {
                        while (interfaces.hasMoreElements()) {
-                               java.net.NetworkInterface iface =
-                                       (java.net.NetworkInterface) 
(interfaces.nextElement());
+                               java.net.NetworkInterface iface = 
interfaces.nextElement();
                                if (logDEBUG)
                                        Logger.debug(
                                                this,
                                                "Scanning NetworkInterface " + 
iface.getDisplayName());
-                               Enumeration ee = iface.getInetAddresses();
+                               Enumeration<InetAddress> ee = 
iface.getInetAddresses();
                                while (ee.hasMoreElements()) {

-                                       InetAddress addr = (InetAddress) 
(ee.nextElement());
+                                       InetAddress addr = ee.nextElement();
                                        addrs.add(addr);
                                        if (logDEBUG)
                                                Logger.debug(
@@ -160,25 +160,28 @@
                }
        }

-       /** Do something with the list of detected IP addresses.
-        * @param v Vector of InetAddresses
+       /**
+        * Do something with the list of detected IP addresses.
+        * 
+        * @param addrs
+        *            Vector of InetAddresses
         */
-       protected void onGetAddresses(Vector v) {
-               Vector output = new Vector();
+       protected void onGetAddresses(List<InetAddress> addrs) {
+               List<InetAddress> output = new ArrayList<InetAddress>();
                boolean logDEBUG = Logger.shouldLog(Logger.DEBUG, this);
                if (logDEBUG)
                        Logger.debug(
                                this,
-                               "onGetAddresses found " + v.size() + " 
potential addresses)");
-               if (v.size() == 0) {
+                               "onGetAddresses found " + addrs.size() + " 
potential addresses)");
+               if (addrs.size() == 0) {
                        Logger.error(this, "No addresses found!");
                        lastAddressList = null;
                        return;
                } else {
 //                     InetAddress lastNonValidAddress = null;
-                       for (int x = 0; x < v.size(); x++) {
-                               if (v.elementAt(x) != null) {
-                                       InetAddress i = (InetAddress) 
(v.elementAt(x));
+                       for (int x = 0; x < addrs.size(); x++) {
+                               if (addrs.get(x) != null) {
+                                       InetAddress i = addrs.get(x);
                                        if (logDEBUG)
                                                Logger.debug(
                                                        this,
@@ -187,9 +190,8 @@
                                                // Wildcard address, 0.0.0.0, 
ignore.
                                        } else if(i.isLinkLocalAddress() || 
i.isLoopbackAddress() ||
                                                        i.isSiteLocalAddress()) 
{
-                                               
if(detector.includeLocalAddressesInNoderefs()) {
-                                                       output.add(i);
-                                               }
+                                               // Will be filtered out later 
if necessary.
+                                               output.add(i);
                                        } else if(i.isMulticastAddress()) {
                                                // Ignore
                                        } else {
@@ -201,7 +203,7 @@
                                }
                        }
                }
-               lastAddressList = (InetAddress[]) output.toArray(new 
InetAddress[output.size()]);
+               lastAddressList = output.toArray(new 
InetAddress[output.size()]);
        }

        public void run() {

Modified: branches/db4o/freenet/test/DatastoreTest.java
===================================================================
--- branches/db4o/freenet/test/DatastoreTest.java       2008-09-24 23:18:12 UTC 
(rev 22828)
+++ branches/db4o/freenet/test/DatastoreTest.java       2008-09-24 23:54:07 UTC 
(rev 22829)
@@ -78,7 +78,7 @@
                     content = line;
                 } else {
                     // Multiple line insert
-                    StringBuffer sb = new StringBuffer(1000);
+                    StringBuilder sb = new StringBuilder(1000);
                     while(true) {
                         line = reader.readLine();
                         if(line.equals(".")) break;

Modified: branches/db4o/freenet/test/PreNodeTest.java
===================================================================
--- branches/db4o/freenet/test/PreNodeTest.java 2008-09-24 23:18:12 UTC (rev 
22828)
+++ branches/db4o/freenet/test/PreNodeTest.java 2008-09-24 23:54:07 UTC (rev 
22829)
@@ -431,7 +431,7 @@
                     content = line;
                 } else {
                     // Multiple line insert
-                    StringBuffer sb = new StringBuffer(1000);
+                    StringBuilder sb = new StringBuilder(1000);
                     while(true) {
                         line = reader.readLine();
                         if(line.equals(".")) break;

Modified: branches/db4o/freenet/test/PreQuasiNodeTest.java
===================================================================
--- branches/db4o/freenet/test/PreQuasiNodeTest.java    2008-09-24 23:18:12 UTC 
(rev 22828)
+++ branches/db4o/freenet/test/PreQuasiNodeTest.java    2008-09-24 23:54:07 UTC 
(rev 22829)
@@ -133,7 +133,7 @@
                     content = line;
                 } else {
                     // Multiple line insert
-                    StringBuffer sb = new StringBuffer(1000);
+                    StringBuilder sb = new StringBuilder(1000);
                     while(true) {
                         line = reader.readLine();
                         if(line.equals(".")) break;

Modified: branches/db4o/freenet/test/QuasiNodeTest.java
===================================================================
--- branches/db4o/freenet/test/QuasiNodeTest.java       2008-09-24 23:18:12 UTC 
(rev 22828)
+++ branches/db4o/freenet/test/QuasiNodeTest.java       2008-09-24 23:54:07 UTC 
(rev 22829)
@@ -291,7 +291,7 @@
                     content = line;
                 } else {
                     // Multiple line insert
-                    StringBuffer sb = new StringBuffer(1000);
+                    StringBuilder sb = new StringBuilder(1000);
                     while(true) {
                         line = reader.readLine();
                         if(line.equals(".")) break;

Modified: branches/db4o/freenet/test/freenet/config/ConfigTest.java
===================================================================
--- branches/db4o/freenet/test/freenet/config/ConfigTest.java   2008-09-24 
23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/test/freenet/config/ConfigTest.java   2008-09-24 
23:54:07 UTC (rev 22829)
@@ -43,7 +43,7 @@

        public void testRegister() {
                /* test if we can register */
-               StringBuffer sb = new StringBuffer();
+               StringBuilder sb = new StringBuilder();
                for(int i=0; i< UTFUtil.PRINTABLE_ASCII.length; i++)
                        sb.append(UTFUtil.PRINTABLE_ASCII[i]);
                for(int i=0; i< UTFUtil.STRESSED_UTF.length; i++)

Modified: branches/db4o/freenet/test/freenet/support/BitArrayTest.java
===================================================================
--- branches/db4o/freenet/test/freenet/support/BitArrayTest.java        
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/test/freenet/support/BitArrayTest.java        
2008-09-24 23:54:07 UTC (rev 22829)
@@ -48,10 +48,10 @@
         * @return the String of toRepeat
         */
        private String createAllOneString(int stringSize, String toRepeat) {
-               StringBuffer methodStringBuffer = new StringBuffer();
+               StringBuilder methodStringBuilder = new StringBuilder();
                for (int i=0;i<stringSize;i++)
-                       methodStringBuffer.append(toRepeat);
-               return methodStringBuffer.toString();
+                       methodStringBuilder.append(toRepeat);
+               return methodStringBuilder.toString();
        }

        /**

Copied: branches/db4o/freenet/test/freenet/support/BloomFilterTest.java (from 
rev 22484, trunk/freenet/test/freenet/support/BloomFilterTest.java)
===================================================================
--- branches/db4o/freenet/test/freenet/support/BloomFilterTest.java             
                (rev 0)
+++ branches/db4o/freenet/test/freenet/support/BloomFilterTest.java     
2008-09-24 23:54:07 UTC (rev 22829)
@@ -0,0 +1,154 @@
+package freenet.support;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Random;
+import java.util.Set;
+
+import junit.framework.TestCase;
+
+import org.spaceroots.mantissa.random.MersenneTwister;
+
+public class BloomFilterTest extends TestCase {
+       private static final int FILTER_SIZE = 4 * 1024; // MUST be > PASS,
+       private static final int PASS = 2048;
+       private static final int PASS_REMOVE = 4096;
+       private static final int PASS_POS = 256;
+       private static final int PASS_FALSE = 8192;
+
+       private final Random rand = new MersenneTwister();
+
+       private void _testFilterPositive(BloomFilter filter) {
+               byte[][] list = new byte[PASS_POS][];
+
+               for (int i = 0; i < PASS_POS; i++) {
+                       byte[] b = new byte[32];
+                       rand.nextBytes(b);
+
+                       filter.addKey(b);
+                       list[i] = b;
+               }
+
+               for (byte[] b : list) {
+                       assertTrue(filter.checkFilter(b));
+               }
+       }
+
+       public void testCountingFilterPositive() {
+               int K = BloomFilter.optimialK(FILTER_SIZE, PASS_POS);
+               BloomFilter filter = BloomFilter.createFilter(FILTER_SIZE, K, 
true);
+               _testFilterPositive(filter);
+       }
+
+       public void testBinaryFilterPositive() {
+               int K = BloomFilter.optimialK(FILTER_SIZE, PASS_POS);
+               BloomFilter filter = BloomFilter.createFilter(FILTER_SIZE, K, 
false);
+               _testFilterPositive(filter);
+       }
+
+       public void testCountingFilterRemove() {
+               int K = BloomFilter.optimialK(FILTER_SIZE, PASS);
+               BloomFilter filter = BloomFilter.createFilter(FILTER_SIZE, K, 
true);
+
+               Map<ByteArrayWrapper, byte[]> baseList = new 
HashMap<ByteArrayWrapper, byte[]>();
+
+               // Add Keys
+               for (int i = 0; i < PASS; i++) {
+                       byte[] b = new byte[32];
+                       do {
+                               rand.nextBytes(b);
+                       } while (baseList.containsKey(new ByteArrayWrapper(b)));
+
+                       filter.addKey(b);
+                       baseList.put(new ByteArrayWrapper(b), b);
+                       assertTrue("check add BASE", filter.checkFilter(b));
+               }
+
+               // Add some FALSE_PASS keys
+               Map<ByteArrayWrapper, byte[]> newList = new 
HashMap<ByteArrayWrapper, byte[]>();
+               int fPos = 0;
+               for (int i = 0; i < PASS_REMOVE; i++) {
+                       byte[] b = new byte[64];
+                       ByteArrayWrapper wrapper;
+                       do {
+                               rand.nextBytes(b);
+                               wrapper = new ByteArrayWrapper(b);
+                       } while (newList.containsKey(wrapper));
+
+                       filter.addKey(b);
+                       newList.put(wrapper, b);
+                       assertTrue("check add NEW", filter.checkFilter(b));
+               }
+
+               // Remove the "NEW" keys and count false positive
+               for (byte[] b : newList.values())
+                       filter.removeKey(b);
+               for (byte[] b : newList.values())
+                       if (filter.checkFilter(b))
+                               fPos++;
+
+               // Check if some should were removed
+               assertFalse("100% false positive?", fPos == PASS_REMOVE);
+
+               // Check if old keys still here
+               for (byte[] b : baseList.values())
+                       assertTrue("check original", filter.checkFilter(b));
+       }
+
+       private void _testFilterFalsePositive(BloomFilter filter) {
+               Set<ByteArrayWrapper> list = new HashSet<ByteArrayWrapper>();
+
+               // Add Keys
+               for (int i = 0; i < PASS; i++) {
+                       byte[] b = new byte[32];
+                       do {
+                               rand.nextBytes(b);
+                       } while (list.contains(new ByteArrayWrapper(b)));
+
+                       filter.addKey(b);
+                       list.add(new ByteArrayWrapper(b));
+                       assertTrue("check add", filter.checkFilter(b));
+               }
+
+               System.out.println("---" + filter + "---");
+
+               int fPos = 0;
+               for (int i = 0; i < PASS_FALSE; i++) {
+                       byte[] b = new byte[64]; // 64 bytes, sure not exist
+                       rand.nextBytes(b);
+
+                       if (filter.checkFilter(b))
+                               fPos++;
+               }
+
+               final int K = filter.getK();
+               final double q = 1 - Math.pow(1 - 1.0 / FILTER_SIZE, K * PASS);
+               final double p = Math.pow(q, K);
+               final double actual = (double) fPos / PASS_FALSE;
+               final double limit = p * 1.05 + 1.0 / PASS_FALSE;
+
+               //*-
+               System.out.println("          k = " + K);
+               System.out.println("          q = " + q);
+               System.out.println("          p = " + p);
+               System.out.println("      limit = " + limit);
+               System.out.println("     actual = " + actual);
+               System.out.println(" actual / p = " + actual / p);
+               /**/
+
+               assertFalse("false positive, p=" + p + ", actual=" + actual, 
actual > limit);
+       }
+
+       public void testCountingFilterFalsePositive() {
+               int K = BloomFilter.optimialK(FILTER_SIZE, PASS);
+               BloomFilter filter = BloomFilter.createFilter(FILTER_SIZE, K, 
true);
+               _testFilterFalsePositive(filter);
+       }
+
+       public void testBinaryFilterFalsePositive() {
+               int K = BloomFilter.optimialK(FILTER_SIZE, PASS);
+               BloomFilter filter = BloomFilter.createFilter(FILTER_SIZE, K, 
false);
+               _testFilterFalsePositive(filter);
+       }
+}

Modified: branches/db4o/freenet/test/freenet/support/FieldsTest.java
===================================================================
--- branches/db4o/freenet/test/freenet/support/FieldsTest.java  2008-09-24 
23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/test/freenet/support/FieldsTest.java  2008-09-24 
23:54:07 UTC (rev 22829)
@@ -241,6 +241,75 @@
                assertTrue(l3.equals(l1)); // should be same due to 
Fields.longHashcode
        }       

+       public void testIntsToBytes() {
+               int[] longs = new int[] {};
+               doRoundTripIntsArrayToBytesArray(longs);
+               
+               longs = new int[] {Integer.MIN_VALUE};
+               doRoundTripIntsArrayToBytesArray(longs);
+               
+               longs = new int[] {0, Integer.MAX_VALUE, Integer.MIN_VALUE};
+               doRoundTripIntsArrayToBytesArray(longs);
+               
+               longs = new int[] {33685760, 51511577};
+               doRoundTripIntsArrayToBytesArray(longs);                
+       }
+
+       private void doRoundTripIntsArrayToBytesArray(int[] ints) {
+               byte[] bytes = Fields.intsToBytes(ints);
+               assert(bytes.length == ints.length * 8);
+               
+               int[] outLongs = Fields.bytesToInts(bytes);
+               for(int i = 0; i < ints.length; i++) {
+                       assertTrue(outLongs[i] == ints[i]);
+               }
+               assertEquals(outLongs.length, ints.length);
+       }
+       
+       public void testBytesToIntException() {
+               byte[] bytes = new byte[3];
+               try {
+                       Fields.bytesToLongs(bytes, 0, bytes.length);
+                       fail();
+               }
+               catch(IllegalArgumentException e){
+                       // expect this
+               }
+       }
+       
+       public void testBytesToInt() {
+               
+               byte[] bytes = new byte[] { 0, 1, 2, 2 };
+               
+               int outLong = Fields.bytesToInt(bytes, 0);
+               assertEquals(outLong, 33685760);
+               
+               doTestRoundTripBytesArrayToInt(bytes);
+               
+               bytes = new byte[] {};
+               try{
+                       doTestRoundTripBytesArrayToInt(bytes);
+                       fail();
+               }
+               catch(IllegalArgumentException e) {
+                       //expect this
+               }
+               
+               bytes = new byte[] {1, 1, 1, 1};
+               doTestRoundTripBytesArrayToInt(bytes);
+               
+       }
+       
+       private void doTestRoundTripBytesArrayToInt(byte[] inBytes) {
+
+               int outLong = Fields.bytesToInt(inBytes, 0);
+               byte[] outBytes = Fields.intToBytes(outLong);
+               for(int i = 0; i < inBytes.length; i++) {
+                       assertEquals(outBytes[i], inBytes[i]);
+               }
+               assertEquals(outBytes.length, inBytes.length);
+       }
+       
        public void testLongsToBytes() {
                long[] longs = new long[] {};
                doRoundTripLongsArrayToBytesArray(longs);
@@ -263,6 +332,7 @@
                for(int i = 0; i < longs.length; i++) {
                        assertTrue(outLongs[i] == longs[i]);
                }
+               assertEquals(outLongs.length, longs.length);
        }

        public void testBytesToLongException() {
@@ -306,5 +376,7 @@
                for(int i = 0; i < inBytes.length; i++) {
                        assertEquals(outBytes[i], inBytes[i]);
                }
+               assertEquals(outBytes.length, inBytes.length);
        }
+
 }

Modified: branches/db4o/freenet/test/freenet/support/HTMLEncoderDecoderTest.java
===================================================================
--- branches/db4o/freenet/test/freenet/support/HTMLEncoderDecoderTest.java      
2008-09-24 23:18:12 UTC (rev 22828)
+++ branches/db4o/freenet/test/freenet/support/HTMLEncoderDecoderTest.java      
2008-09-24 23:54:07 UTC (rev 22829)
@@ -47,8 +47,8 @@
         * with all possible entity appended
         */
        public void testDecodeAppendedEntities() {
-               StringBuffer toDecode = new StringBuffer();
-               StringBuffer expected = new StringBuffer();
+               StringBuilder toDecode = new StringBuilder();
+               StringBuilder expected = new StringBuilder();
                for (int i =0; i<UTFUtil.HTML_ENTITIES_UTF.length; i++) {
                        toDecode.append(UTFUtil.HTML_ENTITIES_UTF[i][1]);
                        expected.append(UTFUtil.HTML_ENTITIES_UTF[i][0]);
@@ -83,9 +83,9 @@
         * (e.g. tabs,newline,space).
         */
        public void testCompactRepeated(){
-               StringBuffer strBuffer[] = new StringBuffer[6];
+               StringBuilder strBuffer[] = new StringBuilder[6];
                for (int i = 0; i < strBuffer.length; i++)
-                       strBuffer[i] = new StringBuffer();
+                       strBuffer[i] = new StringBuilder();

                for (int i=0;i<100;i++) {
                        //adding different "whitespaces"


Reply via email to