Index: /java/main/src/main/java/com/framsticks/communication/ClientSideManagedConnection.java
===================================================================
--- /java/main/src/main/java/com/framsticks/communication/ClientSideManagedConnection.java	(revision 97)
+++ /java/main/src/main/java/com/framsticks/communication/ClientSideManagedConnection.java	(revision 98)
@@ -176,4 +176,5 @@
 
 	private <C> void sendImplementation(Request request, Dispatcher<C> dispatcher, ClientSideResponseFuture callback) {
+		callback.setRequest(request);
 
 		if (getState().ordinal() > JoinableState.RUNNING.ordinal()) {
Index: /java/main/src/main/java/com/framsticks/communication/ClientSideResponseFuture.java
===================================================================
--- /java/main/src/main/java/com/framsticks/communication/ClientSideResponseFuture.java	(revision 97)
+++ /java/main/src/main/java/com/framsticks/communication/ClientSideResponseFuture.java	(revision 98)
@@ -11,4 +11,6 @@
 	}
 
+	protected Request request;
+
 	protected abstract void processOk(Response response);
 
@@ -18,7 +20,21 @@
 			processOk(response);
 		} else {
-			handle(new FramsticksException().msg("invalid response").arg("comment", response.getComment()));
+			handle(new FramsticksException().msg("invalid response").arg("comment", response.getComment()).arg("request", request));
 		}
 	}
 
+	/**
+	 * @return the request
+	 */
+	public Request getRequest() {
+		return request;
+	}
+
+	/**
+	 * @param request the request to set
+	 */
+	public void setRequest(Request request) {
+		this.request = request;
+	}
+
 }
Index: /java/main/src/main/java/com/framsticks/communication/Request.java
===================================================================
--- /java/main/src/main/java/com/framsticks/communication/Request.java	(revision 97)
+++ /java/main/src/main/java/com/framsticks/communication/Request.java	(revision 98)
@@ -48,5 +48,6 @@
 	@Override
 	public String toString() {
-		return getCommand() + " request";
+		// return getCommand();
+		return "request " + stringRepresentation();
 	}
 
Index: /java/main/src/main/java/com/framsticks/communication/RequestHandler.java
===================================================================
--- /java/main/src/main/java/com/framsticks/communication/RequestHandler.java	(revision 97)
+++ /java/main/src/main/java/com/framsticks/communication/RequestHandler.java	(revision 98)
@@ -2,9 +2,10 @@
 
 import com.framsticks.communication.queries.ApplicationRequest;
+import com.framsticks.util.dispatching.ExceptionResultHandler;
 
 /**
  * @author Piotr Sniegowski
  */
-public interface RequestHandler {
+public interface RequestHandler extends ExceptionResultHandler {
 	public void handle(ApplicationRequest request, ServerSideResponseFuture responseCallback);
 }
Index: /java/main/src/main/java/com/framsticks/communication/ServerSideManagedConnection.java
===================================================================
--- /java/main/src/main/java/com/framsticks/communication/ServerSideManagedConnection.java	(revision 97)
+++ /java/main/src/main/java/com/framsticks/communication/ServerSideManagedConnection.java	(revision 98)
@@ -12,5 +12,4 @@
 import java.net.Socket;
 import com.framsticks.util.dispatching.RunAt;
-import com.framsticks.util.dispatching.ThrowExceptionHandler;
 
 /**
@@ -21,5 +20,5 @@
 	private final static Logger log = Logger.getLogger(ServerSideManagedConnection.class);
 
-	RequestHandler requestHandler;
+	protected final RequestHandler requestHandler;
 
 	public ServerSideManagedConnection(Socket socket, RequestHandler requestHandler) {
@@ -70,6 +69,5 @@
 
 	protected final void respond(final Response response, final Integer id) {
-		//TODO TEH: pass it the hosted tree
-		senderThread.dispatch(new RunAt<Connection>(ThrowExceptionHandler.getInstance()) {
+		senderThread.dispatch(new RunAt<Connection>(requestHandler) {
 			@Override
 			protected void runAt() {
Index: /java/main/src/main/java/com/framsticks/communication/Subscription.java
===================================================================
--- /java/main/src/main/java/com/framsticks/communication/Subscription.java	(revision 97)
+++ /java/main/src/main/java/com/framsticks/communication/Subscription.java	(revision 98)
@@ -73,5 +73,4 @@
 
 	public void dispatchCall(final List<File> files) {
-		//TODO TEH
 		Dispatching.dispatchIfNotActive(dispatcher, new RunAt<C>(ThrowExceptionHandler.getInstance()) {
 			@Override
Index: /java/main/src/main/java/com/framsticks/core/AbstractTree.java
===================================================================
--- /java/main/src/main/java/com/framsticks/core/AbstractTree.java	(revision 97)
+++ /java/main/src/main/java/com/framsticks/core/AbstractTree.java	(revision 98)
@@ -1,5 +1,3 @@
 package com.framsticks.core;
-import java.util.HashSet;
-import java.util.Set;
 
 import javax.annotation.Nonnull;
@@ -10,10 +8,18 @@
 import com.framsticks.params.CompositeParam;
 import com.framsticks.params.FramsClass;
-import com.framsticks.params.Param;
 import com.framsticks.params.ParamsPackage;
 import com.framsticks.params.Registry;
 import com.framsticks.params.annotations.AutoAppendAnnotation;
 import com.framsticks.params.annotations.FramsClassAnnotation;
+import com.framsticks.params.annotations.ParamAnnotation;
+import com.framsticks.util.FramsticksException;
+import com.framsticks.util.dispatching.AbstractJoinable;
+import com.framsticks.util.dispatching.Dispatcher;
 import com.framsticks.util.dispatching.Dispatching;
+import com.framsticks.util.dispatching.ExceptionResultHandler;
+import com.framsticks.util.dispatching.Joinable;
+import com.framsticks.util.dispatching.JoinableDispatcher;
+import com.framsticks.util.dispatching.JoinableParent;
+import com.framsticks.util.dispatching.JoinableState;
 import com.framsticks.util.dispatching.RunAt;
 import com.framsticks.util.dispatching.Thread;
@@ -24,18 +30,39 @@
  */
 @FramsClassAnnotation
-public abstract class AbstractTree extends Thread<Tree> implements Tree {
+public abstract class AbstractTree extends AbstractJoinable implements Dispatcher<Tree>, Tree, JoinableParent {
 
 	private static final Logger log = Logger.getLogger(Tree.class);
 
-	private Node root;
-
-	@Override
-	public void setRoot(Node node) {
-		root = node;
-	}
-
-	@Override
-	public @Nonnull Node getRoot() {
-		assert root != null;
+	private Node root = null;
+	private ExceptionResultHandler handler = ThrowExceptionHandler.getInstance();
+
+	private JoinableDispatcher<Tree> dispatcher;
+
+	@Override
+	public void assignRootParam(CompositeParam param) {
+		if (root != null) {
+			throw new FramsticksException().msg("root has already specified type");
+		}
+		root = new Node(this, param, null);
+		log.info("assigned root type: " + root);
+	}
+
+	@Override
+	public void assignRootObject(Object object) {
+		if (root == null) {
+			throw new FramsticksException().msg("root is has no type specified");
+		}
+		if (root.getObject() != null) {
+			throw new FramsticksException().msg("root has already object assigned").arg("current", root.getObject()).arg("candidate", object);
+		}
+		root = new Node(this, root.getParam(), object);
+		log.info("assigned root object: " + root);
+	}
+
+	@Override
+	public @Nonnull Node getAssignedRoot() {
+		if (root == null) {
+			throw new FramsticksException().msg("root has no type specified yet");
+		}
 		return root;
 	}
@@ -46,8 +73,8 @@
 	}
 
-	protected Set<TreeListener> listeners = new HashSet<TreeListener>();
+	protected String name;
 
 	public AbstractTree() {
-		setName("entity");
+		setName("tree");
 	}
 
@@ -55,59 +82,4 @@
 
 	}
-
-
-	protected void fireRun(Exception e) {
-		for (TreeListener l : this.listeners) {
-			l.onRun(e);
-		}
-	}
-
-	protected void fireStop(Exception e) {
-		for (TreeListener l : this.listeners) {
-			l.onStop(e);
-		}
-	}
-
-	@Override
-	public void addListener(final TreeListener listener) {
-		assert Dispatching.isThreadSafe();
-		Dispatching.dispatchIfNotActive(this, new RunAt<Tree>(ThrowExceptionHandler.getInstance()) {
-			@Override
-			protected void runAt() {
-				listeners.add(listener);
-			}
-		});
-	}
-
-	@Override
-	public void removeListener(final TreeListener listener) {
-		assert Dispatching.isThreadSafe();
-		Dispatching.dispatchIfNotActive(this, new RunAt<Tree>(ThrowExceptionHandler.getInstance()) {
-			@Override
-			protected void runAt() {
-				listeners.remove(listener);
-			}
-		});
-	}
-
-	protected void fireListChange(Path path, ListChange change) {
-		assert isActive();
-		for (TreeListener l : this.listeners) {
-			l.onListChange(path, change);
-		}
-	}
-
-	@Override
-	public void notifyOfFetch(Path path) {
-		fireFetch(path);
-	}
-
-	protected void fireFetch(Path path) {
-		assert isActive();
-		for (TreeListener l : this.listeners) {
-			l.onFetch(path);
-		}
-	}
-
 
 	@Override
@@ -142,16 +114,4 @@
 	}
 
-	@Override
-	protected void joinableStart() {
-		dispatch(new RunAt<Tree>(ThrowExceptionHandler.getInstance()) {
-			@Override
-			protected void runAt() {
-				if (!isRootAssigned()) {
-					setRoot(new Node(Param.build().name("Tree").id(getName()).type("o").finish(CompositeParam.class), null));
-				}
-			}
-		});
-		super.joinableStart();
-	}
 
 	@Override
@@ -159,4 +119,108 @@
 		registry.putFramsClass(framclass);
 	}
+
+
+	/**
+	 * @return the handler
+	 */
+	@Override
+	public ExceptionResultHandler getExceptionHandler() {
+		return handler;
+	}
+
+	/**
+	 * @param handler the handler to set
+	 */
+	@Override
+	public void setExceptionHandler(ExceptionResultHandler handler) {
+		this.handler = handler;
+	}
+
+	@Override
+	public void handle(FramsticksException exception) {
+		handler.handle(exception);
+	}
+
+	/**
+	 * @return the dispatcher
+	 */
+	@Override
+	public JoinableDispatcher<Tree> getDispatcher() {
+		return dispatcher;
+	}
+
+	/**
+	 * @param dispatcher the dispatcher to set
+	 */
+	@Override
+	public void setDispatcher(JoinableDispatcher<Tree> dispatcher) {
+		if (this.dispatcher != null) {
+			throw new FramsticksException().msg("dispatcher is already set").arg("tree", this).arg("dispatcher", dispatcher);
+		}
+		this.dispatcher = dispatcher;
+	}
+
+	/**
+	 * @return the name
+	 */
+	@ParamAnnotation
+	public String getName() {
+		return name;
+	}
+
+	/**
+	 * @param name the name to set
+	 */
+	@ParamAnnotation
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	@Override
+	protected void joinableStart() {
+		if (dispatcher == null) {
+			dispatcher = new Thread<Tree>();
+		}
+		Dispatching.use(dispatcher, this);
+	}
+
+	@Override
+	protected void joinableInterrupt() {
+		Dispatching.drop(dispatcher, this);
+	}
+
+	@Override
+	protected void joinableFinish() {
+
+	}
+
+	@Override
+	protected void joinableJoin() throws InterruptedException {
+		Dispatching.join(dispatcher);
+	}
+
+	@Override
+	public void childChangedState(Joinable joinable, JoinableState state) {
+		if (joinable == dispatcher) {
+			proceedToState(state);
+		}
+	}
+
+	@Override
+	public boolean isActive() {
+		if (dispatcher == null) {
+			throw new FramsticksException().msg("no dispatcher is set for tree yet").arg("tree", this);
+		}
+		return dispatcher.isActive();
+	}
+
+	@Override
+	public void dispatch(RunAt<? extends Tree> runnable) {
+		if (dispatcher == null) {
+			throw new FramsticksException().msg("no dispatcher is set for tree yet").arg("tree", this);
+		}
+		dispatcher.dispatch(runnable);
+	}
+
 }
 
Index: va/main/src/main/java/com/framsticks/core/AbstractTreeListener.java
===================================================================
--- /java/main/src/main/java/com/framsticks/core/AbstractTreeListener.java	(revision 97)
+++ 	(revision )
@@ -1,25 +1,0 @@
-package com.framsticks.core;
-
-public abstract class AbstractTreeListener implements TreeListener {
-
-	@Override
-	public void onListChange(Path path, ListChange change) {
-
-	}
-
-	@Override
-	public void onFetch(Path path) {
-
-	}
-
-	@Override
-	public void onRun(Exception e) {
-
-	}
-
-	@Override
-	public void onStop(Exception e) {
-
-	}
-
-}
Index: /java/main/src/main/java/com/framsticks/core/Node.java
===================================================================
--- /java/main/src/main/java/com/framsticks/core/Node.java	(revision 97)
+++ /java/main/src/main/java/com/framsticks/core/Node.java	(revision 98)
@@ -5,5 +5,7 @@
 
 import com.framsticks.params.CompositeParam;
-import com.framsticks.params.ParamBuilder;
+import com.framsticks.util.FramsticksException;
+// import com.framsticks.params.ParamBuilder;
+import com.framsticks.util.lang.Strings;
 
 /**
@@ -13,21 +15,19 @@
 public class Node {
 
+	protected final Tree tree;
 	protected final CompositeParam param;
 	protected final Object object;
-	//protected final Map<String, Node> children = new HashMap<String, Node>();
 
-	public Node() {
-		param = null;
-		object = null;
-	}
-
-	public Node(@Nonnull CompositeParam param, Object object) {
+	public Node(Tree tree, @Nonnull CompositeParam param, Object object) {
 		assert param != null;
+		assert tree != null;
+		this.tree = tree;
 		this.param = param;
 		this.object = object;
 	}
 
-	public Node(@Nonnull ParamBuilder builder, Object object) {
-		this(builder.finish(CompositeParam.class), object);
+
+	public final Tree getTree() {
+		return tree;
 	}
 
@@ -40,3 +40,19 @@
 	}
 
+	@Override
+	public String toString() {
+		return param.toString() + ":" + Strings.toStringNullProof(object, "<null>");
+	}
+
+	public final boolean isResolved() {
+		return object != null;
+	}
+
+	public Node assureResolved() {
+		if (!isResolved()) {
+			throw new FramsticksException().msg("path is not resolved").arg("node", this);
+		}
+		return this;
+	}
+
 }
Index: /java/main/src/main/java/com/framsticks/core/ObjectTree.java
===================================================================
--- /java/main/src/main/java/com/framsticks/core/ObjectTree.java	(revision 97)
+++ /java/main/src/main/java/com/framsticks/core/ObjectTree.java	(revision 98)
@@ -8,10 +8,11 @@
 import com.framsticks.params.Param;
 import com.framsticks.params.PrimitiveParam;
+import com.framsticks.params.ValueParam;
 import com.framsticks.params.annotations.AutoAppendAnnotation;
 import com.framsticks.params.annotations.FramsClassAnnotation;
-import com.framsticks.util.UnsupportedOperationException;
 import com.framsticks.params.types.ProcedureParam;
 import com.framsticks.util.FramsticksException;
 import com.framsticks.util.dispatching.Future;
+
 import static com.framsticks.core.TreeOperations.*;
 
@@ -24,9 +25,10 @@
 		registry.registerAndBuild(object.getClass());
 		AccessInterface access = registry.createAccess(object.getClass());
-		setRoot(new Node(Param.build().forAccess(access).id(getName()).finish(CompositeParam.class), object));
+		assignRootParam(Param.build().forAccess(access).id(getName()).finish(CompositeParam.class));
+		assignRootObject(object);
 	}
 
 	public Object getRootObject() {
-		return getRoot().getObject();
+		return getAssignedRoot().getObject();
 	}
 
@@ -43,15 +45,15 @@
 
 	@Override
-	public void get(final Path path, Mode mode, Future<Object> future) {
+	public void get(Path path, Mode mode, Future<Path> future) {
 		assert isActive();
 		log.debug("requesting: " + path);
-		fireFetch(path);
-		future.pass(path.getTopObject());
+		path = resolveTopSync(path);
+		future.pass(path);
 	}
 
 	@Override
-	public void get(Path path, PrimitiveParam<?> param, Mode mode, Future<Object> future) {
+	public void get(Path path, ValueParam param, Mode mode, Future<Object> future) {
 		assert isActive();
-		fireFetch(path);
+		path = resolveTopSync(path);
 		future.pass(bindAccess(path).get(param, Object.class));
 	}
@@ -80,20 +82,18 @@
 	}
 
-	@Override
-	public void resolve(Path path, Future<Path> future) {
+	protected Path resolveTopSync(Path path) {
 		assert isActive();
 		assert path.isOwner(this);
 		if (path.getTop().getObject() != null) {
-			future.pass(path);
-			return;
+			return path;
 		}
-		AccessInterface access = bindAccess(this, path.getUnder());
+		AccessInterface access = bindAccess(path.getUnder());
 		Object object = access.get(path.getTop().getParam(), Object.class);
 		if (object == null) {
-			future.pass(path);
-			return;
+			return path;
 		}
-		future.pass(path.appendResolution(object));
+		return path.appendResolution(object);
 	}
+
 
 	@Override
@@ -103,10 +103,3 @@
 	}
 
-	@Override
-	public Path create(Path path) {
-		assert isActive();
-		assert !path.isResolved();
-		throw new UnsupportedOperationException();
-	}
-
 }
Index: /java/main/src/main/java/com/framsticks/core/Path.java
===================================================================
--- /java/main/src/main/java/com/framsticks/core/Path.java	(revision 97)
+++ /java/main/src/main/java/com/framsticks/core/Path.java	(revision 98)
@@ -58,5 +58,5 @@
 	public Path appendParam(CompositeParam param) {
 		assert isResolved();
-		return appendNode(new Node(param, null));
+		return appendNode(new Node(tree, param, null));
 	}
 
@@ -99,5 +99,5 @@
 		public PathBuilder setLast(Object object) {
 			Node n = nodes.pollLast();
-			nodes.add(new Node(n.getParam(), object));
+			nodes.add(new Node(n.getTree(), n.getParam(), object));
 			return this;
 		}
@@ -130,4 +130,5 @@
 		}
 
+
 		public PathBuilder resolve(@Nonnull Tree tree, String textual) {
 
@@ -136,14 +137,11 @@
 			this.tree = tree;
 
-			nodes.add(tree.getRoot());
-			Node current = tree.getRoot();
+			Node current = tree.getAssignedRoot();
+			nodes.add(current);
 
 			StringBuilder b = new StringBuilder();
 			Iterator<String> i = splitPath(textual);
 			while (i.hasNext() && current.getObject() != null) {
-				AccessInterface access = tree.prepareAccess(current.getParam());
-				if (access == null) {
-					break;
-				}
+				AccessInterface access = TreeOperations.bindAccess(current);// tree.prepareAccess(current.getParam());
 				String e = i.next();
 				Param p = access.getParam(e);
@@ -155,5 +153,5 @@
 				b.append("/").append(e);
 				access.select(current.getObject());
-				current = new Node(c, getKnownChild(tree, access, c));
+				current = new Node(current.getTree(), c, getKnownChild(tree, access, c));
 				nodes.add(current);
 			}
@@ -218,4 +216,9 @@
 		assert Dispatching.isThreadSafe();
 		return this.textual.equals(textual);
+	}
+
+	public final boolean isTheSameTextually(Path path) {
+		assert Dispatching.isThreadSafe();
+		return (tree == path.getTree()) && textual.equals(path.getTextual());
 	}
 
@@ -242,5 +245,5 @@
 			return Path.build().resolve(tree, "/").finish();
 		}
-		Object child = getKnownChild(tree, TreeOperations.bindAccess(tree, getUnder()), getTop().getParam());
+		Object child = getKnownChild(tree, TreeOperations.bindAccess(getUnder()), getTop().getParam());
 		if (child == null) {
 			return this;
@@ -249,18 +252,4 @@
 	}
 
-	public boolean matches(Path p) {
-		assert Dispatching.isThreadSafe();
-		assert tree == p.tree;
-		Iterator<Node> a = nodes.iterator();
-		Iterator<Node> b = p.nodes.iterator();
-		while (a.hasNext() && b.hasNext()) {
-			Node an = a.next();
-			Node bn = b.next();
-			if (an.object != bn.object) {
-				return false;
-			}
-		}
-		return a.hasNext() == b.hasNext();
-	}
 
 	public String getLastElement() {
@@ -278,8 +267,9 @@
 	}
 
-	public void assureResolved() {
+	public Path assureResolved() {
 		if (!isResolved()) {
 			throw new FramsticksException().msg("path is not resolved").arg("path", this);
 		}
+		return this;
 	}
 
@@ -287,4 +277,30 @@
 		return Path.build().resolve(tree, textual).finish();
 	}
+
+	public boolean isTheSameObjects(Path path) {
+		if (tree != path.getTree()) {
+			return false;
+		}
+		if (size() != path.size()) {
+			return false;
+		}
+		if (!getTextual().equals(path.getTextual())) {
+			return false;
+		}
+		Iterator<Node> a = nodes.iterator();
+		Iterator<Node> b = path.getNodes().iterator();
+		while (a.hasNext()) {
+			assert b.hasNext();
+			if (a.next() != b.next()) {
+				return false;
+			}
+		}
+		return true;
+	}
+
+
+	// public boolean isEmpty() {
+	// 	return nodes.isEmpty();
+	// }
 }
 
Index: /java/main/src/main/java/com/framsticks/core/Tree.java
===================================================================
--- /java/main/src/main/java/com/framsticks/core/Tree.java	(revision 97)
+++ /java/main/src/main/java/com/framsticks/core/Tree.java	(revision 98)
@@ -8,21 +8,20 @@
 import com.framsticks.params.PrimitiveParam;
 import com.framsticks.params.Registry;
+import com.framsticks.params.ValueParam;
 import com.framsticks.params.types.ProcedureParam;
 import com.framsticks.util.dispatching.Dispatcher;
+import com.framsticks.util.dispatching.ExceptionResultHandler;
 import com.framsticks.util.dispatching.Future;
 import com.framsticks.util.dispatching.Joinable;
+import com.framsticks.util.dispatching.JoinableDispatcher;
 
-public interface Tree extends Dispatcher<Tree>, Joinable {
+public interface Tree extends Dispatcher<Tree>, Joinable, ExceptionResultHandler {
 
-	public @Nonnull Node getRoot();
-	public @Nonnull void setRoot(Node node);
+	public @Nonnull Node getAssignedRoot();
+	public void assignRootParam(CompositeParam param);
+	public void assignRootObject(Object object);
 
 	public @Nonnull AccessInterface prepareAccess(CompositeParam param);
 	public void takeAllFrom(Registry source);
-
-	public void addListener(TreeListener listener);
-	public void removeListener(TreeListener listener);
-
-	public void notifyOfFetch(Path path);
 
 	public FramsClass getInfoFromCache(String id);
@@ -30,16 +29,31 @@
 	public void putInfoIntoCache(FramsClass framclass);
 
-	public void resolve(Path path, Future<Path> future);
+	/**
+	 *
+	 * Functions accepts ValueParam, because it is also possible to get number of List elements.
+	 *
+	 */
+	public void get(Path path, ValueParam param, Mode mode, Future<Object> future);
 
-	public void get(Path path, PrimitiveParam<?> param, Mode mode, Future<Object> future);
-
-	public void get(Path path, Mode mode, Future<Object> future);
+	public void get(Path path, Mode mode, Future<Path> future);
 
 	public void call(Path path, ProcedureParam param, Object[] arguments, Future<Object> future);
 
+	/**
+	 *
+	 * Functions accepts PrimitiveParam<?>, because it is not possible to set number of List elements.
+	 *
+	 */
 	public void set(Path path, PrimitiveParam<?> param, Object value, Future<Integer> future);
 
 	public void info(Path path, Future<FramsClass> future);
 
-	public Path create(Path path);
+	public void setExceptionHandler(ExceptionResultHandler handler);
+
+	public ExceptionResultHandler getExceptionHandler();
+
+	public void setDispatcher(JoinableDispatcher<Tree> dispatcher);
+
+	public JoinableDispatcher<Tree> getDispatcher();
+
 }
Index: va/main/src/main/java/com/framsticks/core/TreeListener.java
===================================================================
--- /java/main/src/main/java/com/framsticks/core/TreeListener.java	(revision 97)
+++ 	(revision )
@@ -1,11 +1,0 @@
-package com.framsticks.core;
-
-/**
- * @author Piotr Sniegowski
- */
-public interface TreeListener {
-	public void onListChange(Path path, ListChange change);
-	public void onFetch(Path path);
-	public void onRun(Exception e);
-	public void onStop(Exception e);
-}
Index: /java/main/src/main/java/com/framsticks/core/TreeOperations.java
===================================================================
--- /java/main/src/main/java/com/framsticks/core/TreeOperations.java	(revision 97)
+++ /java/main/src/main/java/com/framsticks/core/TreeOperations.java	(revision 98)
@@ -1,3 +1,4 @@
 package com.framsticks.core;
+
 
 import java.util.List;
@@ -14,5 +15,4 @@
 import com.framsticks.params.Param;
 import com.framsticks.params.PrimitiveParam;
-import com.framsticks.params.ValueParam;
 import com.framsticks.params.types.ObjectParam;
 import com.framsticks.params.types.ProcedureParam;
@@ -28,5 +28,5 @@
 public final class TreeOperations {
 
-	private static final Logger log = Logger.getLogger(TreeOperations.class.getName());
+	private static final Logger log = Logger.getLogger(TreeOperations.class);
 
 	private TreeOperations() {
@@ -36,16 +36,69 @@
 		assert tree.isActive();
 		FramsClass framsClass = Loaders.loadFramsClass(file.getContent());
-		if ("/".equals(file.getPath())) {
-			if (tree.getRoot().getParam().getContainedTypeName() == null) {
-				tree.setRoot(new Node(Param.build().name("Tree").id(tree.getName()).type("o " + framsClass.getId()).finish(CompositeParam.class), tree.getRoot().getObject()));
-			}
-		}
+		log.debug("process fetched info for " + tree + ": " + framsClass);
 		tree.putInfoIntoCache(framsClass);
 		return framsClass;
 	}
 
+	public static void processFetchedValues(Path path, List<File> files) {
+		Tree tree = path.getTree();
+		assert tree.isActive();
+		assert files.size() == 1;
+		assert path.isTheSame(files.get(0).getPath());
+
+		if (!path.isResolved()) {
+			AccessInterface access = tree.prepareAccess(path.getTop().getParam());
+			Object child = access.createAccessee();
+			assert child != null;
+			if (path.size() == 1) {
+				tree.assignRootObject(child);
+			} else {
+				bindAccess(path.getUnder()).set(path.getTop().getParam(), child);
+			}
+			path = path.appendResolution(child);
+		}
+
+		log.debug("process fetched values: " + path);
+		Node node = path.getTop();
+		MultiParamLoader loader = new MultiParamLoader();
+		loader.setNewSource(files.get(0).getContent());
+		loader.addBreakCondition(MultiParamLoader.Status.AfterObject);
+
+		try {
+			if (node.getParam() instanceof ObjectParam) {
+				loader.addAccessInterface(bindAccess(node));
+				loader.go();
+				return;
+			}
+
+			ListAccess listAccess = (ListAccess) bindAccess(node);
+			listAccess.clearValues();
+
+			AccessInterface elementAccess = listAccess.getElementAccess();
+			loader.addAccessInterface(elementAccess);
+			MultiParamLoader.Status status;
+			while ((status = loader.go()) != MultiParamLoader.Status.Finished) {
+				if (status == MultiParamLoader.Status.AfterObject) {
+					AccessInterface accessInterface = loader.getLastAccessInterface();
+
+					String id = listAccess.computeIdentifierFor(accessInterface.getSelected());
+					//TODO listAccessParam
+					CompositeParam param = Param.build().forAccess(accessInterface).id(id).finish(CompositeParam.class);
+					Object child = accessInterface.getSelected();
+					accessInterface.select(null);
+					assert child != null;
+					bindAccess(node).set(param, child);
+				}
+			}
+
+		} catch (FramsticksException e) {
+			throw new FramsticksException().msg("exception occurred while loading").cause(e);
+		}
+	}
+
 	public static FramsClass getInfo(Path path) {
 		Tree tree = path.getTree();
 		assert tree.isActive();
+		log.debug("get info for: " + path);
 		final String name = path.getTop().getParam().getContainedTypeName();
 		return tree.getInfoFromCache(name);
@@ -53,4 +106,5 @@
 
 	public static void findInfo(final Path path, final Future<FramsClass> future) {
+		log.debug("find info for: " + path);
 		try {
 			Tree tree = path.getTree();
@@ -67,117 +121,13 @@
 	}
 
-	public static void processFetchedValues(Path path, List<File> files) {
-		Tree tree = path.getTree();
-		assert tree.isActive();
-		assert files.size() == 1;
-		assert path.isTheSame(files.get(0).getPath());
-		Node node = path.getTop();
-		MultiParamLoader loader = new MultiParamLoader();
-		loader.setNewSource(files.get(0).getContent());
-		loader.addBreakCondition(MultiParamLoader.Status.AfterObject);
-
-		try {
-			if (node.getParam() instanceof ObjectParam) {
-				loader.addAccessInterface(TreeOperations.bindAccess(tree, node));
-				loader.go();
-				tree.notifyOfFetch(path);
-				return;
-			}
-
-			ListAccess listAccess = ((ListAccess) TreeOperations.bindAccess(tree, node));
-			assert listAccess != null;
-			listAccess.clearValues();
-
-			AccessInterface elementAccess = listAccess.getElementAccess();
-			loader.addAccessInterface(elementAccess);
-			MultiParamLoader.Status status;
-			while ((status = loader.go()) != MultiParamLoader.Status.Finished) {
-				if (status == MultiParamLoader.Status.AfterObject) {
-					AccessInterface accessInterface = loader.getLastAccessInterface();
-
-					String id = listAccess.computeIdentifierFor(accessInterface.getSelected());
-					//TODO listAccessParam
-					Param param = Param.build().forAccess(accessInterface).id(id).finish();
-					Object child = accessInterface.getSelected();
-					accessInterface.select(null);
-					assert child != null;
-					TreeOperations.bindAccess(tree, node).set((ValueParam) param, child);
-				}
-			}
-
-			tree.notifyOfFetch(path);
-		} catch (Exception e) {
-			log.error("exception occurred while loading: " + e);
-		}
-
-	}
-
-	public static void resolveAndGet(final Tree tree, final String targetPath, final Future<Path> future) {
-		resolve(tree, targetPath, new FutureHandler<Path>(future) {
-			@Override
-			protected void result(final Path path) {
-				assert path.isResolved(targetPath);
-				//TODO Future
-				tree.get(path, Mode.FETCH, new FutureHandler<Object>(future) {
-					@Override
-					protected void result(Object object) {
-						future.pass(path);
-					}
-				});
-			}
-		});
-	}
-
-
-	public static void resolve(final Path path, final Future<Path> future) {
-		final Tree tree = path.getTree();
-		assert tree.isActive();
-		if (path.getTop().getObject() != null) {
-			if (getInfoFromCache(path) != null) {
-				future.pass(path);
-				return;
-			}
-			TreeOperations.findInfo(path, new FutureHandler<FramsClass>(future) {
-				@Override
-				protected void result(FramsClass result) {
-					future.pass(path);
-				}
-			});
-			return;
-		}
-		TreeOperations.findInfo(path, new FutureHandler<FramsClass>(future) {
-			@Override
-			protected void result(FramsClass result) {
-				assert tree.isActive();
-				assert path.getTop().getParam().isMatchingContainedName(result.getId());
-				Path p = (path.getTop().getParam().getContainedTypeName() != null ? path : path.tryFindResolution());
-				future.pass(TreeOperations.createIfNeeded(p));
-			}
-		});
-	}
-
-	public static Path createIfNeeded(Tree tree, String path) {
-		assert tree.isActive();
-		Path p;
-		while (!(p = Path.to(tree, path)).isResolved(path)) {
-			tree.create(p);
-		}
-		return p;
-	}
-
-	public static Path createIfNeeded(Path path) {
-		Tree tree = path.getTree();
-		assert tree.isActive();
-		if (path.isResolved()) {
-			return path;
-		}
-		return tree.create(path);
-	}
+
 
 	public static @Nonnull AccessInterface bindAccess(Tree tree, String path) {
+		log.debug("bind access for textual: " + path + " in " + tree);
 		return bindAccess(Path.to(tree, path));
 	}
 
-	public static @Nonnull AccessInterface bindAccess(Tree tree, Node node) {
+	public static @Nonnull AccessInterface bindAccess(Node node) {
+		Tree tree = node.getTree();
 		assert tree.isActive();
 		assert node.getObject() != null;
@@ -194,5 +144,6 @@
 		assert path.getTree().isActive();
 		path.assureResolved();
-		return bindAccess(path.getTree(), path.getTop());
+		log.debug("bind access for: " + path);
+		return bindAccess(path.getTop());
 	}
 
@@ -219,19 +170,22 @@
 	}
 
+
 	/** This might not be correct. */
-	public static void resolve(final Tree tree, final String targetPath, final Future<Path> future) {
+	public static void tryGet(final Tree tree, final String targetPath, final Future<Path> future) {
+		log.debug("resolve textual: " + targetPath + " for " + tree);
 		dispatchIfNotActive(tree, new RunAt<Tree>(future) {
 
 			@Override
 			protected void runAt() {
-				tree.resolve(Path.to(tree, targetPath), new FutureHandler<Path>(future) {
+				final Path path = Path.to(tree, targetPath);
+				if (path.isResolved()) {
+					future.pass(path);
+					return;
+				}
+
+				tree.get(path, Mode.FETCH, new FutureHandler<Path>(future) {
 					@Override
 					protected void result(Path result) {
-						assert result.getTree().isActive();
-						if (result.isResolved(targetPath)) {
-							future.pass(result);
-							return;
-						}
-						resolve(tree, targetPath, future);
+						tryGet(tree, targetPath, future);
 					}
 				});
Index: /java/main/src/main/java/com/framsticks/diagnostics/Diagnostics.java
===================================================================
--- /java/main/src/main/java/com/framsticks/diagnostics/Diagnostics.java	(revision 97)
+++ /java/main/src/main/java/com/framsticks/diagnostics/Diagnostics.java	(revision 98)
@@ -1,28 +1,8 @@
 package com.framsticks.diagnostics;
 
-import java.util.Date;
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStreamWriter;
-import java.io.PrintWriter;
-import java.text.SimpleDateFormat;
 
-import org.apache.log4j.Logger;
-
-import com.framsticks.core.AbstractTreeListener;
 import com.framsticks.core.Tree;
-import com.framsticks.core.Path;
-import com.framsticks.dumping.PrintWriterSink;
-import com.framsticks.dumping.SaveStream;
 import com.framsticks.params.annotations.AutoAppendAnnotation;
-import com.framsticks.remote.RecursiveFetcher;
-import com.framsticks.util.FramsticksException;
-import com.framsticks.util.PeriodicTask;
-import com.framsticks.util.dispatching.ExceptionResultHandler;
-import com.framsticks.util.dispatching.FutureHandler;
 import com.framsticks.util.dispatching.JoinableCollection;
-import com.framsticks.util.dispatching.ThrowExceptionHandler;
-import com.framsticks.util.io.Encoding;
 
 /**
@@ -30,5 +10,4 @@
  */
 public class Diagnostics extends JoinableCollection<Tree> {
-	private static final Logger log = Logger.getLogger(Diagnostics.class);
 
 
@@ -48,51 +27,51 @@
 		super.add(tree);
 
-		tree.addListener(new AbstractTreeListener() {
-			@Override
-			public void onRun(Exception e) {
-				if (e != null) {
-					return;
-				}
+		// tree.addListener(new AbstractTreeListener() {
+		// 	@Override
+		// 	public void onRun(Exception e) {
+		// 		if (e != null) {
+		// 			return;
+		// 		}
 
-				if (dumpsInterval != null) {
-					new PeriodicTask<Tree>(ThrowExceptionHandler.getInstance(), tree, dumpsInterval * 1000) {
-						protected final ExceptionResultHandler repeater = new ExceptionResultHandler() {
+		// 		if (dumpsInterval != null) {
+		// 			new PeriodicTask<Tree>(ThrowExceptionHandler.getInstance(), tree, dumpsInterval * 1000) {
+		// 				protected final ExceptionResultHandler repeater = new ExceptionResultHandler() {
 
-							@Override
-							public void handle(FramsticksException exception) {
-								log.error("caught error during diagnostics fetching (repeating): " + exception);
-								again();
-							}
+		// 					@Override
+		// 					public void handle(FramsticksException exception) {
+		// 						log.error("caught error during diagnostics fetching (repeating): " + exception);
+		// 						again();
+		// 					}
 
-						};
-						@Override
-						protected void runAt() {
+		// 				};
+		// 				@Override
+		// 				protected void runAt() {
 
-							log.info("starting periodic dump");
-							new RecursiveFetcher(tree, Path.to(tree, "/"), new FutureHandler<Void>(repeater) {
+		// 					log.info("starting periodic dump");
+		// 					new RecursiveFetcher(tree, Path.to(tree, "/"), new FutureHandler<Void>(repeater) {
 
-								@Override
-								protected void result(Void result) {
-									log.info("tree resolved, saving");
-									try {
-										final String fileName = dumpsPath + "/" + tree + "_" + new SimpleDateFormat(dumpsFormat).format(new Date()) + ".param";
-										File file = new File(fileName);
-										new SaveStream(new PrintWriterSink(new PrintWriter(new OutputStreamWriter(new FileOutputStream(file), Encoding.getFramsticksCharset()))), tree, Path.to(tree, "/"), new FutureHandler<Void>(repeater) {
+		// 						@Override
+		// 						protected void result(Void result) {
+		// 							log.info("tree resolved, saving");
+		// 							try {
+		// 								final String fileName = dumpsPath + "/" + tree + "_" + new SimpleDateFormat(dumpsFormat).format(new Date()) + ".param";
+		// 								File file = new File(fileName);
+		// 								new SaveStream(new PrintWriterSink(new PrintWriter(new OutputStreamWriter(new FileOutputStream(file), Encoding.getFramsticksCharset()))), tree, Path.to(tree, "/"), new FutureHandler<Void>(repeater) {
 
-											@Override
-											protected void result(Void result) {
-												again();
-											}
-										});
-									} catch (IOException e) {
-										throw new FramsticksException().msg("failed to initiate dump").cause(e);
-									}
-								}
-							});
-						}
-					};
-				}
-			}
-		});
+		// 									@Override
+		// 									protected void result(Void result) {
+		// 										again();
+		// 									}
+		// 								});
+		// 							} catch (IOException e) {
+		// 								throw new FramsticksException().msg("failed to initiate dump").cause(e);
+		// 							}
+		// 						}
+		// 					});
+		// 				}
+		// 			};
+		// 		}
+		// 	}
+		// });
 
 
Index: /java/main/src/main/java/com/framsticks/dumping/LoadStream.java
===================================================================
--- /java/main/src/main/java/com/framsticks/dumping/LoadStream.java	(revision 97)
+++ /java/main/src/main/java/com/framsticks/dumping/LoadStream.java	(revision 98)
@@ -59,6 +59,8 @@
 					if (line.equals("ok")) {
 						if (query.first.equals("get")) {
-							Path path = TreeOperations.createIfNeeded(tree, query.second);
-							TreeOperations.processFetchedValues(path, files);
+							// Path path = null;
+							throw new UnimplementedException().msg("rework load stream");
+							// Path path = TreeOperations.createIfNeeded(tree, query.second);
+							// TreeOperations.processFetchedValues(path, files);
 						} else if (query.first.equals("info")) {
 							assert files.size() == 1;
Index: /java/main/src/main/java/com/framsticks/dumping/SaveStream.java
===================================================================
--- /java/main/src/main/java/com/framsticks/dumping/SaveStream.java	(revision 97)
+++ /java/main/src/main/java/com/framsticks/dumping/SaveStream.java	(revision 98)
@@ -14,5 +14,4 @@
 import com.framsticks.util.dispatching.Dispatching;
 import com.framsticks.util.dispatching.Future;
-import com.framsticks.util.dispatching.ThrowExceptionHandler;
 
 import org.apache.log4j.Logger;
@@ -48,6 +47,5 @@
 	protected void dispatchWrite(final Path path) {
 		++dispatched;
-		//TODO TEH
-		tree.dispatch(new RunAt<Tree>(ThrowExceptionHandler.getInstance()) {
+		tree.dispatch(new RunAt<Tree>(tree) {
 			@Override
 			protected void runAt() {
@@ -89,5 +87,5 @@
 			}
 			for (CompositeParam p : filterInstanceof(access.getParams(), CompositeParam.class)) {
-				final Path childPath = path.appendNode(new Node(p, access.get(p, Object.class)));
+				final Path childPath = path.appendNode(new Node(path.getTree(), p, access.get(p, Object.class)));
 				if (childPath.isResolved() && getInfoFromCache(childPath) != null) {
 					dispatchWrite(childPath);
Index: /java/main/src/main/java/com/framsticks/gui/AbstractNode.java
===================================================================
--- /java/main/src/main/java/com/framsticks/gui/AbstractNode.java	(revision 98)
+++ /java/main/src/main/java/com/framsticks/gui/AbstractNode.java	(revision 98)
@@ -0,0 +1,18 @@
+package com.framsticks.gui;
+
+
+import com.framsticks.gui.view.TreeCellRenderer;
+
+public abstract class AbstractNode {
+
+	public AbstractNode() {
+	}
+
+	public abstract int getChildCount();
+	public abstract AbstractNode getChild(int number);
+	public abstract int getIndexOfChild(AbstractNode child);
+
+	public abstract boolean isLeaf();
+	public abstract void render(TreeCellRenderer renderer);
+
+}
Index: /java/main/src/main/java/com/framsticks/gui/Browser.java
===================================================================
--- /java/main/src/main/java/com/framsticks/gui/Browser.java	(revision 97)
+++ /java/main/src/main/java/com/framsticks/gui/Browser.java	(revision 98)
@@ -14,5 +14,4 @@
 import com.framsticks.util.dispatching.ExceptionResultHandler;
 import com.framsticks.util.dispatching.Future;
-import com.framsticks.util.dispatching.FutureHandler;
 import com.framsticks.util.dispatching.Joinable;
 import com.framsticks.util.dispatching.JoinableCollection;
@@ -46,4 +45,5 @@
 
 	protected final List<PopupMenuEntryProvider> popupMenuEntryProviders = new LinkedList<>();
+	// protected final SwingDispatcher
 
 	protected final MainFrame mainFrame;
@@ -63,4 +63,7 @@
 
 		mainFrame = new MainFrame(Browser.this);
+
+		// mainFrame.getStatusBar().setExceptionHandler(ThrowExceptionHandler.getInstance());
+
 		addFrame(mainFrame);
 
@@ -120,26 +123,27 @@
 	public void addTree(Tree tree) {
 		log.info("adding tree: " + tree);
+		tree.setDispatcher(new SwingDispatcher<Tree>());
 		trees.add(tree);
 	}
 
 	public void autoResolvePath(final String path, final Future<Path> future) {
-		final Tree i = trees.get("localhost");
-		i.dispatch(new RunAt<Tree>(future) {
-			@Override
-			protected void runAt() {
-				TreeOperations.resolveAndGet(i, path, new FutureHandler<Path>(future) {
-					@Override
-					protected void result(final Path p) {
-						future.pass(p);
-						mainFrame.dispatch(new RunAt<Frame>(future) {
-							@Override
-							protected void runAt() {
-								mainFrame.goTo(p);
-							}
-						});
-					}
-				});
-			}
-		});
+		// final Tree i = trees.get("localhost");
+		// i.dispatch(new RunAt<Tree>(future) {
+		// 	@Override
+		// 	protected void runAt() {
+		// 		TreeOperations.tryGet(i, path, new FutureHandler<Path>(future) {
+		// 			@Override
+		// 			protected void result(final Path p) {
+		// 				future.pass(p);
+		// 				mainFrame.dispatch(new RunAt<Frame>(future) {
+		// 					@Override
+		// 					protected void runAt() {
+		// 						mainFrame.goTo(p);
+		// 					}
+		// 				});
+		// 			}
+		// 		});
+		// 	}
+		// });
 	}
 
@@ -284,7 +288,22 @@
 	}
 
-	// @Override
-	// public boolean isDone() {
-	//	return frames.isDone() && trees.isDone();
+	// final protected Map<EventParam, Subscription<?>> userSubscriptions = new HashMap<>();
+	// public boolean hasSubscribed(EventParam param) {
+	// 	assert frame.isActive();
+	// 	return userSubscriptions.containsKey(param);
 	// }
+
+	// public void unsubscribe(EventParam eventParam) {
+	// 	assert frame.isActive();
+	// 	if (!hasSubscribed(eventParam)) {
+	// 		log.error("could not unsubscribe from " + eventParam);
+	// 		return;
+	// 	}
+	// 	userSubscriptions.get(eventParam).unsubscribe(new LoggingStateCallback(log, "unsubscribed " + eventParam));
+	// 	userSubscriptions.remove(eventParam);
+	// }
+
+
+
+
 }
Index: /java/main/src/main/java/com/framsticks/gui/EmptyNode.java
===================================================================
--- /java/main/src/main/java/com/framsticks/gui/EmptyNode.java	(revision 98)
+++ /java/main/src/main/java/com/framsticks/gui/EmptyNode.java	(revision 98)
@@ -0,0 +1,50 @@
+package com.framsticks.gui;
+
+
+import com.framsticks.gui.view.TreeCellRenderer;
+import com.framsticks.params.CompositeParam;
+
+public class EmptyNode extends AbstractNode {
+
+	protected final CompositeParam param;
+
+	/**
+	 * @param param
+	 */
+	public EmptyNode(CompositeParam param) {
+		this.param = param;
+	}
+
+	@Override
+	public int getChildCount() {
+		return 0;
+	}
+
+	@Override
+	public AbstractNode getChild(int number) {
+		return null;
+	}
+
+	@Override
+	public int getIndexOfChild(AbstractNode child) {
+		return -1;
+	}
+
+	@Override
+	public boolean isLeaf() {
+		return true;
+	}
+
+	@Override
+	public void render(TreeCellRenderer renderer) {
+		renderer.setIcon(ImageProvider.loadImage(TreeCellRenderer.findIconName(param)));
+		renderer.setText(param.getId());
+		renderer.setToolTipText("?");
+	}
+
+	@Override
+	public String toString() {
+		return param.toString();
+	}
+
+}
Index: /java/main/src/main/java/com/framsticks/gui/Frame.java
===================================================================
--- /java/main/src/main/java/com/framsticks/gui/Frame.java	(revision 97)
+++ /java/main/src/main/java/com/framsticks/gui/Frame.java	(revision 98)
@@ -11,5 +11,5 @@
 import java.awt.event.MouseAdapter;
 import java.awt.event.MouseEvent;
-import java.util.HashMap;
+import java.util.IdentityHashMap;
 import java.util.Map;
 
@@ -28,10 +28,8 @@
 import javax.swing.ToolTipManager;
 import javax.swing.UIManager;
-import javax.swing.event.TreeModelEvent;
-import javax.swing.event.TreeModelListener;
+import javax.swing.event.TreeExpansionEvent;
+import javax.swing.event.TreeExpansionListener;
 import javax.swing.event.TreeSelectionEvent;
 import javax.swing.event.TreeSelectionListener;
-import javax.swing.tree.DefaultMutableTreeNode;
-import javax.swing.tree.DefaultTreeModel;
 import javax.swing.tree.DefaultTreeSelectionModel;
 import javax.swing.tree.TreePath;
@@ -40,16 +38,16 @@
 import org.apache.log4j.Logger;
 
+import com.framsticks.core.Mode;
 import com.framsticks.core.Path;
 import com.framsticks.core.Tree;
+import com.framsticks.core.TreeOperations;
 import com.framsticks.gui.view.TreeCellRenderer;
-import com.framsticks.util.FramsticksException;
+import com.framsticks.params.AccessInterface;
 import com.framsticks.util.dispatching.Dispatching;
-import com.framsticks.util.dispatching.ExceptionResultHandler;
+import com.framsticks.util.dispatching.FutureHandler;
 import com.framsticks.util.dispatching.Joinable;
 import com.framsticks.util.dispatching.JoinableCollection;
 import com.framsticks.util.dispatching.JoinableParent;
 import com.framsticks.util.dispatching.JoinableState;
-import com.framsticks.util.dispatching.RunAt;
-import com.framsticks.util.lang.ScopeEnd;
 import com.framsticks.util.swing.KeyboardModifier;
 import com.framsticks.util.swing.MenuConstructor;
@@ -72,11 +70,12 @@
 	protected JScrollPane treeScrollPane;
 	protected JTree jtree;
-	protected DefaultTreeModel treeModel;
-	protected javax.swing.tree.MutableTreeNode rootNode;
+	protected TreeModel treeModel;
+
+	protected MetaNode rootNode;
+
 	protected JPanel treePanel;
 	protected JPopupMenu treePopupMenu;
 	protected JMenuItem treePopupMenuHeader;
 
-	TreeNode currentlyPoppedTreeNode;
 	protected JPanel mainPanel;
 	protected JPanel leftPanel;
@@ -91,6 +90,6 @@
 	protected JMenu helpMenu;
 
-	protected final Map<Tree, TreeAtFrame> treeAtFrames = new HashMap<Tree, TreeAtFrame>();
-	protected JoinableCollection<Tree> trees = new JoinableCollection<Tree>();
+	protected final Map<Tree, TreeAtFrame> treeAtFrames = new IdentityHashMap<>();
+	protected JoinableCollection<Tree> trees = new JoinableCollection<>();
 
 	public Frame(Browser browser) {
@@ -106,5 +105,4 @@
 		log.debug("creating " + this);
 
-
 		Container contentPane = getSwing().getContentPane();
 		treePopupMenu = new JPopupMenu("title");
@@ -114,27 +112,7 @@
 		treePanel.setLayout(new BorderLayout());
 
-		treeModel = new DefaultTreeModel(null);
-		treeModel.addTreeModelListener(new TreeModelListener() {
-
-			@Override
-			public void treeNodesChanged(TreeModelEvent arg0) {
-				log.trace("treeNodesChanged: " + arg0);
-			}
-
-			@Override
-			public void treeNodesInserted(TreeModelEvent arg0) {
-				// log.trace("treeNodesInserted: " + arg0);
-			}
-
-			@Override
-			public void treeNodesRemoved(TreeModelEvent arg0) {
-				log.trace("treeNodesRemoved: " + arg0);
-			}
-
-			@Override
-			public void treeStructureChanged(TreeModelEvent arg0) {
-				log.trace("treeStructureChanged: " + arg0);
-			}
-		});
+		rootNode = new MetaNode();
+		rootNode.setName("root");
+		treeModel = new TreeModel(this);
 
 		jtree = new JTree(treeModel);
@@ -152,7 +130,19 @@
 		});
 
+		jtree.addTreeExpansionListener(new TreeExpansionListener() {
+
+			@Override
+			public void treeCollapsed(TreeExpansionEvent e) {
+
+			}
+
+			@Override
+			public void treeExpanded(TreeExpansionEvent e) {
+				loadChildren(treeModel.convertToPath(e.getPath()), false);
+			}
+		});
+
 		jtree.setExpandsSelectedPaths(true);
 		jtree.setEditable(false);
-		jtree.setDoubleBuffered(true);
 		jtree.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
 		jtree.setShowsRootHandles(true);
@@ -173,5 +163,9 @@
 		});
 
-		new KeyboardModifier(jtree, JComponent.WHEN_FOCUSED).join(KeyStroke.getKeyStroke('h'), KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0)).join(KeyStroke.getKeyStroke('j'), KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0)).join(KeyStroke.getKeyStroke('k'), KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0)).join(KeyStroke.getKeyStroke('l'), KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0));
+		new KeyboardModifier(jtree, JComponent.WHEN_FOCUSED)
+			.join(KeyStroke.getKeyStroke('h'), KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0))
+			.join(KeyStroke.getKeyStroke('j'), KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0))
+			.join(KeyStroke.getKeyStroke('k'), KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0))
+			.join(KeyStroke.getKeyStroke('l'), KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0));
 
 		jtree.setCellRenderer(new TreeCellRenderer());
@@ -182,7 +176,4 @@
 		treePanel.add(treeScrollPane);
 
-		rootNode = new DefaultMutableTreeNode();
-		rootNode.setUserObject("root");
-		treeModel.setRoot(rootNode);
 
 		normalWorkPanel = new JPanel();
@@ -248,4 +239,12 @@
 		});
 
+		new MenuConstructor(fileMenu).add(KeyStroke.getKeyStroke(KeyEvent.VK_R, ActionEvent.CTRL_MASK), new AbstractAction("Reload current") {
+			@Override
+			public void actionPerformed(ActionEvent actionEvent) {
+
+				loadPath(treeModel.convertToPath(jtree.getSelectionPath()), true);
+			}
+		});
+
 	}
 
@@ -254,16 +253,30 @@
 	}
 
-	public void addRootPath(Path path) {
+	public void addRootPath(final Path path) {
 		assert isActive();
+
 		Tree tree = path.getTree();
+
+		log.info("trying mount: " + path);
+		if (!tree.getAssignedRoot().isResolved()) {
+			tree.get(path, Mode.FETCH, new FutureHandler<Path>(this) {
+
+				@Override
+				protected void result(Path result) {
+					addRootPath(result);
+				}
+			});
+			return;
+		}
+
 		assert browser.getTrees().contains(tree);
 
 		TreeAtFrame e = new TreeAtFrame(tree, this);
-		tree.addListener(e);
 		treeAtFrames.put(tree, e);
-		TreeNode node = new TreeNode(e, path);
-		e.rootTreeNode = node;
-		treeModel.insertNodeInto(node, rootNode, rootNode.getChildCount());
-		jtree.expandPath(new TreePath(rootNode));
+
+		rootNode.getChildren().add(new TreeNode(tree.getAssignedRoot()));
+		e.rootNode = tree.getAssignedRoot();
+		treeModel.nodeStructureChanged(new TreePath(rootNode));
+		// jtree.expandPath(new TreePath(rootNode));
 	}
 
@@ -275,4 +288,5 @@
 	}
 
+
 	private void showPopup(MouseEvent e) {
 		assert isActive();
@@ -280,10 +294,7 @@
 			return;
 		}
-		currentlyPoppedTreeNode = findTreeNodeByTreePath(jtree.getPathForLocation(e.getX(), e.getY()));
-		if (currentlyPoppedTreeNode == null) {
-			return;
-		}
-
-		Path path = currentlyPoppedTreeNode.getTreePath();
+		TreePath treePath = jtree.getPathForLocation(e.getX(), e.getY());
+
+		Path path = treeModel.convertToPath(treePath);
 		treePopupMenu.removeAll();
 
@@ -291,16 +302,8 @@
 			provider.provide(treePopupMenu, path);
 		}
-		// treePopupMenuHeader.setText(path.getTree().getName() + path.getTextual());
 		treePopupMenu.show(e.getComponent(), e.getX(), e.getY());
-		//currentlyPoppedPanel.getNode().getFramsClass().getName()
-	}
-
-	public TreeNode getCurrentlyPoppedTreeNode() {
-		assert isActive();
-		return currentlyPoppedTreeNode;
 	}
 
 	public void clear() {
-		treeModel.setRoot(null);
 		cardPanel.removeAll();
 		cardPanel.updateUI();
@@ -308,82 +311,76 @@
 	}
 
-	public ScopeEnd startChange(final DefaultMutableTreeNode node) {
-		assert isActive();
-		final TreePath selection = jtree.getSelectionPath();
-		return new ScopeEnd() {
-			@Override
-			public void close() {
-				assert isActive();
-				treeModel.nodeChanged(node);
-				jtree.setSelectionPath(selection);
-			}
-		};
-	}
-
-	public void selectTreeNode(final TreeNode treeNode) {
-		assert isActive();
-		/*		final Panel panel = treeNode.getOrCreatePanel();
-		 if (panel == null) {
-		 return;
-		 }
-		 panel.setCurrentTreeNode(treeNode);
-		 treeNode.updateData();
-		 showPanel(panel);*/
-	}
-
-	public TreeNode findTreeNodeByTreePath(TreePath treePath) {
+	public void loadChildren(Path path, boolean reload) {
+		if (path == null) {
+			return;
+		}
+		AccessInterface access = TreeOperations.bindAccess(path);
+
+		int count = access.getCompositeParamCount();
+		for (int i = 0; i < count; ++i) {
+			Path childPath = path.appendParam(access.getCompositeParam(i)).tryFindResolution();
+			loadPath(childPath, reload);
+		}
+
+	}
+
+	public void loadPath(Path path, boolean reload) {
+		if (path == null) {
+			return;
+		}
+		if (path.isResolved() && !reload) {
+			return;
+		}
+		path.getTree().get(path, Mode.FETCH, new FutureHandler<Path>(this) {
+			@Override
+			protected void result(Path result) {
+				final TreePath treePath = treeModel.convertToTreePath(result);
+
+				treeModel.nodeStructureChanged(treePath);
+				if (treePath.equals(jtree.getSelectionPath())) {
+					treeAtFrames.get(result.getTree()).useOrCreatePanel(treePath);
+				}
+			}
+		});
+	}
+
+	public void chooseTreeNode(final TreePath treePath) {
 		assert isActive();
 		if (treePath == null) {
-			return null;
-		}
-		if (!(treePath.getLastPathComponent() instanceof TreeNode)) {
-			return null;
-		}
-		return (TreeNode) treePath.getLastPathComponent();
-	}
-
-	public void chooseTreeNode(TreePath treePath) {
-		assert isActive();
-		final TreeNode treeNode = findTreeNodeByTreePath(treePath);
-		if (treeNode == null) {
-			return;
-		}
-		treeNode.select();
-	}
-
-	protected final ExceptionResultHandler dialogHandler = new ExceptionResultHandler() {
-
-		@Override
-		public void handle(FramsticksException exception) {
-			//TODO TEH
-			throw exception;
-
-		}
-	};
-
-	public void goTo(Path path) {
-		assert isActive();
-		final TreePath treePath = treeAtFrames.get(path.getTree()).getTreePath(path, false);
-		log.info("go to path: " + path + "(" + treePath + ")");
-
-		this.dispatch(new RunAt<Frame>(dialogHandler) {
-			@Override
-			protected void runAt() {
-				log.info("executed");
-				jtree.setSelectionPath(treePath);
-				jtree.makeVisible(treePath);
-				assert jtree.isVisible(treePath);
-			}
-		});
-
-	}
-
-	public void addNode(TreeNode child, DefaultMutableTreeNode parent) {
-		assert isActive();
-
-		try (ScopeEnd e = startChange(parent)) {
-			treeModel.insertNodeInto(child, parent, parent.getChildCount());
-		}
-	}
+			return;
+		}
+		if (treeModel.isChanging()) {
+			return;
+		}
+
+		Path path = treeModel.convertToPath(treePath);
+		if (path == null) {
+			return;
+		}
+		path = path.assureResolved();
+		final Tree tree = path.getTree();
+
+		treeAtFrames.get(tree).useOrCreatePanel(treePath);
+		loadChildren(path, false);
+
+	}
+
+
+	// public void goTo(Path path) {
+	//	assert isActive();
+	//	final TreePath treePath = treeModel.convertToTreePath(path);
+	//	log.info("go to path: " + path + "(" + treePath + ")");
+
+	//	this.dispatch(new RunAt<Frame>(this) {
+	//		@Override
+	//		protected void runAt() {
+	//			log.info("executed");
+	//			jtree.setSelectionPath(treePath);
+	//			jtree.makeVisible(treePath);
+	//			assert jtree.isVisible(treePath);
+	//		}
+	//	});
+
+	// }
 
 	@Override
@@ -422,3 +419,10 @@
 	}
 
+	/**
+	 * @return the treeModel
+	 */
+	public TreeModel getTreeModel() {
+		return treeModel;
+	}
+
 }
Index: /java/main/src/main/java/com/framsticks/gui/ImageProvider.java
===================================================================
--- /java/main/src/main/java/com/framsticks/gui/ImageProvider.java	(revision 97)
+++ /java/main/src/main/java/com/framsticks/gui/ImageProvider.java	(revision 98)
@@ -7,6 +7,7 @@
 
 import javax.swing.*;
+
 import java.util.HashMap;
-import java.util.LinkedHashMap;
+import java.util.Map;
 
 /**
@@ -21,12 +22,12 @@
 	 * HashMap stores icons. Key is icon path, Value is icon.
 	 */
-	private static HashMap<String, ImageIcon> icons = new LinkedHashMap<String, ImageIcon>();
+	private static Map<String, ImageIcon> icons = new HashMap<String, ImageIcon>();
 
 	public static final String IMAGE = "image.png";
 	public static final String LOGO = "logo.png";
 
-	//public static final String FOLDER_OPEN = "folder_open.png";
-	//public static final String FOLDER_CLOSED = "folder_close.png";
-	//public static final String NODE = "node.png";
+	public static final String FOLDER_OPEN = "folder_open.png";
+	public static final String FOLDER_CLOSED = "folder_close.png";
+	public static final String NODE = "node.png";
 
 	public static final String SERVER = "server.png";
Index: /java/main/src/main/java/com/framsticks/gui/ListPanelProvider.java
===================================================================
--- /java/main/src/main/java/com/framsticks/gui/ListPanelProvider.java	(revision 98)
+++ /java/main/src/main/java/com/framsticks/gui/ListPanelProvider.java	(revision 98)
@@ -0,0 +1,15 @@
+package com.framsticks.gui;
+
+import com.framsticks.params.types.ListParam;
+
+public class ListPanelProvider implements PanelProvider {
+
+	@Override
+	public Panel providePanel(Panel.Parameters parameters) {
+		if (parameters.param instanceof ListParam) {
+			return new ListPanel(parameters);
+		}
+		return null;
+	}
+
+}
Index: /java/main/src/main/java/com/framsticks/gui/MetaNode.java
===================================================================
--- /java/main/src/main/java/com/framsticks/gui/MetaNode.java	(revision 98)
+++ /java/main/src/main/java/com/framsticks/gui/MetaNode.java	(revision 98)
@@ -0,0 +1,67 @@
+package com.framsticks.gui;
+
+import java.util.LinkedList;
+import java.util.List;
+
+
+import com.framsticks.gui.view.TreeCellRenderer;
+
+public class MetaNode extends AbstractNode {
+
+	protected List<AbstractNode> children = new LinkedList<>();
+	protected String name = "meta node";
+
+	/**
+	 * @return the children
+	 */
+	public List<AbstractNode> getChildren() {
+		return children;
+	}
+
+	/**
+	 * @return the name
+	 */
+	public String getName() {
+		return name;
+	}
+
+	/**
+	 * @param name the name to set
+	 */
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	@Override
+	public int getChildCount() {
+		return children.size();
+	}
+
+	@Override
+	public AbstractNode getChild(int number) {
+		return children.get(number);
+	}
+
+	@Override
+	public int getIndexOfChild(AbstractNode child) {
+		return children.indexOf(child);
+	}
+
+	@Override
+	public String toString() {
+		return name;
+	}
+
+	@Override
+	public boolean isLeaf() {
+		return false;
+	}
+
+	@Override
+	public void render(TreeCellRenderer renderer) {
+		renderer.setIcon(ImageProvider.loadImage(ImageProvider.SERVER));
+		renderer.setText(name);
+		renderer.setToolTipText("?");
+	}
+
+}
Index: /java/main/src/main/java/com/framsticks/gui/ModifiablePanel.java
===================================================================
--- /java/main/src/main/java/com/framsticks/gui/ModifiablePanel.java	(revision 97)
+++ /java/main/src/main/java/com/framsticks/gui/ModifiablePanel.java	(revision 98)
@@ -2,4 +2,5 @@
 
 import org.apache.log4j.Logger;
+
 
 import javax.swing.*;
@@ -65,9 +66,4 @@
 	}
 
-	@Override
-	public void setCurrentTreeNode(TreeNode node) {
-		super.setCurrentTreeNode(node);
-	}
-
 	protected abstract void applyChanges();
 
Index: /java/main/src/main/java/com/framsticks/gui/MultiPanel.java
===================================================================
--- /java/main/src/main/java/com/framsticks/gui/MultiPanel.java	(revision 97)
+++ /java/main/src/main/java/com/framsticks/gui/MultiPanel.java	(revision 98)
@@ -4,4 +4,6 @@
 
 import javax.swing.*;
+import javax.swing.tree.TreePath;
+
 import java.awt.*;
 import java.util.List;
@@ -46,8 +48,8 @@
 
 	@Override
-	public void setCurrentTreeNode(TreeNode currentTreeNode) {
-		super.setCurrentTreeNode(currentTreeNode);
+	public void setCurrentTreePath(TreePath currentTreePath) {
+		super.setCurrentTreePath(currentTreePath);
 		for (Panel p : panels) {
-			p.setCurrentTreeNode(currentTreeNode);
+			p.setCurrentTreePath(currentTreePath);
 		}
 	}
Index: /java/main/src/main/java/com/framsticks/gui/NodeAtFrame.java
===================================================================
--- /java/main/src/main/java/com/framsticks/gui/NodeAtFrame.java	(revision 98)
+++ /java/main/src/main/java/com/framsticks/gui/NodeAtFrame.java	(revision 98)
@@ -0,0 +1,14 @@
+package com.framsticks.gui;
+
+import java.util.IdentityHashMap;
+import java.util.Map;
+
+import com.framsticks.gui.controls.ValueControl;
+
+public class NodeAtFrame {
+
+	protected Panel panel;
+
+	protected final Map<ValueControl, Object> localChanges = new IdentityHashMap<>();
+
+}
Index: /java/main/src/main/java/com/framsticks/gui/ObjectPanel.java
===================================================================
--- /java/main/src/main/java/com/framsticks/gui/ObjectPanel.java	(revision 97)
+++ /java/main/src/main/java/com/framsticks/gui/ObjectPanel.java	(revision 98)
@@ -12,20 +12,20 @@
 
 import javax.swing.*;
+import javax.swing.tree.TreePath;
 
 import java.util.Collection;
-import java.util.HashMap;
+import java.util.IdentityHashMap;
 import java.util.Map;
 import static com.framsticks.util.lang.Containers.filterInstanceof;
 
 import com.framsticks.util.FramsticksException;
-import com.framsticks.util.dispatching.RunAt;
 
 @SuppressWarnings("serial")
 public class ObjectPanel extends ModifiablePanel implements ControlOwner {
 
-	private static final Logger log = Logger.getLogger(ObjectPanel.class.getName());
+	private static final Logger log = Logger.getLogger(ObjectPanel.class);
 
-	final protected Map<Param, Control> components = new HashMap<Param, Control>();
-	final protected Map<ValueParam, ValueControl> valueControls = new HashMap<ValueParam, ValueControl>();
+	final protected Map<Param, Control> components = new IdentityHashMap<Param, Control>();
+	final protected Map<ValueParam, ValueControl> valueControls = new IdentityHashMap<ValueParam, ValueControl>();
 
 	public ObjectPanel(Panel.Parameters parameters, Collection<Param> params) {
@@ -37,11 +37,12 @@
 		for (final ValueControl c : filterInstanceof(components.values(), ValueControl.class)) {
 			valueControls.put(c.getParam(), c);
+			c.setUserEnabled(true);
 			c.setListener(new ValueControlListener() {
 				@Override
 				public boolean onChange(Object newValue) {
-					if (currentTreeNode == null) {
+					if (currentTreePath == null) {
 						return true;
 					}
-					boolean result = currentTreeNode.changeValue(c, newValue);
+					boolean result = treeAtFrame.changeValue(currentTreePath, c, newValue);
 					refreshControlButtons();
 					return result;
@@ -57,11 +58,11 @@
 	protected void applyChanges() {
 		assert frame.isActive();
-		assert currentTreeNode != null;
-		currentTreeNode.pushLocalChanges();
+		assert currentTreePath != null;
+		treeAtFrame.pushLocalChanges(currentTreePath);
 	}
 
 	protected void refreshControlButtons() {
 		assert frame.isActive();
-		applyButton.setEnabled(currentTreeNode.localChanges != null);
+		applyButton.setEnabled(treeAtFrame.hasLocalChanges(currentTreePath));
 	}
 
@@ -71,28 +72,25 @@
 	@Override
 	public void pullValuesFromLocalToUser(AccessInterface access) {
-		assert currentTreeNode != null;
-		assert currentTreeNode.path.getTree().isActive();
+		assert currentTreePath != null;
 		log.debug("refreshing components");
 
-		final Map<ValueControl, Object> values = new HashMap<ValueControl, Object>();
+		final Map<ValueControl, Object> values = new IdentityHashMap<ValueControl, Object>();
 		for (Map.Entry<ValueParam, ValueControl> e : valueControls.entrySet()) {
 			values.put(e.getValue(), access.get(e.getKey().getId(), Object.class));
 		}
 
-		frame.dispatch(new RunAt<Frame>(frame) {
-			@Override
-			protected void runAt() {
-				if (currentTreeNode.localChanges != null) {
-					for (Map.Entry<ValueControl, Object> e : currentTreeNode.localChanges.entrySet()) {
-						values.put(e.getKey(), e.getValue());
-					}
-				}
-				for (Map.Entry<ValueControl, Object> e : values.entrySet()) {
-					e.getKey().pushValueToUserInterface(e.getValue());
-				}
-				refreshControlButtons();
-				ObjectPanel.this.revalidate();
+
+		NodeAtFrame nodeAtFrame = treeAtFrame.getLocalInfo(currentTreePath);
+		if (nodeAtFrame != null) {
+			for (Map.Entry<ValueControl, Object> e : nodeAtFrame.localChanges.entrySet()) {
+				values.put(e.getKey(), e.getValue());
 			}
-		});
+		}
+
+		for (Map.Entry<ValueControl, Object> e : values.entrySet()) {
+			e.getKey().pushValueToUserInterface(e.getValue());
+		}
+		refreshControlButtons();
+		ObjectPanel.this.revalidate();
 
 	}
@@ -109,34 +107,13 @@
 
 	@Override
-	public TreeNode getCurrentTreeNode() {
-		return super.getCurrentTreeNode();
-	}
-
-	@Override
 	public void handle(FramsticksException exception) {
 		frame.handle(exception);
 	}
 
-	// public void updateValue() {
-	//	//assert panel.getFrame().isActive();
+	@Override
+	public TreePath getCurrentTreePath() {
+		return super.getCurrentTreePath();
+	}
 
-	//	final Node n = panel.getCurrentNode();
-	//	panel.getBrowser().getManager().invokeLater(new Runnable() {
-	//		@Override
-	//		public void run() {
-	//			Object v = n.getAccess().get(param, Object.class);
-	//			if (v == null) {
-	//				v = param.getDef(Object.class);
-	//			}
-	//			final Object fv = v;
-	//			panel.getBrowser().invokeLater(new Runnable() {
-	//				@Override
-	//				public void run() {
-	//					setValueImpl(fv);
-	//				}
-	//			});
-	//		}
-	//	});
-	// }
 
 }
Index: /java/main/src/main/java/com/framsticks/gui/Panel.java
===================================================================
--- /java/main/src/main/java/com/framsticks/gui/Panel.java	(revision 97)
+++ /java/main/src/main/java/com/framsticks/gui/Panel.java	(revision 98)
@@ -4,7 +4,9 @@
 import com.framsticks.params.CompositeParam;
 import com.framsticks.params.FramsClass;
-// import org.apache.log4j.Logger;
 
 import javax.swing.*;
+import javax.swing.tree.TreePath;
+
+import org.apache.log4j.Logger;
 
 /**
@@ -13,4 +15,7 @@
 @SuppressWarnings("serial")
 public abstract class Panel extends JPanel {
+
+	private static final Logger log = Logger.getLogger(Panel.class);
+
 
 	public static class Parameters {
@@ -28,5 +33,5 @@
 	// private static final Logger log = Logger.getLogger(Panel.class.getName());
 
-	protected TreeNode currentTreeNode;
+	protected TreePath currentTreePath;
 	protected final TreeAtFrame treeAtFrame;
 	protected final Frame frame;
@@ -43,16 +48,25 @@
 		this.className = parameters.param.getContainedTypeName();
 		this.setName(parameters.param.getFramsTypeName());
+		log.debug("created panel: " + this);
 	}
 
-	public void setCurrentTreeNode(TreeNode currentTreeNode) {
-		this.currentTreeNode = currentTreeNode;
-	}
 
-	public TreeNode getCurrentTreeNode() {
-		return currentTreeNode;
-	}
 
 	public final Frame getFrame() {
 		return frame;
+	}
+
+	/**
+	 * @return the currentTreePath
+	 */
+	public TreePath getCurrentTreePath() {
+		return currentTreePath;
+	}
+
+	/**
+	 * @param currentTreePath the currentTreePath to set
+	 */
+	public void setCurrentTreePath(TreePath currentTreePath) {
+		this.currentTreePath = currentTreePath;
 	}
 
@@ -70,5 +84,5 @@
 	@Override
 	public String toString() {
-		return uniqueName;
+		return param.toString() + "(" + uniqueName + ")";
 	}
 
Index: /java/main/src/main/java/com/framsticks/gui/StatusBar.java
===================================================================
--- /java/main/src/main/java/com/framsticks/gui/StatusBar.java	(revision 97)
+++ /java/main/src/main/java/com/framsticks/gui/StatusBar.java	(revision 98)
@@ -22,4 +22,5 @@
 	protected JTextField statusBar;
 	protected JPanel swing;
+	protected ExceptionResultHandler exceptionHandler;
 
 	/**
@@ -35,6 +36,9 @@
 			@Override
 			protected void runAt() {
-				log.error("error: " + exception);
+				log.error("error: ", exception);
 				statusBar.setText(exception.getShortMessage(new StringBuilder()).toString());
+				if (exceptionHandler != null) {
+					exceptionHandler.handle(exception);
+				}
 			}
 		});
@@ -70,3 +74,17 @@
 	}
 
+	/**
+	 * @return the exceptionHandler
+	 */
+	public ExceptionResultHandler getExceptionHandler() {
+		return exceptionHandler;
+	}
+
+	/**
+	 * @param exceptionHandler the exceptionHandler to set
+	 */
+	public void setExceptionHandler(ExceptionResultHandler exceptionHandler) {
+		this.exceptionHandler = exceptionHandler;
+	}
+
 }
Index: /java/main/src/main/java/com/framsticks/gui/SwingDispatcher.java
===================================================================
--- /java/main/src/main/java/com/framsticks/gui/SwingDispatcher.java	(revision 97)
+++ /java/main/src/main/java/com/framsticks/gui/SwingDispatcher.java	(revision 98)
@@ -1,5 +1,10 @@
 package com.framsticks.gui;
 
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import com.framsticks.util.dispatching.AbstractJoinable;
 import com.framsticks.util.dispatching.Dispatcher;
+import com.framsticks.util.dispatching.JoinableDispatcher;
 import com.framsticks.util.dispatching.Task;
 import com.framsticks.util.dispatching.ThrowExceptionHandler;
@@ -11,5 +16,5 @@
  * @author Piotr Sniegowski
  */
-public class SwingDispatcher<C> implements Dispatcher<C> {
+public class SwingDispatcher<C> extends AbstractJoinable implements JoinableDispatcher<C> {
 
 	@SuppressWarnings("rawtypes")
@@ -37,7 +42,47 @@
 	@Override
 	public final void dispatch(RunAt<? extends C> runnable) {
-		assert !(runnable instanceof Task);
+		if (runnable instanceof Task) {
+			final Task<?> task = (Task<?>) runnable;
+			Timer timer = new Timer(0, null);
+			timer.addActionListener(new ActionListener() {
+
+				@Override
+				public void actionPerformed(ActionEvent event) {
+					task.run();
+				}
+
+			});
+			timer.setInitialDelay((int) (task.getMoment() - System.currentTimeMillis()));
+			timer.setRepeats(false);
+			timer.start();
+			return;
+		}
 		SwingUtilities.invokeLater(runnable);
 	}
 
+	@Override
+	public String getName() {
+		return "gui";
+	}
+
+	@Override
+	protected void joinableStart() {
+
+	}
+
+	@Override
+	protected void joinableInterrupt() {
+		finish();
+	}
+
+	@Override
+	protected void joinableFinish() {
+
+	}
+
+	@Override
+	protected void joinableJoin() throws InterruptedException {
+
+	}
+
 }
Index: /java/main/src/main/java/com/framsticks/gui/TreeAtFrame.java
===================================================================
--- /java/main/src/main/java/com/framsticks/gui/TreeAtFrame.java	(revision 97)
+++ /java/main/src/main/java/com/framsticks/gui/TreeAtFrame.java	(revision 98)
@@ -4,8 +4,8 @@
 
 import com.framsticks.core.Tree;
-import com.framsticks.core.TreeListener;
-import com.framsticks.core.ListChange;
 import com.framsticks.core.Node;
 import com.framsticks.core.Path;
+import com.framsticks.core.TreeOperations;
+import com.framsticks.gui.controls.ValueControl;
 import com.framsticks.params.CompositeParam;
 import com.framsticks.params.FramsClass;
@@ -14,10 +14,13 @@
 
 import javax.swing.tree.TreePath;
-import com.framsticks.util.dispatching.RunAt;
+
+
+import com.framsticks.util.dispatching.FutureHandler;
+import com.framsticks.util.lang.Casting;
 
 /**
  * @author Piotr Sniegowski
  */
-public class TreeAtFrame implements TreeListener {
+public class TreeAtFrame {
 
 	private static final Logger log = Logger.getLogger(TreeAtFrame.class);
@@ -26,5 +29,7 @@
 	protected final Tree tree;
 	protected final Map<String, Panel> knownPanels = new HashMap<String, Panel>();
-	protected TreeNode rootTreeNode;
+	protected Node rootNode;
+
+	protected Map<TreeNode, NodeAtFrame> nodesStorage = new WeakHashMap<>();
 
 	public TreeAtFrame(Tree tree, Frame frame) {
@@ -90,90 +95,88 @@
 	}
 
-	@Override
-	public void onListChange(Path path, ListChange change) {
+	public boolean hasLocalChanges(TreePath treePath) {
+		NodeAtFrame nodeAtFrame = nodesStorage.get(treePath.getLastPathComponent());
+		if (nodeAtFrame == null) {
+			return false;
+		}
+		return !nodeAtFrame.localChanges.isEmpty();
+	}
+
+	public NodeAtFrame assureLocalInfo(TreePath treePath) {
+		assert frame.isActive();
+		NodeAtFrame nodeAtFrame = nodesStorage.get(treePath.getLastPathComponent());
+
+		if (nodeAtFrame == null) {
+			nodeAtFrame = new NodeAtFrame();
+			nodesStorage.put(Casting.throwCast(TreeNode.class, treePath.getLastPathComponent()), nodeAtFrame);
+		}
+		return nodeAtFrame;
+	}
+
+	public NodeAtFrame getLocalInfo(TreePath treePath) {
+		return nodesStorage.get(treePath.getLastPathComponent());
+	}
+
+	public boolean changeValue(TreePath treePath, ValueControl component, Object newValue) {
+		log.debug("changing value of " + component + " to '" + newValue + "'");
+
+		assureLocalInfo(treePath).localChanges.put(component, newValue);
+
+		return true;
+	}
+
+	public void pushLocalChanges(TreePath treePath) {
+		assert frame.isActive();
+
+		NodeAtFrame nodeAtFrame = nodesStorage.get(treePath.getLastPathComponent());
+		if (nodeAtFrame == null) {
+			return;
+		}
+		Path path = frame.treeModel.convertToPath(treePath);
+
+		for (Map.Entry<ValueControl, Object> e : nodeAtFrame.localChanges.entrySet()) {
+			TreeOperations.set(path, e.getKey().getParam(), e.getValue(), new FutureHandler<Integer>(frame) {
+				@Override
+				protected void result(Integer flag) {
+				}
+			});
+		}
+	}
+
+	public void fillPanelWithValues(TreePath treePath) {
+		NodeAtFrame nodeAtFrame = assureLocalInfo(treePath);
+		if (nodeAtFrame == null) {
+			return;
+		}
+
+		if (nodeAtFrame.panel == null) {
+			return;
+		}
+		Node node = TreeNode.tryGetNode(treePath);
+		if (node == null) {
+			return;
+		}
+		nodeAtFrame.panel.setCurrentTreePath(treePath);
+		nodeAtFrame.panel.pullValuesFromLocalToUser(TreeOperations.bindAccess(node));
+
+		frame.showPanel(nodeAtFrame.panel);
 
 	}
 
-	public TreePath getTreePath(Path path, boolean create) {
-		assert frame.isActive();
-		TreeNode t = rootTreeNode;
-		TreePath result = new TreePath(frame.rootNode).pathByAddingChild(rootTreeNode);
-		List<Node> nodes = path.getNodes();
-		Iterator<Node> i = nodes.iterator();
-		i.next();
-		// Node first = i.next();
+	public void useOrCreatePanel(TreePath treePath) {
+		// node.assureResolved();
+		Node node = TreeNode.tryGetNode(treePath);
 
-		// if (!t.path.isResolved()) {
-		//	t.path = new Path(path.getInstance(), nodes, first);
-		// }
-		while (i.hasNext()) {
-			Node n = i.next();
-			TreeNode r = null;
-			for (TreeNode c : t.childrenIterable()) {
-				if (c.param.getId().equals(n.getParam().getId())) {
-					r = c;
-					break;
-				}
+		NodeAtFrame nodeAtFrame = assureLocalInfo(treePath);
+
+		if (nodeAtFrame.panel == null) {
+			CompositeParam param = node.getParam();
+			nodeAtFrame.panel = findPanel(param.computeAccessId());
+			if (nodeAtFrame.panel == null) {
+				FramsClass framsClass = node.getTree().getInfoFromCache(param.getContainedTypeName());
+				nodeAtFrame.panel = preparePanel(param, framsClass);
 			}
-			if (r == null) {
-				log.debug("missing " + n.getParam().getId() + " in " + t);
-				if (!create) {
-					return result;
-				}
-				Path p = Path.build().tree(path.getTree()).buildUpTo(nodes, n).finish();
-
-
-				log.debug("forced resolution: creating treenode for " + p);
-				TreeNode childNode = new TreeNode(TreeAtFrame.this, p);
-
-				frame.addNode(childNode, t);
-				// frame.treeModel.reload();
-				// t.add(childNode);
-				// frame.treeModel.nodeStructureChanged(t);
-
-				r = childNode;
-			} else {
-				// if (!r.path.isResolved()) {
-				//	r.path = new Path(path.getInstance(), nodes, n);
-				// }
-			}
-			result = result.pathByAddingChild(r);
-			t = r;
 		}
-		return result;
-	}
-
-	@Override
-	public void onFetch(final Path path) {
-		assert tree.isActive();
-		log.trace("fetched " + path);
-
-		frame.dispatch(new RunAt<Frame>(frame) {
-			@Override
-			protected void runAt() {
-
-				TreePath treePath = getTreePath(path, true);
-				assert treePath.getPathCount() == path.size() + 1;
-
-				final TreeNode result = (TreeNode) treePath.getLastPathComponent();
-				// log.trace("found " + result + " == " + path);
-				tree.dispatch(new RunAt<Tree>(frame) {
-					@Override
-					protected void runAt() {
-						result.reactForFetchResult(path, null);
-					}
-				});
-			}
-		});
-	}
-
-	@Override
-	public void onRun(Exception e) {
-
-	}
-
-	@Override
-	public void onStop(Exception e) {
-
+		fillPanelWithValues(treePath);
 	}
 }
Index: /java/main/src/main/java/com/framsticks/gui/TreeModel.java
===================================================================
--- /java/main/src/main/java/com/framsticks/gui/TreeModel.java	(revision 98)
+++ /java/main/src/main/java/com/framsticks/gui/TreeModel.java	(revision 98)
@@ -0,0 +1,172 @@
+package com.framsticks.gui;
+
+// import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+import javax.swing.event.TreeModelEvent;
+import javax.swing.event.TreeModelListener;
+import javax.swing.tree.TreePath;
+
+import org.apache.log4j.Logger;
+
+
+import com.framsticks.core.Node;
+import com.framsticks.core.Path;
+import com.framsticks.util.FramsticksException;
+import com.framsticks.util.UnsupportedOperationException;
+import com.framsticks.util.lang.Casting;
+
+public class TreeModel implements javax.swing.tree.TreeModel {
+	private static final Logger log = Logger.getLogger(TreeModel.class);
+
+
+	protected List<TreeModelListener> listeners = new LinkedList<>();
+
+	protected final Frame frame;
+
+	/**
+	 * @param frame
+	 */
+	public TreeModel(Frame frame) {
+		this.frame = frame;
+	}
+
+	@Override
+	public void addTreeModelListener(TreeModelListener listener) {
+		listeners.add(listener);
+	}
+
+	@Override
+	public AbstractNode getChild(Object parent, int number) {
+		return Casting.assertCast(AbstractNode.class, parent).getChild(number);
+	}
+
+	@Override
+	public int getChildCount(Object parent) {
+		return Casting.assertCast(AbstractNode.class, parent).getChildCount();
+	}
+
+	@Override
+	public int getIndexOfChild(Object parent, Object child) {
+		if ((parent == null) || (child == null)) {
+			return -1;
+		}
+		return Casting.assertCast(AbstractNode.class, parent).getIndexOfChild(Casting.assertCast(AbstractNode.class, child));
+	}
+
+	@Override
+	public MetaNode getRoot() {
+		return frame.rootNode;
+	}
+
+	@Override
+	public boolean isLeaf(Object node) {
+		return Casting.assertCast(AbstractNode.class, node).isLeaf();
+	}
+
+	@Override
+	public void removeTreeModelListener(TreeModelListener listener) {
+		listeners.remove(listener);
+	}
+
+	@Override
+	public void valueForPathChanged(TreePath path, Object value) {
+		throw new UnsupportedOperationException().msg("changing value of tree node");
+	}
+
+
+	protected boolean changing = false;
+
+	public void nodeStructureChanged(TreePath treePath) {
+		if (treePath == null) {
+			return;
+		}
+		assert frame.isActive();
+
+		changing = true;
+		log.debug("changing: " + treePath);
+		// Enumeration<TreePath> expanded = frame.jtree.getExpandedDescendants(treePath);
+		// TreePath selection = frame.jtree.getSelectionPath();
+
+		for (TreeModelListener listener : listeners) {
+			listener.treeStructureChanged(new TreeModelEvent(this, treePath));
+		}
+		// if (expanded != null) {
+		// 	while (expanded.hasMoreElements()) {
+		// 		TreePath expansion = expanded.nextElement();
+		// 		// log.info("reexpanding: " + expansion);
+		// 		frame.jtree.expandPath(expansion);
+		// 	}
+		// }
+		// if (selection != null) {
+		// 	frame.jtree.setSelectionPath(selection);
+		// }
+		changing = false;
+	}
+
+	public Path convertToPath(TreePath treePath) {
+		final Object[] components = treePath.getPath();
+		assert components[0] == frame.rootNode;
+		if (components.length == 1) {
+			return null;
+		}
+		Path.PathBuilder builder = Path.build();
+		builder.tree(Casting.assertCast(TreeNode.class, components[1]).getTree());
+		List<Node> nodes = new LinkedList<>();
+		for (int i = 1; i < components.length; ++i) {
+			TreeNode treeNode = Casting.tryCast(TreeNode.class, components[i]);
+			if (treeNode == null) {
+				return null;
+			}
+			Node node = treeNode.tryCreateNode();
+			if (node == null) {
+				throw new FramsticksException().msg("failed to recreate path").arg("treePath", treePath);
+			}
+			nodes.add(node);
+		}
+		builder.buildUpTo(nodes, null);
+
+		return builder.finish();
+	}
+
+	public TreePath convertToTreePath(Path path) {
+		assert frame.isActive();
+
+		List<Object> accumulator = new LinkedList<Object>();
+		accumulator.add(frame.rootNode);
+
+		for (AbstractNode r : frame.rootNode.getChildren()) {
+			if (r instanceof TreeNode) {
+				TreeNode root = (TreeNode) r;
+				if (root.getTree() == path.getTree()) {
+					accumulator.add(root);
+
+					Iterator<Node> i = path.getNodes().iterator();
+					i.next();
+					TreeNode treeNode = root;
+
+					while (i.hasNext()) {
+						Node node = i.next();
+						treeNode = treeNode.getTreeNodeForChild(node.getObject());
+						if (treeNode == null) {
+							break;
+						}
+						accumulator.add(treeNode);
+					}
+
+					break;
+				}
+			}
+		}
+		return new TreePath(accumulator.toArray());
+	}
+
+	/**
+	 * @return the changing
+	 */
+	public boolean isChanging() {
+		return changing;
+	}
+}
Index: /java/main/src/main/java/com/framsticks/gui/TreeNode.java
===================================================================
--- /java/main/src/main/java/com/framsticks/gui/TreeNode.java	(revision 97)
+++ /java/main/src/main/java/com/framsticks/gui/TreeNode.java	(revision 98)
@@ -1,480 +1,219 @@
 package com.framsticks.gui;
 
-import com.framsticks.communication.Subscription;
-import com.framsticks.communication.util.LoggingStateCallback;
-import com.framsticks.core.Mode;
+import java.lang.ref.WeakReference;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import javax.swing.tree.TreePath;
+
+import org.apache.log4j.Logger;
+
+import com.framsticks.core.Node;
 import com.framsticks.core.Tree;
-import com.framsticks.core.TreeOperations;
-import com.framsticks.core.ListChange;
-import com.framsticks.core.Path;
-import com.framsticks.gui.controls.ValueControl;
 import com.framsticks.gui.view.TreeCellRenderer;
 import com.framsticks.params.AccessInterface;
 import com.framsticks.params.CompositeParam;
-import com.framsticks.params.FramsClass;
-import com.framsticks.params.types.*;
-import com.framsticks.remote.*;
+import com.framsticks.params.types.StringParam;
+import com.framsticks.util.FramsticksException;
 import com.framsticks.util.lang.Casting;
-import com.framsticks.util.lang.Holder;
+import com.framsticks.util.lang.Pair;
 import com.framsticks.util.swing.TooltipConstructor;
-import com.framsticks.util.dispatching.ExceptionResultHandler;
-import com.framsticks.util.dispatching.FutureHandler;
-import com.framsticks.util.FramsticksException;
-import com.framsticks.util.Logging;
-import org.apache.log4j.Logger;
-import com.framsticks.util.dispatching.RunAt;
-
-import javax.swing.tree.DefaultMutableTreeNode;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import static com.framsticks.util.lang.Containers.filterInstanceof;
-import com.framsticks.util.swing.TreeNodeUtils;
-import static com.framsticks.core.TreeOperations.*;
-
-/**
- * @author Piotr Sniegowski
- */
-@SuppressWarnings("serial")
-public class TreeNode extends DefaultMutableTreeNode implements NodeListener, ExceptionResultHandler {
-
-	private static final Logger log = Logger.getLogger(TreeNode.class.getName());
-
-	Panel panel;
-
-	final protected Frame frame;
-	final protected TreeAtFrame treeAtFrame;
-
-	final protected Map<EventParam, Subscription<?>> userSubscriptions = new HashMap<>();
-	protected Map<ValueControl, Object> localChanges = null;
-	protected String tooltip;
-	protected String name;
+
+public class TreeNode extends AbstractNode {
+	private static final Logger log = Logger.getLogger(TreeNode.class);
+
+
+	protected static final AtomicInteger counter = new AtomicInteger();
+
+	protected final WeakReference<Object> reference;
 	protected final CompositeParam param;
-	protected String iconName;
-	protected Path path;
-
-	public TreeNode(TreeAtFrame treeAtFrame, final Path path) {
-		this.frame = treeAtFrame.getFrame();
-		assert frame.isActive();
-		this.param = path.getTop().getParam();
-		this.name = this.param.getId();
-		log.debug("creating treenode " + name + ": " + path);
-		this.path = path;
-		this.treeAtFrame = treeAtFrame;
-
-		iconName = TreeCellRenderer.findIconName(name, path.getTextual());
-		tooltip = "?";
-		path.getTree().dispatch(new RunAt<Tree>(this) {
-			@Override
-			protected void runAt() {
-				updateDescriptions(path);
-			}
-		});
-	}
-
-	public void fetch(final Path p) {
-		assert p.getTree().isActive();
-		log.debug("fetching: " + p);
-		p.getTree().get(p, Mode.FETCH, new FutureHandler<Object>(this) {
-			@Override
-			protected void result(Object result) {
-
-			}
-		});
-	}
-
-	protected void reactForFetchResult(final Path p, Exception e) {
-		assert p.getTree().isActive();
-		if (Logging.log(log, "fetch", TreeNode.this, e)) {
-			frame.dispatch(new RunAt<Frame>(this) {
-				@Override
-				protected void runAt() {
-					log.debug("removing node from tree: " + p);
-					frame.treeModel.removeNodeFromParent(TreeNode.this);
-				}
-			});
-			return;
-		}
-		updateChildren(p);
-		frame.dispatch(new RunAt<Frame>(this) {
-			@Override
-			protected void runAt() {
-				//TODO maybe this should be called from some better place
-				useOrCreatePanel();
-			}
-		});
-	}
-
-	protected void postUpdatePath(final Path newPath) {
-		assert !frame.isActive();
-		/** TODO those two actions could be merged into single closure */
-		frame.dispatch(new RunAt<Frame>(this) {
-			@Override
-			protected void runAt() {
-				updatePath(newPath);
-			}
-		});
-		updateDescriptions(newPath);
-	}
-
-	protected void updatePath(Path newPath) {
-		assert frame.isActive();
-		if (!path.isResolved()) {
-			path = newPath;
-			log.debug("updated treenode's path: " + path);
-			return;
-		}
-		if (path.matches(newPath)) {
-			return;
-		}
-		log.debug("removing all children due to path update");
-		this.removeAllChildren();
-		frame.treeModel.nodeStructureChanged(this);
-	}
-
-	public Iterable<TreeNode> childrenIterable() {
-		return filterInstanceof(TreeNodeUtils.children(TreeNode.this, frame.treeModel), TreeNode.class);
-	}
-
-	/** Update children, by removing non existing and adding new ones.
+	protected final Tree tree;
+	protected final List<Pair<WeakReference<Object>, WeakReference<TreeNode>>> children = new LinkedList<>();
+	protected final int number;
+
+	public TreeNode(Tree tree, CompositeParam param, Object object) {
+		this.tree = tree;
+		this.param = param;
+		reference = new WeakReference<Object>(object);
+		number = counter.getAndIncrement();
+	}
+
+	public TreeNode(Node node) {
+		this(node.getTree(), node.getParam(), node.assureResolved().getObject());
+	}
+
+	public Node tryCreateNode() {
+		Object child = lock();
+		if (child == null) {
+			return null;
+		}
+		return new Node(tree, param, child);
+	}
+
+	@Override
+	public int getChildCount() {
+		Object referent = lock();
+		if (referent == null) {
+			return 0;
+		}
+		AccessInterface access = tree.prepareAccess(param).select(referent);
+		final int count = access.getCompositeParamCount();
+		return count;
+	}
+
+	public TreeNode getTreeNodeForChild(Object child) {
+		Iterator<Pair<WeakReference<Object>, WeakReference<TreeNode>>> i = children.iterator();
+		while (i.hasNext()) {
+			Pair<WeakReference<Object>, WeakReference<TreeNode>> p = i.next();
+			Object object = p.first.get();
+			if (object == null) {
+				i.remove();
+				continue;
+			}
+			TreeNode treeNode = p.second.get();
+			if (treeNode == null) {
+				i.remove();
+				continue;
+			}
+			if (object == child) {
+				return treeNode;
+			}
+		}
+		return null;
+
+		// WeakReference<GuiTreeNode> resultReference = children.get(child);
+		// if (resultReference == null) {
+		//	return null;
+		// }
+		// return resultReference.get();
+	}
+
+	@Override
+	public AbstractNode getChild(int number) {
+		Object referent = lock();
+		if (referent == null) {
+			throw new FramsticksException().msg("invalid state - missing referent");
+		}
+		AccessInterface access = tree.prepareAccess(param).select(referent);
+
+		final int count = access.getCompositeParamCount();
+		if (number >= count) {
+			throw new FramsticksException().msg("invalid state - no child");
+		}
+
+		CompositeParam childParam = access.getCompositeParam(number);
+		Object child = access.get(childParam, Object.class);
+		if (child == null) {
+			log.debug("returing dummy node for " + childParam + " in " + referent);
+			return new EmptyNode(childParam);
+		}
+
+		TreeNode result = getTreeNodeForChild(child);
+		if (result != null) {
+			return result;
+		}
+		result = new TreeNode(tree, childParam, child);
+
+		children.add(Pair.make(new WeakReference<Object>(child), new WeakReference<TreeNode>(result)));
+
+		return result;
+
+	}
+
+	public Object lock() {
+		return reference.get();
+	}
+
+	@Override
+	public int getIndexOfChild(AbstractNode child) {
+		final TreeNode treeChild = Casting.tryCast(TreeNode.class, child);
+		if (treeChild == null) {
+			return -1;
+		}
+		final Object childObject = treeChild.lock();
+		final Object parentObject = lock();
+		if (childObject == null || parentObject == null) {
+			return -1;
+		}
+		final AccessInterface access = tree.prepareAccess(param).select(parentObject);
+
+		final int count = access.getCompositeParamCount();
+		for (int i = 0; i < count; ++i) {
+			Object c = access.get(access.getCompositeParam(i), Object.class);
+			if (c == childObject) {
+				return i;
+			}
+		}
+		log.debug(child + " not found in " + this);
+		return -1;
+	}
+
+	/**
+	 * @return the param
 	 */
-	protected void updateChildren(final Path p) {
-		assert p.getTree().isActive();
-		log.debug("updating children of " + this);
-		AccessInterface access = TreeOperations.bindAccess(p.getTree(), p.getTop());
-		final List<Path> childrenPaths = new LinkedList<Path>();
-		/**Prepare path for each child.*/
-		for (CompositeParam param : filterInstanceof(access.getParams(), CompositeParam.class)) {
-			childrenPaths.add(p.appendParam(param).tryFindResolution());
-		}
-
-		/**If some child were found, update in frame context.*/
-		if (childrenPaths.size() > 0) {
-			frame.dispatch(new RunAt<Frame>(this) {
-				@Override
-				protected void runAt() {
-					// TreePath treePath = frame.startChange();
-					updatePath(p);
-					Map<String, TreeNode> current = new HashMap<String, TreeNode>();
-					for (TreeNode n : childrenIterable()) {
-						current.put(n.path.getLastElement(), n);
-					}
-					assert current.size() == TreeNode.this.getChildCount();
-					assert TreeNode.this.getChildCount() == frame.treeModel.getChildCount(TreeNode.this);
-					log.trace("current " + TreeNode.this.getChildCount() + " children: " + current.values());
-					for (Path childPath : childrenPaths) {
-						String e = childPath.getLastElement();
-						if (current.containsKey(e)) {
-							current.remove(e);
-							continue;
-						}
-						log.debug("update: treenode for " + p);
-						TreeNode childNode = new TreeNode(treeAtFrame, childPath);
-
-						frame.addNode(childNode, TreeNode.this);
-					}
-					for (TreeNode n : current.values()) {
-						frame.treeModel.removeNodeFromParent(n);
-					}
-					log.debug("updated children of " + TreeNode.this + ": " + TreeNode.this.getChildCount());
-				}
-			});
+	public CompositeParam getParam() {
+		return param;
+	}
+
+	/**
+	 * @return the tree
+	 */
+	public Tree getTree() {
+		return tree;
+	}
+
+
+	@Override
+	public String toString() {
+		return param.toString();
+	}
+
+	public static Node tryGetNode(TreePath treePath) {
+		return Casting.throwCast(TreeNode.class, treePath.getLastPathComponent()).tryCreateNode();
+	}
+
+	@Override
+	public boolean isLeaf() {
+		Object referent = lock();
+		if (referent == null) {
+			return true;
+		}
+		AccessInterface access = tree.prepareAccess(param).select(referent);
+		return access.getCompositeParamCount() == 0;
+	}
+
+
+	@Override
+	public void render(TreeCellRenderer renderer) {
+		String name = param.getId();
+
+		Object child = lock();
+		if (child != null) {
+			AccessInterface access = tree.prepareAccess(param).select(child);
+
+			StringParam nameParam = Casting.tryCast(StringParam.class, access.getParam("name"));
+
+			if (nameParam != null) {
+				name = access.get(nameParam, String.class);
+			}
+
+			renderer.setToolTipText(new TooltipConstructor()
+				.append("frams", access.getId())
+				.append("java", child.getClass().getCanonicalName())
+				.append("access", access.getClass().getSimpleName())
+				.append("name", name)
+				.append("id", param.getId())
+				.append("object", Integer.toHexString(System.identityHashCode(child)))
+				.append("number", number)
+				.build());
 		} else {
-			log.debug("no children in " + TreeNode.this);
-		}
-	}
-
-	public void select() {
-		final Path p = path;
-
-		p.getTree().dispatch(new RunAt<Tree>(this) {
-			@Override
-			protected void runAt() {
-				final Path updated = (p.isResolved()) ? p : p.tryFindResolution();
-				if (updated.isResolved()) {
-					Logging.log(log, "update", updated, null);
-					fetch(updated);
-					postUpdatePath(updated);
-					return;
-				}
-				p.getTree().resolve(updated, new FutureHandler<Path>(Logging.logger(log, "resolve and select", TreeNode.this)) {
-					@Override
-					protected void result(Path result) {
-						fetch(result);
-						postUpdatePath(result);
-					}
-				});
-			}
-		});
-
-	}
-
-	@Override
-	public String toString() {
-		return path.toString();
-	}
-
-	public final Panel getPanel() {
-		assert frame.isActive();
-		return panel;
-	}
-
-	protected void updateDescriptions(Path p) {
-		assert p.getTree().isActive();
-
-		if (!p.isResolved()) {
-			return;
-		}
-		AccessInterface access = TreeOperations.bindAccess(p);
-
-		final String tooltip = new TooltipConstructor().append("frams", access.getId()).append("java", p.getTopObject().getClass().getCanonicalName()).append("access", access.getClass().getSimpleName()).append("name", name).append("id", param.getId()).append("object", Integer.toHexString(System.identityHashCode(this))).build();
-
-		StringParam nameParam = Casting.tryCast(StringParam.class, access.getParam("name"));
-		final String name = (nameParam != null ? access.get(nameParam, String.class) : path.getTop().getParam().getId());
-
-		frame.dispatch(new RunAt<Frame>(this) {
-			@Override
-			protected void runAt() {
-				TreeNode.this.tooltip = tooltip;
-				TreeNode.this.name = name;
-
-				log.debug("updated descriptions for " + path + ": " + name);
-			}
-		});
-	}
-
-	public void showPanel() {
-		assert frame.isActive();
-		assert panel != null;
-		frame.showPanel(panel);
-	}
-
-	public void fillPanelWithValues() {
-		assert frame.isActive();
-		if (panel == null) {
-			return;
-		}
-		final Path p = path;
-		assert p.isResolved();
-		panel.setCurrentTreeNode(this);
-		p.getTree().dispatch(new RunAt<Tree>(this) {
-			@Override
-			protected void runAt() {
-				AccessInterface access = TreeOperations.bindAccess(p);
-				panel.pullValuesFromLocalToUser(access);
-
-				frame.dispatch(new RunAt<Frame>(this) {
-					@Override
-					protected void runAt() {
-						showPanel();
-					}
-				});
-			}
-		});
-
-	}
-
-	public void useOrCreatePanel() {
-		assert frame.isActive();
-		if (panel != null) {
-			log.trace("panel is already attached: " + path);
-			fillPanelWithValues();
-			return;
-		}
-		if (!path.isResolved()) {
-			log.trace("path is not resolved: " + path);
-			return;
-		}
-
-		CompositeParam param = path.getTop().getParam();
-		panel = treeAtFrame.findPanel(param.computeAccessId());
-		if (panel != null) {
-			log.debug("found prepared panel for: " + path);
-			fillPanelWithValues();
-			return;
-		}
-		final Path p = path;
-		log.debug("preparing panel: " + p);
-		p.getTree().dispatch(new RunAt<Tree>(this) {
-			@Override
-			protected void runAt() {
-				assert p.getTree().isActive();
-				final CompositeParam param = p.getTop().getParam();
-				final FramsClass framsClass = p.getTree().getInfoFromCache(param.getContainedTypeName());
-				frame.dispatch(new RunAt<Frame>(this) {
-					@Override
-					protected void runAt() {
-						panel = treeAtFrame.preparePanel(param, framsClass);
-						fillPanelWithValues();
-					}
-				});
-			}
-		});
-	}
-
-	public String getTooltip() {
-		assert frame.isActive();
-		return tooltip;
-	}
-
-	/*public void subscribe(final EventParam eventParam) {
-		assert browser.isActive();
-		if (hasSubscribed(eventParam)) {
-			log.error(eventParam + " is already subscribed for " + this);
-			return;
-		}
-		Node node = getNode();
-		node.getConnection().subscribe(node.getPath() + "/" + eventParam.getId(), new SubscriptionCallback() {
-			@Override
-			public EventCallback subscribed(final Subscription subscription) {
-				if (subscription == null) {
-					log.error("subscription failed");
-					return null;
-				}
-				if (hasSubscribed(eventParam)) {
-					//abort subscription
-					return null;
-				}
-				userSubscriptions.put(eventParam, subscription);
-				log.debug("subscription succeeded: " + subscription);
-				subscription.setDispatcher(browser);
-				return new EventCallback() {
-					@Override
-					public void call(SourceInterface content) {
-						assert browser.isActive();
-						log.info("event " + subscription + " occurred");
-					}
-				};
-			}
-		});
-
-	}*/
-
-	public boolean hasSubscribed(EventParam param) {
-		assert frame.isActive();
-		return userSubscriptions.containsKey(param);
-	}
-
-	public void unsubscribe(EventParam eventParam) {
-		assert frame.isActive();
-		if (!hasSubscribed(eventParam)) {
-			log.error("could not unsubscribe from " + eventParam);
-			return;
-		}
-		userSubscriptions.get(eventParam).unsubscribe(new LoggingStateCallback(log, "unsubscribed " + eventParam));
-		userSubscriptions.remove(eventParam);
-	}
-
-	// @Override
-	// public void onChildChange(final Child child, ListChange.Action action) {
-	// assert browser.manager.isActive();
-
-	// switch (action) {
-	// case Remove: {
-	// Dispatching.invokeDispatch(browser, browser.manager, new Runnable() {
-	// @Override
-	// public void run() {
-	// assert browser.manager.isActive();
-	// final TreeNode treeNode = (TreeNode) child.getUserObject();
-	// if (treeNode == null) {
-	// log.error("child " + child + " had no tree node attached");
-	// return;
-	// }
-	// browser.invokeLater(new Runnable() {
-	// @Override
-	// public void run() {
-	// assert browser.isActive();
-	// TreePath path = browser.startChange();
-	// //assert treeNode.getParent() == TreeNode.this;
-	// if (treeNode.getParent() != null) {
-	// browser.treeModel.removeNodeFromParent(treeNode);
-	// }
-	// //remove(treeNode);
-	// browser.markNodeChanged(TreeNode.this, path);
-	// }
-	// });
-	// }
-	// });
-	// break;
-	// }
-	// }
-
-	// }
-
-	public String getName() {
-		return name;
-	}
-
-	public String getIconName() {
-		return iconName;
-	}
-
-	@Override
-	public void onUpgrade(Path path) {
-	}
-
-	@Override
-	public void onChange(Path path) {
-	}
-
-	@Override
-	public void onChildChange(Path path, ListChange.Action action) {
-	}
-
-	public final Frame getFrame() {
-		return frame;
-	}
-
-	public boolean changeValue(ValueControl component, Object newValue) {
-		log.debug("changing value of " + component + " to '" + newValue + "'");
-
-		if (localChanges == null) {
-			localChanges = new HashMap<ValueControl, Object>();
-		}
-		localChanges.put(component, newValue);
-
-		return true;
-	}
-
-	public Path getTreePath() {
-		assert frame.isActive();
-		return path;
-	}
-
-	public void pushLocalChanges() {
-		assert frame.isActive();
-		if (localChanges == null) {
-			return;
-		}
-		Map<ValueControl, Object> changes = localChanges;
-		localChanges = null;
-		final Holder<Integer> counter = new Holder<>(changes.size());
-		final Path p = path;
-
-		for (Map.Entry<ValueControl, Object> e : changes.entrySet()) {
-			set(p, e.getKey().getParam(), e.getValue(), new FutureHandler<Integer>(this) {
-				@Override
-				protected void result(Integer flag) {
-					counter.set(counter.get() - 1);
-					if (counter.get() != 0) {
-						return;
-					}
-					log.debug("applied changes for: " + p);
-					frame.dispatch(new RunAt<Frame>(this) {
-						@Override
-						protected void runAt() {
-							fillPanelWithValues();
-						}
-					});
-				}
-
-			});
-		}
-	}
-
-	@Override
-	public void handle(FramsticksException exception) {
-		frame.handle(exception);
-	}
+			renderer.setToolTipText("?");
+		}
+		renderer.setText(name);
+		renderer.setIcon(ImageProvider.loadImage(TreeCellRenderer.findIconName(param)));
+
+	}
+
 }
Index: /java/main/src/main/java/com/framsticks/gui/console/InteractiveConsole.java
===================================================================
--- /java/main/src/main/java/com/framsticks/gui/console/InteractiveConsole.java	(revision 97)
+++ /java/main/src/main/java/com/framsticks/gui/console/InteractiveConsole.java	(revision 98)
@@ -109,6 +109,4 @@
 			}
 		});
-
-
 	}
 
Index: /java/main/src/main/java/com/framsticks/gui/console/ManagedConsole.java
===================================================================
--- /java/main/src/main/java/com/framsticks/gui/console/ManagedConsole.java	(revision 97)
+++ /java/main/src/main/java/com/framsticks/gui/console/ManagedConsole.java	(revision 98)
@@ -3,5 +3,4 @@
 import java.util.LinkedList;
 import java.util.List;
-
 
 import com.framsticks.communication.ClientSideManagedConnection;
@@ -11,4 +10,5 @@
 import com.framsticks.communication.Response;
 import com.framsticks.communication.queries.ApplicationRequest;
+import com.framsticks.core.Mode;
 import com.framsticks.core.Path;
 import static com.framsticks.core.TreeOperations.*;
@@ -17,7 +17,10 @@
 import com.framsticks.params.annotations.AutoAppendAnnotation;
 import com.framsticks.params.annotations.FramsClassAnnotation;
+import com.framsticks.params.types.ListParam;
 import com.framsticks.remote.RemoteTree;
 import com.framsticks.util.FramsticksException;
+import com.framsticks.util.dispatching.Dispatching;
 import com.framsticks.util.dispatching.FutureHandler;
+import com.framsticks.util.dispatching.RunAt;
 import com.framsticks.util.lang.Casting;
 import com.framsticks.util.lang.Containers;
@@ -27,4 +30,5 @@
 @FramsClassAnnotation
 public class ManagedConsole extends InteractiveConsole {
+
 
 	protected RemoteTree tree;
@@ -70,7 +74,11 @@
 	}
 
+
 	@Override
 	protected void findCompletionPropositions(final String prefix) {
 		Pair<CharSequence, CharSequence> command = Request.takeIdentifier(prefix);
+		if (command == null) {
+			return;
+		}
 
 		Casting.throwCast(ApplicationRequest.class, Request.createRequestByTypeString(command.first.toString()));
@@ -90,22 +98,59 @@
 		// final Iterator<String> iterator = Path.splitPath(textual);
 
-		resolve(tree, textual, new FutureHandler<Path>(this) {
+		tryGet(tree, textual, new FutureHandler<Path>(this) {
 
 			@Override
-			protected void result(Path path) {
+			protected void result(final Path path) {
 				if (!textual.startsWith(path.getTextual())) {
 					throw new FramsticksException().msg("invalid state").arg("line", prefix).arg("path", path);
 				}
+				assert path.getTree().isActive();
 
-				List<String> propositions = new LinkedList<String>();
-				String remaining = textual.substring(path.getTextual().length());
-				remaining = Path.PathBuilder.splitPath(remaining).next();
+				final Runnable finalizeCompletion = new Runnable() {
+					@Override
+					public void run() {
+						String remaining = textual.substring(path.getTextual().length());
 
-				for (CompositeParam p : Containers.filterInstanceof(bindAccess(path).getParams(), CompositeParam.class)) {
-					if (p.getId().startsWith(remaining)) {
-						propositions.add(p.getId());
+						String base = prefix.substring(0, prefix.length() - (textual.length() - path.getTextual().length()));
+						if (path.size() > 1) {
+							base = base + "/";
+						}
+
+						if (remaining.startsWith("/")) {
+							remaining = remaining.substring(1);
+						}
+
+						if (remaining.indexOf('/') != -1) {
+							/** It is to long. */
+							return;
+						}
+						final List<String> propositions = new LinkedList<String>();
+						for (CompositeParam p : Containers.filterInstanceof(bindAccess(path).getParams(), CompositeParam.class)) {
+							if (remaining.equals("") || p.getId().startsWith(remaining)) {
+								propositions.add(base + p.getId());
+							}
+						}
+
+						dispatch(new RunAt<ManagedConsole>(ManagedConsole.this) {
+
+							@Override
+							protected void runAt() {
+								processCompletionResult(prefix, propositions);
+							}
+						});
 					}
+				};
+
+				if (path.getTop().getParam() instanceof ListParam) {
+					tree.get(path, Mode.FETCH, new FutureHandler<Path>(ManagedConsole.this) {
+						@Override
+						protected void result(Path result) {
+							finalizeCompletion.run();
+						}
+					});
+					return;
 				}
-				processCompletionResult(prefix, propositions);
+				finalizeCompletion.run();
+
 			}
 		});
@@ -119,3 +164,21 @@
 		connection = tree.getConnection();
 	}
+
+	@Override
+	protected void joinableStart() {
+		super.joinableStart();
+		Dispatching.use(tree, this);
+	}
+
+	@Override
+	protected void joinableInterrupt() {
+		Dispatching.drop(tree, this);
+		super.joinableInterrupt();
+	}
+
+	@Override
+	protected void joinableJoin() throws InterruptedException {
+		Dispatching.join(tree);
+		super.joinableJoin();
+	}
 }
Index: /java/main/src/main/java/com/framsticks/gui/console/TrackConsole.java
===================================================================
--- /java/main/src/main/java/com/framsticks/gui/console/TrackConsole.java	(revision 97)
+++ /java/main/src/main/java/com/framsticks/gui/console/TrackConsole.java	(revision 98)
@@ -1,3 +1,11 @@
 package com.framsticks.gui.console;
+
+import java.awt.BorderLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.Box;
+import javax.swing.BoxLayout;
+import javax.swing.JCheckBox;
 
 import com.framsticks.communication.Connection;
@@ -8,4 +16,7 @@
 @FramsClassAnnotation
 public class TrackConsole extends Console implements ConnectionListener {
+
+	volatile boolean writeOut = true;
+	volatile boolean writeIn = true;
 
 	public TrackConsole() {
@@ -30,13 +41,49 @@
 	}
 
-
 	@Override
 	public void connectionOutgoing(String line) {
-		dispatchWrite(line);
+		if (writeOut) {
+			dispatchWrite(line);
+		}
 	}
 
 	@Override
 	public void connectionIncomming(String line) {
-		dispatchWrite(line);
+		if (writeIn) {
+			dispatchWrite(line);
+		}
+	}
+
+	@Override
+	protected void initializeGui() {
+		super.initializeGui();
+
+		final Box box = new Box(BoxLayout.LINE_AXIS);
+
+		final JCheckBox outCheckbox = new JCheckBox();
+		outCheckbox.setText("Show out");
+		outCheckbox.setSelected(true);
+		outCheckbox.addActionListener(new ActionListener() {
+			@Override
+			public void actionPerformed(ActionEvent arg0) {
+				writeOut = outCheckbox.isSelected();
+			}
+		});
+
+		final JCheckBox inCheckbox = new JCheckBox();
+		inCheckbox.setText("Show in");
+		inCheckbox.setSelected(true);
+		inCheckbox.addActionListener(new ActionListener() {
+			@Override
+			public void actionPerformed(ActionEvent arg0) {
+				writeIn = inCheckbox.isSelected();
+			}
+		});
+
+		box.add(outCheckbox);
+		box.add(Box.createHorizontalStrut(10));
+		box.add(inCheckbox);
+
+		panel.add(box, BorderLayout.PAGE_END);
 	}
 
Index: /java/main/src/main/java/com/framsticks/gui/controls/CheckBoxControl.java
===================================================================
--- /java/main/src/main/java/com/framsticks/gui/controls/CheckBoxControl.java	(revision 97)
+++ /java/main/src/main/java/com/framsticks/gui/controls/CheckBoxControl.java	(revision 98)
@@ -21,5 +21,4 @@
 		super(booleanParam);
 		checkBox = new JCheckBox();
-		checkBox.setEnabled(!isReadOnly());
 		checkBox.addActionListener(new ActionListener() {
 
@@ -52,3 +51,8 @@
 	}
 
+	@Override
+	protected void updateEnabled(boolean enabled) {
+		checkBox.setEnabled(enabled);
+	}
+
 }
Index: /java/main/src/main/java/com/framsticks/gui/controls/Control.java
===================================================================
--- /java/main/src/main/java/com/framsticks/gui/controls/Control.java	(revision 97)
+++ /java/main/src/main/java/com/framsticks/gui/controls/Control.java	(revision 98)
@@ -24,10 +24,11 @@
 	protected ControlOwner owner;
 
+	protected abstract void updateEnabled(boolean enabled);
+
+	private boolean userEnabled = true;
+
 	public Control(Param param) {
 		this.param = param;
 		setName(param.getId());
-
-		this.setEnabled(!param.hasFlag(Flags.READONLY));
-		// TODO: take care of textField exception: setEditable
 	}
 
@@ -38,4 +39,23 @@
 	public void setOwner(ControlOwner owner) {
 		this.owner = owner;
+	}
+
+	/**
+	 * @return the userEnabled
+	 */
+	public final boolean isUserEnabled() {
+		return userEnabled;
+	}
+
+	/**
+	 * @param userEnabled the userEnabled to set
+	 */
+	public final void setUserEnabled(boolean userEnabled) {
+		this.userEnabled = userEnabled;
+		updateEnabled(!isReadonly());
+	}
+
+	public final boolean isReadonly() {
+		return !userEnabled || param.hasFlag(Flags.READONLY);
 	}
 
Index: /java/main/src/main/java/com/framsticks/gui/controls/ControlOwner.java
===================================================================
--- /java/main/src/main/java/com/framsticks/gui/controls/ControlOwner.java	(revision 97)
+++ /java/main/src/main/java/com/framsticks/gui/controls/ControlOwner.java	(revision 98)
@@ -2,6 +2,7 @@
 
 import javax.swing.JPanel;
+import javax.swing.tree.TreePath;
 
-import com.framsticks.gui.TreeNode;
+import com.framsticks.gui.Frame;
 import com.framsticks.util.dispatching.ExceptionResultHandler;
 
@@ -9,5 +10,6 @@
 
 	public JPanel getPanel();
-	public TreeNode getCurrentTreeNode();
+	public TreePath getCurrentTreePath();
+	public Frame getFrame();
 
 }
Index: /java/main/src/main/java/com/framsticks/gui/controls/EnumControl.java
===================================================================
--- /java/main/src/main/java/com/framsticks/gui/controls/EnumControl.java	(revision 97)
+++ /java/main/src/main/java/com/framsticks/gui/controls/EnumControl.java	(revision 98)
@@ -28,5 +28,4 @@
 		}
 		list.setEditable(false);
-		list.setEnabled(!isReadOnly());
 		list.addItemListener(new ItemListener() {
 			@Override
@@ -61,3 +60,9 @@
 	}
 
+	@Override
+	protected void updateEnabled(boolean enabled) {
+		list.setEnabled(enabled);
+
+	}
+
 }
Index: /java/main/src/main/java/com/framsticks/gui/controls/EventControl.java
===================================================================
--- /java/main/src/main/java/com/framsticks/gui/controls/EventControl.java	(revision 97)
+++ /java/main/src/main/java/com/framsticks/gui/controls/EventControl.java	(revision 98)
@@ -39,4 +39,9 @@
 	}
 
+	@Override
+	protected void updateEnabled(boolean enabled) {
+		button.setEnabled(enabled);
+	}
+
 	/*
 	@Override
Index: /java/main/src/main/java/com/framsticks/gui/controls/ProcedureControl.java
===================================================================
--- /java/main/src/main/java/com/framsticks/gui/controls/ProcedureControl.java	(revision 97)
+++ /java/main/src/main/java/com/framsticks/gui/controls/ProcedureControl.java	(revision 98)
@@ -3,6 +3,6 @@
 import com.framsticks.core.Tree;
 import com.framsticks.core.Path;
+import com.framsticks.gui.Frame;
 import com.framsticks.gui.Gui;
-import com.framsticks.gui.TreeNode;
 import com.framsticks.params.Param;
 import com.framsticks.params.ValueParam;
@@ -15,4 +15,5 @@
 import javax.swing.*;
 import javax.swing.border.BevelBorder;
+import javax.swing.tree.TreePath;
 
 import org.apache.log4j.Logger;
@@ -20,5 +21,5 @@
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
-import java.util.HashMap;
+import java.util.IdentityHashMap;
 import java.util.LinkedList;
 import java.util.List;
@@ -32,5 +33,5 @@
 	protected final JButton procedureButton;
 
-	final protected Map<ValueParam, ValueControl> components = new HashMap<>();
+	final protected Map<ValueParam, ValueControl> components = new IdentityHashMap<>();
 
 	public ProcedureControl(ProcedureParam procedureParam) {
@@ -54,9 +55,6 @@
 			@Override
 			public void actionPerformed(ActionEvent e) {
-				TreeNode treeNode = owner.getCurrentTreeNode();
-				assert treeNode != null;
 
-				log.debug("calling " + getParam() + " on " + treeNode);
-				final Path path = treeNode.getTreePath();
+				final Path path = getFrame().getTreeModel().convertToPath(getCurrentTreePath());
 
 				final List<Object> arguments = new LinkedList<Object>();
@@ -93,12 +91,25 @@
 
 	@Override
-	public TreeNode getCurrentTreeNode() {
-		return owner.getCurrentTreeNode();
-	}
-
-	@Override
 	public ProcedureParam getParam() {
 		return (ProcedureParam) param;
 	}
 
+	@Override
+	protected void updateEnabled(boolean enabled) {
+		procedureButton.setEnabled(enabled);
+		for (ValueControl vc : components.values()) {
+			vc.setUserEnabled(enabled);
+		}
+	}
+
+	@Override
+	public Frame getFrame() {
+		return owner.getFrame();
+	}
+
+	@Override
+	public TreePath getCurrentTreePath() {
+		return owner.getCurrentTreePath();
+	}
+
 }
Index: /java/main/src/main/java/com/framsticks/gui/controls/SliderControl.java
===================================================================
--- /java/main/src/main/java/com/framsticks/gui/controls/SliderControl.java	(revision 97)
+++ /java/main/src/main/java/com/framsticks/gui/controls/SliderControl.java	(revision 98)
@@ -17,5 +17,4 @@
 import org.apache.log4j.Logger;
 
-import com.framsticks.params.Flags;
 import com.framsticks.params.types.DecimalParam;
 import com.framsticks.params.types.FloatParam;
@@ -55,5 +54,4 @@
 		slider = new JSlider();
 
-		slider.setEnabled(!isReadOnly());
 		slider.setPaintLabels(false);
 		if (param instanceof DecimalParam) {
@@ -110,5 +108,4 @@
 		text.setHorizontalAlignment(JSlider.CENTER);
 
-		text.setEnabled(!param.hasFlag(Flags.READONLY));
 
 		slider.addChangeListener(new ChangeListener() {
@@ -206,3 +203,9 @@
 	}
 
+	@Override
+	protected void updateEnabled(boolean enabled) {
+		slider.setEnabled(enabled);
+		text.setEnabled(enabled);
+	}
+
 }
Index: /java/main/src/main/java/com/framsticks/gui/controls/TextAreaControl.java
===================================================================
--- /java/main/src/main/java/com/framsticks/gui/controls/TextAreaControl.java	(revision 97)
+++ /java/main/src/main/java/com/framsticks/gui/controls/TextAreaControl.java	(revision 98)
@@ -18,5 +18,4 @@
 		textArea.setLineWrap(true);
 		textArea.setWrapStyleWord(true);
-		textArea.setEditable(!isReadOnly());
 		addDefaultDocumentListener(textArea);
 
@@ -47,3 +46,8 @@
 	}
 
+	@Override
+	protected void updateEnabled(boolean enabled) {
+		textArea.setEditable(enabled);
+	}
+
 }
Index: /java/main/src/main/java/com/framsticks/gui/controls/TextFieldControl.java
===================================================================
--- /java/main/src/main/java/com/framsticks/gui/controls/TextFieldControl.java	(revision 97)
+++ /java/main/src/main/java/com/framsticks/gui/controls/TextFieldControl.java	(revision 98)
@@ -31,6 +31,4 @@
 		this.setMaximumSize(new Dimension(Integer.MAX_VALUE, Control.LINE_HEIGHT));
 
-		textField.setEditable(!isReadOnly());
-
 		addDefaultDocumentListener(textField);
 
@@ -48,3 +46,8 @@
 	}
 
+	@Override
+	protected void updateEnabled(boolean enabled) {
+		textField.setEnabled(enabled);
+	}
+
 }
Index: /java/main/src/main/java/com/framsticks/gui/controls/ValueControl.java
===================================================================
--- /java/main/src/main/java/com/framsticks/gui/controls/ValueControl.java	(revision 97)
+++ /java/main/src/main/java/com/framsticks/gui/controls/ValueControl.java	(revision 98)
@@ -97,9 +97,4 @@
 	}
 
-	public final boolean isReadOnly() {
-		return (param.getFlags() & Flags.READONLY) != 0;
-	}
-
-
 
 }
Index: va/main/src/main/java/com/framsticks/gui/view/NodeAction.java
===================================================================
--- /java/main/src/main/java/com/framsticks/gui/view/NodeAction.java	(revision 97)
+++ 	(revision )
@@ -1,11 +1,0 @@
-package com.framsticks.gui.view;
-
-
-import com.framsticks.gui.TreeNode;
-
-/**
- * @author Piotr Sniegowski
- */
-public interface NodeAction {
-    public void actionPerformed(TreeNode treeNode);
-}
Index: /java/main/src/main/java/com/framsticks/gui/view/TreeCellRenderer.java
===================================================================
--- /java/main/src/main/java/com/framsticks/gui/view/TreeCellRenderer.java	(revision 97)
+++ /java/main/src/main/java/com/framsticks/gui/view/TreeCellRenderer.java	(revision 98)
@@ -1,13 +1,12 @@
 package com.framsticks.gui.view;
 
-import com.framsticks.gui.ImageProvider;
-import com.framsticks.gui.TreeNode;
+import java.awt.Component;
 
-import javax.swing.*;
+import javax.swing.JTree;
 import javax.swing.tree.DefaultTreeCellRenderer;
 
-import org.apache.log4j.Logger;
-
-import java.awt.*;
+import com.framsticks.gui.AbstractNode;
+import com.framsticks.gui.ImageProvider;
+import com.framsticks.params.CompositeParam;
 
 /**
@@ -16,12 +15,10 @@
 @SuppressWarnings("serial")
 public class TreeCellRenderer extends DefaultTreeCellRenderer {
-	private static final Logger log =
-		Logger.getLogger(TreeCellRenderer.class);
-
 
 	public TreeCellRenderer() {
-		setOpenIcon(null);
-		setClosedIcon(null);
-		setLeafIcon(null);
+
+		// setOpenIcon(ImageProvider.loadImage(ImageProvider.FOLDER_OPEN));
+		// setClosedIcon(ImageProvider.loadImage(ImageProvider.FOLDER_CLOSED));
+		// setLeafIcon(ImageProvider.loadImage(ImageProvider.NODE));
 	}
 
@@ -31,121 +28,69 @@
 			boolean hasFocus) {
 
-		//super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf,
-		//		row, hasFocus);
+		super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);
+
 		if (value == null) {
+			setText("!null value");
 			return this;
 		}
-		if (!(value instanceof TreeNode)) {
+
+		if (!(value instanceof AbstractNode)) {
 			setIcon(ImageProvider.loadImage(ImageProvider.SERVER));
 			setText("framsticks");
 			return this;
 		}
-		TreeNode treeNode = (TreeNode)value;
-		assert treeNode.getFrame().isActive();
-		setToolTipText(treeNode.getTooltip());
-		setIcon(ImageProvider.loadImage(treeNode.getIconName()));
-		setText(treeNode.getName());
+		((AbstractNode) value).render(this);
+
 		return this;
 	}
 
-	public static String findIconName(String nodeName, String path) {
-		if (nodeName == null || path == null) {
-			log.warn("given invalid parameters: " + nodeName + " " + path);
-			// return null;
-			return ImageProvider.SERVER;
+	public static String findIconName(CompositeParam param) {
+		switch (param.getFramsTypeName()) {
+			case "o Server": return ImageProvider.SERVER;
+			case "o Simulator": return ImageProvider.SIMULATOR;
+			case "o CLI": return ImageProvider.CLI;
+			case "o World": return ImageProvider.WORLD;
+			case "o GenePools": return ImageProvider.GENEPOOLS;
+			case "l GenePool": return ImageProvider.SIMULATOR; //HERE
+			case "o GenePool": return ImageProvider.GENEPOOLS_GROUP; //HERE
+
+			case "o Populations": return ImageProvider.POPULATIONS;
+			case "l Population": return ImageProvider.SIMULATOR; ///HERE
+			case "o Population": return ImageProvider.POPULATION_GROUP;
+			case "o ExpParams": return ImageProvider.EXPERIMENT;
+			case "o stats": return ImageProvider.STATISTIC;
+			case "l Genotype uid": return ImageProvider.GENOTYPES_GROUP;
+			case "o Genotype": return ImageProvider.GENOTYPES;
+
+			case "o Part": return ImageProvider.PART;
+			case "o Joint": return ImageProvider.JOINT;
+			case "o NeuroDef": return ImageProvider.NEURON_DEF;
+			case "o NeuroConn": return ImageProvider.NEURON_DEF;
+
+			case "o MechPart": return ImageProvider.MECH_PART;
+			case "o MechJoint": return ImageProvider.MECH_JOINT;
+			case "o Neuro": return ImageProvider.NEURON;
+
+			case "l Part": return ImageProvider.PART_GROUP;
+			case "l Joint": return ImageProvider.JOINT_GROUP;
+			case "l NeuroDef": return ImageProvider.NEURON_DEF_GROUP;
+			case "l NeuroConn": return ImageProvider.NEURON_DEF_GROUP;
+
+			case "l MechPart": return ImageProvider.MECH_PART_GROUP;
+			case "l MechJoint": return ImageProvider.MECH_JOINT_GROUP;
+			case "l Neuro": return ImageProvider.NEURON_GROUP;
+
+			case "o Creature": return ImageProvider.CREATURE;
+			case "l Creature uid": return ImageProvider.CREATURES_GROUP;
+			case "l Event id": return ImageProvider.EVENT;
+			case "o Event": return ImageProvider.EVENT;
+
 		}
-		if (path.equals("/")) {
-			return ImageProvider.SERVER;
-		}
-		if (path.endsWith("simulator")) {
-			return ImageProvider.SIMULATOR;
-		}
-		if (path.endsWith("cli")) {
-			return ImageProvider.CLI;
-		}
-		if (path.endsWith("world")) {
-			return ImageProvider.WORLD;
-		}
-		if (path.endsWith("genepools")) {
-			return ImageProvider.GENEPOOLS;
-		}
-		if (path.endsWith("populations")) {
-			return ImageProvider.POPULATIONS;
-		}
-		if (path.endsWith("experiment")) {
-			return ImageProvider.EXPERIMENT;
-		}
-		if (path.endsWith("stats")) {
-			return ImageProvider.STATISTIC;
-		}
-		if (nodeName.equals("creatures") || path.endsWith("creatures")) {
-			return ImageProvider.CREATURES_GROUP;
-		}
-		if (nodeName.equals("Favourite Fields")) {
-			return ImageProvider.FAVORITE_FIELDS;
-		}
-		if (nodeName.equals("genotypes") || path.endsWith("creatures")) {
-			return ImageProvider.GENOTYPES_GROUP;
-		}
-		if (nodeName.equals("parts") || path.endsWith("parts")) {
-			return ImageProvider.PART_GROUP;
-		}
-		if (nodeName.equals("joints") || path.endsWith("joints")) {
-			return ImageProvider.JOINT_GROUP;
-		}
-		if (nodeName.equals("neurodefs") || path.endsWith("neurodefs")) {
-			return ImageProvider.NEURON_DEF_GROUP;
-		}
-		if (nodeName.equals("neuroconns") || path.endsWith("neuroconns")) {
-			return ImageProvider.NEURON_DEF_GROUP;
-		}
-		if (nodeName.equals("mechparts") || path.endsWith("mechparts")) {
-			return ImageProvider.MECH_PART_GROUP;
-		}
-		if (nodeName.equals("mechjoints") || path.endsWith("mechjoints")) {
-			return ImageProvider.MECH_JOINT_GROUP;
-		}
-		if (nodeName.equals("neurons") || path.endsWith("neurons")) {
-			return ImageProvider.NEURON_GROUP;
-		}
-		if (path.matches("^.*parts/[0-9]+$")) {
-			return ImageProvider.PART;
-		}
-		if (path.matches("^.*joints/[0-9]+$")) {
-			return ImageProvider.JOINT;
-		}
-		if (path.matches("^.*neurodefs/[0-9]+$")) {
-			return ImageProvider.NEURON_DEF;
-		}
-		if (path.matches("^.*neuroconns/[0-9]+$")) {
-			return ImageProvider.NEURON_DEF;
-		}
-		if (path.matches("^.*mechparts/[0-9]+$")) {
-			return ImageProvider.MECH_PART;
-		}
-		if (path.matches("^.*mechjoints/[0-9]+$")) {
-			return ImageProvider.MECH_JOINT;
-		}
-		if (path.matches("^.*neurons/[0-9]+$")) {
-			return ImageProvider.NEURON;
-		}
-		if (path.matches("^.*creatures/c[0-9]+$")) {
-			return ImageProvider.CREATURE;
-		}
-		if (path.matches("^.*genotypes/g[0-9]+$")) {
-			return ImageProvider.GENOTYPES;
-		}
-		if (path.matches("^.*populations/groups/[0-9]+$")) {
-			return ImageProvider.POPULATION_GROUP;
-		}
-		if (path.matches("^.*genepools/groups/[0-9]+$")) {
-			return ImageProvider.GENEPOOLS_GROUP;
-		}
-		if (path.matches("^.*events/e[0-9]+$")) {
-			return ImageProvider.EVENT;
-		}
-		return ImageProvider.SIMULATOR;
+
+
+		return ImageProvider.SERVER;
 	}
 
 
+
 }
Index: /java/main/src/main/java/com/framsticks/hosting/ClientAtServer.java
===================================================================
--- /java/main/src/main/java/com/framsticks/hosting/ClientAtServer.java	(revision 97)
+++ /java/main/src/main/java/com/framsticks/hosting/ClientAtServer.java	(revision 98)
@@ -9,5 +9,4 @@
 import com.framsticks.communication.queries.InfoRequest;
 import com.framsticks.communication.queries.SetRequest;
-import com.framsticks.core.Mode;
 import com.framsticks.core.Tree;
 import com.framsticks.core.Path;
@@ -18,4 +17,5 @@
 import com.framsticks.util.dispatching.AbstractJoinable;
 import com.framsticks.util.dispatching.Dispatching;
+import com.framsticks.util.dispatching.ExceptionResultHandler;
 import com.framsticks.util.dispatching.FutureHandler;
 import com.framsticks.util.dispatching.Joinable;
@@ -31,5 +31,5 @@
  * @author Piotr Sniegowski
  */
-public class ClientAtServer extends AbstractJoinable implements RequestHandler, JoinableParent {
+public class ClientAtServer extends AbstractJoinable implements RequestHandler, JoinableParent, ExceptionResultHandler {
 
 	protected final Server server;
@@ -52,7 +52,11 @@
 		assureNotEmpty(request.getPath());
 
-		resolve(tree, request.getPath(), new FutureHandler<Path>(responseCallback) {
+		tryGet(tree, request.getPath(), new FutureHandler<Path>(responseCallback) {
 			@Override
 			protected void result(final Path path) {
+
+				if (!path.getTextual().equals(request.getPath())) {
+					throw new FramsticksException().msg("invalid path").arg("path", request.getPath());
+				}
 
 				// final AccessInterface access = tree.prepareAccess(path);
@@ -73,19 +77,13 @@
 
 				if (request instanceof GetRequest) {
-					tree.get(path, Mode.FETCH, new FutureHandler<Object>(responseCallback) {
-
-						@Override
-						protected void result(Object result) {
-							if (result != access.getSelected()) {
-								throw new FramsticksException().msg("mismatch objects during fetch").arg("path", path);
-							}
-							// TODO Auto-generated method stub
-							List<File> files = new LinkedList<File>();
-							ListSink sink = new ListSink();
-							access.save(sink);
-							files.add(new File(path.getTextual(), new ListSource(sink.getOut())));
-							responseCallback.pass(new Response(true, "", files));
-						}
-					});
+					Object result = path.getTopObject();
+					if (result != access.getSelected()) {
+						throw new FramsticksException().msg("mismatch objects during fetch").arg("path", path);
+					}
+					List<File> files = new LinkedList<File>();
+					ListSink sink = new ListSink();
+					access.save(sink);
+					files.add(new File(path.getTextual(), new ListSource(sink.getOut())));
+					responseCallback.pass(new Response(true, "", files));
 
 					return;
@@ -148,4 +146,8 @@
 	}
 
+	@Override
+	public void handle(FramsticksException exception) {
+		tree.handle(exception);
+	}
 
 }
Index: /java/main/src/main/java/com/framsticks/hosting/Server.java
===================================================================
--- /java/main/src/main/java/com/framsticks/hosting/Server.java	(revision 97)
+++ /java/main/src/main/java/com/framsticks/hosting/Server.java	(revision 98)
@@ -124,6 +124,5 @@
 			return;
 		}
-		//TODO TEH
-		acceptThread.dispatch(new RunAt<Accept>(ThrowExceptionHandler.getInstance()) {
+		acceptThread.dispatch(new RunAt<Accept>(hosted) {
 			@Override
 			protected void runAt() {
Index: /java/main/src/main/java/com/framsticks/params/AccessInterface.java
===================================================================
--- /java/main/src/main/java/com/framsticks/params/AccessInterface.java	(revision 97)
+++ /java/main/src/main/java/com/framsticks/params/AccessInterface.java	(revision 98)
@@ -1,5 +1,4 @@
 package com.framsticks.params;
 
-import java.util.Collection;
 
 import com.framsticks.params.types.ProcedureParam;
@@ -71,5 +70,5 @@
 	Object createAccessee();
 
-	Collection<Param> getParams();
+	Iterable<Param> getParams();
 
 	FramsClass getFramsClass();
@@ -77,4 +76,8 @@
 	void tryAutoAppend(Object object);
 
+	int getCompositeParamCount();
+
+	CompositeParam getCompositeParam(int number);
+
 
 }
Index: /java/main/src/main/java/com/framsticks/params/ArrayListAccess.java
===================================================================
--- /java/main/src/main/java/com/framsticks/params/ArrayListAccess.java	(revision 97)
+++ /java/main/src/main/java/com/framsticks/params/ArrayListAccess.java	(revision 98)
@@ -1,10 +1,11 @@
 package com.framsticks.params;
 
+import com.framsticks.util.UnimplementedException;
 import com.framsticks.util.lang.Numbers;
 
 import java.util.ArrayList;
-import java.util.Collection;
-import java.util.LinkedList;
+import java.util.Iterator;
 import java.util.List;
+import java.util.ListIterator;
 
 /**
@@ -30,11 +31,13 @@
 
 	@Override
-	public Param getParam(int i) {
-		//TODO listAccessParam
-		return Param.build().id(Integer.toString(i)).forAccess(elementAccess).finish();
+	public CompositeParam getParam(int i) {
+		if ((i < 0) ||  (i >= list.size())) {
+			return null;
+		}
+		return Param.build().id(Integer.toString(i)).forAccess(elementAccess).finish(CompositeParam.class);
 	}
 
 	@Override
-	public Param getParam(String id) {
+	public CompositeParam getParam(String id) {
 		Integer i = Numbers.parse(id, Integer.class);
 		return (i == null ? null : getParam(i));
@@ -53,8 +56,8 @@
 	@Override
 	public <T> T get(int i, Class<T> type) {
-		if (i < list.size()) {
-			return type.cast(list.get(i));
+		if ((i < 0) ||  (i >= list.size())) {
+			return null;
 		}
-		return null;
+		return type.cast(list.get(i));
 	}
 
@@ -112,13 +115,43 @@
 
 	@Override
-	public Collection<Param> getParams() {
-		List<Param> result = new LinkedList<Param>();
-		if (list == null) {
-			return result;
-		}
-		for (int i = 0; i < list.size(); ++i) {
-			result.add(getParam(i));
-		}
-		return result;
+	public Iterable<Param> getParams() {
+		return new Iterable<Param>() {
+
+			@Override
+			public Iterator<Param> iterator() {
+				return new Iterator<Param>() {
+
+					protected ListIterator<Object> internal = list.listIterator();
+
+					@Override
+					public boolean hasNext() {
+						return internal.hasNext();
+					}
+
+					@Override
+					public Param next() {
+						Param param = Param.build().id(Integer.toString(internal.nextIndex())).forAccess(elementAccess).finish();
+						internal.next();
+						return param;
+					}
+
+					@Override
+					public void remove() {
+						throw new UnimplementedException().msg("remove element from list").arg("list", ArrayListAccess.this);
+
+					}
+				};
+			}
+		};
+	}
+
+	@Override
+	public int getCompositeParamCount() {
+		return list.size();
+	}
+
+	@Override
+	public CompositeParam getCompositeParam(int number) {
+		return getParam(number);
 	}
 
Index: /java/main/src/main/java/com/framsticks/params/CompositeParam.java
===================================================================
--- /java/main/src/main/java/com/framsticks/params/CompositeParam.java	(revision 97)
+++ /java/main/src/main/java/com/framsticks/params/CompositeParam.java	(revision 98)
@@ -36,3 +36,8 @@
 	}
 
+	@Override
+	public String toString() {
+		return getId() + ":" + this.getClass().getSimpleName() + "(" + containedTypeName + ")";
+	}
+
 }
Index: /java/main/src/main/java/com/framsticks/params/FramsClass.java
===================================================================
--- /java/main/src/main/java/com/framsticks/params/FramsClass.java	(revision 97)
+++ /java/main/src/main/java/com/framsticks/params/FramsClass.java	(revision 98)
@@ -43,12 +43,12 @@
 	protected final List<Param> paramList;
 
+	protected final List<CompositeParam> compositeParamList = new ArrayList<>();
+
 	/**
 	 * The param entry map <parameterId, param> (for fast accessing of parameters
 	 * by their name)
 	 */
-	protected Map<String, Param> paramEntryMap = new LinkedHashMap<String, Param>();
-
-	// /** The param getId map (for fast lookup of offset based on name */
-	// protected Map<String, Integer> paramIdMap = new HashMap<String, Integer>();
+	protected Map<String, Param> paramEntryMap = new HashMap<>();
+
 
 	@ParamAnnotation(id = "props", name = "props")
@@ -67,4 +67,7 @@
 		for (Param param : paramList) {
 			paramEntryMap.put(param.getId(), param);
+			if (param instanceof CompositeParam) {
+				compositeParamList.add((CompositeParam) param);
+			}
 		}
 
@@ -182,4 +185,12 @@
 	}
 
+	public final int getCompositeParamCount() {
+		return compositeParamList.size();
+	}
+
+	public final CompositeParam getCompositeParam(int i) {
+		return compositeParamList.get(i);
+	}
+
 	@Override
 	public String toString() {
@@ -190,3 +201,4 @@
 		return new FramsClassBuilder();
 	}
+
 }
Index: /java/main/src/main/java/com/framsticks/params/FramsClassBuilder.java
===================================================================
--- /java/main/src/main/java/com/framsticks/params/FramsClassBuilder.java	(revision 97)
+++ /java/main/src/main/java/com/framsticks/params/FramsClassBuilder.java	(revision 98)
@@ -9,5 +9,5 @@
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.HashMap;
+import java.util.IdentityHashMap;
 import java.util.LinkedList;
 import java.util.List;
@@ -197,5 +197,5 @@
 	}
 
-	public static final Map<Class<?>, FramsClass> synchronizedCacheForBasedOnForJavaClass = Collections.synchronizedMap(new HashMap<Class<?>, FramsClass>());
+	public static final Map<Class<?>, FramsClass> synchronizedCacheForBasedOnForJavaClass = Collections.synchronizedMap(new IdentityHashMap<Class<?>, FramsClass>());
 
 	public FramsClass forClass(Class<?> javaClass) throws ConstructionException {
Index: /java/main/src/main/java/com/framsticks/params/ReflectionAccess.java
===================================================================
--- /java/main/src/main/java/com/framsticks/params/ReflectionAccess.java	(revision 97)
+++ /java/main/src/main/java/com/framsticks/params/ReflectionAccess.java	(revision 98)
@@ -8,4 +8,5 @@
 import java.util.Comparator;
 import java.util.HashMap;
+import java.util.IdentityHashMap;
 import java.util.List;
 import java.util.Map;
@@ -56,7 +57,7 @@
 		}
 
-		protected final Map<ValueParam, ReflectedSetter> setters = new HashMap<>();
-		protected final Map<ValueParam, ReflectedGetter> getters = new HashMap<>();
-		protected final Map<ProcedureParam, ReflectedCaller> callers = new HashMap<>();
+		protected final Map<ValueParam, ReflectedSetter> setters = new IdentityHashMap<>();
+		protected final Map<ValueParam, ReflectedGetter> getters = new IdentityHashMap<>();
+		protected final Map<ProcedureParam, ReflectedCaller> callers = new IdentityHashMap<>();
 		protected final List<Method> autoAppendMethods = new ArrayList<>();
 
Index: /java/main/src/main/java/com/framsticks/params/Registry.java
===================================================================
--- /java/main/src/main/java/com/framsticks/params/Registry.java	(revision 97)
+++ /java/main/src/main/java/com/framsticks/params/Registry.java	(revision 98)
@@ -7,6 +7,7 @@
 import com.framsticks.util.DoubleMap;
 import com.framsticks.util.FramsticksException;
+import com.framsticks.util.lang.Strings;
 
-import java.util.HashMap;
+import java.util.IdentityHashMap;
 import java.util.Map;
 import java.util.Set;
@@ -23,5 +24,5 @@
 	protected final DoubleMap<String, Class<?>> javaClasses = new DoubleMap<>();
 	protected final DoubleMap<String, FramsClass> framsClasses = new DoubleMap<>();
-	protected final Map<Class<?>, FramsClass> javaToFramsAssociation = new HashMap<>();
+	protected final Map<Class<?>, FramsClass> javaToFramsAssociation = new IdentityHashMap<>();
 
 	/**
@@ -108,4 +109,5 @@
 	public @Nonnull AccessInterface createAccess(@Nonnull String name) throws ConstructionException {
 		try {
+			Strings.assureNotEmpty(name);
 			FramsClass framsClass = getFramsClass(name);
 			if (framsClass == null) {
Index: /java/main/src/main/java/com/framsticks/params/SimpleAbstractAccess.java
===================================================================
--- /java/main/src/main/java/com/framsticks/params/SimpleAbstractAccess.java	(revision 97)
+++ /java/main/src/main/java/com/framsticks/params/SimpleAbstractAccess.java	(revision 98)
@@ -1,5 +1,4 @@
 package com.framsticks.params;
 
-import java.util.Collection;
 
 import static com.framsticks.util.lang.Containers.filterInstanceof;
@@ -113,5 +112,5 @@
 			ReassignResult<?> result = param.reassign(value, oldValue);
 			Object casted = result.getValue();
-			if (!casted.equals(oldValue)) {
+			if (casted != null && !casted.equals(oldValue)) {
 				internalSet(param, casted);
 			}
@@ -273,6 +272,16 @@
 
 	@Override
-	public Collection<Param> getParams() {
+	public Iterable<Param> getParams() {
 		return framsClass.getParamEntries();
+	}
+
+	@Override
+	public int getCompositeParamCount() {
+		return framsClass.getCompositeParamCount();
+	}
+
+	@Override
+	public CompositeParam getCompositeParam(int number) {
+		return framsClass.getCompositeParam(number);
 	}
 
Index: /java/main/src/main/java/com/framsticks/params/UniqueListAccess.java
===================================================================
--- /java/main/src/main/java/com/framsticks/params/UniqueListAccess.java	(revision 97)
+++ /java/main/src/main/java/com/framsticks/params/UniqueListAccess.java	(revision 98)
@@ -1,4 +1,7 @@
 package com.framsticks.params;
 
+import com.framsticks.util.FramsticksException;
+import com.framsticks.util.UnimplementedException;
+import com.framsticks.util.UnsupportedOperationException;
 import com.framsticks.util.lang.Casting;
 import com.framsticks.util.lang.Numbers;
@@ -12,5 +15,5 @@
 public class UniqueListAccess extends ListAccess {
 
-	private static final Logger log = Logger.getLogger(UniqueListAccess.class.getName());
+	private static final Logger log = Logger.getLogger(UniqueListAccess.class);
 
 	Map<String, Object> map;
@@ -23,27 +26,75 @@
 	}
 
+	public static Integer getUidNumber(String uid) {
+		try {
+			return Integer.valueOf(uid.substring(1));
+		} catch (NumberFormatException e) {
+			return null;
+		}
+	}
+
+	public static class UidComparator implements Comparator<String> {
+
+		protected String name;
+
+		/**
+		 * @param name
+		 */
+		public UidComparator(String name) {
+			this.name = name;
+		}
+
+		@Override
+		public int compare(String a, String b) {
+			if (a.equals(b)) {
+				return 0;
+			}
+			int diff = a.length() - b.length();
+			if (diff != 0) {
+				return diff;
+			}
+			Integer au = getUidNumber(a);
+			Integer bu = getUidNumber(b);
+			if (au == null || bu == null) {
+				throw new FramsticksException().msg("comparator failure").arg("left", a).arg("right", b).arg("in", this);
+			}
+			return au - bu;
+		}
+
+		@Override
+		public String toString() {
+			return "comparator " + name;
+		}
+
+
+	}
+
 	@Override
 	public Map<String, Object> createAccessee() {
-		return new HashMap<String, Object>();
-	}
-
-	@Override
-	public Param getParam(int i) {
-		log.error("accesing unique list through index");
-		assert false;
-		return null;
-		//log.error("accesing unique list through index");
-		//return null;
-		//return Param.build().setId(Integer.toString(i)).setName(elementAccess.getId()).type("o " + elementAccess.getId()).build();
-	}
-
-	@Override
-	public Param getParam(String id) {
+		return new TreeMap<String, Object>(new UidComparator(elementAccess.toString()));
+	}
+
+	@Override
+	public CompositeParam getParam(int i) {
+		if ((i < 0) ||  (i >= map.size())) {
+			return null;
+		}
+		return Param.build().id(Integer.toString(i)).forAccess(elementAccess).finish(CompositeParam.class);
+	}
+
+	@Override
+	public CompositeParam getParam(String id) {
 		Integer i = Numbers.parse(id, Integer.class);
 		if (i != null) {
 			return getParam(i);
 		}
-		//TODO list access here
-		return Param.build().id(id).forAccess(elementAccess).finish();
+		Integer uidNumber = getUidNumber(id);
+		if (uidNumber == null) {
+			return null;
+		}
+		if (!map.containsKey(id)) {
+			return null;
+		}
+		return Param.build().id(id).forAccess(elementAccess).finish(CompositeParam.class);
 	}
 
@@ -60,9 +111,16 @@
 	@Override
 	public <T> T get(int i, Class<T> type) {
-		log.error("accesing unique list through index");
-		assert false;
-		return null;
-		//Object[] values = map.values().toArray();
-		//return Casting.tryCast(i < values.length ? values[i] : null, type);
+		Iterator<Map.Entry<String, Object>> iterator = map.entrySet().iterator();
+		while (i > 0 && iterator.hasNext()) {
+			iterator.next();
+			--i;
+		}
+		if (i > 0) {
+			return null;
+		}
+		if (!iterator.hasNext()) {
+			return null;
+		}
+		return Casting.tryCast(type, iterator.next().getValue());
 	}
 
@@ -73,5 +131,9 @@
 			return get(i, type);
 		}
-		return Casting.tryCast(type, map.containsKey(id) ? map.get(id) : null);
+		Integer uidNumber = getUidNumber(id);
+		if (uidNumber == null) {
+			return null;
+		}
+		return Casting.tryCast(type, map.get(id));
 	}
 
@@ -110,7 +172,5 @@
 	@Override
 	public <T> int set(int i, T value) {
-		log.error("accesing unique list through index");
-		//return setByUid(value, null);
-		return 0;
+		throw new UnsupportedOperationException().msg("accesing unique list through index");
 	}
 
@@ -184,13 +244,41 @@
 
 	@Override
-	public Collection<Param> getParams() {
-		List<Param> result = new LinkedList<Param>();
-		if (map == null) {
-			return result;
-		}
-		for (String k : map.keySet()) {
-			result.add(getParam(k));
-		}
-		return result;
+	public Iterable<Param> getParams() {
+		return new Iterable<Param>() {
+
+			@Override
+			public Iterator<Param> iterator() {
+				return new Iterator<Param>() {
+
+					protected Iterator<Map.Entry<String, Object>> internal = map.entrySet().iterator();
+
+					@Override
+					public boolean hasNext() {
+						return internal.hasNext();
+					}
+
+					@Override
+					public Param next() {
+						return Param.build().id(internal.next().getKey()).forAccess(elementAccess).finish();
+					}
+
+					@Override
+					public void remove() {
+						throw new UnimplementedException().msg("remove element from list").arg("list", UniqueListAccess.this);
+
+					}
+				};
+			}
+		};
+	}
+
+	@Override
+	public int getCompositeParamCount() {
+		return map.size();
+	}
+
+	@Override
+	public CompositeParam getCompositeParam(int number) {
+		return getParam(number);
 	}
 }
Index: /java/main/src/main/java/com/framsticks/params/types/ObjectParam.java
===================================================================
--- /java/main/src/main/java/com/framsticks/params/types/ObjectParam.java	(revision 97)
+++ /java/main/src/main/java/com/framsticks/params/types/ObjectParam.java	(revision 98)
@@ -50,3 +50,4 @@
 	}
 
+
 }
Index: /java/main/src/main/java/com/framsticks/params/types/UniqueListParam.java
===================================================================
--- /java/main/src/main/java/com/framsticks/params/types/UniqueListParam.java	(revision 97)
+++ /java/main/src/main/java/com/framsticks/params/types/UniqueListParam.java	(revision 98)
@@ -6,7 +6,7 @@
 import com.framsticks.params.ReassignResult;
 import com.framsticks.params.UniqueListAccess;
+import com.framsticks.util.lang.Casting;
 import com.framsticks.util.lang.Numbers;
 
-import java.util.HashMap;
 import java.util.Map;
 
@@ -54,8 +54,6 @@
 			information about it's elements is available, which would break resolution flow
 			*/
-			if (oldValue != null) {
-				return new ReassignResult<Map<?,?>>((Map<?,?>) oldValue);
-			}
-			return ReassignResult.create(new HashMap<Object, Object>());
+			return new ReassignResult<Map<?,?>>(Casting.tryCast(Map.class, oldValue));
+			// return ReassignResult.create(new TreeMap<Object, Object>());
 		}
 
Index: /java/main/src/main/java/com/framsticks/parsers/F0Parser.java
===================================================================
--- /java/main/src/main/java/com/framsticks/parsers/F0Parser.java	(revision 97)
+++ /java/main/src/main/java/com/framsticks/parsers/F0Parser.java	(revision 98)
@@ -7,5 +7,4 @@
 import java.text.ParseException;
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.List;
 
@@ -176,10 +175,15 @@
 		List<Exception> exceptions = new ArrayList<Exception>();
 
-		Collection<Param> paramsC = access.getParams();
-		Param[] params = paramsC.toArray(new Param[] {null});
+		List<Param> paramsL = new ArrayList<>();
+
+		for (Param param : access.getParams()) {
+			paramsL.add(param);
+		}
+
+		Param[] params = paramsL.toArray(new Param[] {null});
 		if (params.length == 0) {
 			return exceptions;
 		}
-		for (PrimitiveParam<?> p : Containers.filterInstanceof(paramsC, PrimitiveParam.class)) {
+		for (PrimitiveParam<?> p : Containers.filterInstanceof(paramsL, PrimitiveParam.class)) {
 			Object def = p.getDef(Object.class);
 			if (def != null) {
Index: /java/main/src/main/java/com/framsticks/portals/Portal.java
===================================================================
--- /java/main/src/main/java/com/framsticks/portals/Portal.java	(revision 97)
+++ /java/main/src/main/java/com/framsticks/portals/Portal.java	(revision 98)
@@ -2,18 +2,8 @@
 
 
-import com.framsticks.core.AbstractTreeListener;
 import com.framsticks.core.Tree;
-import com.framsticks.core.TreeOperations;
-import com.framsticks.core.Path;
 import com.framsticks.params.annotations.FramsClassAnnotation;
 import com.framsticks.params.annotations.ParamAnnotation;
-import com.framsticks.util.Logging;
-import com.framsticks.util.dispatching.Dispatching;
-import com.framsticks.util.dispatching.FutureHandler;
 import com.framsticks.util.dispatching.JoinableCollection;
-import com.framsticks.util.dispatching.RunAt;
-import com.framsticks.util.dispatching.ThrowExceptionHandler;
-
-import org.apache.log4j.Logger;
 
 
@@ -23,6 +13,4 @@
 @FramsClassAnnotation
 public class Portal extends JoinableCollection<Tree> {
-
-	private final static Logger log = Logger.getLogger(Portal.class.getName());
 
 	@ParamAnnotation
@@ -49,28 +37,28 @@
 	public void add(final Tree tree) {
 		super.add(tree);
-		tree.addListener(new AbstractTreeListener() {
-			@Override
-			public void onRun(Exception e) {
-				assert Dispatching.isThreadSafe();
+		// tree.addListener(new AbstractTreeListener() {
+		// 	@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";
-				tree.dispatch(new RunAt<Tree>(ThrowExceptionHandler.getInstance()) {
-					@Override
-					protected void runAt() {
-						TreeOperations.resolve(tree, path, new FutureHandler<Path>(Logging.logger(log, "resolve", path)) {
-							@Override
-							public void result(Path result) {
-								Logging.log(log, "resolve", path, null);
-							}
-						});
-					}
-				});
-			}
-		});
+		// 		if (e != null) {
+		// 			return;
+		// 		}
+		// 		final String path = "/simulator/genepools/groups/0/genotypes";
+		// 		tree.dispatch(new RunAt<Tree>(ThrowExceptionHandler.getInstance()) {
+		// 			@Override
+		// 			protected void runAt() {
+		// 				tryGet(tree, path, new FutureHandler<Path>(Logging.logger(log, "resolve", path)) {
+		// 					@Override
+		// 					public void result(Path result) {
+		// 						Logging.log(log, "resolve", path, null);
+		// 					}
+		// 				});
+		// 			}
+		// 		});
+		// 	}
+		// });
 	}
 
Index: /java/main/src/main/java/com/framsticks/remote/RecursiveFetcher.java
===================================================================
--- /java/main/src/main/java/com/framsticks/remote/RecursiveFetcher.java	(revision 97)
+++ /java/main/src/main/java/com/framsticks/remote/RecursiveFetcher.java	(revision 98)
@@ -55,5 +55,5 @@
 			for (CompositeParam p : filterInstanceof(access.getParams(), CompositeParam.class)) {
 				Object child = access.get(p, Object.class);
-				final Path childPath = path.appendNode(new Node(p, child));
+				final Path childPath = path.appendNode(new Node(path.getTree(), p, child));
 				if (childPath.isResolved() && getInfoFromCache(childPath) != null) {
 					++dispatched;
@@ -67,5 +67,5 @@
 				}
 				++dispatched;
-				tree.resolve(childPath, new FutureHandler<Path>(Logging.logger(log, "resolve", RecursiveFetcher.this)) {
+				tree.get(childPath, Mode.FETCH, new FutureHandler<Path>(Logging.logger(log, "resolve", RecursiveFetcher.this)) {
 					@Override
 					protected void result(Path result) {
@@ -83,5 +83,5 @@
 
 	protected void fetch(final Path path) {
-		tree.get(path, Mode.FETCH, new Future<Object>() {
+		tree.get(path, Mode.FETCH, new Future<Path>() {
 
 			@Override
@@ -92,6 +92,6 @@
 
 			@Override
-			protected void result(Object object) {
-				process(path);
+			protected void result(Path result) {
+				process(result);
 			}
 		});
Index: /java/main/src/main/java/com/framsticks/remote/RemoteTree.java
===================================================================
--- /java/main/src/main/java/com/framsticks/remote/RemoteTree.java	(revision 97)
+++ /java/main/src/main/java/com/framsticks/remote/RemoteTree.java	(revision 98)
@@ -8,7 +8,5 @@
 import com.framsticks.core.AbstractTree;
 import com.framsticks.core.Mode;
-import com.framsticks.core.TreeOperations;
 import com.framsticks.core.ListChange;
-import com.framsticks.core.Node;
 import com.framsticks.core.Path;
 import com.framsticks.params.*;
@@ -22,4 +20,5 @@
 import com.framsticks.util.*;
 import com.framsticks.util.dispatching.Dispatching;
+import com.framsticks.util.dispatching.Dispatching.DispatcherWaiter;
 import com.framsticks.util.dispatching.Future;
 import com.framsticks.util.dispatching.FutureHandler;
@@ -27,4 +26,5 @@
 import com.framsticks.util.dispatching.JoinableParent;
 import com.framsticks.util.dispatching.JoinableState;
+import com.framsticks.util.dispatching.ThrowExceptionHandler;
 import com.framsticks.util.lang.Casting;
 import com.framsticks.util.lang.Pair;
@@ -52,5 +52,5 @@
 	public Pair<Path, Subscription<?>> getSubscription(Path path) {
 		for (Pair<Path, Subscription<?>> s : subscriptions) {
-			if (s.first.matches(path)) {
+			if (s.first.isTheSameObjects(path)) {
 				return s;
 			}
@@ -75,14 +75,8 @@
 	public void setConnection(final ClientSideManagedConnection connection) {
 		this.connection = connection;
-		// final ExceptionResultHandler failure = new ExceptionResultHandler() {
-		// 	@Override
-		// 	public void handle(FramsticksException exception) {
-		// 		log.fatal("failed to establish connection: ", exception);
-		// 		// log.fatal("unsupported protocol version!\n minimal version is: " + "\nmanager protocol is: " + connection.getProtocolVersion());
-		// 		Dispatching.drop(connection, RemoteTree.this);
-		// 		fireRun(exception);
-		// 	}
-		// };
-
+	}
+
+	public final ClientSideManagedConnection getConnection() {
+		return connection;
 	}
 
@@ -93,13 +87,9 @@
 	}
 
-	public final ClientSideManagedConnection getConnection() {
-		return connection;
-	}
-
-	@Override
-	public void get(final Path path, final PrimitiveParam<?> param, Mode mode, final Future<Object> future) {
+	@Override
+	public void get(final Path path, final ValueParam param, Mode mode, final Future<Object> future) {
 		assert isActive();
 		assert param != null;
-		assert path.isResolved();
+		// assert path.isResolved();
 		//TODO only do that if needed
 		connection.send(new GetRequest().field(param.getId()).path(path.getTextual()), this, new ClientSideResponseFuture(future) {
@@ -107,6 +97,6 @@
 			protected void processOk(Response response) {
 				assert isActive();
-				TreeOperations.processFetchedValues(path, response.getFiles());
-				future.pass(bindAccess(path).get(param, Object.class));
+				processFetchedValues(path, response.getFiles());
+				future.pass(bindAccess(path.tryResolveIfNeeded()).get(param, Object.class));
 			}
 		});
@@ -164,5 +154,5 @@
 					throw new FramsticksException().msg("path mismatch").arg("returned path", response.getFiles().get(0).getPath());
 				}
-				FramsClass framsClass = TreeOperations.processFetchedInfo(RemoteTree.this, response.getFiles().get(0));
+				FramsClass framsClass = processFetchedInfo(RemoteTree.this, response.getFiles().get(0));
 
 				CompositeParam thisParam = path.getTop().getParam();
@@ -176,28 +166,30 @@
 
 	@Override
-	public void get(final Path path, Mode mode, final Future<Object> future) {
-		assert isActive();
-		assert path.getTop().getObject() != null;
+	public void get(final Path path, final Mode mode, final Future<Path> future) {
+		assert isActive();
 
 		log.trace("fetching values for " + path);
-		connection.send(new GetRequest().path(path.getTextual()), this, new ClientSideResponseFuture(future) {
-			@Override
-			protected void processOk(Response response) {
-				assert isActive();
-				TreeOperations.processFetchedValues(path, response.getFiles());
-				future.pass(path.getTopObject());
-			}
-		});
-	}
-
-	@Override
-	public void resolve(final Path path, final Future<Path> future) {
-		TreeOperations.resolve(path, future);
-	}
+		findInfo(path, new FutureHandler<FramsClass>(future) {
+			@Override
+			protected void result(FramsClass result) {
+
+				connection.send(new GetRequest().path(path.getTextual()), RemoteTree.this, new ClientSideResponseFuture(future) {
+					@Override
+					protected void processOk(Response response) {
+						assert isActive();
+						Path p = path.tryResolveIfNeeded();
+						processFetchedValues(p, response.getFiles());
+						future.pass(p.tryResolveIfNeeded().assureResolved());
+					}
+				});
+			}
+		});
+	}
+
 
 	@Override
 	protected void tryRegisterOnChangeEvents(final Path path) {
 		assert isActive();
-		AccessInterface access = TreeOperations.bindAccess(path);
+		AccessInterface access = bindAccess(path);
 		if (!(access instanceof ListAccess)) {
 			return;
@@ -274,5 +266,4 @@
 			protected void result(Path result) {
 				log.debug(listChange + ": " + result);
-				fireListChange(result, listChange);
 			}
 		};
@@ -282,10 +273,10 @@
 		assert isActive();
 		log.debug("reacting to change " + listChange + " in " + path);
-		AccessInterface access = TreeOperations.bindAccess(path);
+		AccessInterface access = bindAccess(path);
 		assert access != null;
 
 		if ((listChange.getAction() == ListChange.Action.Modify) && (listChange.getPosition() == -1)) {
 			final String p = path.getTextual();
-			TreeOperations.resolveAndGet(this, p, futureListChanger(listChange, p));
+			tryGet(this, p, futureListChanger(listChange, p));
 			return;
 		}
@@ -296,15 +287,14 @@
 			case Add: {
 				final String p = path.getTextual() + "/" + childParam.getId();
-				TreeOperations.resolveAndGet(this, p, futureListChanger(listChange, p));
+				tryGet(this, p, futureListChanger(listChange, p));
 				break;
 			}
 			case Remove: {
 				access.set(childParam, null);
-				fireListChange(path, listChange);
 				break;
 			}
 			case Modify: {
 				final String p = path.getTextual() + "/" + childParam.getId();
-				TreeOperations.resolveAndGet(this, p, futureListChanger(listChange, p));
+				tryGet(this, p, futureListChanger(listChange, p));
 				break;
 			}
@@ -315,5 +305,5 @@
 	public void set(final Path path, final PrimitiveParam<?> param, final Object value, final Future<Integer> future) {
 		assert isActive();
-		final Integer flag = TreeOperations.bindAccess(path).set(param, value);
+		final Integer flag = bindAccess(path).set(param, value);
 
 		log.trace("storing value " + param + " for " + path);
@@ -331,4 +321,21 @@
 		Dispatching.use(connection, this);
 		super.joinableStart();
+
+		dispatch(new RunAt<RemoteTree>(ThrowExceptionHandler.getInstance()) {
+			@Override
+			protected void runAt() {
+				final DispatcherWaiter<Tree, Tree> waiter = new DispatcherWaiter<Tree, Tree>(RemoteTree.this);
+
+				connection.send(new InfoRequest().path("/"), waiter, new ClientSideResponseFuture(this) {
+					@Override
+					protected void processOk(Response response) {
+						FramsClass framsClass = processFetchedInfo(RemoteTree.this, response.getFiles().get(0));
+						assignRootParam(Param.build().name("Tree").id(RemoteTree.this.getName()).type("o " + framsClass.getId()).finish(CompositeParam.class));
+					}
+				});
+
+				waiter.waitFor();
+			}
+		});
 	}
 
@@ -373,25 +380,26 @@
 	}
 
-	@Override
-	public Path create(Path path) {
-		assert isActive();
-		assert !path.isResolved();
-		Path resolved = path.tryFindResolution();
-		if (!resolved.isResolved()) {
-			log.debug("creating: " + path);
-			AccessInterface access = registry.prepareAccess(path.getTop().getParam());
-			assert access != null;
-			Object child = access.createAccessee();
-			assert child != null;
-			if (path.size() == 1) {
-				setRoot(new Node(getRoot().getParam(), child));
-			} else {
-				bindAccess(this, path.getUnder()).set(path.getTop().getParam(), child);
-			}
-			resolved = path.appendResolution(child);
-		}
-		tryRegisterOnChangeEvents(resolved);
-		return resolved;
-	}
+	// @Override
+	// public Path create(Path path) {
+	//	assert isActive();
+	//	assert !path.isResolved();
+	//	Path resolved = path.tryFindResolution();
+	//	if (!resolved.isResolved()) {
+	//		log.debug("creating: " + path);
+	//		//TODO: access parent here, check if it is valid, only then create
+	//		AccessInterface access = registry.prepareAccess(path.getTop().getParam());
+	//		assert access != null;
+	//		Object child = access.createAccessee();
+	//		assert child != null;
+	//		if (path.size() == 1) {
+	//			setRoot(new Node(getRoot().getParam(), child));
+	//		} else {
+	//			bindAccess(this, path.getUnder()).set(path.getTop().getParam(), child);
+	//		}
+	//		resolved = path.appendResolution(child);
+	//	}
+	//	tryRegisterOnChangeEvents(resolved);
+	//	return resolved;
+	// }
 
 }
Index: /java/main/src/main/java/com/framsticks/remote/SimulatorTree.java
===================================================================
--- /java/main/src/main/java/com/framsticks/remote/SimulatorTree.java	(revision 97)
+++ /java/main/src/main/java/com/framsticks/remote/SimulatorTree.java	(revision 98)
@@ -80,10 +80,9 @@
 			@Override
 			protected void runAt() {
-				resolveAndGet(SimulatorTree.this, "/simulator", new FutureHandler<Path>(Logging.logger(log, "failed to resolve simulator node", SimulatorTree.this)) {
+				tryGet(SimulatorTree.this, "/simulator", new FutureHandler<Path>(Logging.logger(log, "failed to resolve simulator node", SimulatorTree.this)) {
 					@Override
 					protected void result(Path path) {
 						assert isActive();
 						simulator = path;
-						fireRun(null);
 						log.info("resolved simulator node");
 
@@ -94,6 +93,5 @@
 							@Override
 							public void call(List<File> files) {
-								//TODO TEH
-								dispatch(new RunAt<Tree>(ThrowExceptionHandler.getInstance()) {
+								dispatch(new RunAt<Tree>(getExceptionHandler()) {
 									@Override
 									protected void runAt() {
@@ -103,5 +101,5 @@
 							}
 						}));
-						new PeriodicTask<Tree>(ThrowExceptionHandler.getInstance(), SimulatorTree.this, 1000) {
+						new PeriodicTask<Tree>(getExceptionHandler(), SimulatorTree.this, 1000) {
 							@Override
 							protected void runAt() {
Index: /java/main/src/main/java/com/framsticks/util/FramsticksException.java
===================================================================
--- /java/main/src/main/java/com/framsticks/util/FramsticksException.java	(revision 97)
+++ /java/main/src/main/java/com/framsticks/util/FramsticksException.java	(revision 98)
@@ -4,4 +4,5 @@
 import java.util.List;
 
+import com.framsticks.util.dispatching.ExceptionResultHandler;
 import com.framsticks.util.lang.Delimeted;
 import com.framsticks.util.lang.Pair;
@@ -75,3 +76,13 @@
 	}
 
+
+	public static ExceptionResultHandler addArgumentHandler(final ExceptionResultHandler innerHandler, final String header, final Object argument) {
+		return new ExceptionResultHandler() {
+			@Override
+			public void handle(FramsticksException exception) {
+				innerHandler.handle(exception.arg(header, argument));
+			}
+		};
+	}
+
 }
Index: /java/main/src/main/java/com/framsticks/util/dispatching/AtOnceDispatcher.java
===================================================================
--- /java/main/src/main/java/com/framsticks/util/dispatching/AtOnceDispatcher.java	(revision 97)
+++ /java/main/src/main/java/com/framsticks/util/dispatching/AtOnceDispatcher.java	(revision 98)
@@ -1,3 +1,4 @@
 package com.framsticks.util.dispatching;
+
 
 /**
@@ -24,4 +25,3 @@
 	}
 
-
 }
Index: /java/main/src/main/java/com/framsticks/util/dispatching/Dispatching.java
===================================================================
--- /java/main/src/main/java/com/framsticks/util/dispatching/Dispatching.java	(revision 97)
+++ /java/main/src/main/java/com/framsticks/util/dispatching/Dispatching.java	(revision 98)
@@ -86,4 +86,7 @@
 
 	public static void childChangedState(final JoinableParent parent, final Joinable joinable, final JoinableState state) {
+		if (state.ordinal() <= JoinableState.RUNNING.ordinal()) {
+			return;
+		}
 		dispatcherGuardedInvoke(joinable, new RunAt<Object>(ThrowExceptionHandler.getInstance()) {
 			@Override
@@ -118,6 +121,22 @@
 	}
 
-	public interface Query<T> {
+	public interface Query<T> extends ExceptionResultHandler {
 		T get();
+	}
+
+	public static abstract class QueryHandler<T> implements Query<T> {
+		ExceptionResultHandler handler;
+
+		/**
+		 * @param handler
+		 */
+		public QueryHandler(ExceptionResultHandler handler) {
+			this.handler = handler;
+		}
+
+		@Override
+		public void handle(FramsticksException exception) {
+			handler.handle(exception);
+		}
 	}
 
@@ -131,6 +150,5 @@
 		 */
 		public QueryRunner(Query<T> query) {
-			//TODO TEH
-			super(ThrowExceptionHandler.getInstance());
+			super(query);
 			this.query = query;
 		}
@@ -164,4 +182,42 @@
 	}
 
+	public static class DispatcherWaiter<C, T extends Dispatcher<C> & Joinable> implements Dispatcher<C> {
+		// protected boolean done = false;
+		protected final T dispatcher;
+		protected RunAt<? extends C> runnable;
+
+		/**
+		 * @param joinable
+		 */
+		public DispatcherWaiter(T dispatcher) {
+			this.dispatcher = dispatcher;
+		}
+
+		public synchronized void waitFor() {
+			while ((runnable == null) && (dispatcher.getState().ordinal() <= JoinableState.RUNNING.ordinal())) {
+				try {
+					this.wait();
+				} catch (InterruptedException e) {
+				}
+			}
+			if (runnable != null) {
+				runnable.run();
+			}
+
+		}
+
+		@Override
+		public boolean isActive() {
+			return dispatcher.isActive();
+		}
+
+		@Override
+		public synchronized void dispatch(RunAt<? extends C> runnable) {
+			this.runnable = runnable;
+			this.notifyAll();
+		}
+
+	}
+
 	public static class Waiter {
 		protected boolean done = false;
Index: /java/main/src/main/java/com/framsticks/util/dispatching/JoinableDispatcher.java
===================================================================
--- /java/main/src/main/java/com/framsticks/util/dispatching/JoinableDispatcher.java	(revision 98)
+++ /java/main/src/main/java/com/framsticks/util/dispatching/JoinableDispatcher.java	(revision 98)
@@ -0,0 +1,5 @@
+package com.framsticks.util.dispatching;
+
+public interface JoinableDispatcher<C> extends Dispatcher<C>, Joinable {
+
+}
Index: /java/main/src/main/java/com/framsticks/util/dispatching/Thread.java
===================================================================
--- /java/main/src/main/java/com/framsticks/util/dispatching/Thread.java	(revision 97)
+++ /java/main/src/main/java/com/framsticks/util/dispatching/Thread.java	(revision 98)
@@ -13,5 +13,5 @@
  * @author Piotr Sniegowski
  */
-public class Thread<C> extends AbstractJoinable implements Dispatcher<C> {
+public class Thread<C> extends AbstractJoinable implements JoinableDispatcher<C> {
 
 	private static final Logger log = Logger.getLogger(Thread.class);
Index: va/main/src/main/java/com/framsticks/util/swing/TreeNodeUtils.java
===================================================================
--- /java/main/src/main/java/com/framsticks/util/swing/TreeNodeUtils.java	(revision 97)
+++ 	(revision )
@@ -1,61 +1,0 @@
-package com.framsticks.util.swing;
-
-import java.util.Iterator;
-
-import javax.swing.tree.DefaultTreeModel;
-import javax.swing.tree.MutableTreeNode;
-import javax.swing.tree.TreeNode;
-
-public final class TreeNodeUtils {
-
-	private TreeNodeUtils() {
-	}
-
-	public static class TreeNodeChildrenIterator implements Iterator<TreeNode> {
-
-		final TreeNode treeNode;
-		final DefaultTreeModel treeModel;
-		int index;
-
-		/**
-		 * @param treeNode
-		 * @param number
-		 */
-		public TreeNodeChildrenIterator(TreeNode treeNode, DefaultTreeModel treeModel) {
-			this.treeNode = treeNode;
-			this.treeModel = treeModel;
-			this.index = 0;
-		}
-
-		@Override
-		public boolean hasNext() {
-			return index < treeNode.getChildCount();
-		}
-
-		@Override
-		public TreeNode next() {
-			int i = index;
-			++index;
-			return (TreeNode) treeModel.getChild(treeNode, i);
-		}
-
-		@Override
-		public void remove() {
-			if (treeNode instanceof MutableTreeNode) {
-				((MutableTreeNode) treeNode).remove(index);
-				return;
-			}
-			throw new UnsupportedOperationException();
-		}
-	}
-
-	public static Iterable<TreeNode> children(final TreeNode treeNode, final DefaultTreeModel treeModel) {
-		return new Iterable<TreeNode>() {
-			@Override
-			public Iterator<TreeNode> iterator() {
-				return new TreeNodeChildrenIterator(treeNode, treeModel);
-			}
-		};
-	}
-
-}
Index: /java/main/src/main/resources/configs/framsticks.xml
===================================================================
--- /java/main/src/main/resources/configs/framsticks.xml	(revision 97)
+++ /java/main/src/main/resources/configs/framsticks.xml	(revision 98)
@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <Framsticks>
-	<import class="com.framsticks.gui.console.ManagedConsole" />
-	<import class="com.framsticks.remote.RemoteTree" />
-	<ManagedConsole>
-		<RemoteTree name="remote" address="localhost:9009" />
-	</ManagedConsole>
+	<!-- <import class="com.framsticks.gui.console.ManagedConsole" /> -->
+	<!-- <import class="com.framsticks.remote.RemoteTree" /> -->
+	<!-- <ManagedConsole> -->
+	<!-- 	<RemoteTree name="remote" address="localhost:9009" /> -->
+	<!-- </ManagedConsole> -->
 
 	<!-- <import class="com.framsticks.gui.console.DirectConsole" /> -->
@@ -13,25 +13,25 @@
 	<!-- </DirectConsole> -->
 
-	<!-- <import class="com.framsticks.gui.Browser" /> -->
-	<!-- <import class="com.framsticks.remote.RemoteTree" /> -->
-	<!-- <import class="com.framsticks.remote.SimulatorTree" /> -->
-	<!-- <import class="com.framsticks.model.ModelPackage" /> -->
-	<!-- <import class="com.framsticks.model.ModelBuilder" /> -->
-	<!-- <import class="com.framsticks.model.f0.SchemaBuilder" /> -->
-	<!-- <import class="com.framsticks.core.ObjectTree" /> -->
-	<!-- <import class="com.framsticks.hosting.Server" /> -->
-	<!-- <import class="com.framsticks.test.TestClass" /> -->
-	<!-- <Browser> -->
-	<!-- 	<SimulatorTree name="localhost:9009" address="localhost:9009"> -->
-	<!-- 		<ModelPackage /> -->
-	<!-- 	</SimulatorTree> -->
-	<!-- 	<ObjectTree name="model"> -->
-	<!-- 		<ModelBuilder resource="/examples/f0_example.txt" /> -->
-	<!-- 	</ObjectTree> -->
-	<!-- 	<ObjectTree name="f0schema"> -->
-	<!-- 		<SchemaBuilder /> -->
-	<!-- 	</ObjectTree> -->
-	<!-- 	<RemoteTree name="remote" address="localhost:9007" /> -->
-	<!-- </Browser> -->
+	<import class="com.framsticks.gui.Browser" />
+	<import class="com.framsticks.remote.RemoteTree" />
+	<import class="com.framsticks.remote.SimulatorTree" />
+	<import class="com.framsticks.model.ModelPackage" />
+	<import class="com.framsticks.model.ModelBuilder" />
+	<import class="com.framsticks.model.f0.SchemaBuilder" />
+	<import class="com.framsticks.core.ObjectTree" />
+	<import class="com.framsticks.hosting.Server" />
+	<import class="com.framsticks.test.TestClass" />
+	<Browser>
+		<SimulatorTree name="localhost:9009" address="localhost:9009">
+			<ModelPackage />
+		</SimulatorTree>
+		<!-- <ObjectTree name="model"> -->
+		<!-- 	<ModelBuilder resource="/examples/f0_example.txt" /> -->
+		<!-- </ObjectTree> -->
+		<!-- <ObjectTree name="f0schema"> -->
+		<!-- 	<SchemaBuilder /> -->
+		<!-- </ObjectTree> -->
+		<!-- <RemoteTree name="remote" address="localhost:9007" /> -->
+	</Browser>
 	<!-- <Server name="server" port="9007"> -->
 	<!-- 	<ObjectTree name="test"> -->
Index: /java/main/src/main/resources/configs/log4j.properties
===================================================================
--- /java/main/src/main/resources/configs/log4j.properties	(revision 97)
+++ /java/main/src/main/resources/configs/log4j.properties	(revision 98)
@@ -29,5 +29,6 @@
 
 log4j.logger.com.framsticks=INFO
-# log4j.logger.com.framsticks.core.Framsticks=DEBUG
+# log4j.logger.com.framsticks.gui.Panel=DEBUG
+# log4j.logger.com.framsticks.remote.RemoteTree=DEBUG
 # log4j.logger.com.framsticks.gui.Frame=DEBUG
 # log4j.logger.com.framsticks.gui.controls.ProcedureControl=DEBUG
Index: /java/main/src/test/java/com/framsticks/core/ObjectTreeTest.java
===================================================================
--- /java/main/src/test/java/com/framsticks/core/ObjectTreeTest.java	(revision 97)
+++ /java/main/src/test/java/com/framsticks/core/ObjectTreeTest.java	(revision 98)
@@ -58,5 +58,5 @@
 		monitor.use();
 
-		assertThat(Dispatching.get(tree, new Dispatching.Query<String>() {
+		assertThat(Dispatching.get(tree, new Dispatching.QueryHandler<String>(failOnException) {
 				@Override
 				public String get() {
Index: /java/main/src/test/java/com/framsticks/gui/BrowserBaseTest.java
===================================================================
--- /java/main/src/test/java/com/framsticks/gui/BrowserBaseTest.java	(revision 97)
+++ /java/main/src/test/java/com/framsticks/gui/BrowserBaseTest.java	(revision 98)
@@ -12,4 +12,5 @@
 import org.fest.swing.edt.GuiActionRunner;
 
+import com.framsticks.util.dispatching.Dispatching;
 import com.framsticks.util.dispatching.Joinable;
 
@@ -26,4 +27,5 @@
 	protected Joinable createSubject() {
 		configureBrowser();
+		// browser.getMainFrame().getStatusBar().setExceptionHandler(failOnException);
 		return browser;
 	}
@@ -47,5 +49,7 @@
 
 	protected void clickAndExpandPath(String path) {
-		tree.clickPath(path).expandPath(path);
+		tree.clickPath(path);
+		Dispatching.sleep(1.0);
+		tree.expandPath(path);
 		robot.waitForIdle();
 	}
Index: /java/main/src/test/java/com/framsticks/gui/BrowserTest.java
===================================================================
--- /java/main/src/test/java/com/framsticks/gui/BrowserTest.java	(revision 97)
+++ /java/main/src/test/java/com/framsticks/gui/BrowserTest.java	(revision 98)
@@ -36,4 +36,6 @@
 	@Test(timeOut = 30000)
 	public void testShow() {
+		Dispatching.synchronize(localhost, 1.0);
+		// Dispatching.sleep(0.5);
 		log.info("testing");
 		tree.clickRow(0).expandRow(0);
@@ -56,6 +58,6 @@
 		clickAndExpandPath("localhost/simulator/genepools/groups/Genotypes");
 		clickAndExpandPath("localhost/simulator/genepools/groups/Genotypes/genotypes");
-		Dispatching.sleep(2.0);
-		clickAndExpandPath("localhost/simulator/genepools/groups/Genotypes/genotypes");
+		// Dispatching.sleep(2.0);
+		// clickAndExpandPath("localhost/simulator/genepools/groups/Genotypes/genotypes");
 		robot.pressAndReleaseKey(KeyEvent.VK_J);
 		waitForIdle();
Index: /java/main/src/test/java/com/framsticks/gui/console/TrackConsoleTest.java
===================================================================
--- /java/main/src/test/java/com/framsticks/gui/console/TrackConsoleTest.java	(revision 97)
+++ /java/main/src/test/java/com/framsticks/gui/console/TrackConsoleTest.java	(revision 98)
@@ -41,8 +41,8 @@
 	@Test
 	public void testCommunication() {
-		// Dispatching.sleep(2.0);
+		Dispatching.sleep(2.0);
 		final Waiter waiter = produceWaiter(1.0);
 
-		resolveAndGet(tree, "/simulator/genepools/groups/0", new FutureHandler<Path>(failOnException) {
+		tryGet(tree, "/simulator/genepools/groups/0", new FutureHandler<Path>(failOnException) {
 
 			@Override
Index: /java/main/src/test/java/com/framsticks/hosting/ServerTest.java
===================================================================
--- /java/main/src/test/java/com/framsticks/hosting/ServerTest.java	(revision 97)
+++ /java/main/src/test/java/com/framsticks/hosting/ServerTest.java	(revision 98)
@@ -84,18 +84,13 @@
 				assertThat(path.isResolved()).isFalse();
 
-				remote.resolve(path, new FutureHandler<Path>(failOnException) {
+				remote.get(path, Mode.FETCH, new FutureHandler<Path>(failOnException) {
 					@Override
-					protected void result(final Path result) {
-						assertThat(result.isResolved()).isTrue();
-						remotePath = result;
-						remote.get(result, Mode.FETCH, new FutureHandler<Object>(failOnException) {
-							@Override
-							protected void result(Object object) {
-								AccessInterface access = bindAccess(result);
-								assertThat(access).isInstanceOf(PropertiesAccess.class);
-								assertThat(access.get("name", String.class)).isEqualTo("a test name");
-								waiter.pass();
-							}
-						});
+					protected void result(Path path) {
+						assertThat(path.isResolved()).isTrue();
+						remotePath = path;
+						AccessInterface access = bindAccess(path);
+						assertThat(access).isInstanceOf(PropertiesAccess.class);
+						assertThat(access.get("name", String.class)).isEqualTo("a test name");
+						waiter.pass();
 					}
 				});
Index: /java/main/src/test/java/com/framsticks/test/TestConfiguration.java
===================================================================
--- /java/main/src/test/java/com/framsticks/test/TestConfiguration.java	(revision 97)
+++ /java/main/src/test/java/com/framsticks/test/TestConfiguration.java	(revision 98)
@@ -91,4 +91,5 @@
 		@Override
 		public void handle(FramsticksException e) {
+			e.printStackTrace();
 			assertThat(e).isNull();
 		}
Index: /java/main/src/test/resources/log4j.properties
===================================================================
--- /java/main/src/test/resources/log4j.properties	(revision 97)
+++ /java/main/src/test/resources/log4j.properties	(revision 98)
@@ -28,4 +28,7 @@
 log4j.logger.com.framsticks=WARN
 log4j.logger.com.framsticks.test.TestConfiguration=INFO
+# log4j.logger.com.framsticks.core.TreeOperations=DEBUG
+# log4j.logger.com.framsticks.core.AbstractTree=DEBUG
+# log4j.logger.com.framsticks.remote.RemoteTree=DEBUG
 # log4j.logger.com.framsticks.gui.console.TrackConsole=DEBUG
 # log4j.logger.com.framsticks.gui.controls.ProcedureControl=DEBUG
