diff --git a/pom.xml b/pom.xml
index 00fca205dbcad6104844ec94caf10a3ffe2dfc7b..8b3198dc055255f765a83559a0e7bb3de6c46fcf 100644
--- a/pom.xml
+++ b/pom.xml
@@ -111,7 +111,7 @@
                 <groupId>org.apache.maven.plugins</groupId>
                 <artifactId>maven-javadoc-plugin</artifactId>
                 <configuration>
-                    <additionalparam>-Xdoclint:none</additionalparam>
+                    <show>private</show>
                 </configuration>
             </plugin>
             <plugin>
diff --git a/src/main/java/org/opennars/web/httpnar/HTTPServeFiles.java b/src/main/java/org/opennars/web/httpnar/HTTPServeFiles.java
index 8451a7be1801b100a3c14b6ed39b3caf8134e002..f38b42852410b4f202c26072785eb766e5dbd245 100644
--- a/src/main/java/org/opennars/web/httpnar/HTTPServeFiles.java
+++ b/src/main/java/org/opennars/web/httpnar/HTTPServeFiles.java
@@ -22,7 +22,6 @@ import java.util.Properties;
 
 /**
  *
- * @author me
  */
 public class HTTPServeFiles extends HTTPServer {
 
@@ -45,6 +44,12 @@ public class HTTPServeFiles extends HTTPServer {
     /**
      * Serves file from homeDir and its' subdirectories (only). Uses only URI,
      * ignores all headers and HTTP parameters.
+     *
+     * @param uri unified resource identifier of the served file
+     * @param header
+     * @param homeDir
+     * @param allowDirectoryListing
+     * @return
      */
     public Response serveFile(String uri, Properties header, File homeDir,
             boolean allowDirectoryListing) {
diff --git a/src/main/java/org/opennars/web/httpnar/HTTPServer.java b/src/main/java/org/opennars/web/httpnar/HTTPServer.java
index 655edc979976c33cff773babcf2b21da5da94b97..4a01f2e4dbb8c12129db775ddc14efa4f813ed53 100644
--- a/src/main/java/org/opennars/web/httpnar/HTTPServer.java
+++ b/src/main/java/org/opennars/web/httpnar/HTTPServer.java
@@ -118,12 +118,12 @@ abstract public class HTTPServer {
      *
      * (By default, this delegates to serveFile() and allows directory listing.)
      *
-     * @parm uri Percent-decoded URI without parameters, for example
+     * @param uri Percent-decoded URI without parameters, for example
      * "/index.cgi"
-     * @parm method "GET", "POST" etc.
-     * @parm parms Parsed, percent decoded parameters from URI and, in case of
+     * @param method "GET", "POST" etc.
+     * @param parms Parsed, percent decoded parameters from URI and, in case of
      * POST, data.
-     * @parm header Header entries, percent decoded
+     * @param header Header entries, percent decoded
      * @return HTTP response, see class Response for details
      */
     abstract public Response serve(String uri, String method, Properties header, Properties parms);
@@ -151,14 +151,17 @@ abstract public class HTTPServer {
     public class Response {
 
         /**
-         * Default constructor: response = HTTP_OK, data = mime = 'null'
+         * constructor to set it to default values
          */
         public Response() {
             this.status = HTTP_OK;
         }
 
         /**
-         * Basic constructor.
+         *
+         * @param status
+         * @param mimeType Multipurpose Internet Mail Extensions type
+         * @param data
          */
         public Response(String status, String mimeType, InputStream data) {
             this.status = status;
@@ -168,6 +171,10 @@ abstract public class HTTPServer {
 
         /**
          * Convenience method that makes an InputStream out of given text.
+         *
+         * @param status
+         * @param mimeType Multipurpose Internet Mail Extensions type
+         * @param txt
          */
         public Response(String status, String mimeType, String txt) {
             this.status = status;
@@ -176,7 +183,10 @@ abstract public class HTTPServer {
         }
 
         /**
-         * Adds given line to the header.
+         * Adds given line to the header
+         *
+         * @param name name of the header
+         * @param value value of the header
          */
         public void addHeader(String name, String value) {
             header.put(name, value);
@@ -188,7 +198,7 @@ abstract public class HTTPServer {
         public String status;
 
         /**
-         * MIME type of content, e.g. "text/html"
+         * Multipurpose Internet Mail Extensions type of content, e.g. "text/html"
          */
         public String mimeType;
 
@@ -221,9 +231,10 @@ abstract public class HTTPServer {
     // Socket & server code
     // 
     /**
-     * Starts a HTTP server to given port.
-     * <p>
-     * Throws an IOException if the socket is already in use
+     * Starts a HTTP server
+     *
+     * @param port the port of the HTTP server
+     * @throws IOException if the socket is already in use
      */
     public HTTPServer(int port) throws IOException {
         myTcpPort = port;        
@@ -244,7 +255,7 @@ abstract public class HTTPServer {
         t.start();
     }
 
-    /**
+    /*
      * Starts as a standalone file server and waits for Enter.
      */
     /*public static void main(String[] args) {
@@ -392,8 +403,13 @@ abstract public class HTTPServer {
         }
 
         /**
-         * Decodes the percent encoding scheme. <br/> For example:
-         * "an+example%20string" -> "an example string"
+         * Decodes the percent encoding scheme.
+         *
+         * <br>
+         * For example: "an+example%20string" -&gt; "an example string"
+         *
+         * @param str string which has to be decoded
+         * @return decoded string
          */
         private String decodePercent(String str) throws InterruptedException {
             try {
@@ -422,27 +438,34 @@ abstract public class HTTPServer {
 
         /**
          * Decodes parameters in percent-encoded URI-format ( e.g.
-         * "name=Jack%20Daniels&pass=Single%20Malt" ) and adds them to given
+         * "name=Jack%20Daniels&amp;pass=Single%20Malt" ) and adds them to given
          * Properties.
+         *
+         * @param parameters
+         * @param properties
          */
-        private void decodeParms(String parms, Properties p) throws InterruptedException {
-            if (parms == null) {
+        private void decodeParms(String parameters, Properties properties) throws InterruptedException {
+            if (parameters == null) {
                 return;
             }
 
-            StringTokenizer st = new StringTokenizer(parms, "&");
+            StringTokenizer st = new StringTokenizer(parameters, "&");
             while (st.hasMoreTokens()) {
                 String e = st.nextToken();
                 int sep = e.indexOf('=');
                 if (sep >= 0) {
-                    p.put(decodePercent(e.substring(0, sep)).trim(), decodePercent(e.substring(sep + 1)));
+                    properties.put(decodePercent(e.substring(0, sep)).trim(), decodePercent(e.substring(sep + 1)));
                 }
             }
         }
 
         /**
-         * Returns an error message as a HTTP response and throws
-         * InterruptedException to stop furhter request processing.
+         * Returns an error message as a HTTP response
+         *
+         * @param status status to be sent
+         * @param msg error message to be sent
+         *
+         * @throws InterruptedException to stop further request processing.
          */
         private void sendError(String status, String msg) throws InterruptedException {
             sendResponse(status, MIME_PLAINTEXT, null, new ByteArrayInputStream(msg.getBytes()));
@@ -451,7 +474,12 @@ abstract public class HTTPServer {
 
 
         /**
-         * Sends given response to the socket.
+         * Sends given response
+         *
+         * @param status status code
+         * @param mime Multipurpose Internet Mail Extensions type
+         * @param header content of the HTTP header
+         * @param data payload
          */
         private void sendResponse(String status, String mime, Properties header, InputStream data) {
             try {
@@ -511,7 +539,12 @@ abstract public class HTTPServer {
     }
 
     /**
-     * URL-encodes everything between "/"-characters. Encodes spaces as '%20'
+     * Encodes the Unified resource identifier
+     *
+     * @param uri Unified resource identifier to be encoded
+     * @return encoded Unified resource identifier
+     */
+    /* URL-encodes everything between "/"-characters. Encodes spaces as '%20'
      * instead of '+'.
      */
     public static String encodeUri(String uri) throws UnsupportedEncodingException {
@@ -542,7 +575,7 @@ abstract public class HTTPServer {
 
 
     /**
-     * Hashtable mapping (String)FILENAME_EXTENSION -> (String)MIME_TYPE
+     * Hashtable mapping (String)FILENAME_EXTENSION -&gt; (String)MIME_TYPE
      */
     public static final Hashtable theMimeTypes = new Hashtable();
 
diff --git a/src/main/java/org/opennars/web/multinar/NarNode.java b/src/main/java/org/opennars/web/multinar/NarNode.java
index 8da563dab238f3dd9e11abdc07f09dcd2d7c344d..44d941fa317ab89695756752cdafab33897b7d5f 100644
--- a/src/main/java/org/opennars/web/multinar/NarNode.java
+++ b/src/main/java/org/opennars/web/multinar/NarNode.java
@@ -1,265 +1,266 @@
-/**
- * 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.lang.reflect.InvocationTargetException;
-import java.net.DatagramPacket;
-import java.net.DatagramSocket;
-import java.net.InetAddress;
-import java.net.SocketException;
-import java.net.UnknownHostException;
-import java.text.ParseException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-import javax.xml.parsers.ParserConfigurationException;
-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;
-import org.opennars.main.Shell;
-import org.xml.sax.SAXException;
-
-public class NarNode implements EventObserver  {
-    
-    /* An extra event for received tasks*/
-    public class EventReceivedTask {}
-    
-    /* The socket the Nar listens from */
-    private transient DatagramSocket receiveSocket;
-    
-    /* Listen port however is not transient and can be used to recover the deserialized instance */
-    private int listenPort;
-    
-    public Nar nar;
-    
-    /***
-     * 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, IOException, InstantiationException, 
-            InvocationTargetException, NoSuchMethodException, ParserConfigurationException, IllegalAccessException, SAXException, 
-            ClassNotFoundException, ParseException {
-        this(new Nar(),listenPort);
-    }
-    public NarNode(Nar nar, int listenPort) throws SocketException, UnknownHostException, IOException, InstantiationException, 
-            InvocationTargetException, NoSuchMethodException, ParserConfigurationException, IllegalAccessException, SAXException, 
-            ClassNotFoundException, ParseException {
-        super();
-        this.nar = nar;
-        this.listenPort = listenPort;
-        this.receiveSocket = new DatagramSocket(listenPort, InetAddress.getByName("127.0.0.1"));
-        nar.event(this, true, Events.TaskAdd.class);
-        NarNode THIS = this;
-        new Thread() {
-            public void run() {
-                for(;;) {
-                    try {
-                        Object ret = THIS.receiveObject();
-                        if(ret != null) {
-                            if(ret instanceof Task) {
-                                nar.memory.event.emit(EventReceivedTask.class, new Object[]{ret});
-                                nar.addInput((Task) ret, nar);
-                            } else
-                            if(ret instanceof String) { //emits IN.class anyway
-                                nar.addInput((String) 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 (Exception 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 {
-        String wat = t.toString();
-        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);
-                }
-            }
-        }
-    }
-    
-    /**
-     * Send Narsese that contains the optional mustContainTerm
-     * 
-     * @param t
-     * @throws IOException 
-     */
-    public static void sendNarsese(String input, TargetNar target) throws IOException {
-        ByteArrayOutputStream bStream = new ByteArrayOutputStream();
-        ObjectOutput oo = new ObjectOutputStream(bStream); 
-        oo.writeObject(input);
-        oo.close();
-        byte[] serializedMessage = bStream.toByteArray();
-        boolean searchTerm = target.mustContainTerm != null;
-        boolean containsFound = searchTerm && input.contains(target.mustContainTerm.toString());
-        if(!searchTerm || containsFound) {
-            DatagramPacket packet = new DatagramPacket(serializedMessage, serializedMessage.length, target.targetAddress, target.targetPort);
-            target.sendSocket.send(packet);
-            //System.out.println("narsese sent:" + input);
-        }
-    }
-    public static void sendNarsese(String input, final String targetIP, final int targetPort, final float taskThreshold, Term mustContainTerm) throws IOException {
-        sendNarsese(input, new TargetNar(targetIP, targetPort, taskThreshold, mustContainTerm, true));
-    }
-
-    public static 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, boolean sendInput) throws SocketException, UnknownHostException {
-            this.targetAddress = InetAddress.getByName(targetIP);
-            this.sendSocket = new DatagramSocket();
-            this.threshold = threshold;
-            this.targetPort = targetPort;
-            this.mustContainTerm = mustContainTerm;
-            this.sendInput = sendInput;
-        }
-        final float threshold;
-        final DatagramSocket sendSocket;
-        final int targetPort;
-        final InetAddress targetAddress;
-        final Term mustContainTerm;
-        final boolean sendInput;
-    }
-    
-    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, boolean sendInput) throws SocketException, UnknownHostException {
-        addRedirectionTo(new TargetNar(targetIP, targetPort, taskThreshold, mustContainTerm, sendInput));
-    }
-    public void addRedirectionTo(TargetNar target) throws SocketException, UnknownHostException {
-        targets.add(target);
-    }
- 
-    /***
-     * NarNode's receiving a task
-     * 
-     * @return
-     * @throws IOException
-     * @throws ClassNotFoundException 
-     */
-    private Object receiveObject() 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));
-        Object msg = iStream.readObject();
-        iStream.close();
-        return msg;
-    }
-    
-    
-    /**
-     * An example with one NarNode sending a task to another NarNode
-     * 
-     * @param args
-     * @throws SocketException
-     * @throws UnknownHostException
-     * @throws IOException
-     * @throws InterruptedException 
-     */
-    public static void main(String[] args) throws SocketException, UnknownHostException, IOException, 
-            InterruptedException, InstantiationException, InvocationTargetException, ParserConfigurationException, 
-            NoSuchMethodException, SAXException, ClassNotFoundException, IllegalAccessException, ParseException {
-        if((args.length-3) % 5 != 0) { //args length check, it has to be 3+5*k, with k in N0
-            System.out.println("expected arguments: file cycles listenPort targetIP1 targetPort1 prioThres1 mustContainTerm1 sendInput1 ... targetIPN targetPortN prioThresN mustContainTermN sendInputN");
-            System.exit(0);
-        }
-        int nar1port = Integer.parseInt(args[2]);
-        NarNode nar1 = new NarNode(new Nar(),nar1port);
-        List<TargetNar> redirections = new ArrayList<TargetNar>();
-        for(int i=3; i<args.length; i+=5) {
-            Term T = args[i+3].equals("null") ? null : new Term(args[i+3]);
-            redirections.add(new TargetNar(args[i], Integer.parseInt(args[i+1]), Float.parseFloat(args[i+2]), T, Boolean.parseBoolean(args[i+4])));
-        }
-        for(TargetNar target : redirections) {
-            nar1.addRedirectionTo(target);
-        }
-        new Shell(nar1.nar).run(new String[]{args[0], args[1]});
-    }
-}
+/**
+ * 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.lang.reflect.InvocationTargetException;
+import java.net.DatagramPacket;
+import java.net.DatagramSocket;
+import java.net.InetAddress;
+import java.net.SocketException;
+import java.net.UnknownHostException;
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import javax.xml.parsers.ParserConfigurationException;
+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;
+import org.opennars.main.Shell;
+import org.xml.sax.SAXException;
+
+public class NarNode implements EventObserver  {
+    
+    /* An extra event for received tasks*/
+    public class EventReceivedTask {}
+    
+    /* The socket the Nar listens from */
+    private transient DatagramSocket receiveSocket;
+    
+    /* Listen port however is not transient and can be used to recover the deserialized instance */
+    private int listenPort;
+    
+    public Nar nar;
+    
+    /***
+     * 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, IOException, InstantiationException, 
+            InvocationTargetException, NoSuchMethodException, ParserConfigurationException, IllegalAccessException, SAXException, 
+            ClassNotFoundException, ParseException {
+        this(new Nar(),listenPort);
+    }
+    public NarNode(Nar nar, int listenPort) throws SocketException, UnknownHostException, IOException, InstantiationException, 
+            InvocationTargetException, NoSuchMethodException, ParserConfigurationException, IllegalAccessException, SAXException, 
+            ClassNotFoundException, ParseException {
+        super();
+        this.nar = nar;
+        this.listenPort = listenPort;
+        this.receiveSocket = new DatagramSocket(listenPort, InetAddress.getByName("127.0.0.1"));
+        nar.event(this, true, Events.TaskAdd.class);
+        NarNode THIS = this;
+        new Thread() {
+            public void run() {
+                for(;;) {
+                    try {
+                        Object ret = THIS.receiveObject();
+                        if(ret != null) {
+                            if(ret instanceof Task) {
+                                nar.memory.event.emit(EventReceivedTask.class, new Object[]{ret});
+                                nar.addInput((Task) ret, nar);
+                            } else
+                            if(ret instanceof String) { //emits IN.class anyway
+                                nar.addInput((String) 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 (Exception 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 {
+        String wat = t.toString();
+        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);
+                }
+            }
+        }
+    }
+    
+    /**
+     * Send Narsese that contains the optional mustContainTerm
+     *
+     * @param input
+     * @param target
+     * @throws IOException 
+     */
+    public static void sendNarsese(String input, TargetNar target) throws IOException {
+        ByteArrayOutputStream bStream = new ByteArrayOutputStream();
+        ObjectOutput oo = new ObjectOutputStream(bStream); 
+        oo.writeObject(input);
+        oo.close();
+        byte[] serializedMessage = bStream.toByteArray();
+        boolean searchTerm = target.mustContainTerm != null;
+        boolean containsFound = searchTerm && input.contains(target.mustContainTerm.toString());
+        if(!searchTerm || containsFound) {
+            DatagramPacket packet = new DatagramPacket(serializedMessage, serializedMessage.length, target.targetAddress, target.targetPort);
+            target.sendSocket.send(packet);
+            //System.out.println("narsese sent:" + input);
+        }
+    }
+    public static void sendNarsese(String input, final String targetIP, final int targetPort, final float taskThreshold, Term mustContainTerm) throws IOException {
+        sendNarsese(input, new TargetNar(targetIP, targetPort, taskThreshold, mustContainTerm, true));
+    }
+
+    public static 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, boolean sendInput) throws SocketException, UnknownHostException {
+            this.targetAddress = InetAddress.getByName(targetIP);
+            this.sendSocket = new DatagramSocket();
+            this.threshold = threshold;
+            this.targetPort = targetPort;
+            this.mustContainTerm = mustContainTerm;
+            this.sendInput = sendInput;
+        }
+        final float threshold;
+        final DatagramSocket sendSocket;
+        final int targetPort;
+        final InetAddress targetAddress;
+        final Term mustContainTerm;
+        final boolean sendInput;
+    }
+    
+    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, boolean sendInput) throws SocketException, UnknownHostException {
+        addRedirectionTo(new TargetNar(targetIP, targetPort, taskThreshold, mustContainTerm, sendInput));
+    }
+    public void addRedirectionTo(TargetNar target) throws SocketException, UnknownHostException {
+        targets.add(target);
+    }
+ 
+    /***
+     * NarNode's receiving a task
+     * 
+     * @return
+     * @throws IOException
+     * @throws ClassNotFoundException 
+     */
+    private Object receiveObject() 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));
+        Object msg = iStream.readObject();
+        iStream.close();
+        return msg;
+    }
+    
+    
+    /**
+     * An example with one NarNode sending a task to another NarNode
+     * 
+     * @param args
+     * @throws SocketException
+     * @throws UnknownHostException
+     * @throws IOException
+     * @throws InterruptedException 
+     */
+    public static void main(String[] args) throws SocketException, UnknownHostException, IOException, 
+            InterruptedException, InstantiationException, InvocationTargetException, ParserConfigurationException, 
+            NoSuchMethodException, SAXException, ClassNotFoundException, IllegalAccessException, ParseException {
+        if((args.length-3) % 5 != 0) { //args length check, it has to be 3+5*k, with k in N0
+            System.out.println("expected arguments: file cycles listenPort targetIP1 targetPort1 prioThres1 mustContainTerm1 sendInput1 ... targetIPN targetPortN prioThresN mustContainTermN sendInputN");
+            System.exit(0);
+        }
+        int nar1port = Integer.parseInt(args[2]);
+        NarNode nar1 = new NarNode(new Nar(),nar1port);
+        List<TargetNar> redirections = new ArrayList<TargetNar>();
+        for(int i=3; i<args.length; i+=5) {
+            Term T = args[i+3].equals("null") ? null : new Term(args[i+3]);
+            redirections.add(new TargetNar(args[i], Integer.parseInt(args[i+1]), Float.parseFloat(args[i+2]), T, Boolean.parseBoolean(args[i+4])));
+        }
+        for(TargetNar target : redirections) {
+            nar1.addRedirectionTo(target);
+        }
+        new Shell(nar1.nar).run(new String[]{args[0], args[1]});
+    }
+}
diff --git a/src/test/java/NarNodeTest.java b/src/test/java/NarNodeTest.java
index 6ac02006ff660cdd14a7d54b422e9e17d68a5cde..2570c867ef899adb5669ab0bdb1a2fec339eacb3 100644
--- a/src/test/java/NarNodeTest.java
+++ b/src/test/java/NarNodeTest.java
@@ -1,67 +1,67 @@
-/**
- * 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/>.
- */
-import java.io.IOException;
-import java.lang.reflect.InvocationTargetException;
-import java.net.SocketException;
-import java.net.UnknownHostException;
-import java.text.ParseException;
-import javax.xml.parsers.ParserConfigurationException;
-import org.junit.Test;
-import org.opennars.entity.Task;
-import org.opennars.io.events.EventEmitter;
-import org.opennars.io.events.OutputHandler.IN;
-import org.opennars.web.multinar.NarNode;
-import org.opennars.web.multinar.NarNode.TargetNar;
-import org.xml.sax.SAXException;
-
-
-public class NarNodeTest {
-    static Integer a = 0;
-    @Test
-    public void testNarToNar() throws UnknownHostException, IOException, SocketException, InstantiationException, InvocationTargetException, 
-            NoSuchMethodException, ParserConfigurationException, IllegalAccessException, SAXException, ClassNotFoundException, ParseException, InterruptedException {
-        int nar1port = 64001;
-        int nar2port = 64002;
-        String localIP = "127.0.0.1";
-        NarNode nar1 = new NarNode(nar1port);
-        NarNode nar2 = new NarNode(nar2port);
-        TargetNar nar2_connection = new TargetNar(localIP, nar2port, 0.5f, null, true);
-        nar1.addRedirectionTo(nar2_connection);
-        nar2.nar.event(new EventEmitter.EventObserver() {
-            @Override
-            public void event(Class event, Object[] args) {
-                if(event == NarNode.EventReceivedTask.class || event == IN.class) {
-                    Task task = (Task) args[0];
-                    System.out.println("received task event triggered in nar2: " + task);
-                    synchronized(a) {
-                        a++;
-                    }
-                }
-            }
-        }, true, NarNode.EventReceivedTask.class, IN.class);
-        System.out.println("High priority task occurred in nar1");
-        NarNode.sendNarsese("<{task1} --> [great]>.", nar2_connection);
-        nar1.nar.addInput("<{task1} --> [great]>.");
-        while(true) {
-            synchronized(a) {
-                if(a == 2) {
-                    System.out.println("success");
-                    break;
-                }
-            }
-        }
-        assert(true);
-    }
-}
+/**
+ * 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/>.
+ */
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.net.SocketException;
+import java.net.UnknownHostException;
+import java.text.ParseException;
+import javax.xml.parsers.ParserConfigurationException;
+import org.junit.Test;
+import org.opennars.entity.Task;
+import org.opennars.io.events.EventEmitter;
+import org.opennars.io.events.OutputHandler.IN;
+import org.opennars.web.multinar.NarNode;
+import org.opennars.web.multinar.NarNode.TargetNar;
+import org.xml.sax.SAXException;
+
+
+public class NarNodeTest {
+    static Integer a = 0;
+    @Test
+    public void testNarToNar() throws UnknownHostException, IOException, SocketException, InstantiationException, InvocationTargetException, 
+            NoSuchMethodException, ParserConfigurationException, IllegalAccessException, SAXException, ClassNotFoundException, ParseException, InterruptedException {
+        int nar1port = 64001;
+        int nar2port = 64002;
+        String localIP = "127.0.0.1";
+        NarNode nar1 = new NarNode(nar1port);
+        NarNode nar2 = new NarNode(nar2port);
+        TargetNar nar2_connection = new TargetNar(localIP, nar2port, 0.5f, null, true);
+        nar1.addRedirectionTo(nar2_connection);
+        nar2.nar.event(new EventEmitter.EventObserver() {
+            @Override
+            public void event(Class event, Object[] args) {
+                if(event == NarNode.EventReceivedTask.class || event == IN.class) {
+                    Task task = (Task) args[0];
+                    System.out.println("received task event triggered in nar2: " + task);
+                    synchronized(a) {
+                        a++;
+                    }
+                }
+            }
+        }, true, NarNode.EventReceivedTask.class, IN.class);
+        System.out.println("High priority task occurred in nar1");
+        NarNode.sendNarsese("<{task1} --> [great]>.", nar2_connection);
+        nar1.nar.addInput("<{task1} --> [great]>.");
+        while(true) {
+            synchronized(a) {
+                if(a == 2) {
+                    System.out.println("success");
+                    break;
+                }
+            }
+        }
+        assert(true);
+    }
+}