Index: java/main/src/main/java/com/framsticks/communication/ClientConnection.java
===================================================================
--- java/main/src/main/java/com/framsticks/communication/ClientConnection.java	(revision 84)
+++ java/main/src/main/java/com/framsticks/communication/ClientConnection.java	(revision 85)
@@ -21,4 +21,5 @@
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
+import com.framsticks.util.dispatching.RunAt;
 
 /**
@@ -29,5 +30,5 @@
 	private final static Logger log = Logger.getLogger(ClientConnection.class);
 
-	protected final Map<String, Subscription> subscriptions = new HashMap<String, Subscription>();
+	protected final Map<String, Subscription<?>> subscriptions = new HashMap<>();
 
 	public String getAddress() {
@@ -93,7 +94,7 @@
 
 	private static class EventFire extends InboundMessage {
-		public final Subscription subscription;
-
-		private EventFire(Subscription subscription) {
+		public final Subscription<?> subscription;
+
+		private EventFire(Subscription<?> subscription) {
 			this.subscription = subscription;
 		}
@@ -107,17 +108,13 @@
 		public void eof() {
 			finishCurrentFile();
-			Dispatching.invokeLaterOrNow(subscription.getDispatcher(), new Runnable() {
-				@Override
-				public void run() {
-					subscription.getEventCallback().call(getFiles());
-				}
-			});
-		}
-	}
-
-	private static class SentQuery extends InboundMessage {
+
+			subscription.dispatchCall(getFiles());
+		}
+	}
+
+	private static class SentQuery<C> extends InboundMessage {
 		Request request;
-		ResponseCallback callback;
-		Dispatcher dispatcher;
+		ResponseCallback<? extends C> callback;
+		Dispatcher<C> dispatcher;
 
 		public void startFile(String path) {
@@ -139,6 +136,15 @@
 			return request.toString();
 		}
-	}
-	private Map<Integer, SentQuery> queryMap = new HashMap<Integer, SentQuery>();
+
+		public void dispatchResponseProcess(final Response response) {
+			Dispatching.invokeLaterOrNow(dispatcher, new RunAt<C>() {
+				@Override
+				public void run() {
+					callback.process(response);
+				}
+			});
+		}
+	}
+	private Map<Integer, SentQuery<?>> queryMap = new HashMap<>();
 
 
@@ -163,11 +169,13 @@
 	}
 
-	private SentQuery currentlySentQuery;
-
-	public void send(Request request, ResponseCallback callback) {
-		send(request, AtOnceDispatcher.instance, callback);
-	}
-
-	public void send(Request request, Dispatcher dispatcher, ResponseCallback callback) {
+	private SentQuery<?> currentlySentQuery;
+
+
+	public <C extends Connection> void send(Request request, ResponseCallback<C> callback) {
+		//TODO RunAt
+		send(request, AtOnceDispatcher.getInstance(), callback);
+	}
+
+	public <C> void send(Request request, Dispatcher<C> dispatcher, ResponseCallback<? extends C> callback) {
 
 		if (!isConnected()) {
@@ -175,12 +183,13 @@
 			return;
 		}
-		final SentQuery sentQuery = new SentQuery();
+		final SentQuery<C> sentQuery = new SentQuery<C>();
 		sentQuery.request = request;
 		sentQuery.callback = callback;
 		sentQuery.dispatcher = dispatcher;
 
-		senderThread.invokeLater(new Runnable(){
+		senderThread.invokeLater(new RunAt<Connection>(){
 			@Override
 			public void run() {
+				Integer id;
 				synchronized (ClientConnection.this) {
 
@@ -192,6 +201,12 @@
 						}
 					}
-				}
-				Integer id = stashQuery(sentQuery);
+					if (requestIdEnabled) {
+						queryMap.put(nextQueryId, sentQuery);
+						id = nextQueryId++;
+					} else {
+						currentlySentQuery = sentQuery;
+						id = null;
+					}
+				}
 				String command = sentQuery.request.getCommand();
 				StringBuilder message = new StringBuilder();
@@ -223,6 +238,6 @@
 	}
 
-	public void subscribe(final String path, final SubscriptionCallback callback) {
-		send(new RegistrationRequest().setPath(path), new ResponseCallback() {
+	public <C> void subscribe(final String path, final Dispatcher<C> dispatcher, final SubscriptionCallback<? extends C> callback) {
+		send(new RegistrationRequest().path(path), new ResponseCallback<Connection>() {
 			@Override
 			public void process(Response response) {
@@ -233,5 +248,5 @@
 				}
 				assert response.getFiles().isEmpty();
-				Subscription subscription = new Subscription(ClientConnection.this, path, response.getComment());
+				Subscription<C> subscription = new Subscription<C>(ClientConnection.this, path, response.getComment(), dispatcher);
 				log.debug("registered on event: " + subscription);
 				synchronized (subscriptions) {
@@ -241,5 +256,5 @@
 				if (subscription.getEventCallback() == null) {
 					log.info("subscription for " + path + " aborted");
-					subscription.unsubscribe(new LoggingStateCallback(log, "abort subscription"));
+					subscription.unsubscribe(new LoggingStateCallback<C>(log, "abort subscription"));
 				}
 			}
@@ -253,5 +268,5 @@
 
 	public void sendQueryVersion(final int version, final StateFunctor stateFunctor) {
-		send(new VersionRequest().version(version), new StateCallback() {
+		send(new VersionRequest().version(version), new StateCallback<Connection>() {
 			@Override
 			public void call(Exception e) {
@@ -266,5 +281,5 @@
 					return;
 				}
-				send(new UseRequest().feature("request_id"), new StateCallback() {
+				send(new UseRequest().feature("request_id"), new StateCallback<Connection>() {
 					@Override
 					public void call(Exception e) {
@@ -289,10 +304,10 @@
 
 
-	private synchronized SentQuery fetchQuery(Integer id, boolean remove) {
+	private synchronized SentQuery<?> fetchQuery(Integer id, boolean remove) {
 		if (id == null) {
 			if (requestIdEnabled) {
 				return null;
 			}
-			SentQuery result = currentlySentQuery;
+			SentQuery<?> result = currentlySentQuery;
 			if (remove) {
 				currentlySentQuery = null;
@@ -302,5 +317,5 @@
 		}
 		if (queryMap.containsKey(id)) {
-			SentQuery result = queryMap.get(id);
+			SentQuery<?> result = queryMap.get(id);
 			if (remove) {
 				queryMap.remove(id);
@@ -312,13 +327,4 @@
 
 	private int nextQueryId = 0;
-
-	private Integer stashQuery(SentQuery sentQuery) {
-		if (!requestIdEnabled) {
-			currentlySentQuery = sentQuery;
-			return null;
-		}
-		queryMap.put(nextQueryId, sentQuery);
-		return nextQueryId++;
-	}
 
 	protected void processMessage(InboundMessage inboundMessage) throws Exception {
@@ -342,5 +348,5 @@
 			return;
 		}
-		Subscription subscription = subscriptions.get(matcher.group(1));
+		Subscription<?> subscription = subscriptions.get(matcher.group(1));
 		if (subscription == null) {
 			log.error("non subscribed event: " + matcher.group(1));
@@ -362,5 +368,5 @@
 
 		if (command.first.equals("file")) {
-			SentQuery sentQuery = fetchQuery(rest.first, false);
+			SentQuery<?> sentQuery = fetchQuery(rest.first, false);
 			sentQuery.startFile(rest.second);
 			processMessage(sentQuery);
@@ -368,5 +374,5 @@
 		}
 
-		SentQuery sentQuery = fetchQuery(rest.first, true);
+		SentQuery<?> sentQuery = fetchQuery(rest.first, true);
 		if (sentQuery == null) {
 			return;
@@ -374,13 +380,5 @@
 		log.debug("parsing response for request " + sentQuery);
 
-		final Response response = new Response(command.first.equals("ok"), rest.second, sentQuery.getFiles());
-		final ResponseCallback callback = sentQuery.callback;
-
-		Dispatching.invokeLaterOrNow(sentQuery.dispatcher, new Runnable() {
-			@Override
-			public void run() {
-				callback.process(response);
-			}
-		});
+		sentQuery.dispatchResponseProcess(new Response(command.first.equals("ok"), rest.second, sentQuery.getFiles()));
 	}
 
Index: java/main/src/main/java/com/framsticks/communication/Connection.java
===================================================================
--- java/main/src/main/java/com/framsticks/communication/Connection.java	(revision 84)
+++ java/main/src/main/java/com/framsticks/communication/Connection.java	(revision 85)
@@ -1,4 +1,5 @@
 package com.framsticks.communication;
 
+import com.framsticks.util.io.Encoding;
 import com.framsticks.util.lang.Pair;
 import org.apache.log4j.Logger;
@@ -6,10 +7,13 @@
 import java.io.IOException;
 import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
 import java.io.PrintWriter;
-import java.lang.Thread;
 import java.net.Socket;
 import java.net.SocketTimeoutException;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
+
+import com.framsticks.util.dispatching.RunAt;
+import com.framsticks.util.dispatching.Thread;
 
 public abstract class Connection {
@@ -28,6 +32,6 @@
 	protected int protocolVersion = -1;
 
-	protected final com.framsticks.util.dispatching.Thread senderThread = new com.framsticks.util.dispatching.Thread();
-	protected Thread receiverThread;
+	protected final Thread<Connection> senderThread = new Thread<>();
+	protected final Thread<Connection> receiverThread = new Thread<>();
 
 	public boolean isConnected() {
@@ -42,9 +46,7 @@
 			senderThread.interrupt();
 			senderThread.join();
-			if (receiverThread != null) {
-				receiverThread.interrupt();
-				receiverThread.join();
-				receiverThread = null;
-			}
+
+			receiverThread.interrupt();
+			receiverThread.join();
 
 			if (output != null) {
@@ -72,7 +74,7 @@
 
 	protected static final String ARGUMENT_PATTERN_FRAGMENT = "((?:\\S+)|(?:\"[^\"]*\"))";
-	protected static Pattern requestIdEnabledPattern = Pattern.compile("^\\s*([0-9]+)(?:\\s+" + ARGUMENT_PATTERN_FRAGMENT + ")?\\n$");
-	protected static Pattern requestIDisabledPattern = Pattern.compile("^\\s*" + ARGUMENT_PATTERN_FRAGMENT + "?\\n$");
-	protected static Pattern eventPattern = Pattern.compile("^\\s*(\\S+)\\s*(\\S+)\\n");
+	protected static final Pattern requestIdEnabledPattern = Pattern.compile("^\\s*([0-9]+)(?:\\s+" + ARGUMENT_PATTERN_FRAGMENT + ")?\\n$");
+	protected static final Pattern requestIDisabledPattern = Pattern.compile("^\\s*" + ARGUMENT_PATTERN_FRAGMENT + "?\\n$");
+	protected static final Pattern eventPattern = Pattern.compile("^\\s*(\\S+)\\s*(\\S+)\\n");
 
 
@@ -126,6 +128,6 @@
 	protected void runThreads() {
 		try {
-			output = new PrintWriter(socket.getOutputStream(), true);
-			input = new BufferedReader(new InputStreamReader(socket.getInputStream()));
+			output = new PrintWriter(new OutputStreamWriter(socket.getOutputStream(), Encoding.getFramsticksCharset()), true);
+			input = new BufferedReader(new InputStreamReader(socket.getInputStream(), Encoding.getFramsticksCharset()));
 		} catch (IOException e) {
 			log.error("buffer creation failure");
@@ -135,5 +137,10 @@
 
 		senderThread.setName(this + "-sender");
-		receiverThread = new Thread(new Runnable() {
+		receiverThread.setName(this + "-receiver");
+
+		senderThread.start();
+		receiverThread.start();
+
+		receiverThread.invokeLater(new RunAt<Connection>() {
 			@Override
 			public void run() {
@@ -148,8 +155,5 @@
 			}
 		});
-		receiverThread.setName(this + "-receiver");
 
-		senderThread.start();
-		receiverThread.start();
 	}
 
Index: java/main/src/main/java/com/framsticks/communication/RequestHandler.java
===================================================================
--- java/main/src/main/java/com/framsticks/communication/RequestHandler.java	(revision 84)
+++ java/main/src/main/java/com/framsticks/communication/RequestHandler.java	(revision 85)
@@ -7,4 +7,4 @@
  */
 public interface RequestHandler {
-    public void handle(ApplicationRequest request, ResponseCallback responseCallback);
+	public void handle(ApplicationRequest request, ResponseCallback<?> responseCallback);
 }
Index: java/main/src/main/java/com/framsticks/communication/ResponseCallback.java
===================================================================
--- java/main/src/main/java/com/framsticks/communication/ResponseCallback.java	(revision 84)
+++ java/main/src/main/java/com/framsticks/communication/ResponseCallback.java	(revision 85)
@@ -4,5 +4,5 @@
  * @author Piotr Sniegowski
  */
-public interface ResponseCallback {
+public interface ResponseCallback<C> {
 	public void process(Response response);
 }
Index: java/main/src/main/java/com/framsticks/communication/ServerConnection.java
===================================================================
--- java/main/src/main/java/com/framsticks/communication/ServerConnection.java	(revision 84)
+++ java/main/src/main/java/com/framsticks/communication/ServerConnection.java	(revision 85)
@@ -8,4 +8,5 @@
 
 import java.net.Socket;
+import com.framsticks.util.dispatching.RunAt;
 
 /**
@@ -26,6 +27,4 @@
 
 	public void start() {
-
-
 		runThreads();
 	}
@@ -43,7 +42,7 @@
 	}
 
-	protected void handleRequest(Request request, ResponseCallback responseCallback) {
+	protected void handleRequest(Request request, ResponseCallback<?> responseCallback) {
 		if (request instanceof ApplicationRequest) {
-			requestHandler.handle((ApplicationRequest)request, responseCallback);
+			requestHandler.handle((ApplicationRequest) request, responseCallback);
 			return;
 		}
@@ -70,5 +69,5 @@
 
 	protected final void respond(final Response response, final Integer id) {
-		senderThread.invokeLater(new Runnable() {
+		senderThread.invokeLater(new RunAt<Connection>() {
 			@Override
 			public void run() {
@@ -118,5 +117,5 @@
 		}
 
-		handleRequest(request, new ResponseCallback() {
+		handleRequest(request, new ResponseCallback<ServerConnection>() {
 			@Override
 			public void process(Response response) {
Index: java/main/src/main/java/com/framsticks/communication/StateCallback.java
===================================================================
--- java/main/src/main/java/com/framsticks/communication/StateCallback.java	(revision 84)
+++ java/main/src/main/java/com/framsticks/communication/StateCallback.java	(revision 85)
@@ -6,5 +6,5 @@
  * @author Piotr Sniegowski
  */
-public abstract class StateCallback implements ResponseCallback, StateFunctor {
+public abstract class StateCallback<C> implements ResponseCallback<C>, StateFunctor {
 	@Override
 	public void process(Response response) {
Index: java/main/src/main/java/com/framsticks/communication/Subscription.java
===================================================================
--- java/main/src/main/java/com/framsticks/communication/Subscription.java	(revision 84)
+++ java/main/src/main/java/com/framsticks/communication/Subscription.java	(revision 85)
@@ -1,7 +1,10 @@
 package com.framsticks.communication;
 
+import java.util.List;
+
 import com.framsticks.communication.queries.RegistrationRequest;
-import com.framsticks.util.dispatching.AtOnceDispatcher;
 import com.framsticks.util.dispatching.Dispatcher;
+import com.framsticks.util.dispatching.Dispatching;
+import com.framsticks.util.dispatching.RunAt;
 import com.framsticks.util.StateFunctor;
 import org.apache.log4j.Logger;
@@ -11,19 +14,20 @@
  * @author Piotr Sniegowski
  */
-public class Subscription {
+public class Subscription<C> {
 
-    private final static Logger log = Logger.getLogger(Subscription.class);
+	private final static Logger log = Logger.getLogger(Subscription.class);
 
-    private final ClientConnection connection;
-    private final String path;
+	private final ClientConnection connection;
+	private final String path;
 	private final String registeredPath;
-    private Dispatcher dispatcher = AtOnceDispatcher.instance;
+	private final Dispatcher<C> dispatcher;
 
 	private EventCallback eventCallback;
 
-	public Subscription(ClientConnection connection, String path, String registeredPath) {
+	public Subscription(ClientConnection connection, String path, String registeredPath, Dispatcher<C> dispatcher) {
 		this.connection = connection;
-        this.path = path;
+		this.path = path;
 		this.registeredPath = registeredPath;
+		this.dispatcher = dispatcher;
 	}
 
@@ -41,35 +45,40 @@
 	}
 
-    public void setDispatcher(Dispatcher dispatcher) {
-        this.dispatcher = dispatcher;
-    }
+	public void unsubscribe(final StateFunctor stateFunctor) {
+		//@todo remove that /cli/ prefix, when registeredPath will be a fully qualified path
+		connection.send(new RegistrationRequest().register(false).path(registeredPath), new ResponseCallback<Connection>() {
+			@Override
+			public void process(Response response) {
+				if (!response.getOk()) {
+					log.error("failed to unsunscribe " + this + ": " + response.getComment());
+					stateFunctor.call(new Exception(response.getComment()));
+					return;
+				}
+				assert response.hasFiles();
+				log.debug("unsunscribed " + this);
+				stateFunctor.call(null);
+			}
+		});
+	}
 
-    public void unsubscribe(final StateFunctor stateFunctor) {
-        //@todo remove that /cli/ prefix, when registeredPath will be a fully qualified path
-        connection.send(new RegistrationRequest().register(false).setPath(registeredPath), new ResponseCallback() {
-            @Override
-            public void process(Response response) {
-                if (!response.getOk()) {
-                    log.error("failed to unsunscribe " + this + ": " + response.getComment());
-                    stateFunctor.call(new Exception(response.getComment()));
-                    return;
-                }
-                assert response.hasFiles();
-                log.debug("unsunscribed " + this);
-                stateFunctor.call(null);
-            }
-        });
-    }
+	public EventCallback getEventCallback() {
+		return eventCallback;
+	}
 
-    public EventCallback getEventCallback() {
-        return eventCallback;
-    }
+	public Dispatcher<C> getDispatcher() {
+		return dispatcher;
+	}
 
-    public Dispatcher getDispatcher() {
-        return dispatcher;
-    }
+	public void setEventCallback(EventCallback eventCallback) {
+		this.eventCallback = eventCallback;
+	}
 
-    public void setEventCallback(EventCallback eventCallback) {
-        this.eventCallback = eventCallback;
-    }
+	public void dispatchCall(final List<File> files) {
+		Dispatching.invokeLaterOrNow(dispatcher, new RunAt<C>() {
+			@Override
+			public void run() {
+				eventCallback.call(files);
+			}
+		});
+	}
 }
Index: java/main/src/main/java/com/framsticks/communication/SubscriptionCallback.java
===================================================================
--- java/main/src/main/java/com/framsticks/communication/SubscriptionCallback.java	(revision 84)
+++ java/main/src/main/java/com/framsticks/communication/SubscriptionCallback.java	(revision 85)
@@ -4,5 +4,5 @@
  * @author Piotr Sniegowski
  */
-public interface SubscriptionCallback {
-	EventCallback subscribed(Subscription subscription);
+public interface SubscriptionCallback<C> {
+	EventCallback subscribed(Subscription<? super C> subscription);
 }
Index: java/main/src/main/java/com/framsticks/communication/queries/ApplicationRequest.java
===================================================================
--- java/main/src/main/java/com/framsticks/communication/queries/ApplicationRequest.java	(revision 84)
+++ java/main/src/main/java/com/framsticks/communication/queries/ApplicationRequest.java	(revision 85)
@@ -14,5 +14,5 @@
 	protected String fields;
 
-	public ApplicationRequest setPath(String path) {
+	public ApplicationRequest path(String path) {
 		assert path != null;
 		this.path = path;
@@ -20,15 +20,15 @@
 	}
 
-	public ApplicationRequest setField(String field) {
+	public ApplicationRequest field(String field) {
 		this.fields = field;
 		return this;
 	}
 
-	public ApplicationRequest setFields(Collection<String> fields) {
+	public ApplicationRequest fields(Collection<String> fields) {
 		Delimeted d = new Delimeted(",", "");
 		for (String f : fields) {
 			d.append(f);
 		}
-		return setField(d.build());
+		return field(d.build());
 	}
 
Index: java/main/src/main/java/com/framsticks/communication/util/LoggingStateCallback.java
===================================================================
--- java/main/src/main/java/com/framsticks/communication/util/LoggingStateCallback.java	(revision 84)
+++ java/main/src/main/java/com/framsticks/communication/util/LoggingStateCallback.java	(revision 85)
@@ -7,5 +7,5 @@
  * @author Piotr Sniegowski
  */
-public class LoggingStateCallback extends StateCallback {
+public class LoggingStateCallback<C> extends StateCallback<C> {
 
 	protected final Logger logger;
@@ -23,5 +23,5 @@
 			return;
 		}
-        logger.debug(message);
+		logger.debug(message);
 	}
 }
Index: java/main/src/main/java/com/framsticks/communication/util/LoggingSubscriptionCallback.java
===================================================================
--- java/main/src/main/java/com/framsticks/communication/util/LoggingSubscriptionCallback.java	(revision 84)
+++ java/main/src/main/java/com/framsticks/communication/util/LoggingSubscriptionCallback.java	(revision 85)
@@ -9,24 +9,24 @@
  * @author Piotr Sniegowski
  */
-public class LoggingSubscriptionCallback implements SubscriptionCallback {
+public class LoggingSubscriptionCallback<C> implements SubscriptionCallback<C> {
 
-    protected final Logger logger;
-    protected final String message;
-    private final EventCallback eventCallback;
+	protected final Logger logger;
+	protected final String message;
+	private final EventCallback eventCallback;
 
-    public LoggingSubscriptionCallback(Logger logger, String message, EventCallback eventCallback) {
-        this.logger = logger;
-        this.message = message;
-        this.eventCallback = eventCallback;
-    }
+	public LoggingSubscriptionCallback(Logger logger, String message, EventCallback eventCallback) {
+		this.logger = logger;
+		this.message = message;
+		this.eventCallback = eventCallback;
+	}
 
-    @Override
-    public EventCallback subscribed(Subscription subscription) {
-        if (subscription == null) {
-            logger.error("failed to subscribe for " + message);
-            return null;
-        }
-        logger.info("successfuly subscribed for " + message);
-        return eventCallback;
-    }
+	@Override
+	public EventCallback subscribed(Subscription<? super C> subscription) {
+		if (subscription == null) {
+			logger.error("failed to subscribe for " + message);
+			return null;
+		}
+		logger.info("successfuly subscribed for " + message);
+		return eventCallback;
+	}
 }
Index: java/main/src/main/java/com/framsticks/core/Entity.java
===================================================================
--- java/main/src/main/java/com/framsticks/core/Entity.java	(revision 84)
+++ java/main/src/main/java/com/framsticks/core/Entity.java	(revision 85)
@@ -1,3 +1,5 @@
 package com.framsticks.core;
+
+import javax.annotation.OverridingMethodsMustInvokeSuper;
 
 import com.framsticks.params.FramsClass;
@@ -7,9 +9,10 @@
 import org.apache.commons.configuration.Configuration;
 import org.apache.log4j.Logger;
+import com.framsticks.util.dispatching.RunAt;
 
 /**
  * @author Piotr Sniegowski
  */
-public abstract class Entity implements Dispatcher {
+public abstract class Entity implements Dispatcher<Entity> {
 
 	private final static Logger log = Logger.getLogger(Entity.class.getName());
@@ -17,5 +20,5 @@
 	protected String name = "entity";
 	protected EntityOwner owner;
-	protected Dispatcher dispatcher;
+	protected Dispatcher<Entity> dispatcher;
 
 	public Entity() {
@@ -32,5 +35,5 @@
 		this.name = name;
 		if (dispatcher instanceof Thread) {
-			((Thread) dispatcher).setName(name);
+			((Thread<Entity>) dispatcher).setName(name);
 		}
 	}
@@ -56,13 +59,14 @@
 
 	@Override
-	public final void invokeLater(Runnable runnable) {
+	public final void invokeLater(RunAt<? extends Entity> runnable) {
 		assert dispatcher != null;
 		dispatcher.invokeLater(runnable);
 	}
 
-	public Dispatcher createDefaultDispatcher() {
-		return new Thread(name);
+	public Dispatcher<Entity> createDefaultDispatcher() {
+		return new Thread<Entity>(name).start();
 	}
 
+	@OverridingMethodsMustInvokeSuper
 	protected void run() {
 		assert isActive();
@@ -74,5 +78,5 @@
 	}
 
-	public Dispatcher getDispatcher() {
+	public Dispatcher<Entity> getDispatcher() {
 		return dispatcher;
 	}
@@ -81,5 +85,5 @@
 	 * @param dispatcher the dispatcher to set
 	 */
-	public void setDispatcher(Dispatcher dispatcher) {
+	public void setDispatcher(Dispatcher<Entity> dispatcher) {
 		this.dispatcher = dispatcher;
 	}
@@ -90,5 +94,5 @@
 			setDispatcher(createDefaultDispatcher());
 		}
-		invokeLater(new Runnable() {
+		invokeLater(new RunAt<Entity>() {
 			@Override
 			public void run() {
Index: java/main/src/main/java/com/framsticks/core/Instance.java
===================================================================
--- java/main/src/main/java/com/framsticks/core/Instance.java	(revision 84)
+++ java/main/src/main/java/com/framsticks/core/Instance.java	(revision 85)
@@ -12,4 +12,5 @@
 import com.framsticks.util.lang.Casting;
 import org.apache.log4j.Logger;
+import com.framsticks.util.dispatching.RunAt;
 
 import java.util.*;
@@ -33,5 +34,5 @@
 	protected void run() {
 		super.run();
-		root = new Node((CompositeParam)new ParamBuilder().setName("Instance").setId(name).setType("o").build(), null);
+		root = new Node((CompositeParam)Param.build().name("Instance").id(name).type("o").finish(), null);
 		com.framsticks.model.Package.register(registry);
 	}
@@ -71,5 +72,5 @@
 	public void storeValue(Path path, Param param, Object value, final StateFunctor stateFunctor) {
 		assert isActive();
-		invokeLater(new Runnable() {
+		invokeLater(new RunAt<Instance>() {
 			@Override
 			public void run() {
@@ -93,5 +94,5 @@
 	public void addListener(final InstanceListener listener) {
 		assert Dispatching.isThreadSafe();
-		Dispatching.invokeLaterOrNow(this, new Runnable() {
+		Dispatching.invokeLaterOrNow(this, new RunAt<Instance>() {
 			@Override
 			public void run() {
@@ -103,5 +104,5 @@
 	public void removeListener(final InstanceListener listener) {
 		assert Dispatching.isThreadSafe();
-		Dispatching.invokeLaterOrNow(this, new Runnable() {
+		Dispatching.invokeLaterOrNow(this, new RunAt<Instance>() {
 			@Override
 			public void run() {
@@ -271,5 +272,5 @@
 		if ("/".equals(file.getPath())) {
 			if (root.getParam().getContainedTypeName() == null) {
-				root = new Node((CompositeParam)new ParamBuilder().setName("Instance").setId(name).setType("o " + framsClass.getId()).build(), root.getObject());
+				root = new Node((CompositeParam)Param.build().name("Instance").id(name).type("o " + framsClass.getId()).finish(), root.getObject());
 			}
 		}
@@ -310,5 +311,5 @@
 
 					String id = listAccess.computeIdentifierFor(accessInterface.getSelected());
-					Param param = new ParamBuilder().setType("o " + accessInterface.getId()).setId(id).build();
+					Param param = Param.build().type("o " + accessInterface.getId()).id(id).finish();
 					Object child = accessInterface.getSelected();
 					accessInterface.select(null);
Index: java/main/src/main/java/com/framsticks/core/ListChange.java
===================================================================
--- java/main/src/main/java/com/framsticks/core/ListChange.java	(revision 84)
+++ java/main/src/main/java/com/framsticks/core/ListChange.java	(revision 85)
@@ -2,5 +2,5 @@
 
 import com.framsticks.params.FramsClass;
-import com.framsticks.params.ParamBuilder;
+import com.framsticks.params.Param;
 import com.framsticks.params.types.DecimalParam;
 import com.framsticks.params.types.EnumParam;
@@ -55,7 +55,7 @@
 	public static FramsClass getFramsClass() {
 		return new FramsClass("ListChange", "ListChange", null)
-				.append(new ParamBuilder().setId("type").setName("type").setType(new EnumParam(Arrays.asList("Add", "Remove", "Modify"))).build())
-				.append(new ParamBuilder().setId("id").setName("identifier").setType(StringParam.class).build())
-				.append(new ParamBuilder().setId("pos").setName("position").setType(DecimalParam.class).build());
+				.append(Param.build().id("type").name("type").type(new EnumParam(Arrays.asList("Add", "Remove", "Modify"))))
+				.append(Param.build().id("id").name("identifier").type(StringParam.class))
+				.append(Param.build().id("pos").name("position").type(DecimalParam.class));
 	}
 
Index: java/main/src/main/java/com/framsticks/core/LocalInstance.java
===================================================================
--- java/main/src/main/java/com/framsticks/core/LocalInstance.java	(revision 84)
+++ java/main/src/main/java/com/framsticks/core/LocalInstance.java	(revision 85)
@@ -13,4 +13,5 @@
 import java.util.HashSet;
 import java.util.Set;
+import com.framsticks.util.dispatching.RunAt;
 
 
@@ -33,5 +34,5 @@
 				acceptSocket = new ServerSocket();
 				acceptSocket.setReuseAddress(true);
-				acceptThread = new Thread(name + "-accept");
+				acceptThread = new Thread<Accept>(name + "-accept").start();
 				tryBind(accept);
 			} catch (IOException e) {
@@ -43,8 +44,12 @@
 	protected final Set<InstanceClient> clients = new HashSet<InstanceClient>();
 	ServerSocket acceptSocket;
-	Thread acceptThread;
+
+	public static class Accept {
+	};
+
+	Thread<Accept> acceptThread;
 
 	protected void acceptNext() {
-		acceptThread.invokeLater(new Runnable() {
+		acceptThread.invokeLater(new RunAt<Accept>() {
 			@Override
 			public void run() {
@@ -53,5 +58,5 @@
 					assert socket != null;
 					log.debug("accepted socket: " + socket.getInetAddress().getHostAddress());
-					invokeLater(new Runnable() {
+					invokeLater(new RunAt<LocalInstance>() {
 						@Override
 						public void run() {
@@ -70,5 +75,5 @@
 
 	public void tryBind(final Integer accept) {
-		acceptThread.invokeLater(new Runnable() {
+		acceptThread.invokeLater(new RunAt<Accept>() {
 			@Override
 			public void run() {
Index: java/main/src/main/java/com/framsticks/core/Path.java
===================================================================
--- java/main/src/main/java/com/framsticks/core/Path.java	(revision 84)
+++ java/main/src/main/java/com/framsticks/core/Path.java	(revision 85)
@@ -5,8 +5,12 @@
 import com.framsticks.params.Param;
 import com.framsticks.util.dispatching.Dispatching;
+
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 
+import javax.annotation.concurrent.Immutable;
+import javax.annotation.Nonnull;
+
 import org.apache.commons.collections.ListUtils;
 
@@ -14,4 +18,5 @@
  * @author Piotr Sniegowski
  */
+@Immutable
 public class Path {
 	// private final static Logger log = Logger.getLogger(Path.class.getName());
@@ -63,5 +68,5 @@
 	}
 
-	public Path(Instance instance, List<Node> nodes, Node node) {
+	public Path(@Nonnull Instance instance, List<Node> nodes, Node node) {
 		this.instance = instance;
 		StringBuilder b = new StringBuilder();
@@ -196,4 +201,8 @@
 	}
 
+	public void setInstance(Instance instance) {
+		this.instance = instance;
+	}
+
 	@SuppressWarnings("unchecked")
 	public
Index: java/main/src/main/java/com/framsticks/core/Program.java
===================================================================
--- java/main/src/main/java/com/framsticks/core/Program.java	(revision 84)
+++ java/main/src/main/java/com/framsticks/core/Program.java	(revision 85)
@@ -10,9 +10,10 @@
 import java.lang.reflect.Constructor;
 import java.util.*;
+import com.framsticks.util.dispatching.RunAt;
 
 /**
  * @author Piotr Sniegowski
  */
-public class Program extends com.framsticks.util.dispatching.Thread {
+public class Program extends com.framsticks.util.dispatching.Thread<Program> {
 
 	private final static Logger log = Logger.getLogger(Program.class.getName());
@@ -101,5 +102,5 @@
 
 		final Program program = new Program("program");
-		program.invokeLater(new Runnable() {
+		program.invokeLater(new RunAt<Program>() {
 			@Override
 			public void run() {
Index: java/main/src/main/java/com/framsticks/diagnostics/DiagnosticsEndpoint.java
===================================================================
--- java/main/src/main/java/com/framsticks/diagnostics/DiagnosticsEndpoint.java	(revision 84)
+++ java/main/src/main/java/com/framsticks/diagnostics/DiagnosticsEndpoint.java	(revision 85)
@@ -1,4 +1,5 @@
 package com.framsticks.diagnostics;
 
+import com.framsticks.core.Instance;
 import com.framsticks.dumping.PrintWriterSink;
 import com.framsticks.dumping.SaveStream;
@@ -8,8 +9,12 @@
 import com.framsticks.util.PeriodicTask;
 import com.framsticks.util.StateFunctor;
+import com.framsticks.util.io.Encoding;
+
 import org.apache.log4j.Logger;
 
 import java.io.File;
+import java.io.FileOutputStream;
 import java.io.IOException;
+import java.io.OutputStreamWriter;
 import java.io.PrintWriter;
 import java.text.SimpleDateFormat;
@@ -22,5 +27,4 @@
 
 	private final static Logger log = Logger.getLogger(DiagnosticsEndpoint.class.getName());
-
 
 	public DiagnosticsEndpoint() {
@@ -39,5 +43,5 @@
 
 		if (getObserver().dumpsInterval != null) {
-			new PeriodicTask(instance, getObserver().dumpsInterval * 1000) {
+			new PeriodicTask<Instance>(instance, getObserver().dumpsInterval * 1000) {
 				@Override
 				public void run() {
@@ -55,5 +59,5 @@
 								final String fileName = getObserver().dumpsPath + "/" + instance + "_" + new SimpleDateFormat(getObserver().dumpsFormat).format(new Date()) + ".param";
 								File file = new File(fileName);
-								new SaveStream(new PrintWriterSink(new PrintWriter(file)), instance, instance.getRootPath(), new StateFunctor() {
+								new SaveStream(new PrintWriterSink(new PrintWriter(new OutputStreamWriter(new FileOutputStream(file), Encoding.getFramsticksCharset()))), instance, instance.getRootPath(), new StateFunctor() {
 									@Override
 									public void call(Exception e) {
Index: java/main/src/main/java/com/framsticks/dumping/FileInstance.java
===================================================================
--- java/main/src/main/java/com/framsticks/dumping/FileInstance.java	(revision 84)
+++ java/main/src/main/java/com/framsticks/dumping/FileInstance.java	(revision 85)
@@ -5,4 +5,5 @@
 import com.framsticks.core.Instance;
 import com.framsticks.util.dispatching.Future;
+import com.framsticks.util.io.Encoding;
 
 import org.apache.commons.configuration.Configuration;
@@ -11,6 +12,7 @@
 import java.io.BufferedReader;
 import java.io.File;
-import java.io.FileReader;
+import java.io.FileInputStream;
 import java.io.IOException;
+import java.io.InputStreamReader;
 
 /**
@@ -36,6 +38,5 @@
 		super.run();
 		try {
-			FileReader fileReader = new FileReader(file);
-			LoadStream stream = new LoadStream(this.getRootPath(), new BufferedReader(fileReader), this, new Future<Path>() {
+			LoadStream stream = new LoadStream(this.getRootPath(), new BufferedReader(new InputStreamReader(new FileInputStream(file), Encoding.getFramsticksCharset())), this, new Future<Path>() {
 				@Override
 				public void result(Path result, Exception e) {
Index: java/main/src/main/java/com/framsticks/dumping/SaveStream.java
===================================================================
--- java/main/src/main/java/com/framsticks/dumping/SaveStream.java	(revision 84)
+++ java/main/src/main/java/com/framsticks/dumping/SaveStream.java	(revision 85)
@@ -13,4 +13,5 @@
 import com.framsticks.util.dispatching.Dispatching;
 import org.apache.log4j.Logger;
+import com.framsticks.util.dispatching.RunAt;
 
 import java.util.HashSet;
@@ -43,5 +44,5 @@
 	protected void dispatchWrite(final Path path) {
 		++dispatched;
-		instance.invokeLater(new Runnable() {
+		instance.invokeLater(new RunAt<Instance>() {
 			@Override
 			public void run() {
Index: java/main/src/main/java/com/framsticks/examples/GenotypeBrowser.java
===================================================================
--- java/main/src/main/java/com/framsticks/examples/GenotypeBrowser.java	(revision 84)
+++ java/main/src/main/java/com/framsticks/examples/GenotypeBrowser.java	(revision 85)
@@ -43,8 +43,8 @@
 
 		registry.putInfoIntoCache(new FramsClass("ModelBuilderRoot", "ModelBuilderRoot", null)
-				.append(new ParamBuilder().setType("o Model").setId("model").setName("model").build())
-				.append(new ParamBuilder().setType("s 1").setId("genotype").setName("genotype").build())
+				.append(Param.build().type("o Model").id("model").name("model"))
+				.append(Param.build().type("s 1").id("genotype").name("genotype"))
 		);
-		root = new Node((CompositeParam)new ParamBuilder().setType("o ModelBuilderRoot").setId(name).setName("Instance").build(), PropertiesAccess.createPropertiesMap());
+		root = new Node((CompositeParam)Param.build().type("o ModelBuilderRoot").id(name).name("Instance").finish(), PropertiesAccess.createPropertiesMap());
 	}
 
Index: java/main/src/main/java/com/framsticks/gui/Browser.java
===================================================================
--- java/main/src/main/java/com/framsticks/gui/Browser.java	(revision 84)
+++ java/main/src/main/java/com/framsticks/gui/Browser.java	(revision 85)
@@ -19,9 +19,10 @@
 import java.util.List;
 import java.util.Set;
+import com.framsticks.util.dispatching.RunAt;
 
 /**
  * @author Piotr Sniegowski
  */
-public class Browser extends Observer implements Dispatcher {
+public class Browser extends Observer {
 
 	private static final Logger log = Logger.getLogger(Browser.class.getName());
@@ -78,5 +79,5 @@
 	public void autoResolvePath(final String path, final Future<Path> future) {
 		final Instance i = endpoints.get("localhost").getInstance();
-		i.invokeLater(new Runnable() {
+		i.invokeLater(new RunAt<Instance>() {
 			@Override
 			public void run() {
@@ -89,5 +90,5 @@
 						}
 						if (e == null) {
-							mainFrame.invokeLater(new Runnable() {
+							mainFrame.invokeLater(new RunAt<Frame>() {
 								@Override
 								public void run() {
@@ -142,9 +143,9 @@
 
 		for (final Endpoint e : getEndpoints().values()) {
-			e.invokeLater(new Runnable() {
+			e.invokeLater(new RunAt<Instance>() {
 				@Override
 				public void run() {
 					final Path p = e.getInstance().getRootPath();
-					invokeLater(new Runnable() {
+					invokeLater(new RunAt<Browser>() {
 						@Override
 						public void run() {
@@ -199,6 +200,6 @@
 
 	@Override
-	public Dispatcher createDefaultDispatcher() {
-		return SwingDispatcher.instance;
+	public Dispatcher<Entity> createDefaultDispatcher() {
+		return SwingDispatcher.getInstance();
 	}
 
Index: java/main/src/main/java/com/framsticks/gui/EndpointAtFrame.java
===================================================================
--- java/main/src/main/java/com/framsticks/gui/EndpointAtFrame.java	(revision 84)
+++ java/main/src/main/java/com/framsticks/gui/EndpointAtFrame.java	(revision 85)
@@ -14,4 +14,5 @@
 
 import javax.swing.tree.TreePath;
+import com.framsticks.util.dispatching.RunAt;
 
 /**
@@ -121,4 +122,8 @@
 				}
 				Path p = new Path(path.getInstance(), nodes, n);
+
+				//TODO breaks immutable
+				path.setInstance(path.getInstance());
+
 				log.debug("forced resolution: creating treenode for " + p);
 				TreeNode childNode = new TreeNode(EndpointAtFrame.this, p);
@@ -146,5 +151,5 @@
 		log.trace("fetched " + path);
 
-		frame.invokeLater(new Runnable() {
+		frame.invokeLater(new RunAt<Frame>() {
 			@Override
 			public void run() {
@@ -155,5 +160,5 @@
 				final TreeNode result = (TreeNode) treePath.getLastPathComponent();
 				// log.trace("found " + result + " == " + path);
-				instance.invokeLater(new Runnable() {
+				instance.invokeLater(new RunAt<Instance>() {
 					@Override
 					public void run() {
Index: java/main/src/main/java/com/framsticks/gui/Frame.java
===================================================================
--- java/main/src/main/java/com/framsticks/gui/Frame.java	(revision 84)
+++ java/main/src/main/java/com/framsticks/gui/Frame.java	(revision 85)
@@ -6,4 +6,5 @@
 import com.framsticks.gui.view.TreeCellRenderer;
 import com.framsticks.util.dispatching.Dispatcher;
+import com.framsticks.util.lang.ScopeEnd;
 import com.framsticks.util.swing.KeyboardModifier;
 import org.apache.log4j.Logger;
@@ -21,4 +22,5 @@
 import java.util.HashMap;
 import java.util.Map;
+import com.framsticks.util.dispatching.RunAt;
 
 /**
@@ -26,5 +28,5 @@
  */
 @SuppressWarnings("serial")
-public class Frame extends JFrame implements Dispatcher {
+public class Frame extends JFrame implements Dispatcher<Frame> {
 
 	private static final Logger log = Logger.getLogger(Frame.class.getName());
@@ -267,6 +269,6 @@
 
 	@Override
-	public void invokeLater(Runnable runnable) {
-		SwingDispatcher.instance.invokeLater(runnable);
+	public void invokeLater(RunAt<? extends Frame> runnable) {
+		SwingDispatcher.getInstance().invokeLater(runnable);
 	}
 
@@ -325,10 +327,10 @@
 	}
 
-	public Runnable startChange(final DefaultMutableTreeNode node) {
+	public ScopeEnd startChange(final DefaultMutableTreeNode node) {
 		assert isActive();
 		final TreePath selection = tree.getSelectionPath();
-		return new Runnable() {
-			@Override
-			public void run() {
+		return new ScopeEnd() {
+			@Override
+			public void close() {
 				assert isActive();
 				treeModel.nodeChanged(node);
@@ -373,13 +375,15 @@
 		final TreePath treePath = endpointsByInstance.get(path.getInstance()).getTreePath(path, false);
 		log.info("go to path: " + path + "(" + treePath + ")");
-		invokeLater(new Runnable() {
+
+		new RunAt<Frame>(this) {
 			@Override
 			public void run() {
+				log.info("executed");
 				tree.setSelectionPath(treePath);
 				tree.makeVisible(treePath);
 				assert tree.isVisible(treePath);
 			}
-
-		});
+		};
+
 	}
 
@@ -387,7 +391,8 @@
 	public void addNode(TreeNode child, DefaultMutableTreeNode parent) {
 		assert isActive();
-		Runnable r = startChange(parent);
-		treeModel.insertNodeInto(child, parent, parent.getChildCount());
-		r.run();
+
+		try (ScopeEnd e = startChange(parent)) {
+			treeModel.insertNodeInto(child, parent, parent.getChildCount());
+		}
 	}
 
Index: java/main/src/main/java/com/framsticks/gui/ObjectPanel.java
===================================================================
--- java/main/src/main/java/com/framsticks/gui/ObjectPanel.java	(revision 84)
+++ java/main/src/main/java/com/framsticks/gui/ObjectPanel.java	(revision 85)
@@ -15,4 +15,5 @@
 import java.util.Map;
 import static com.framsticks.util.lang.Containers.filterInstanceof;
+import com.framsticks.util.dispatching.RunAt;
 
 @SuppressWarnings("serial")
@@ -73,5 +74,5 @@
 		}
 
-		frame.invokeLater(new Runnable() {
+		frame.invokeLater(new RunAt<Frame>() {
 			@Override
 			public void run() {
Index: java/main/src/main/java/com/framsticks/gui/SwingDispatcher.java
===================================================================
--- java/main/src/main/java/com/framsticks/gui/SwingDispatcher.java	(revision 84)
+++ java/main/src/main/java/com/framsticks/gui/SwingDispatcher.java	(revision 85)
@@ -5,14 +5,21 @@
 
 import javax.swing.*;
+import com.framsticks.util.dispatching.RunAt;
 
 /**
  * @author Piotr Sniegowski
  */
-public class SwingDispatcher implements Dispatcher {
+public class SwingDispatcher<C> implements Dispatcher<C> {
 
-	public static final SwingDispatcher instance = new SwingDispatcher();
+	@SuppressWarnings("rawtypes")
+	protected static final SwingDispatcher instance = new SwingDispatcher();
+
+	@SuppressWarnings("unchecked")
+	public static <C> Dispatcher<C> getInstance() {
+		return (Dispatcher<C>) instance;
+	}
 
 	public SwingDispatcher() {
-		invokeLater(new Runnable() {
+		invokeLater(new RunAt<C>() {
 			@Override
 			public void run() {
@@ -28,5 +35,5 @@
 
 	@Override
-	public final void invokeLater(Runnable runnable) {
+	public final void invokeLater(RunAt<? extends C> runnable) {
 		assert !(runnable instanceof Task);
 		SwingUtilities.invokeLater(runnable);
Index: java/main/src/main/java/com/framsticks/gui/TreeNode.java
===================================================================
--- java/main/src/main/java/com/framsticks/gui/TreeNode.java	(revision 84)
+++ java/main/src/main/java/com/framsticks/gui/TreeNode.java	(revision 85)
@@ -1,6 +1,8 @@
 package com.framsticks.gui;
 
+import com.framsticks.communication.Connection;
 import com.framsticks.communication.Subscription;
 import com.framsticks.communication.util.LoggingStateCallback;
+import com.framsticks.core.Instance;
 import com.framsticks.core.ListChange;
 import com.framsticks.core.Path;
@@ -18,4 +20,5 @@
 import com.framsticks.util.StateFunctor;
 import org.apache.log4j.Logger;
+import com.framsticks.util.dispatching.RunAt;
 
 import javax.swing.tree.DefaultMutableTreeNode;
@@ -40,5 +43,5 @@
 	final protected EndpointAtFrame endpoint;
 
-	final protected Map<EventParam, Subscription> userSubscriptions = new HashMap<EventParam, Subscription>();
+	final protected Map<EventParam, Subscription<?>> userSubscriptions = new HashMap<>();
 	protected Map<ValueControl, Object> localChanges = null;
 	protected String tooltip;
@@ -59,5 +62,5 @@
 		iconName = TreeCellRenderer.findIconName(name, path.getTextual());
 		tooltip = "?";
-		path.getInstance().invokeLater(new Runnable() {
+		path.getInstance().invokeLater(new RunAt<Instance>() {
 			@Override
 			public void run() {
@@ -82,5 +85,5 @@
 		assert p.getInstance().isActive();
 		if (Logging.log(log, "fetch", TreeNode.this, e)) {
-			frame.invokeLater(new Runnable() {
+			frame.invokeLater(new RunAt<Frame>() {
 				@Override
 				public void run() {
@@ -92,5 +95,5 @@
 		}
 		updateChildren(p);
-		frame.invokeLater(new Runnable() {
+		frame.invokeLater(new RunAt<Frame>() {
 			@Override
 			public void run() {
@@ -104,5 +107,5 @@
 		assert !frame.isActive();
 		/** TODO those two actions could be merged into single closure */
-		frame.invokeLater(new Runnable() {
+		frame.invokeLater(new RunAt<Frame>() {
 			@Override
 			public void run() {
@@ -149,5 +152,5 @@
 		/**If some child were found, update in frame context.*/
 		if (childrenPaths.size() > 0) {
-			frame.invokeLater(new Runnable() {
+			frame.invokeLater(new RunAt<Frame>() {
 				@Override
 				public void run() {
@@ -186,5 +189,5 @@
 		final Path p = path;
 
-		p.getInstance().invokeLater(new Runnable() {
+		p.getInstance().invokeLater(new RunAt<Instance>() {
 			@Override
 			public void run() {
@@ -246,5 +249,5 @@
 		final String name = (nameParam != null ? access.get(nameParam, String.class) : path.getTop().getParam().getId());
 
-		frame.invokeLater(new Runnable() {
+		frame.invokeLater(new RunAt<Frame>() {
 			@Override
 			public void run() {
@@ -303,5 +306,5 @@
 		assert p.isResolved();
 		panel.setCurrentTreeNode(this);
-		p.getInstance().invokeLater(new Runnable() {
+		p.getInstance().invokeLater(new RunAt<Instance>() {
 			@Override
 			public void run() {
@@ -309,5 +312,5 @@
 				panel.pullValuesFromLocalToUser(access);
 
-				frame.invokeLater(new Runnable() {
+				frame.invokeLater(new RunAt<Frame>() {
 					@Override
 					public void run() {
@@ -341,5 +344,5 @@
 		final Path p = path;
 		log.debug("preparing panel: " + p);
-		p.getInstance().invokeLater(new Runnable() {
+		p.getInstance().invokeLater(new RunAt<Instance>() {
 			@Override
 			public void run() {
@@ -347,5 +350,5 @@
 				final CompositeParam param = p.getTop().getParam();
 				final FramsClass framsClass = p.getInstance().getInfoFromCache(param.getContainedTypeName());
-				frame.invokeLater(new Runnable() {
+				frame.invokeLater(new RunAt<Frame>() {
 					@Override
 					public void run() {
@@ -410,5 +413,5 @@
 			return;
 		}
-		userSubscriptions.get(eventParam).unsubscribe(new LoggingStateCallback(log, "unsubscribed " + eventParam));
+		userSubscriptions.get(eventParam).unsubscribe(new LoggingStateCallback<Connection>(log, "unsubscribed " + eventParam));
 		userSubscriptions.remove(eventParam);
 	}
@@ -500,5 +503,5 @@
 		final Map<ValueControl, Object> changes = localChanges;
 		localChanges = null;
-		endpoint.getEndpoint().invokeLater(new Runnable() {
+		endpoint.getEndpoint().invokeLater(new RunAt<Instance>() {
 			@Override
 			public void run() {
@@ -514,5 +517,5 @@
 							}
 							log.debug("applied changes for: " + p);
-							frame.invokeLater(new Runnable() {
+							frame.invokeLater(new RunAt<Frame>() {
 								@Override
 								public void run() {
@@ -526,4 +529,3 @@
 		});
 	}
-
 }
Index: java/main/src/main/java/com/framsticks/gui/controls/EnumControl.java
===================================================================
--- java/main/src/main/java/com/framsticks/gui/controls/EnumControl.java	(revision 84)
+++ java/main/src/main/java/com/framsticks/gui/controls/EnumControl.java	(revision 85)
@@ -14,5 +14,5 @@
 public class EnumControl extends ValueControl {
 
-	protected final JComboBox list;
+	protected final JComboBox<String> list;
 
 	private static final Logger log = Logger.getLogger(EnumControl.class.getName());
@@ -23,5 +23,5 @@
 		this.setMaximumSize(new Dimension(Integer.MAX_VALUE, LINE_HEIGHT));
 
-		list = new JComboBox();
+		list = new JComboBox<String>();
 		for (String item : enumParam.getElements()) {
 			list.addItem(item);
Index: java/main/src/main/java/com/framsticks/gui/windows/ServerLogFrame.java
===================================================================
--- java/main/src/main/java/com/framsticks/gui/windows/ServerLogFrame.java	(revision 84)
+++ java/main/src/main/java/com/framsticks/gui/windows/ServerLogFrame.java	(revision 85)
@@ -43,5 +43,5 @@
 		logText.setWrapStyleWord(true);
 		logText.setLineWrap(true);
-		JComboBox levelBox = new JComboBox();
+		JComboBox<String> levelBox = new JComboBox<String>();
 		for (String i : STR_) {
 			levelBox.addItem(i);
@@ -49,5 +49,5 @@
 		levelBox.addActionListener(new ActionListener() {
 			public void actionPerformed(ActionEvent e) {
-				levelReporting = ((JComboBox) e.getSource()).getSelectedIndex();
+				levelReporting = ((JComboBox<?>) e.getSource()).getSelectedIndex();
 			}
 		});
Index: java/main/src/main/java/com/framsticks/gui/windows/console/ConsoleFrame.java
===================================================================
--- java/main/src/main/java/com/framsticks/gui/windows/console/ConsoleFrame.java	(revision 84)
+++ java/main/src/main/java/com/framsticks/gui/windows/console/ConsoleFrame.java	(revision 85)
@@ -172,5 +172,5 @@
 		addSentMessage(commandText);
 		commandLine.setText("");
-		connection.send(request, new ResponseCallback() {
+		connection.send(request, new ResponseCallback<Connection>() {
 			@Override
 			public void process(Response response) {
Index: java/main/src/main/java/com/framsticks/hosting/InstanceClient.java
===================================================================
--- java/main/src/main/java/com/framsticks/hosting/InstanceClient.java	(revision 84)
+++ java/main/src/main/java/com/framsticks/hosting/InstanceClient.java	(revision 85)
@@ -5,4 +5,5 @@
 import com.framsticks.communication.queries.GetRequest;
 import com.framsticks.communication.queries.InfoRequest;
+import com.framsticks.core.Instance;
 import com.framsticks.core.Path;
 import com.framsticks.params.*;
@@ -15,4 +16,5 @@
 import java.util.LinkedList;
 import java.util.List;
+import com.framsticks.util.dispatching.RunAt;
 
 /**
@@ -37,6 +39,6 @@
 
 	@Override
-	public void handle(final ApplicationRequest request, final ResponseCallback responseCallback) {
-		instance.invokeLater(new Runnable() {
+	public void handle(final ApplicationRequest request, final ResponseCallback<?> responseCallback) {
+		instance.invokeLater(new RunAt<Instance>() {
 			@Override
 			public void run() {
Index: java/main/src/main/java/com/framsticks/hosting/ServerInstance.java
===================================================================
--- java/main/src/main/java/com/framsticks/hosting/ServerInstance.java	(revision 84)
+++ java/main/src/main/java/com/framsticks/hosting/ServerInstance.java	(revision 85)
@@ -4,5 +4,5 @@
 import com.framsticks.params.CompositeParam;
 import com.framsticks.params.FramsClass;
-import com.framsticks.params.ParamBuilder;
+import com.framsticks.params.Param;
 import com.framsticks.core.LocalInstance;
 import com.framsticks.util.dispatching.Future;
@@ -42,5 +42,5 @@
 		hosted.setName("hosted");
 		hosted.configure(hostedConfig);
-		root = new Node((CompositeParam)new ParamBuilder().setName("root").setId("root").setType("o" + hosted.getClass().getCanonicalName()).build(), hosted);
+		root = new Node((CompositeParam)Param.build().name("root").id("root").type("o" + hosted.getClass().getCanonicalName()).finish(), hosted);
 	}
 
Index: java/main/src/main/java/com/framsticks/leftovers/FavouritesXMLFactory.java
===================================================================
--- java/main/src/main/java/com/framsticks/leftovers/FavouritesXMLFactory.java	(revision 84)
+++ java/main/src/main/java/com/framsticks/leftovers/FavouritesXMLFactory.java	(revision 85)
@@ -3,9 +3,11 @@
 import java.io.BufferedWriter;
 import java.io.File;
-import java.io.FileWriter;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.nio.file.Files;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.Map;
@@ -13,17 +15,94 @@
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.stream.XMLOutputFactory;
+import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamWriter;
 
+import org.apache.log4j.Logger;
 import org.w3c.dom.Document;
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
+import org.xml.sax.SAXException;
+
+import com.framsticks.util.io.Encoding;
 
 public class FavouritesXMLFactory {
-
-	private final String pathMark = "path";
-	private final String nameMark = "name";
-	private final String fieldMark = "field";
-	private final String typeMark = "type";
+	private static final Logger log = Logger
+			.getLogger(FavouritesXMLFactory.class);
+
+	private static final String PATH_MARK = "path";
+	private static final String NAME_MARK = "name";
+	private static final String FIELD_MARK = "field";
+	private static final String TYPE_MARK = "type";
+
+	protected Node readDocument(String filename) {
+		File file = new File(filename);
+		if (!file.exists()) {
+			return null;
+		}
+		DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory
+				.newInstance();
+		try {
+			DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
+			Document doc = docBuilder.parse(file);
+			doc.getDocumentElement().normalize();
+			return doc.getFirstChild();
+
+		} catch (ParserConfigurationException | SAXException | IOException e) {
+			log.error(e);
+			return null;
+		}
+	}
+
+	public static class XmlWriter implements AutoCloseable {
+
+		BufferedWriter writer = null;
+		XMLStreamWriter xml = null;
+
+		public XmlWriter(String filename) throws XMLStreamException,
+				IOException {
+			XMLOutputFactory factory = XMLOutputFactory.newInstance();
+
+			File file = new File(filename);
+			Files.deleteIfExists(file.toPath());
+
+			writer = new BufferedWriter(new OutputStreamWriter(
+					new FileOutputStream(file),
+					Encoding.getDefaultCharset()));
+			xml = factory.createXMLStreamWriter(writer);
+
+			xml.writeStartDocument("1.0");
+		}
+
+		public void close() {
+			try {
+				xml.writeEndDocument();
+				xml.flush();
+				xml.close();
+				writer.close();
+			} catch (XMLStreamException | IOException e) {
+				log.error(e);
+			}
+		}
+
+		public void start(String name) throws XMLStreamException {
+			xml.writeStartElement(name);
+		}
+
+		public void element(String name, Object value) throws XMLStreamException {
+			start(name);
+			xml.writeCharacters(value.toString());
+			end();
+		}
+
+		public void end() throws XMLStreamException {
+			xml.writeEndElement();
+		}
+
+		public void attribute(String name, Object value) throws XMLStreamException {
+			xml.writeAttribute(name, value.toString());
+		}
+	}
 
 	/**
@@ -39,26 +118,12 @@
 			return;
 		}
-		XMLOutputFactory factory = XMLOutputFactory.newInstance();
-		BufferedWriter writer = null;
-		XMLStreamWriter xmlWriter = null;
-		try {
-			File file = new File(path);
-			if (file.exists()) {
-				file.delete();
-			}
-			writer = new BufferedWriter(new FileWriter(file));
-			xmlWriter = factory.createXMLStreamWriter(writer);
-			xmlWriter.writeStartDocument("1.0");
-			xmlWriter.writeStartElement("root");
+
+		try (XmlWriter xml = new XmlWriter(path)) {
+			xml.start("framsticks");
 			for (UserFavourite node : nodes) {
-				xmlWriter.writeStartElement("item");
-
-				xmlWriter.writeStartElement(pathMark);
-				xmlWriter.writeCharacters(node.getPath());
-				xmlWriter.writeEndElement();
-
-				xmlWriter.writeStartElement(nameMark);
-				xmlWriter.writeCharacters(node.getName());
-				xmlWriter.writeEndElement();
+				xml.start("item");
+
+				xml.element(PATH_MARK, node.getPath());
+				xml.element(NAME_MARK, node.getName());
 
 				/*if(node.isFavouriteNode()){
@@ -67,21 +132,10 @@
 					xmlWriter.writeEndElement();
 				}else{ //isFavouriteField() */
-					xmlWriter.writeStartElement(fieldMark);
-					xmlWriter.writeCharacters(node.getField());
-					xmlWriter.writeEndElement();
-				//}
-
-				xmlWriter.writeEndElement();
-			}
-
-			xmlWriter.writeEndDocument();
-			xmlWriter.flush();
-		} catch (Exception e) {
-		} finally {
-			try {
-				xmlWriter.close();
-				writer.close();
-			} catch (Exception e) {
-			}
+				xml.element(FIELD_MARK, node.getField());
+				xml.end();
+			}
+			xml.end();
+		} catch (XMLStreamException | IOException e) {
+			log.error(e);
 		}
 	}
@@ -95,49 +149,41 @@
 	 *         concatenation of path and field getName.
 	 */
-	public LinkedHashMap<String, UserFavourite> readFavouritesXML(String filePath) {
+	public LinkedHashMap<String, UserFavourite> readFavouritesXML(
+			String filePath) {
+
+		Node root = readDocument(filePath);
+		if (root == null) {
+			return null;
+		}
 		LinkedHashMap<String, UserFavourite> result = new LinkedHashMap<String, UserFavourite>();
 
-		File file = new File(filePath);
-		if (file.exists()) {
-			DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory
-					.newInstance();
-			try {
-				DocumentBuilder docBuilder = docBuilderFactory
-						.newDocumentBuilder();
-				Document doc = docBuilder.parse(file);
-				doc.getDocumentElement().normalize();
-				Node root = doc.getFirstChild();
-				NodeList items = root.getChildNodes();
-				UserFavourite userNode;
-				String path, name, field;
-				for (int i = 0; i < items.getLength(); i++) {
-					Node item = items.item(i);
-					NodeList itemDetails = item.getChildNodes();
-					if (itemDetails.getLength() == 3) {
-						if (itemDetails.item(0).getNodeName().equals(pathMark)
-								&& itemDetails.item(1).getNodeName().equals(nameMark)
-								&& (itemDetails.item(2).getNodeName().equals(fieldMark)
-										|| itemDetails.item(2).getNodeName().equals(typeMark))) {
-							path = itemDetails.item(0).getTextContent();
-							name = itemDetails.item(1).getTextContent();
-							if (itemDetails.item(2).getNodeName().equals(
-									fieldMark)) {
-								field = itemDetails.item(2).getTextContent();
-								userNode = new UserFavourite(path, name, field);
-								result.put(path+field, userNode);
-							}else{
-								try {
-									// int nodeTypeId = Integer.parseInt(itemDetails.item(2).getTextContent());
-									userNode = new UserFavourite(path, name, null);
-									result.put(path, userNode);
-								} catch (Exception e) {
-								}
-							}
+		NodeList items = root.getChildNodes();
+		UserFavourite userNode;
+		String path, name, field;
+		for (int i = 0; i < items.getLength(); i++) {
+			Node item = items.item(i);
+			NodeList itemDetails = item.getChildNodes();
+			if (itemDetails.getLength() == 3) {
+				if (itemDetails.item(0).getNodeName().equals(PATH_MARK)
+						&& itemDetails.item(1).getNodeName().equals(NAME_MARK)
+						&& (itemDetails.item(2).getNodeName().equals(FIELD_MARK)
+								|| itemDetails.item(2).getNodeName().equals(TYPE_MARK))) {
+					path = itemDetails.item(0).getTextContent();
+					name = itemDetails.item(1).getTextContent();
+					if (itemDetails.item(2).getNodeName().equals(
+							FIELD_MARK)) {
+						field = itemDetails.item(2).getTextContent();
+						userNode = new UserFavourite(path, name, field);
+						result.put(path+field, userNode);
+					}else{
+						try {
+							// int nodeTypeId = Integer.parseInt(itemDetails.item(2).getTextContent());
+							userNode = new UserFavourite(path, name, null);
+							result.put(path, userNode);
+						} catch (Exception e) {
 						}
 					}
 				}
-			} catch (Exception e) {
-			}
-
+			}
 		}
 
@@ -159,46 +205,17 @@
 			return;
 		}
-		XMLOutputFactory factory = XMLOutputFactory.newInstance();
-		BufferedWriter writer = null;
-		XMLStreamWriter xmlWriter = null;
-		try {
-			File file = new File(path);
-			if (file.exists()) {
-				file.delete();
-			}
-			writer = new BufferedWriter(new FileWriter(file));
-			xmlWriter = factory.createXMLStreamWriter(writer);
-			xmlWriter.writeStartDocument("1.0");
-			xmlWriter.writeStartElement("root");
-
-			Iterator<String> iterator = groupColumns.keySet().iterator();
-			while (iterator.hasNext()) {
-				/*
-	  Definition of read/write mark.
-	 */
-				String itemMark = "item";
-				xmlWriter.writeStartElement(itemMark);
-				String itemPath = iterator.next();
-				xmlWriter.writeAttribute(pathMark, itemPath);
-
-				for (String column : groupColumns.get(itemPath)) {
-					String columnMark = "column";
-					xmlWriter.writeStartElement(columnMark);
-					xmlWriter.writeCharacters(column);
-					xmlWriter.writeEndElement();
+		try (XmlWriter xml = new XmlWriter(path)) {
+			xml.start("framsticks");
+			for (Map.Entry<String, ArrayList<String>> i : groupColumns.entrySet()) {
+				xml.start("item");
+				xml.attribute(PATH_MARK, i.getKey());
+				for (String column : i.getValue()) {
+					xml.element("column", column);
 				}
-
-				xmlWriter.writeEndElement();
-			}
-
-			xmlWriter.writeEndDocument();
-			xmlWriter.flush();
-		} catch (Exception e) {
-		} finally {
-			try {
-				xmlWriter.close();
-				writer.close();
-			} catch (Exception e) {
-			}
+				xml.end();
+			}
+			xml.end();
+		} catch (XMLStreamException | IOException e) {
+			log.error(e);
 		}
 	}
@@ -214,35 +231,25 @@
 	public HashMap<String, ArrayList<String>> readColumnConfigurationXML(
 			String path) {
+		Node root = readDocument(path);
+		if (root == null) {
+			return null;
+		}
+
 		HashMap<String, ArrayList<String>> result = new LinkedHashMap<String, ArrayList<String>>();
 
-		File file = new File(path);
-		if (file.exists()) {
-			DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory
-					.newInstance();
-			try {
-				DocumentBuilder docBuilder = docBuilderFactory
-						.newDocumentBuilder();
-				Document doc = docBuilder.parse(file);
-				doc.getDocumentElement().normalize();
-				Node root = doc.getFirstChild();
-				NodeList items = root.getChildNodes();
-				String itemPath;
-				ArrayList<String> columns;
-				for (int i = 0; i < items.getLength(); i++) {
-					Node item = items.item(i);
-					itemPath = item.getAttributes().getNamedItem(pathMark)
-							.getNodeValue();
-					columns = new ArrayList<String>();
-					NodeList itemDetails = item.getChildNodes();
-					for (int j = 0; j < itemDetails.getLength(); j++) {
-						columns.add(itemDetails.item(j).getTextContent());
-					}
-					result.put(itemPath, columns);
-				}
-			} catch (Exception e) {
-			}
-
-		}
-
+		NodeList items = root.getChildNodes();
+		String itemPath;
+		ArrayList<String> columns;
+		for (int i = 0; i < items.getLength(); i++) {
+			Node item = items.item(i);
+			itemPath = item.getAttributes().getNamedItem(PATH_MARK)
+					.getNodeValue();
+			columns = new ArrayList<String>();
+			NodeList itemDetails = item.getChildNodes();
+			for (int j = 0; j < itemDetails.getLength(); j++) {
+				columns.add(itemDetails.item(j).getTextContent());
+			}
+			result.put(itemPath, columns);
+		}
 		return result;
 	}
Index: java/main/src/main/java/com/framsticks/leftovers/f0/NeuroClass.java
===================================================================
--- java/main/src/main/java/com/framsticks/leftovers/f0/NeuroClass.java	(revision 84)
+++ java/main/src/main/java/com/framsticks/leftovers/f0/NeuroClass.java	(revision 85)
@@ -16,7 +16,7 @@
 
 	/**
-	 * The symbol glymph.
-	 */
-	private int[] symbolGlymph;
+	 * The symbol glyph.
+	 */
+	private int[] symbolGlyph;
 
 	/**
@@ -71,10 +71,9 @@
 	 * @param prefLocation the pref location
 	 * @param visualHints  the visual hints
-	 * @param symbolGlymph the symbol glymph
+	 * @param symbolGlyph the symbol glymph
 	 */
 	public NeuroClass(FramsClass framsClass, int prefInputs,
 					  int prefOutput, int prefLocation, int visualHints,
-					  int[] symbolGlymph) {
-		super();
+					  int[] symbolGlyph) {
 		this.framsClass = framsClass;
 		this.prefInputs = prefInputs;
@@ -82,5 +81,5 @@
 		this.prefLocation = prefLocation;
 		this.visualHints = visualHints;
-		this.symbolGlymph = symbolGlymph;
+		this.symbolGlyph = (symbolGlyph == null ? null : Arrays.copyOf(symbolGlyph, symbolGlyph.length));
 	}
 
@@ -153,5 +152,5 @@
 	 */
 	int[] getSymbolGlyph() {
-		return symbolGlymph;
+		return symbolGlyph;
 	}
 
@@ -165,5 +164,5 @@
 	 */
 	void setSymbolGlyph(int[] data) {
-		symbolGlymph = data;
+		symbolGlyph = data;
 	}
 
@@ -191,5 +190,5 @@
 				.append(", prefLocation=").append(prefLocation)
 				.append(", visualHints=").append(visualHints)
-				.append(", symbolGlymph=").append(Arrays.toString(symbolGlymph));
+				.append(", symbolGlymph=").append(Arrays.toString(symbolGlyph));
 
 		sb.append(", paramList={");
Index: java/main/src/main/java/com/framsticks/observers/Endpoint.java
===================================================================
--- java/main/src/main/java/com/framsticks/observers/Endpoint.java	(revision 84)
+++ java/main/src/main/java/com/framsticks/observers/Endpoint.java	(revision 85)
@@ -8,9 +8,10 @@
 import com.framsticks.util.dispatching.Dispatcher;
 import org.apache.log4j.Logger;
+import com.framsticks.util.dispatching.RunAt;
 
 /**
  * @author Piotr Sniegowski
  */
-public class Endpoint implements Dispatcher, InstanceListener {
+public class Endpoint implements Dispatcher<Instance>, InstanceListener {
 	private final static Logger log = Logger.getLogger(Endpoint.class.getName());
 
@@ -67,5 +68,5 @@
 
 	@Override
-	public final void invokeLater(Runnable runnable) {
+	public final void invokeLater(RunAt<? extends Instance> runnable) {
 		instance.invokeLater(runnable);
 	}
Index: java/main/src/main/java/com/framsticks/params/ArrayListAccess.java
===================================================================
--- java/main/src/main/java/com/framsticks/params/ArrayListAccess.java	(revision 84)
+++ java/main/src/main/java/com/framsticks/params/ArrayListAccess.java	(revision 85)
@@ -31,5 +31,5 @@
 	@Override
 	public Param getParam(int i) {
-		return new ParamBuilder().setId(Integer.toString(i)).setName(elementAccess.getId()).setType("o " + elementAccess.getId()).build();
+		return Param.build().id(Integer.toString(i)).name(elementAccess.getId()).type("o " + elementAccess.getId()).finish();
 	}
 
Index: java/main/src/main/java/com/framsticks/params/Flags.java
===================================================================
--- java/main/src/main/java/com/framsticks/params/Flags.java	(revision 84)
+++ java/main/src/main/java/com/framsticks/params/Flags.java	(revision 85)
@@ -60,7 +60,5 @@
 				}
 			}
-		} catch (IllegalArgumentException e) {
-			e.printStackTrace();
-		} catch (IllegalAccessException e) {
+		} catch (IllegalArgumentException | IllegalAccessException e) {
 			e.printStackTrace();
 		}
@@ -80,9 +78,5 @@
 				} catch (SecurityException e) {
 					log.warn("security exception was thrown while trying to read flag (" + flag + ")");
-				} catch (NoSuchFieldException e) {
-					log.warn("selected flag is not known (" + flag + ")");
-				} catch (IllegalArgumentException e) {
-					log.warn("selected flag is not known (" + flag + ")");
-				} catch (IllegalAccessException e) {
+				} catch (NoSuchFieldException | IllegalArgumentException | IllegalAccessException e) {
 					log.warn("selected flag is not known (" + flag + ")");
 				}
Index: java/main/src/main/java/com/framsticks/params/FramsClass.java
===================================================================
--- java/main/src/main/java/com/framsticks/params/FramsClass.java	(revision 84)
+++ java/main/src/main/java/com/framsticks/params/FramsClass.java	(revision 85)
@@ -26,9 +26,10 @@
 public final class FramsClass {
 
-	private final static Logger log = Logger.getLogger(FramsClass.class.getName());
-
-	/**
-	  * The Class which represents group.
-	  */
+	private final static Logger log = Logger.getLogger(FramsClass.class
+			.getName());
+
+	/**
+	 * The Class which represents group.
+	 */
 
 	/** The offset of the parameter (applied for newly added parameter). */
@@ -91,4 +92,8 @@
 	}
 
+	public FramsClass append(ParamBuilder builder) {
+		return append(builder.finish());
+	}
+
 	/**
 	 * Adds new group.
@@ -185,7 +190,7 @@
 	public static FramsClass getFramsClass() {
 		return new FramsClass("class", "class", null)
-			.append(new ParamBuilder().setId("name").setName("Name").setType(StringParam.class).build())
-			.append(new ParamBuilder().setId("id").setName("id").setType(StringParam.class).build())
-			.append(new ParamBuilder().setId("desc").setName("Description").setType(StringParam.class).build());
+			.append(Param.build().id("name").name("Name").type(StringParam.class))
+			.append(Param.build().id("id").name("id").type(StringParam.class))
+			.append(Param.build().id("desc").name("Description").type(StringParam.class));
 	}
 
@@ -210,5 +215,6 @@
 				//TODO uid should be passed along during construction
 				if (containedType instanceof Class) {
-					return "l " + ((Class<?>) containedType).getCanonicalName() + " name";
+					return "l " + ((Class<?>) containedType).getCanonicalName()
+							+ " name";
 				}
 			}
@@ -248,10 +254,14 @@
 
 		public Constructor(Class<?> src, String name) {
-			result = new FramsClass(name, name, GENERATE_HELP_PREFIX + src.toString());
+			result = new FramsClass(name, name, GENERATE_HELP_PREFIX
+					+ src.toString());
 			currentClass = src;
 			while (currentClass != null) {
 				try {
 					currentClass.getMethod("constructFramsClass", Constructor.class).invoke(null, this);
-				} catch (Exception ignored) {
+				} catch (IllegalAccessException | IllegalArgumentException
+						| InvocationTargetException | NoSuchMethodException
+						| SecurityException e) {
+					log.debug("failed to use constructFramsClass static method (skipping): ", e);
 				}
 				currentClass = currentClass.getSuperclass();
@@ -285,5 +295,5 @@
 					if (method.getName().startsWith("get")) {
 						String fieldName = method.getName().substring(3, 4).toLowerCase() + method.getName().substring(4);
-						Param param = new ParamBuilder().setType(returnParamClass).setName(fieldName).setId(fieldName).setHelp(GENERATE_HELP_PREFIX + method.toString()).build();
+						Param param = Param.build().type(returnParamClass).name(fieldName).id(fieldName).help(GENERATE_HELP_PREFIX + method.toString()).finish();
 						assert param != null;
 						result.append(param);
@@ -308,5 +318,5 @@
 					return this;
 				}
-				Param param = new ParamBuilder().setType(paramClass).setName(field.getName()).setId(field.getName()).setHelp(GENERATE_HELP_PREFIX + field.toString()).build();
+				Param param = Param.build().type(paramClass).name(field.getName()).id(field.getName()).help(GENERATE_HELP_PREFIX + field.toString()).finish();
 				assert param != null;
 				result.append(param);
Index: java/main/src/main/java/com/framsticks/params/Param.java
===================================================================
--- java/main/src/main/java/com/framsticks/params/Param.java	(revision 84)
+++ java/main/src/main/java/com/framsticks/params/Param.java	(revision 85)
@@ -105,9 +105,13 @@
 	public static FramsClass getFramsClass() {
 		return new FramsClass("prop", "prop", null)
-				.append(new ParamBuilder().setId("name").setName("Name").setType(StringParam.class).build())
-				.append(new ParamBuilder().setId("id").setName("Id").setType(StringParam.class).build())
-				.append(new ParamBuilder().setId("type").setName("Type").setType(StringParam.class).build())
-				.append(new ParamBuilder().setId("help").setName("Help").setType(StringParam.class).build())
-				.append(new ParamBuilder().setId("flags").setName("Flags").setType(DecimalParam.class).build());
+			.append(Param.build().id("name").name("Name").type(StringParam.class).finish())
+			.append(Param.build().id("id").name("Id").type(StringParam.class).finish())
+			.append(Param.build().id("type").name("Type").type(StringParam.class).finish())
+			.append(Param.build().id("help").name("Help").type(StringParam.class).finish())
+			.append(Param.build().id("flags").name("Flags").type(DecimalParam.class).finish());
+	}
+
+	public static ParamBuilder build() {
+		return new ParamBuilder();
 	}
 
Index: java/main/src/main/java/com/framsticks/params/ParamBuilder.java
===================================================================
--- java/main/src/main/java/com/framsticks/params/ParamBuilder.java	(revision 84)
+++ java/main/src/main/java/com/framsticks/params/ParamBuilder.java	(revision 85)
@@ -55,4 +55,7 @@
 	private PrimitiveParam primitiveParam;
 
+	ParamBuilder() {
+	}
+
 	/**
 	 * Build Param based on provided data.
@@ -62,5 +65,5 @@
 	 *             when Param getType is not defined
 	 */
-	public Param build()  {
+	public Param finish()  {
 		assert param != null;
 		param.id = id;
@@ -73,5 +76,5 @@
 	}
 
-	public ParamBuilder setId(String id) {
+	public ParamBuilder id(String id) {
 		this.id = id;
 		return this;
@@ -87,16 +90,14 @@
 	}
 
-	public <T extends Param> ParamBuilder setType(Class<T> type) {
+	public <T extends Param> ParamBuilder type(Class<T> type) {
 		try {
 			return internalSetType(type, type.newInstance());
-		} catch (InstantiationException e) {
+		} catch (InstantiationException | IllegalAccessException e) {
 			e.printStackTrace();
-		} catch (IllegalAccessException e) {
-			e.printStackTrace();
-		}
-		return this;
-	}
-
-	public <T extends Param> ParamBuilder setType(T param) {
+		}
+		return this;
+	}
+
+	public <T extends Param> ParamBuilder type(T param) {
 		return internalSetType(param.getClass(), param);
 	}
@@ -108,15 +109,15 @@
 	}
 
-	public ParamBuilder setGroup(Integer group) {
+	public ParamBuilder group(Integer group) {
 		this.group = group;
 		return this;
 	}
 
-	public ParamBuilder setFlags(Integer flags) {
+	public ParamBuilder flags(Integer flags) {
 		this.flags = flags;
 		return this;
 	}
 
-	public ParamBuilder setName(String name) {
+	public ParamBuilder name(String name) {
 		this.name = name;
 		return this;
@@ -142,5 +143,5 @@
 	}
 
-	public ParamBuilder setType(String type) {
+	public ParamBuilder type(String type) {
 
 		log.trace("parsing type: " + type);
@@ -153,5 +154,5 @@
 		switch (first.charAt(0)) {
 			case 'o': {
-				setType(new ObjectParam(second != null ? second : first.substring(1)));
+				type(new ObjectParam(second != null ? second : first.substring(1)));
 				break;
 			}
@@ -164,5 +165,5 @@
 					log.error("invalid procedure signature '" + signature + "': " + e);
 				}
-				setType(procedureParam);
+				type(procedureParam);
 				break;
 			}
@@ -171,23 +172,27 @@
 				int tildeIndex = type.indexOf("~");
 				if (tildeIndex != -1) {
-					setType(new EnumParam(new ArrayList<String>(Arrays.asList(type.substring(tildeIndex + 1).split("~")))));
+					type(new EnumParam(new ArrayList<String>(Arrays.asList(type.substring(tildeIndex + 1).split("~")))));
 				} else {
 					if (first.length() >= 2) {
-				switch (first.charAt(1)) {
+						switch (first.charAt(1)) {
 							case 'b': {
-								setType(BinaryParam.class);
+								type(BinaryParam.class);
 								break;
 							}
 							case 'c': {
-								setType(ColorParam.class);
+								type(ColorParam.class);
 								break;
+							}
+							default: {
+								log.error("unknown type: " + first);
+								return this;
 							}
 						}
 					}
 					if ("0".equals(second) && "1".equals(third)) {
-						setType(BooleanParam.class);
+						type(BooleanParam.class);
 					}
 					if (param == null) {
-						setType(DecimalParam.class);
+						type(DecimalParam.class);
 					}
 				}
@@ -198,32 +203,35 @@
 			}
 			case 'f': {
-				setType(FloatParam.class);
+				type(FloatParam.class);
 				parseMinMaxDefNumber(Double.class, second, third);
 				break;
 			}
 			case 'x': {
-				setType(UniversalParam.class);
+				type(UniversalParam.class);
 				break;
 			}
 			case 's': {
-				setType(StringParam.class);
-				setMin(second);
-				setMax(third);
+				type(StringParam.class);
+				min(second);
+				max(third);
 				break;
 			}
 			case 'e': {
-				setType(EventParam.class);
+				type(EventParam.class);
 				break;
 			}
 			case 'l': {
-				setType(third != null ? new UniqueListParam(second, third) : new ArrayListParam(second));
-				break;
-			}
-
-		}
-		return this;
-	}
-
-	public ParamBuilder setHelp(String help) {
+				type(third != null ? new UniqueListParam(second, third) : new ArrayListParam(second));
+				break;
+			}
+			default:{
+				log.error("unknown type: " + first);
+				return this;
+			}
+		}
+		return this;
+	}
+
+	public ParamBuilder help(String help) {
 		this.help = help;
 		return this;
@@ -237,5 +245,5 @@
 	}
 
-	public <T> ParamBuilder setMin(T min) {
+	public <T> ParamBuilder min(T min) {
 		if (primitiveParam != null) {
 			this.primitiveParam.min = min;
@@ -244,5 +252,5 @@
 	}
 
-	public <T> ParamBuilder setMax(T max) {
+	public <T> ParamBuilder max(T max) {
 		if (primitiveParam != null) {
 			this.primitiveParam.max = max;
@@ -251,5 +259,5 @@
 	}
 
-	public <T> ParamBuilder setDef(T def) {
+	public <T> ParamBuilder def(T def) {
 		if (def != null && primitiveParam != null) {
 			this.primitiveParam.def = def;
@@ -277,10 +285,10 @@
 
 		try {
-			setId(paramEntryValues[0]);
-			setGroup(Integer.valueOf(paramEntryValues[1]));
-			setFlags(Flags.read(paramEntryValues[2]));
-			setName(paramEntryValues[3]);
-			setType(paramEntryValues[4]);
-			setHelp(paramEntryValues[6]);
+			id(paramEntryValues[0]);
+			group(Integer.valueOf(paramEntryValues[1]));
+			flags(Flags.read(paramEntryValues[2]));
+			name(paramEntryValues[3]);
+			type(paramEntryValues[4]);
+			help(paramEntryValues[6]);
 		} catch (IndexOutOfBoundsException e) {
 			/** everything is ok, parameters have just finished*/
@@ -290,20 +298,30 @@
 			return null;
 		}
-		return build();
+		return finish();
 	}
 
 	public void setField(String key, String value) {
-		if (key.equals(ID_FIELD)) {
-			setId(value);
-		} else if (key.equals(NAME_FIELD)) {
-			setName(value);
-		} else if (key.equals(TYPE_FIELD)) {
-			setType(value);
-		} else if (key.equals(FLAGS_FIELD)) {
-			setFlags(Flags.read(value));
-		} else if (key.equals(HELP_FIELD)) {
-			setHelp(value);
-		} else if (key.equals(GROUP_FIELD)) {
-			setGroup(Integer.valueOf(value));
+		switch (key) {
+			case ID_FIELD:
+				id(value);
+				break;
+			case NAME_FIELD:
+				name(value);
+				break;
+			case TYPE_FIELD:
+				type(value);
+				break;
+			case FLAGS_FIELD:
+				flags(Flags.read(value));
+				break;
+			case HELP_FIELD:
+				help(value);
+				break;
+			case GROUP_FIELD:
+				group(Integer.valueOf(value));
+				break;
+			default:
+				log.error("unknown field for Param: " + key);
+				break;
 		}
 	}
@@ -312,9 +330,10 @@
 	public static FramsClass getFramsClass() {
 		return new FramsClass("prop", "prop", null)
-				.append(new ParamBuilder().setId("name").setName("Name").setType(StringParam.class).build())
-				.append(new ParamBuilder().setId("id").setName("Id").setType(StringParam.class).build())
-				.append(new ParamBuilder().setId("type").setName("Type").setType(StringParam.class).build())
-				.append(new ParamBuilder().setId("help").setName("Help").setType(StringParam.class).build())
-				.append(new ParamBuilder().setId("flags").setName("Flags").setType(DecimalParam.class).build());
+			.append(Param.build().id("name").name("Name").type(StringParam.class))
+			.append(Param.build().id("id").name("Id").type(StringParam.class))
+			.append(Param.build().id("type").name("Type").type(StringParam.class))
+			.append(Param.build().id("help").name("Help").type(StringParam.class))
+			.append(Param.build().id("group").name("Group").type(DecimalParam.class))
+			.append(Param.build().id("flags").name("Flags").type(DecimalParam.class));
 	}
 
Index: java/main/src/main/java/com/framsticks/params/PropertiesAccess.java
===================================================================
--- java/main/src/main/java/com/framsticks/params/PropertiesAccess.java	(revision 84)
+++ java/main/src/main/java/com/framsticks/params/PropertiesAccess.java	(revision 85)
@@ -40,13 +40,16 @@
 		assert properties != null;
 		assert param != null;
-		Object object = null;
+		Object object = properties.get(param.getId());
+		if (object != null) {
+			try {
+				return type.cast(object);
+			} catch (ClassCastException e) {
+				throw (ClassCastException) new ClassCastException("property " + param + " type is " + object.getClass().getName() + ", not " + type.getName()).initCause(e);
+			}
+		}
 		try {
-			object = properties.get(param.getId());
-			if (object == null) {
-				return param.getDef(type);
-			}
-			return type.cast(object);
+			return param.getDef(type);
 		} catch (ClassCastException e) {
-			throw new ClassCastException("property " + param.getId() + " type is " + object.getClass().getName() + ", not " + type.getName());
+			throw (ClassCastException) new ClassCastException("default value of property " + param + " is not of type " + type.getName()).initCause(e);
 		}
 
Index: java/main/src/main/java/com/framsticks/params/ReflectionAccess.java
===================================================================
--- java/main/src/main/java/com/framsticks/params/ReflectionAccess.java	(revision 84)
+++ java/main/src/main/java/com/framsticks/params/ReflectionAccess.java	(revision 85)
@@ -47,13 +47,16 @@
 			try {
 				return type.cast(reflectedClass.getMethod(accessorName(true, id)).invoke(object));
-			} catch (NoSuchMethodException ex) {
-				//ex.printStackTrace();
-			} catch (InvocationTargetException e) {
+			} catch (NoSuchMethodException | InvocationTargetException ex) {
+				//e.printStackTrace();
+			}
+			try {
+				return type.cast(reflectedClass.getMethod(id).invoke(object));
+			} catch (NoSuchMethodException | InvocationTargetException ex) {
 				//e.printStackTrace();
 			}
 
-		} catch (IllegalAccessException ex) {
+		} catch (IllegalAccessException e) {
 			log.warn("illegal access error occurred while trying to access returnedObject");
-			ex.printStackTrace();
+			e.printStackTrace();
 		} catch (ClassCastException ignored) {
 
@@ -87,6 +90,9 @@
 			try {
 				reflectedClass.getMethod(accessorName(false, id), new Class[]{param.getStorageType()}).invoke(object, value);
-			} catch (InvocationTargetException ignored) {
-			} catch (NoSuchMethodException ignored) {
+			} catch (InvocationTargetException | NoSuchMethodException ignored) {
+			}
+			try {
+				reflectedClass.getMethod(id, new Class[]{param.getStorageType()}).invoke(object, value);
+			} catch (InvocationTargetException | NoSuchMethodException ignored) {
 			}
 		} catch (Exception ex) {
@@ -161,7 +167,5 @@
 		try {
 			return reflectedClass.newInstance();
-		} catch (InstantiationException e) {
-			e.printStackTrace();
-		} catch (IllegalAccessException e) {
+		} catch (InstantiationException | IllegalAccessException e) {
 			e.printStackTrace();
 		}
Index: java/main/src/main/java/com/framsticks/params/UniqueListAccess.java
===================================================================
--- java/main/src/main/java/com/framsticks/params/UniqueListAccess.java	(revision 84)
+++ java/main/src/main/java/com/framsticks/params/UniqueListAccess.java	(revision 85)
@@ -35,5 +35,5 @@
 		//log.error("accesing unique list through index");
 		//return null;
-		//return new ParamBuilder().setId(Integer.toString(i)).setName(elementAccess.getId()).setType("o " + elementAccess.getId()).build();
+		//return Param.build().setId(Integer.toString(i)).setName(elementAccess.getId()).type("o " + elementAccess.getId()).build();
 	}
 
@@ -44,5 +44,5 @@
 			return getParam(i);
 		}
-		return new ParamBuilder().setId(id).setName(elementAccess.getId()).setType("o " + elementAccess.getId()).build();
+		return Param.build().id(id).name(elementAccess.getId()).type("o " + elementAccess.getId()).finish();
 	}
 
Index: java/main/src/main/java/com/framsticks/params/types/ProcedureParam.java
===================================================================
--- java/main/src/main/java/com/framsticks/params/types/ProcedureParam.java	(revision 84)
+++ java/main/src/main/java/com/framsticks/params/types/ProcedureParam.java	(revision 85)
@@ -2,5 +2,4 @@
 
 import com.framsticks.params.Param;
-import com.framsticks.params.ParamBuilder;
 import com.framsticks.util.lang.Strings;
 
@@ -20,5 +19,5 @@
 
 	protected static Param parseType(String type, String name) {
-		return new ParamBuilder().setType(type).setName(name).build();
+		return Param.build().type(type).name(name).finish();
 	}
 
Index: java/main/src/main/java/com/framsticks/parsers/F0Parser.java
===================================================================
--- java/main/src/main/java/com/framsticks/parsers/F0Parser.java	(revision 84)
+++ java/main/src/main/java/com/framsticks/parsers/F0Parser.java	(revision 85)
@@ -84,7 +84,5 @@
 			ParseException {
 
-		InputStreamReader reader = null;
-		try {
-			reader = new InputStreamReader(is, "UTF-8");
+		try (InputStreamReader reader = new InputStreamReader(is, "UTF-8")) {
 			BufferedReader br = new BufferedReader(reader);
 			while (br.ready()) {
@@ -114,8 +112,4 @@
 			if (result.isEmpty() || !(result.get(0) instanceof Model)) {
 				result.add(0, processLine("m:"));
-			}
-		} finally {
-			if (reader != null) {
-				reader.close();
 			}
 		}
Index: java/main/src/main/java/com/framsticks/parsers/F0Writer.java
===================================================================
--- java/main/src/main/java/com/framsticks/parsers/F0Writer.java	(revision 84)
+++ java/main/src/main/java/com/framsticks/parsers/F0Writer.java	(revision 85)
@@ -15,5 +15,5 @@
 	protected final SinkInterface sink;
 	protected final Model model;
-	protected boolean omit = true;
+	protected boolean omitDefaults = true;
 
 	public F0Writer(Schema schema, Model model, SinkInterface sink) {
@@ -23,6 +23,6 @@
 	}
 
-	F0Writer omitDefaultValues(boolean omit) {
-		this.omit = omit;
+	public F0Writer setOmitDefaults(boolean omitDefaults) {
+		this.omitDefaults = omitDefaults;
 		return this;
 	}
@@ -49,5 +49,5 @@
 			}
 			Object value = access.get(param, Object.class);
-			if ((param instanceof PrimitiveParam) && Misc.equals(value, ((PrimitiveParam) param).getDef(Object.class))) {
+			if (omitDefaults && (param instanceof PrimitiveParam) && Misc.equals(value, ((PrimitiveParam) param).getDef(Object.class))) {
 				contiguous = false;
 				continue;
Index: java/main/src/main/java/com/framsticks/parsers/FileSource.java
===================================================================
--- java/main/src/main/java/com/framsticks/parsers/FileSource.java	(revision 84)
+++ java/main/src/main/java/com/framsticks/parsers/FileSource.java	(revision 85)
@@ -2,4 +2,5 @@
 
 import com.framsticks.params.SourceInterface;
+import com.framsticks.util.io.Encoding;
 
 import java.io.*;
@@ -8,21 +9,22 @@
 public class FileSource implements SourceInterface {
 
-	private BufferedReader reader;
-	private String filename;
-	
-	public FileSource(String filename) throws IOException
-	{
+	private final BufferedReader reader;
+	private final String filename;
+
+	protected FileSource(InputStream stream, String filename) {
 		this.filename = filename;
-        reader = new BufferedReader(new FileReader(filename));
+		this.reader = new BufferedReader(new InputStreamReader(stream, Encoding.getFramsticksCharset()));
+	}
+
+	public FileSource(String filename) throws IOException {
+		this(new FileInputStream(filename), filename);
 	}
 
 	public FileSource(InputStream stream) {
-		filename = "<stream>";
-		reader = new BufferedReader(new InputStreamReader(stream));
+		this(stream, "<stream>");
 	}
 
-
-    @Override
-    public String readLine()
+	@Override
+	public String readLine()
 	{
 		try
@@ -35,12 +37,12 @@
 	}
 
-    @Override
-    public String getFilename()
+	@Override
+	public String getFilename()
 	{
 		return filename;
 	}
 
-    @Override
-    public String demangleInclude(String include)
+	@Override
+	public String demangleInclude(String include)
 	{
 		if (!include.contains(java.io.File.separator)) {
@@ -52,10 +54,10 @@
 			}
 			include = currentFilePath + include;
-		}	
+		}
 		return include;
 	}
 
-    @Override
-    public SourceInterface openInclude(String include)
+	@Override
+	public SourceInterface openInclude(String include)
 	{
 		try
@@ -65,18 +67,18 @@
 		catch(IOException e)
 		{
-			
+
 		}
 		return null;
 	}
 
-    @Override
-    public void close()
+	@Override
+	public void close()
 	{
 		try {
 			reader.close();
 		} catch (IOException e) {
-			
+
 		}
 	}
-	
+
 }
Index: java/main/src/main/java/com/framsticks/parsers/GenotypeLoader.java
===================================================================
--- java/main/src/main/java/com/framsticks/parsers/GenotypeLoader.java	(revision 84)
+++ java/main/src/main/java/com/framsticks/parsers/GenotypeLoader.java	(revision 85)
@@ -22,34 +22,34 @@
 		//getId, group-number, getFlags, getName, getType(getType min max), getHelp
 		entries
-			.append(new ParamBuilder().setId("name").setGroup(0).setName("Name").setType(new StringParam()).setMin(0).setMax(40).build())
-			.append(new ParamBuilder().setId("genotype").setGroup(0).setName("Genotype").setType(new StringParam()).setMin(1).build())
-			.append(new ParamBuilder().setId("info").setGroup(0).setName("Info").setType(new StringParam()).setMin(1).setHelp("Additional information or comments").build())
-			.append(new ParamBuilder().setId("simi").setGroup(1).setFlags(Flags.READONLY | Flags.DONTSAVE).setName("Similarity").setType(new FloatParam()).build())
-			.append(new ParamBuilder().setId("energ0").setGroup(1).setFlags(Flags.READONLY | Flags.DONTSAVE).setName("Starting energy").setType(new FloatParam()).build())
-			.append(new ParamBuilder().setId("strsiz").setGroup(1).setFlags(Flags.READONLY | Flags.DONTSAVE | Flags.USERHIDDEN).setName("Body parts (deprecated; use numparts)").setType(new FloatParam()).build())
-			.append(new ParamBuilder().setId("strjoints").setGroup(1).setFlags(Flags.READONLY | Flags.DONTSAVE | Flags.USERHIDDEN).setName("Body joints (deprecated; use numjoints)").setType(new FloatParam()).build())
-			.append(new ParamBuilder().setId("nnsiz").setGroup(1).setFlags(Flags.READONLY | Flags.DONTSAVE | Flags.USERHIDDEN).setName("Brain size (deprecated; use numneurons)").setType(new FloatParam()).build())
-			.append(new ParamBuilder().setId("nncon").setGroup(1).setFlags(Flags.READONLY | Flags.DONTSAVE | Flags.USERHIDDEN).setName("Brain connections (deprecated; use numconnections)").setType(new FloatParam()).build())
-			.append(new ParamBuilder().setId("numparts").setGroup(1).setFlags(Flags.READONLY | Flags.DONTSAVE).setName("Body parts").setType(new FloatParam()).build())
-			.append(new ParamBuilder().setId("numjoints").setGroup(1).setFlags(Flags.READONLY | Flags.DONTSAVE).setName("Body joints").setType(new FloatParam()).build())
-			.append(new ParamBuilder().setId("numneurons").setGroup(1).setFlags(Flags.READONLY | Flags.DONTSAVE).setName("Brain size").setType(new FloatParam()).build())
-			.append(new ParamBuilder().setId("numconnections").setGroup(1).setFlags(Flags.READONLY | Flags.DONTSAVE).setName("Brain connections").setType(new FloatParam()).build())
-			.append(new ParamBuilder().setId("num").setGroup(2).setName("Ordinal number").setType(new DecimalParam()).build())
-			.append(new ParamBuilder().setId("gnum").setGroup(2).setName("Generation").setType(new DecimalParam()).build())
-			.append(new ParamBuilder().setId("popsiz").setGroup(2).setFlags(Flags.USERHIDDEN).setName("Deprecated; use entities").setType(new DecimalParam()).build())
-			.append(new ParamBuilder().setId("entities").setGroup(2).setFlags(Flags.DONTSAVE).setName("Instances").setType(new DecimalParam()).setHelp("Copies of this genotype").build())
-			.append(new ParamBuilder().setId("lifespan").setGroup(2).setName("Life span").setType(new FloatParam()).setHelp("Average life span").build())
-			.append(new ParamBuilder().setId("velocity").setGroup(2).setName("Velocity").setType(new FloatParam()).setHelp("Average velocity").build())
-			.append(new ParamBuilder().setId("distance").setGroup(2).setName("Distance").setType(new FloatParam()).build())
-			.append(new ParamBuilder().setId("vertvel").setGroup(2).setName("Vertical velocity").setType(new FloatParam()).build())
-			.append(new ParamBuilder().setId("vertpos").setGroup(2).setName("Vertical position").setType(new FloatParam()).build())
-			.append(new ParamBuilder().setId("fit").setGroup(3).setFlags(Flags.READONLY | Flags.DONTSAVE).setName("Fitness").setType(new FloatParam()).build())
-			.append(new ParamBuilder().setId("fit2").setGroup(3).setFlags(Flags.READONLY | Flags.DONTSAVE).setName("Final fitness").setType(new FloatParam()).setHelp("Fitness shifted by (avg-n*stddev)").build())
-			.append(new ParamBuilder().setId("f0genotype").setGroup(4).setFlags(Flags.READONLY | Flags.DONTSAVE).setName("f0 genotype").setType(new StringParam()).setMin(1).setHelp("converted to f0 genotype").build())
-			.append(new ParamBuilder().setId("user1").setGroup(2).setName("User field 1").setType(new UniversalParam()).build())
-			.append(new ParamBuilder().setId("user2").setGroup(2).setName("User field 2").setType(new UniversalParam()).build())
-			.append(new ParamBuilder().setId("user3").setGroup(2).setName("User field 3").setType(new UniversalParam()).build())
-			.append(new ParamBuilder().setId("isValid").setGroup(0).setFlags(Flags.READONLY | Flags.DONTSAVE | Flags.USERHIDDEN).setName("Valid").setType(new DecimalParam()).setMin(0).setMax(1).build())
-			.append(new ParamBuilder().setId("uid").setGroup(0).setFlags(Flags.READONLY | Flags.USERHIDDEN).setName("#").setType("s").setHelp("Unique identifier").build());
+			.append(Param.build().id("name").group(0).name("Name").type(StringParam.class).min(0).max(40))
+			.append(Param.build().id("genotype").group(0).name("Genotype").type(StringParam.class).min(1))
+			.append(Param.build().id("info").group(0).name("Info").type(StringParam.class).min(1).help("Additional information or comments"))
+			.append(Param.build().id("simi").group(1).flags(Flags.READONLY | Flags.DONTSAVE).name("Similarity").type(FloatParam.class))
+			.append(Param.build().id("energ0").group(1).flags(Flags.READONLY | Flags.DONTSAVE).name("Starting energy").type(FloatParam.class))
+			.append(Param.build().id("strsiz").group(1).flags(Flags.READONLY | Flags.DONTSAVE | Flags.USERHIDDEN).name("Body parts (deprecated; use numparts)").type(FloatParam.class))
+			.append(Param.build().id("strjoints").group(1).flags(Flags.READONLY | Flags.DONTSAVE | Flags.USERHIDDEN).name("Body joints (deprecated; use numjoints)").type(FloatParam.class))
+			.append(Param.build().id("nnsiz").group(1).flags(Flags.READONLY | Flags.DONTSAVE | Flags.USERHIDDEN).name("Brain size (deprecated; use numneurons)").type(FloatParam.class))
+			.append(Param.build().id("nncon").group(1).flags(Flags.READONLY | Flags.DONTSAVE | Flags.USERHIDDEN).name("Brain connections (deprecated; use numconnections)").type(FloatParam.class))
+			.append(Param.build().id("numparts").group(1).flags(Flags.READONLY | Flags.DONTSAVE).name("Body parts").type(FloatParam.class))
+			.append(Param.build().id("numjoints").group(1).flags(Flags.READONLY | Flags.DONTSAVE).name("Body joints").type(FloatParam.class))
+			.append(Param.build().id("numneurons").group(1).flags(Flags.READONLY | Flags.DONTSAVE).name("Brain size").type(FloatParam.class))
+			.append(Param.build().id("numconnections").group(1).flags(Flags.READONLY | Flags.DONTSAVE).name("Brain connections").type(FloatParam.class))
+			.append(Param.build().id("num").group(2).name("Ordinal number").type(DecimalParam.class))
+			.append(Param.build().id("gnum").group(2).name("Generation").type(DecimalParam.class))
+			.append(Param.build().id("popsiz").group(2).flags(Flags.USERHIDDEN).name("Deprecated; use entities").type(DecimalParam.class))
+			.append(Param.build().id("entities").group(2).flags(Flags.DONTSAVE).name("Instances").type(DecimalParam.class).help("Copies of this genotype"))
+			.append(Param.build().id("lifespan").group(2).name("Life span").type(FloatParam.class).help("Average life span"))
+			.append(Param.build().id("velocity").group(2).name("Velocity").type(FloatParam.class).help("Average velocity"))
+			.append(Param.build().id("distance").group(2).name("Distance").type(FloatParam.class))
+			.append(Param.build().id("vertvel").group(2).name("Vertical velocity").type(FloatParam.class))
+			.append(Param.build().id("vertpos").group(2).name("Vertical position").type(FloatParam.class))
+			.append(Param.build().id("fit").group(3).flags(Flags.READONLY | Flags.DONTSAVE).name("Fitness").type(FloatParam.class))
+			.append(Param.build().id("fit2").group(3).flags(Flags.READONLY | Flags.DONTSAVE).name("Final fitness").type(FloatParam.class).help("Fitness shifted by (avg-n*stddev)"))
+			.append(Param.build().id("f0genotype").group(4).flags(Flags.READONLY | Flags.DONTSAVE).name("f0 genotype").type(StringParam.class).min(1).help("converted to f0 genotype"))
+			.append(Param.build().id("user1").group(2).name("User field 1").type(UniversalParam.class))
+			.append(Param.build().id("user2").group(2).name("User field 2").type(UniversalParam.class))
+			.append(Param.build().id("user3").group(2).name("User field 3").type(UniversalParam.class))
+			.append(Param.build().id("isValid").group(0).flags(Flags.READONLY | Flags.DONTSAVE | Flags.USERHIDDEN).name("Valid").type(DecimalParam.class).min(0).max(1))
+			.append(Param.build().id("uid").group(0).flags(Flags.READONLY | Flags.USERHIDDEN).name("#").type("s").help("Unique identifier"));
 
 		ReflectionAccess reflectionParam = new ReflectionAccess(Genotype.class, entries);
Index: java/main/src/main/java/com/framsticks/parsers/Loaders.java
===================================================================
--- java/main/src/main/java/com/framsticks/parsers/Loaders.java	(revision 84)
+++ java/main/src/main/java/com/framsticks/parsers/Loaders.java	(revision 85)
@@ -35,5 +35,5 @@
 					}
 					if (object instanceof ParamBuilder) {
-						result.append(((ParamBuilder) object).build());
+						result.append(((ParamBuilder) object).finish());
 					}
 				}
Index: java/main/src/main/java/com/framsticks/parsers/Schema.java
===================================================================
--- java/main/src/main/java/com/framsticks/parsers/Schema.java	(revision 84)
+++ java/main/src/main/java/com/framsticks/parsers/Schema.java	(revision 85)
@@ -26,5 +26,5 @@
  * classes definitions that can be used in f0 representation). Definitions are
  * loaded from XML stream.
- * 
+ *
  * @author Jarek Szymczak <name.surname@gmail.com>
  * (please replace name and surname with my personal data)
@@ -46,5 +46,5 @@
 	/**
 	 * Instantiates a new schema.
-	 * 
+	 *
 	 * @param inputStream
 	 *            the xml stream with schema
@@ -104,11 +104,5 @@
 			}
 
-		} catch (IOException e) {
-			logger.fatal("unexpected exception occurred: ", e);
-			throw e;
-		} catch (ParserConfigurationException e) {
-			logger.fatal("unexpected exception occurred: ", e);
-			throw e;
-		} catch (SAXException e) {
+		} catch (IOException | ParserConfigurationException | SAXException e) {
 			logger.fatal("unexpected exception occurred: ", e);
 			throw e;
@@ -121,7 +115,7 @@
 	 * node under certain attribute getName. If value is not present or is other
 	 * getType than integer 0 is returned.
-	 * 
+	 *
 	 * @return attribute value if value exists and it's integer (0 otherwise)
-	 * 
+	 *
 	 */
 	private static int getIntAttribute(NamedNodeMap attributes, String name) {
@@ -152,5 +146,5 @@
 	 * Method used for convenience, it retrieves the value stored in node under
 	 * certain attribute getName. If value is not present method returns null.
-	 * 
+	 *
 	 * @param attributeName
 	 *            the attribute getName
@@ -158,5 +152,5 @@
 	 *            the node
 	 * @return attribute value if value exists (null otherwise)
-	 * 
+	 *
 	 */
 	private static String getAttributeFromNode(String attributeName, Node node) {
@@ -169,5 +163,5 @@
 	/**
 	 * In this method analysis of single class is performed.
-	 * 
+	 *
 	 * @param classNode
 	 *            the class node
@@ -228,5 +222,5 @@
 	/**
 	 * It analyses the single property within the class
-	 * 
+	 *
 	 * @param attributes
 	 *            the attributes of property
@@ -267,26 +261,26 @@
 		}
 
-		ParamBuilder builder = new ParamBuilder();
-		builder.setId(id).setName(name).setHelp(description).setGroup(group).setFlags(flags);
-
-		builder.setType(type);
+		ParamBuilder builder = Param.build();
+		builder.id(id).name(name).help(description).group(group).flags(flags);
+
+		builder.type(type);
 
 		if ("d".equals(type)) {
-			builder.setMin(extractAttribute(attributes, "MIN", Integer.class));
-			builder.setMax(extractAttribute(attributes, "MAX", Integer.class));
-			builder.setDef(extractAttribute(attributes, "DEF", Integer.class));
+			builder.min(extractAttribute(attributes, "MIN", Integer.class));
+			builder.max(extractAttribute(attributes, "MAX", Integer.class));
+			builder.def(extractAttribute(attributes, "DEF", Integer.class));
 		} else if ("f".equals(type)) {
-			builder.setMin(extractAttribute(attributes, "MIN", Double.class));
-			builder.setMax(extractAttribute(attributes, "MAX", Double.class));
-			builder.setDef(extractAttribute(attributes, "DEF", Double.class));
+			builder.min(extractAttribute(attributes, "MIN", Double.class));
+			builder.max(extractAttribute(attributes, "MAX", Double.class));
+			builder.def(extractAttribute(attributes, "DEF", Double.class));
 		} else if ("s".equals(type)) {
-			builder.setMin(extractAttribute(attributes, "MIN", Integer.class));
-			builder.setMax(extractAttribute(attributes, "MAX", Integer.class));
-			builder.setDef(extractAttribute(attributes, "DEF", Integer.class));
-			builder.setDef(getAttribute(attributes, "DEF"));
+			builder.min(extractAttribute(attributes, "MIN", Integer.class));
+			builder.max(extractAttribute(attributes, "MAX", Integer.class));
+			builder.def(extractAttribute(attributes, "DEF", Integer.class));
+			builder.def(getAttribute(attributes, "DEF"));
 		} else {
-			builder.setType(type);
-		}
-		return builder.build();
+			builder.type(type);
+		}
+		return builder.finish();
 	}
 
Index: java/main/src/main/java/com/framsticks/portals/Portal.java
===================================================================
--- java/main/src/main/java/com/framsticks/portals/Portal.java	(revision 84)
+++ java/main/src/main/java/com/framsticks/portals/Portal.java	(revision 85)
@@ -22,5 +22,5 @@
 	public void run() {
 		super.run();
-		new PeriodicTask(this, 1000) {
+		new PeriodicTask<Portal>(this, 1000) {
 
 			@Override
Index: java/main/src/main/java/com/framsticks/portals/PortalEndpoint.java
===================================================================
--- java/main/src/main/java/com/framsticks/portals/PortalEndpoint.java	(revision 84)
+++ java/main/src/main/java/com/framsticks/portals/PortalEndpoint.java	(revision 85)
@@ -1,4 +1,5 @@
 package com.framsticks.portals;
 
+import com.framsticks.core.Instance;
 import com.framsticks.core.Path;
 import com.framsticks.observers.Endpoint;
@@ -7,4 +8,5 @@
 import com.framsticks.util.Logging;
 import org.apache.log4j.Logger;
+import com.framsticks.util.dispatching.RunAt;
 
 /**
@@ -18,48 +20,48 @@
 	}
 
-    @Override
-    public Portal getObserver() {
-        return (Portal) observer;
-    }
+	@Override
+	public Portal getObserver() {
+		return (Portal) observer;
+	}
 
-    @Override
-    public void onRun(Exception e) {
-        assert Dispatching.isThreadSafe();
+	@Override
+	public void onRun(Exception e) {
+		assert Dispatching.isThreadSafe();
 
-        super.onRun(e);
+		super.onRun(e);
 
-        if (e != null) {
-            return;
-        }
-        final String path = "/simulator/genepools/groups/0/genotypes";
-        instance.invokeLater(new Runnable() {
-            @Override
-            public void run() {
-                PortalEndpoint.this.instance.resolve(path, new Future<Path>() {
-                    @Override
-                    public void result(Path result, Exception e) {
-                        Logging.log(log, "resolve", path, e);
-                    }
-                });
-            }
-        });
-    }
+		if (e != null) {
+			return;
+		}
+		final String path = "/simulator/genepools/groups/0/genotypes";
+		instance.invokeLater(new RunAt<Instance>() {
+			@Override
+			public void run() {
+				PortalEndpoint.this.instance.resolve(path, new Future<Path>() {
+					@Override
+					public void result(Path result, Exception e) {
+						Logging.log(log, "resolve", path, e);
+					}
+				});
+			}
+		});
+	}
 
-    @Override
-    public void onStop(Exception e) {
-    }
+	@Override
+	public void onStop(Exception e) {
+	}
 
 
-    /*@Override
-    public void onChange(final Path path) {
-        //if path.getTop().getParam().
-        observer.invokeLater(new Runnable() {
-            @Override
-            public void run() {
-                log.debug("change at " + path);
-            }
-        });
-    }
-    */
+	/*@Override
+	public void onChange(final Path path) {
+		//if path.getTop().getParam().
+		observer.invokeLater(new Runnable() {
+			@Override
+			public void run() {
+				log.debug("change at " + path);
+			}
+		});
+	}
+	*/
 
 
Index: java/main/src/main/java/com/framsticks/remote/RecursiveFetcher.java
===================================================================
--- java/main/src/main/java/com/framsticks/remote/RecursiveFetcher.java	(revision 84)
+++ java/main/src/main/java/com/framsticks/remote/RecursiveFetcher.java	(revision 85)
@@ -12,4 +12,5 @@
 import org.apache.log4j.Logger;
 import static com.framsticks.util.lang.Containers.filterInstanceof;
+import com.framsticks.util.dispatching.RunAt;
 
 /**
@@ -51,5 +52,5 @@
 				if (childPath.isResolved() && instance.getInfoFromCache(childPath) != null) {
 					++dispatched;
-					instance.invokeLater(new Runnable() {
+					instance.invokeLater(new RunAt<Instance>() {
 						@Override
 						public void run() {
Index: java/main/src/main/java/com/framsticks/remote/RemoteInstance.java
===================================================================
--- java/main/src/main/java/com/framsticks/remote/RemoteInstance.java	(revision 84)
+++ java/main/src/main/java/com/framsticks/remote/RemoteInstance.java	(revision 85)
@@ -17,4 +17,5 @@
 import com.framsticks.util.lang.Casting;
 import com.framsticks.util.lang.Pair;
+import com.framsticks.util.dispatching.RunAt;
 
 import org.apache.commons.configuration.Configuration;
@@ -33,8 +34,8 @@
 	protected ClientConnection connection;
 
-	protected final Set<Pair<Path, Subscription>> subscriptions = new HashSet<Pair<Path, Subscription>>();
-
-	public Pair<Path, Subscription> getSubscription(Path path) {
-		for (Pair<Path, Subscription> s : subscriptions) {
+	protected final Set<Pair<Path, Subscription<?>>> subscriptions = new HashSet<>();
+
+	public Pair<Path, Subscription<?>> getSubscription(Path path) {
+		for (Pair<Path, Subscription<?>> s : subscriptions) {
 			if (s.first.matches(path)) {
 				return s;
@@ -67,5 +68,5 @@
 						}
 
-						invokeLater(new Runnable() {
+						invokeLater(new RunAt<Instance>() {
 							@Override
 							public void run() {
@@ -85,8 +86,8 @@
 										EventParam param = getParam(simulator, "running_changed", EventParam.class);
 										assert param != null;
-										connection.subscribe(simulator.getTextual() + "/" + param.getId(), new LoggingSubscriptionCallback(log, "server running state change", new EventCallback() {
+										connection.subscribe(simulator.getTextual() + "/" + param.getId(), RemoteInstance.this, new LoggingSubscriptionCallback<Instance>(log, "server running state change", new EventCallback() {
 											@Override
 											public void call(List<File> files) {
-												invokeLater(new Runnable() {
+												invokeLater(new RunAt<Instance>() {
 													@Override
 													public void run() {
@@ -96,5 +97,5 @@
 											}
 										}));
-										new PeriodicTask(RemoteInstance.this, 1000) {
+										new PeriodicTask<Instance>(RemoteInstance.this, 1000) {
 											@Override
 											public void run() {
@@ -187,5 +188,5 @@
 		assert param != null;
 		assert path.isResolved();
-		connection.send(new GetRequest().setField(param.getId()).setPath(path.getTextual()), this, new ResponseCallback() {
+		connection.send(new GetRequest().field(param.getId()).path(path.getTextual()), this, new ResponseCallback<Instance>() {
 			@Override
 			public void process(Response response) {
@@ -232,5 +233,5 @@
 
 		//TODO: if the info is in the cache, then don't communicate
-		connection.send(new InfoRequest().setPath(path.getTextual()), this, new ResponseCallback() {
+		connection.send(new InfoRequest().path(path.getTextual()), this, new ResponseCallback<Instance>() {
 			@Override
 			public void process(Response response) {
@@ -268,5 +269,5 @@
 
 		log.trace("fetching values for " + path);
-		connection.send(new GetRequest().setPath(path.getTextual()), this, new ResponseCallback() {
+		connection.send(new GetRequest().path(path.getTextual()), this, new ResponseCallback<Instance>() {
 			@Override
 			public void process(Response response) {
@@ -344,10 +345,10 @@
 		}
 
-		final Pair<Path, Subscription> temporary = new Pair<Path, Subscription>(path, null);
+		final Pair<Path, Subscription<?>> temporary = new Pair<>(path, null);
 		subscriptions.add(temporary);
 
-		connection.subscribe(path.getTextual() + "_changed", new SubscriptionCallback() {
-			@Override
-			public EventCallback subscribed(final Subscription subscription) {
+		connection.subscribe(path.getTextual() + "_changed", this, new SubscriptionCallback<Instance>() {
+			@Override
+			public EventCallback subscribed(final Subscription<? super Instance> subscription) {
 				if (subscription == null) {
 					log.error("failed to subscribe for change event for " + path);
@@ -355,10 +356,10 @@
 				}
 				log.debug("subscribed for change event for " + path);
-				subscription.setDispatcher(RemoteInstance.this);
-				RemoteInstance.this.invokeLater(new Runnable() {
+				// subscription.setDispatcher(RemoteInstance.this);
+				RemoteInstance.this.invokeLater(new RunAt<Instance>() {
 					@Override
 					public void run() {
 						subscriptions.remove(temporary);
-						subscriptions.add(new Pair<Path, Subscription>(path, subscription));
+						subscriptions.add(new Pair<Path, Subscription<?>>(path, subscription));
 					}
 				});
@@ -459,5 +460,5 @@
 
 		log.trace("storing value " + param + " for " + path);
-		connection.send(new SetRequest().value(value.toString()).setField(param.getId()).setPath(path.getTextual()), this, new StateCallback() {
+		connection.send(new SetRequest().value(value.toString()).field(param.getId()).path(path.getTextual()), this, new StateCallback<Instance>() {
 			@Override
 			public void call(Exception e) {
Index: java/main/src/main/java/com/framsticks/util/PeriodicTask.java
===================================================================
--- java/main/src/main/java/com/framsticks/util/PeriodicTask.java	(revision 84)
+++ java/main/src/main/java/com/framsticks/util/PeriodicTask.java	(revision 85)
@@ -3,28 +3,29 @@
 import com.framsticks.util.dispatching.Dispatcher;
 import com.framsticks.util.dispatching.Task;
+import com.framsticks.util.dispatching.RunAt;
 
 /**
  * @author Piotr Sniegowski
  */
-public abstract class PeriodicTask implements Runnable {
+public abstract class PeriodicTask<C> extends RunAt<C> {
 
-    protected final long period;
-    protected Dispatcher dispatcher;
+	protected final long period;
+	protected Dispatcher<? super C> dispatcher;
 
-    public PeriodicTask(Dispatcher dispatcher, long period) {
-        this.period = period;
-        this.dispatcher = dispatcher;
-        dispatcher.invokeLater(this);
-    }
+	public PeriodicTask(Dispatcher<? super C> dispatcher, long period) {
+		this.period = period;
+		this.dispatcher = dispatcher;
+		dispatcher.invokeLater(this);
+	}
 
 
-    public void again() {
-        dispatcher.invokeLater(new Task(System.currentTimeMillis() + period) {
-            @Override
-            public void run() {
-                PeriodicTask.this.run();
-            }
-        });
-    }
+	public void again() {
+		dispatcher.invokeLater(new Task<C>(System.currentTimeMillis() + period) {
+			@Override
+			public void run() {
+				PeriodicTask.this.run();
+			}
+		});
+	}
 
 }
Index: java/main/src/main/java/com/framsticks/util/StateFunctor.java
===================================================================
--- java/main/src/main/java/com/framsticks/util/StateFunctor.java	(revision 84)
+++ java/main/src/main/java/com/framsticks/util/StateFunctor.java	(revision 85)
@@ -5,4 +5,5 @@
  */
 public interface StateFunctor {
+	//TODO RunAt
 	public void call(Exception e);
 }
Index: java/main/src/main/java/com/framsticks/util/dispatching/AtOnceDispatcher.java
===================================================================
--- java/main/src/main/java/com/framsticks/util/dispatching/AtOnceDispatcher.java	(revision 84)
+++ java/main/src/main/java/com/framsticks/util/dispatching/AtOnceDispatcher.java	(revision 85)
@@ -4,16 +4,22 @@
  * @author Piotr Sniegowski
  */
-public class AtOnceDispatcher implements Dispatcher {
+public class AtOnceDispatcher<C> implements Dispatcher<C> {
 
-    public static final AtOnceDispatcher instance = new AtOnceDispatcher();
+	@SuppressWarnings("rawtypes")
+	protected static final AtOnceDispatcher instance = new AtOnceDispatcher();
 
-    @Override
-    public final boolean isActive() {
-        return true;
-    }
+	@SuppressWarnings("unchecked")
+	public static <C> Dispatcher<C> getInstance() {
+		return (Dispatcher<C>) instance;
+	}
 
-    @Override
-    public final void invokeLater(Runnable runnable) {
-        runnable.run();
-    }
+	@Override
+	public final boolean isActive() {
+		return true;
+	}
+
+	@Override
+	public final void invokeLater(RunAt<? extends C> runnable) {
+		runnable.run();
+	}
 }
Index: java/main/src/main/java/com/framsticks/util/dispatching/Dispatcher.java
===================================================================
--- java/main/src/main/java/com/framsticks/util/dispatching/Dispatcher.java	(revision 84)
+++ java/main/src/main/java/com/framsticks/util/dispatching/Dispatcher.java	(revision 85)
@@ -4,6 +4,6 @@
  * @author Piotr Sniegowski
  */
-public interface Dispatcher {
-    public boolean isActive();
-    public void invokeLater(Runnable runnable);
+public interface Dispatcher<C> {
+	public boolean isActive();
+	public void invokeLater(RunAt<? extends C> runnable);
 }
Index: java/main/src/main/java/com/framsticks/util/dispatching/Dispatching.java
===================================================================
--- java/main/src/main/java/com/framsticks/util/dispatching/Dispatching.java	(revision 84)
+++ java/main/src/main/java/com/framsticks/util/dispatching/Dispatching.java	(revision 85)
@@ -8,38 +8,39 @@
 public abstract class Dispatching {
 
-    public static boolean isThreadSafe() {
-        return true;
-    }
+	public static boolean isThreadSafe() {
+		return true;
+	}
 
-    public static void invokeLaterOrNow(Dispatcher dispatcher, Runnable runnable) {
-        if (dispatcher.isActive()) {
-            runnable.run();
-            return;
-        }
-        dispatcher.invokeLater(runnable);
-    }
+	public static <C> void invokeLaterOrNow(Dispatcher<C> dispatcher, RunAt<? extends C> runnable) {
+		if (dispatcher.isActive()) {
+			runnable.run();
+			return;
+		}
+		dispatcher.invokeLater(runnable);
+	}
 
-    public static void dispatchOk(Dispatcher dispatcher, final StateFunctor stateFunctor) {
-        dispatcher.invokeLater(new Runnable() {
-            @Override
-            public void run() {
-                stateFunctor.call(null);
-            }
-        });
-    }
+	//TODO RunAt StateFunctor
+	public static <C> void dispatchOk(Dispatcher<C> dispatcher, final StateFunctor stateFunctor) {
+		dispatcher.invokeLater(new RunAt<C>() {
+			@Override
+			public void run() {
+				stateFunctor.call(null);
+			}
+		});
+	}
 
-    public static boolean assertInvokeLater(Dispatcher dispatcher, Runnable runnable) {
-        dispatcher.invokeLater(runnable);
-        return true;
-    }
+	// public static boolean assertInvokeLater(Dispatcher dispatcher, RunAt runnable) {
+	// 	dispatcher.invokeLater(runnable);
+	// 	return true;
+	// }
 
-    public static void invokeDispatch(Dispatcher dispatcher, final Dispatcher finalDispatcher, final Runnable runnable) {
-        dispatcher.invokeLater(new Runnable() {
-            @Override
-            public void run() {
-                finalDispatcher.invokeLater(runnable);
-            }
-        });
-    }
+	public static <P, C> void invokeDispatch(Dispatcher<P> dispatcher, final Dispatcher<C> finalDispatcher, final RunAt<C> runnable) {
+		dispatcher.invokeLater(new RunAt<P>() {
+			@Override
+			public void run() {
+				finalDispatcher.invokeLater(runnable);
+			}
+		});
+	}
 
 }
Index: java/main/src/main/java/com/framsticks/util/dispatching/RunAt.java
===================================================================
--- java/main/src/main/java/com/framsticks/util/dispatching/RunAt.java	(revision 85)
+++ java/main/src/main/java/com/framsticks/util/dispatching/RunAt.java	(revision 85)
@@ -0,0 +1,11 @@
+package com.framsticks.util.dispatching;
+
+public abstract class RunAt<C> implements java.lang.Runnable {
+
+	public RunAt() {
+	}
+
+	public RunAt(Dispatcher<? super C> dispatcher) {
+		dispatcher.invokeLater(this);
+	}
+}
Index: java/main/src/main/java/com/framsticks/util/dispatching/Task.java
===================================================================
--- java/main/src/main/java/com/framsticks/util/dispatching/Task.java	(revision 84)
+++ java/main/src/main/java/com/framsticks/util/dispatching/Task.java	(revision 85)
@@ -4,19 +4,19 @@
  * @author Piotr Sniegowski
  */
-public abstract class Task implements Runnable {
+public abstract class Task<C> extends RunAt<C> {
 
-    protected final long moment;
+	protected final long moment;
 
-    public Task() {
-        moment = System.currentTimeMillis();
-    }
+	public Task() {
+		moment = System.currentTimeMillis();
+	}
 
-    public Task(long moment) {
-        this.moment = moment;
-    }
+	public Task(long moment) {
+		this.moment = moment;
+	}
 
-    public final long getMoment() {
-        return moment;
-    }
+	public final long getMoment() {
+		return moment;
+	}
 
 }
Index: java/main/src/main/java/com/framsticks/util/dispatching/Thread.java
===================================================================
--- java/main/src/main/java/com/framsticks/util/dispatching/Thread.java	(revision 84)
+++ java/main/src/main/java/com/framsticks/util/dispatching/Thread.java	(revision 85)
@@ -5,9 +5,10 @@
 import java.util.LinkedList;
 import java.util.ListIterator;
+import com.framsticks.util.dispatching.RunAt;
 
 /**
  * @author Piotr Sniegowski
  */
-public class Thread implements Dispatcher {
+public class Thread<C> implements Dispatcher<C> {
 
 	private static final Logger log = Logger.getLogger(Thread.class.getName());
@@ -15,8 +16,8 @@
 	protected final java.lang.Thread thread;
 
-	private final LinkedList<Task> queue = new LinkedList<Task>();
+	private final LinkedList<Task<? extends C>> queue = new LinkedList<>();
 
 	public Thread() {
-		thread = new java.lang.Thread(new Runnable() {
+		thread = new java.lang.Thread(new java.lang.Runnable() {
 			@Override
 			public void run() {
@@ -25,8 +26,9 @@
 		});
 	}
+
 	public Thread(String s) {
 		this();
 		thread.setName(s);
-		thread.start();
+		// thread.start();
 	}
 
@@ -34,4 +36,9 @@
 		this.thread = thread;
 		thread.setName(s);
+	}
+
+	public Thread<C> start() {
+		thread.start();
+		return this;
 	}
 
@@ -43,5 +50,5 @@
 	protected void routine() {
 		while (!java.lang.Thread.interrupted()) {
-			Task task;
+			Task<? extends C> task;
 			synchronized (queue) {
 				if (queue.isEmpty()) {
@@ -74,9 +81,9 @@
 	}
 
-	protected void enqueueTask(Task task) {
+	protected void enqueueTask(Task<? extends C> task) {
 		synchronized (queue) {
-			ListIterator<Task> i = queue.listIterator();
+			ListIterator<Task<? extends C>> i = queue.listIterator();
 			while (i.hasNext()) {
-				Task t = i.next();
+				Task<? extends C> t = i.next();
 				if (t.getMoment() > task.getMoment()) {
 					i.previous();
@@ -104,7 +111,7 @@
 
 	@Override
-	public void invokeLater(final Runnable runnable) {
+	public void invokeLater(final RunAt<? extends C> runnable) {
 		if (!(runnable instanceof Task)) {
-			enqueueTask(new Task() {
+			enqueueTask(new Task<C>() {
 				@Override
 				public void run() {
@@ -114,5 +121,5 @@
 			return;
 		}
-		enqueueTask((Task)runnable);
+		enqueueTask((Task<? extends C>) runnable);
 	}
 
@@ -125,11 +132,11 @@
 	}
 
-	public void start() {
-		thread.start();
-	}
-
 	public void setName(String name) {
 		thread.setName(name);
 
 	}
+
+	public static boolean interrupted() {
+		return java.lang.Thread.interrupted();
+	}
 }
Index: java/main/src/main/java/com/framsticks/util/io/Encoding.java
===================================================================
--- java/main/src/main/java/com/framsticks/util/io/Encoding.java	(revision 85)
+++ java/main/src/main/java/com/framsticks/util/io/Encoding.java	(revision 85)
@@ -0,0 +1,23 @@
+package com.framsticks.util.io;
+
+import java.nio.charset.Charset;
+
+public final class Encoding {
+
+	protected static final Charset defaultCharset = Charset.forName("UTF-8");
+
+	protected static final Charset framsticksCharset = Charset.forName("ISO-8859-1");
+
+
+	protected Encoding() {
+	}
+
+	public static Charset getFramsticksCharset() {
+		return framsticksCharset;
+	}
+
+	public static Charset getDefaultCharset() {
+		return defaultCharset;
+	}
+
+}
Index: java/main/src/main/java/com/framsticks/util/lang/ScopeEnd.java
===================================================================
--- java/main/src/main/java/com/framsticks/util/lang/ScopeEnd.java	(revision 85)
+++ java/main/src/main/java/com/framsticks/util/lang/ScopeEnd.java	(revision 85)
@@ -0,0 +1,6 @@
+package com.framsticks.util.lang;
+
+public interface ScopeEnd extends AutoCloseable {
+	@Override
+	public void close();
+}
Index: java/main/src/main/java/com/framsticks/visualization/Viewer.java
===================================================================
--- java/main/src/main/java/com/framsticks/visualization/Viewer.java	(revision 84)
+++ java/main/src/main/java/com/framsticks/visualization/Viewer.java	(revision 85)
@@ -1,4 +1,5 @@
 package com.framsticks.visualization;
 
+import com.framsticks.util.io.Encoding;
 import com.sun.j3d.loaders.IncorrectFormatException;
 import com.sun.j3d.loaders.ParsingErrorException;
@@ -18,145 +19,139 @@
 import java.io.*;
 
-// import org.apache.log4j.Logger;
+import org.apache.log4j.Logger;
 
 public class Viewer {
 
-    // private static Logger log = Logger.getLogger(Viewer.class);
+	private static Logger log = Logger.getLogger(Viewer.class);
 
-    Canvas3D canvas3d;
-    SimpleUniverse universe;
+	Canvas3D canvas3d;
+	SimpleUniverse universe;
 
-    public Viewer() {
-        super();
+	public Viewer() {
+		super();
 
-        init();
-    }
+		init();
+	}
 
 	public BranchGroup createSceneGraph() {
-        // Create the root of the branch graph
-        BranchGroup objRoot = new BranchGroup();
+		// Create the root of the branch graph
+		BranchGroup objRoot = new BranchGroup();
 
-        // Create a Transform group to scale all objects so they
-        // appear in the scene.
-        TransformGroup objScale = new TransformGroup();
-        Transform3D t3d = new Transform3D();
-        t3d.setScale(0.7);
-        objScale.setTransform(t3d);
-        objRoot.addChild(objScale);
+		// Create a Transform group to scale all objects so they
+		// appear in the scene.
+		TransformGroup objScale = new TransformGroup();
+		Transform3D t3d = new Transform3D();
+		t3d.setScale(0.7);
+		objScale.setTransform(t3d);
+		objRoot.addChild(objScale);
 
-        TransformGroup objTrans = new TransformGroup();
-        objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
-        objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
-        objScale.addChild(objTrans);
+		TransformGroup objTrans = new TransformGroup();
+		objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+		objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
+		objScale.addChild(objTrans);
 
-        String filename = "/visualization/models/cylinder.obj";
-        int flags = ObjectFile.RESIZE;
-        flags |= ObjectFile.TRIANGULATE;
-        flags |= ObjectFile.STRIPIFY;
+		String filename = "/visualization/models/cylinder.obj";
+		int flags = ObjectFile.RESIZE;
+		flags |= ObjectFile.TRIANGULATE;
+		flags |= ObjectFile.STRIPIFY;
 		double creaseAngle = 60.0;
 		ObjectFile f = new ObjectFile(flags,
-                (float) (creaseAngle * Math.PI / 180.0));
-        Scene s = null;
-        try {
+				(float) (creaseAngle * Math.PI / 180.0));
+		Scene s = null;
+		try {
 			InputStream is = this.getClass().getResourceAsStream(filename);
-            s = f.load(new InputStreamReader(is));
-        } catch (FileNotFoundException e) {
-            System.err.println(e);
-            System.exit(1);
-        } catch (ParsingErrorException e) {
-            System.err.println(e);
-            System.exit(1);
-        } catch (IncorrectFormatException e) {
-            System.err.println(e);
-            System.exit(1);
-        }
+			s = f.load(new InputStreamReader(is, Encoding.getDefaultCharset()));
+		} catch (FileNotFoundException | ParsingErrorException | IncorrectFormatException e) {
+			log.fatal("fatal error", e);
+			return null;
+		}
 
-        objTrans.addChild(s.getSceneGroup());
+		objTrans.addChild(s.getSceneGroup());
 
-        BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0);
+		BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0);
 
-        Color3f bgColor = new Color3f(0.05f, 0.05f, 0.5f);
-        Background bgNode = new Background(bgColor);
-        bgNode.setApplicationBounds(bounds);
-        objRoot.addChild(bgNode);
+		Color3f bgColor = new Color3f(0.05f, 0.05f, 0.5f);
+		Background bgNode = new Background(bgColor);
+		bgNode.setApplicationBounds(bounds);
+		objRoot.addChild(bgNode);
 
-        return objRoot;
-    }
+		return objRoot;
+	}
 
-    private void init() {
+	private void init() {
 
-	    JTextPane textPane = new JTextPane();
-        textPane.setEditable(false);
+		JTextPane textPane = new JTextPane();
+		textPane.setEditable(false);
 
-        GraphicsConfiguration config = SimpleUniverse.getPreferredConfiguration();
+		GraphicsConfiguration config = SimpleUniverse.getPreferredConfiguration();
 
-        // Create a Canvas3D using the preferred configuration
-        canvas3d = new Canvas3D(config);
+		// Create a Canvas3D using the preferred configuration
+		canvas3d = new Canvas3D(config);
 
-        // Create simple universe with view branch
-        universe = new SimpleUniverse(canvas3d);
-        BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0);
+		// Create simple universe with view branch
+		universe = new SimpleUniverse(canvas3d);
+		BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0);
 
-        // add mouse behaviours to the ViewingPlatform
-        ViewingPlatform viewingPlatform = universe.getViewingPlatform();
+		// add mouse behaviours to the ViewingPlatform
+		ViewingPlatform viewingPlatform = universe.getViewingPlatform();
 
-        PlatformGeometry platformGeometry = new PlatformGeometry();
+		PlatformGeometry platformGeometry = new PlatformGeometry();
 
-        // Set up the ambient light
-        Color3f ambientColor = new Color3f(0.1f, 0.1f, 0.1f);
-        AmbientLight ambientLightNode = new AmbientLight(ambientColor);
-        ambientLightNode.setInfluencingBounds(bounds);
-        platformGeometry.addChild(ambientLightNode);
+		// Set up the ambient light
+		Color3f ambientColor = new Color3f(0.1f, 0.1f, 0.1f);
+		AmbientLight ambientLightNode = new AmbientLight(ambientColor);
+		ambientLightNode.setInfluencingBounds(bounds);
+		platformGeometry.addChild(ambientLightNode);
 
-        // Set up the directional lights
-        Color3f light1Color = new Color3f(1.0f, 1.0f, 0.9f);
-        Vector3f light1Direction = new Vector3f(1.0f, 1.0f, 1.0f);
-        Color3f light2Color = new Color3f(1.0f, 1.0f, 1.0f);
-        Vector3f light2Direction = new Vector3f(-1.0f, -1.0f, -1.0f);
+		// Set up the directional lights
+		Color3f light1Color = new Color3f(1.0f, 1.0f, 0.9f);
+		Vector3f light1Direction = new Vector3f(1.0f, 1.0f, 1.0f);
+		Color3f light2Color = new Color3f(1.0f, 1.0f, 1.0f);
+		Vector3f light2Direction = new Vector3f(-1.0f, -1.0f, -1.0f);
 
-        DirectionalLight light1 = new DirectionalLight(light1Color,
-                light1Direction);
-        light1.setInfluencingBounds(bounds);
-        platformGeometry.addChild(light1);
+		DirectionalLight light1 = new DirectionalLight(light1Color,
+				light1Direction);
+		light1.setInfluencingBounds(bounds);
+		platformGeometry.addChild(light1);
 
-        DirectionalLight light2 = new DirectionalLight(light2Color,
-                light2Direction);
-        light2.setInfluencingBounds(bounds);
-        platformGeometry.addChild(light2);
+		DirectionalLight light2 = new DirectionalLight(light2Color,
+				light2Direction);
+		light2.setInfluencingBounds(bounds);
+		platformGeometry.addChild(light2);
 
-        viewingPlatform.setPlatformGeometry(platformGeometry);
+		viewingPlatform.setPlatformGeometry(platformGeometry);
 
-        viewingPlatform.setNominalViewingTransform();
+		viewingPlatform.setNominalViewingTransform();
 
-        // Ensure at least 5 msec per frame (i.e., < 200Hz)
-        universe.getViewer().getView().setMinimumFrameCycleTime(5);
+		// Ensure at least 5 msec per frame (i.e., < 200Hz)
+		universe.getViewer().getView().setMinimumFrameCycleTime(5);
 
-        BranchGroup scene = new BranchGroup();
-        BranchGroup content = createSceneGraph();
+		BranchGroup scene = new BranchGroup();
+		BranchGroup content = createSceneGraph();
 
-        // canvas3d.addMouseListener(behaviour);
-        TransformGroup transformGroup = new TransformGroup(new Transform3D());
-        transformGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
-        transformGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
-        MouseRotate behaviour = new MouseRotate();
-        behaviour.setTransformGroup(transformGroup);
-        transformGroup.addChild(behaviour);
-        // behaviour.addListener(canvas3d);
-        // behaviour.initialize();
-        behaviour.setSchedulingBounds(new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0));
-        transformGroup.addChild(content);
-        // transformGroup.addChild(behaviour);
-        scene.addChild(transformGroup);
+		// canvas3d.addMouseListener(behaviour);
+		TransformGroup transformGroup = new TransformGroup(new Transform3D());
+		transformGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
+		transformGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
+		MouseRotate behaviour = new MouseRotate();
+		behaviour.setTransformGroup(transformGroup);
+		transformGroup.addChild(behaviour);
+		// behaviour.addListener(canvas3d);
+		// behaviour.initialize();
+		behaviour.setSchedulingBounds(new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0));
+		transformGroup.addChild(content);
+		// transformGroup.addChild(behaviour);
+		scene.addChild(transformGroup);
 
-        universe.addBranchGraph(scene);
+		universe.addBranchGraph(scene);
 		canvas3d.startRenderer();
 		Dimension d = new Dimension(500, 500);
 		canvas3d.setMinimumSize(d);
 		canvas3d.setSize(d);
-    }
+	}
 
-    public Component getViewComponent() {
-        return canvas3d;
-    }
+	public Component getViewComponent() {
+		return canvas3d;
+	}
 
 
