diff --git a/src/main/java/org/opennars/web/HTTPServeFiles.java b/src/main/java/org/opennars/web/httpnar/HTTPServeFiles.java
similarity index 99%
rename from src/main/java/org/opennars/web/HTTPServeFiles.java
rename to src/main/java/org/opennars/web/httpnar/HTTPServeFiles.java
index 6a3200c9faa6d68c5ac76265c39849265eb30951..8451a7be1801b100a3c14b6ed39b3caf8134e002 100644
--- a/src/main/java/org/opennars/web/HTTPServeFiles.java
+++ b/src/main/java/org/opennars/web/httpnar/HTTPServeFiles.java
@@ -12,7 +12,7 @@
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
-package org.opennars.web;
+package org.opennars.web.httpnar;
 
 import java.io.File;
 import java.io.FileInputStream;
diff --git a/src/main/java/org/opennars/web/HTTPServer.java b/src/main/java/org/opennars/web/httpnar/HTTPServer.java
similarity index 99%
rename from src/main/java/org/opennars/web/HTTPServer.java
rename to src/main/java/org/opennars/web/httpnar/HTTPServer.java
index 585cc5ee5f7b76bc289018c556dce2282af8c907..655edc979976c33cff773babcf2b21da5da94b97 100644
--- a/src/main/java/org/opennars/web/HTTPServer.java
+++ b/src/main/java/org/opennars/web/httpnar/HTTPServer.java
@@ -12,7 +12,7 @@
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
-package org.opennars.web;
+package org.opennars.web.httpnar;
 
 /*
  "Copyright (C) 2001,2005 by Jarno Elonen <elonen@iki.fi>\n"+
diff --git a/src/main/java/org/opennars/web/NARConnection.java b/src/main/java/org/opennars/web/httpnar/NARConnection.java
similarity index 87%
rename from src/main/java/org/opennars/web/NARConnection.java
rename to src/main/java/org/opennars/web/httpnar/NARConnection.java
index 605c582ca944ae272ae78f2bbe04aef47695b340..7ea69c022f22e834a3b885ad3420e03eb7b72d7d 100644
--- a/src/main/java/org/opennars/web/NARConnection.java
+++ b/src/main/java/org/opennars/web/httpnar/NARConnection.java
@@ -18,9 +18,10 @@
  * and open the template in the editor.
  */
 
-package org.opennars.web;
+package org.opennars.web.httpnar;
 
-import org.opennars.main.NAR;
+import org.opennars.interfaces.pub.Reasoner;
+import org.opennars.main.Nar;
 import org.opennars.io.events.TextOutputHandler;
 import org.opennars.io.events.TextOutputHandler.LineOutput;
 
@@ -29,17 +30,17 @@ import org.opennars.io.events.TextOutputHandler.LineOutput;
  * @author me
  */
 abstract public class NARConnection implements LineOutput {
-    public final NAR nar;
+    public final Reasoner nar;
     protected final TextOutputHandler writer;
     int cycleIntervalMS;
     //private final TextReaction extraParser;
         
     
-    public NARConnection(NAR nar, int cycleIntervalMS) {
+    public NARConnection(Reasoner nar, int cycleIntervalMS) {
         this.nar = nar;
         this.cycleIntervalMS = cycleIntervalMS;
              
-        this.writer = new TextOutputHandler(nar, this);
+        this.writer = new TextOutputHandler((Nar) nar, this);
     }
 
     public void read(final String message) {
diff --git a/src/main/java/org/opennars/web/NARServer.java b/src/main/java/org/opennars/web/httpnar/NARServer.java
similarity index 94%
rename from src/main/java/org/opennars/web/NARServer.java
rename to src/main/java/org/opennars/web/httpnar/NARServer.java
index db92394107727cfe35c0067574a1477fcae55d9b..fdf482f02b17b856b45e1d5ebfaa38e2550a798c 100644
--- a/src/main/java/org/opennars/web/NARServer.java
+++ b/src/main/java/org/opennars/web/httpnar/NARServer.java
@@ -12,19 +12,19 @@
  * You should have received a copy of the GNU General Public License
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
-package org.opennars.web;
+package org.opennars.web.httpnar;
 
 import java.io.File;
 import java.io.IOException;
 import java.net.InetSocketAddress;
-import java.net.UnknownHostException;
 import java.util.HashMap;
 import java.util.Map;
-import org.opennars.main.NAR;
 import org.java_websocket.WebSocket;
 import org.java_websocket.WebSocketImpl;
 import org.java_websocket.handshake.ClientHandshake;
 import org.java_websocket.server.WebSocketServer;
+import org.opennars.interfaces.pub.Reasoner;
+import org.opennars.main.Nar;
 
 public class NARServer  {
 
@@ -43,6 +43,8 @@ public class NARServer  {
         public void onStart() {
         }
 
+        public Reasoner nar;
+        
         @Override
         public void onOpen(final WebSocket conn, ClientHandshake handshake) {
             //this.sendToAll("new connection: " + handshake.getResourceDescriptor());
@@ -51,7 +53,10 @@ public class NARServer  {
 
             if (WEBSOCKET_DEBUG) System.out.println("Connect: " + conn.getRemoteSocketAddress().getAddress().getHostAddress());
 
-            final NARConnection n = new NARConnection(new NAR(), cycleIntervalMS) {
+            if(nar == null) {
+                nar = new Nar();
+            }
+            final NARConnection n = new NARConnection(nar, cycleIntervalMS) {
                 @Override public void println(String output) {
                     conn.send(output);
                 }
diff --git a/src/main/java/org/opennars/web/multinar/NarNode.java b/src/main/java/org/opennars/web/multinar/NarNode.java
new file mode 100644
index 0000000000000000000000000000000000000000..2bc3297ea0ac48489afcd0ef813fdd4228cbfeca
--- /dev/null
+++ b/src/main/java/org/opennars/web/multinar/NarNode.java
@@ -0,0 +1,216 @@
+/**
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+package org.opennars.web.multinar;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutput;
+import java.io.ObjectOutputStream;
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.net.InetAddress;
+import java.net.SocketException;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import org.opennars.entity.Task;
+import org.opennars.io.events.EventEmitter.EventObserver;
+import org.opennars.io.events.Events;
+import org.opennars.language.CompoundTerm;
+import org.opennars.language.Term;
+import org.opennars.main.Nar;
+
+public class NarNode extends Nar implements EventObserver  {
+    
+    /* An extra event for received tasks*/
+    public class EventReceivedTask {}
+    
+    /* The socket the Nar listens from */
+    private DatagramSocket receiveSocket;
+    
+    /***
+     * Create a Nar node that listens for received tasks from other NarNode instances
+     * 
+     * @param listenPort
+     * @throws SocketException
+     * @throws UnknownHostException 
+     */
+    public NarNode(int listenPort) throws SocketException, UnknownHostException {
+        super();
+        this.receiveSocket = new DatagramSocket(listenPort, InetAddress.getByName("127.0.0.1"));
+        this.event(this, true, Events.TaskAdd.class);
+        NarNode THIS = this;
+        new Thread() {
+            public void run() {
+                for(;;) {
+                    try {
+                        Task ret = THIS.receiveTask();
+                        if(ret != null) {
+                            THIS.memory.event.emit(EventReceivedTask.class, new Object[]{ret});
+                            THIS.addInput(ret);
+                        }
+                    } catch (IOException ex) {
+                        Logger.getLogger(NarNode.class.getName()).log(Level.SEVERE, null, ex);
+                    } catch (ClassNotFoundException ex) {
+                        Logger.getLogger(NarNode.class.getName()).log(Level.SEVERE, null, ex);
+                    }
+                }
+            }
+        }.start();
+    }
+
+    /**
+     * Input and derived tasks will be potentially sent
+     * 
+     * @param event
+     * @param args 
+     */
+    @Override
+    public void event(Class event, Object[] args) {
+        if(event == Events.TaskAdd.class) {
+            Task t = (Task) args[0];
+            try {
+                sendTask(t);
+            } catch (IOException ex) {
+                Logger.getLogger(NarNode.class.getName()).log(Level.SEVERE, null, ex);
+            }
+        }
+    }
+    
+    /**
+     * Send tasks that are above priority threshold and contain the optional mustContainTerm
+     * 
+     * @param t
+     * @throws IOException 
+     */
+    private void sendTask(Task t) throws IOException {
+        ByteArrayOutputStream bStream = new ByteArrayOutputStream();
+        ObjectOutput oo = new ObjectOutputStream(bStream); 
+        oo.writeObject(t);
+        oo.close();
+        byte[] serializedMessage = bStream.toByteArray();
+        for(TargetNar target : targets) {
+            if(t.getPriority() > target.threshold) {
+                Term term = t.getTerm();
+                boolean isCompound = (term instanceof CompoundTerm);
+                boolean searchTerm = target.mustContainTerm != null;
+                boolean atomicEqualsSearched =     searchTerm && !isCompound && target.mustContainTerm.equals(term);
+                boolean compoundContainsSearched = searchTerm &&  isCompound && ((CompoundTerm) term).containsTermRecursively(target.mustContainTerm);
+                if(!searchTerm || atomicEqualsSearched || compoundContainsSearched) {
+                    DatagramPacket packet = new DatagramPacket(serializedMessage, serializedMessage.length, target.targetAddress, target.targetPort);
+                    target.sendSocket.send(packet);
+                    System.out.println("task sent:" + t);
+                }
+            }
+        }
+    }
+
+    public class TargetNar {
+        
+        /**
+         * The target Nar node, specifying under which conditions the current Nar node redirects tasks to it.
+         * 
+         * @param targetIP
+         * @param targetPort
+         * @param threshold
+         * @param mustContainTerm
+         * @throws SocketException
+         * @throws UnknownHostException 
+         */
+        public TargetNar(final String targetIP, final int targetPort, final float threshold, Term mustContainTerm) throws SocketException, UnknownHostException {
+            this.targetAddress = InetAddress.getByName(targetIP);
+            this.sendSocket = new DatagramSocket();
+            this.threshold = threshold;
+            this.targetPort = targetPort;
+            this.mustContainTerm = mustContainTerm;
+        }
+        final float threshold;
+        final DatagramSocket sendSocket;
+        final int targetPort;
+        final InetAddress targetAddress;
+        final Term mustContainTerm;
+    }
+    
+    private List<TargetNar> targets = new ArrayList<>();
+    /**
+     * Add another target Nar node to redirect tasks to, and under which conditions.
+     * 
+     * @param targetIP The target Nar node IP
+     * @param targetPort The target Nar node port
+     * @param taskThreshold The threshold the priority of the task has to have to redirect
+     * @param mustContainTerm The optional term that needs to be contained recursively in the task term
+     * @throws SocketException
+     * @throws UnknownHostException 
+     */
+    public void addRedirectionTo(final String targetIP, final int targetPort, final float taskThreshold, Term mustContainTerm) throws SocketException, UnknownHostException {
+        targets.add(new TargetNar(targetIP, targetPort, taskThreshold, mustContainTerm));
+    }
+ 
+    /***
+     * NarNode's receiving a task
+     * 
+     * @return
+     * @throws IOException
+     * @throws ClassNotFoundException 
+     */
+    private Task receiveTask() throws IOException, ClassNotFoundException {
+        byte[] recBytes = new byte[100000];
+        DatagramPacket packet = new DatagramPacket(recBytes, recBytes.length);
+        receiveSocket.receive(packet);
+        ObjectInputStream iStream = new ObjectInputStream(new ByteArrayInputStream(recBytes));
+        Task T = (Task) iStream.readObject();
+        System.out.println("task received: " + T);
+        iStream.close();
+        return T;
+    }
+    
+    
+    /**
+     * An example
+     * 
+     * @param args
+     * @throws SocketException
+     * @throws UnknownHostException
+     * @throws IOException
+     * @throws InterruptedException 
+     */
+    public static void main(String[] args) throws SocketException, UnknownHostException, IOException, InterruptedException {
+        int nar1port = 64001;
+        int nar2port = 64002;
+        String localIP = "127.0.0.1";
+        NarNode nar1 = new NarNode(nar1port);
+        NarNode nar2 = new NarNode(nar2port);
+        nar1.addRedirectionTo(localIP, nar2port, 0.5f, null);
+        //nar2.connectTo(localIP, nar1port, 0.5f);
+        nar2.event(new EventObserver() {
+            @Override
+            public void event(Class event, Object[] args) {
+                if(event == EventReceivedTask.class) {
+                    Task task = (Task) args[0];
+                    System.out.println("received task event triggered for task: " + task);
+                    System.out.println("success");
+                }
+            }
+        }, true, EventReceivedTask.class);
+        nar1.addInput("<{task1} --> [great]>.");
+        Thread.sleep(5000);
+        System.exit(0);
+    }
+    
+}