Author: toad
Date: 2006-08-12 19:24:25 +0000 (Sat, 12 Aug 2006)
New Revision: 10048

Added:
   trunk/freenet/src/freenet/node/NodeClientCore.java
Modified:
   trunk/freenet/src/freenet/client/HighLevelSimpleClientImpl.java
   trunk/freenet/src/freenet/client/async/BaseSingleFileFetcher.java
   trunk/freenet/src/freenet/client/async/SingleBlockInserter.java
   trunk/freenet/src/freenet/client/async/USKManager.java
   trunk/freenet/src/freenet/clients/http/BookmarkManager.java
   trunk/freenet/src/freenet/clients/http/ConfigToadlet.java
   trunk/freenet/src/freenet/clients/http/DarknetConnectionsToadlet.java
   trunk/freenet/src/freenet/clients/http/FProxyToadlet.java
   trunk/freenet/src/freenet/clients/http/LocalFileInsertToadlet.java
   trunk/freenet/src/freenet/clients/http/N2NTMToadlet.java
   trunk/freenet/src/freenet/clients/http/NinjaSpider.java
   trunk/freenet/src/freenet/clients/http/PluginToadlet.java
   trunk/freenet/src/freenet/clients/http/PproxyToadlet.java
   trunk/freenet/src/freenet/clients/http/QueueToadlet.java
   trunk/freenet/src/freenet/clients/http/SimpleToadletServer.java
   trunk/freenet/src/freenet/clients/http/Spider.java
   trunk/freenet/src/freenet/clients/http/WelcomeToadlet.java
   trunk/freenet/src/freenet/node/ARKFetcher.java
   trunk/freenet/src/freenet/node/CHKInsertSender.java
   trunk/freenet/src/freenet/node/IPDetectorPluginManager.java
   trunk/freenet/src/freenet/node/Node.java
   trunk/freenet/src/freenet/node/NodeARKInserter.java
   trunk/freenet/src/freenet/node/NodeDispatcher.java
   trunk/freenet/src/freenet/node/NodeIPDetector.java
   trunk/freenet/src/freenet/node/PeerManager.java
   trunk/freenet/src/freenet/node/RequestSender.java
   trunk/freenet/src/freenet/node/RequestStarter.java
   trunk/freenet/src/freenet/node/SSKInsertSender.java
   trunk/freenet/src/freenet/node/SendableRequest.java
   trunk/freenet/src/freenet/node/SimpleSendableInsert.java
   trunk/freenet/src/freenet/node/TextModeClientInterface.java
   trunk/freenet/src/freenet/node/TextModeClientInterfaceServer.java
   trunk/freenet/src/freenet/node/fcp/ClientGet.java
   trunk/freenet/src/freenet/node/fcp/ClientPut.java
   trunk/freenet/src/freenet/node/fcp/ClientPutDir.java
   trunk/freenet/src/freenet/node/fcp/ClientPutMessage.java
   trunk/freenet/src/freenet/node/fcp/ClientRequest.java
   trunk/freenet/src/freenet/node/fcp/FCPClient.java
   trunk/freenet/src/freenet/node/fcp/FCPConnectionHandler.java
   trunk/freenet/src/freenet/node/fcp/FCPConnectionInputHandler.java
   trunk/freenet/src/freenet/node/fcp/FCPServer.java
   trunk/freenet/src/freenet/node/fcp/SubscribeUSK.java
   trunk/freenet/src/freenet/node/fcp/SubscribeUSKMessage.java
   trunk/freenet/src/freenet/node/updater/NodeUpdater.java
   trunk/freenet/src/freenet/node/useralerts/MeaningfulNodeNameUserAlert.java
   trunk/freenet/src/freenet/plugin/PluginManager.java
   trunk/freenet/src/freenet/pluginmanager/PluginManager.java
   trunk/freenet/src/freenet/pluginmanager/PluginRespirator.java
Log:
More refactoring (Node now under 3kloc), fix bug in last lot.

Modified: trunk/freenet/src/freenet/client/HighLevelSimpleClientImpl.java
===================================================================
--- trunk/freenet/src/freenet/client/HighLevelSimpleClientImpl.java     
2006-08-12 18:13:01 UTC (rev 10047)
+++ trunk/freenet/src/freenet/client/HighLevelSimpleClientImpl.java     
2006-08-12 19:24:25 UTC (rev 10048)
@@ -14,6 +14,7 @@
 import freenet.crypt.RandomSource;
 import freenet.keys.FreenetURI;
 import freenet.node.Node;
+import freenet.node.NodeClientCore;
 import freenet.support.Logger;
 import freenet.support.io.Bucket;
 import freenet.support.io.BucketFactory;
@@ -28,7 +29,7 @@
        private final BucketFactory bucketFactory;
        private final BucketFactory persistentBucketFactory;
        private final PersistentFileTracker persistentFileTracker;
-       private final Node node;
+       private final NodeClientCore core;
        /** One CEP for all requests and inserts */
        private final ClientEventProducer globalEventProducer;
        private long curMaxLength;
@@ -71,8 +72,8 @@
        static final int SPLITFILE_CHECK_BLOCKS_PER_SEGMENT = 64;


-       public HighLevelSimpleClientImpl(Node node, ArchiveManager mgr, 
BucketFactory bf, RandomSource r, boolean cacheLocalRequests, short 
priorityClass) {
-               this.node = node;
+       public HighLevelSimpleClientImpl(NodeClientCore node, ArchiveManager 
mgr, BucketFactory bf, RandomSource r, boolean cacheLocalRequests, short 
priorityClass) {
+               this.core = node;
                archiveManager = mgr;
                this.priorityClass = priorityClass;
                bucketFactory = bf;
@@ -103,7 +104,7 @@
                if(uri == null) throw new NullPointerException();
                FetcherContext context = getFetcherContext();
                FetchWaiter fw = new FetchWaiter();
-               ClientGetter get = new ClientGetter(fw, node.chkFetchScheduler, 
node.sskFetchScheduler, uri, context, priorityClass, this, null);
+               ClientGetter get = new ClientGetter(fw, core.chkFetchScheduler, 
core.sskFetchScheduler, uri, context, priorityClass, this, null);
                get.start();
                return fw.waitForCompletion();
        }
@@ -112,7 +113,7 @@
                if(uri == null) throw new NullPointerException();
                FetcherContext context = getFetcherContext(overrideMaxSize);
                FetchWaiter fw = new FetchWaiter();
-               ClientGetter get = new ClientGetter(fw, node.chkFetchScheduler, 
node.sskFetchScheduler, uri, context, priorityClass, this, null);
+               ClientGetter get = new ClientGetter(fw, core.chkFetchScheduler, 
core.sskFetchScheduler, uri, context, priorityClass, this, null);
                get.start();
                return fw.waitForCompletion();
        }
@@ -125,7 +126,7 @@
                InserterContext context = getInserterContext(true);
                PutWaiter pw = new PutWaiter();
                ClientPutter put = new ClientPutter(pw, insert.data, 
insert.desiredURI, insert.clientMetadata, 
-                               context, node.chkPutScheduler, 
node.sskPutScheduler, priorityClass, getCHKOnly, isMetadata, this, null);
+                               context, core.chkPutScheduler, 
core.sskPutScheduler, priorityClass, getCHKOnly, isMetadata, this, null);
                put.start();
                return pw.waitForCompletion();
        }
@@ -150,7 +151,7 @@
        public FreenetURI insertManifest(FreenetURI insertURI, HashMap 
bucketsByName, String defaultName) throws InserterException {
                PutWaiter pw = new PutWaiter();
                SimpleManifestPutter putter =
-                       new SimpleManifestPutter(pw, node.chkPutScheduler, 
node.sskPutScheduler, 
SimpleManifestPutter.bucketsByNameToManifestEntries(bucketsByName), 
priorityClass, insertURI, defaultName, getInserterContext(true), false, this);
+                       new SimpleManifestPutter(pw, core.chkPutScheduler, 
core.sskPutScheduler, 
SimpleManifestPutter.bucketsByNameToManifestEntries(bucketsByName), 
priorityClass, insertURI, defaultName, getInserterContext(true), false, this);
                putter.start();
                return pw.waitForCompletion();
        }
@@ -177,7 +178,7 @@
                                FETCH_SPLITFILES, FOLLOW_REDIRECTS, 
LOCAL_REQUESTS_ONLY,
                                MAX_SPLITFILE_BLOCKS_PER_SEGMENT, 
MAX_SPLITFILE_CHECK_BLOCKS_PER_SEGMENT,
                                random, archiveManager, bucketFactory, 
globalEventProducer, 
-                               cacheLocalRequests, node.uskManager, 
healingQueue);
+                               cacheLocalRequests, core.uskManager, 
healingQueue);
        }

        public InserterContext getInserterContext(boolean forceNonPersistent) {
@@ -185,6 +186,6 @@
                                forceNonPersistent ? new 
NullPersistentFileTracker() : persistentFileTracker,
                                random, INSERT_RETRIES, 
CONSECUTIVE_RNFS_ASSUME_SUCCESS,
                                SPLITFILE_INSERT_THREADS, 
SPLITFILE_BLOCKS_PER_SEGMENT, SPLITFILE_CHECK_BLOCKS_PER_SEGMENT, 
-                               globalEventProducer, cacheLocalRequests, 
node.uskManager);
+                               globalEventProducer, cacheLocalRequests, 
core.uskManager);
        }
 }

Modified: trunk/freenet/src/freenet/client/async/BaseSingleFileFetcher.java
===================================================================
--- trunk/freenet/src/freenet/client/async/BaseSingleFileFetcher.java   
2006-08-12 18:13:01 UTC (rev 10047)
+++ trunk/freenet/src/freenet/client/async/BaseSingleFileFetcher.java   
2006-08-12 19:24:25 UTC (rev 10048)
@@ -7,6 +7,7 @@
 import freenet.keys.ClientSSK;
 import freenet.node.LowLevelGetException;
 import freenet.node.Node;
+import freenet.node.NodeClientCore;
 import freenet.node.SendableGet;
 import freenet.support.Logger;

@@ -32,7 +33,7 @@
        }

        /** Do the request, blocking. Called by RequestStarter. */
-       public void send(Node node) {
+       public void send(NodeClientCore core) {
                synchronized (this) {
                        if(cancelled) {
                                onFailure(new 
LowLevelGetException(LowLevelGetException.CANCELLED));
@@ -42,7 +43,7 @@
                // Do we need to support the last 3?
                ClientKeyBlock block;
                try {
-                       block = node.realGetKey(key, ctx.localRequestOnly, 
ctx.cacheLocalRequests, ctx.ignoreStore);
+                       block = core.realGetKey(key, ctx.localRequestOnly, 
ctx.cacheLocalRequests, ctx.ignoreStore);
                } catch (LowLevelGetException e) {
                        onFailure(e);
                        return;

Modified: trunk/freenet/src/freenet/client/async/SingleBlockInserter.java
===================================================================
--- trunk/freenet/src/freenet/client/async/SingleBlockInserter.java     
2006-08-12 18:13:01 UTC (rev 10047)
+++ trunk/freenet/src/freenet/client/async/SingleBlockInserter.java     
2006-08-12 19:24:25 UTC (rev 10048)
@@ -16,6 +16,7 @@
 import freenet.keys.SSKEncodeException;
 import freenet.node.LowLevelPutException;
 import freenet.node.Node;
+import freenet.node.NodeClientCore;
 import freenet.node.SendableInsert;
 import freenet.support.Logger;
 import freenet.support.SimpleFieldSet;
@@ -269,12 +270,12 @@
                return finished;
        }

-       public void send(Node node) {
+       public void send(NodeClientCore core) {
                try {
                        Logger.minor(this, "Starting request: "+this);
                        ClientKeyBlock b = getBlock();
                        if(b != null)
-                               node.realPut(b, ctx.cacheLocalRequests);
+                               core.realPut(b, ctx.cacheLocalRequests);
                        else
                                fail(new 
InserterException(InserterException.CANCELLED));
                } catch (LowLevelPutException e) {

Modified: trunk/freenet/src/freenet/client/async/USKManager.java
===================================================================
--- trunk/freenet/src/freenet/client/async/USKManager.java      2006-08-12 
18:13:01 UTC (rev 10047)
+++ trunk/freenet/src/freenet/client/async/USKManager.java      2006-08-12 
19:24:25 UTC (rev 10048)
@@ -5,6 +5,7 @@
 import freenet.client.FetcherContext;
 import freenet.keys.USK;
 import freenet.node.Node;
+import freenet.node.NodeClientCore;
 import freenet.node.RequestStarter;
 import freenet.support.LRUQueue;
 import freenet.support.Logger;
@@ -51,12 +52,12 @@
                this.sskRequestScheduler = sskRequestScheduler;
        }

-       public USKManager(Node node) {
-               backgroundFetchContext = 
node.makeClient(RequestStarter.UPDATE_PRIORITY_CLASS).getFetcherContext();
+       public USKManager(NodeClientCore core) {
+               backgroundFetchContext = 
core.makeClient(RequestStarter.UPDATE_PRIORITY_CLASS).getFetcherContext();
                backgroundFetchContext.followRedirects = false;
                backgroundFetchContext.uskManager = this;
-               this.chkRequestScheduler = node.chkFetchScheduler;
-               this.sskRequestScheduler = node.sskFetchScheduler;
+               this.chkRequestScheduler = core.chkFetchScheduler;
+               this.sskRequestScheduler = core.sskFetchScheduler;
                latestVersionByClearUSK = new HashMap();
                subscribersByClearUSK = new HashMap();
                fetchersByUSK = new HashMap();

Modified: trunk/freenet/src/freenet/clients/http/BookmarkManager.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/BookmarkManager.java 2006-08-12 
18:13:01 UTC (rev 10047)
+++ trunk/freenet/src/freenet/clients/http/BookmarkManager.java 2006-08-12 
19:24:25 UTC (rev 10048)
@@ -7,6 +7,7 @@
 import freenet.keys.USK;
 import freenet.keys.FreenetURI;
 import freenet.node.Node;
+import freenet.node.NodeClientCore;
 import freenet.config.StringArrCallback;
 import freenet.config.StringArrOption;
 import freenet.config.InvalidConfigValueException;
@@ -21,7 +22,7 @@
                "USK at 
PFeLTa1si2Ml5sDeUy7eDhPso6TPdmw-2gWfQ4Jg02w,3ocfrqgUMVWA2PeorZx40TW0c-FiIOL-TWKQHoDbVdE,AQABAAE/Index/-1/=Darknet
 Index"
        };
        Vector bookmarks;
-       Node node;
+       NodeClientCore node;
        USKUpdatedCallback uskcb;

        public class BookmarkCallback implements StringArrCallback {
@@ -74,11 +75,11 @@
                                }
                        }

-                       node.config.store();
+                       node.storeConfig();
                }
        }

-       public BookmarkManager(Node n, SubConfig sc) {
+       public BookmarkManager(NodeClientCore n, SubConfig sc) {
                this.bookmarks = new Vector();
                this.node = n;
                this.uskcb = new USKUpdatedCallback();
@@ -134,7 +135,7 @@
                        try {
                                USK u = USK.create(b.key);
                                this.node.uskManager.subscribe(u, this.uskcb, 
true);
-                               node.config.store();
+                               node.storeConfig();
                        } catch (MalformedURLException mue) {

                        }
@@ -151,6 +152,6 @@
                        }
                }
                this.bookmarks.remove(b);
-               node.config.store();
+               node.storeConfig();
        }
 }

Modified: trunk/freenet/src/freenet/clients/http/ConfigToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/ConfigToadlet.java   2006-08-12 
18:13:01 UTC (rev 10047)
+++ trunk/freenet/src/freenet/clients/http/ConfigToadlet.java   2006-08-12 
19:24:25 UTC (rev 10048)
@@ -9,6 +9,7 @@
 import freenet.config.Option;
 import freenet.config.SubConfig;
 import freenet.node.Node;
+import freenet.node.NodeClientCore;
 import freenet.support.HTMLNode;
 import freenet.support.Logger;
 import freenet.support.MultiValueTable;
@@ -19,11 +20,13 @@
 // FIXME: add logging, comments
 public class ConfigToadlet extends Toadlet {
        private Config config;
+       private final NodeClientCore core;
        private final Node node;

-       ConfigToadlet(HighLevelSimpleClient client, Config conf, Node node) {
+       ConfigToadlet(HighLevelSimpleClient client, Config conf, Node node, 
NodeClientCore core) {
                super(client);
                config=conf;
+               this.core = core;
                this.node = node;
        }

@@ -48,7 +51,7 @@
                }

                String pass = request.getParam("formPassword");
-               if((pass == null) || !pass.equals(node.formPassword)) {
+               if((pass == null) || !pass.equals(core.formPassword)) {
                        MultiValueTable headers = new MultiValueTable();
                        headers.put("Location", "/config/");
                        ctx.sendReplyHeaders(302, "Found", headers, null, 0);
@@ -106,7 +109,7 @@

        public void handleGet(URI uri, ToadletContext ctx) throws 
ToadletContextClosedException, IOException {
                SubConfig[] sc = config.getConfigs();
-               boolean advancedEnabled = 
node.getToadletContainer().isAdvancedDarknetEnabled();
+               boolean advancedEnabled = core.isAdvancedDarknetEnabled();

                HTMLNode pageNode = ctx.getPageMaker().getPageNode("Freenet 
Node Configuration of " + node.getMyName());
                HTMLNode contentNode = 
ctx.getPageMaker().getContentNode(pageNode);
@@ -115,7 +118,7 @@
                infobox.addChild("div", "class", "infobox-header", "Freenet 
node configuration");
                HTMLNode configNode = infobox.addChild("div", "class", 
"infobox-content");
                HTMLNode formNode = configNode.addChild("form", new String[] { 
"action", "method" }, new String[] { ".", "post" });
-               formNode.addChild("input", new String[] { "type", "name", 
"value" }, new String[] { "hidden", "formPassword", node.formPassword });
+               formNode.addChild("input", new String[] { "type", "name", 
"value" }, new String[] { "hidden", "formPassword", core.formPassword });

                for(int i=0; i<sc.length;i++){
                        short displayedConfigElements = 0;

Modified: trunk/freenet/src/freenet/clients/http/DarknetConnectionsToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/DarknetConnectionsToadlet.java       
2006-08-12 18:13:01 UTC (rev 10047)
+++ trunk/freenet/src/freenet/clients/http/DarknetConnectionsToadlet.java       
2006-08-12 19:24:25 UTC (rev 10048)
@@ -21,6 +21,7 @@
 import freenet.io.comm.PeerParseException;
 import freenet.node.FSParseException;
 import freenet.node.Node;
+import freenet.node.NodeClientCore;
 import freenet.node.PeerNode;
 import freenet.node.PeerNodeStatus;
 import freenet.support.HTMLNode;
@@ -47,11 +48,13 @@

        }

-       private Node node;
+       private final Node node;
+       private final NodeClientCore core;

-       protected DarknetConnectionsToadlet(Node n, HighLevelSimpleClient 
client) {
+       protected DarknetConnectionsToadlet(Node n, NodeClientCore core, 
HighLevelSimpleClient client) {
                super(client);
                this.node = n;
+               this.core = core;
        }

        public String supportedMethods() {
@@ -86,7 +89,7 @@
                        return;
                }

-               final boolean advancedEnabled = 
node.getToadletContainer().isAdvancedDarknetEnabled();
+               final boolean advancedEnabled = node.isAdvancedDarknetEnabled();

                /* gather connection statistics */
                PeerNodeStatus[] peerNodeStatuses = node.getPeerNodeStatuses();
@@ -129,7 +132,7 @@
                // FIXME! We need some nice images
                long now = System.currentTimeMillis();

-               contentNode.addChild(node.alerts.createSummary());
+               contentNode.addChild(core.alerts.createSummary());

                /* node status values */
                int bwlimitDelayTime = (int) node.getBwlimitDelayTime();
@@ -268,7 +271,7 @@
                        peerTableInfoboxContent.addChild("#", " and read the 
top infobox to see how it is done.");
                } else {
                        HTMLNode peerForm = 
peerTableInfoboxContent.addChild("form", new String[] { "action", "method", 
"enctype" }, new String[] { ".", "post", "multipart/form-data" });
-                       peerForm.addChild("input", new String[] { "type", 
"name", "value" }, new String[] { "hidden", "formPassword", node.formPassword 
});
+                       peerForm.addChild("input", new String[] { "type", 
"name", "value" }, new String[] { "hidden", "formPassword", core.formPassword 
});
                        HTMLNode peerTable = peerForm.addChild("table", 
"class", "darknet_connections");
                        HTMLNode peerTableHeaderRow = peerTable.addChild("tr");
                        peerTableHeaderRow.addChild("th");
@@ -423,7 +426,7 @@
                peerAdditionInfobox.addChild("div", "class", "infobox-header", 
"Add another peer");
                HTMLNode peerAdditionContent = 
peerAdditionInfobox.addChild("div", "class", "infobox-content");
                HTMLNode peerAdditionForm = 
peerAdditionContent.addChild("form", new String[] { "action", "method", 
"enctype" }, new String[] { ".", "post", "multipart/form-data" });
-               peerAdditionForm.addChild("input", new String[] { "type", 
"name", "value" }, new String[] { "hidden", "formPassword", node.formPassword 
});
+               peerAdditionForm.addChild("input", new String[] { "type", 
"name", "value" }, new String[] { "hidden", "formPassword", core.formPassword 
});
                peerAdditionForm.addChild("#", "Paste the reference here:");
                peerAdditionForm.addChild("br");
                peerAdditionForm.addChild("textarea", new String[] { "id", 
"name", "rows", "cols" }, new String[] { "reftext", "ref", "8", "74" });
@@ -455,7 +458,7 @@
                HTTPRequest request = new HTTPRequest(uri, data, ctx);

                String pass = request.getPartAsString("formPassword", 32);
-               if((pass == null) || !pass.equals(node.formPassword)) {
+               if((pass == null) || !pass.equals(core.formPassword)) {
                        MultiValueTable headers = new MultiValueTable();
                        headers.put("Location", "/darknet/");
                        ctx.sendReplyHeaders(302, "Found", headers, null, 0);

Modified: trunk/freenet/src/freenet/clients/http/FProxyToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/FProxyToadlet.java   2006-08-12 
18:13:01 UTC (rev 10047)
+++ trunk/freenet/src/freenet/clients/http/FProxyToadlet.java   2006-08-12 
19:24:25 UTC (rev 10048)
@@ -23,6 +23,7 @@
 import freenet.config.SubConfig;
 import freenet.keys.FreenetURI;
 import freenet.node.Node;
+import freenet.node.NodeClientCore;
 import freenet.node.RequestStarter;
 import freenet.support.Base64;
 import freenet.support.HTMLNode;
@@ -36,19 +37,19 @@
 public class FProxyToadlet extends Toadlet {

        final byte[] random;
-       final Node node;
+       final NodeClientCore core;

        // ?force= links become invalid after 2 hours.
        long FORCE_GRAIN_INTERVAL = 60*60*1000;
        /** Maximum size for transparent pass-through, should be a config 
option */
        static final long MAX_LENGTH = 2*1024*1024; // 2MB

-       public FProxyToadlet(HighLevelSimpleClient client, byte[] random, Node 
node) {
+       public FProxyToadlet(HighLevelSimpleClient client, byte[] random, 
NodeClientCore core) {
                super(client);
                this.random = random;
                client.setMaxLength(MAX_LENGTH);
                client.setMaxIntermediateLength(MAX_LENGTH);
-               this.node = node;
+               this.core = core;
        }

        public String supportedMethods() {
@@ -278,7 +279,7 @@
                                optionForm.addChild("input", new String[] { 
"type", "name", "value" }, new String[] { "hidden", "key", key.toString(false) 
});
                                optionForm.addChild("input", new String[] { 
"type", "name", "value" }, new String[] { "hidden", "return-type", "disk" });
                                optionForm.addChild("input", new String[] { 
"type", "name", "value" }, new String[] { "hidden", "persistence", "forever" });
-                               optionForm.addChild("input", new String[] { 
"type", "name", "value" }, new String[] { "hidden", "formPassword", 
node.formPassword });
+                               optionForm.addChild("input", new String[] { 
"type", "name", "value" }, new String[] { "hidden", "formPassword", 
core.formPassword });
                                if (mime != null) {
                                        optionForm.addChild("input", new 
String[] { "type", "name", "value" }, new String[] { "hidden", "type", mime });
                                }
@@ -332,30 +333,31 @@
                }
        }

-       public static void maybeCreateFProxyEtc(Node node, Config config, 
SubConfig fproxyConfig) throws IOException, InvalidConfigValueException {
+       public static void maybeCreateFProxyEtc(NodeClientCore core, Node node, 
Config config, SubConfig fproxyConfig) throws IOException, 
InvalidConfigValueException {

                try {
-                       SimpleToadletServer server = new 
SimpleToadletServer(fproxyConfig, node);

-                       HighLevelSimpleClient client = 
node.makeClient(RequestStarter.INTERACTIVE_PRIORITY_CLASS);
+                       SimpleToadletServer server = new 
SimpleToadletServer(fproxyConfig, core);

-                       node.setToadletContainer(server);
+                       HighLevelSimpleClient client = 
core.makeClient(RequestStarter.INTERACTIVE_PRIORITY_CLASS);
+                       
+                       core.setToadletContainer(server);
                        byte[] random = new byte[32];
-                       node.random.nextBytes(random);
-                       FProxyToadlet fproxy = new FProxyToadlet(client, 
random, node);
-                       node.setFProxy(fproxy);
+                       core.random.nextBytes(random);
+                       FProxyToadlet fproxy = new FProxyToadlet(client, 
random, core);
+                       core.setFProxy(fproxy);
                        server.register(fproxy, "/", false, "Home", "homepage");

-                       PproxyToadlet pproxy = new PproxyToadlet(client, 
node.pluginManager, node);
+                       PproxyToadlet pproxy = new PproxyToadlet(client, 
node.pluginManager, core);
                        server.register(pproxy, "/plugins/", true, "Plugins", 
"configure and manage plugins");

-                       WelcomeToadlet welcometoadlet = new 
WelcomeToadlet(client, node, fproxyConfig);
+                       WelcomeToadlet welcometoadlet = new 
WelcomeToadlet(client, core, node, fproxyConfig);
                        server.register(welcometoadlet, "/welcome/", true);

-                       PluginToadlet pluginToadlet = new PluginToadlet(client, 
node.pluginManager2, node);
+                       PluginToadlet pluginToadlet = new PluginToadlet(client, 
node.pluginManager2, core);
                        server.register(pluginToadlet, "/plugin/", true);

-                       ConfigToadlet configtoadlet = new ConfigToadlet(client, 
config, node);
+                       ConfigToadlet configtoadlet = new ConfigToadlet(client, 
config, node, core);
                        server.register(configtoadlet, "/config/", true, 
"Configuration", "configure your node");

                        StaticToadlet statictoadlet = new StaticToadlet(client);
@@ -364,27 +366,27 @@
                        SymlinkerToadlet symlinkToadlet = new 
SymlinkerToadlet(client, node);
                        server.register(symlinkToadlet, "/sl/", true);

-                       DarknetConnectionsToadlet darknetToadlet = new 
DarknetConnectionsToadlet(node, client);
+                       DarknetConnectionsToadlet darknetToadlet = new 
DarknetConnectionsToadlet(node, core, client);
                        server.register(darknetToadlet, "/darknet/", true, 
"Darknet", "manage darknet connections");

-                       N2NTMToadlet n2ntmToadlet = new N2NTMToadlet(node, 
client);
+                       N2NTMToadlet n2ntmToadlet = new N2NTMToadlet(node, 
core, client);
                        server.register(n2ntmToadlet, "/send_n2ntm/", true);

-                       QueueToadlet queueToadlet = new QueueToadlet(node, 
node.getFCPServer(), client);
+                       QueueToadlet queueToadlet = new QueueToadlet(core, 
core.getFCPServer(), client);
                        server.register(queueToadlet, "/queue/", true, "Queue", 
"manage queued requests");

-                       LocalFileInsertToadlet localFileInsertToadlet = new 
LocalFileInsertToadlet(node, client);
+                       LocalFileInsertToadlet localFileInsertToadlet = new 
LocalFileInsertToadlet(core, client);
                        server.register(localFileInsertToadlet, "/files/", 
true, "Insert Files", "insert files from the local disk");

                        // Now start the server.
                        server.start();

                }catch (BindException e){
-                       Logger.error(node,"Failed to start FProxy port already 
bound: isn't freenet already running ?");
+                       Logger.error(core,"Failed to start FProxy port already 
bound: isn't freenet already running ?");
                        System.err.println("Failed to start FProxy port already 
bound: isn't freenet already running ?");
                        throw new InvalidConfigValueException("Can't bind 
fproxy on that port!");
                }catch (IOException ioe) {
-                       Logger.error(node,"Failed to start FProxy: "+ioe, ioe);
+                       Logger.error(core,"Failed to start FProxy: "+ioe, ioe);
                }

                fproxyConfig.finishedInitialization();

Modified: trunk/freenet/src/freenet/clients/http/LocalFileInsertToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/LocalFileInsertToadlet.java  
2006-08-12 18:13:01 UTC (rev 10047)
+++ trunk/freenet/src/freenet/clients/http/LocalFileInsertToadlet.java  
2006-08-12 19:24:25 UTC (rev 10048)
@@ -8,6 +8,7 @@

 import freenet.client.HighLevelSimpleClient;
 import freenet.node.Node;
+import freenet.node.NodeClientCore;
 import freenet.support.HTMLEncoder;
 import freenet.support.HTMLNode;
 import freenet.support.URLEncoder;
@@ -18,16 +19,16 @@
  */
 public class LocalFileInsertToadlet extends Toadlet {

-       private final Node node;
+       private final NodeClientCore core;

        private File currentPath;

        /**
         * 
         */
-       public LocalFileInsertToadlet(Node node, HighLevelSimpleClient 
highLevelSimpleClient) {
+       public LocalFileInsertToadlet(NodeClientCore core, 
HighLevelSimpleClient highLevelSimpleClient) {
                super(highLevelSimpleClient);
-               this.node = node;
+               this.core = core;
        }

        /**
@@ -53,7 +54,7 @@

                HTMLNode pageNode = pageMaker.getPageNode("Listing of " + 
currentPath.getAbsolutePath());
                HTMLNode contentNode = pageMaker.getContentNode(pageNode);
-               contentNode.addChild(node.alerts.createSummary());
+               contentNode.addChild(core.alerts.createSummary());

                HTMLNode infoboxDiv = contentNode.addChild("div", "class", 
"infobox");
                infoboxDiv.addChild("div", "class", "infobox-header", 
"Directory Listing: " + currentPath.getAbsolutePath());
@@ -114,7 +115,7 @@
                                        if (currentFile.canRead()) {
                                                HTMLNode cellNode = 
fileRow.addChild("td");
                                                HTMLNode formNode = 
cellNode.addChild("form", new String[] { "action", "method", "accept-charset" 
}, new String[] { "/queue/", "post", "utf-8" });
-                                               formNode.addChild("input", new 
String[] { "type", "name", "value" }, new String[] { "hidden", "formPassword", 
node.formPassword });
+                                               formNode.addChild("input", new 
String[] { "type", "name", "value" }, new String[] { "hidden", "formPassword", 
core.formPassword });
                                                formNode.addChild("input", new 
String[] { "type", "name", "value" }, new String[] { "hidden", "filename", 
currentFile.getAbsolutePath() });
                                                formNode.addChild("input", new 
String[] { "type", "name", "value" }, new String[] { "submit", "insert-local", 
"Insert" });
                                                fileRow.addChild("td", 
currentFile.getName());

Modified: trunk/freenet/src/freenet/clients/http/N2NTMToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/N2NTMToadlet.java    2006-08-12 
18:13:01 UTC (rev 10047)
+++ trunk/freenet/src/freenet/clients/http/N2NTMToadlet.java    2006-08-12 
19:24:25 UTC (rev 10048)
@@ -9,8 +9,8 @@
 import freenet.io.comm.NotConnectedException;
 import freenet.io.comm.UdpSocketManager;
 import freenet.node.Node;
+import freenet.node.NodeClientCore;
 import freenet.node.PeerNode;
-import freenet.support.HTMLEncoder;
 import freenet.support.HTMLNode;
 import freenet.support.Logger;
 import freenet.support.MultiValueTable;
@@ -19,11 +19,13 @@
 public class N2NTMToadlet extends Toadlet {

   private Node node;
+  private NodeClientCore core;
   private UdpSocketManager usm;

-  protected N2NTMToadlet(Node n, HighLevelSimpleClient client) {
+  protected N2NTMToadlet(Node n, NodeClientCore core, HighLevelSimpleClient 
client) {
     super(client);
     this.node = n;
+    this.core = core;
     this.usm = n.getUSM();
   }

@@ -68,7 +70,7 @@
                  infobox.addChild("div", "class", "infobox-header", "Send Node 
to Node Text Message");
                  HTMLNode infoboxContent = infobox.addChild("div", "class", 
"infobox-content");
                  HTMLNode messageForm = infoboxContent.addChild("form", new 
String[] { "action", "method", "enctype" }, new String[] { ".", "post", 
"multipart/form-data" });
-                 messageForm.addChild("input", new String[] { "type", "name", 
"value" }, new String[] { "hidden", "formPassword", node.formPassword });
+                 messageForm.addChild("input", new String[] { "type", "name", 
"value" }, new String[] { "hidden", "formPassword", core.formPassword });
                  messageForm.addChild("input", new String[] { "type", "name", 
"value" }, new String[] { "hidden", "hashcode", input_hashcode_string });
                  messageForm.addChild("textarea", new String[] { "id", "name", 
"rows", "cols" }, new String[] { "n2ntmtext", "message", "8", "74" });
                  messageForm.addChild("br");
@@ -103,7 +105,7 @@
          HTTPRequest request = new HTTPRequest(uri, data, ctx);

          String pass = request.getPartAsString("formPassword", 32);
-         if((pass == null) || !pass.equals(node.formPassword)) {
+         if((pass == null) || !pass.equals(core.formPassword)) {
                  MultiValueTable headers = new MultiValueTable();
                  headers.put("Location", "/send_n2ntm/");
                  ctx.sendReplyHeaders(302, "Found", headers, null, 0);

Modified: trunk/freenet/src/freenet/clients/http/NinjaSpider.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/NinjaSpider.java     2006-08-12 
18:13:01 UTC (rev 10047)
+++ trunk/freenet/src/freenet/clients/http/NinjaSpider.java     2006-08-12 
19:24:25 UTC (rev 10048)
@@ -1,5 +1,6 @@
 package freenet.clients.http;

+import java.io.File;
 import java.io.IOException;
 import java.net.MalformedURLException;
 import java.net.URI;
@@ -14,21 +15,19 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-import java.io.File;

-
-/* XML */
-import org.w3c.dom.Document;
-import javax.xml.parsers.DocumentBuilderFactory;
 import javax.xml.parsers.DocumentBuilder;
-import org.w3c.dom.DOMImplementation;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
 import javax.xml.transform.stream.StreamResult;
+
+import org.w3c.dom.DOMImplementation;
+import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 import org.w3c.dom.Text;
-import javax.xml.transform.dom.DOMSource;
-import javax.xml.transform.TransformerFactory;
-import javax.xml.transform.Transformer;
-import javax.xml.transform.OutputKeys;

 import freenet.client.ClientMetadata;
 import freenet.client.FetchException;
@@ -42,11 +41,10 @@
 import freenet.clients.http.filter.FoundURICallback;
 import freenet.clients.http.filter.UnsafeContentTypeException;
 import freenet.keys.FreenetURI;
-import freenet.node.Node;
+import freenet.node.NodeClientCore;
 import freenet.node.RequestStarter;
 import freenet.plugin.HttpPlugin;
 import freenet.plugin.PluginManager;
-import freenet.support.HTMLEncoder;
 import freenet.support.HTMLNode;
 import freenet.support.Logger;
 import freenet.support.MultiValueTable;
@@ -90,7 +88,7 @@
        private static final int maxParallelRequests = 20;
        private int maxShownURIs = 50;

-       private Node node;
+       private NodeClientCore core;
        private FetcherContext ctx;
        private final short PRIORITY_CLASS = 
RequestStarter.PREFETCH_PRIORITY_CLASS;
        private boolean stopped = true;
@@ -183,7 +181,7 @@
        }

        private ClientGetter makeGetter(FreenetURI uri) {
-               ClientGetter g = new ClientGetter(this, node.chkFetchScheduler, 
node.sskFetchScheduler, uri, ctx, PRIORITY_CLASS, this, null);
+               ClientGetter g = new ClientGetter(this, core.chkFetchScheduler, 
core.sskFetchScheduler, uri, ctx, PRIORITY_CLASS, this, null);
                return g;
        }

@@ -696,8 +694,8 @@
         * @see 
freenet.plugin.Plugin#setPluginManager(freenet.plugin.PluginManager)
         */
        public void setPluginManager(PluginManager pluginManager) {
-               this.node = pluginManager.getNode();
-               this.ctx = node.makeClient((short) 0).getFetcherContext();
+               this.core = pluginManager.getClientCore();
+               this.ctx = core.makeClient((short) 0).getFetcherContext();
                ctx.maxSplitfileBlockRetries = 10;
                ctx.maxNonSplitfileRetries = 10;
                ctx.maxTempLength = 2 * 1024 * 1024;
@@ -710,7 +708,7 @@
         * @see freenet.plugin.Plugin#startPlugin()
         */
        public void startPlugin() {
-               FreenetURI[] initialURIs = 
node.bookmarkManager.getBookmarkURIs();
+               FreenetURI[] initialURIs = 
core.bookmarkManager.getBookmarkURIs();
                for (int i = 0; i < initialURIs.length; i++)
                        queueURI(initialURIs[i]);
                stopped = false;

Modified: trunk/freenet/src/freenet/clients/http/PluginToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/PluginToadlet.java   2006-08-12 
18:13:01 UTC (rev 10047)
+++ trunk/freenet/src/freenet/clients/http/PluginToadlet.java   2006-08-12 
19:24:25 UTC (rev 10048)
@@ -8,6 +8,7 @@

 import freenet.client.HighLevelSimpleClient;
 import freenet.node.Node;
+import freenet.node.NodeClientCore;
 import freenet.plugin.HttpPlugin;
 import freenet.plugin.Plugin;
 import freenet.plugin.PluginManager;
@@ -26,7 +27,7 @@

        /** The plugin manager backing this toadlet. */
        private final PluginManager pluginManager;
-       private final Node node;
+       private final NodeClientCore core;

        /**
         * Creates a new toadlet.
@@ -36,10 +37,10 @@
         * @param pluginManager
         *            The plugin manager to use
         */
-       protected PluginToadlet(HighLevelSimpleClient client, PluginManager 
pluginManager, Node n) {
+       protected PluginToadlet(HighLevelSimpleClient client, PluginManager 
pluginManager, NodeClientCore core) {
                super(client);
                this.pluginManager = pluginManager;
-               this.node = n;
+               this.core = core;
        }

        /**
@@ -122,7 +123,7 @@
                }

                String pass = httpRequest.getParam("formPassword");
-               if((pass == null) || !pass.equals(node.formPassword)) {
+               if((pass == null) || !pass.equals(core.formPassword)) {
                        MultiValueTable headers = new MultiValueTable();
                        headers.put("Location", "/plugin/");
                        ctx.sendReplyHeaders(302, "Found", headers, null, 0);
@@ -222,12 +223,12 @@
                        reloadForm.addChild("input", new String[] { "type", 
"name", "value" }, new String[] { "hidden", "action", "reload" });
                        reloadForm.addChild("input", new String[] { "type", 
"name", "value" }, new String[] { "hidden", "pluginName", internalName });
                        reloadForm.addChild("input", new String[] { "type", 
"value" }, new String[] { "submit", "Reload" });
-                       reloadForm.addChild("input", new String[] { "type", 
"name", "value" }, new String[] { "hidden", "formPassword", node.formPassword 
});
+                       reloadForm.addChild("input", new String[] { "type", 
"name", "value" }, new String[] { "hidden", "formPassword", core.formPassword 
});
                        HTMLNode unloadForm = 
tableRow.addChild("td").addChild("form", new String[] { "action", "method" }, 
new String[] { ".", "post" });
                        unloadForm.addChild("input", new String[] { "type", 
"name", "value" }, new String[] { "hidden", "action", "unload" });
                        unloadForm.addChild("input", new String[] { "type", 
"name", "value" }, new String[] { "hidden", "pluginName", internalName });
                        unloadForm.addChild("input", new String[] { "type", 
"value" }, new String[] { "submit", "Unload" });
-                       unloadForm.addChild("input", new String[] { "type", 
"name", "value" }, new String[] { "hidden", "formPassword", node.formPassword 
});
+                       unloadForm.addChild("input", new String[] { "type", 
"name", "value" }, new String[] { "hidden", "formPassword", core.formPassword 
});
                }

                contentNode.addChild(createAddPluginBox());
@@ -278,7 +279,7 @@
                addPluginBox.addChild("div", "class", "infobox-header", "Add a 
plugin");
                HTMLNode addForm = addPluginBox.addChild("div", "class", 
"infobox-content").addChild("form", new String[] { "action", "method" }, new 
String[] { ".", "post" });
                addForm.addChild("input", new String[] { "type", "name", 
"value" }, new String[] { "hidden", "action", "add" });
-               addForm.addChild("input", new String[] { "type", "name", 
"value" }, new String[] { "hidden", "formPassword", node.formPassword });
+               addForm.addChild("input", new String[] { "type", "name", 
"value" }, new String[] { "hidden", "formPassword", core.formPassword });
                addForm.addChild("input", new String[] { "type", "name", 
"value", "size" }, new String[] { "text", "pluginName", "", "40" });
                addForm.addChild("input", new String[] { "type", "value" }, new 
String[] { "submit", "Load plugin" });
                return addPluginBox;

Modified: trunk/freenet/src/freenet/clients/http/PproxyToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/PproxyToadlet.java   2006-08-12 
18:13:01 UTC (rev 10047)
+++ trunk/freenet/src/freenet/clients/http/PproxyToadlet.java   2006-08-12 
19:24:25 UTC (rev 10048)
@@ -10,6 +10,7 @@

 import freenet.client.HighLevelSimpleClient;
 import freenet.node.Node;
+import freenet.node.NodeClientCore;
 import freenet.pluginmanager.PluginHTTPException;
 import freenet.pluginmanager.PluginInfoWrapper;
 import freenet.pluginmanager.PluginManager;
@@ -21,12 +22,12 @@

 public class PproxyToadlet extends Toadlet {
        private final PluginManager pm;
-       private final Node node;
+       private final NodeClientCore core;

-       public PproxyToadlet(HighLevelSimpleClient client, PluginManager pm, 
Node n) {
+       public PproxyToadlet(HighLevelSimpleClient client, PluginManager pm, 
NodeClientCore core) {
                super(client);
                this.pm = pm;
-               this.node = n;
+               this.core = core;
        }

        public String supportedMethods() {
@@ -55,7 +56,7 @@
                MultiValueTable headers = new MultiValueTable();

                String pass = request.getParam("formPassword");
-               if((pass == null) || !pass.equals(node.formPassword)) {
+               if((pass == null) || !pass.equals(core.formPassword)) {
                        MultiValueTable hdrs = new MultiValueTable();
                        headers.put("Location", "/queue/");
                        ctx.sendReplyHeaders(302, "Found", hdrs, null, 0);
@@ -93,7 +94,7 @@
                        HTMLNode infoboxContent = infobox.addChild("div", 
"class", "infobox-content");
                        infoboxContent.addChild("#", "Are you sure you wish to 
unload " + request.getParam("unload") + "?");
                        HTMLNode unloadForm = infoboxContent.addChild("form", 
new String[] { "action", "method" }, new String[] { "/plugins/", "post" });
-                       unloadForm.addChild("input", new String[] { "type", 
"name", "value" }, new String[] { "hidden", "formPassword", node.formPassword 
});
+                       unloadForm.addChild("input", new String[] { "type", 
"name", "value" }, new String[] { "hidden", "formPassword", core.formPassword 
});
                        unloadForm.addChild("input", new String[] { "type", 
"name", "value" }, new String[] { "submit", "cancel", "Cancel" });
                        unloadForm.addChild("input", new String[] { "type", 
"name", "value" }, new String[] { "hidden", "unloadconfirm", 
request.getParam("unload") });
                        unloadForm.addChild("input", new String[] { "type", 
"name", "value" }, new String[] { "submit", "confirm", "Unload" });
@@ -185,7 +186,7 @@

        private void showPluginList(ToadletContext ctx, HTTPRequest request) 
throws ToadletContextClosedException, IOException {
                if (!request.hasParameters()) {
-                       HTMLNode pageNode = 
ctx.getPageMaker().getPageNode("Plugins of " + node.getMyName());
+                       HTMLNode pageNode = 
ctx.getPageMaker().getPageNode("Plugins of " + core.getMyName());
                        HTMLNode contentNode = 
ctx.getPageMaker().getContentNode(pageNode);

                        HTMLNode infobox = contentNode.addChild("div", "class", 
"infobox infobox-normal");
@@ -212,22 +213,22 @@
                                        HTMLNode actionCell = 
pluginRow.addChild("td");
                                        if (pi.isPproxyPlugin()) {
                                                HTMLNode visitForm = 
actionCell.addChild("form", new String[] { "method", "action" }, new String[] { 
"get", pi.getPluginClassName() });
-                                               visitForm.addChild("input", new 
String[] { "type", "name", "value" }, new String[] { "hidden", "formPassword", 
node.formPassword });
+                                               visitForm.addChild("input", new 
String[] { "type", "name", "value" }, new String[] { "hidden", "formPassword", 
core.formPassword });
                                                visitForm.addChild("input", new 
String[] { "type", "value" }, new String[] { "submit", "Visit" });
                                        }
                                        HTMLNode unloadForm = 
actionCell.addChild("form", new String[] { "action", "method" }, new String[] { 
".", "post" });
-                                       unloadForm.addChild("input", new 
String[] { "type", "name", "value" }, new String[] { "hidden", "formPassword", 
node.formPassword });
+                                       unloadForm.addChild("input", new 
String[] { "type", "name", "value" }, new String[] { "hidden", "formPassword", 
core.formPassword });
                                        unloadForm.addChild("input", new 
String[] { "type", "name", "value" }, new String[] { "hidden", "unload", 
pi.getThreadName() });
                                        unloadForm.addChild("input", new 
String[] { "type", "value" }, new String[] { "submit", "Unload" });
                                        HTMLNode reloadForm = 
actionCell.addChild("form", new String[] { "action", "method" }, new String[] { 
".", "post" });
-                                       reloadForm.addChild("input", new 
String[] { "type", "name", "value" }, new String[] { "hidden", "formPassword", 
node.formPassword });
+                                       reloadForm.addChild("input", new 
String[] { "type", "name", "value" }, new String[] { "hidden", "formPassword", 
core.formPassword });
                                        reloadForm.addChild("input", new 
String[] { "type", "name", "value" }, new String[] { "hidden", "reload", 
pi.getThreadName() });
                                        reloadForm.addChild("input", new 
String[] { "type", "value" }, new String[] { "submit", "Reload" });
                                }
                        }

                        HTMLNode addForm = infoboxContent.addChild("form", new 
String[] { "action", "method" }, new String[] { ".", "post" });
-                       addForm.addChild("input", new String[] { "type", 
"name", "value" }, new String[] { "hidden", "formPassword", node.formPassword 
});
+                       addForm.addChild("input", new String[] { "type", 
"name", "value" }, new String[] { "hidden", "formPassword", core.formPassword 
});
                        HTMLNode loadDiv = addForm.addChild("div");
                        loadDiv.addChild("#", "Load plugin: ");
                        loadDiv.addChild("input", new String[] { "type", 
"name", "size" }, new String[] { "text", "load", "40" });

Modified: trunk/freenet/src/freenet/clients/http/QueueToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/QueueToadlet.java    2006-08-12 
18:13:01 UTC (rev 10047)
+++ trunk/freenet/src/freenet/clients/http/QueueToadlet.java    2006-08-12 
19:24:25 UTC (rev 10048)
@@ -15,6 +15,7 @@
 import freenet.client.HighLevelSimpleClient;
 import freenet.keys.FreenetURI;
 import freenet.node.Node;
+import freenet.node.NodeClientCore;
 import freenet.node.RequestStarter;
 import freenet.node.fcp.ClientGet;
 import freenet.node.fcp.ClientPut;
@@ -49,12 +50,12 @@
        private static final int LIST_PROGRESS = 11;
        private static final int LIST_REASON = 12;

-       private Node node;
+       private NodeClientCore core;
        final FCPServer fcp;

-       public QueueToadlet(Node n, FCPServer fcp, HighLevelSimpleClient 
client) {
+       public QueueToadlet(NodeClientCore core, FCPServer fcp, 
HighLevelSimpleClient client) {
                super(client);
-               this.node = n;
+               this.core = core;
                this.fcp = fcp;
                if(fcp == null) throw new NullPointerException();
        }
@@ -71,7 +72,7 @@
                        if (pass.length() == 0) {
                                pass = request.getPartAsString("formPassword", 
128);
                        }
-                       if ((pass.length() == 0) || 
!pass.equals(node.formPassword)) {
+                       if ((pass.length() == 0) || 
!pass.equals(core.formPassword)) {
                                MultiValueTable headers = new MultiValueTable();
                                headers.put("Location", "/queue/");
                                ctx.sendReplyHeaders(302, "Found", headers, 
null, 0);
@@ -162,7 +163,7 @@
                                boolean compress = 
request.getPartAsString("compress", 128).length() > 0;
                                String identifier = file.getFilename() + 
"-fred-" + System.currentTimeMillis();
                                /* copy bucket data */
-                               Bucket copiedBucket = 
node.persistentEncryptedTempBucketFactory.makeBucket(file.getData().size());
+                               Bucket copiedBucket = 
core.persistentEncryptedTempBucketFactory.makeBucket(file.getData().size());
                                BucketTools.copy(file.getData(), copiedBucket);
                                try {
                                        ClientPut clientPut = new 
ClientPut(fcp.getGlobalClient(), insertURI, identifier, Integer.MAX_VALUE, 
RequestStarter.BULK_SPLITFILE_PRIORITY_CLASS, ClientRequest.PERSIST_FOREVER, 
null, false, !compress, -1, ClientPutMessage.UPLOAD_FROM_DIRECT, new 
File(file.getFilename()), file.getContentType(), copiedBucket, null);
@@ -198,7 +199,7 @@
                PageMaker pageMaker = context.getPageMaker();
                HTMLNode pageNode = pageMaker.getPageNode("Error process 
request");
                HTMLNode contentNode = pageMaker.getContentNode(pageNode);
-               contentNode.addChild(node.alerts.createSummary());
+               contentNode.addChild(core.alerts.createSummary());
                HTMLNode infobox = 
contentNode.addChild(pageMaker.getInfobox("infobox-error", "Error process 
request"));
                HTMLNode infoboxContent = pageMaker.getContentNode(infobox);
                infoboxContent.addChild("#", message);
@@ -234,7 +235,7 @@
                Logger.minor(this, "Request count: "+reqs.length);

                if(reqs.length < 1){
-                       HTMLNode pageNode = pageMaker.getPageNode("Global queue 
of " + node.getMyName());
+                       HTMLNode pageNode = pageMaker.getPageNode("Global queue 
of " + core.getMyName());
                        HTMLNode contentNode = 
pageMaker.getContentNode(pageNode);
                        HTMLNode infobox = 
contentNode.addChild(pageMaker.getInfobox("infobox-information", "Global queue 
is empty"));
                        HTMLNode infoboxContent = 
pageMaker.getContentNode(infobox);
@@ -308,11 +309,11 @@
                HTMLNode pageNode = pageMaker.getPageNode("(" + 
(uncompletedDirUpload.size() + uncompletedDownload.size()
                                + uncompletedUpload.size()) + "/" + 
(failedDirUpload.size() + failedDownload.size() + failedUpload.size()) + "/"
                                + (completedDirUpload.size() + 
completedDownloadToDisk.size() + completedDownloadToTemp.size()
-                               + completedUpload.size()) + ") Queued Requests 
of " + node.getMyName());
+                               + completedUpload.size()) + ") Queued Requests 
of " + core.getMyName());
                HTMLNode contentNode = pageMaker.getContentNode(pageNode);

                /* add alert summary box */
-               contentNode.addChild(node.alerts.createSummary());
+               contentNode.addChild(core.alerts.createSummary());
                /* add file insert box */
                contentNode.addChild(createInsertBox(pageMaker));

@@ -378,7 +379,7 @@
                        contentNode.addChild(createPanicBox(pageMaker));
                }

-               boolean advancedEnabled = 
node.getToadletContainer().isAdvancedDarknetEnabled();
+               boolean advancedEnabled = core.isAdvancedDarknetEnabled();

                if (!completedDownloadToTemp.isEmpty()) {
                        contentNode.addChild("a", "name", 
"completedDownloadToTemp");
@@ -514,7 +515,7 @@
                }

                //double frac = p.getSuccessFraction();
-               if (!node.getToadletContainer().isAdvancedDarknetEnabled()) {
+               if (!core.isAdvancedDarknetEnabled()) {
                        total = min;
                }

@@ -565,7 +566,7 @@
        private HTMLNode createPriorityCell(PageMaker pageMaker, String 
identifier, short priorityClass) {
                HTMLNode priorityCell = new HTMLNode("td", "class", 
"request-priority nowrap");
                HTMLNode priorityForm = priorityCell.addChild("form", new 
String[] { "action", "method" }, new String[] { "/queue/", "post" });
-               
priorityForm.addChild(pageMaker.createFormPasswordInput(node.formPassword));
+               
priorityForm.addChild(pageMaker.createFormPasswordInput(core.formPassword));
                priorityForm.addChild("input", new String[] { "type", "name", 
"value" }, new String[] { "hidden", "identifier", identifier });
                HTMLNode prioritySelect = priorityForm.addChild("select", 
"name", "priority");
                for (int p = 0; p < RequestStarter.NUMBER_OF_PRIORITY_CLASSES; 
p++) {
@@ -582,7 +583,7 @@
        private HTMLNode createDeleteCell(PageMaker pageMaker, String 
identifier) {
                HTMLNode deleteNode = new HTMLNode("td", "class", 
"request-delete");
                HTMLNode deleteForm = deleteNode.addChild("form", new String[] 
{ "action", "method" }, new String[] { "/queue/", "post" });
-               
deleteForm.addChild(pageMaker.createFormPasswordInput(node.formPassword));
+               
deleteForm.addChild(pageMaker.createFormPasswordInput(core.formPassword));
                deleteForm.addChild("input", new String[] { "type", "name", 
"value" }, new String[] { "hidden", "identifier", identifier });
                deleteForm.addChild("input", new String[] { "type", "name", 
"value" }, new String[] { "submit", "remove_request", "Delete" });
                return deleteNode;
@@ -591,7 +592,7 @@
        private HTMLNode createPanicBox(PageMaker pageMaker) {
                HTMLNode panicBox = pageMaker.getInfobox("infobox-alert", 
"Panic Button");
                HTMLNode panicForm = 
pageMaker.getContentNode(panicBox).addChild("form", new String[] { "action", 
"method" }, new String[] { "/queue/", "post" });
-               
panicForm.addChild(pageMaker.createFormPasswordInput(node.formPassword));
+               
panicForm.addChild(pageMaker.createFormPasswordInput(core.formPassword));
                panicForm.addChild("input", new String[] { "type", "name", 
"value" }, new String[] { "submit", "remove_AllRequests", "Delete everything 
without confirmation!" });
                return panicBox;
        }
@@ -656,7 +657,7 @@
                /* the insert file box */
                HTMLNode insertBox = pageMaker.getInfobox("Insert File");
                HTMLNode insertForm = 
pageMaker.getContentNode(insertBox).addChild("form", new String[] { "action", 
"method", "enctype" }, new String[] { ".", "post", "multipart/form-data" });
-               
insertForm.addChild(pageMaker.createFormPasswordInput(node.formPassword));
+               
insertForm.addChild(pageMaker.createFormPasswordInput(core.formPassword));
                insertForm.addChild("#", "Insert as: ");
                insertForm.addChild("input", new String[] { "type", "name", 
"value", "checked" }, new String[] { "radio", "keytype", "chk", "checked" });
                insertForm.addChild("#", " CHK \u00a0 ");

Modified: trunk/freenet/src/freenet/clients/http/SimpleToadletServer.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/SimpleToadletServer.java     
2006-08-12 18:13:01 UTC (rev 10047)
+++ trunk/freenet/src/freenet/clients/http/SimpleToadletServer.java     
2006-08-12 19:24:25 UTC (rev 10048)
@@ -26,6 +26,7 @@
 import freenet.crypt.DummyRandomSource;
 import freenet.io.NetworkInterface;
 import freenet.node.Node;
+import freenet.node.NodeClientCore;
 import freenet.support.FileLoggerHook;
 import freenet.support.Logger;
 import freenet.support.FileLoggerHook.IntervalParseException;
@@ -163,7 +164,7 @@
         * Create a SimpleToadletServer, using the settings from the SubConfig 
(the fproxy.*
         * config).
         */
-       public SimpleToadletServer(SubConfig fproxyConfig, Node node) throws 
IOException, InvalidConfigValueException {
+       public SimpleToadletServer(SubConfig fproxyConfig, NodeClientCore core) 
throws IOException, InvalidConfigValueException {

                fproxyConfig.register("enabled", true, 1, true, "Enable 
FProxy?", "Whether to enable FProxy and related HTTP services",
                                new FProxyEnabledCallback());
@@ -222,7 +223,7 @@
                fproxyConfig.register("advancedDarknetEnabled", false, 1, 
false, "Enable Advanced Darknet?", "Whether to show or not informations meant 
for advanced users/devs. This setting should be turned to false in most cases.",
                                new FProxyAdvancedDarknetEnabledCallback(this));

-               this.bf = node.tempBucketFactory;
+               this.bf = core.tempBucketFactory;
                port = fproxyConfig.getInt("port");
                bindTo = fproxyConfig.getString("bindTo");
                allowedHosts = fproxyConfig.getString("allowedHosts");
@@ -233,11 +234,11 @@
                pageMaker = new PageMaker(cssName);

                toadlets = new LinkedList();
-               node.setToadletContainer(this); // even if not enabled, because 
of config
+               core.setToadletContainer(this); // even if not enabled, because 
of config

                this.networkInterface = new NetworkInterface(port, this.bindTo, 
this.allowedHosts);
                if(!enabled) {
-                       Logger.normal(node, "Not starting FProxy as it's 
disabled");
+                       Logger.normal(core, "Not starting FProxy as it's 
disabled");
                        System.out.println("Not starting FProxy as it's 
disabled");
                } else {
                        myThread = new Thread(this, "SimpleToadletServer");

Modified: trunk/freenet/src/freenet/clients/http/Spider.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/Spider.java  2006-08-12 18:13:01 UTC 
(rev 10047)
+++ trunk/freenet/src/freenet/clients/http/Spider.java  2006-08-12 19:24:25 UTC 
(rev 10048)
@@ -32,6 +32,7 @@
 import freenet.clients.http.filter.UnsafeContentTypeException;
 import freenet.keys.FreenetURI;
 import freenet.node.Node;
+import freenet.node.NodeClientCore;
 import freenet.node.RequestStarter;
 import freenet.plugin.HttpPlugin;
 import freenet.plugin.PluginManager;
@@ -63,7 +64,7 @@
        private static final int maxParallelRequests = 20;
        private int maxShownURIs = 50;

-       private Node node;
+       private NodeClientCore core;
        private FetcherContext ctx;
        private final short PRIORITY_CLASS = 
RequestStarter.PREFETCH_PRIORITY_CLASS;
        private boolean stopped = true;
@@ -127,7 +128,7 @@
        }

        private ClientGetter makeGetter(FreenetURI uri) {
-               ClientGetter g = new ClientGetter(this, node.chkFetchScheduler, 
node.sskFetchScheduler, uri, ctx, PRIORITY_CLASS, this, null);
+               ClientGetter g = new ClientGetter(this, core.chkFetchScheduler, 
core.sskFetchScheduler, uri, ctx, PRIORITY_CLASS, this, null);
                return g;
        }

@@ -425,8 +426,8 @@
         * @see 
freenet.plugin.Plugin#setPluginManager(freenet.plugin.PluginManager)
         */
        public void setPluginManager(PluginManager pluginManager) {
-               this.node = pluginManager.getNode();
-               this.ctx = node.makeClient((short) 0).getFetcherContext();
+               this.core = pluginManager.getClientCore();
+               this.ctx = core.makeClient((short) 0).getFetcherContext();
                ctx.maxSplitfileBlockRetries = 10;
                ctx.maxNonSplitfileRetries = 10;
                ctx.maxTempLength = 2 * 1024 * 1024;
@@ -439,7 +440,7 @@
         * @see freenet.plugin.Plugin#startPlugin()
         */
        public void startPlugin() {
-               FreenetURI[] initialURIs = 
node.bookmarkManager.getBookmarkURIs();
+               FreenetURI[] initialURIs = 
core.bookmarkManager.getBookmarkURIs();
                for (int i = 0; i < initialURIs.length; i++)
                        queueURI(initialURIs[i]);
                stopped = false;

Modified: trunk/freenet/src/freenet/clients/http/WelcomeToadlet.java
===================================================================
--- trunk/freenet/src/freenet/clients/http/WelcomeToadlet.java  2006-08-12 
18:13:01 UTC (rev 10047)
+++ trunk/freenet/src/freenet/clients/http/WelcomeToadlet.java  2006-08-12 
19:24:25 UTC (rev 10048)
@@ -13,6 +13,7 @@
 import freenet.config.SubConfig;
 import freenet.keys.FreenetURI;
 import freenet.node.Node;
+import freenet.node.NodeClientCore;
 import freenet.node.NodeStarter;
 import freenet.node.Version;
 import freenet.node.useralerts.UserAlert;
@@ -24,15 +25,17 @@
 public class WelcomeToadlet extends Toadlet {
        private final static int MODE_ADD = 1;
        private final static int MODE_EDIT = 2;
+       NodeClientCore core;
        Node node;
        SubConfig config;
        BookmarkManager bookmarks;

-       WelcomeToadlet(HighLevelSimpleClient client, Node n, SubConfig sc) {
+       WelcomeToadlet(HighLevelSimpleClient client, NodeClientCore core, Node 
node, SubConfig sc) {
                super(client);
-               this.node = n;
+               this.core = core;
+               this.node = node;
                this.config = sc;
-               this.bookmarks = node.bookmarkManager;
+               this.bookmarks = core.bookmarkManager;
        }

        public void handlePost(URI uri, Bucket data, ToadletContext ctx) throws 
ToadletContextClosedException, IOException {
@@ -48,14 +51,14 @@
                if (request.getParam("shutdownconfirm").length() > 0) {
                        // Do the actual shutdown
                        MultiValueTable headers = new MultiValueTable();
-                       headers.put("Location", 
".?shutdownconfirm="+node.formPassword.hashCode());
+                       headers.put("Location", 
".?shutdownconfirm="+core.formPassword.hashCode());
                        ctx.sendReplyHeaders(302, "Found", headers, null, 0);
                        this.node.exit("Shutdown from fproxy");
                        return;
                }else if(request.getParam("restartconfirm").length() > 0){
                        // Do the actual restart
                        MultiValueTable headers = new MultiValueTable();
-                       headers.put("Location", 
".?restartconfirm="+node.formPassword.hashCode());
+                       headers.put("Location", 
".?restartconfirm="+core.formPassword.hashCode());
                        ctx.sendReplyHeaders(302, "Found", headers, null, 0);
                        node.getNodeStarter().restart();
                        return;
@@ -151,7 +154,7 @@
                                return;
                        }
                }else if(request.isParameterSet("disable")){
-                       UserAlert[] alerts=node.alerts.getAlerts();
+                       UserAlert[] alerts=core.alerts.getAlerts();
                        for(int i=0;i<alerts.length;i++){
                                
if(request.getIntParam("disable")==alerts[i].hashCode()){
                                        UserAlert alert = alerts[i];
@@ -159,7 +162,7 @@
                                        if(alert.userCanDismiss() && 
alert.shouldUnregisterOnDismiss()) {
                                                alert.onDismiss();
                                                
Logger.normal(this,"Unregistering the userAlert "+alert.hashCode());
-                                               node.alerts.unregister(alert);
+                                               core.alerts.unregister(alert);
                                        } else {
                                                Logger.normal(this,"Disabling 
the userAlert "+alert.hashCode());
                                                alert.isValid(false);
@@ -215,7 +218,7 @@
        }

        public void handleGet(URI uri, ToadletContext ctx) throws 
ToadletContextClosedException, IOException {
-               boolean advancedDarknetOutputEnabled = 
node.getToadletContainer().isAdvancedDarknetEnabled();
+               boolean advancedDarknetOutputEnabled = 
core.getToadletContainer().isAdvancedDarknetEnabled();

                HTTPRequest request = new HTTPRequest(uri);
                if (request.getParam("newbookmark").length() > 0) {
@@ -257,7 +260,7 @@
                        return;
                }else if (request.getParam("shutdownconfirm").length() > 0) {
                        // Tell the user that the node is shutting down
-                       if(request.getIntParam("shutdownconfirm") != 
node.formPassword.hashCode()){
+                       if(request.getIntParam("shutdownconfirm") != 
core.formPassword.hashCode()){
                                MultiValueTable headers = new MultiValueTable();
                                headers.put("Location", "/");
                                ctx.sendReplyHeaders(302, "Found", headers, 
null, 0);
@@ -272,7 +275,7 @@
                        return;
                }else if(request.getParam("restartconfirm").length() > 0){
                        // Tell the user that the node is restarting
-                       if(request.getIntParam("restartconfirm") != 
node.formPassword.hashCode()){
+                       if(request.getIntParam("restartconfirm") != 
core.formPassword.hashCode()){
                                MultiValueTable headers = new MultiValueTable();
                                headers.put("Location", "/");
                                ctx.sendReplyHeaders(302, "Found", headers, 
null, 0);
@@ -310,7 +313,7 @@
                }

                // Alerts
-               contentNode.addChild(node.alerts.createAlerts());
+               contentNode.addChild(core.alerts.createAlerts());

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

Modified: trunk/freenet/src/freenet/node/ARKFetcher.java
===================================================================
--- trunk/freenet/src/freenet/node/ARKFetcher.java      2006-08-12 18:13:01 UTC 
(rev 10047)
+++ trunk/freenet/src/freenet/node/ARKFetcher.java      2006-08-12 19:24:25 UTC 
(rev 10048)
@@ -91,7 +91,7 @@
                                startedEdition = uri.getSuggestedEdition();
                                fetchingURI = uri;
                                Logger.minor(this, "Fetching ARK: "+uri+" for 
"+peer);
-                               cg = new ClientGetter(this, 
node.chkFetchScheduler, node.sskFetchScheduler, 
+                               cg = new ClientGetter(this, 
node.clientCore.chkFetchScheduler, node.clientCore.sskFetchScheduler, 
                                                uri, node.arkFetcherContext, 
RequestStarter.UPDATE_PRIORITY_CLASS, 
                                                this, new ArrayBucket());
                                getter = cg;

Modified: trunk/freenet/src/freenet/node/CHKInsertSender.java
===================================================================
--- trunk/freenet/src/freenet/node/CHKInsertSender.java 2006-08-12 18:13:01 UTC 
(rev 10047)
+++ trunk/freenet/src/freenet/node/CHKInsertSender.java 2006-08-12 19:24:25 UTC 
(rev 10048)
@@ -236,7 +236,7 @@
             PeerNode next;
             // Can backtrack, so only route to nodes closer than we are to 
target.
             double nextValue;
-            next = node.peers.closerPeer(source, nodesRoutedTo, 
nodesNotIgnored, target, true);
+            next = node.peers.closerPeer(source, nodesRoutedTo, 
nodesNotIgnored, target, true, node.isAdvancedDarknetEnabled());
             if(next != null)
                 nextValue = next.getLocation().getValue();
             else

Modified: trunk/freenet/src/freenet/node/IPDetectorPluginManager.java
===================================================================
--- trunk/freenet/src/freenet/node/IPDetectorPluginManager.java 2006-08-12 
18:13:01 UTC (rev 10047)
+++ trunk/freenet/src/freenet/node/IPDetectorPluginManager.java 2006-08-12 
19:24:25 UTC (rev 10048)
@@ -22,11 +22,11 @@
        private final Node node;
        FredPluginIPDetector[] plugins;

-       IPDetectorPluginManager(Node node) {
+       IPDetectorPluginManager(Node node, NodeIPDetector detector) {
                plugins = new FredPluginIPDetector[0];
                this.node = node;
                this.ticker = node.ps;
-               this.detector = node.ipDetector;
+               this.detector = detector;
        }

        void start() {

Modified: trunk/freenet/src/freenet/node/Node.java
===================================================================
--- trunk/freenet/src/freenet/node/Node.java    2006-08-12 18:13:01 UTC (rev 
10047)
+++ trunk/freenet/src/freenet/node/Node.java    2006-08-12 19:24:25 UTC (rev 
10048)
@@ -30,19 +30,7 @@

 import com.sleepycat.je.DatabaseException;

-import freenet.client.ArchiveManager;
 import freenet.client.FetcherContext;
-import freenet.client.HighLevelSimpleClient;
-import freenet.client.HighLevelSimpleClientImpl;
-import freenet.client.InserterContext;
-import freenet.client.async.ClientRequestScheduler;
-import freenet.client.async.HealingQueue;
-import freenet.client.async.SimpleHealingQueue;
-import freenet.client.async.USKManager;
-import freenet.client.events.SimpleEventProducer;
-import freenet.clients.http.BookmarkManager;
-import freenet.clients.http.FProxyToadlet;
-import freenet.clients.http.SimpleToadletServer;
 import freenet.config.Config;
 import freenet.config.IntCallback;
 import freenet.config.InvalidConfigValueException;
@@ -62,7 +50,6 @@
 import freenet.io.comm.Peer;
 import freenet.io.comm.PeerParseException;
 import freenet.io.comm.UdpSocketManager;
-import freenet.io.xfer.AbortedException;
 import freenet.io.xfer.PartiallyReceivedBlock;
 import freenet.keys.CHKBlock;
 import freenet.keys.CHKVerifyException;
@@ -81,14 +68,12 @@
 import freenet.keys.NodeSSK;
 import freenet.keys.SSKBlock;
 import freenet.keys.SSKVerifyException;
-import freenet.node.fcp.FCPServer;
 import freenet.node.updater.NodeUpdater;
 import freenet.node.useralerts.BuildOldAgeUserAlert;
 import freenet.node.useralerts.ExtOldAgeUserAlert;
 import freenet.node.useralerts.MeaningfulNodeNameUserAlert;
 import freenet.node.useralerts.N2NTMUserAlert;
 import freenet.node.useralerts.UserAlert;
-import freenet.node.useralerts.UserAlertManager;
 import freenet.pluginmanager.PluginManager;
 import freenet.store.BerkeleyDBFreenetStore;
 import freenet.store.FreenetStore;
@@ -106,13 +91,6 @@
 import freenet.support.Logger;
 import freenet.support.SimpleFieldSet;
 import freenet.support.TokenBucket;
-import freenet.support.io.BucketFactory;
-import freenet.support.io.FilenameGenerator;
-import freenet.support.io.PaddedEphemerallyEncryptedBucketFactory;
-import freenet.support.io.PersistentEncryptedTempBucketFactory;
-import freenet.support.io.PersistentTempBucketFactory;
-import freenet.support.io.TempBucketFactory;
-import freenet.support.math.BootstrappingDecayingRunningAverage;
 import freenet.support.math.RunningAverage;
 import freenet.support.math.TimeDecayingRunningAverage;

@@ -153,9 +131,9 @@
                        }
                        public String get() {
                                if(myName.startsWith("Node created around")|| 
myName.equals("MyFirstFreenetNode")){
-                                       node.alerts.register(nodeNameUserAlert);
+                                       
clientCore.alerts.register(nodeNameUserAlert);
                                }else{
-                                       
node.alerts.unregister(nodeNameUserAlert);
+                                       
clientCore.alerts.unregister(nodeNameUserAlert);
                                }
                                return myName;
                        }
@@ -163,45 +141,13 @@
                        public void set(String val) throws 
InvalidConfigValueException {
                                myName = val;
                                if(myName.startsWith("Node created around")|| 
myName.equals("MyFirstFreenetNode")){
-                                       node.alerts.register(nodeNameUserAlert);
+                                       
clientCore.alerts.register(nodeNameUserAlert);
                                }else{
-                                       
node.alerts.unregister(nodeNameUserAlert);
+                                       
clientCore.alerts.unregister(nodeNameUserAlert);
                                }
                        }
        }

-       public class MyRequestThrottle implements BaseRequestThrottle {
-
-               private final BootstrappingDecayingRunningAverage 
roundTripTime; 
-               
-               public MyRequestThrottle(ThrottleWindowManager throttleWindow, 
int rtt, String string) {
-                       roundTripTime = new 
BootstrappingDecayingRunningAverage(rtt, 10, 5*60*1000, 10);
-               }
-
-               public synchronized long getDelay() {
-                       double rtt = roundTripTime.currentValue();
-                       double winSizeForMinPacketDelay = rtt / MIN_DELAY;
-                       double _simulatedWindowSize = 
throttleWindow.currentValue();
-                       if (_simulatedWindowSize > winSizeForMinPacketDelay) {
-                               _simulatedWindowSize = winSizeForMinPacketDelay;
-                       }
-                       if (_simulatedWindowSize < 1.0) {
-                               _simulatedWindowSize = 1.0F;
-                       }
-                       // return (long) (_roundTripTime / 
_simulatedWindowSize);
-                       return Math.max(MIN_DELAY, Math.min((long) (rtt / 
_simulatedWindowSize), MAX_DELAY));
-               }
-
-               public synchronized void successfulCompletion(long rtt) {
-                       roundTripTime.report(Math.max(rtt, 10));
-                       Logger.minor(this, "Reported successful completion: 
"+rtt+" on "+this+" avg "+roundTripTime.currentValue());
-               }
-               
-               public String toString() {
-                       return "rtt: "+roundTripTime.currentValue()+" 
_s="+throttleWindow.currentValue();
-               }
-       }
-       
        /** Config object for the whole node. */
        public final Config config;

@@ -392,7 +338,6 @@
        final File nodeDir;
        /** Directory to put extra peer data into */
        final File extraPeerDataDir;
-       final File tempDir;
        public final RandomSource random; // strong RNG
        final UdpSocketManager usm;
        final FNPPacketMangler packetMangler;
@@ -400,7 +345,6 @@
        public final PacketSender ps;
        final NodeDispatcher dispatcher;
        final NodePinger nodePinger;
-       final FilenameGenerator tempFilenameGenerator;
        static final int MAX_CACHED_KEYS = 1000;
        final LRUHashtable cachedPubKeys;
        final boolean testnetEnabled;
@@ -449,24 +393,12 @@
        public final long bootID;
        public final long startupTime;

-       // Client stuff
-       public final USKManager uskManager;
-       final ArchiveManager archiveManager;
-       public final BucketFactory tempBucketFactory;
-       final ThrottleWindowManager throttleWindow;
-       final MyRequestThrottle chkRequestThrottle;
-       final RequestStarter chkRequestStarter;
-       final MyRequestThrottle chkInsertThrottle;
-       final RequestStarter chkInsertStarter;
-       final MyRequestThrottle sskRequestThrottle;
-       final RequestStarter sskRequestStarter;
-       final MyRequestThrottle sskInsertThrottle;
-       final RequestStarter sskInsertStarter;
-       public final UserAlertManager alerts;
+       public final NodeClientCore clientCore;
+       final String bindto;
+       /** Average delay caused by throttling for sending a packet */
        final TimeDecayingRunningAverage throttledPacketSendAverage;
-       private final HealingQueue healingQueue;
-       /** Must be included as a hidden field in order for any dangerous HTTP 
operation to complete successfully. */
-       public final String formPassword;
+       
+       // Stats
        final TimeDecayingRunningAverage remoteChkFetchBytesSentAverage;
        final TimeDecayingRunningAverage remoteSskFetchBytesSentAverage;
        final TimeDecayingRunningAverage remoteChkInsertBytesSentAverage;
@@ -483,18 +415,6 @@
        final TimeDecayingRunningAverage localSskFetchBytesReceivedAverage;
        final TimeDecayingRunningAverage localChkInsertBytesReceivedAverage;
        final TimeDecayingRunningAverage localSskInsertBytesReceivedAverage;
-
-       File downloadDir;
-       public final ClientRequestScheduler chkFetchScheduler;
-       public final ClientRequestScheduler chkPutScheduler;
-       public final ClientRequestScheduler sskFetchScheduler;
-       public final ClientRequestScheduler sskPutScheduler;
-       final String bindto;
-       TextModeClientInterfaceServer tmci;
-       TextModeClientInterface directTMCI;
-       FCPServer fcpServer;
-       FProxyToadlet fproxyServlet;
-       SimpleToadletServer toadletContainer;

        // The version we were before we restarted.
        public int lastVersion;
@@ -502,21 +422,10 @@
        /** NodeUpdater **/
        public NodeUpdater nodeUpdater;

-       // Persistent temporary buckets
-       public final PersistentTempBucketFactory persistentTempBucketFactory;
-       public final PersistentEncryptedTempBucketFactory 
persistentEncryptedTempBucketFactory;
-       
        // Things that's needed to keep track of
        public final PluginManager pluginManager;
        public freenet.plugin.PluginManager pluginManager2;

-       // Client stuff that needs to be configged - FIXME
-       static final int MAX_ARCHIVE_HANDLERS = 200; // don't take up much 
RAM... FIXME
-       static final long MAX_CACHED_ARCHIVE_DATA = 32*1024*1024; // make a 
fixed fraction of the store by default? FIXME
-       static final long MAX_ARCHIVE_SIZE = 2*1024*1024; // ??? FIXME
-       static final long MAX_ARCHIVED_FILE_SIZE = 1024*1024; // arbitrary... 
FIXME
-       static final int MAX_CACHED_ELEMENTS = 1024; // equally arbitrary! 
FIXME hopefully we can cache many of these though
-
        // Helpers
        public final InetAddress localhostAddress;
        public final FreenetInetAddress fLocalhostAddress;
@@ -759,16 +668,11 @@
                // Easy stuff
                Logger.normal(this, "Initializing Node using SVN 
r"+Version.cvsRevision+" and freenet-ext r"+NodeStarter.extRevisionNumber);
                System.out.println("Initializing Node using SVN 
r"+Version.cvsRevision+" and freenet-ext r"+NodeStarter.extRevisionNumber);
-               byte[] pwdBuf = new byte[16];
-               random.nextBytes(pwdBuf);
-               this.formPassword = Base64.encode(pwdBuf);
                pInstantRejectIncoming = new TimeDecayingRunningAverage(0, 
60000, 0.0, 1.0);
                nodeStarter=ns;
                if(logConfigHandler != lc)
                        logConfigHandler=lc;
                startupTime = System.currentTimeMillis();
-               throttleWindow = new ThrottleWindowManager(2.0);
-               alerts = new UserAlertManager();
                nodeNameUserAlert = new MeaningfulNodeNameUserAlert(this);
                recentlyCompletedIDs = new LRUQueue();
                this.config = config;
@@ -1066,55 +970,6 @@
                usm.setDispatcher(dispatcher=new NodeDispatcher(this));
                usm.setLowLevelFilter(packetMangler = new 
FNPPacketMangler(this));

-               // Temp files
-               
-               nodeConfig.register("tempDir", new File(nodeDir, 
"temp-"+portNumber).toString(), sortOrder++, true, "Temp files directory", 
"Name of directory to put temporary files in", 
-                               new StringCallback() {
-                                       public String get() {
-                                               return tempDir.getPath();
-                                       }
-                                       public void set(String val) throws 
InvalidConfigValueException {
-                                               if(tempDir.equals(new 
File(val))) return;
-                                               // FIXME
-                                               throw new 
InvalidConfigValueException("Moving temp directory on the fly not supported at 
present");
-                                       }
-               });
-               
-               tempDir = new File(nodeConfig.getString("tempDir"));
-               if(!((tempDir.exists() && tempDir.isDirectory()) || 
(tempDir.mkdir()))) {
-                       String msg = "Could not find or create temporary 
directory";
-                       throw new NodeInitException(EXIT_BAD_TEMP_DIR, msg);
-               }
-               
-               try {
-                       tempFilenameGenerator = new FilenameGenerator(random, 
true, tempDir, "temp-");
-               } catch (IOException e) {
-                       String msg = "Could not find or create temporary 
directory (filename generator)";
-                       throw new NodeInitException(EXIT_BAD_TEMP_DIR, msg);
-               }
-               tempBucketFactory = new 
PaddedEphemerallyEncryptedBucketFactory(new 
TempBucketFactory(tempFilenameGenerator), random, 1024);
-
-               // Persistent temp files
-               nodeConfig.register("persistentTempDir", new File(nodeDir, 
"persistent-temp-"+portNumber).toString(), sortOrder++, true, "Persistent temp 
files directory", "Name of directory to put persistent temp files in",
-                               new StringCallback() {
-                                       public String get() {
-                                               return 
persistentTempBucketFactory.getDir().toString();
-                                       }
-                                       public void set(String val) throws 
InvalidConfigValueException {
-                                               if(!get().equals(val))
-                                                       return;
-                                               // FIXME
-                                               throw new 
InvalidConfigValueException("Moving persistent temp directory on the fly not 
supported at present");
-                                       }
-               });
-               try {
-                       persistentTempBucketFactory = new 
PersistentTempBucketFactory(new 
File(nodeConfig.getString("persistentTempDir")), "freenet-temp-", random);
-                       persistentEncryptedTempBucketFactory = new 
PersistentEncryptedTempBucketFactory(persistentTempBucketFactory);
-               } catch (IOException e2) {
-                       String msg = "Could not find or create persistent 
temporary directory";
-                       throw new NodeInitException(EXIT_BAD_TEMP_DIR, msg);
-               }
-
                // Extra Peer Data Directory
                nodeConfig.register("extraPeerDataDir", new File(nodeDir, 
"extra-peer-data-"+portNumber).toString(), sortOrder++, true, "Extra peer data 
directory", "Name of directory to put extra peer data in",
                                new StringCallback() {
@@ -1337,33 +1192,7 @@
                        throw new NodeInitException(EXIT_STORE_OTHER, msg);
                }

-               // Downloads directory

-               nodeConfig.register("downloadsDir", "downloads", sortOrder++, 
true, "Default download directory", "The directory to save downloaded files 
into by default", new StringCallback() {
-
-                       public String get() {
-                               return downloadDir.getPath();
-                       }
-
-                       public void set(String val) throws 
InvalidConfigValueException {
-                               if(downloadDir.equals(new File(val)))
-                                       return;
-                               File f = new File(val);
-                               if(!((f.exists() && f.isDirectory()) || 
(f.mkdir()))) {
-                                       throw new 
InvalidConfigValueException("Could not find or create directory");
-                               }
-                               downloadDir = new File(val);
-                       }
-                       
-               });
-               
-               String val = nodeConfig.getString("downloadsDir");
-               downloadDir = new File(val);
-               if(!((downloadDir.exists() && downloadDir.isDirectory()) || 
(downloadDir.mkdir()))) {
-                       throw new NodeInitException(EXIT_BAD_DOWNLOADS_DIR, 
"Could not find or create default downloads directory");
-               }
-
-               
                // Guesstimates. Hopefully well over the reality.
                localChkFetchBytesSentAverage = new 
TimeDecayingRunningAverage(500, 180000, 0.0, Long.MAX_VALUE);
                localSskFetchBytesSentAverage = new 
TimeDecayingRunningAverage(500, 180000, 0.0, Long.MAX_VALUE);
@@ -1382,59 +1211,19 @@
                remoteSskFetchBytesReceivedAverage = new 
TimeDecayingRunningAverage(2048+500, 180000, 0.0, Long.MAX_VALUE);
                remoteChkInsertBytesReceivedAverage = new 
TimeDecayingRunningAverage(32768+1024+500, 180000, 0.0, Long.MAX_VALUE);
                remoteSskInsertBytesReceivedAverage = new 
TimeDecayingRunningAverage(1024+1024+500, 180000, 0.0, Long.MAX_VALUE);
-
-               SubConfig schedulerConfig = new SubConfig("node.scheduler", 
config);

-               archiveManager = new ArchiveManager(MAX_ARCHIVE_HANDLERS, 
MAX_CACHED_ARCHIVE_DATA, MAX_ARCHIVE_SIZE, MAX_ARCHIVED_FILE_SIZE, 
MAX_CACHED_ELEMENTS, random, tempFilenameGenerator);
-               chkRequestThrottle = new MyRequestThrottle(throttleWindow, 
5000, "CHK Request");
-               chkRequestStarter = new RequestStarter(this, 
chkRequestThrottle, "CHK Request starter ("+portNumber+")", 
requestOutputThrottle, requestInputThrottle, localChkFetchBytesSentAverage, 
localChkFetchBytesReceivedAverage);
-               chkFetchScheduler = new ClientRequestScheduler(false, false, 
random, chkRequestStarter, this, schedulerConfig, "CHKrequester");
-               chkRequestStarter.setScheduler(chkFetchScheduler);
-               chkRequestStarter.start();
-               //insertThrottle = new ChainedRequestThrottle(10000, 2.0F, 
requestThrottle);
-               // FIXME reenable the above
-               chkInsertThrottle = new MyRequestThrottle(throttleWindow, 
20000, "CHK Insert");
-               chkInsertStarter = new RequestStarter(this, chkInsertThrottle, 
"CHK Insert starter ("+portNumber+")", requestOutputThrottle, 
requestInputThrottle, localChkInsertBytesSentAverage, 
localChkInsertBytesReceivedAverage);
-               chkPutScheduler = new ClientRequestScheduler(true, false, 
random, chkInsertStarter, this, schedulerConfig, "CHKinserter");
-               chkInsertStarter.setScheduler(chkPutScheduler);
-               chkInsertStarter.start();
-
-               sskRequestThrottle = new MyRequestThrottle(throttleWindow, 
5000, "SSK Request");
-               sskRequestStarter = new RequestStarter(this, 
sskRequestThrottle, "SSK Request starter ("+portNumber+")", 
requestOutputThrottle, requestInputThrottle, localSskFetchBytesSentAverage, 
localSskFetchBytesReceivedAverage);
-               sskFetchScheduler = new ClientRequestScheduler(false, true, 
random, sskRequestStarter, this, schedulerConfig, "SSKrequester");
-               sskRequestStarter.setScheduler(sskFetchScheduler);
-               sskRequestStarter.start();
-               //insertThrottle = new ChainedRequestThrottle(10000, 2.0F, 
requestThrottle);
-               // FIXME reenable the above
-               sskInsertThrottle = new MyRequestThrottle(throttleWindow, 
20000, "SSK Insert");
-               sskInsertStarter = new RequestStarter(this, sskInsertThrottle, 
"SSK Insert starter ("+portNumber+")", requestOutputThrottle, 
requestInputThrottle, localSskInsertBytesSentAverage, 
localSskFetchBytesReceivedAverage);
-               sskPutScheduler = new ClientRequestScheduler(true, true, 
random, sskInsertStarter, this, schedulerConfig, "SSKinserter");
-               sskInsertStarter.setScheduler(sskPutScheduler);
-               sskInsertStarter.start();
+               clientCore = new NodeClientCore(this, config, nodeConfig, 
nodeDir, portNumber, sortOrder);

-               schedulerConfig.finishedInitialization();
-
-               
                nodeConfig.finishedInitialization();
                writeNodeFile();

-               
-               Logger.normal(this, "Initializing USK Manager");
-               System.out.println("Initializing USK Manager");
-               uskManager = new USKManager(this);
-               
                // And finally, Initialize the plugin manager
                Logger.normal(this, "Initializing Plugin Manager");
                System.out.println("Initializing Plugin Manager");
                pluginManager = new PluginManager(this);

-               healingQueue = new SimpleHealingQueue(chkPutScheduler,
-                               new InserterContext(tempBucketFactory, 
tempBucketFactory, persistentTempBucketFactory, 
-                                               random, 0, 2, 1, 0, 0, new 
SimpleEventProducer(), 
-                                               false, uskManager), 
RequestStarter.PREFETCH_PRIORITY_CLASS, 512 /* FIXME make configurable */);
+               FetcherContext ctx = 
clientCore.makeClient((short)0).getFetcherContext();

-               FetcherContext ctx = makeClient((short)0).getFetcherContext();
-               
                ctx.allowSplitfiles = false;
                ctx.dontEnterImplicitArchives = true;
                ctx.maxArchiveRestarts = 0;
@@ -1467,6 +1256,7 @@
                ps.start();
                usm.start();
                myMemoryChecker.start();
+               peers.start();

                if(isUsingWrapper()) {
                        Logger.normal(this, "Using wrapper correctly: 
"+nodeStarter);
@@ -1481,41 +1271,11 @@
                System.out.println("FNP port is on "+bindto+":"+portNumber);
                // Start services

-               // TMCI
-               try{
-                       TextModeClientInterfaceServer.maybeCreate(this, config);
-               } catch (IOException e) {
-                       e.printStackTrace();
-                       throw new NodeInitException(EXIT_COULD_NOT_START_TMCI, 
"Could not start TMCI: "+e);
-               }
-               
-               // FCP (including persistent requests so needs to start before 
FProxy)
-               try {
-                       fcpServer = FCPServer.maybeCreate(this, config);
-               } catch (IOException e) {
-                       throw new NodeInitException(EXIT_COULD_NOT_START_FCP, 
"Could not start FCP: "+e);
-               } catch (InvalidConfigValueException e) {
-                       throw new NodeInitException(EXIT_COULD_NOT_START_FCP, 
"Could not start FCP: "+e);
-               }
-               
-               SubConfig fproxyConfig = new SubConfig("fproxy", config);
-               bookmarkManager = new BookmarkManager(this, fproxyConfig);
                pluginManager2 = new freenet.plugin.PluginManager(this);

 //             SubConfig pluginManagerConfig = new SubConfig("pluginmanager3", 
config);
 //             pluginManager3 = new 
freenet.plugin_new.PluginManager(pluginManagerConfig);

-               // FProxy
-               // FIXME this is a hack, the real way to do this is plugins
-               try {
-                       FProxyToadlet.maybeCreateFProxyEtc(this, config, 
fproxyConfig);
-               } catch (IOException e) {
-                       e.printStackTrace();
-                       throw new 
NodeInitException(EXIT_COULD_NOT_START_FPROXY, "Could not start FProxy: "+e);
-               } catch (InvalidConfigValueException e) {
-                       throw new 
NodeInitException(EXIT_COULD_NOT_START_FPROXY, "Could not start FProxy: "+e);
-               }
-
                // Node Updater
                try{
                        nodeUpdater = NodeUpdater.maybeCreate(this, config);
@@ -1533,16 +1293,31 @@
                server.register(pproxy, "/plugins/", true);
                 * */

-               // After everything has been created, write the config file 
back to disk.
-               config.finishedInit();
-               config.store();
-               
                ipDetector.start();

                // Start testnet handler
                if(testnetHandler != null)
                        testnetHandler.start();

+               checkForEvilJVMBug();
+               
+               // TODO: implement a "required" version if needed
+               if(NodeStarter.RECOMMENDED_EXT_BUILD_NUMBER > 
NodeStarter.extBuildNumber)
+                       clientCore.alerts.register(new ExtOldAgeUserAlert());
+
+               this.clientCore.start(config);
+               
+               // After everything has been created, write the config file 
back to disk.
+               config.finishedInit();
+               config.store();
+               
+               // Process any data in the extra peer data directory
+               peers.readExtraPeerData();
+               
+               hasStarted = true;
+       }
+       
+       private void checkForEvilJVMBug() {
                // Now check whether we are likely to get the EvilJVMBug.
                // If we are running a Sun or Blackdown JVM, on Linux, and 
LD_ASSUME_KERNEL is not set, then we are.

@@ -1573,7 +1348,7 @@
                        if((assumeKernel == null) || (assumeKernel.length() == 
0) || (!(assumeKernel.startsWith("2.2") || assumeKernel.startsWith("2.4")))) {
                                System.err.println(ERROR_SUN_NPTL);
                                Logger.error(this, ERROR_SUN_NPTL);
-                               this.alerts.register(new UserAlert() {
+                               clientCore.alerts.register(new UserAlert() {

                                        public boolean userCanDismiss() {
                                                return false;
@@ -1619,462 +1394,8 @@
                                });
                        }
                }
-               
-               // TODO: implement a "required" version if needed
-               if(NodeStarter.RECOMMENDED_EXT_BUILD_NUMBER > 
NodeStarter.extBuildNumber)
-                       this.alerts.register(new ExtOldAgeUserAlert());
-               
-               Thread completer = new Thread(new Runnable() {
-                       public void run() {
-                               System.out.println("Resuming persistent 
requests");
-                               Logger.normal(this, "Resuming persistent 
requests");
-                               fcpServer.finishStart();
-                               persistentTempBucketFactory.completedInit();
-                               hasStarted = true;
-                               System.out.println("Completed startup: All 
persistent requests resumed or restarted");
-                               Logger.normal(this, "Completed startup: All 
persistent requests resumed or restarted");
-                       }
-               }, "Startup completion thread");
-               completer.setDaemon(true);
-               completer.start();
-               
-               // Process any data in the extra peer data directory
-               peers.readExtraPeerData();
        }
-       
-       public ClientKeyBlock realGetKey(ClientKey key, boolean localOnly, 
boolean cache, boolean ignoreStore) throws LowLevelGetException {
-               if(key instanceof ClientCHK)
-                       return realGetCHK((ClientCHK)key, localOnly, cache, 
ignoreStore);
-               else if(key instanceof ClientSSK)
-                       return realGetSSK((ClientSSK)key, localOnly, cache, 
ignoreStore);
-               else
-                       throw new IllegalArgumentException("Not a CHK or SSK: 
"+key);
-       }
-       
-       ClientCHKBlock realGetCHK(ClientCHK key, boolean localOnly, boolean 
cache, boolean ignoreStore) throws LowLevelGetException {
-               long startTime = System.currentTimeMillis();
-               long uid = random.nextLong();
-               if(!lockUID(uid)) {
-                       Logger.error(this, "Could not lock UID just randomly 
generated: "+uid+" - probably indicates broken PRNG");
-                       throw new 
LowLevelGetException(LowLevelGetException.INTERNAL_ERROR);
-               }
-               Object o = makeRequestSender(key.getNodeCHK(), MAX_HTL, uid, 
null, lm.loc.getValue(), false, localOnly, cache, ignoreStore);
-               if(o instanceof CHKBlock) {
-                       try {
-                               return new ClientCHKBlock((CHKBlock)o, key);
-                       } catch (CHKVerifyException e) {
-                               Logger.error(this, "Does not verify: "+e, e);
-                               throw new 
LowLevelGetException(LowLevelGetException.DECODE_FAILED);
-                       }
-               }
-               if(o == null) {
-                       throw new 
LowLevelGetException(LowLevelGetException.DATA_NOT_FOUND_IN_STORE);
-               }
-               RequestSender rs = (RequestSender)o;
-               boolean rejectedOverload = false;
-               while(true) {
-                       if(rs.waitUntilStatusChange() && (!rejectedOverload)) {
-                               // See below; inserts count both
-                               throttleWindow.rejectedOverload();
-                               rejectedOverload = true;
-                       }

-                       int status = rs.getStatus();
-                       
-                       if(status == RequestSender.NOT_FINISHED) 
-                               continue;
-                       
-               if(status != RequestSender.TIMED_OUT && status != 
RequestSender.GENERATED_REJECTED_OVERLOAD && status != 
RequestSender.INTERNAL_ERROR) {
-               Logger.minor(this, "CHK fetch cost 
"+rs.getTotalSentBytes()+"/"+rs.getTotalReceivedBytes()+" bytes ("+status+")");
-               localChkFetchBytesSentAverage.report(rs.getTotalSentBytes());
-               
localChkFetchBytesReceivedAverage.report(rs.getTotalReceivedBytes());
-               }
-                       
-                       if((status == RequestSender.TIMED_OUT) ||
-                                       (status == 
RequestSender.GENERATED_REJECTED_OVERLOAD)) {
-                               if(!rejectedOverload) {
-                                       // See below
-                                       throttleWindow.rejectedOverload();
-                                       rejectedOverload = true;
-                               }
-                       } else {
-                               if((status == RequestSender.DATA_NOT_FOUND) ||
-                                               (status == 
RequestSender.SUCCESS) ||
-                                               (status == 
RequestSender.ROUTE_NOT_FOUND) ||
-                                               (status == 
RequestSender.VERIFY_FAILURE)) {
-                                       long rtt = System.currentTimeMillis() - 
startTime;
-                                       if(!rejectedOverload)
-                                               
throttleWindow.requestCompleted();
-                                       
chkRequestThrottle.successfulCompletion(rtt);
-                               }
-                       }
-                       
-                       if(rs.getStatus() == RequestSender.SUCCESS) {
-                               try {
-                                       return new 
ClientCHKBlock(rs.getPRB().getBlock(), rs.getHeaders(), key, true);
-                               } catch (CHKVerifyException e) {
-                                       Logger.error(this, "Does not verify: 
"+e, e);
-                                       throw new 
LowLevelGetException(LowLevelGetException.DECODE_FAILED);
-                               } catch (AbortedException e) {
-                                       Logger.error(this, "Impossible: "+e, e);
-                                       throw new 
LowLevelGetException(LowLevelGetException.INTERNAL_ERROR);
-                               }
-                       } else {
-                               switch(rs.getStatus()) {
-                               case RequestSender.NOT_FINISHED:
-                                       Logger.error(this, "RS still running in 
getCHK!: "+rs);
-                                       throw new 
LowLevelGetException(LowLevelGetException.INTERNAL_ERROR);
-                               case RequestSender.DATA_NOT_FOUND:
-                                       throw new 
LowLevelGetException(LowLevelGetException.DATA_NOT_FOUND);
-                               case RequestSender.ROUTE_NOT_FOUND:
-                                       throw new 
LowLevelGetException(LowLevelGetException.ROUTE_NOT_FOUND);
-                               case RequestSender.TRANSFER_FAILED:
-                                       throw new 
LowLevelGetException(LowLevelGetException.TRANSFER_FAILED);
-                               case RequestSender.VERIFY_FAILURE:
-                                       throw new 
LowLevelGetException(LowLevelGetException.VERIFY_FAILED);
-                               case RequestSender.GENERATED_REJECTED_OVERLOAD:
-                               case RequestSender.TIMED_OUT:
-                                       throw new 
LowLevelGetException(LowLevelGetException.REJECTED_OVERLOAD);
-                               case RequestSender.INTERNAL_ERROR:
-                                       throw new 
LowLevelGetException(LowLevelGetException.INTERNAL_ERROR);
-                               default:
-                                       Logger.error(this, "Unknown 
RequestSender code in getCHK: "+rs.getStatus()+" on "+rs);
-                                       throw new 
LowLevelGetException(LowLevelGetException.INTERNAL_ERROR);
-                               }
-                       }
-               }
-       }
-
-       ClientSSKBlock realGetSSK(ClientSSK key, boolean localOnly, boolean 
cache, boolean ignoreStore) throws LowLevelGetException {
-               long startTime = System.currentTimeMillis();
-               long uid = random.nextLong();
-               if(!lockUID(uid)) {
-                       Logger.error(this, "Could not lock UID just randomly 
generated: "+uid+" - probably indicates broken PRNG");
-                       throw new 
LowLevelGetException(LowLevelGetException.INTERNAL_ERROR);
-               }
-               Object o = makeRequestSender(key.getNodeKey(), MAX_HTL, uid, 
null, lm.loc.getValue(), false, localOnly, cache, ignoreStore);
-               if(o instanceof SSKBlock) {
-                       try {
-                               SSKBlock block = (SSKBlock)o;
-                               key.setPublicKey(block.getPubKey());
-                               return new ClientSSKBlock(block, key);
-                       } catch (SSKVerifyException e) {
-                               Logger.error(this, "Does not verify: "+e, e);
-                               throw new 
LowLevelGetException(LowLevelGetException.DECODE_FAILED);
-                       }
-               }
-               if(o == null) {
-                       throw new 
LowLevelGetException(LowLevelGetException.DATA_NOT_FOUND_IN_STORE);
-               }
-               RequestSender rs = (RequestSender)o;
-               boolean rejectedOverload = false;
-               while(true) {
-                       if(rs.waitUntilStatusChange() && (!rejectedOverload)) {
-                               throttleWindow.rejectedOverload();
-                               rejectedOverload = true;
-                       }
-
-                       int status = rs.getStatus();
-                       
-                       if(status == RequestSender.NOT_FINISHED) 
-                               continue;
-
-               if(status != RequestSender.TIMED_OUT && status != 
RequestSender.GENERATED_REJECTED_OVERLOAD && status != 
RequestSender.INTERNAL_ERROR) {
-               Logger.minor(this, "SSK fetch cost 
"+rs.getTotalSentBytes()+"/"+rs.getTotalReceivedBytes()+" bytes ("+status+")");
-               localSskFetchBytesSentAverage.report(rs.getTotalSentBytes());
-               
localSskFetchBytesReceivedAverage.report(rs.getTotalReceivedBytes());
-               }
-                       
-                       if((status == RequestSender.TIMED_OUT) ||
-                                       (status == 
RequestSender.GENERATED_REJECTED_OVERLOAD)) {
-                               if(!rejectedOverload) {
-                                       throttleWindow.rejectedOverload();
-                                       rejectedOverload = true;
-                               }
-                       } else {
-                               if((status == RequestSender.DATA_NOT_FOUND) ||
-                                               (status == 
RequestSender.SUCCESS) ||
-                                               (status == 
RequestSender.ROUTE_NOT_FOUND) ||
-                                               (status == 
RequestSender.VERIFY_FAILURE)) {
-                                       long rtt = System.currentTimeMillis() - 
startTime;
-                                       
-                                       if(!rejectedOverload)
-                                               
throttleWindow.requestCompleted();
-                                       
sskRequestThrottle.successfulCompletion(rtt);
-                               }
-                       }
-                       
-                       if(rs.getStatus() == RequestSender.SUCCESS) {
-                               try {
-                                       SSKBlock block = rs.getSSKBlock();
-                                       key.setPublicKey(block.getPubKey());
-                                       return new ClientSSKBlock(block, key);
-                               } catch (SSKVerifyException e) {
-                                       Logger.error(this, "Does not verify: 
"+e, e);
-                                       throw new 
LowLevelGetException(LowLevelGetException.DECODE_FAILED);
-                               }
-                       } else {
-                               switch(rs.getStatus()) {
-                               case RequestSender.NOT_FINISHED:
-                                       Logger.error(this, "RS still running in 
getCHK!: "+rs);
-                                       throw new 
LowLevelGetException(LowLevelGetException.INTERNAL_ERROR);
-                               case RequestSender.DATA_NOT_FOUND:
-                                       throw new 
LowLevelGetException(LowLevelGetException.DATA_NOT_FOUND);
-                               case RequestSender.ROUTE_NOT_FOUND:
-                                       throw new 
LowLevelGetException(LowLevelGetException.ROUTE_NOT_FOUND);
-                               case RequestSender.TRANSFER_FAILED:
-                                       Logger.error(this, "WTF? Transfer 
failed on an SSK? on "+uid);
-                                       throw new 
LowLevelGetException(LowLevelGetException.TRANSFER_FAILED);
-                               case RequestSender.VERIFY_FAILURE:
-                                       throw new 
LowLevelGetException(LowLevelGetException.VERIFY_FAILED);
-                               case RequestSender.GENERATED_REJECTED_OVERLOAD:
-                               case RequestSender.TIMED_OUT:
-                                       throw new 
LowLevelGetException(LowLevelGetException.REJECTED_OVERLOAD);
-                               case RequestSender.INTERNAL_ERROR:
-                               default:
-                                       Logger.error(this, "Unknown 
RequestSender code in getCHK: "+rs.getStatus()+" on "+rs);
-                                       throw new 
LowLevelGetException(LowLevelGetException.INTERNAL_ERROR);
-                               }
-                       }
-               }
-       }
-
-       public void realPut(KeyBlock block, boolean cache) throws 
LowLevelPutException {
-               if(block instanceof CHKBlock)
-                       realPutCHK((CHKBlock)block, cache);
-               else if(block instanceof SSKBlock)
-                       realPutSSK((SSKBlock)block, cache);
-               else
-                       throw new IllegalArgumentException("Unknown put type 
"+block.getClass());
-       }
-       
-       public void realPutCHK(CHKBlock block, boolean cache) throws 
LowLevelPutException {
-               byte[] data = block.getData();
-               byte[] headers = block.getHeaders();
-               PartiallyReceivedBlock prb = new 
PartiallyReceivedBlock(PACKETS_IN_BLOCK, PACKET_SIZE, data);
-               CHKInsertSender is;
-               long uid = random.nextLong();
-               if(!lockUID(uid)) {
-                       Logger.error(this, "Could not lock UID just randomly 
generated: "+uid+" - probably indicates broken PRNG");
-                       throw new 
LowLevelPutException(LowLevelPutException.INTERNAL_ERROR);
-               }
-               long startTime = System.currentTimeMillis();
-               if(cache) {
-                       store(block);
-               }
-               is = makeInsertSender((NodeCHK)block.getKey(), 
-                               MAX_HTL, uid, null, headers, prb, false, 
lm.getLocation().getValue(), cache);
-               boolean hasReceivedRejectedOverload = false;
-               // Wait for status
-               while(true) {
-                       synchronized(is) {
-                               if(is.getStatus() == 
CHKInsertSender.NOT_FINISHED) {
-                                       try {
-                                               is.wait(5*1000);
-                                       } catch (InterruptedException e) {
-                                               // Ignore
-                                       }
-                               }
-                               if(is.getStatus() != 
CHKInsertSender.NOT_FINISHED) break;
-                       }
-                       if((!hasReceivedRejectedOverload) && 
is.receivedRejectedOverload()) {
-                               hasReceivedRejectedOverload = true;
-                               throttleWindow.rejectedOverload();
-                       }
-               }
-               
-               // Wait for completion
-               while(true) {
-                       synchronized(is) {
-                               if(is.completed()) break;
-                               try {
-                                       is.wait(10*1000);
-                               } catch (InterruptedException e) {
-                                       // Go around again
-                               }
-                       }
-                       if(is.anyTransfersFailed() && 
(!hasReceivedRejectedOverload)) {
-                               hasReceivedRejectedOverload = true; // not 
strictly true but same effect
-                               throttleWindow.rejectedOverload();
-                       }
-               }
-               
-               Logger.minor(this, "Completed "+uid+" 
overload="+hasReceivedRejectedOverload+" "+is.getStatusString());
-               
-               // Finished?
-               if(!hasReceivedRejectedOverload) {
-                       // Is it ours? Did we send a request?
-                       if(is.sentRequest() && (is.uid == uid) && 
((is.getStatus() == CHKInsertSender.ROUTE_NOT_FOUND) 
-                                       || (is.getStatus() == 
CHKInsertSender.SUCCESS))) {
-                               // It worked!
-                               long endTime = System.currentTimeMillis();
-                               long len = endTime - startTime;
-                               
-                               chkInsertThrottle.successfulCompletion(len);
-                               if(!hasReceivedRejectedOverload)
-                                       throttleWindow.requestCompleted();
-                       }
-               }
-               
-               int status = is.getStatus();
-        if(status != CHKInsertSender.TIMED_OUT && status != 
CHKInsertSender.GENERATED_REJECTED_OVERLOAD && status != 
CHKInsertSender.INTERNAL_ERROR
-                       && status != CHKInsertSender.ROUTE_REALLY_NOT_FOUND) {
-               int sent = is.getTotalSentBytes();
-               int received = is.getTotalReceivedBytes();
-               Logger.minor(this, "Local CHK insert cost "+sent+"/"+received+" 
bytes ("+status+")");
-               localChkInsertBytesSentAverage.report(sent);
-               localChkInsertBytesReceivedAverage.report(received);
-        }
-        
-               if(status == CHKInsertSender.SUCCESS) {
-                       Logger.normal(this, "Succeeded inserting "+block);
-                       return;
-               } else {
-                       String msg = "Failed inserting "+block+" : 
"+is.getStatusString();
-                       if(status == CHKInsertSender.ROUTE_NOT_FOUND)
-                               msg += " - this is normal on small networks; 
the data will still be propagated, but it can't find the 20+ nodes needed for 
full success";
-                       if(is.getStatus() != CHKInsertSender.ROUTE_NOT_FOUND)
-                               Logger.error(this, msg);
-                       else
-                               Logger.normal(this, msg);
-                       switch(is.getStatus()) {
-                       case CHKInsertSender.NOT_FINISHED:
-                               Logger.error(this, "IS still running in 
putCHK!: "+is);
-                               throw new 
LowLevelPutException(LowLevelPutException.INTERNAL_ERROR);
-                       case CHKInsertSender.GENERATED_REJECTED_OVERLOAD:
-                       case CHKInsertSender.TIMED_OUT:
-                               throw new 
LowLevelPutException(LowLevelPutException.REJECTED_OVERLOAD);
-                       case CHKInsertSender.ROUTE_NOT_FOUND:
-                               throw new 
LowLevelPutException(LowLevelPutException.ROUTE_NOT_FOUND);
-                       case CHKInsertSender.ROUTE_REALLY_NOT_FOUND:
-                               throw new 
LowLevelPutException(LowLevelPutException.ROUTE_REALLY_NOT_FOUND);
-                       case CHKInsertSender.INTERNAL_ERROR:
-                               throw new 
LowLevelPutException(LowLevelPutException.INTERNAL_ERROR);
-                       default:
-                               Logger.error(this, "Unknown CHKInsertSender 
code in putCHK: "+is.getStatus()+" on "+is);
-                               throw new 
LowLevelPutException(LowLevelPutException.INTERNAL_ERROR);
-                       }
-               }
-       }
-
-       public void realPutSSK(SSKBlock block, boolean cache) throws 
LowLevelPutException {
-               SSKInsertSender is;
-               long uid = random.nextLong();
-               if(!lockUID(uid)) {
-                       Logger.error(this, "Could not lock UID just randomly 
generated: "+uid+" - probably indicates broken PRNG");
-                       throw new 
LowLevelPutException(LowLevelPutException.INTERNAL_ERROR);
-               }
-               long startTime = System.currentTimeMillis();
-               if(cache) {
-                       try {
-                               if(cache)
-                                       storeInsert(block);
-                       } catch (KeyCollisionException e) {
-                               throw new 
LowLevelPutException(LowLevelPutException.COLLISION);
-                       }
-               }
-               is = makeInsertSender(block, 
-                               MAX_HTL, uid, null, false, 
lm.getLocation().getValue(), false, cache);
-               boolean hasReceivedRejectedOverload = false;
-               // Wait for status
-               while(true) {
-                       synchronized(is) {
-                               if(is.getStatus() == 
SSKInsertSender.NOT_FINISHED) {
-                                       try {
-                                               is.wait(5*1000);
-                                       } catch (InterruptedException e) {
-                                               // Ignore
-                                       }
-                               }
-                               if(is.getStatus() != 
SSKInsertSender.NOT_FINISHED) break;
-                       }
-                       if((!hasReceivedRejectedOverload) && 
is.receivedRejectedOverload()) {
-                               hasReceivedRejectedOverload = true;
-                               throttleWindow.rejectedOverload();
-                       }
-               }
-               
-               // Wait for completion
-               while(true) {
-                       synchronized(is) {
-                               if(is.getStatus() != 
SSKInsertSender.NOT_FINISHED) break;
-                               try {
-                                       is.wait(10*1000);
-                               } catch (InterruptedException e) {
-                                       // Go around again
-                               }
-                       }
-               }
-               
-               Logger.minor(this, "Completed "+uid+" 
overload="+hasReceivedRejectedOverload+" "+is.getStatusString());
-               
-               // Finished?
-               if(!hasReceivedRejectedOverload) {
-                       // Is it ours? Did we send a request?
-                       if(is.sentRequest() && (is.uid == uid) && 
((is.getStatus() == SSKInsertSender.ROUTE_NOT_FOUND) 
-                                       || (is.getStatus() == 
SSKInsertSender.SUCCESS))) {
-                               // It worked!
-                               long endTime = System.currentTimeMillis();
-                               long rtt = endTime - startTime;
-                               throttleWindow.requestCompleted();
-                               sskInsertThrottle.successfulCompletion(rtt);
-                       }
-               }
-
-               int status = is.getStatus();
-               
-        if(status != CHKInsertSender.TIMED_OUT && status != 
CHKInsertSender.GENERATED_REJECTED_OVERLOAD && status != 
CHKInsertSender.INTERNAL_ERROR
-                       && status != CHKInsertSender.ROUTE_REALLY_NOT_FOUND) {
-               int sent = is.getTotalSentBytes();
-               int received = is.getTotalReceivedBytes();
-               Logger.minor(this, "Local SSK insert cost "+sent+"/"+received+" 
bytes ("+status+")");
-               localSskInsertBytesSentAverage.report(sent);
-               localSskInsertBytesReceivedAverage.report(received);
-        }
-        
-               if(is.hasCollided()) {
-                       // Store it locally so it can be fetched immediately, 
and overwrites any locally inserted.
-                       try {
-                               sskDatacache.put(is.getBlock(), true);
-                       } catch (KeyCollisionException e) {
-                               // Impossible
-                       } catch (IOException e) {
-                               Logger.error(this, "Datastore failure: "+e, e);
-                       }
-                       throw new 
LowLevelPutException(LowLevelPutException.COLLISION);
-               }
-               
-               if(status == SSKInsertSender.SUCCESS) {
-                       Logger.normal(this, "Succeeded inserting "+block);
-                       return;
-               } else {
-                       String msg = "Failed inserting "+block+" : 
"+is.getStatusString();
-                       if(status == CHKInsertSender.ROUTE_NOT_FOUND)
-                               msg += " - this is normal on small networks; 
the data will still be propagated, but it can't find the 20+ nodes needed for 
full success";
-                       if(is.getStatus() != SSKInsertSender.ROUTE_NOT_FOUND)
-                               Logger.error(this, msg);
-                       else
-                               Logger.normal(this, msg);
-                       switch(is.getStatus()) {
-                       case SSKInsertSender.NOT_FINISHED:
-                               Logger.error(this, "IS still running in 
putCHK!: "+is);
-                               throw new 
LowLevelPutException(LowLevelPutException.INTERNAL_ERROR);
-                       case SSKInsertSender.GENERATED_REJECTED_OVERLOAD:
-                       case SSKInsertSender.TIMED_OUT:
-                               throw new 
LowLevelPutException(LowLevelPutException.REJECTED_OVERLOAD);
-                       case SSKInsertSender.ROUTE_NOT_FOUND:
-                               throw new 
LowLevelPutException(LowLevelPutException.ROUTE_NOT_FOUND);
-                       case SSKInsertSender.ROUTE_REALLY_NOT_FOUND:
-                               throw new 
LowLevelPutException(LowLevelPutException.ROUTE_REALLY_NOT_FOUND);
-                       case SSKInsertSender.INTERNAL_ERROR:
-                               throw new 
LowLevelPutException(LowLevelPutException.INTERNAL_ERROR);
-                       default:
-                               Logger.error(this, "Unknown CHKInsertSender 
code in putSSK: "+is.getStatus()+" on "+is);
-                               throw new 
LowLevelPutException(LowLevelPutException.INTERNAL_ERROR);
-                       }
-               }
-       }
-
        private long lastAcceptedRequest = -1;

        private long lastCheckedUncontended = -1;
@@ -2158,7 +1479,7 @@
                }

                // Do we have the bandwidth?
-               double expected = 
+               double expected =
                        (isInsert ? (isSSK ? 
this.remoteSskInsertBytesSentAverage : this.remoteChkInsertBytesSentAverage)
                                        : (isSSK ? 
this.remoteSskFetchBytesSentAverage : 
this.remoteChkFetchBytesSentAverage)).currentValue();
                int expectedSent = (int)Math.max(expected, 0);
@@ -2802,28 +2123,6 @@
                        recentlyCompletedIDs.pop();
        }

-       public HighLevelSimpleClient makeClient(short prioClass) {
-               return new HighLevelSimpleClientImpl(this, archiveManager, 
tempBucketFactory, random, !DONT_CACHE_LOCAL_REQUESTS, prioClass);
-       }
-       
-       public BaseRequestThrottle getCHKRequestThrottle() {
-               return chkRequestThrottle;
-       }
-
-       public BaseRequestThrottle getCHKInsertThrottle() {
-               return chkInsertThrottle;
-       }
-       
-       public BaseRequestThrottle getSSKRequestThrottle() {
-               return sskRequestThrottle;
-       }
-       
-       public BaseRequestThrottle getSSKInsertThrottle() {
-               return sskInsertThrottle;
-       }
-
-       public BookmarkManager bookmarkManager;
-
        /**
         * Look up a cached public key by its hash.
         */
@@ -2941,34 +2240,6 @@
                return new ClientCHKBlock(block, clientCHK);
        }

-       public FCPServer getFCPServer() {
-               return fcpServer;
-       }
-
-       public void setToadletContainer(SimpleToadletServer server) {
-               toadletContainer = server;
-       }
-
-       public FProxyToadlet getFProxy() {
-               return fproxyServlet;
-       }
-
-       public SimpleToadletServer getToadletContainer() {
-               return toadletContainer;
-       }
-       
-       public TextModeClientInterfaceServer getTextModeClientInterface(){
-               return tmci;
-       }
-
-       public void setFProxy(FProxyToadlet fproxy) {
-               this.fproxyServlet = fproxy;
-       }
-
-       public void setFCPServer(FCPServer fcp) {
-               this.fcpServer = fcp;
-       }
-       
        public void exit(int reason) {
                try {
                        this.park();
@@ -3001,18 +2272,6 @@
                return nodeUpdater;
        }

-       public void setTMCI(TextModeClientInterfaceServer server) {
-               this.tmci = server;
-       }
-
-       public TextModeClientInterface getDirectTMCI() {
-               return directTMCI;
-       }
-       
-       public void setDirectTMCI(TextModeClientInterface i) {
-               this.directTMCI = i;
-       }
-
        public PeerNode[] getDarknetConnections() {
                return peers.myPeers;
        }
@@ -3027,10 +2286,6 @@
                peers.disconnect(pn);
        }

-       public File getDownloadDir() {
-               return downloadDir;
-       }
-
        public void onConnectedPeer() {
                Logger.minor(this, "onConnectedPeer()");
                ipDetector.onConnectedPeer();
@@ -3047,7 +2302,7 @@
        public synchronized boolean setNewestPeerLastGoodVersion( int version ) 
{
                if( version > buildOldAgeUserAlert.lastGoodVersion ) {
                        if( buildOldAgeUserAlert.lastGoodVersion == 0 ) {
-                               alerts.register(buildOldAgeUserAlert);
+                               
clientCore.alerts.register(buildOldAgeUserAlert);
                        }
                        buildOldAgeUserAlert.lastGoodVersion = version;
                        return true;
@@ -3263,7 +2518,7 @@
                        return;
                }
                N2NTMUserAlert userAlert = new N2NTMUserAlert(source, 
source_nodename, target_nodename, text, fileNumber);
-                       alerts.register(userAlert);
+                       clientCore.alerts.register(userAlert);
          } else {
                Logger.error(this, "Received unknown node to node message type 
'"+type+"' from "+source.getPeer());
          }
@@ -3445,19 +2700,8 @@
                return hasStarted;
        }

-       public HealingQueue getHealingQueue() {
-               return healingQueue;
-       }
-
        public void queueRandomReinsert(KeyBlock block) {
-               SimpleSendableInsert ssi = new SimpleSendableInsert(this, 
block, RequestStarter.MAXIMUM_PRIORITY_CLASS);
-               Logger.minor(this, "Queueing random reinsert for "+block+" : 
"+ssi);
-               if(block instanceof CHKBlock)
-                       chkPutScheduler.register(ssi);
-               else if(block instanceof SSKBlock)
-                       sskPutScheduler.register(ssi);
-               else
-                       Logger.error(this, "Don't know what to do with 
"+block+" should be queued for reinsert");
+               clientCore.queueRandomReinsert(block);
        }

        public double pRejectIncomingInstantly() {
@@ -3471,4 +2715,12 @@
        public boolean noConnectedPeers() {
                return !peers.anyConnectedPeers();
        }
+
+       public double getLocation() {
+               return lm.loc.getValue();
+       }
+
+       public boolean isAdvancedDarknetEnabled() {
+               return clientCore.isAdvancedDarknetEnabled();
+       }
 }

Modified: trunk/freenet/src/freenet/node/NodeARKInserter.java
===================================================================
--- trunk/freenet/src/freenet/node/NodeARKInserter.java 2006-08-12 18:13:01 UTC 
(rev 10047)
+++ trunk/freenet/src/freenet/node/NodeARKInserter.java 2006-08-12 19:24:25 UTC 
(rev 10048)
@@ -33,9 +33,9 @@
        /**
         * @param node
         */
-       NodeARKInserter(Node node) {
+       NodeARKInserter(Node node, NodeIPDetector detector) {
                this.node = node;
-               this.detector = node.ipDetector;
+               this.detector = detector;
        }

        private ClientPutter inserter;
@@ -130,8 +130,8 @@

                inserter = new ClientPutter(this, b, uri,
                                        new ClientMetadata("text/plain") /* it 
won't quite fit in an SSK anyway */, 
-                                       
this.node.makeClient((short)0).getInserterContext(true),
-                                       this.node.chkPutScheduler, 
this.node.sskPutScheduler, RequestStarter.INTERACTIVE_PRIORITY_CLASS, false, 
false, this, null);
+                                       
node.clientCore.makeClient((short)0).getInserterContext(true),
+                                       node.clientCore.chkPutScheduler, 
node.clientCore.sskPutScheduler, RequestStarter.INTERACTIVE_PRIORITY_CLASS, 
false, false, this, null);

                try {


Added: trunk/freenet/src/freenet/node/NodeClientCore.java
===================================================================
--- trunk/freenet/src/freenet/node/NodeClientCore.java  2006-08-12 18:13:01 UTC 
(rev 10047)
+++ trunk/freenet/src/freenet/node/NodeClientCore.java  2006-08-12 19:24:25 UTC 
(rev 10048)
@@ -0,0 +1,834 @@
+package freenet.node;
+
+import java.io.File;
+import java.io.IOException;
+
+import freenet.client.ArchiveManager;
+import freenet.client.HighLevelSimpleClient;
+import freenet.client.HighLevelSimpleClientImpl;
+import freenet.client.InserterContext;
+import freenet.client.async.ClientRequestScheduler;
+import freenet.client.async.HealingQueue;
+import freenet.client.async.SimpleHealingQueue;
+import freenet.client.async.USKManager;
+import freenet.client.events.SimpleEventProducer;
+import freenet.clients.http.BookmarkManager;
+import freenet.clients.http.FProxyToadlet;
+import freenet.clients.http.SimpleToadletServer;
+import freenet.config.Config;
+import freenet.config.InvalidConfigValueException;
+import freenet.config.StringCallback;
+import freenet.config.SubConfig;
+import freenet.crypt.RandomSource;
+import freenet.io.xfer.AbortedException;
+import freenet.io.xfer.PartiallyReceivedBlock;
+import freenet.keys.CHKBlock;
+import freenet.keys.CHKVerifyException;
+import freenet.keys.ClientCHK;
+import freenet.keys.ClientCHKBlock;
+import freenet.keys.ClientKey;
+import freenet.keys.ClientKeyBlock;
+import freenet.keys.ClientSSK;
+import freenet.keys.ClientSSKBlock;
+import freenet.keys.KeyBlock;
+import freenet.keys.NodeCHK;
+import freenet.keys.SSKBlock;
+import freenet.keys.SSKVerifyException;
+import freenet.node.Node.NodeInitException;
+import freenet.node.fcp.FCPServer;
+import freenet.node.useralerts.UserAlertManager;
+import freenet.store.KeyCollisionException;
+import freenet.support.Base64;
+import freenet.support.Logger;
+import freenet.support.io.BucketFactory;
+import freenet.support.io.FilenameGenerator;
+import freenet.support.io.PaddedEphemerallyEncryptedBucketFactory;
+import freenet.support.io.PersistentEncryptedTempBucketFactory;
+import freenet.support.io.PersistentTempBucketFactory;
+import freenet.support.io.TempBucketFactory;
+import freenet.support.math.BootstrappingDecayingRunningAverage;
+import freenet.support.math.TimeDecayingRunningAverage;
+
+public class NodeClientCore {
+
+       public final USKManager uskManager;
+       final ArchiveManager archiveManager;
+       final ThrottleWindowManager throttleWindow;
+       final MyRequestThrottle chkRequestThrottle;
+       final RequestStarter chkRequestStarter;
+       final MyRequestThrottle chkInsertThrottle;
+       final RequestStarter chkInsertStarter;
+       final MyRequestThrottle sskRequestThrottle;
+       final RequestStarter sskRequestStarter;
+       final MyRequestThrottle sskInsertThrottle;
+       final RequestStarter sskInsertStarter;
+       private final HealingQueue healingQueue;
+       /** Must be included as a hidden field in order for any dangerous HTTP 
operation to complete successfully. */
+       public final String formPassword;
+
+       File downloadDir;
+       public final ClientRequestScheduler chkFetchScheduler;
+       public final ClientRequestScheduler chkPutScheduler;
+       public final ClientRequestScheduler sskFetchScheduler;
+       public final ClientRequestScheduler sskPutScheduler;
+       final FilenameGenerator tempFilenameGenerator;
+       public final BucketFactory tempBucketFactory;
+       final Node node;
+       public final RandomSource random;
+       final File tempDir;
+
+       // Persistent temporary buckets
+       public final PersistentTempBucketFactory persistentTempBucketFactory;
+       public final PersistentEncryptedTempBucketFactory 
persistentEncryptedTempBucketFactory;
+       
+       public final UserAlertManager alerts;
+       TextModeClientInterfaceServer tmci;
+       TextModeClientInterface directTMCI;
+       FCPServer fcpServer;
+       FProxyToadlet fproxyServlet;
+       SimpleToadletServer toadletContainer;
+       // FIXME why isn't this just in fproxy?
+       public BookmarkManager bookmarkManager;
+       
+       // Client stuff that needs to be configged - FIXME
+       static final int MAX_ARCHIVE_HANDLERS = 200; // don't take up much 
RAM... FIXME
+       static final long MAX_CACHED_ARCHIVE_DATA = 32*1024*1024; // make a 
fixed fraction of the store by default? FIXME
+       static final long MAX_ARCHIVE_SIZE = 2*1024*1024; // ??? FIXME
+       static final long MAX_ARCHIVED_FILE_SIZE = 1024*1024; // arbitrary... 
FIXME
+       static final int MAX_CACHED_ELEMENTS = 1024; // equally arbitrary! 
FIXME hopefully we can cache many of these though
+
+       NodeClientCore(Node node, Config config, SubConfig nodeConfig, File 
nodeDir, int portNumber, int sortOrder) throws NodeInitException {
+               this.node = node;
+               this.random = node.random;
+               byte[] pwdBuf = new byte[16];
+               random.nextBytes(pwdBuf);
+               this.formPassword = Base64.encode(pwdBuf);
+               alerts = new UserAlertManager();
+               throttleWindow = new ThrottleWindowManager(2.0);
+               
+               // Temp files
+               
+               nodeConfig.register("tempDir", new File(nodeDir, 
"temp-"+portNumber).toString(), sortOrder++, true, "Temp files directory", 
"Name of directory to put temporary files in", 
+                               new StringCallback() {
+                                       public String get() {
+                                               return tempDir.getPath();
+                                       }
+                                       public void set(String val) throws 
InvalidConfigValueException {
+                                               if(tempDir.equals(new 
File(val))) return;
+                                               // FIXME
+                                               throw new 
InvalidConfigValueException("Moving temp directory on the fly not supported at 
present");
+                                       }
+               });
+               
+               tempDir = new File(nodeConfig.getString("tempDir"));
+               if(!((tempDir.exists() && tempDir.isDirectory()) || 
(tempDir.mkdir()))) {
+                       String msg = "Could not find or create temporary 
directory";
+                       throw new NodeInitException(Node.EXIT_BAD_TEMP_DIR, 
msg);
+               }
+               
+               try {
+                       tempFilenameGenerator = new FilenameGenerator(random, 
true, tempDir, "temp-");
+               } catch (IOException e) {
+                       String msg = "Could not find or create temporary 
directory (filename generator)";
+                       throw new NodeInitException(Node.EXIT_BAD_TEMP_DIR, 
msg);
+               }
+
+               // Persistent temp files
+               nodeConfig.register("persistentTempDir", new File(nodeDir, 
"persistent-temp-"+portNumber).toString(), sortOrder++, true, "Persistent temp 
files directory", "Name of directory to put persistent temp files in",
+                               new StringCallback() {
+                                       public String get() {
+                                               return 
persistentTempBucketFactory.getDir().toString();
+                                       }
+                                       public void set(String val) throws 
InvalidConfigValueException {
+                                               if(!get().equals(val))
+                                                       return;
+                                               // FIXME
+                                               throw new 
InvalidConfigValueException("Moving persistent temp directory on the fly not 
supported at present");
+                                       }
+               });
+               try {
+                       persistentTempBucketFactory = new 
PersistentTempBucketFactory(new 
File(nodeConfig.getString("persistentTempDir")), "freenet-temp-", random);
+                       persistentEncryptedTempBucketFactory = new 
PersistentEncryptedTempBucketFactory(persistentTempBucketFactory);
+               } catch (IOException e2) {
+                       String msg = "Could not find or create persistent 
temporary directory";
+                       throw new NodeInitException(Node.EXIT_BAD_TEMP_DIR, 
msg);
+               }
+
+               tempBucketFactory = new 
PaddedEphemerallyEncryptedBucketFactory(new 
TempBucketFactory(tempFilenameGenerator), random, 1024);
+               
+               // Downloads directory
+               
+               nodeConfig.register("downloadsDir", "downloads", sortOrder++, 
true, "Default download directory", "The directory to save downloaded files 
into by default", new StringCallback() {
+
+                       public String get() {
+                               return downloadDir.getPath();
+                       }
+
+                       public void set(String val) throws 
InvalidConfigValueException {
+                               if(downloadDir.equals(new File(val)))
+                                       return;
+                               File f = new File(val);
+                               if(!((f.exists() && f.isDirectory()) || 
(f.mkdir()))) {
+                                       throw new 
InvalidConfigValueException("Could not find or create directory");
+                               }
+                               downloadDir = new File(val);
+                       }
+                       
+               });
+               
+               String val = nodeConfig.getString("downloadsDir");
+               downloadDir = new File(val);
+               if(!((downloadDir.exists() && downloadDir.isDirectory()) || 
(downloadDir.mkdir()))) {
+                       throw new 
NodeInitException(Node.EXIT_BAD_DOWNLOADS_DIR, "Could not find or create 
default downloads directory");
+               }
+
+
+               SubConfig schedulerConfig = new SubConfig("node.scheduler", 
config);
+               
+               archiveManager = new ArchiveManager(MAX_ARCHIVE_HANDLERS, 
MAX_CACHED_ARCHIVE_DATA, MAX_ARCHIVE_SIZE, MAX_ARCHIVED_FILE_SIZE, 
MAX_CACHED_ELEMENTS, random, tempFilenameGenerator);
+               chkRequestThrottle = new MyRequestThrottle(throttleWindow, 
5000, "CHK Request");
+               chkRequestStarter = new RequestStarter(this, 
chkRequestThrottle, "CHK Request starter ("+portNumber+")", 
node.requestOutputThrottle, node.requestInputThrottle, 
node.localChkFetchBytesSentAverage, node.localChkFetchBytesReceivedAverage);
+               chkFetchScheduler = new ClientRequestScheduler(false, false, 
random, chkRequestStarter, node, schedulerConfig, "CHKrequester");
+               chkRequestStarter.setScheduler(chkFetchScheduler);
+               chkRequestStarter.start();
+               //insertThrottle = new ChainedRequestThrottle(10000, 2.0F, 
requestThrottle);
+               // FIXME reenable the above
+               chkInsertThrottle = new MyRequestThrottle(throttleWindow, 
20000, "CHK Insert");
+               chkInsertStarter = new RequestStarter(this, chkInsertThrottle, 
"CHK Insert starter ("+portNumber+")", node.requestOutputThrottle, 
node.requestInputThrottle, node.localChkInsertBytesSentAverage, 
node.localChkInsertBytesReceivedAverage);
+               chkPutScheduler = new ClientRequestScheduler(true, false, 
random, chkInsertStarter, node, schedulerConfig, "CHKinserter");
+               chkInsertStarter.setScheduler(chkPutScheduler);
+               chkInsertStarter.start();
+
+               sskRequestThrottle = new MyRequestThrottle(throttleWindow, 
5000, "SSK Request");
+               sskRequestStarter = new RequestStarter(this, 
sskRequestThrottle, "SSK Request starter ("+portNumber+")", 
node.requestOutputThrottle, node.requestInputThrottle, 
node.localSskFetchBytesSentAverage, node.localSskFetchBytesReceivedAverage);
+               sskFetchScheduler = new ClientRequestScheduler(false, true, 
random, sskRequestStarter, node, schedulerConfig, "SSKrequester");
+               sskRequestStarter.setScheduler(sskFetchScheduler);
+               sskRequestStarter.start();
+               //insertThrottle = new ChainedRequestThrottle(10000, 2.0F, 
requestThrottle);
+               // FIXME reenable the above
+               sskInsertThrottle = new MyRequestThrottle(throttleWindow, 
20000, "SSK Insert");
+               sskInsertStarter = new RequestStarter(this, sskInsertThrottle, 
"SSK Insert starter ("+portNumber+")", node.requestOutputThrottle, 
node.requestInputThrottle, node.localSskInsertBytesSentAverage, 
node.localSskFetchBytesReceivedAverage);
+               sskPutScheduler = new ClientRequestScheduler(true, true, 
random, sskInsertStarter, node, schedulerConfig, "SSKinserter");
+               sskInsertStarter.setScheduler(sskPutScheduler);
+               sskInsertStarter.start();
+               
+               Logger.normal(this, "Initializing USK Manager");
+               System.out.println("Initializing USK Manager");
+               uskManager = new USKManager(this);
+               
+               healingQueue = new SimpleHealingQueue(chkPutScheduler,
+                               new InserterContext(tempBucketFactory, 
tempBucketFactory, persistentTempBucketFactory, 
+                                               random, 0, 2, 1, 0, 0, new 
SimpleEventProducer(), 
+                                               false, uskManager), 
RequestStarter.PREFETCH_PRIORITY_CLASS, 512 /* FIXME make configurable */);
+               
+               schedulerConfig.finishedInitialization();
+       }
+       
+       
+       public class MyRequestThrottle implements BaseRequestThrottle {
+
+               private final BootstrappingDecayingRunningAverage 
roundTripTime; 
+               
+               public MyRequestThrottle(ThrottleWindowManager throttleWindow, 
int rtt, String string) {
+                       roundTripTime = new 
BootstrappingDecayingRunningAverage(rtt, 10, 5*60*1000, 10);
+               }
+
+               public synchronized long getDelay() {
+                       double rtt = roundTripTime.currentValue();
+                       double winSizeForMinPacketDelay = rtt / MIN_DELAY;
+                       double _simulatedWindowSize = 
throttleWindow.currentValue();
+                       if (_simulatedWindowSize > winSizeForMinPacketDelay) {
+                               _simulatedWindowSize = winSizeForMinPacketDelay;
+                       }
+                       if (_simulatedWindowSize < 1.0) {
+                               _simulatedWindowSize = 1.0F;
+                       }
+                       // return (long) (_roundTripTime / 
_simulatedWindowSize);
+                       return Math.max(MIN_DELAY, Math.min((long) (rtt / 
_simulatedWindowSize), MAX_DELAY));
+               }
+
+               public synchronized void successfulCompletion(long rtt) {
+                       roundTripTime.report(Math.max(rtt, 10));
+                       Logger.minor(this, "Reported successful completion: 
"+rtt+" on "+this+" avg "+roundTripTime.currentValue());
+               }
+               
+               public String toString() {
+                       return "rtt: "+roundTripTime.currentValue()+" 
_s="+throttleWindow.currentValue();
+               }
+       }
+
+
+       public void start(Config config) throws NodeInitException {
+               // TMCI
+               try{
+                       TextModeClientInterfaceServer.maybeCreate(node, config);
+               } catch (IOException e) {
+                       e.printStackTrace();
+                       throw new 
NodeInitException(Node.EXIT_COULD_NOT_START_TMCI, "Could not start TMCI: "+e);
+               }
+               
+               // FCP (including persistent requests so needs to start before 
FProxy)
+               try {
+                       fcpServer = FCPServer.maybeCreate(node, this, 
node.config);
+               } catch (IOException e) {
+                       throw new 
NodeInitException(Node.EXIT_COULD_NOT_START_FCP, "Could not start FCP: "+e);
+               } catch (InvalidConfigValueException e) {
+                       throw new 
NodeInitException(Node.EXIT_COULD_NOT_START_FCP, "Could not start FCP: "+e);
+               }
+               
+               SubConfig fproxyConfig = new SubConfig("fproxy", config);
+               bookmarkManager = new BookmarkManager(this, fproxyConfig);
+               
+               // FProxy
+               // FIXME this is a hack, the real way to do this is plugins
+               try {
+                       FProxyToadlet.maybeCreateFProxyEtc(this, node, config, 
fproxyConfig);
+               } catch (IOException e) {
+                       e.printStackTrace();
+                       throw new 
NodeInitException(Node.EXIT_COULD_NOT_START_FPROXY, "Could not start FProxy: 
"+e);
+               } catch (InvalidConfigValueException e) {
+                       throw new 
NodeInitException(Node.EXIT_COULD_NOT_START_FPROXY, "Could not start FProxy: 
"+e);
+               }
+
+               Thread completer = new Thread(new Runnable() {
+                       public void run() {
+                               System.out.println("Resuming persistent 
requests");
+                               Logger.normal(this, "Resuming persistent 
requests");
+                               fcpServer.finishStart();
+                               persistentTempBucketFactory.completedInit();
+                               System.out.println("Completed startup: All 
persistent requests resumed or restarted");
+                               Logger.normal(this, "Completed startup: All 
persistent requests resumed or restarted");
+                       }
+               }, "Startup completion thread");
+               completer.setDaemon(true);
+               completer.start();
+       }
+       
+       public ClientKeyBlock realGetKey(ClientKey key, boolean localOnly, 
boolean cache, boolean ignoreStore) throws LowLevelGetException {
+               if(key instanceof ClientCHK)
+                       return realGetCHK((ClientCHK)key, localOnly, cache, 
ignoreStore);
+               else if(key instanceof ClientSSK)
+                       return realGetSSK((ClientSSK)key, localOnly, cache, 
ignoreStore);
+               else
+                       throw new IllegalArgumentException("Not a CHK or SSK: 
"+key);
+       }
+       
+       ClientCHKBlock realGetCHK(ClientCHK key, boolean localOnly, boolean 
cache, boolean ignoreStore) throws LowLevelGetException {
+               long startTime = System.currentTimeMillis();
+               long uid = random.nextLong();
+               if(!node.lockUID(uid)) {
+                       Logger.error(this, "Could not lock UID just randomly 
generated: "+uid+" - probably indicates broken PRNG");
+                       throw new 
LowLevelGetException(LowLevelGetException.INTERNAL_ERROR);
+               }
+               Object o = node.makeRequestSender(key.getNodeCHK(), 
Node.MAX_HTL, uid, null, node.getLocation(), false, localOnly, cache, 
ignoreStore);
+               if(o instanceof CHKBlock) {
+                       try {
+                               return new ClientCHKBlock((CHKBlock)o, key);
+                       } catch (CHKVerifyException e) {
+                               Logger.error(this, "Does not verify: "+e, e);
+                               throw new 
LowLevelGetException(LowLevelGetException.DECODE_FAILED);
+                       }
+               }
+               if(o == null) {
+                       throw new 
LowLevelGetException(LowLevelGetException.DATA_NOT_FOUND_IN_STORE);
+               }
+               RequestSender rs = (RequestSender)o;
+               boolean rejectedOverload = false;
+               while(true) {
+                       if(rs.waitUntilStatusChange() && (!rejectedOverload)) {
+                               // See below; inserts count both
+                               throttleWindow.rejectedOverload();
+                               rejectedOverload = true;
+                       }
+
+                       int status = rs.getStatus();
+                       
+                       if(status == RequestSender.NOT_FINISHED) 
+                               continue;
+                       
+               if(status != RequestSender.TIMED_OUT && status != 
RequestSender.GENERATED_REJECTED_OVERLOAD && status != 
RequestSender.INTERNAL_ERROR) {
+               Logger.minor(this, "CHK fetch cost 
"+rs.getTotalSentBytes()+"/"+rs.getTotalReceivedBytes()+" bytes ("+status+")");
+               
node.localChkFetchBytesSentAverage.report(rs.getTotalSentBytes());
+               
node.localChkFetchBytesReceivedAverage.report(rs.getTotalReceivedBytes());
+               }
+                       
+                       if((status == RequestSender.TIMED_OUT) ||
+                                       (status == 
RequestSender.GENERATED_REJECTED_OVERLOAD)) {
+                               if(!rejectedOverload) {
+                                       // See below
+                                       throttleWindow.rejectedOverload();
+                                       rejectedOverload = true;
+                               }
+                       } else {
+                               if((status == RequestSender.DATA_NOT_FOUND) ||
+                                               (status == 
RequestSender.SUCCESS) ||
+                                               (status == 
RequestSender.ROUTE_NOT_FOUND) ||
+                                               (status == 
RequestSender.VERIFY_FAILURE)) {
+                                       long rtt = System.currentTimeMillis() - 
startTime;
+                                       if(!rejectedOverload)
+                                               
throttleWindow.requestCompleted();
+                                       
chkRequestThrottle.successfulCompletion(rtt);
+                               }
+                       }
+                       
+                       if(rs.getStatus() == RequestSender.SUCCESS) {
+                               try {
+                                       return new 
ClientCHKBlock(rs.getPRB().getBlock(), rs.getHeaders(), key, true);
+                               } catch (CHKVerifyException e) {
+                                       Logger.error(this, "Does not verify: 
"+e, e);
+                                       throw new 
LowLevelGetException(LowLevelGetException.DECODE_FAILED);
+                               } catch (AbortedException e) {
+                                       Logger.error(this, "Impossible: "+e, e);
+                                       throw new 
LowLevelGetException(LowLevelGetException.INTERNAL_ERROR);
+                               }
+                       } else {
+                               switch(rs.getStatus()) {
+                               case RequestSender.NOT_FINISHED:
+                                       Logger.error(this, "RS still running in 
getCHK!: "+rs);
+                                       throw new 
LowLevelGetException(LowLevelGetException.INTERNAL_ERROR);
+                               case RequestSender.DATA_NOT_FOUND:
+                                       throw new 
LowLevelGetException(LowLevelGetException.DATA_NOT_FOUND);
+                               case RequestSender.ROUTE_NOT_FOUND:
+                                       throw new 
LowLevelGetException(LowLevelGetException.ROUTE_NOT_FOUND);
+                               case RequestSender.TRANSFER_FAILED:
+                                       throw new 
LowLevelGetException(LowLevelGetException.TRANSFER_FAILED);
+                               case RequestSender.VERIFY_FAILURE:
+                                       throw new 
LowLevelGetException(LowLevelGetException.VERIFY_FAILED);
+                               case RequestSender.GENERATED_REJECTED_OVERLOAD:
+                               case RequestSender.TIMED_OUT:
+                                       throw new 
LowLevelGetException(LowLevelGetException.REJECTED_OVERLOAD);
+                               case RequestSender.INTERNAL_ERROR:
+                                       throw new 
LowLevelGetException(LowLevelGetException.INTERNAL_ERROR);
+                               default:
+                                       Logger.error(this, "Unknown 
RequestSender code in getCHK: "+rs.getStatus()+" on "+rs);
+                                       throw new 
LowLevelGetException(LowLevelGetException.INTERNAL_ERROR);
+                               }
+                       }
+               }
+       }
+
+       ClientSSKBlock realGetSSK(ClientSSK key, boolean localOnly, boolean 
cache, boolean ignoreStore) throws LowLevelGetException {
+               long startTime = System.currentTimeMillis();
+               long uid = random.nextLong();
+               if(!node.lockUID(uid)) {
+                       Logger.error(this, "Could not lock UID just randomly 
generated: "+uid+" - probably indicates broken PRNG");
+                       throw new 
LowLevelGetException(LowLevelGetException.INTERNAL_ERROR);
+               }
+               Object o = node.makeRequestSender(key.getNodeKey(), 
Node.MAX_HTL, uid, null, node.getLocation(), false, localOnly, cache, 
ignoreStore);
+               if(o instanceof SSKBlock) {
+                       try {
+                               SSKBlock block = (SSKBlock)o;
+                               key.setPublicKey(block.getPubKey());
+                               return new ClientSSKBlock(block, key);
+                       } catch (SSKVerifyException e) {
+                               Logger.error(this, "Does not verify: "+e, e);
+                               throw new 
LowLevelGetException(LowLevelGetException.DECODE_FAILED);
+                       }
+               }
+               if(o == null) {
+                       throw new 
LowLevelGetException(LowLevelGetException.DATA_NOT_FOUND_IN_STORE);
+               }
+               RequestSender rs = (RequestSender)o;
+               boolean rejectedOverload = false;
+               while(true) {
+                       if(rs.waitUntilStatusChange() && (!rejectedOverload)) {
+                               throttleWindow.rejectedOverload();
+                               rejectedOverload = true;
+                       }
+
+                       int status = rs.getStatus();
+                       
+                       if(status == RequestSender.NOT_FINISHED) 
+                               continue;
+
+               if(status != RequestSender.TIMED_OUT && status != 
RequestSender.GENERATED_REJECTED_OVERLOAD && status != 
RequestSender.INTERNAL_ERROR) {
+               Logger.minor(this, "SSK fetch cost 
"+rs.getTotalSentBytes()+"/"+rs.getTotalReceivedBytes()+" bytes ("+status+")");
+               
node.localSskFetchBytesSentAverage.report(rs.getTotalSentBytes());
+               
node.localSskFetchBytesReceivedAverage.report(rs.getTotalReceivedBytes());
+               }
+                       
+                       if((status == RequestSender.TIMED_OUT) ||
+                                       (status == 
RequestSender.GENERATED_REJECTED_OVERLOAD)) {
+                               if(!rejectedOverload) {
+                                       throttleWindow.rejectedOverload();
+                                       rejectedOverload = true;
+                               }
+                       } else {
+                               if((status == RequestSender.DATA_NOT_FOUND) ||
+                                               (status == 
RequestSender.SUCCESS) ||
+                                               (status == 
RequestSender.ROUTE_NOT_FOUND) ||
+                                               (status == 
RequestSender.VERIFY_FAILURE)) {
+                                       long rtt = System.currentTimeMillis() - 
startTime;
+                                       
+                                       if(!rejectedOverload)
+                                               
throttleWindow.requestCompleted();
+                                       
sskRequestThrottle.successfulCompletion(rtt);
+                               }
+                       }
+                       
+                       if(rs.getStatus() == RequestSender.SUCCESS) {
+                               try {
+                                       SSKBlock block = rs.getSSKBlock();
+                                       key.setPublicKey(block.getPubKey());
+                                       return new ClientSSKBlock(block, key);
+                               } catch (SSKVerifyException e) {
+                                       Logger.error(this, "Does not verify: 
"+e, e);
+                                       throw new 
LowLevelGetException(LowLevelGetException.DECODE_FAILED);
+                               }
+                       } else {
+                               switch(rs.getStatus()) {
+                               case RequestSender.NOT_FINISHED:
+                                       Logger.error(this, "RS still running in 
getCHK!: "+rs);
+                                       throw new 
LowLevelGetException(LowLevelGetException.INTERNAL_ERROR);
+                               case RequestSender.DATA_NOT_FOUND:
+                                       throw new 
LowLevelGetException(LowLevelGetException.DATA_NOT_FOUND);
+                               case RequestSender.ROUTE_NOT_FOUND:
+                                       throw new 
LowLevelGetException(LowLevelGetException.ROUTE_NOT_FOUND);
+                               case RequestSender.TRANSFER_FAILED:
+                                       Logger.error(this, "WTF? Transfer 
failed on an SSK? on "+uid);
+                                       throw new 
LowLevelGetException(LowLevelGetException.TRANSFER_FAILED);
+                               case RequestSender.VERIFY_FAILURE:
+                                       throw new 
LowLevelGetException(LowLevelGetException.VERIFY_FAILED);
+                               case RequestSender.GENERATED_REJECTED_OVERLOAD:
+                               case RequestSender.TIMED_OUT:
+                                       throw new 
LowLevelGetException(LowLevelGetException.REJECTED_OVERLOAD);
+                               case RequestSender.INTERNAL_ERROR:
+                               default:
+                                       Logger.error(this, "Unknown 
RequestSender code in getCHK: "+rs.getStatus()+" on "+rs);
+                                       throw new 
LowLevelGetException(LowLevelGetException.INTERNAL_ERROR);
+                               }
+                       }
+               }
+       }
+
+       public void realPut(KeyBlock block, boolean cache) throws 
LowLevelPutException {
+               if(block instanceof CHKBlock)
+                       realPutCHK((CHKBlock)block, cache);
+               else if(block instanceof SSKBlock)
+                       realPutSSK((SSKBlock)block, cache);
+               else
+                       throw new IllegalArgumentException("Unknown put type 
"+block.getClass());
+       }
+       
+       public void realPutCHK(CHKBlock block, boolean cache) throws 
LowLevelPutException {
+               byte[] data = block.getData();
+               byte[] headers = block.getHeaders();
+               PartiallyReceivedBlock prb = new 
PartiallyReceivedBlock(Node.PACKETS_IN_BLOCK, Node.PACKET_SIZE, data);
+               CHKInsertSender is;
+               long uid = random.nextLong();
+               if(!node.lockUID(uid)) {
+                       Logger.error(this, "Could not lock UID just randomly 
generated: "+uid+" - probably indicates broken PRNG");
+                       throw new 
LowLevelPutException(LowLevelPutException.INTERNAL_ERROR);
+               }
+               long startTime = System.currentTimeMillis();
+               if(cache) {
+                       node.store(block);
+               }
+               is = node.makeInsertSender((NodeCHK)block.getKey(), 
+                               Node.MAX_HTL, uid, null, headers, prb, false, 
node.getLocation(), cache);
+               boolean hasReceivedRejectedOverload = false;
+               // Wait for status
+               while(true) {
+                       synchronized(is) {
+                               if(is.getStatus() == 
CHKInsertSender.NOT_FINISHED) {
+                                       try {
+                                               is.wait(5*1000);
+                                       } catch (InterruptedException e) {
+                                               // Ignore
+                                       }
+                               }
+                               if(is.getStatus() != 
CHKInsertSender.NOT_FINISHED) break;
+                       }
+                       if((!hasReceivedRejectedOverload) && 
is.receivedRejectedOverload()) {
+                               hasReceivedRejectedOverload = true;
+                               throttleWindow.rejectedOverload();
+                       }
+               }
+               
+               // Wait for completion
+               while(true) {
+                       synchronized(is) {
+                               if(is.completed()) break;
+                               try {
+                                       is.wait(10*1000);
+                               } catch (InterruptedException e) {
+                                       // Go around again
+                               }
+                       }
+                       if(is.anyTransfersFailed() && 
(!hasReceivedRejectedOverload)) {
+                               hasReceivedRejectedOverload = true; // not 
strictly true but same effect
+                               throttleWindow.rejectedOverload();
+                       }
+               }
+               
+               Logger.minor(this, "Completed "+uid+" 
overload="+hasReceivedRejectedOverload+" "+is.getStatusString());
+               
+               // Finished?
+               if(!hasReceivedRejectedOverload) {
+                       // Is it ours? Did we send a request?
+                       if(is.sentRequest() && (is.uid == uid) && 
((is.getStatus() == CHKInsertSender.ROUTE_NOT_FOUND) 
+                                       || (is.getStatus() == 
CHKInsertSender.SUCCESS))) {
+                               // It worked!
+                               long endTime = System.currentTimeMillis();
+                               long len = endTime - startTime;
+                               
+                               chkInsertThrottle.successfulCompletion(len);
+                               if(!hasReceivedRejectedOverload)
+                                       throttleWindow.requestCompleted();
+                       }
+               }
+               
+               int status = is.getStatus();
+        if(status != CHKInsertSender.TIMED_OUT && status != 
CHKInsertSender.GENERATED_REJECTED_OVERLOAD && status != 
CHKInsertSender.INTERNAL_ERROR
+                       && status != CHKInsertSender.ROUTE_REALLY_NOT_FOUND) {
+               int sent = is.getTotalSentBytes();
+               int received = is.getTotalReceivedBytes();
+               Logger.minor(this, "Local CHK insert cost "+sent+"/"+received+" 
bytes ("+status+")");
+               node.localChkInsertBytesSentAverage.report(sent);
+               node.localChkInsertBytesReceivedAverage.report(received);
+        }
+        
+               if(status == CHKInsertSender.SUCCESS) {
+                       Logger.normal(this, "Succeeded inserting "+block);
+                       return;
+               } else {
+                       String msg = "Failed inserting "+block+" : 
"+is.getStatusString();
+                       if(status == CHKInsertSender.ROUTE_NOT_FOUND)
+                               msg += " - this is normal on small networks; 
the data will still be propagated, but it can't find the 20+ nodes needed for 
full success";
+                       if(is.getStatus() != CHKInsertSender.ROUTE_NOT_FOUND)
+                               Logger.error(this, msg);
+                       else
+                               Logger.normal(this, msg);
+                       switch(is.getStatus()) {
+                       case CHKInsertSender.NOT_FINISHED:
+                               Logger.error(this, "IS still running in 
putCHK!: "+is);
+                               throw new 
LowLevelPutException(LowLevelPutException.INTERNAL_ERROR);
+                       case CHKInsertSender.GENERATED_REJECTED_OVERLOAD:
+                       case CHKInsertSender.TIMED_OUT:
+                               throw new 
LowLevelPutException(LowLevelPutException.REJECTED_OVERLOAD);
+                       case CHKInsertSender.ROUTE_NOT_FOUND:
+                               throw new 
LowLevelPutException(LowLevelPutException.ROUTE_NOT_FOUND);
+                       case CHKInsertSender.ROUTE_REALLY_NOT_FOUND:
+                               throw new 
LowLevelPutException(LowLevelPutException.ROUTE_REALLY_NOT_FOUND);
+                       case CHKInsertSender.INTERNAL_ERROR:
+                               throw new 
LowLevelPutException(LowLevelPutException.INTERNAL_ERROR);
+                       default:
+                               Logger.error(this, "Unknown CHKInsertSender 
code in putCHK: "+is.getStatus()+" on "+is);
+                               throw new 
LowLevelPutException(LowLevelPutException.INTERNAL_ERROR);
+                       }
+               }
+       }
+
+       public void realPutSSK(SSKBlock block, boolean cache) throws 
LowLevelPutException {
+               SSKInsertSender is;
+               long uid = random.nextLong();
+               if(!node.lockUID(uid)) {
+                       Logger.error(this, "Could not lock UID just randomly 
generated: "+uid+" - probably indicates broken PRNG");
+                       throw new 
LowLevelPutException(LowLevelPutException.INTERNAL_ERROR);
+               }
+               long startTime = System.currentTimeMillis();
+               if(cache) {
+                       try {
+                               if(cache)
+                                       node.storeInsert(block);
+                       } catch (KeyCollisionException e) {
+                               throw new 
LowLevelPutException(LowLevelPutException.COLLISION);
+                       }
+               }
+               is = node.makeInsertSender(block, 
+                               Node.MAX_HTL, uid, null, false, 
node.getLocation(), false, cache);
+               boolean hasReceivedRejectedOverload = false;
+               // Wait for status
+               while(true) {
+                       synchronized(is) {
+                               if(is.getStatus() == 
SSKInsertSender.NOT_FINISHED) {
+                                       try {
+                                               is.wait(5*1000);
+                                       } catch (InterruptedException e) {
+                                               // Ignore
+                                       }
+                               }
+                               if(is.getStatus() != 
SSKInsertSender.NOT_FINISHED) break;
+                       }
+                       if((!hasReceivedRejectedOverload) && 
is.receivedRejectedOverload()) {
+                               hasReceivedRejectedOverload = true;
+                               throttleWindow.rejectedOverload();
+                       }
+               }
+               
+               // Wait for completion
+               while(true) {
+                       synchronized(is) {
+                               if(is.getStatus() != 
SSKInsertSender.NOT_FINISHED) break;
+                               try {
+                                       is.wait(10*1000);
+                               } catch (InterruptedException e) {
+                                       // Go around again
+                               }
+                       }
+               }
+               
+               Logger.minor(this, "Completed "+uid+" 
overload="+hasReceivedRejectedOverload+" "+is.getStatusString());
+               
+               // Finished?
+               if(!hasReceivedRejectedOverload) {
+                       // Is it ours? Did we send a request?
+                       if(is.sentRequest() && (is.uid == uid) && 
((is.getStatus() == SSKInsertSender.ROUTE_NOT_FOUND) 
+                                       || (is.getStatus() == 
SSKInsertSender.SUCCESS))) {
+                               // It worked!
+                               long endTime = System.currentTimeMillis();
+                               long rtt = endTime - startTime;
+                               throttleWindow.requestCompleted();
+                               sskInsertThrottle.successfulCompletion(rtt);
+                       }
+               }
+
+               int status = is.getStatus();
+               
+        if(status != CHKInsertSender.TIMED_OUT && status != 
CHKInsertSender.GENERATED_REJECTED_OVERLOAD && status != 
CHKInsertSender.INTERNAL_ERROR
+                       && status != CHKInsertSender.ROUTE_REALLY_NOT_FOUND) {
+               int sent = is.getTotalSentBytes();
+               int received = is.getTotalReceivedBytes();
+               Logger.minor(this, "Local SSK insert cost "+sent+"/"+received+" 
bytes ("+status+")");
+               node.localSskInsertBytesSentAverage.report(sent);
+               node.localSskInsertBytesReceivedAverage.report(received);
+        }
+        
+               if(is.hasCollided()) {
+                       // Store it locally so it can be fetched immediately, 
and overwrites any locally inserted.
+                       try {
+                               node.storeInsert(is.getBlock());
+                       } catch (KeyCollisionException e) {
+                               // Impossible
+                       }
+                       throw new 
LowLevelPutException(LowLevelPutException.COLLISION);
+               }
+               
+               if(status == SSKInsertSender.SUCCESS) {
+                       Logger.normal(this, "Succeeded inserting "+block);
+                       return;
+               } else {
+                       String msg = "Failed inserting "+block+" : 
"+is.getStatusString();
+                       if(status == CHKInsertSender.ROUTE_NOT_FOUND)
+                               msg += " - this is normal on small networks; 
the data will still be propagated, but it can't find the 20+ nodes needed for 
full success";
+                       if(is.getStatus() != SSKInsertSender.ROUTE_NOT_FOUND)
+                               Logger.error(this, msg);
+                       else
+                               Logger.normal(this, msg);
+                       switch(is.getStatus()) {
+                       case SSKInsertSender.NOT_FINISHED:
+                               Logger.error(this, "IS still running in 
putCHK!: "+is);
+                               throw new 
LowLevelPutException(LowLevelPutException.INTERNAL_ERROR);
+                       case SSKInsertSender.GENERATED_REJECTED_OVERLOAD:
+                       case SSKInsertSender.TIMED_OUT:
+                               throw new 
LowLevelPutException(LowLevelPutException.REJECTED_OVERLOAD);
+                       case SSKInsertSender.ROUTE_NOT_FOUND:
+                               throw new 
LowLevelPutException(LowLevelPutException.ROUTE_NOT_FOUND);
+                       case SSKInsertSender.ROUTE_REALLY_NOT_FOUND:
+                               throw new 
LowLevelPutException(LowLevelPutException.ROUTE_REALLY_NOT_FOUND);
+                       case SSKInsertSender.INTERNAL_ERROR:
+                               throw new 
LowLevelPutException(LowLevelPutException.INTERNAL_ERROR);
+                       default:
+                               Logger.error(this, "Unknown CHKInsertSender 
code in putSSK: "+is.getStatus()+" on "+is);
+                               throw new 
LowLevelPutException(LowLevelPutException.INTERNAL_ERROR);
+                       }
+               }
+       }
+
+       public HighLevelSimpleClient makeClient(short prioClass) {
+               return new HighLevelSimpleClientImpl(this, archiveManager, 
tempBucketFactory, random, !Node.DONT_CACHE_LOCAL_REQUESTS, prioClass);
+       }
+       
+       public BaseRequestThrottle getCHKRequestThrottle() {
+               return chkRequestThrottle;
+       }
+
+       public BaseRequestThrottle getCHKInsertThrottle() {
+               return chkInsertThrottle;
+       }
+       
+       public BaseRequestThrottle getSSKRequestThrottle() {
+               return sskRequestThrottle;
+       }
+       
+       public BaseRequestThrottle getSSKInsertThrottle() {
+               return sskInsertThrottle;
+       }
+
+       public FCPServer getFCPServer() {
+               return fcpServer;
+       }
+
+       public void setToadletContainer(SimpleToadletServer server) {
+               toadletContainer = server;
+       }
+
+       public FProxyToadlet getFProxy() {
+               return fproxyServlet;
+       }
+
+       public SimpleToadletServer getToadletContainer() {
+               return toadletContainer;
+       }
+       
+       public TextModeClientInterfaceServer getTextModeClientInterface(){
+               return tmci;
+       }
+
+       public void setFProxy(FProxyToadlet fproxy) {
+               this.fproxyServlet = fproxy;
+       }
+
+       public void setFCPServer(FCPServer fcp) {
+               this.fcpServer = fcp;
+       }
+       
+       public void setTMCI(TextModeClientInterfaceServer server) {
+               this.tmci = server;
+       }
+
+       public TextModeClientInterface getDirectTMCI() {
+               return directTMCI;
+       }
+       
+       public void setDirectTMCI(TextModeClientInterface i) {
+               this.directTMCI = i;
+       }
+
+       public File getDownloadDir() {
+               return downloadDir;
+       }
+
+       public HealingQueue getHealingQueue() {
+               return healingQueue;
+       }
+
+       public void queueRandomReinsert(KeyBlock block) {
+               SimpleSendableInsert ssi = new SimpleSendableInsert(this, 
block, RequestStarter.MAXIMUM_PRIORITY_CLASS);
+               Logger.minor(this, "Queueing random reinsert for "+block+" : 
"+ssi);
+               if(block instanceof CHKBlock)
+                       chkPutScheduler.register(ssi);
+               else if(block instanceof SSKBlock)
+                       sskPutScheduler.register(ssi);
+               else
+                       Logger.error(this, "Don't know what to do with 
"+block+" should be queued for reinsert");
+       }
+
+       public void storeConfig() {
+               node.config.store();
+       }
+
+       public boolean isTestnetEnabled() {
+               return node.isTestnetEnabled();
+       }
+
+       public boolean isAdvancedDarknetEnabled() {
+               return (getToadletContainer() != null) &&
+                       getToadletContainer().isAdvancedDarknetEnabled();
+       }
+
+       public String getMyName() {
+               return node.getMyName();
+       }
+
+}

Modified: trunk/freenet/src/freenet/node/NodeDispatcher.java
===================================================================
--- trunk/freenet/src/freenet/node/NodeDispatcher.java  2006-08-12 18:13:01 UTC 
(rev 10047)
+++ trunk/freenet/src/freenet/node/NodeDispatcher.java  2006-08-12 19:24:25 UTC 
(rev 10048)
@@ -326,7 +326,7 @@
         // Forward
         m = preForward(m, htl);
         while(true) {
-            PeerNode next = node.peers.closerPeer(pn, ctx.routedTo, 
ctx.notIgnored, target, true);
+            PeerNode next = node.peers.closerPeer(pn, ctx.routedTo, 
ctx.notIgnored, target, true, node.isAdvancedDarknetEnabled());
             Logger.minor(this, "Next: "+next+" message: "+m);
             if(next != null) {
                // next is connected, or at least has been => next.getPeer() 
CANNOT be null.

Modified: trunk/freenet/src/freenet/node/NodeIPDetector.java
===================================================================
--- trunk/freenet/src/freenet/node/NodeIPDetector.java  2006-08-12 18:13:01 UTC 
(rev 10047)
+++ trunk/freenet/src/freenet/node/NodeIPDetector.java  2006-08-12 19:24:25 UTC 
(rev 10048)
@@ -50,10 +50,10 @@
        public NodeIPDetector(Node node) {
                this.node = node;
                this.ticker = node.ps;
-               ipDetectorManager = new IPDetectorPluginManager(node);
+               ipDetectorManager = new IPDetectorPluginManager(node, this);
                ipDetector = new IPAddressDetector(10*1000, this);
                primaryIPUndetectedAlert = new IPUndetectedUserAlert();
-               arkPutter = new NodeARKInserter(node);
+               arkPutter = new NodeARKInserter(node, this);
        }

        /**
@@ -138,10 +138,12 @@
                                }
                        }
                }
-               if (addresses.isEmpty()) {
-                       node.alerts.register(primaryIPUndetectedAlert);
-               } else {
-                       node.alerts.unregister(primaryIPUndetectedAlert);
+               if(node.clientCore != null) {
+                       if (addresses.isEmpty()) {
+                               
node.clientCore.alerts.register(primaryIPUndetectedAlert);
+                       } else {
+                               
node.clientCore.alerts.unregister(primaryIPUndetectedAlert);
+                       }
                }
                lastIPAddress = (Peer[]) addresses.toArray(new 
Peer[addresses.size()]);
                return lastIPAddress;

Modified: trunk/freenet/src/freenet/node/PeerManager.java
===================================================================
--- trunk/freenet/src/freenet/node/PeerManager.java     2006-08-12 18:13:01 UTC 
(rev 10047)
+++ trunk/freenet/src/freenet/node/PeerManager.java     2006-08-12 19:24:25 UTC 
(rev 10048)
@@ -43,7 +43,7 @@

     final String filename;

-    private final PeerManagerUserAlert ua;
+    final PeerManagerUserAlert ua;

     /**
      * Create a PeerManager by reading a list of peers from
@@ -56,7 +56,6 @@
         System.out.println("Creating PeerManager");
         this.filename = filename;
         ua = new PeerManagerUserAlert(node);
-        node.alerts.register(ua);
         myPeers = new PeerNode[0];
         connectedPeers = new PeerNode[0];
         this.node = node;
@@ -117,14 +116,13 @@
             // End of file, fine
         } catch (IOException e1) {
             Logger.error(this, "Could not read peers file: "+e1, e1);
-        } finally {
-            try {
-                br.close();
-            } catch (IOException e3) {
-                Logger.error(this, "Ignoring "+e3+" caught reading "+filename, 
e3);
-            }
-            return gotSome;
         }
+        try {
+               br.close();
+        } catch (IOException e3) {
+               Logger.error(this, "Ignoring "+e3+" caught reading "+filename, 
e3);
+        }
+        return gotSome;
        }

        public boolean addPeer(PeerNode pn) {
@@ -445,10 +443,9 @@
      * This scans the same array 4 times.  It would be better to scan once and 
execute 4 callbacks...
      * For this reason the metrics are only updated if advanced mode is enabled
      */
-    public PeerNode closerPeer(PeerNode pn, HashSet routedTo, HashSet 
notIgnored, double loc, boolean ignoreSelf) {
+    public PeerNode closerPeer(PeerNode pn, HashSet routedTo, HashSet 
notIgnored, double loc, boolean ignoreSelf, boolean calculateMisrouting) {
        PeerNode best = _closerPeer(pn, routedTo, notIgnored, loc, ignoreSelf, 
false);
-       if ((best != null) && (node.getToadletContainer() != null) &&
-                       node.getToadletContainer().isAdvancedDarknetEnabled()) {
+       if ((best != null) && calculateMisrouting) {
                PeerNode nbo = _closerPeer(pn, routedTo, notIgnored, loc, 
ignoreSelf, true);
                if(nbo != null) {
                        node.missRoutingDistance.report(distance(best, 
nbo.getLocation().getValue()));
@@ -686,4 +683,8 @@
                Logger.normal(this, msg);
                System.out.println(msg);
        }
+
+       public void start() {
+               node.clientCore.alerts.register(ua);
+       }
 }

Modified: trunk/freenet/src/freenet/node/RequestSender.java
===================================================================
--- trunk/freenet/src/freenet/node/RequestSender.java   2006-08-12 18:13:01 UTC 
(rev 10047)
+++ trunk/freenet/src/freenet/node/RequestSender.java   2006-08-12 19:24:25 UTC 
(rev 10048)
@@ -126,7 +126,7 @@
             // Route it
             PeerNode next;
             double nextValue;
-            next = node.peers.closerPeer(source, nodesRoutedTo, 
nodesNotIgnored, target, true);
+            next = node.peers.closerPeer(source, nodesRoutedTo, 
nodesNotIgnored, target, true, node.isAdvancedDarknetEnabled());
             if(next != null)
                 nextValue = next.getLocation().getValue();
             else

Modified: trunk/freenet/src/freenet/node/RequestStarter.java
===================================================================
--- trunk/freenet/src/freenet/node/RequestStarter.java  2006-08-12 18:13:01 UTC 
(rev 10047)
+++ trunk/freenet/src/freenet/node/RequestStarter.java  2006-08-12 19:24:25 UTC 
(rev 10048)
@@ -42,12 +42,12 @@
        final RunningAverage averageInputBytesPerRequest;
        final RunningAverage averageOutputBytesPerRequest;
        RequestScheduler sched;
-       final Node node;
+       final NodeClientCore core;
        private long sentRequestTime;

-       public RequestStarter(Node node, BaseRequestThrottle throttle, String 
name, TokenBucket outputBucket, TokenBucket inputBucket,
+       public RequestStarter(NodeClientCore node, BaseRequestThrottle 
throttle, String name, TokenBucket outputBucket, TokenBucket inputBucket,
                        RunningAverage averageOutputBytesPerRequest, 
RunningAverage averageInputBytesPerRequest) {
-               this.node = node;
+               this.core = node;
                this.throttle = throttle;
                this.name = name;
                this.outputBucket = outputBucket;
@@ -153,7 +153,7 @@
                }

                public void run() {
-                       req.send(node);
+                       req.send(core);
                }

        }

Modified: trunk/freenet/src/freenet/node/SSKInsertSender.java
===================================================================
--- trunk/freenet/src/freenet/node/SSKInsertSender.java 2006-08-12 18:13:01 UTC 
(rev 10047)
+++ trunk/freenet/src/freenet/node/SSKInsertSender.java 2006-08-12 19:24:25 UTC 
(rev 10048)
@@ -133,7 +133,7 @@
             // Can backtrack, so only route to nodes closer than we are to 
target.
             double nextValue;
             synchronized(node.peers) {
-                next = node.peers.closerPeer(source, nodesRoutedTo, 
nodesNotIgnored, target, true);
+                next = node.peers.closerPeer(source, nodesRoutedTo, 
nodesNotIgnored, target, true, node.isAdvancedDarknetEnabled());
                 if(next != null)
                     nextValue = next.getLocation().getValue();
                 else

Modified: trunk/freenet/src/freenet/node/SendableRequest.java
===================================================================
--- trunk/freenet/src/freenet/node/SendableRequest.java 2006-08-12 18:13:01 UTC 
(rev 10047)
+++ trunk/freenet/src/freenet/node/SendableRequest.java 2006-08-12 19:24:25 UTC 
(rev 10048)
@@ -14,7 +14,7 @@
        public int getRetryCount();

        /** ONLY called by RequestStarter */
-       public void send(Node node);
+       public void send(NodeClientCore node);

        /** Get client context object */
        public Object getClient();

Modified: trunk/freenet/src/freenet/node/SimpleSendableInsert.java
===================================================================
--- trunk/freenet/src/freenet/node/SimpleSendableInsert.java    2006-08-12 
18:13:01 UTC (rev 10047)
+++ trunk/freenet/src/freenet/node/SimpleSendableInsert.java    2006-08-12 
19:24:25 UTC (rev 10048)
@@ -12,12 +12,12 @@
  */
 public class SimpleSendableInsert implements SendableInsert {

-       public final Node node;
+       public final NodeClientCore node;
        public final KeyBlock block;
        public final short prioClass;
        private boolean finished;

-       public SimpleSendableInsert(Node node, KeyBlock block, short prioClass) 
{
+       public SimpleSendableInsert(NodeClientCore node, KeyBlock block, short 
prioClass) {
                this.node = node;
                this.block = block;
                this.prioClass = prioClass;
@@ -41,10 +41,10 @@
                return 0;
        }

-       public void send(Node node) {
+       public void send(NodeClientCore core) {
                try {
                        Logger.minor(this, "Starting request: "+this);
-                       node.realPut(block, false);
+                       core.realPut(block, false);
                } catch (LowLevelPutException e) {
                        onFailure(e);
                        Logger.minor(this, "Request failed: "+this+" for "+e);

Modified: trunk/freenet/src/freenet/node/TextModeClientInterface.java
===================================================================
--- trunk/freenet/src/freenet/node/TextModeClientInterface.java 2006-08-12 
18:13:01 UTC (rev 10047)
+++ trunk/freenet/src/freenet/node/TextModeClientInterface.java 2006-08-12 
19:24:25 UTC (rev 10048)
@@ -51,6 +51,7 @@

     final RandomSource r;
     final Node n;
+    final NodeClientCore core;
     final HighLevelSimpleClient client;
     final Hashtable streams;
     final File downloadsDir;
@@ -59,8 +60,9 @@

     public TextModeClientInterface(TextModeClientInterfaceServer server, 
InputStream in, OutputStream out) {
        this.n = server.n;
+       this.core = server.n.clientCore;
        this.r = server.r;
-        client = 
server.n.makeClient(RequestStarter.INTERACTIVE_PRIORITY_CLASS);
+        client = core.makeClient(RequestStarter.INTERACTIVE_PRIORITY_CLASS);
        this.streams = new Hashtable();
        this.downloadsDir = server.downloadsDir;
        this.in = in;
@@ -71,6 +73,7 @@
     public TextModeClientInterface(Node n, HighLevelSimpleClient c, File 
downloadDir, InputStream in, OutputStream out) {
        this.n = n;
        this.r = n.random;
+       this.core = n.clientCore;
        this.client = c;
        this.streams = new Hashtable();
        this.downloadsDir = downloadDir;
@@ -168,7 +171,7 @@
         sb.append("SHUTDOWN - exit the program\r\n");
         if(n.isUsingWrapper())
                sb.append("RESTART - restart the program\r\n");
-        if(n.directTMCI != this) {
+        if(core.directTMCI != this) {
           sb.append("QUIT - close the socket\r\n");
         }
         if(n.testnetEnabled) {
@@ -332,7 +335,7 @@
                out.write(sb.toString().getBytes());
                out.flush();
                n.getNodeStarter().restart();
-       } else if(uline.startsWith("QUIT") && (n.directTMCI == this)) {
+       } else if(uline.startsWith("QUIT") && (core.directTMCI == this)) {
                StringBuffer sb = new StringBuffer();
                sb.append("QUIT command not available in console mode.\r\n");
                out.write(sb.toString().getBytes());

Modified: trunk/freenet/src/freenet/node/TextModeClientInterfaceServer.java
===================================================================
--- trunk/freenet/src/freenet/node/TextModeClientInterfaceServer.java   
2006-08-12 18:13:01 UTC (rev 10047)
+++ trunk/freenet/src/freenet/node/TextModeClientInterfaceServer.java   
2006-08-12 19:24:25 UTC (rev 10048)
@@ -24,6 +24,7 @@

     final RandomSource r;
     final Node n;
+    final NodeClientCore core;
 //    final HighLevelSimpleClient client;
     final Hashtable streams;
     final File downloadsDir;
@@ -33,16 +34,17 @@
     boolean isEnabled;
     NetworkInterface networkInterface;

-    TextModeClientInterfaceServer(Node n, int port, String bindTo, String 
allowedHosts) {
-        this.n = n;
+    TextModeClientInterfaceServer(Node node, int port, String bindTo, String 
allowedHosts) {
+       this.n = node;
+       this.core = n.clientCore;
         this.r = n.random;
         streams = new Hashtable();
-        this.downloadsDir = n.downloadDir;
+        this.downloadsDir = core.downloadDir;
         this.port=port;
         this.bindTo=bindTo;
         this.allowedHosts = allowedHosts;
         this.isEnabled=true;
-        n.setTMCI(this);
+        core.setTMCI(this);
     }

     void start() {
@@ -54,16 +56,18 @@
        public static void maybeCreate(Node node, Config config) throws 
IOException {
                SubConfig TMCIConfig = new SubConfig("console", config);

+               NodeClientCore core = node.clientCore;
+               
                TMCIConfig.register("enabled", true, 1, true, "Enable TMCI", 
"Whether to enable the TMCI",
-                               new TMCIEnabledCallback(node));
+                               new TMCIEnabledCallback(core));
                TMCIConfig.register("bindTo", "127.0.0.1", 2, true, "IP address 
to bind to", "IP address to bind to",
-                               new TMCIBindtoCallback(node));
+                               new TMCIBindtoCallback(core));
                TMCIConfig.register("allowedHosts", "127.0.0.1", 2, true, 
"Allowed hosts", "Hostnames or IP addresses that are allowed to connect to the 
TMCI. May be a comma-separated list of hostnames, single IPs and even CIDR 
masked IPs like 192.168.0.0/24",
-                               new TMCIAllowedHostsCallback(node));
+                               new TMCIAllowedHostsCallback(core));
                TMCIConfig.register("port", 2323, 1, true, "Telnet port", 
"Telnet port number",
-                       new TCMIPortNumberCallback(node));
+                       new TCMIPortNumberCallback(core));
                TMCIConfig.register("directEnabled", false, 1, true, "Enable on 
stdout/stdin?", "Enable text mode client interface on standard input/output? 
(.enabled refers to providing a telnet-style server, this runs it over a 
socket)",
-                               new TMCIDirectEnabledCallback(node));
+                               new TMCIDirectEnabledCallback(core));

                boolean TMCIEnabled = TMCIConfig.getBoolean("enabled");
                int port =  TMCIConfig.getInt("port");
@@ -73,22 +77,22 @@

                if(TMCIEnabled){
                        new TextModeClientInterfaceServer(node, port, bind_ip, 
allowedHosts).start();
-                       Logger.normal(node, "TMCI started on 
"+bind_ip+":"+port);
+                       Logger.normal(core, "TMCI started on 
"+bind_ip+":"+port);
                        System.out.println("TMCI started on "+bind_ip+":"+port);
                }
                else{
-                       Logger.normal(node, "Not starting TMCI as it's 
disabled");
+                       Logger.normal(core, "Not starting TMCI as it's 
disabled");
                        System.out.println("Not starting TMCI as it's 
disabled");
                }

                if(direct) {
-               HighLevelSimpleClient client = 
node.makeClient(RequestStarter.INTERACTIVE_PRIORITY_CLASS);
+               HighLevelSimpleClient client = 
core.makeClient(RequestStarter.INTERACTIVE_PRIORITY_CLASS);
                        TextModeClientInterface directTMCI =
-                               new TextModeClientInterface(node, client, 
node.downloadDir, System.in, System.out);
+                               new TextModeClientInterface(node, client, 
core.downloadDir, System.in, System.out);
                        Thread t = new Thread(directTMCI, "Direct text mode 
interface");
                        t.setDaemon(true);
                        t.start();
-                       node.setDirectTMCI(directTMCI);
+                       core.setDirectTMCI(directTMCI);
                }

                TMCIConfig.finishedInitialization();
@@ -97,14 +101,14 @@

     static class TMCIEnabledCallback implements BooleanCallback {

-       final Node node;
+       final NodeClientCore core;

-       TMCIEnabledCallback(Node n) {
-               this.node = n;
+       TMCIEnabledCallback(NodeClientCore core) {
+               this.core = core;
        }

        public boolean get() {
-               return node.getTextModeClientInterface() != null;
+               return core.getTextModeClientInterface() != null;
        }

        public void set(boolean val) throws InvalidConfigValueException {
@@ -116,14 +120,14 @@

     static class TMCIDirectEnabledCallback implements BooleanCallback {

-       final Node node;
+       final NodeClientCore core;

-       TMCIDirectEnabledCallback(Node n) {
-               this.node = n;
+       TMCIDirectEnabledCallback(NodeClientCore core) {
+               this.core = core;
        }

        public boolean get() {
-               return node.getDirectTMCI() != null;
+               return core.getDirectTMCI() != null;
        }

        public void set(boolean val) throws InvalidConfigValueException {
@@ -135,15 +139,15 @@

     static class TMCIBindtoCallback implements StringCallback {

-       final Node node;
+       final NodeClientCore core;

-       TMCIBindtoCallback(Node n) {
-               this.node = n;
+       TMCIBindtoCallback(NodeClientCore core) {
+               this.core = core;
        }

        public String get() {
-               if(node.getTextModeClientInterface()!=null)
-                       return node.getTextModeClientInterface().bindTo;
+               if(core.getTextModeClientInterface()!=null)
+                       return core.getTextModeClientInterface().bindTo;
                else
                        return "127.0.0.1";
        }
@@ -151,8 +155,8 @@
        public void set(String val) throws InvalidConfigValueException {
                if(val.equals(get())) return;
                try {
-                               
node.getTextModeClientInterface().networkInterface.setBindTo(val);
-                               node.getTextModeClientInterface().bindTo = val;
+                               
core.getTextModeClientInterface().networkInterface.setBindTo(val);
+                               core.getTextModeClientInterface().bindTo = val;
                        } catch (IOException e) {
                                throw new InvalidConfigValueException("could 
not change bind to!");
                        }
@@ -161,23 +165,23 @@

     static class TMCIAllowedHostsCallback implements StringCallback {

-       private final Node node;
+       private final NodeClientCore core;

-       public TMCIAllowedHostsCallback(Node node) {
-               this.node = node;
+       public TMCIAllowedHostsCallback(NodeClientCore core) {
+               this.core = core;
        }

                public String get() {
-                       if (node.getTextModeClientInterface() != null) {
-                               return 
node.getTextModeClientInterface().allowedHosts;
+                       if (core.getTextModeClientInterface() != null) {
+                               return 
core.getTextModeClientInterface().allowedHosts;
                        }
                        return "127.0.0.1";
                }

                public void set(String val) {
                        if (!val.equals(get())) {
-                               
node.getTextModeClientInterface().networkInterface.setAllowedHosts(val);
-                               node.getTextModeClientInterface().allowedHosts 
= val;
+                               
core.getTextModeClientInterface().networkInterface.setAllowedHosts(val);
+                               core.getTextModeClientInterface().allowedHosts 
= val;
                        }
                }

@@ -185,15 +189,15 @@

     static class TCMIPortNumberCallback implements IntCallback{

-       final Node node;
+       final NodeClientCore core;

-       TCMIPortNumberCallback(Node n) {
-               this.node = n;
+       TCMIPortNumberCallback(NodeClientCore core) {
+               this.core = core;
        }

        public int get() {
-               if(node.getTextModeClientInterface()!=null)
-                       return node.getTextModeClientInterface().port;
+               if(core.getTextModeClientInterface()!=null)
+                       return core.getTextModeClientInterface().port;
                else
                        return 2323;
        }
@@ -201,7 +205,7 @@
        // TODO: implement it
        public void set(int val) throws InvalidConfigValueException {
                if(val == get()) return;
-               node.getTextModeClientInterface().setPort(val);
+               core.getTextModeClientInterface().setPort(val);
        }
     }


Modified: trunk/freenet/src/freenet/node/fcp/ClientGet.java
===================================================================
--- trunk/freenet/src/freenet/node/fcp/ClientGet.java   2006-08-12 18:13:01 UTC 
(rev 10047)
+++ trunk/freenet/src/freenet/node/fcp/ClientGet.java   2006-08-12 19:24:25 UTC 
(rev 10048)
@@ -96,7 +96,7 @@
                        tempFile = null;
                        try {
                                if(persistenceType == PERSIST_FOREVER)
-                                       ret = 
client.server.node.persistentTempBucketFactory.makeEncryptedBucket();
+                                       ret = 
client.server.core.persistentTempBucketFactory.makeEncryptedBucket();
                                else
                                        ret = fctx.bucketFactory.makeBucket(-1);
                        } catch (IOException e) {
@@ -114,7 +114,7 @@
                                ret.free();
                                throw e;
                        }
-               getter = new ClientGetter(this, client.node.chkFetchScheduler, 
client.node.sskFetchScheduler, uri, fctx, priorityClass, client, returnBucket);
+               getter = new ClientGetter(this, client.core.chkFetchScheduler, 
client.core.sskFetchScheduler, uri, fctx, priorityClass, client, returnBucket);
                if(persistenceType != PERSIST_CONNECTION) {
                        FCPMessage msg = persistentTagMessage();
                        client.queueClientRequestMessage(msg, 0);
@@ -153,7 +153,7 @@
                        tempFile = null;
                        try {
                                if(persistenceType == PERSIST_FOREVER)
-                                       ret = 
client.server.node.persistentTempBucketFactory.makeEncryptedBucket();
+                                       ret = 
client.server.core.persistentTempBucketFactory.makeEncryptedBucket();
                                else
                                        ret = fctx.bucketFactory.makeBucket(-1);
                        } catch (IOException e) {
@@ -171,7 +171,7 @@
                                ret.free();
                                throw e;
                        }
-               getter = new ClientGetter(this, client.node.chkFetchScheduler, 
client.node.sskFetchScheduler, uri, fctx, priorityClass, client, returnBucket);
+               getter = new ClientGetter(this, client.core.chkFetchScheduler, 
client.core.sskFetchScheduler, uri, fctx, priorityClass, client, returnBucket);
                if(persistenceType != PERSIST_CONNECTION) {
                        FCPMessage msg = persistentTagMessage();
                        client.queueClientRequestMessage(msg, 0);
@@ -229,13 +229,13 @@
                } else if(returnType == ClientGetMessage.RETURN_TYPE_DIRECT) {
                        byte[] key = 
HexUtil.hexToBytes(fs.get("ReturnBucket.DecryptKey"));
                        String fnam = fs.get("ReturnBucket.Filename");
-                       ret = 
client.server.node.persistentTempBucketFactory.registerEncryptedBucket(fnam, 
key, succeeded ? foundDataLength : 0);
+                       ret = 
client.server.core.persistentTempBucketFactory.registerEncryptedBucket(fnam, 
key, succeeded ? foundDataLength : 0);
                } else {
                        throw new IllegalArgumentException();
                }
                returnBucket = ret;

-               getter = new ClientGetter(this, client.node.chkFetchScheduler, 
client.node.sskFetchScheduler, uri, fctx, priorityClass, client, returnBucket);
+               getter = new ClientGetter(this, client.core.chkFetchScheduler, 
client.core.sskFetchScheduler, uri, fctx, priorityClass, client, returnBucket);
                if(persistenceType != PERSIST_CONNECTION) {
                        FCPMessage msg = persistentTagMessage();
                        client.queueClientRequestMessage(msg, 0);

Modified: trunk/freenet/src/freenet/node/fcp/ClientPut.java
===================================================================
--- trunk/freenet/src/freenet/node/fcp/ClientPut.java   2006-08-12 18:13:01 UTC 
(rev 10047)
+++ trunk/freenet/src/freenet/node/fcp/ClientPut.java   2006-08-12 19:24:25 UTC 
(rev 10048)
@@ -110,7 +110,7 @@
                this.clientMetadata = cm;
                Logger.minor(this, "data = "+data+", uploadFrom = 
"+ClientPutMessage.uploadFromString(uploadFrom));
                inserter = new ClientPutter(this, data, uri, cm, 
-                               ctx, client.node.chkPutScheduler, 
client.node.sskPutScheduler, priorityClass, 
+                               ctx, client.core.chkPutScheduler, 
client.core.sskPutScheduler, priorityClass, 
                                getCHKOnly, isMetadata, client, null);
                if(persistenceType != PERSIST_CONNECTION) {
                        FCPMessage msg = persistentTagMessage();
@@ -157,7 +157,7 @@
                this.clientMetadata = cm;
                Logger.minor(this, "data = "+data+", uploadFrom = 
"+ClientPutMessage.uploadFromString(uploadFrom));
                inserter = new ClientPutter(this, data, uri, cm, 
-                               ctx, client.node.chkPutScheduler, 
client.node.sskPutScheduler, priorityClass, 
+                               ctx, client.core.chkPutScheduler, 
client.core.sskPutScheduler, priorityClass, 
                                getCHKOnly, isMetadata, client, null);
                if(persistenceType != PERSIST_CONNECTION) {
                        FCPMessage msg = persistentTagMessage();
@@ -212,7 +212,7 @@
                                String fnam = fs.get("TempBucket.Filename");
                                long sz = 
Long.parseLong(fs.get("TempBucket.Size"));
                                try {
-                                       data = 
client.server.node.persistentTempBucketFactory.registerEncryptedBucket(fnam, 
key, sz);
+                                       data = 
client.server.core.persistentTempBucketFactory.registerEncryptedBucket(fnam, 
key, sz);
                                        if(data.size() != sz)
                                                throw new 
PersistenceParseException("Size of bucket is wrong: "+data.size()+" should be 
"+sz);
                                } catch (IOException e) {
@@ -245,8 +245,8 @@
                        throw new PersistenceParseException("shouldn't happen");
                }
                this.clientMetadata = cm;
-               inserter = new ClientPutter(this, data, uri, cm, ctx, 
client.node.chkPutScheduler, 
-                               client.node.sskPutScheduler, priorityClass, 
getCHKOnly, isMetadata, client, fs.subset("progress"));
+               inserter = new ClientPutter(this, data, uri, cm, ctx, 
client.core.chkPutScheduler, 
+                               client.core.sskPutScheduler, priorityClass, 
getCHKOnly, isMetadata, client, fs.subset("progress"));
                if(persistenceType != PERSIST_CONNECTION) {
                        FCPMessage msg = persistentTagMessage();
                        client.queueClientRequestMessage(msg, 0);

Modified: trunk/freenet/src/freenet/node/fcp/ClientPutDir.java
===================================================================
--- trunk/freenet/src/freenet/node/fcp/ClientPutDir.java        2006-08-12 
18:13:01 UTC (rev 10047)
+++ trunk/freenet/src/freenet/node/fcp/ClientPutDir.java        2006-08-12 
19:24:25 UTC (rev 10048)
@@ -37,7 +37,7 @@
                this.defaultName = message.defaultName;
                SimpleManifestPutter p;
                try {
-                       p = new SimpleManifestPutter(this, 
client.node.chkPutScheduler, client.node.sskPutScheduler,
+                       p = new SimpleManifestPutter(this, 
client.core.chkPutScheduler, client.core.sskPutScheduler,
                                        manifestElements, priorityClass, uri, 
defaultName, ctx, message.getCHKOnly, client);
                } catch (InserterException e) {
                        onFailure(e, null);
@@ -88,7 +88,7 @@
                                        // Direct (persistent temp bucket)
                                        byte[] key = 
HexUtil.hexToBytes(subset.get("TempBucket.DecryptKey"));
                                        String fnam = 
subset.get("TempBucket.Filename");
-                                       data = 
client.server.node.persistentTempBucketFactory.registerEncryptedBucket(fnam, 
key, sz);
+                                       data = 
client.server.core.persistentTempBucketFactory.registerEncryptedBucket(fnam, 
key, sz);
                                        if(data.size() != sz)
                                                throw new 
PersistenceParseException("Size of bucket is wrong: "+data.size()+" should be 
"+sz);
                                } else {
@@ -123,7 +123,7 @@
                SimpleManifestPutter p = null;
                try {
                        if(!finished)
-                               p = new SimpleManifestPutter(this, 
client.node.chkPutScheduler, client.node.sskPutScheduler,
+                               p = new SimpleManifestPutter(this, 
client.core.chkPutScheduler, client.core.sskPutScheduler,
                                                manifestElements, 
priorityClass, uri, defaultName, ctx, getCHKOnly, client);
                } catch (InserterException e) {
                        onFailure(e, null);

Modified: trunk/freenet/src/freenet/node/fcp/ClientPutMessage.java
===================================================================
--- trunk/freenet/src/freenet/node/fcp/ClientPutMessage.java    2006-08-12 
18:13:01 UTC (rev 10047)
+++ trunk/freenet/src/freenet/node/fcp/ClientPutMessage.java    2006-08-12 
19:24:25 UTC (rev 10048)
@@ -215,7 +215,7 @@

        Bucket createBucket(BucketFactory bf, long length, FCPServer server) 
throws IOException {
                if(persistenceType == ClientRequest.PERSIST_FOREVER) {
-                       return 
server.node.persistentTempBucketFactory.makeEncryptedBucket();
+                       return 
server.core.persistentTempBucketFactory.makeEncryptedBucket();
                } else {
                        return super.createBucket(bf, length, server);
                }

Modified: trunk/freenet/src/freenet/node/fcp/ClientRequest.java
===================================================================
--- trunk/freenet/src/freenet/node/fcp/ClientRequest.java       2006-08-12 
18:13:01 UTC (rev 10047)
+++ trunk/freenet/src/freenet/node/fcp/ClientRequest.java       2006-08-12 
19:24:25 UTC (rev 10048)
@@ -143,7 +143,7 @@
                boolean isGlobal = Fields.stringToBool(fs.get("Global"), false);
                FCPClient client;
                if(!isGlobal)
-                       client = server.registerClient(clientName, server.node, 
null);
+                       client = server.registerClient(clientName, server.core, 
null);
                else
                        client = server.globalClient;
                try {

Modified: trunk/freenet/src/freenet/node/fcp/FCPClient.java
===================================================================
--- trunk/freenet/src/freenet/node/fcp/FCPClient.java   2006-08-12 18:13:01 UTC 
(rev 10047)
+++ trunk/freenet/src/freenet/node/fcp/FCPClient.java   2006-08-12 19:24:25 UTC 
(rev 10048)
@@ -9,7 +9,7 @@
 import freenet.client.FetcherContext;
 import freenet.client.HighLevelSimpleClient;
 import freenet.client.InserterContext;
-import freenet.node.Node;
+import freenet.node.NodeClientCore;
 import freenet.support.LRUQueue;
 import freenet.support.Logger;

@@ -29,8 +29,8 @@
                this.completedUnackedRequests = new LRUQueue();
                this.clientRequestsByIdentifier = new HashMap();
                this.server = server;
-               this.node = server.node;
-               this.client = node.makeClient((short)0);
+               this.core = server.core;
+               this.client = core.makeClient((short)0);
                this.isGlobalQueue = isGlobalQueue;
                defaultFetchContext = client.getFetcherContext();
                defaultInsertContext = client.getInserterContext(false);
@@ -55,7 +55,7 @@
        private final HighLevelSimpleClient client;
        public final FetcherContext defaultFetchContext;
        public final InserterContext defaultInsertContext;
-       public final Node node;
+       public final NodeClientCore core;
        /** Are we the global queue? */
        public final boolean isGlobalQueue;
        /** Are we watching the global queue? */

Modified: trunk/freenet/src/freenet/node/fcp/FCPConnectionHandler.java
===================================================================
--- trunk/freenet/src/freenet/node/fcp/FCPConnectionHandler.java        
2006-08-12 18:13:01 UTC (rev 10047)
+++ trunk/freenet/src/freenet/node/fcp/FCPConnectionHandler.java        
2006-08-12 19:24:25 UTC (rev 10048)
@@ -25,7 +25,7 @@
                this.sock = s;
                this.server = server;
                isClosed = false;
-               this.bf = server.node.tempBucketFactory;
+               this.bf = server.core.tempBucketFactory;
                requestsByIdentifier = new HashMap();
                this.inputHandler = new FCPConnectionInputHandler(this);
                this.outputHandler = new FCPConnectionOutputHandler(this);
@@ -91,7 +91,7 @@

        public void setClientName(String name) {
                this.clientName = name;
-               client = server.registerClient(name, server.node, this);
+               client = server.registerClient(name, server.core, this);
        }

        public String getClientName() {

Modified: trunk/freenet/src/freenet/node/fcp/FCPConnectionInputHandler.java
===================================================================
--- trunk/freenet/src/freenet/node/fcp/FCPConnectionInputHandler.java   
2006-08-12 18:13:01 UTC (rev 10047)
+++ trunk/freenet/src/freenet/node/fcp/FCPConnectionInputHandler.java   
2006-08-12 19:24:25 UTC (rev 10048)
@@ -52,7 +52,7 @@
                        fs = new SimpleFieldSet(lis, 4096, 128, true, true);
                        FCPMessage msg;
                        try {
-                               msg = FCPMessage.create(messageType, fs, 
handler.bf, handler.server.node.persistentTempBucketFactory);
+                               msg = FCPMessage.create(messageType, fs, 
handler.bf, handler.server.core.persistentTempBucketFactory);
                                if(msg == null) continue;
                        } catch (MessageInvalidException e) {
                                FCPMessage err = new 
ProtocolErrorMessage(e.protocolCode, false, e.getMessage(), e.ident);

Modified: trunk/freenet/src/freenet/node/fcp/FCPServer.java
===================================================================
--- trunk/freenet/src/freenet/node/fcp/FCPServer.java   2006-08-12 18:13:01 UTC 
(rev 10047)
+++ trunk/freenet/src/freenet/node/fcp/FCPServer.java   2006-08-12 19:24:25 UTC 
(rev 10048)
@@ -33,6 +33,7 @@
 import freenet.io.NetworkInterface;
 import freenet.keys.FreenetURI;
 import freenet.node.Node;
+import freenet.node.NodeClientCore;
 import freenet.node.RequestStarter;
 import freenet.support.Base64;
 import freenet.support.Logger;
@@ -44,6 +45,7 @@
 public class FCPServer implements Runnable {

        NetworkInterface networkInterface;
+       final NodeClientCore core;
        final Node node;
        final int port;
        public final boolean enabled;
@@ -78,7 +80,7 @@
                persister = null;
        }

-       public FCPServer(String ipToBindTo, String allowedHosts, int port, Node 
node, boolean persistentDownloadsEnabled, String persistentDownloadsDir, long 
persistenceInterval, boolean isEnabled) throws IOException, 
InvalidConfigValueException {
+       public FCPServer(String ipToBindTo, String allowedHosts, int port, Node 
node, NodeClientCore core, boolean persistentDownloadsEnabled, String 
persistentDownloadsDir, long persistenceInterval, boolean isEnabled) throws 
IOException, InvalidConfigValueException {
                this.bindTo = ipToBindTo;
                this.allowedHosts = allowedHosts;
                this.persistenceInterval = persistenceInterval;
@@ -87,12 +89,13 @@
                this.enablePersistentDownloads = persistentDownloadsEnabled;
                setPersistentDownloadsFile(new File(persistentDownloadsDir));
                this.node = node;
+               this.core = core;
                clientsByName = new WeakHashMap();


                // This one is only used to get the default settings. 
Individual FCP conns
                // will make their own.
-               HighLevelSimpleClient client = node.makeClient((short)0);
+               HighLevelSimpleClient client = core.makeClient((short)0);
                defaultFetchContext = client.getFetcherContext();
                defaultInsertContext = client.getInserterContext(false);

@@ -154,9 +157,9 @@

        static class FCPPortNumberCallback implements IntCallback {

-               private final Node node;
+               private final NodeClientCore node;

-               FCPPortNumberCallback(Node node) {
+               FCPPortNumberCallback(NodeClientCore node) {
                        this.node = node;
                }

@@ -173,9 +176,9 @@

        static class FCPEnabledCallback implements BooleanCallback{

-               final Node node;
+               final NodeClientCore node;

-               FCPEnabledCallback(Node node) {
+               FCPEnabledCallback(NodeClientCore node) {
                        this.node = node;
                }

@@ -195,9 +198,9 @@

        static class FCPBindtoCallback implements StringCallback{

-               final Node node;
+               final NodeClientCore node;

-               FCPBindtoCallback(Node node) {
+               FCPBindtoCallback(NodeClientCore node) {
                        this.node = node;
                }

@@ -219,9 +222,9 @@

        static class FCPAllowedHostsCallback implements StringCallback {

-               private final Node node;
+               private final NodeClientCore node;

-               public FCPAllowedHostsCallback(Node node) {
+               public FCPAllowedHostsCallback(NodeClientCore node) {
                        this.node = node;
                }

@@ -287,13 +290,13 @@
                }
        }

-       public static FCPServer maybeCreate(Node node, Config config) throws 
IOException, InvalidConfigValueException {
+       public static FCPServer maybeCreate(Node node, NodeClientCore core, 
Config config) throws IOException, InvalidConfigValueException {
                SubConfig fcpConfig = new SubConfig("fcp", config);
-               fcpConfig.register("enabled", true, 2, true, "Is FCP server 
enabled ?", "Is FCP server enabled ?", new FCPEnabledCallback(node));
+               fcpConfig.register("enabled", true, 2, true, "Is FCP server 
enabled ?", "Is FCP server enabled ?", new FCPEnabledCallback(core));
                fcpConfig.register("port", 9481 /* anagram of 1984, and 1000 up 
from old number */,
-                               2, true, "FCP port number", "FCP port number", 
new FCPPortNumberCallback(node));
-               fcpConfig.register("bindTo", "127.0.0.1", 2, true, "Ip address 
to bind to", "Ip address to bind the FCP server to", new 
FCPBindtoCallback(node));
-               fcpConfig.register("allowedHosts", "127.0.0.1", 2, true, 
"Allowed hosts", "Hostnames or IP addresses that are allowed to connect to the 
FCP server. May be a comma-separated list of hostnames, single IPs and even 
CIDR masked IPs like 192.168.0.0/24", new FCPAllowedHostsCallback(node));
+                               2, true, "FCP port number", "FCP port number", 
new FCPPortNumberCallback(core));
+               fcpConfig.register("bindTo", "127.0.0.1", 2, true, "Ip address 
to bind to", "Ip address to bind the FCP server to", new 
FCPBindtoCallback(core));
+               fcpConfig.register("allowedHosts", "127.0.0.1", 2, true, 
"Allowed hosts", "Hostnames or IP addresses that are allowed to connect to the 
FCP server. May be a comma-separated list of hostnames, single IPs and even 
CIDR masked IPs like 192.168.0.0/24", new FCPAllowedHostsCallback(core));
                PersistentDownloadsEnabledCallback cb1;
                PersistentDownloadsFileCallback cb2;
                PersistentDownloadsIntervalCallback cb3;
@@ -312,8 +315,8 @@

                FCPServer fcp;

-               fcp = new FCPServer(fcpConfig.getString("bindTo"), 
fcpConfig.getString("allowedHosts"), fcpConfig.getInt("port"), node, 
persistentDownloadsEnabled, persistentDownloadsDir, 
persistentDownloadsInterval, fcpConfig.getBoolean("enabled"));
-               node.setFCPServer(fcp); 
+               fcp = new FCPServer(fcpConfig.getString("bindTo"), 
fcpConfig.getString("allowedHosts"), fcpConfig.getInt("port"), node, core, 
persistentDownloadsEnabled, persistentDownloadsDir, 
persistentDownloadsInterval, fcpConfig.getBoolean("enabled"));
+               core.setFCPServer(fcp); 

                if(fcp != null) {
                        cb1.server = fcp;
@@ -379,7 +382,7 @@
                }
        }

-       public FCPClient registerClient(String name, Node node, 
FCPConnectionHandler handler) {
+       public FCPClient registerClient(String name, NodeClientCore core, 
FCPConnectionHandler handler) {
                FCPClient oldClient;
                synchronized(this) {
                        oldClient = (FCPClient) clientsByName.get(name);
@@ -484,7 +487,7 @@
                Bucket[] toFree = null;
                try {
                        synchronized(persistenceSync) {
-                               toFree = 
node.persistentTempBucketFactory.grabBucketsToFree();
+                               toFree = 
core.persistentTempBucketFactory.grabBucketsToFree();
                                try {
                                        File compressedTemp = new 
File(persistentDownloadsTempFile+".gz");
                                        File compressedFinal = new 
File(persistentDownloadsFile.toString()+".gz");
@@ -634,7 +637,7 @@
                                                while(true) {
                                                        byte[] buf = new 
byte[8];
                                                        try {
-                                                               
node.random.nextBytes(buf);
+                                                               
core.random.nextBytes(buf);
                                                                String id = 
"FProxy:"+Base64.encode(buf);
                                                                
innerMakePersistentGlobalRequest(fetchURI, persistence, returnType, id, 
returnFilename, returnTempFilename);
                                                                return;
@@ -659,12 +662,12 @@
                } else ext = null;
                String extAdd = (ext == null ? "" : "." + ext);
                String preferred = uri.getPreferredFilename();
-               File f = new File(node.getDownloadDir(), preferred + extAdd);
-               File f1 = new File(node.getDownloadDir(), preferred + 
".freenet-tmp");
+               File f = new File(core.getDownloadDir(), preferred + extAdd);
+               File f1 = new File(core.getDownloadDir(), preferred + 
".freenet-tmp");
                int x = 0;
                while(f.exists() || f1.exists()) {
-                       f = new File(node.getDownloadDir(), preferred + "-" + x 
+ extAdd);
-                       f1 = new File(node.getDownloadDir(), preferred + "-" + 
x + extAdd + ".freenet-tmp");
+                       f = new File(core.getDownloadDir(), preferred + "-" + x 
+ extAdd);
+                       f1 = new File(core.getDownloadDir(), preferred + "-" + 
x + extAdd + ".freenet-tmp");
                }
                return f;
        }

Modified: trunk/freenet/src/freenet/node/fcp/SubscribeUSK.java
===================================================================
--- trunk/freenet/src/freenet/node/fcp/SubscribeUSK.java        2006-08-12 
18:13:01 UTC (rev 10047)
+++ trunk/freenet/src/freenet/node/fcp/SubscribeUSK.java        2006-08-12 
19:24:25 UTC (rev 10048)
@@ -3,25 +3,26 @@
 import freenet.client.async.USKCallback;
 import freenet.keys.USK;
 import freenet.node.Node;
+import freenet.node.NodeClientCore;

 public class SubscribeUSK implements USKCallback {

        final FCPConnectionHandler handler;
        final String identifier;
-       final Node node;
+       final NodeClientCore core;
        final boolean dontPoll;

-       public SubscribeUSK(SubscribeUSKMessage message, Node node, 
FCPConnectionHandler handler) {
+       public SubscribeUSK(SubscribeUSKMessage message, NodeClientCore core, 
FCPConnectionHandler handler) {
                this.handler = handler;
                this.dontPoll = message.dontPoll;
                this.identifier = message.identifier;
-               this.node = node;
-               node.uskManager.subscribe(message.key, this, !message.dontPoll);
+               this.core = core;
+               core.uskManager.subscribe(message.key, this, !message.dontPoll);
        }

        public void onFoundEdition(long l, USK key) {
                if(handler.isClosed()) {
-                       node.uskManager.unsubscribe(key, this, !dontPoll);
+                       core.uskManager.unsubscribe(key, this, !dontPoll);
                        return;
                }
                FCPMessage msg = new SubscribedUSKUpdate(identifier, l, key);

Modified: trunk/freenet/src/freenet/node/fcp/SubscribeUSKMessage.java
===================================================================
--- trunk/freenet/src/freenet/node/fcp/SubscribeUSKMessage.java 2006-08-12 
18:13:01 UTC (rev 10047)
+++ trunk/freenet/src/freenet/node/fcp/SubscribeUSKMessage.java 2006-08-12 
19:24:25 UTC (rev 10048)
@@ -56,7 +56,7 @@

        public void run(FCPConnectionHandler handler, Node node)
                        throws MessageInvalidException {
-               new SubscribeUSK(this, node, handler);
+               new SubscribeUSK(this, node.clientCore, handler);
        }

 }

Modified: trunk/freenet/src/freenet/node/updater/NodeUpdater.java
===================================================================
--- trunk/freenet/src/freenet/node/updater/NodeUpdater.java     2006-08-12 
18:13:01 UTC (rev 10047)
+++ trunk/freenet/src/freenet/node/updater/NodeUpdater.java     2006-08-12 
19:24:25 UTC (rev 10048)
@@ -28,7 +28,9 @@
 import freenet.keys.FreenetURI;
 import freenet.keys.USK;
 import freenet.node.Node;
+import freenet.node.NodeClientCore;
 import freenet.node.RequestStarter;
+import freenet.node.Ticker;
 import freenet.node.Version;
 import freenet.node.useralerts.RevocationKeyFoundUserAlert;
 import freenet.node.useralerts.UpdatedVersionAvailableUserAlert;
@@ -48,6 +50,8 @@
        private boolean finalCheck;
        private final FreenetURI URI;
        private final FreenetURI revocationURI;
+       private final Ticker ticker;
+       private final NodeClientCore core;
        private final Node node;

        private final int currentVersion;
@@ -73,8 +77,10 @@
                this.revocationURI = revocationURI;
                this.revocationAlert = null;
                this.revocationDNFCounter = 0;
+               this.ticker = n.ps;
+               this.core = n.clientCore;
                this.node = n;
-               node.nodeUpdater = this;
+               n.nodeUpdater = this;
                this.currentVersion = Version.buildNumber();
                this.availableVersion = currentVersion;
                this.hasBeenBlown = false;
@@ -85,14 +91,14 @@

                this.alert= new 
UpdatedVersionAvailableUserAlert(currentVersion, this);
                alert.isValid(false);
-               node.alerts.register(alert);
+               core.alerts.register(alert);

-               FetcherContext tempContext = 
n.makeClient((short)0).getFetcherContext();                
+               FetcherContext tempContext = 
core.makeClient((short)0).getFetcherContext();             
                tempContext.allowSplitfiles = true;
                tempContext.dontEnterImplicitArchives = false;
                this.ctx = tempContext;

-               ctxRevocation = n.makeClient((short)0).getFetcherContext();
+               ctxRevocation = core.makeClient((short)0).getFetcherContext();
                ctxRevocation.allowSplitfiles = false;
                ctxRevocation.cacheLocalRequests = false;
                ctxRevocation.maxArchiveLevels = 1;
@@ -123,7 +129,7 @@
                if(found > availableVersion){
                        Logger.minor(this, "Updating availableVersion from 
"+availableVersion+" to "+found+" and queueing an update");
                        this.availableVersion = found;
-                       node.ps.queueTimedJob(new Runnable() {
+                       ticker.queueTimedJob(new Runnable() {
                                public void run() {
                                        maybeUpdate();
                                }
@@ -153,7 +159,7 @@
                        try{
                                if((cg==null)||cg.isCancelled()){
                                        Logger.minor(this, "Scheduling request 
for "+URI.setSuggestedEdition(availableVersion));
-                                       cg = new ClientGetter(this, 
node.chkFetchScheduler, node.sskFetchScheduler, 
+                                       cg = new ClientGetter(this, 
core.chkFetchScheduler, core.sskFetchScheduler, 
                                                        
URI.setSuggestedEdition(availableVersion), ctx, 
RequestStarter.UPDATE_PRIORITY_CLASS, 
                                                        this, new 
ArrayBucket());
                                        toStart = cg;
@@ -503,7 +509,7 @@
                                                        Logger.minor(this, 
"fetcher="+revocationGetter);
                                                        if(revocationGetter != 
null)
                                                                
Logger.minor(this, "revocation fetcher: 
cancelled="+revocationGetter.isCancelled()+", 
finished="+revocationGetter.isFinished());
-                                                       cg = revocationGetter = 
new ClientGetter(NodeUpdater.this, node.chkFetchScheduler, 
node.sskFetchScheduler, revocationURI, ctxRevocation, 
RequestStarter.MAXIMUM_PRIORITY_CLASS, NodeUpdater.this, null);
+                                                       cg = revocationGetter = 
new ClientGetter(NodeUpdater.this, core.chkFetchScheduler, 
core.sskFetchScheduler, revocationURI, ctxRevocation, 
RequestStarter.MAXIMUM_PRIORITY_CLASS, NodeUpdater.this, null);
                                                        Logger.minor(this, 
"Queued another revocation fetcher");
                                                }
                                        }
@@ -575,9 +581,9 @@
                        this.hasBeenBlown = true;
                        if(revocationAlert==null){
                                revocationAlert = new 
RevocationKeyFoundUserAlert(msg);
-                               node.alerts.register(revocationAlert);
+                               core.alerts.register(revocationAlert);
                                // we don't need to advertize updates : we are 
not going to do them
-                               node.alerts.unregister(alert);
+                               core.alerts.unregister(alert);
                        }
                        Logger.error(this, "The updater has acknoledged that it 
knows the private key has been blown");
                }

Modified: 
trunk/freenet/src/freenet/node/useralerts/MeaningfulNodeNameUserAlert.java
===================================================================
--- trunk/freenet/src/freenet/node/useralerts/MeaningfulNodeNameUserAlert.java  
2006-08-12 18:13:01 UTC (rev 10047)
+++ trunk/freenet/src/freenet/node/useralerts/MeaningfulNodeNameUserAlert.java  
2006-08-12 19:24:25 UTC (rev 10048)
@@ -34,7 +34,7 @@
                "Putting your e-mail address or IRC nickname there is generally 
speaking " +
                "a good idea and helps your friends to identify your node.");
                buf.append("<form method=\"post\" action=\"/config/\">");
-               buf.append("<input type=\"hidden\" name=\"formPassword\" 
value=\""+node.formPassword+"\">");
+               buf.append("<input type=\"hidden\" name=\"formPassword\" 
value=\""+node.clientCore.formPassword+"\">");
                //buf.append("<ul class=\"config\"><span 
class=\"configprefix\">"+sc.getPrefix()+"</span>\n");
                buf.append("<ul class=\"config\">\n");
                buf.append("<li>");
@@ -66,7 +66,7 @@
                textNode.addChild("a", "href", "/config/", "Configuration 
Page");
                textNode.addChild("#", ". Putting your e-mail address or IRC 
nickname there is generally speaking a good idea and helps your friends to 
identify your node.");
                HTMLNode formNode = alertNode.addChild("form", new String[] { 
"action", "method" }, new String[] { "/config/", "post" });
-               formNode.addChild("input", new String[] { "type", "name", 
"value" }, new String[] { "hidden", "formPassword", node.formPassword });
+               formNode.addChild("input", new String[] { "type", "name", 
"value" }, new String[] { "hidden", "formPassword", 
node.clientCore.formPassword });
                HTMLNode listNode = formNode.addChild("ul", "class", "config");
                HTMLNode itemNode = listNode.addChild("li");
                itemNode.addChild("span", "class", "configshortdesc", 
o.getShortDesc()).addChild("input", new String[] { "type", "name", "value" }, 
new String[] { "text", sc.getPrefix() + ".name", o.getValueString() });

Modified: trunk/freenet/src/freenet/plugin/PluginManager.java
===================================================================
--- trunk/freenet/src/freenet/plugin/PluginManager.java 2006-08-12 18:13:01 UTC 
(rev 10047)
+++ trunk/freenet/src/freenet/plugin/PluginManager.java 2006-08-12 19:24:25 UTC 
(rev 10048)
@@ -12,6 +12,7 @@
 import freenet.config.StringArrOption;
 import freenet.config.SubConfig;
 import freenet.node.Node;
+import freenet.node.NodeClientCore;
 import freenet.support.Logger;

 /**
@@ -218,4 +219,8 @@
                return null;
        }

+       public NodeClientCore getClientCore() {
+               return node.clientCore;
+       }
+
 }

Modified: trunk/freenet/src/freenet/pluginmanager/PluginManager.java
===================================================================
--- trunk/freenet/src/freenet/pluginmanager/PluginManager.java  2006-08-12 
18:13:01 UTC (rev 10047)
+++ trunk/freenet/src/freenet/pluginmanager/PluginManager.java  2006-08-12 
19:24:25 UTC (rev 10048)
@@ -21,9 +21,9 @@
 import freenet.config.StringArrOption;
 import freenet.config.SubConfig;
 import freenet.node.Node;
+import freenet.node.NodeClientCore;
 import freenet.node.useralerts.SimpleUserAlert;
 import freenet.node.useralerts.UserAlert;
-import freenet.support.HTMLNode;
 import freenet.support.Logger;

 public class PluginManager {
@@ -41,7 +41,8 @@
        private HashMap toadletList;
        private HashMap pluginInfo;
        private PluginRespirator pluginRespirator = null;
-       private Node node;
+       private final Node node;
+       private final NodeClientCore core;
        SubConfig pmconfig;


@@ -49,6 +50,7 @@
                pluginInfo = new HashMap();
                toadletList = new HashMap();
                this.node = node;
+               this.core = node.clientCore;
                pluginRespirator = new PluginRespirator(node, this);

                pmconfig = new SubConfig("pluginmanager", node.config);
@@ -130,7 +132,7 @@
                        if(jvmVersion.startsWith("1.4.") || 
jvmVersion.equals("1.4")) {
                                System.err.println("Plugin "+filename+" appears 
to require a later JVM");
                                Logger.error(this, "Plugin "+filename+" appears 
to require a later JVM");
-                               node.alerts.register(new SimpleUserAlert(true, 
"Later JVM required by plugin "+filename,
+                               core.alerts.register(new SimpleUserAlert(true, 
"Later JVM required by plugin "+filename,
                                                "The plugin "+filename+" seems 
to require a later JVM. Please install at least Sun java 1.5, or remove the 
plugin.",
                                                UserAlert.ERROR));
                        }

Modified: trunk/freenet/src/freenet/pluginmanager/PluginRespirator.java
===================================================================
--- trunk/freenet/src/freenet/pluginmanager/PluginRespirator.java       
2006-08-12 18:13:01 UTC (rev 10047)
+++ trunk/freenet/src/freenet/pluginmanager/PluginRespirator.java       
2006-08-12 19:24:25 UTC (rev 10048)
@@ -10,7 +10,7 @@

        public PluginRespirator(Node node, PluginManager pm) {
                this.node = node;
-               this.hlsc = 
node.makeClient(RequestStarter.INTERACTIVE_PRIORITY_CLASS);
+               this.hlsc = 
node.clientCore.makeClient(RequestStarter.INTERACTIVE_PRIORITY_CLASS);
        }

        //public HighLevelSimpleClient getHLSimpleClient() throws 
PluginSecurityException {


Reply via email to