Index: /java/main/src/main/java/com/framsticks/communication/ClientConnection.java
===================================================================
--- /java/main/src/main/java/com/framsticks/communication/ClientConnection.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/communication/ClientConnection.java	(revision 90)
@@ -45,5 +45,5 @@
 	protected void joinableStart() {
 		try {
-			log.info("connecting to " + address);
+			log.debug("connecting to " + address);
 
 			socket = new Socket(hostName, port);
@@ -51,5 +51,5 @@
 			socket.setSoTimeout(500);
 
-			log.info("connected to " + hostName + ":" + port);
+			log.debug("connected to " + hostName + ":" + port);
 			connected = true;
 			runThreads();
@@ -145,5 +145,5 @@
 
 		public void dispatchResponseProcess(final Response response) {
-			Dispatching.invokeLaterOrNow(dispatcher, new RunAt<C>() {
+			Dispatching.dispatchIfNotActive(dispatcher, new RunAt<C>() {
 				@Override
 				public void run() {
@@ -193,5 +193,5 @@
 		sentQuery.dispatcher = dispatcher;
 
-		senderThread.invokeLater(new RunAt<Connection>(){
+		senderThread.dispatch(new RunAt<Connection>(){
 			@Override
 			public void run() {
Index: /java/main/src/main/java/com/framsticks/communication/Connection.java
===================================================================
--- /java/main/src/main/java/com/framsticks/communication/Connection.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/communication/Connection.java	(revision 90)
@@ -135,5 +135,5 @@
 		Dispatching.use(threads, this);
 
-		receiverThread.invokeLater(new RunAt<Connection>() {
+		receiverThread.dispatch(new RunAt<Connection>() {
 			@Override
 			public void run() {
Index: /java/main/src/main/java/com/framsticks/communication/ServerConnection.java
===================================================================
--- /java/main/src/main/java/com/framsticks/communication/ServerConnection.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/communication/ServerConnection.java	(revision 90)
@@ -66,5 +66,5 @@
 
 	protected final void respond(final Response response, final Integer id) {
-		senderThread.invokeLater(new RunAt<Connection>() {
+		senderThread.dispatch(new RunAt<Connection>() {
 			@Override
 			public void run() {
Index: /java/main/src/main/java/com/framsticks/communication/Subscription.java
===================================================================
--- /java/main/src/main/java/com/framsticks/communication/Subscription.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/communication/Subscription.java	(revision 90)
@@ -75,5 +75,5 @@
 
 	public void dispatchCall(final List<File> files) {
-		Dispatching.invokeLaterOrNow(dispatcher, new RunAt<C>() {
+		Dispatching.dispatchIfNotActive(dispatcher, new RunAt<C>() {
 			@Override
 			public void run() {
Index: /java/main/src/main/java/com/framsticks/core/Framsticks.java
===================================================================
--- /java/main/src/main/java/com/framsticks/core/Framsticks.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/core/Framsticks.java	(revision 90)
@@ -4,5 +4,5 @@
 import com.framsticks.parsers.XmlLoader;
 import com.framsticks.util.dispatching.JoinableCollection;
-import com.framsticks.util.dispatching.JoinableMonitor;
+import com.framsticks.util.dispatching.Monitor;
 
 import org.apache.log4j.Logger;
@@ -23,17 +23,14 @@
 
 	public static Framsticks loadConfiguration(InputStream stream) {
-		return new XmlLoader().load(stream, Framsticks.class);
+		return new XmlLoader().load(Framsticks.class, stream);
 	}
 
 	public static void main(final String[] args) {
 
-		final Framsticks framsticks = loadConfiguration(Framsticks.class.getResourceAsStream("/configs/framsticks.xml"));
-
-		new JoinableMonitor(framsticks).use().waitFor().drop().join();
-
-		// monitor.use();
-		// monitor.waitFor();
-		// monitor.drop();
-		// monitor.join();
+		new Monitor(loadConfiguration(Framsticks.class.getResourceAsStream("/configs/framsticks.xml")))
+			.use()
+			.waitFor()
+			.drop()
+			.join();
 
 		log.info("exiting main");
Index: /java/main/src/main/java/com/framsticks/core/Instance.java
===================================================================
--- /java/main/src/main/java/com/framsticks/core/Instance.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/core/Instance.java	(revision 90)
@@ -8,5 +8,4 @@
 
 import javax.annotation.Nonnull;
-import javax.annotation.OverridingMethodsMustInvokeSuper;
 
 import org.apache.log4j.Logger;
@@ -14,14 +13,19 @@
 import com.framsticks.communication.File;
 import com.framsticks.params.AccessInterface;
+import com.framsticks.params.CompositeParam;
 import com.framsticks.params.ConstructionException;
 import com.framsticks.params.FramsClass;
 import com.framsticks.params.ListAccess;
 import com.framsticks.params.Param;
+import com.framsticks.params.ParamsPackage;
 import com.framsticks.params.Registry;
 import com.framsticks.params.ValueParam;
+import com.framsticks.params.annotations.AutoAppendAnnotation;
 import com.framsticks.params.annotations.FramsClassAnnotation;
 import com.framsticks.params.types.ObjectParam;
+import com.framsticks.params.types.ProcedureParam;
 import com.framsticks.parsers.Loaders;
 import com.framsticks.parsers.MultiParamLoader;
+import com.framsticks.util.FramsticksException;
 import com.framsticks.util.StateFunctor;
 import com.framsticks.util.UnsupportedOperationException;
@@ -40,5 +44,25 @@
 	private static final Logger log = Logger.getLogger(Instance.class.getName());
 
-	protected Node root;
+	private Node root;
+
+	protected @Nonnull Node setRoot(CompositeParam param, Object object) {
+		// if (isRootAssigned()) {
+		// 	throw new FramsticksException().msg("root is already assigned");
+		// }
+		// assert isActive();
+		root = new Node(param, object);
+		return root;
+	}
+
+	protected @Nonnull Node getRoot() {
+		// assert isActive();
+		assert root != null;
+		return root;
+	}
+
+	public boolean isRootAssigned() {
+		// assert isActive();
+		return root != null;
+	}
 
 	protected Set<InstanceListener> listeners = new HashSet<InstanceListener>();
@@ -68,11 +92,18 @@
 	}
 
-	public void fetchValue(Path path, Param param, StateFunctor stateFunctor) {
-		stateFunctor.call(null);
-	}
-
-	public void fetchValues(Path path, StateFunctor stateFunctor) {
-		stateFunctor.call(null);
-	}
+	/** This is part of the Instance interface.
+	 *
+	 */
+	public abstract void fetchValue(Path path, Param param, StateFunctor stateFunctor);
+
+	/** This is part of the Instance interface.
+	 *
+	 */
+	public abstract void fetchValues(Path path, StateFunctor stateFunctor);
+
+	/** This is part of the Instance interface.
+	 *
+	 */
+	public abstract void call(Path path, ProcedureParam param, Object[] arguments, StateFunctor stateFunctor);
 
 	protected void tryRegisterOnChangeEvents(Path path) {
@@ -82,5 +113,5 @@
 	public void storeValue(Path path, Param param, Object value, final StateFunctor stateFunctor) {
 		assert isActive();
-		invokeLater(new RunAt<Instance>() {
+		dispatch(new RunAt<Instance>() {
 			@Override
 			public void run() {
@@ -104,5 +135,5 @@
 	public void addListener(final InstanceListener listener) {
 		assert Dispatching.isThreadSafe();
-		Dispatching.invokeLaterOrNow(this, new RunAt<Instance>() {
+		Dispatching.dispatchIfNotActive(this, new RunAt<Instance>() {
 			@Override
 			public void run() {
@@ -114,5 +145,5 @@
 	public void removeListener(final InstanceListener listener) {
 		assert Dispatching.isThreadSafe();
-		Dispatching.invokeLaterOrNow(this, new RunAt<Instance>() {
+		Dispatching.dispatchIfNotActive(this, new RunAt<Instance>() {
 			@Override
 			public void run() {
@@ -142,5 +173,5 @@
 	public FramsClass getInfoFromCache(String id) {
 		assert isActive();
-		return registry.getInfoFromCache(id);
+		return registry.getFramsClass(id);
 	}
 
@@ -169,9 +200,18 @@
 	}
 
+	public final AccessInterface bindAccess(String path) {
+		return bindAccess(getPath(path));
+	}
+
 	public final AccessInterface bindAccess(Node node) {
+		assert isActive();
 		assert node.getObject() != null;
 
 		try {
-			return registry.prepareAccess(node.getParam()).select(node.getObject());
+			AccessInterface access = registry.prepareAccess(node.getParam());
+			if (access == null) {
+				throw new FramsticksException().msg("failed to prepare access for param").arg("param", node.getParam());
+			}
+			return access.select(node.getObject());
 		} catch (ConstructionException e) {
 			log.error("failed to bind access for " + node.getParam() + ": " + e);
@@ -185,5 +225,5 @@
 
 	public final AccessInterface bindAccess(Path path) {
-		assert path.isResolved();
+		path.assureResolved();
 		return bindAccess(path.getTop());
 	}
@@ -260,5 +300,5 @@
 			assert child != null;
 			if (path.size() == 1) {
-				root = new Node(root.getParam(), child);
+				setRoot(getRoot().getParam(), child);
 			} else {
 				bindAccess(path.getUnder()).set(path.getTop().getParam(), child);
@@ -277,9 +317,9 @@
 		FramsClass framsClass = Loaders.loadFramsClass(file.getContent());
 		if ("/".equals(file.getPath())) {
-			if (root.getParam().getContainedTypeName() == null) {
-				root = new Node(Param.build().name("Instance").id(getName()).type("o " + framsClass.getId()), root.getObject());
-			}
-		}
-		registry.putInfoIntoCache(framsClass);
+			if (getRoot().getParam().getContainedTypeName() == null) {
+				setRoot(Param.build().name("Instance").id(getName()).type("o " + framsClass.getId()).finish(CompositeParam.class), getRoot().getObject());
+			}
+		}
+		registry.putFramsClass(framsClass);
 		return framsClass;
 	}
@@ -299,7 +339,4 @@
 				loader.go();
 				fireFetch(path);
-	//            for (NodeListener l : listeners) {
-	//                l.onChange(this);
-	//            }
 				return;
 			}
@@ -318,5 +355,5 @@
 					String id = listAccess.computeIdentifierFor(accessInterface.getSelected());
 					//TODO listAccessParam
-					Param param = Param.build().type("o " + accessInterface.getId()).id(id).finish();
+					Param param = Param.build().forAccess(accessInterface).id(id).finish();
 					Object child = accessInterface.getSelected();
 					accessInterface.select(null);
@@ -327,7 +364,4 @@
 
 			fireFetch(path);
-	//        for (NodeListener l : listeners) {
-	//            l.onChange(this);
-	//        }
 		} catch (Exception e) {
 			log.error("exception occurred while loading: " + e);
@@ -358,9 +392,27 @@
 	}
 
+	@AutoAppendAnnotation
+	public void usePackage(ParamsPackage paramsPackage) {
+		log.debug("using package " + paramsPackage + " in instance " + this);
+		paramsPackage.register(registry);
+	}
+
+	@AutoAppendAnnotation
+	public void takeFromRegistry(Registry registry) {
+		log.debug("taking from registry " + registry + " in instance " + this);
+		this.registry.takeAllFrom(registry);
+	}
+
 	@Override
-	@OverridingMethodsMustInvokeSuper
-	protected void firstTask() {
-		root = new Node(Param.build().name("Instance").id(getName()).type("o"), null);
-		com.framsticks.model.Package.register(registry);
+	protected void joinableStart() {
+		dispatch(new RunAt<Instance>() {
+			@Override
+			public void run() {
+				if (!isRootAssigned()) {
+					setRoot(Param.build().name("Instance").id(getName()).type("o").finish(CompositeParam.class), null);
+				}
+			}
+		});
+		super.joinableStart();
 	}
 
Index: /java/main/src/main/java/com/framsticks/core/LocalInstance.java
===================================================================
--- /java/main/src/main/java/com/framsticks/core/LocalInstance.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/core/LocalInstance.java	(revision 90)
@@ -50,5 +50,5 @@
 
 	protected void acceptNext() {
-		acceptThread.invokeLater(new RunAt<Accept>() {
+		acceptThread.dispatch(new RunAt<Accept>() {
 			@Override
 			public void run() {
@@ -57,5 +57,5 @@
 					assert socket != null;
 					log.debug("accepted socket: " + socket.getInetAddress().getHostAddress());
-					invokeLater(new RunAt<LocalInstance>() {
+					dispatch(new RunAt<LocalInstance>() {
 						@Override
 						public void run() {
@@ -74,5 +74,5 @@
 
 	public void tryBind(final Integer accept) {
-		acceptThread.invokeLater(new RunAt<Accept>() {
+		acceptThread.dispatch(new RunAt<Accept>() {
 			@Override
 			public void run() {
Index: /java/main/src/main/java/com/framsticks/core/Node.java
===================================================================
--- /java/main/src/main/java/com/framsticks/core/Node.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/core/Node.java	(revision 90)
@@ -29,5 +29,5 @@
 
 	public Node(@Nonnull ParamBuilder builder, Object object) {
-		this((CompositeParam) builder.finish(), object);
+		this(builder.finish(CompositeParam.class), object);
 	}
 
Index: /java/main/src/main/java/com/framsticks/core/ObjectInstance.java
===================================================================
--- /java/main/src/main/java/com/framsticks/core/ObjectInstance.java	(revision 90)
+++ /java/main/src/main/java/com/framsticks/core/ObjectInstance.java	(revision 90)
@@ -0,0 +1,65 @@
+package com.framsticks.core;
+
+import org.apache.log4j.Logger;
+
+import com.framsticks.params.AccessInterface;
+import com.framsticks.params.CompositeParam;
+import com.framsticks.params.Param;
+import com.framsticks.params.annotations.AutoAppendAnnotation;
+import com.framsticks.params.annotations.FramsClassAnnotation;
+import com.framsticks.params.types.ProcedureParam;
+import com.framsticks.util.FramsticksException;
+import com.framsticks.util.StateFunctor;
+
+@FramsClassAnnotation
+public class ObjectInstance extends Instance {
+	private static final Logger log = Logger.getLogger(ObjectInstance.class);
+
+	@AutoAppendAnnotation
+	public void setRootObject(Object object) {
+		registry.registerAndBuild(object.getClass());
+		AccessInterface access = registry.createAccess(object.getClass());
+		setRoot(Param.build().forAccess(access).id(getName()).finish(CompositeParam.class), object);
+	}
+
+	public Object getRootObject() {
+		return getRoot().getObject();
+	}
+
+	public <T> T getRootObject(Class<T> type) {
+		Object result = getRootObject();
+		if (result == null) {
+			throw new FramsticksException().msg("object instance is empty").arg("instance", this);
+		}
+		if (!type.isInstance(result)) {
+			throw new FramsticksException().msg("object instance holds object of different kind").arg("object", result).arg("requested", type).arg("instance", this);
+		}
+		return type.cast(result);
+	}
+
+	@Override
+	public void fetchValues(final Path path, final StateFunctor stateFunctor) {
+		assert isActive();
+		log.debug("requesting: " + path);
+		fireFetch(path);
+		stateFunctor.call(null);
+	}
+
+	@Override
+	public void fetchValue(Path path, Param param, StateFunctor stateFunctor) {
+		assert isActive();
+		fireFetch(path);
+		stateFunctor.call(null);
+	}
+
+	@Override
+	public void call(Path path, ProcedureParam param, Object[] arguments, StateFunctor stateFunctor) {
+		assert isActive();
+		try {
+			bindAccess(path).call(param, arguments);
+			stateFunctor.call(null);
+		} catch (FramsticksException e) {
+			stateFunctor.call(e);
+		}
+	}
+}
Index: /java/main/src/main/java/com/framsticks/core/Path.java
===================================================================
--- /java/main/src/main/java/com/framsticks/core/Path.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/core/Path.java	(revision 90)
@@ -4,4 +4,5 @@
 import com.framsticks.params.CompositeParam;
 import com.framsticks.params.Param;
+import com.framsticks.util.FramsticksException;
 import com.framsticks.util.dispatching.Dispatching;
 
@@ -30,5 +31,10 @@
 			return null;
 		}
-		return (instance.registry.prepareAccess(param) != null) ? child : null;
+		try {
+			instance.registry.prepareAccess(param);
+			return child;
+		} catch (FramsticksException e) {
+		}
+		return null;
 	}
 
@@ -119,6 +125,6 @@
 			this.instance = instance;
 
-			nodes.add(instance.root);
-			Node current = instance.root;
+			nodes.add(instance.getRoot());
+			Node current = instance.getRoot();
 
 			StringBuilder b = new StringBuilder();
@@ -254,4 +260,10 @@
 		return ListUtils.unmodifiableList(nodes);
 	}
+
+	public void assureResolved() {
+		if (!isResolved()) {
+			throw new FramsticksException().msg("path is not resolved").arg("path", this);
+		}
+	}
 }
 
Index: /java/main/src/main/java/com/framsticks/dumping/FileInstance.java
===================================================================
--- /java/main/src/main/java/com/framsticks/dumping/FileInstance.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/dumping/FileInstance.java	(revision 90)
@@ -7,4 +7,5 @@
 import com.framsticks.params.annotations.ParamAnnotation;
 import com.framsticks.util.dispatching.Future;
+import com.framsticks.util.dispatching.RunAt;
 import com.framsticks.util.io.Encoding;
 
@@ -17,5 +18,4 @@
 import java.io.InputStreamReader;
 
-import javax.annotation.OverridingMethodsMustInvokeSuper;
 
 /**
@@ -23,5 +23,5 @@
  */
 @FramsClassAnnotation
-public class FileInstance extends LocalInstance {
+public abstract class FileInstance extends LocalInstance {
 
 	private static final Logger log = Logger.getLogger(Instance.class.getName());
@@ -42,34 +42,39 @@
 
 	@Override
-	@OverridingMethodsMustInvokeSuper
-	protected void firstTask() {
-		assert isActive();
-		super.firstTask();
-		try {
-			LoadStream stream = new LoadStream(this.getRootPath(), new BufferedReader(new InputStreamReader(new FileInputStream(file), Encoding.getFramsticksCharset())), this, new Future<Path>() {
-				@Override
-				public void result(Path result, Exception e) {
-					if (e != null) {
-						log.error("failed to load file instance " + FileInstance.this + ": " + e);
-						fireRun(e);
-						return;
-					}
-					log.info("loaded file instance " + FileInstance.this);
-					fireRun(null);
-				}
-			});
-			stream.load();
-		} catch (IOException e) {
-			log.error("io failure: " + e);
-			fireRun(e);
-		}
-	}
-
-	@Override
 	public String toString() {
 		return "file@" + file.getName();
 	}
 
+	@Override
+	protected void joinableStart() {
+		dispatch(new RunAt<Instance>() {
 
+			@Override
+			public void run() {
+				assert isActive();
+
+				try {
+					LoadStream stream = new LoadStream(FileInstance.this.getRootPath(), new BufferedReader(new InputStreamReader(new FileInputStream(file), Encoding.getFramsticksCharset())), FileInstance.this, new Future<Path>() {
+						@Override
+						public void result(Path result, Exception e) {
+							if (e != null) {
+								log.error("failed to load file instance " + FileInstance.this + ": " + e);
+								fireRun(e);
+								return;
+							}
+							log.info("loaded file instance " + FileInstance.this);
+							fireRun(null);
+						}
+					});
+					stream.load();
+				} catch (IOException e) {
+					log.error("io failure: " + e);
+					fireRun(e);
+				}
+			}
+
+		});
+		super.joinableStart();
+	}
 
 }
Index: /java/main/src/main/java/com/framsticks/dumping/SaveStream.java
===================================================================
--- /java/main/src/main/java/com/framsticks/dumping/SaveStream.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/dumping/SaveStream.java	(revision 90)
@@ -44,5 +44,5 @@
 	protected void dispatchWrite(final Path path) {
 		++dispatched;
-		instance.invokeLater(new RunAt<Instance>() {
+		instance.dispatch(new RunAt<Instance>() {
 			@Override
 			public void run() {
Index: /java/main/src/main/java/com/framsticks/gui/Browser.java
===================================================================
--- /java/main/src/main/java/com/framsticks/gui/Browser.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/gui/Browser.java	(revision 90)
@@ -69,5 +69,5 @@
 	public void autoResolvePath(final String path, final Future<Path> future) {
 		final Instance i = instances.get("localhost");
-		i.invokeLater(new RunAt<Instance>() {
+		i.dispatch(new RunAt<Instance>() {
 			@Override
 			public void run() {
@@ -80,5 +80,5 @@
 						}
 						if (e == null) {
-							mainFrame.invokeLater(new RunAt<Frame>() {
+							mainFrame.dispatch(new RunAt<Frame>() {
 								@Override
 								public void run() {
@@ -100,7 +100,7 @@
 	}
 
-	protected void firstTask() {
+	protected void initializeGUI() {
 		assert isActive();
-		log.info("executing first task");
+		log.debug("executing first task");
 
 		try {
@@ -129,9 +129,9 @@
 
 		for (final Instance i : instances) {
-			i.invokeLater(new RunAt<Instance>() {
+			i.dispatch(new RunAt<Instance>() {
 				@Override
 				public void run() {
 					final Path p = i.getRootPath();
-					invokeLater(new RunAt<Browser>() {
+					dispatch(new RunAt<Browser>() {
 						@Override
 						public void run() {
@@ -183,8 +183,8 @@
 		Dispatching.use(instances, this);
 
-		invokeLater(new RunAt<Browser>() {
+		dispatch(new RunAt<Browser>() {
 			@Override
 			public void run() {
-				firstTask();
+				initializeGUI();
 			}
 		});
@@ -227,6 +227,6 @@
 
 	@Override
-	public void invokeLater(RunAt<? extends Browser> runnable) {
-		SwingDispatcher.getInstance().invokeLater(runnable);
+	public void dispatch(RunAt<? extends Browser> runnable) {
+		SwingDispatcher.getInstance().dispatch(runnable);
 	}
 
Index: /java/main/src/main/java/com/framsticks/gui/Frame.java
===================================================================
--- /java/main/src/main/java/com/framsticks/gui/Frame.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/gui/Frame.java	(revision 90)
@@ -285,6 +285,6 @@
 
 	@Override
-	public void invokeLater(RunAt<? extends Frame> runnable) {
-		SwingDispatcher.getInstance().invokeLater(runnable);
+	public void dispatch(RunAt<? extends Frame> runnable) {
+		SwingDispatcher.getInstance().dispatch(runnable);
 	}
 
@@ -427,5 +427,5 @@
 		super.joinableInterrupt();
 
-		invokeLater(new RunAt<Frame>() {
+		dispatch(new RunAt<Frame>() {
 			@Override
 			public void run() {
Index: /java/main/src/main/java/com/framsticks/gui/Gui.java
===================================================================
--- /java/main/src/main/java/com/framsticks/gui/Gui.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/gui/Gui.java	(revision 90)
@@ -14,4 +14,5 @@
 import com.framsticks.gui.controls.CheckBoxControl;
 import com.framsticks.gui.controls.Control;
+import com.framsticks.gui.controls.ControlOwner;
 import com.framsticks.gui.controls.EnumControl;
 import com.framsticks.gui.controls.EventControl;
@@ -33,4 +34,5 @@
 import com.framsticks.params.types.StringParam;
 import com.framsticks.params.types.UniversalParam;
+import com.framsticks.util.FramsticksException;
 import com.framsticks.util.lang.Strings;
 
@@ -92,20 +94,26 @@
 	}
 
-	public static void fillWithControls(JPanel panel, Collection<Param> params, Map<Param, Control> components) {
-		for (Param param : params) {
+	public static <P extends Param, C extends Control> void fillWithControls(ControlOwner owner, Collection<P> params, Map<P, C> components, Class<C> controlType) {
+		JPanel panel = owner.getPanel();
+		for (P param : params) {
 			if (param.isUserHidden()) {
 				continue;
 			}
 			assert !(param instanceof CompositeParam);
-			Control control = Gui.createSuitable(param);
-			if (control == null) {
-				log.error("component for param " + param + " of type " + param.getClass().getSimpleName() + " was not added");
-				continue;
+			Control c = Gui.createSuitable(param);
+
+			if (!controlType.isInstance(c)) {
+				throw new FramsticksException().msg("created control is not of required type").arg("control", c).arg("type", controlType);
 			}
+
+			C control = controlType.cast(c);
+
+			control.setOwner(owner);
+
 			log.debug("add component for " + param);
 			JPanel line = new JPanel();
 			line.setLayout(new BoxLayout(line, BoxLayout.LINE_AXIS));
 			line.setAlignmentX(JPanel.LEFT_ALIGNMENT);
-			JLabel label = new JLabel(Strings.notEmpty(param.getName()) ? param.getName() : "? (" + param.getId() + ")");
+			JLabel label = new JLabel(Strings.notEmpty(param.getName()) ? param.getName() : (Strings.notEmpty(param.getId()) ? param.getId() : "?"));
 			label.setToolTipText(control.getToolTipText());
 			label.setHorizontalAlignment(JLabel.RIGHT);
Index: /java/main/src/main/java/com/framsticks/gui/ImageProvider.java
===================================================================
--- /java/main/src/main/java/com/framsticks/gui/ImageProvider.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/gui/ImageProvider.java	(revision 90)
@@ -15,8 +15,8 @@
 public class ImageProvider {
 
-    private final static Logger log = Logger.getLogger(ImageProvider.class.getName());
+	private final static Logger log = Logger.getLogger(ImageProvider.class.getName());
 
 
-    /**
+	/**
 	 * HashMap stores icons. Key is icon path, Value is icon.
 	 */
@@ -80,11 +80,11 @@
 			return icons.get(imageName);
 		}
-        String resourceName = "/shared/res/network/" + imageName;
+		String resourceName = "/shared/res/network/" + imageName;
 		try {
-            ImageIcon icon = new ImageIcon(ImageProvider.class.getResource(resourceName));
+			ImageIcon icon = new ImageIcon(ImageProvider.class.getResource(resourceName));
 			icons.put(imageName, icon);
-            return icon;
+			return icon;
 		} catch (Exception ignored) {
-            log.error("failed to read icon: " + resourceName);
+			log.error("failed to read icon: " + resourceName);
 		}
 		return null;
Index: /java/main/src/main/java/com/framsticks/gui/InstanceAtFrame.java
===================================================================
--- /java/main/src/main/java/com/framsticks/gui/InstanceAtFrame.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/gui/InstanceAtFrame.java	(revision 90)
@@ -72,6 +72,5 @@
 		List<Panel> panels = new ArrayList<Panel>();
 
-		Panel.Parameters parameters = new Panel.Parameters(this, param,
-				framsClass);
+		Panel.Parameters parameters = new Panel.Parameters(this, param, framsClass);
 		for (PanelProvider pp : frame.browser.panelProviders) {
 			Panel p = pp.providePanel(parameters);
@@ -150,5 +149,5 @@
 		log.trace("fetched " + path);
 
-		frame.invokeLater(new RunAt<Frame>() {
+		frame.dispatch(new RunAt<Frame>() {
 			@Override
 			public void run() {
@@ -159,5 +158,5 @@
 				final TreeNode result = (TreeNode) treePath.getLastPathComponent();
 				// log.trace("found " + result + " == " + path);
-				instance.invokeLater(new RunAt<Instance>() {
+				instance.dispatch(new RunAt<Instance>() {
 					@Override
 					public void run() {
Index: /java/main/src/main/java/com/framsticks/gui/ObjectPanel.java
===================================================================
--- /java/main/src/main/java/com/framsticks/gui/ObjectPanel.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/gui/ObjectPanel.java	(revision 90)
@@ -2,4 +2,5 @@
 
 import com.framsticks.gui.controls.Control;
+import com.framsticks.gui.controls.ControlOwner;
 import com.framsticks.gui.controls.ValueControl;
 import com.framsticks.gui.controls.ValueControlListener;
@@ -11,4 +12,5 @@
 
 import javax.swing.*;
+
 import java.util.Collection;
 import java.util.HashMap;
@@ -18,5 +20,5 @@
 
 @SuppressWarnings("serial")
-public class ObjectPanel extends ModifiablePanel {
+public class ObjectPanel extends ModifiablePanel implements ControlOwner {
 
 	private static final Logger log = Logger.getLogger(ObjectPanel.class.getName());
@@ -28,5 +30,6 @@
 		super(parameters);
 
-		Gui.fillWithControls(contentPanel, params, components);
+		Gui.fillWithControls(this, params, components, Control.class);
+		setName(framsClass.getId());
 
 		for (final ValueControl c : filterInstanceof(components.values(), ValueControl.class)) {
@@ -44,4 +47,5 @@
 			});
 		}
+
 		contentPanel.add(Box.createVerticalGlue());
 		this.revalidate();
@@ -74,5 +78,5 @@
 		}
 
-		frame.invokeLater(new RunAt<Frame>() {
+		frame.dispatch(new RunAt<Frame>() {
 			@Override
 			public void run() {
@@ -97,25 +101,34 @@
 	}
 
+	@Override
+	public JPanel getPanel() {
+		return contentPanel;
+	}
+
+	@Override
+	public TreeNode getCurrentTreeNode() {
+		return super.getCurrentTreeNode();
+	}
 
 	// public void updateValue() {
-	// 	//assert panel.getFrame().isActive();
+	//	//assert panel.getFrame().isActive();
 
-	// 	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);
-	// 				}
-	// 			});
-	// 		}
-	// 	});
+	//	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/SwingDispatcher.java
===================================================================
--- /java/main/src/main/java/com/framsticks/gui/SwingDispatcher.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/gui/SwingDispatcher.java	(revision 90)
@@ -21,5 +21,5 @@
 
 	public SwingDispatcher() {
-		invokeLater(new RunAt<C>() {
+		dispatch(new RunAt<C>() {
 			@Override
 			public void run() {
@@ -35,5 +35,5 @@
 
 	@Override
-	public final void invokeLater(RunAt<? extends C> runnable) {
+	public final void dispatch(RunAt<? extends C> runnable) {
 		assert !(runnable instanceof Task);
 		SwingUtilities.invokeLater(runnable);
Index: /java/main/src/main/java/com/framsticks/gui/TreeNode.java
===================================================================
--- /java/main/src/main/java/com/framsticks/gui/TreeNode.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/gui/TreeNode.java	(revision 90)
@@ -62,5 +62,5 @@
 		iconName = TreeCellRenderer.findIconName(name, path.getTextual());
 		tooltip = "?";
-		path.getInstance().invokeLater(new RunAt<Instance>() {
+		path.getInstance().dispatch(new RunAt<Instance>() {
 			@Override
 			public void run() {
@@ -85,5 +85,5 @@
 		assert p.getInstance().isActive();
 		if (Logging.log(log, "fetch", TreeNode.this, e)) {
-			frame.invokeLater(new RunAt<Frame>() {
+			frame.dispatch(new RunAt<Frame>() {
 				@Override
 				public void run() {
@@ -95,5 +95,5 @@
 		}
 		updateChildren(p);
-		frame.invokeLater(new RunAt<Frame>() {
+		frame.dispatch(new RunAt<Frame>() {
 			@Override
 			public void run() {
@@ -107,5 +107,5 @@
 		assert !frame.isActive();
 		/** TODO those two actions could be merged into single closure */
-		frame.invokeLater(new RunAt<Frame>() {
+		frame.dispatch(new RunAt<Frame>() {
 			@Override
 			public void run() {
@@ -152,5 +152,5 @@
 		/**If some child were found, update in frame context.*/
 		if (childrenPaths.size() > 0) {
-			frame.invokeLater(new RunAt<Frame>() {
+			frame.dispatch(new RunAt<Frame>() {
 				@Override
 				public void run() {
@@ -189,5 +189,5 @@
 		final Path p = path;
 
-		p.getInstance().invokeLater(new RunAt<Instance>() {
+		p.getInstance().dispatch(new RunAt<Instance>() {
 			@Override
 			public void run() {
@@ -249,5 +249,5 @@
 		final String name = (nameParam != null ? access.get(nameParam, String.class) : path.getTop().getParam().getId());
 
-		frame.invokeLater(new RunAt<Frame>() {
+		frame.dispatch(new RunAt<Frame>() {
 			@Override
 			public void run() {
@@ -306,5 +306,5 @@
 		assert p.isResolved();
 		panel.setCurrentTreeNode(this);
-		p.getInstance().invokeLater(new RunAt<Instance>() {
+		p.getInstance().dispatch(new RunAt<Instance>() {
 			@Override
 			public void run() {
@@ -312,5 +312,5 @@
 				panel.pullValuesFromLocalToUser(access);
 
-				frame.invokeLater(new RunAt<Frame>() {
+				frame.dispatch(new RunAt<Frame>() {
 					@Override
 					public void run() {
@@ -344,5 +344,5 @@
 		final Path p = path;
 		log.debug("preparing panel: " + p);
-		p.getInstance().invokeLater(new RunAt<Instance>() {
+		p.getInstance().dispatch(new RunAt<Instance>() {
 			@Override
 			public void run() {
@@ -350,5 +350,5 @@
 				final CompositeParam param = p.getTop().getParam();
 				final FramsClass framsClass = p.getInstance().getInfoFromCache(param.getContainedTypeName());
-				frame.invokeLater(new RunAt<Frame>() {
+				frame.dispatch(new RunAt<Frame>() {
 					@Override
 					public void run() {
@@ -503,5 +503,5 @@
 		final Map<ValueControl, Object> changes = localChanges;
 		localChanges = null;
-		instanceAtFrame.getInstance().invokeLater(new RunAt<Instance>() {
+		instanceAtFrame.getInstance().dispatch(new RunAt<Instance>() {
 			@Override
 			public void run() {
@@ -517,5 +517,5 @@
 							}
 							log.debug("applied changes for: " + p);
-							frame.invokeLater(new RunAt<Frame>() {
+							frame.dispatch(new RunAt<Frame>() {
 								@Override
 								public void run() {
Index: /java/main/src/main/java/com/framsticks/gui/configuration/UserFavourite.java
===================================================================
--- /java/main/src/main/java/com/framsticks/gui/configuration/UserFavourite.java	(revision 90)
+++ /java/main/src/main/java/com/framsticks/gui/configuration/UserFavourite.java	(revision 90)
@@ -0,0 +1,68 @@
+package com.framsticks.gui.configuration;
+
+import com.framsticks.params.annotations.FramsClassAnnotation;
+import com.framsticks.params.annotations.ParamAnnotation;
+
+/**
+ * Class stores information about user favourite node or field.
+ */
+@FramsClassAnnotation
+public class UserFavourite {
+
+	/**
+	 * Name of node/field.
+	 */
+	protected String name;
+
+	/**
+	 * Path to node/field.
+	 */
+	protected String path;
+
+	/**
+	 * Field name - property getId or group name if node is group;
+	 */
+	protected String fieldId;
+
+	public UserFavourite() {
+	}
+
+	@ParamAnnotation
+	public String getPath() {
+		return path;
+	}
+
+	/**
+	 * @param path the path to set
+	 */
+	@ParamAnnotation
+	public void setPath(String path) {
+		this.path = path;
+	}
+
+	/**
+	 * @param fieldId the fieldId to set
+	 */
+	@ParamAnnotation
+	public void setFieldId(String fieldId) {
+		this.fieldId = fieldId;
+	}
+
+	@ParamAnnotation
+	public String getName() {
+		return name;
+	}
+
+	/**
+	 * @param name the name to set
+	 */
+	@ParamAnnotation
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	@ParamAnnotation
+	public String getFieldId() {
+		return fieldId;
+	}
+}
Index: /java/main/src/main/java/com/framsticks/gui/controls/Control.java
===================================================================
--- /java/main/src/main/java/com/framsticks/gui/controls/Control.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/gui/controls/Control.java	(revision 90)
@@ -22,7 +22,9 @@
 	protected Frame frame;
 	protected final Param param;
+	protected ControlOwner owner;
 
 	public Control(Param param) {
 		this.param = param;
+		setName(param.getId());
 
 		this.setEnabled(!param.hasFlag(Flags.READONLY));
@@ -38,4 +40,8 @@
 	}
 
+	public void setOwner(ControlOwner owner) {
+		this.owner = owner;
+	}
+
 	protected void addAsOnlyChild(JComponent component) {
 		this.setLayout(new BorderLayout());
Index: /java/main/src/main/java/com/framsticks/gui/controls/ControlOwner.java
===================================================================
--- /java/main/src/main/java/com/framsticks/gui/controls/ControlOwner.java	(revision 90)
+++ /java/main/src/main/java/com/framsticks/gui/controls/ControlOwner.java	(revision 90)
@@ -0,0 +1,12 @@
+package com.framsticks.gui.controls;
+
+import javax.swing.JPanel;
+
+import com.framsticks.gui.TreeNode;
+
+public interface ControlOwner {
+
+	public JPanel getPanel();
+	public TreeNode getCurrentTreeNode();
+
+}
Index: /java/main/src/main/java/com/framsticks/gui/controls/ProcedureControl.java
===================================================================
--- /java/main/src/main/java/com/framsticks/gui/controls/ProcedureControl.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/gui/controls/ProcedureControl.java	(revision 90)
@@ -1,22 +1,35 @@
 package com.framsticks.gui.controls;
 
+import com.framsticks.core.Instance;
+import com.framsticks.core.Path;
 import com.framsticks.gui.Gui;
+import com.framsticks.gui.TreeNode;
 import com.framsticks.params.Param;
+import com.framsticks.params.ValueParam;
 import com.framsticks.params.types.ProcedureParam;
+import com.framsticks.util.Logging;
+import com.framsticks.util.StateFunctor;
+import com.framsticks.util.dispatching.RunAt;
 
 import javax.swing.*;
 import javax.swing.border.BevelBorder;
+
+import org.apache.log4j.Logger;
+
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
 import java.util.Map;
 
 @SuppressWarnings("serial")
-public class ProcedureControl extends Control {
-	// private static final Logger log = Logger.getLogger(Control.class.getName());
+public class ProcedureControl extends Control implements ControlOwner {
+
+	private static final Logger log = Logger.getLogger(ProcedureControl.class);
 
 	protected final JButton procedureButton;
 
-	final protected Map<Param, Control> components = new HashMap<Param, Control>();
+	final protected Map<ValueParam, ValueControl> components = new HashMap<>();
 
 	public ProcedureControl(ProcedureParam procedureParam) {
@@ -24,8 +37,9 @@
 
 		procedureButton = new JButton("Call");
+		procedureButton.setName("call");
 
 		this.setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
 
-		Gui.fillWithControls(this, procedureParam.getArgumentsType(), components);
+		Gui.fillWithControls(this, procedureParam.getArgumentsType(), components, ValueControl.class);
 
 		if (components.size() != procedureParam.getArgumentsType().size()) {
@@ -39,22 +53,26 @@
 			@Override
 			public void actionPerformed(ActionEvent e) {
+				TreeNode treeNode = owner.getCurrentTreeNode();
+				assert treeNode != null;
 
-/*
-				Node node = panel.getCurrentNode();
-				if (argumentWindow != null) {
-					argumentWindow.askForArguments();
-					return;
+				log.debug("calling " + getParam() + " on " + treeNode);
+				final Path path = treeNode.getInstancePath();
+
+				final List<Object> arguments = new LinkedList<Object>();
+				for (Param arg : getParam().getArgumentsType()) {
+					arguments.add(((ValueControl) components.get(arg)).getCurrentValue());
 				}
-				node.getConnection().send(new CallQuery().setMethod(param.getId()).setPath(node.getPath()).setCallback(new QueryCallback() {
+
+				path.getInstance().dispatch(new RunAt<Instance>() {
 					@Override
-					public void call(boolean ok, String comment, SourceInterface content) {
-						if (!ok) {
-							log.error("failed to call method: " + param);
-							return;
-						}
-						log.debug("successful call of method: " + param);
+					public void run() {
+						path.getInstance().call(path, getParam(), arguments.toArray(), new StateFunctor() {
+							@Override
+							public void call(Exception e) {
+								Logging.log(log, "call procedure", path, e);
+							}
+						});
 					}
-				}));
-*/
+				});
 			}
 		});
@@ -63,3 +81,18 @@
 	}
 
+	@Override
+	public JPanel getPanel() {
+		return this;
+	}
+
+	@Override
+	public TreeNode getCurrentTreeNode() {
+		return owner.getCurrentTreeNode();
+	}
+
+	@Override
+	public ProcedureParam getParam() {
+		return (ProcedureParam) param;
+	}
+
 }
Index: /java/main/src/main/java/com/framsticks/gui/controls/TextFieldControl.java
===================================================================
--- /java/main/src/main/java/com/framsticks/gui/controls/TextFieldControl.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/gui/controls/TextFieldControl.java	(revision 90)
@@ -26,4 +26,5 @@
 		super(valueParam);
 		textField = new JTextField();
+		textField.setName("value");
 
 		textField.setMinimumSize(new Dimension(0, Control.LINE_HEIGHT));
Index: /java/main/src/main/java/com/framsticks/gui/controls/ValueControl.java
===================================================================
--- /java/main/src/main/java/com/framsticks/gui/controls/ValueControl.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/gui/controls/ValueControl.java	(revision 90)
@@ -78,4 +78,11 @@
 	}
 
+	/** This method is meant as a public interface to obtain current and correct value from control.
+	 *
+	 */
+	public final Object getCurrentValue() {
+		return filterValueThroughConstraints(pullValueFromUserInterface());
+	}
+
 	protected boolean notifyOfChange() {
 		if (!programmaticChange) {
@@ -83,5 +90,5 @@
 				return true;
 			}
-			return listener.onChange(filterValueThroughConstraints(pullValueFromUserInterface()));
+			return listener.onChange(getCurrentValue());
 		}
 		return true;
Index: /java/main/src/main/java/com/framsticks/gui/view/TreeCellRenderer.java
===================================================================
--- /java/main/src/main/java/com/framsticks/gui/view/TreeCellRenderer.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/gui/view/TreeCellRenderer.java	(revision 90)
@@ -97,4 +97,7 @@
 			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;
@@ -113,4 +116,7 @@
 		}
 		if (path.matches("^.*neurodefs/[0-9]+$")) {
+			return ImageProvider.NEURON_DEF;
+		}
+		if (path.matches("^.*neuroconns/[0-9]+$")) {
 			return ImageProvider.NEURON_DEF;
 		}
@@ -139,5 +145,5 @@
 			return ImageProvider.EVENT;
 		}
-		return ImageProvider.SERVER;
+		return ImageProvider.SIMULATOR;
 	}
 
Index: /java/main/src/main/java/com/framsticks/hosting/InstanceClient.java
===================================================================
--- /java/main/src/main/java/com/framsticks/hosting/InstanceClient.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/hosting/InstanceClient.java	(revision 90)
@@ -43,5 +43,5 @@
 	@Override
 	public void handle(final ApplicationRequest request, final ResponseCallback<?> responseCallback) {
-		instance.invokeLater(new RunAt<Instance>() {
+		instance.dispatch(new RunAt<Instance>() {
 			@Override
 			public void run() {
Index: /java/main/src/main/java/com/framsticks/hosting/ServerInstance.java
===================================================================
--- /java/main/src/main/java/com/framsticks/hosting/ServerInstance.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/hosting/ServerInstance.java	(revision 90)
@@ -16,5 +16,5 @@
  * @author Piotr Sniegowski
  */
-public class ServerInstance extends LocalInstance implements JoinableParent {
+public abstract class ServerInstance extends LocalInstance implements JoinableParent {
 
 	private final static Logger log = Logger.getLogger(ServerInstance.class.getName());
@@ -23,11 +23,4 @@
 
 	public ServerInstance() {
-	}
-
-	@Override
-	protected void firstTask() {
-		super.firstTask();
-		assert hosted != null;
-		Dispatching.use(hosted, this);
 	}
 
@@ -53,5 +46,5 @@
 			return null;
 		}
-		FramsClass cached = registry.getInfoFromCache(id);
+		FramsClass cached = registry.getFramsClass(id);
 		if (cached != null) {
 			return cached;
@@ -67,5 +60,5 @@
 
 			registry.registerReflectedClass(null, id, nativeClass);
-			registry.putInfoIntoCache(framsClass);
+			registry.putFramsClass(framsClass);
 			return framsClass;
 		} catch (ClassNotFoundException ignored) {
@@ -98,15 +91,23 @@
 	public void childChangedState(Joinable joinable, JoinableState state) {
 		proceedToState(state);
+	}
 
+	@Override
+	protected void joinableStart() {
+		super.joinableStart();
+		assert hosted != null;
+		Dispatching.use(hosted, this);
 	}
 
 	@Override
 	protected void joinableInterrupt() {
+		super.joinableInterrupt();
 		Dispatching.drop(hosted, this);
 	}
 
 	@Override
-	protected void joinableFinish() {
-
+	protected void joinableJoin() throws InterruptedException {
+		Dispatching.join(hosted);
+		super.joinableJoin();
 	}
 
Index: /java/main/src/main/java/com/framsticks/model/BasePart.java
===================================================================
--- /java/main/src/main/java/com/framsticks/model/BasePart.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/model/BasePart.java	(revision 90)
@@ -16,6 +16,6 @@
 	public void setPosition(Point3d p) { x = p.x; y = p.y; z = p.z; }
 
-	@ParamAnnotation(id = "m")
-	public double mass = 0.0;
+	@ParamAnnotation(id = "m", stringType = "f 0.1 999.0 1.0")
+	public double mass = 1.0;
 
 	@ParamAnnotation(id = "s")
Index: /java/main/src/main/java/com/framsticks/model/Creature.java
===================================================================
--- /java/main/src/main/java/com/framsticks/model/Creature.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/model/Creature.java	(revision 90)
@@ -154,9 +154,9 @@
 	public final List<Joint> joints = new ArrayList<Joint>();
 	@ParamAnnotation
-	public final List<NeuroDef> neurodefs = new ArrayList<NeuroDef>();
+	public final List<NeuroDefinition> neurodefs = new ArrayList<NeuroDefinition>();
 
 	public final List<Part> getParts() { return parts; }
 	public final List<Joint> getJoints() { return joints; }
-	public final List<NeuroDef> getNeuroDefs() { return neurodefs; }
+	public final List<NeuroDefinition> getNeuroDefs() { return neurodefs; }
 
 	@ParamAnnotation
Index: /java/main/src/main/java/com/framsticks/model/Joint.java
===================================================================
--- /java/main/src/main/java/com/framsticks/model/Joint.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/model/Joint.java	(revision 90)
@@ -10,5 +10,5 @@
  */
 @FramsClassAnnotation(id = "j")
-public class Joint extends BaseJoint {
+public class Joint extends BaseJoint implements ModelComponent {
 
 	@ParamAnnotation(id = "i")
Index: /java/main/src/main/java/com/framsticks/model/Model.java
===================================================================
--- /java/main/src/main/java/com/framsticks/model/Model.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/model/Model.java	(revision 90)
@@ -3,12 +3,7 @@
 import com.framsticks.params.annotations.FramsClassAnnotation;
 import com.framsticks.params.annotations.ParamAnnotation;
-import com.framsticks.util.lang.Casting;
 import com.framsticks.util.lang.Containers;
-import com.framsticks.util.lang.IterableIterator;
-import com.framsticks.util.math.Orientation;
-import org.apache.log4j.Logger;
 
 import java.util.ArrayList;
-import java.util.Iterator;
 import java.util.List;
 
@@ -17,7 +12,5 @@
  */
 @FramsClassAnnotation(id = "m")
-public class Model {
-
-	private final static Logger log = Logger.getLogger(Model.class);
+public class Model implements ModelComponent {
 
 	@ParamAnnotation(id = "se")
@@ -39,6 +32,9 @@
 	public final List<Joint> joints = new ArrayList<Joint>();
 
-	@ParamAnnotation
-	public final List<NeuroDef> neurodefs = new ArrayList<NeuroDef>();
+	@ParamAnnotation(id = "neurodefs")
+	public final List<NeuroDefinition> neuroDefinitions = new ArrayList<NeuroDefinition>();
+
+	@ParamAnnotation(id = "neuroconns")
+	public final List<NeuroConnection> neuroConnections = new ArrayList<NeuroConnection>();
 
 	//TODO: why those methods returns and accepts doubles?
@@ -48,5 +44,5 @@
 	public double getNumjoints() { return (double)joints.size(); }
 	@ParamAnnotation
-	public double getNumneurons() { return (double)neurodefs.size(); }
+	public double getNumneurons() { return (double)neuroDefinitions.size(); }
 
 	//this is impossible to use, because numparts field is marked as readonly
@@ -56,49 +52,10 @@
 	public void setNumjoints(double numjoints) { Containers.resizeList(joints, (int)(double)numjoints); }
 	@ParamAnnotation
-	public void setNumneurons(double numneurons) { Containers.resizeList(neurodefs, (int)(double)numneurons); }
+	public void setNumneurons(double numneurons) { Containers.resizeList(neuroDefinitions, (int)(double)numneurons); }
 
 	public List<Part> getParts() { return parts; }
 	public List<Joint> getJoints() { return joints; }
-	public List<NeuroDef> getNeuroDefs() { return neurodefs; }
+	public List<NeuroDefinition> getNeuroDefinitions() { return neuroDefinitions; }
+	public List<NeuroConnection> getNeuroConnections() { return neuroConnections; }
 
-	public static Model build(List<Object> objects) {
-		Iterator<Object> i = objects.iterator();
-		if (!i.hasNext()) {
-			return null;
-		}
-		Model f0Genotype = Casting.tryCast(Model.class, i.next());
-		if (f0Genotype == null) {
-			log.fatal("first object is not a Model");
-			return null;
-		}
-		for (Object object : new IterableIterator<Object>(i)) {
-			if (object instanceof Joint) {
-				f0Genotype.joints.add((Joint)object);
-				continue;
-			}
-			if (object instanceof Part) {
-				f0Genotype.parts.add((Part)object);
-				continue;
-			}
-			if (object instanceof NeuroDef) {
-				f0Genotype.neurodefs.add((NeuroDef) object);
-				continue;
-			}
-			log.error("invalid class: " + object.getClass().getCanonicalName());
-		}
-
-		for (Part p : f0Genotype.getParts()) {
-			p.setOrientation(new Orientation().rotate(p.getRotation()));
-		}
-		for (Joint j : f0Genotype.getJoints()) {
-			/** based on c++ Joint::attachToParts*/
-			Part p1 = f0Genotype.parts.get(j.part1);
-			Part p2 = f0Genotype.parts.get(j.part2);
-			assert p1 != null && p2 != null;
-			Orientation o = new Orientation().rotate(j.getRotation());
-			p2.setOrientation(p1.getOrientation().transform(o));
-			p2.setPosition(p2.getOrientation().transform(j.getDelta()).add(p1.getPosition()));
-		}
-		return f0Genotype;
-	}
 }
Index: /java/main/src/main/java/com/framsticks/model/ModelBuilder.java
===================================================================
--- /java/main/src/main/java/com/framsticks/model/ModelBuilder.java	(revision 90)
+++ /java/main/src/main/java/com/framsticks/model/ModelBuilder.java	(revision 90)
@@ -0,0 +1,121 @@
+package com.framsticks.model;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+import com.framsticks.model.f0.Schema;
+import com.framsticks.params.Util;
+import com.framsticks.params.annotations.AutoAppendAnnotation;
+import com.framsticks.params.annotations.FramsClassAnnotation;
+// import com.framsticks.params.annotations.ParamAnnotation;
+import com.framsticks.parsers.F0Parser;
+import com.framsticks.util.AutoBuilder;
+import com.framsticks.util.FramsticksException;
+import com.framsticks.util.ResourceBuilder;
+import com.framsticks.util.lang.Casting;
+import com.framsticks.util.lang.IterableIterator;
+import com.framsticks.util.math.Orientation;
+
+@FramsClassAnnotation
+public class ModelBuilder extends ResourceBuilder<Model> implements AutoBuilder {
+
+	Schema schema;
+	final List<ModelComponent> components = new ArrayList<>();
+
+	@Override
+	public Model finish() {
+		if (stream == null && components.isEmpty()) {
+			throw new FramsticksException().msg("model builder instance not ready");
+		}
+		if (stream != null) {
+			if (schema == null) {
+				schema = Schema.getDefaultSchema();
+			}
+			F0Parser parser = new F0Parser(schema, stream);
+			components.addAll(Util.stripAccessInterface(parser.parse(), ModelComponent.class));
+		}
+		return build();
+	}
+
+	/**
+	 * @return the schema
+	 */
+	public Schema getSchema() {
+		return schema;
+	}
+
+	/**
+	 * @param schema the schema to set
+	 */
+	@AutoAppendAnnotation
+	public ModelBuilder schema(Schema schema) {
+		this.schema = schema;
+		return this;
+	}
+
+	@AutoAppendAnnotation
+	public ModelBuilder addComponent(ModelComponent component) {
+		components.add(component);
+		return this;
+	}
+
+	@AutoAppendAnnotation
+	public ModelBuilder addComponents(List<ModelComponent> component) {
+		this.components.addAll(component);
+		return this;
+	}
+
+	public Model build() {
+		Iterator<ModelComponent> i = components.iterator();
+		if (!i.hasNext()) {
+			throw new FramsticksException().msg("empty components list");
+		}
+		Model f0Genotype = Casting.tryCast(Model.class, i.next());
+		if (f0Genotype == null) {
+			throw new FramsticksException().msg("first component is not a Model");
+		}
+		for (ModelComponent component : new IterableIterator<ModelComponent>(i)) {
+			if (component instanceof Joint) {
+				f0Genotype.joints.add((Joint)component);
+				continue;
+			}
+			if (component instanceof Part) {
+				f0Genotype.parts.add((Part)component);
+				continue;
+			}
+			if (component instanceof NeuroDefinition) {
+				f0Genotype.neuroDefinitions.add((NeuroDefinition) component);
+				continue;
+			}
+			if (component instanceof NeuroConnection) {
+				f0Genotype.neuroConnections.add((NeuroConnection) component);
+				continue;
+			}
+			throw new FramsticksException().msg("invalid class").arg("class", component.getClass().getCanonicalName());
+		}
+
+		for (Part p : f0Genotype.getParts()) {
+			p.setOrientation(new Orientation().rotate(p.getRotation()));
+		}
+		for (Joint j : f0Genotype.getJoints()) {
+			/** based on c++ Joint::attachToParts*/
+			Part p1 = f0Genotype.parts.get(j.part1);
+			Part p2 = f0Genotype.parts.get(j.part2);
+			assert p1 != null && p2 != null;
+			Orientation o = new Orientation().rotate(j.getRotation());
+			p2.setOrientation(p1.getOrientation().transform(o));
+			p2.setPosition(p2.getOrientation().transform(j.getDelta()).add(p1.getPosition()));
+		}
+		return f0Genotype;
+	}
+
+	@Override
+	public List<Object> autoFinish() {
+		Model model = finish();
+		assert schema != null;
+		return Arrays.asList(schema.getRegistry(), model);
+	}
+
+}
Index: /java/main/src/main/java/com/framsticks/model/ModelComponent.java
===================================================================
--- /java/main/src/main/java/com/framsticks/model/ModelComponent.java	(revision 90)
+++ /java/main/src/main/java/com/framsticks/model/ModelComponent.java	(revision 90)
@@ -0,0 +1,5 @@
+package com.framsticks.model;
+
+public interface ModelComponent {
+
+}
Index: /java/main/src/main/java/com/framsticks/model/ModelPackage.java
===================================================================
--- /java/main/src/main/java/com/framsticks/model/ModelPackage.java	(revision 90)
+++ /java/main/src/main/java/com/framsticks/model/ModelPackage.java	(revision 90)
@@ -0,0 +1,27 @@
+package com.framsticks.model;
+
+import com.framsticks.params.ParamsPackage;
+import com.framsticks.params.Registry;
+import com.framsticks.params.annotations.FramsClassAnnotation;
+
+/**
+ * Author: Piotr Śniegowski
+ */
+@FramsClassAnnotation
+public class ModelPackage extends ParamsPackage {
+	@Override
+	public void register(Registry registry) {
+		register(registry, MechPart.class);
+		register(registry, MechPart.class);
+		register(registry, Joint.class);
+		register(registry, MechJoint.class);
+		register(registry, Neuro.class);
+		register(registry, NeuroDefinition.class);
+		register(registry, NeuroConnection.class);
+		register(registry, Part.class);
+		register(registry, Model.class);
+		register(registry, Creature.class);
+		register(registry, Genotype.class);
+		register(registry, World.class);
+	}
+}
Index: /java/main/src/main/java/com/framsticks/model/NeuroConnection.java
===================================================================
--- /java/main/src/main/java/com/framsticks/model/NeuroConnection.java	(revision 90)
+++ /java/main/src/main/java/com/framsticks/model/NeuroConnection.java	(revision 90)
@@ -0,0 +1,27 @@
+package com.framsticks.model;
+
+import com.framsticks.params.annotations.FramsClassAnnotation;
+import com.framsticks.params.annotations.ParamAnnotation;
+
+/**
+ * The Class NeuroConnection.
+ */
+@FramsClassAnnotation(id = "c", name = "NeuroConn")
+public class NeuroConnection implements ModelComponent {
+
+	@ParamAnnotation(id = "n1")
+	public int thisNeuro;
+
+	@ParamAnnotation(id = "n2")
+	public int connectedNeuro;
+
+	@ParamAnnotation(id = "w")
+	public double weight;
+
+	@ParamAnnotation(id = "i")
+	public String info;
+
+	@ParamAnnotation(id = "Vstyle")
+	public String visualizationStyle;
+
+}
Index: va/main/src/main/java/com/framsticks/model/NeuroDef.java
===================================================================
--- /java/main/src/main/java/com/framsticks/model/NeuroDef.java	(revision 89)
+++ 	(revision )
@@ -1,27 +1,0 @@
-package com.framsticks.model;
-
-import com.framsticks.params.annotations.FramsClassAnnotation;
-import com.framsticks.params.annotations.ParamAnnotation;
-
-/**
- * @author Piotr Sniegowski
- */
-@FramsClassAnnotation(id = "n")
-public class NeuroDef extends BaseNeuro {
-
-	@ParamAnnotation(id = "p")
-	public int part;
-
-	@ParamAnnotation(id = "j")
-	public int joint;
-
-	@ParamAnnotation(id = "d")
-	public String details;
-
-	@ParamAnnotation(id = "i")
-	public String info;
-
-	@ParamAnnotation(id = "Vstyle")
-	public String visualizationStyle;
-
-}
Index: /java/main/src/main/java/com/framsticks/model/NeuroDefinition.java
===================================================================
--- /java/main/src/main/java/com/framsticks/model/NeuroDefinition.java	(revision 90)
+++ /java/main/src/main/java/com/framsticks/model/NeuroDefinition.java	(revision 90)
@@ -0,0 +1,27 @@
+package com.framsticks.model;
+
+import com.framsticks.params.annotations.FramsClassAnnotation;
+import com.framsticks.params.annotations.ParamAnnotation;
+
+/**
+ * @author Piotr Sniegowski
+ */
+@FramsClassAnnotation(id = "n", name = "NeuroDef")
+public class NeuroDefinition extends BaseNeuro implements ModelComponent {
+
+	@ParamAnnotation(id = "p")
+	public int part;
+
+	@ParamAnnotation(id = "j")
+	public int joint;
+
+	@ParamAnnotation(id = "d")
+	public String details;
+
+	@ParamAnnotation(id = "i")
+	public String info;
+
+	@ParamAnnotation(id = "Vstyle")
+	public String visualizationStyle;
+
+}
Index: va/main/src/main/java/com/framsticks/model/Package.java
===================================================================
--- /java/main/src/main/java/com/framsticks/model/Package.java	(revision 89)
+++ 	(revision )
@@ -1,22 +1,0 @@
-package com.framsticks.model;
-
-import com.framsticks.params.Registry;
-
-/**
- * Author: Piotr Śniegowski
- */
-public class Package {
-	public static void register(Registry registry) {
-		registry
-			.register(MechPart.class)
-			.register(Joint.class)
-			.register(MechJoint.class)
-			.register(Neuro.class)
-			.register(NeuroDef.class)
-			.register(Part.class)
-			.register(Model.class)
-			.register(Creature.class)
-			.register(Genotype.class)
-			.register(World.class);
-	}
-}
Index: /java/main/src/main/java/com/framsticks/model/Part.java
===================================================================
--- /java/main/src/main/java/com/framsticks/model/Part.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/model/Part.java	(revision 90)
@@ -10,5 +10,5 @@
  */
 @FramsClassAnnotation(id = "p")
-public class Part extends BasePart {
+public class Part extends BasePart implements ModelComponent {
 
 	@ParamAnnotation
Index: va/main/src/main/java/com/framsticks/model/f0/NeuroConnection.java
===================================================================
--- /java/main/src/main/java/com/framsticks/model/f0/NeuroConnection.java	(revision 89)
+++ 	(revision )
@@ -1,27 +1,0 @@
-package com.framsticks.model.f0;
-
-import com.framsticks.params.annotations.FramsClassAnnotation;
-import com.framsticks.params.annotations.ParamAnnotation;
-
-/**
- * The Class NeuroConnection.
- */
-@FramsClassAnnotation
-public class NeuroConnection {
-
-	@ParamAnnotation(id = "n1")
-	public Integer thisNeuro;
-
-	@ParamAnnotation(id = "n2")
-	public Integer connectedNeuro;
-
-	@ParamAnnotation(id = "w")
-	public Double weight;
-
-	@ParamAnnotation(id = "i")
-	public String info;
-
-	@ParamAnnotation(id = "Vstyle")
-	public String visStyle;
-
-}
Index: /java/main/src/main/java/com/framsticks/model/f0/Schema.java
===================================================================
--- /java/main/src/main/java/com/framsticks/model/f0/Schema.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/model/f0/Schema.java	(revision 90)
@@ -7,9 +7,7 @@
 import com.framsticks.params.annotations.AutoAppendAnnotation;
 import com.framsticks.params.annotations.FramsClassAnnotation;
-import com.framsticks.parsers.XmlLoader;
-import com.framsticks.util.DoubleMap;
-import com.framsticks.util.FramsticksException;
+import com.framsticks.params.annotations.ParamAnnotation;
+import com.framsticks.util.lang.Casting;
 
-import com.framsticks.model.Package;
 
 /**
@@ -27,6 +25,8 @@
 
 	/** The neuro classes (classess representing different types of neurons). */
-	private DoubleMap<String, FramsClass> framsClasses = new DoubleMap<>();
-	private DoubleMap<String, NeuroClass> neuroClasses = new DoubleMap<>();
+	private final Registry framsClasses = new Registry();
+	private final Registry neuroClasses = new Registry();
+	// private DoubleMap<String, FramsClass> framsClasses = new DoubleMap<>();
+	// private DoubleMap<String, NeuroClass> neuroClasses = new DoubleMap<>();
 
 	public static InputStream getDefaultDefinitionAsStream() {
@@ -35,24 +35,11 @@
 	}
 
-	public static Schema load(InputStream stream) {
+	protected static Schema defaultSchema;
 
-		XmlLoader xmlLoader = new XmlLoader();
-		xmlLoader.setUseLowerCase(true);
-		xmlLoader.getRegistry()
-			.registerAndBuild(Schema.class)
-			.registerAndBuild(FramsClassBuilder.class)
-			.registerAndBuild(NeuroClassBuilder.class)
-			.registerAndBuild(ParamBuilder.class)
-			.registerAndBuild(NeuroParamBuilder.class)
-			.registerAndBuild(GroupBuilder.class)
-			;
-
-		Package.register(xmlLoader.getRegistry());
-
-		Object object = xmlLoader.load(Schema.getDefaultDefinitionAsStream());
-		if (!(object instanceof Schema)) {
-			throw new FramsticksException().msg("failed to load schema");
+	public synchronized static Schema getDefaultSchema() {
+		if (defaultSchema == null) {
+			defaultSchema = new SchemaBuilder().stream(getDefaultDefinitionAsStream()).finish();
 		}
-		return (Schema) object;
+		return defaultSchema;
 	}
 
@@ -60,11 +47,12 @@
 	}
 
+	@AutoAppendAnnotation
 	public void addClass(FramsClass framsClass) {
-		registry.putInfoIntoCache(framsClass);
+		registry.putFramsClass(framsClass);
 		if (framsClass instanceof NeuroClass) {
-			neuroClasses.put(framsClass.getId(), framsClass.getName(), (NeuroClass) framsClass);
+			neuroClasses.putFramsClass(framsClass);
 			return;
 		}
-		framsClasses.put(framsClass.getId(), framsClass.getName(), framsClass);
+		framsClasses.putFramsClass(framsClass);
 	}
 
@@ -74,23 +62,35 @@
 	}
 
-	public Set<NeuroClass> getNeuroClasses() {
-		return neuroClasses.getValues();
+	public Set<FramsClass> getNeuroClasses() {
+		return neuroClasses.getFramsClasses();
 	}
 
 	public Set<FramsClass> getFramsClasses() {
-		return framsClasses.getValues();
+		return framsClasses.getFramsClasses();
 	}
 
 	public NeuroClass getNeuroClass(String identifier) {
-		return neuroClasses.get(identifier);
+		return Casting.throwCast(NeuroClass.class, neuroClasses.getFramsClass(identifier));
 	}
 
 	public FramsClass getFramsClass(String identifier) {
-		return framsClasses.get(identifier);
+		return framsClasses.getFramsClass(identifier);
 	}
 
+	@ParamAnnotation
 	public final Registry getRegistry() {
 		return registry;
 	}
 
+	@ParamAnnotation
+	public final Registry getFramsRegistry() {
+		return framsClasses;
+	}
+
+	@ParamAnnotation
+	public final Registry getNeurosRegistry() {
+		return neuroClasses;
+	}
+
+
 }
Index: /java/main/src/main/java/com/framsticks/model/f0/SchemaBuilder.java
===================================================================
--- /java/main/src/main/java/com/framsticks/model/f0/SchemaBuilder.java	(revision 90)
+++ /java/main/src/main/java/com/framsticks/model/f0/SchemaBuilder.java	(revision 90)
@@ -0,0 +1,49 @@
+package com.framsticks.model.f0;
+
+import java.util.Arrays;
+import java.util.List;
+
+import com.framsticks.model.ModelPackage;
+import com.framsticks.params.FramsClassBuilder;
+import com.framsticks.params.GroupBuilder;
+import com.framsticks.params.ParamBuilder;
+import com.framsticks.params.annotations.FramsClassAnnotation;
+import com.framsticks.parsers.XmlLoader;
+import com.framsticks.util.AutoBuilder;
+import com.framsticks.util.ResourceBuilder;
+
+@FramsClassAnnotation
+public class SchemaBuilder extends ResourceBuilder<Schema> implements AutoBuilder {
+
+	@Override
+	public Schema finish() {
+
+		if (stream == null) {
+			stream(Schema.getDefaultDefinitionAsStream());
+		}
+
+		XmlLoader xmlLoader = new XmlLoader();
+		xmlLoader.setUseLowerCase(true);
+		xmlLoader.getRegistry()
+			.registerAndBuild(Schema.class)
+			.registerAndBuild(FramsClassBuilder.class)
+			.registerAndBuild(NeuroClassBuilder.class)
+			.registerAndBuild(ParamBuilder.class)
+			.registerAndBuild(NeuroParamBuilder.class)
+			.registerAndBuild(GroupBuilder.class)
+			;
+
+		new ModelPackage().register(xmlLoader.getRegistry());
+
+		Schema schema = xmlLoader.load(Schema.class, stream);
+		new ModelPackage().register(schema.getRegistry());
+		return schema;
+	}
+
+	@Override
+	public List<Object> autoFinish() {
+		Schema result = finish();
+		return Arrays.asList((Object) result);
+	}
+
+}
Index: /java/main/src/main/java/com/framsticks/params/AccessInterface.java
===================================================================
--- /java/main/src/main/java/com/framsticks/params/AccessInterface.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/params/AccessInterface.java	(revision 90)
@@ -2,4 +2,6 @@
 
 import java.util.Collection;
+
+import com.framsticks.params.types.ProcedureParam;
 
 
@@ -20,10 +22,9 @@
 	String getId();
 
-	Param getGroupMember(int gi, int n);
-
 	int getParamCount();
 
-	// void call(int i, Object args, Object ret);
-	// TODO: as for now it's not necessary to implement this method
+	Object call(String id, Object[] arguments);
+
+	Object call(ProcedureParam param, Object[] arguments);
 
 	<T> T get(int i, Class<T> type);
Index: /java/main/src/main/java/com/framsticks/params/ArrayListAccess.java
===================================================================
--- /java/main/src/main/java/com/framsticks/params/ArrayListAccess.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/params/ArrayListAccess.java	(revision 90)
@@ -32,5 +32,5 @@
 	public Param getParam(int i) {
 		//TODO listAccessParam
-		return Param.build().id(Integer.toString(i)).name(elementAccess.getId()).type("o " + elementAccess.getId()).finish();
+		return Param.build().id(Integer.toString(i)).forAccess(elementAccess).finish();
 	}
 
Index: /java/main/src/main/java/com/framsticks/params/FramsClass.java
===================================================================
--- /java/main/src/main/java/com/framsticks/params/FramsClass.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/params/FramsClass.java	(revision 90)
@@ -4,4 +4,5 @@
 import com.framsticks.params.annotations.ParamAnnotation;
 import com.framsticks.util.FramsticksException;
+import com.framsticks.util.lang.Containers;
 // import com.framsticks.util.FramsticksException;
 
@@ -51,6 +52,7 @@
 	// protected Map<String, Integer> paramIdMap = new HashMap<String, Integer>();
 
-	public Collection<Param> getParamEntries() {
-		return paramList;
+	@ParamAnnotation(id = "props", name = "props")
+	public List<Param> getParamEntries() {
+		return Collections.unmodifiableList(paramList);
 	}
 
@@ -60,17 +62,9 @@
 		this.name = builder.getName();
 		this.description = builder.getDescription();
-		this.groups = builder.groups;
+		this.groups = Containers.build(builder.groupBuilders);
 		this.paramList = builder.params;
 
 		for (Param param : paramList) {
 			paramEntryMap.put(param.getId(), param);
-			try {
-				Group group = groups.get(param.getGroup());
-				if (group != null) {
-					group.addProperty(param);
-				}
-			} catch (IndexOutOfBoundsException ignored) {
-
-			}
 		}
 
@@ -88,33 +82,37 @@
 	}
 
-	/**
-	 * Gets the group member.
-	 *
-	 * @param gi
-	 *            the offset of group
-	 * @param pi
-	 *            the offset of member within a group
-	 * @return the pi-th member of group gi
-	 */
-	public Param getGroupMember(int gi, int pi) {
-		if (gi < 0 || pi < 0 || gi >= groups.size()) {
-			return null;
-		}
-		Group group = groups.get(gi);
-		return (group != null ? group.getProperty(pi) : null);
+	public Group getGroup(int groupNumber) {
+		return Containers.getFromList(groups, groupNumber, "group", this);
 	}
 
-	/**
-	 * Gets the group name.
-	 *
-	 * @param gi
-	 *            the offset of group
-	 * @return the group name
-	 */
-	public String getGroupName(int gi) {
-		if (gi < 0 || gi >= groups.size())
-			return null;
-		return groups.get(gi).name;
-	}
+	// /**
+	//  * Gets the group member.
+	//  *
+	//  * @param gi
+	//  *            the offset of group
+	//  * @param pi
+	//  *            the offset of member within a group
+	//  * @return the pi-th member of group gi
+	//  */
+	// public Param getGroupMember(int gi, int pi) {
+	// 	if (gi < 0 || pi < 0 || gi >= groups.size()) {
+	// 		return null;
+	// 	}
+	// 	Group group = groups.get(gi);
+	// 	return (group != null ? group.getProperty(pi) : null);
+	// }
+
+	// /**
+	//  * Gets the group name.
+	//  *
+	//  * @param gi
+	//  *            the offset of group
+	//  * @return the group name
+	//  */
+	// public String getGroupName(int gi) {
+	// 	if (gi < 0 || gi >= groups.size())
+	// 		return null;
+	// 	return groups.get(gi).name;
+	// }
 
 	@ParamAnnotation
Index: /java/main/src/main/java/com/framsticks/params/FramsClassBuilder.java
===================================================================
--- /java/main/src/main/java/com/framsticks/params/FramsClassBuilder.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/params/FramsClassBuilder.java	(revision 90)
@@ -22,5 +22,5 @@
 import com.framsticks.parsers.Loaders;
 import com.framsticks.util.Builder;
-import com.framsticks.util.FramsticksException;
+import com.framsticks.util.lang.Containers;
 import com.framsticks.util.lang.Strings;
 
@@ -38,5 +38,6 @@
 	}
 
-	public static String getParamTypeForNativeType(Type type) {
+	public static ParamBuilder induceParamType(ParamBuilder builder, Type type) {
+
 		if (type instanceof ParameterizedType) {
 			ParameterizedType p = (ParameterizedType) type;
@@ -52,5 +53,5 @@
 			}
 			if (!(containedType instanceof Class)) {
-				return null;
+				return builder;
 			}
 			Class<?> containedClass = (Class<?>) containedType;
@@ -60,5 +61,5 @@
 			if (fca == null) {
 				log.error("the class is not annotated: " + containedClass);
-				return null;
+				return builder;
 			}
 			b.append(getName(fca, containedClass));
@@ -67,5 +68,6 @@
 			}
 
-			return b.toString();
+			builder.type(b.toString());
+			return builder;
 		}
 
@@ -87,23 +89,50 @@
 			// }
 			if (cl.equals(Integer.class) || cl.equals(int.class)) {
-				return "d";
+				builder.type("d");
+				return builder;
 			}
 			if (cl.equals(String.class)) {
-				return "s";
+				builder.type("s");
+				return builder;
 			}
 			if (cl.equals(Double.class) || cl.equals(double.class)) {
-				return "f";
+				builder.type("f");
+				return builder;
 			}
 			if (cl.equals(Boolean.class) || cl.equals(boolean.class)) {
-				return "d 0 1";
+				builder.type( "d 0 1");
+				return builder;
 			}
 			if (cl.equals(Object.class)) {
-				return "x";
-			}
-
-			return "o " + ((Class<?>) type).getCanonicalName();
+				builder.type("x");
+				return builder;
+			}
+
+			// builder.type("o " + (cl).getCanonicalName());
+			builder.type("o " + cl.getSimpleName());
+			builder.fillStorageType(cl);
+			return builder;
 		}
 
 		throw new ConstructionException().msg("failed to find framsticks for native type").arg("type", type);
+	}
+
+
+	public static ParamBuilder induceParamType(ParamBuilder builder, ParamCandidate candidate) {
+		Method method = candidate.getCaller();
+		if (method == null) {
+			return induceParamType(builder, candidate.getType());
+		}
+
+		builder.resultType(induceParamType(Param.build(), method.getGenericReturnType()).finish(ValueParam.class));
+
+		List<ValueParam> arguments = new ArrayList<>();
+		int number = 0;
+		for (Type arg : method.getGenericParameterTypes()) {
+			arguments.add(induceParamType(Param.build(), arg).idAndName("arg" + (number++)).finish(ValueParam.class));
+		}
+		builder.argumentsType(arguments);
+
+		return builder;
 	}
 
@@ -183,12 +212,31 @@
 		name(getName(fca, javaClass));
 
-		Map<String, ParamCandidate> candidates = ParamCandidate.getAllCandidates(javaClass);
-
-		for (ParamCandidate pc : candidates.values()) {
-			String type = getParamTypeForNativeType(pc.getType());
-			if (type == null) {
-				throw new FramsticksException().msg("failed to find type for param candidate").arg("candidate", pc);
-			}
-			param(Param.build().id(pc.getId()).name(pc.getName()).type(type).flags(pc.getFlags()));
+		for (ParamCandidate pc : ParamCandidate.getAllCandidates(javaClass).getOrder()) {
+			ParamBuilder builder = Param.build().id(pc.getId()).name(pc.getName()).flags(pc.getFlags());
+
+			induceParamType(builder, pc);
+
+			for (ParamAnnotation pa : pc.getAnnotations()) {
+				if (!"".equals(pa.def())) {
+					builder.def(pa.def());
+				}
+				if (!"".equals(pa.help())) {
+					builder.help(pa.help());
+				}
+				if (!"".equals(pa.min())) {
+					builder.min(pa.min());
+				}
+				if (!"".equals(pa.max())) {
+					builder.max(pa.max());
+				}
+				builder.extra(pa.extra());
+				if (!"".equals(pa.stringType())) {
+					builder.type(pa.stringType());
+				}
+				if (!pa.paramType().equals(Param.class)) {
+					builder.type(pa.paramType());
+				}
+			}
+			param(builder);
 		}
 
@@ -209,5 +257,5 @@
 	protected final List<Param> params = new LinkedList<>();
 
-	protected List<Group> groups = new ArrayList<Group>();
+	protected List<GroupBuilder> groupBuilders = new ArrayList<GroupBuilder>();
 
 	@ParamAnnotation
@@ -242,22 +290,20 @@
 	}
 
-	public FramsClassBuilder append(Param param) {
-		params.add(param);
-		return this;
-	}
-
 	@AutoAppendAnnotation
 	public FramsClassBuilder param(ParamBuilder builder) {
-		return append(builder.finish());
+		Param param = builder.finish();
+
+		Integer group = param.getGroup();
+		if (group != null) {
+			Containers.getFromList(groupBuilders, group, "group", this).addParam(param);
+		}
+
+		params.add(param);
+		return this;
 	}
 
 	@AutoAppendAnnotation
 	public FramsClassBuilder group(GroupBuilder builder) {
-		return group(builder.finish());
-	}
-
-	@AutoAppendAnnotation
-	public FramsClassBuilder group(Group group) {
-		groups.add(group);
+		groupBuilders.add(builder);
 		return this;
 	}
@@ -288,10 +334,7 @@
 
 	public FramsClassBuilder group(String group) {
-		return group(new Group(group));
-	}
-
-	public ParamBuilder param(String id) {
-		return new ParamBuilder(this).id(id);
-	}
+		return group(new GroupBuilder().name(group));
+	}
+
 
 }
Index: /java/main/src/main/java/com/framsticks/params/Group.java
===================================================================
--- /java/main/src/main/java/com/framsticks/params/Group.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/params/Group.java	(revision 90)
@@ -1,9 +1,11 @@
 package com.framsticks.params;
 
-import java.util.ArrayList;
 import java.util.List;
+
+import javax.annotation.concurrent.Immutable;
 
 import com.framsticks.params.annotations.FramsClassAnnotation;
 import com.framsticks.params.annotations.ParamAnnotation;
+import com.framsticks.util.lang.Containers;
 
 /**
@@ -11,25 +13,18 @@
  */
 @FramsClassAnnotation
+@Immutable
 public class Group {
 
 	@ParamAnnotation
-	protected String name;
+	protected final String name;
 
 	/**
 	 * Group members.
 	 */
-	List<Param> params = new ArrayList<Param>();
+	protected final List<Param> params;
 
-	public Group(String name) {
-		this.name = name;
-	}
-
-	/**
-	 * Adds new group member.
-	 *
-	 * @param p the new group member
-	 */
-	void addProperty(Param p) {
-		params.add(p);
+	public Group(GroupBuilder builder) {
+		this.name = builder.getName();
+		this.params = builder.getParams();
 	}
 
@@ -40,13 +35,11 @@
 	 * @return the property
 	 */
-	Param getProperty(int i) {
-		if (i < 0 || i >= params.size())
-			return null;
-		return params.get(i);
+	public Param getParam(int number) {
+		return Containers.getFromList(params, number, "param", this);
 	}
 
 	@Override
 	public String toString() {
-		return name;
+		return "group" + name;
 	}
 
@@ -59,3 +52,7 @@
 	}
 
+	public int getCount() {
+		return params.size();
+	}
+
 }
Index: /java/main/src/main/java/com/framsticks/params/GroupBuilder.java
===================================================================
--- /java/main/src/main/java/com/framsticks/params/GroupBuilder.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/params/GroupBuilder.java	(revision 90)
@@ -1,12 +1,18 @@
 package com.framsticks.params;
+
+import java.util.ArrayList;
+import java.util.List;
 
 import com.framsticks.params.annotations.FramsClassAnnotation;
 import com.framsticks.params.annotations.ParamAnnotation;
+import com.framsticks.util.Builder;
 
 @FramsClassAnnotation(id = "group", name = "group")
-public class GroupBuilder {
+public class GroupBuilder implements Builder<Group> {
 
 	@ParamAnnotation
 	protected String name;
+
+	protected final List<Param> params = new ArrayList<Param>();
 
 	public GroupBuilder() {
@@ -19,6 +25,24 @@
 	}
 
+	/**
+	 * @return the name
+	 */
+	public String getName() {
+		return name;
+	}
+
+	/**
+	 * @return the params
+	 */
+	public List<Param> getParams() {
+		return params;
+	}
+
 	public Group finish() {
-		return new Group(name);
+		return new Group(this);
+	}
+
+	public void addParam(Param param) {
+		params.add(param);
 	}
 
Index: /java/main/src/main/java/com/framsticks/params/InvalidOperationException.java
===================================================================
--- /java/main/src/main/java/com/framsticks/params/InvalidOperationException.java	(revision 90)
+++ /java/main/src/main/java/com/framsticks/params/InvalidOperationException.java	(revision 90)
@@ -0,0 +1,8 @@
+package com.framsticks.params;
+
+import com.framsticks.util.FramsticksException;
+
+@SuppressWarnings("serial")
+public class InvalidOperationException extends FramsticksException {
+
+}
Index: /java/main/src/main/java/com/framsticks/params/ListAccess.java
===================================================================
--- /java/main/src/main/java/com/framsticks/params/ListAccess.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/params/ListAccess.java	(revision 90)
@@ -4,4 +4,6 @@
 
 import static com.framsticks.util.lang.Containers.filterInstanceof;
+
+import com.framsticks.params.types.ProcedureParam;
 
 /**
@@ -16,8 +18,8 @@
 	}
 
-	@Override
-	public Param getGroupMember(int gi, int n) {
-		return null;
-	}
+	// @Override
+	// public Param getGroupMember(int gi, int n) {
+	//	return null;
+	// }
 
 	@Override
@@ -81,3 +83,13 @@
 	}
 
+	@Override
+	public Object call(String id, Object[] arguments) {
+		throw new InvalidOperationException().msg("list access does not support calling methods").arg("id", id);
+	}
+
+	@Override
+	public Object call(ProcedureParam param, Object[] arguments) {
+		throw new InvalidOperationException().msg("list access does not support calling methods").arg("param", param);
+	}
+
 };
Index: /java/main/src/main/java/com/framsticks/params/Param.java
===================================================================
--- /java/main/src/main/java/com/framsticks/params/Param.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/params/Param.java	(revision 90)
@@ -23,11 +23,4 @@
 	protected final String id;
 
-	//TODO
-	/**
-	 * The parameter internal id. It's set by a user to use user's own getId in
-	 * code
-	 */
-	protected final String internalId;
-
 	/** The parameter name. */
 	protected final String name;
@@ -48,5 +41,4 @@
 	public Param(ParamBuilder builder) {
 		id = builder.getId();
-		internalId = builder.getInternalId();
 		name = builder.getName();
 		help = builder.getHelp();
@@ -59,8 +51,4 @@
 	public String getId() {
 		return id;
-	}
-
-	public String getInternalId() {
-		return internalId;
 	}
 
@@ -87,10 +75,5 @@
 	public abstract String getFramsTypeName();
 
-
-	public String getEffectiveId() {
-		return (internalId != null) ? internalId : id;
-	}
-
-
+	@ParamAnnotation
 	public Integer getExtra() {
 		return extra;
Index: /java/main/src/main/java/com/framsticks/params/ParamBuilder.java
===================================================================
--- /java/main/src/main/java/com/framsticks/params/ParamBuilder.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/params/ParamBuilder.java	(revision 90)
@@ -11,6 +11,11 @@
 
 import java.lang.reflect.InvocationTargetException;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.annotation.Nonnull;
 
 /**
@@ -37,12 +42,6 @@
 	private String id;
 
-	/**
-	 * The parameter internal id. It's set by a user to use user's own id in
-	 * code
-	 */
-	private String internalId;
-
 	/** The number of group, that parameter belongs to. */
-	private Integer group = 0;
+	private Integer group;
 
 	/** The flags stored as a bit sum. */
@@ -76,4 +75,7 @@
 	}
 
+	protected ValueParam resultType;
+
+	protected List<ValueParam> argumentsType;
 
 	/**
@@ -114,4 +116,36 @@
 
 	/**
+	 * @return the resultType
+	 */
+	public ValueParam getResultType() {
+		return resultType;
+	}
+
+
+	/**
+	 * @param resultType the resultType to set
+	 */
+	public ParamBuilder resultType(ValueParam resultType) {
+		this.resultType = resultType;
+		return this;
+	}
+
+	/**
+	 * @return the argumentsType
+	 */
+	public List<ValueParam> getArgumentsType() {
+		return argumentsType;
+	}
+
+
+	/**
+	 * @param argumentsType the argumentsType to set
+	 */
+	public ParamBuilder argumentsType(List<ValueParam> argumentsType) {
+		this.argumentsType = argumentsType;
+		return this;
+	}
+
+	/**
 	 * @return the enumValues
 	 */
@@ -121,15 +155,16 @@
 
 	/**
-	 * @return the procedureSignature
-	 */
-	public String getProcedureSignature() {
-		return procedureSignature;
-	}
-
-	/**
 	 * @return the uid
 	 */
 	public String getUid() {
 		return uid;
+	}
+
+	public @Nonnull <T extends Param> T finish(Class<T> requested) {
+		Param param = finish();
+		if (!requested.isInstance(param)) {
+			throw new FramsticksException().msg("param is of wrong type").arg("requested", requested).arg("actual", param.getClass());
+		}
+		return requested.cast(param);
 	}
 
@@ -141,10 +176,9 @@
 	 *             when Param getType is not defined
 	 */
-	public Param finish() {
+	public @Nonnull Param finish() {
 		try {
 			if (paramType == null) {
 				throw new FramsticksException().msg("trying to finish incomplete param");
 			}
-
 			return paramType.getConstructor(ParamBuilder.class).newInstance(this);
 		} catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException | SecurityException | FramsticksException e) {
@@ -165,9 +199,4 @@
 	}
 
-	// public <T extends Param> ParamBuilder type(T param) {
-	//	return internalSetType(param.getClass(), param);
-	// }
-
-
 	/**
 	 * @return the id
@@ -178,16 +207,4 @@
 	}
 
-	/**
-	 * @return the internalId
-	 */
-	public String getInternalId() {
-		return internalId;
-	}
-
-	public ParamBuilder setInternalId(String internalId) {
-		this.internalId = internalId;
-		return this;
-	}
-
 	@ParamAnnotation
 	public ParamBuilder group(Integer group) {
@@ -208,5 +225,5 @@
 	}
 
-	protected <T extends Number> void parseMinMaxDefNumber(Class<T> type, String second, String third) {
+	protected <T extends Number> void parseMinMaxDefNumber(Class<T> type, String second, String third, String fourth) {
 		if (second != null) {
 			min = second;
@@ -214,4 +231,7 @@
 		if (third != null) {
 			max = third;
+		}
+		if (fourth != null) {
+			def = fourth;
 		}
 	}
@@ -223,6 +243,4 @@
 		return type(EnumParam.class);
 	}
-
-	protected String procedureSignature;
 
 	protected String uid;
@@ -239,4 +257,5 @@
 		String second = typeSplitted.length > 1 ? typeSplitted[1] : null;
 		String third = typeSplitted.length > 2 ? typeSplitted[2] : null;
+		String fourth = typeSplitted.length > 3 ? typeSplitted[3] : null;
 
 		switch (first.charAt(0)) {
@@ -247,6 +266,6 @@
 			}
 			case 'p': {
-				procedureSignature = type.substring(1);
 				type(ProcedureParam.class);
+				signature(type.substring(1));
 				break;
 			}
@@ -281,5 +300,5 @@
 				}
 				if (DecimalParam.class.isAssignableFrom(this.paramType)) {
-					parseMinMaxDefNumber(Integer.class, second, third);
+					parseMinMaxDefNumber(Integer.class, second, third, fourth);
 				}
 				break;
@@ -287,5 +306,5 @@
 			case 'f': {
 				type(FloatParam.class);
-				parseMinMaxDefNumber(Double.class, second, third);
+				parseMinMaxDefNumber(Double.class, second, third, fourth);
 				break;
 			}
@@ -472,8 +491,59 @@
 	}
 
-
 	public Class<?> getStorageType() {
 		return storageType;
 	}
+
+	public ParamBuilder forAccess(AccessInterface access) {
+		return name(access.getId()).type("o " + access.getId());
+	}
+
+	protected static ValueParam parseProcedureTypePart(String type, String name) {
+		return Param.build().type(type).name(name).id(name).finish(ValueParam.class);
+	}
+
+	private static Pattern addressPattern = Pattern.compile("^([^\\(]+)?\\(([^\\)]*)\\)$");
+
+	public ParamBuilder signature(String signature) {
+		argumentsType = new ArrayList<>();
+
+		if (!Strings.notEmpty(signature)) {
+			resultType = null;
+			return this;
+		}
+		Matcher matcher = addressPattern.matcher(signature);
+		if (!matcher.matches()) {
+			throw new FramsticksException().msg("invalid signature");
+		}
+		String result = Strings.collapse(matcher.group(1));
+		resultType = (result != null) ? parseProcedureTypePart(result, null) : null;
+		String arguments = matcher.group(2);
+		if (!Strings.notEmpty(arguments)) {
+			return this;
+		}
+		int number = 0;
+		for (String a : arguments.split(",")) {
+			int space = a.indexOf(' ');
+			String type;
+			String name;
+			if (space == -1) {
+				type = a;
+				name = "arg" + number;
+			} else {
+				type = a.substring(0, space);
+				name = a.substring(space + 1);
+			}
+			argumentsType.add(parseProcedureTypePart(type, name));
+			++number;
+		}
+		return this;
+	}
+
+
+	public ParamBuilder idAndName(String name) {
+		id(name);
+		name(name);
+		return this;
+	}
 }
 
Index: /java/main/src/main/java/com/framsticks/params/ParamCandidate.java
===================================================================
--- /java/main/src/main/java/com/framsticks/params/ParamCandidate.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/params/ParamCandidate.java	(revision 90)
@@ -10,9 +10,16 @@
 import java.lang.reflect.ParameterizedType;
 import java.lang.reflect.Type;
+import java.util.Arrays;
 import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
 import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
 import java.util.Map;
 
+import com.framsticks.params.annotations.FramsClassAnnotation;
 import com.framsticks.params.annotations.ParamAnnotation;
+import com.framsticks.params.types.ProcedureParam;
 
 public class ParamCandidate {
@@ -65,4 +72,7 @@
 	protected final OneTime<Method> setter = new OneTime<>("setter");
 	protected final OneTime<Method> getter = new OneTime<>("getter");
+	protected final OneTime<Method> caller = new OneTime<>("caller");
+
+	protected final List<ParamAnnotation> annotations = new LinkedList<>();
 
 	/**
@@ -124,6 +134,29 @@
 	}
 
+	/**
+	 * @return the getter
+	 */
+	public Method getCaller() {
+		return caller.get();
+	}
+
+	/**
+	 * @return the annotations
+	 */
+	public List<ParamAnnotation> getAnnotations() {
+		return Collections.unmodifiableList(annotations);
+	}
+
 	void validate() throws ConstructionException {
 		try {
+			if (caller.has()) {
+				if (!isPublic(caller)) {
+					throw new ConstructionException().msg("method is not public");
+				}
+				if (getter.has() || setter.has()) {
+					throw new ConstructionException().msg("getter or setter coexist with caller");
+				}
+				return;
+			}
 			if (isPublic(field)) {
 				if (getter.has()) {
@@ -147,4 +180,7 @@
 
 	boolean isFinal() {
+		if (caller.has()) {
+			return false;
+		}
 		if (Collection.class.isAssignableFrom(getRawType())) {
 			return false;
@@ -160,4 +196,7 @@
 
 	boolean isReadOnly() {
+		if (caller.has()) {
+			return false;
+		}
 		if (Collection.class.isAssignableFrom(getRawType())) {
 			return false;
@@ -172,8 +211,9 @@
 	}
 
-	void add(Member member, String name) {
+	void add(ParamAnnotation paramAnnotation, Member member, String name) {
 		this.name.set(name);
+		annotations.add(paramAnnotation);
 		if (member instanceof Field) {
-			this.field.set((Field) member);
+			field.set((Field) member);
 			setType(field.get().getGenericType());
 			return;
@@ -181,4 +221,11 @@
 		if (member instanceof Method) {
 			Method m = (Method) member;
+			if (!paramAnnotation.paramType().equals(Param.class)) {
+				if (paramAnnotation.paramType().equals(ProcedureParam.class)) {
+					caller.set(m);
+					return;
+				}
+				throw new ConstructionException().msg("explicit set of paramType different than ProcedureParam is not yet supported").arg("name", name).arg("method", m).arg("in", this);
+			}
 			Type[] ps = m.getGenericParameterTypes();
 			if (ps.length == 0) {
@@ -222,5 +269,5 @@
 	}
 
-	public static <M extends Member & AnnotatedElement> void filterParamsCandidates(Map<String, ParamCandidate> params, M[] members) {
+	public static <M extends Member & AnnotatedElement> void filterParamsCandidates(Set set, M[] members) {
 		for (M m : members) {
 			ParamAnnotation pa = m.getAnnotation(ParamAnnotation.class);
@@ -228,38 +275,89 @@
 				continue;
 			}
-			// if (!isPublic(m)) {
-			// 	throw new ConstructionException().msg("field is not public").arg("field", m);
-			// }
 			String id = FramsClassBuilder.getId(pa, m);
 			ParamCandidate pc = null;
-			if (params.containsKey(id)) {
-				pc = params.get(id);
+			if (set.getCandidates().containsKey(id)) {
+				pc = set.getCandidates().get(id);
 			} else {
 				pc = new ParamCandidate(id);
-				params.put(id, pc);
-			}
-			pc.add(m, FramsClassBuilder.getName(pa, m));
-
-		}
-	}
-
-	public static Map<String, ParamCandidate> getAllCandidates(Class<?> javaClass) throws ConstructionException {
-		Map<String, ParamCandidate> candidates = new HashMap<>();
-
+				set.getCandidates().put(id, pc);
+				set.getOrder().add(pc);
+			}
+			pc.add(pa, m, FramsClassBuilder.getName(pa, m));
+		}
+	}
+
+	public static class Set {
+		protected final Map<String, ParamCandidate> candidates;
+		protected final List<ParamCandidate> order;
+
+		/**
+		 * @param candidates
+		 * @param order
+		 */
+		public Set(Map<String, ParamCandidate> candidates, List<ParamCandidate> order) {
+			this.candidates = candidates;
+			this.order = order;
+		}
+
+		/**
+		 * @return the candidates
+		 */
+		public Map<String, ParamCandidate> getCandidates() {
+			return candidates;
+		}
+
+		/**
+		 * @return the order
+		 */
+		public List<ParamCandidate> getOrder() {
+			return order;
+		}
+	}
+
+	public static Set getAllCandidates(Class<?> javaClass) throws ConstructionException {
+
+		List<Class<?>> javaClasses = new LinkedList<>();
 		while (javaClass != null) {
-			filterParamsCandidates(candidates, javaClass.getDeclaredFields());
-			filterParamsCandidates(candidates, javaClass.getDeclaredMethods());
-
+			javaClasses.add(0, javaClass);
 			javaClass = javaClass.getSuperclass();
 		}
 
-		for (ParamCandidate pc : candidates.values()) {
+		Set resultSet = new Set(new HashMap<String, ParamCandidate>(), new LinkedList<ParamCandidate>());
+
+		for (Class<?> j : javaClasses) {
+			Set set = new Set(resultSet.getCandidates(), new LinkedList<ParamCandidate>());
+			filterParamsCandidates(set, j.getDeclaredFields());
+			filterParamsCandidates(set, j.getDeclaredMethods());
+
+			FramsClassAnnotation fa = j.getAnnotation(FramsClassAnnotation.class);
+			if (fa != null) {
+				final List<String> order = Arrays.asList(fa.order());
+				Collections.sort(set.getOrder(), new Comparator<ParamCandidate>() {
+					@Override
+					public int compare(ParamCandidate pc0, ParamCandidate pc1) {
+						int u0 = order.indexOf(pc0.getId());
+						int u1 = order.indexOf(pc1.getId());
+						if (u0 == -1 || u1 == -1) {
+							return 0;
+						}
+						return u0 - u1;
+					}
+				});
+			}
+			resultSet.getOrder().addAll(0, set.getOrder());
+		}
+
+		for (ParamCandidate pc : resultSet.getOrder()) {
 			pc.validate();
 		}
 
-		return candidates;
+		return resultSet;
 	}
 
 	public static Class<?> getRawClass(final Type type) {
+		if (type == null) {
+			throw new IllegalArgumentException();
+		}
 		if (Class.class.isInstance(type)) {
 			return Class.class.cast(type);
Index: /java/main/src/main/java/com/framsticks/params/ParamsPackage.java
===================================================================
--- /java/main/src/main/java/com/framsticks/params/ParamsPackage.java	(revision 90)
+++ /java/main/src/main/java/com/framsticks/params/ParamsPackage.java	(revision 90)
@@ -0,0 +1,38 @@
+package com.framsticks.params;
+
+import com.framsticks.params.annotations.FramsClassAnnotation;
+import com.framsticks.params.annotations.ParamAnnotation;
+
+@FramsClassAnnotation
+public abstract class ParamsPackage {
+
+
+	protected boolean build = false;
+
+	public abstract void register(Registry registry);
+
+	/**
+	 * @return the build
+	 */
+	@ParamAnnotation
+	public boolean getBuild() {
+		return build;
+	}
+
+	/**
+	 * @param build the build to set
+	 */
+	@ParamAnnotation
+	public void setBuild(boolean build) {
+		this.build = build;
+	}
+
+	protected void register(Registry registry, Class<?> javaClass) {
+		if (build) {
+			registry.registerAndBuild(javaClass);
+		} else {
+			registry.register(javaClass);
+		}
+	}
+
+}
Index: /java/main/src/main/java/com/framsticks/params/PrimitiveParam.java
===================================================================
--- /java/main/src/main/java/com/framsticks/params/PrimitiveParam.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/params/PrimitiveParam.java	(revision 90)
@@ -96,3 +96,4 @@
 		return tryCastAndReturn(def, type);
 	}
+
 }
Index: /java/main/src/main/java/com/framsticks/params/PropertiesAccess.java
===================================================================
--- /java/main/src/main/java/com/framsticks/params/PropertiesAccess.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/params/PropertiesAccess.java	(revision 90)
@@ -3,4 +3,6 @@
 import java.util.HashMap;
 import java.util.Map;
+
+import com.framsticks.params.types.ProcedureParam;
 
 
@@ -93,3 +95,13 @@
 	}
 
+	@Override
+	public Object call(String id, Object[] arguments) {
+		throw new InvalidOperationException().msg("list access does not support calling methods").arg("id", id);
+	}
+
+	@Override
+	public Object call(ProcedureParam param, Object[] arguments) {
+		throw new InvalidOperationException().msg("list access does not support calling methods").arg("param", param);
+	}
+
 }
Index: /java/main/src/main/java/com/framsticks/params/ReflectionAccess.java
===================================================================
--- /java/main/src/main/java/com/framsticks/params/ReflectionAccess.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/params/ReflectionAccess.java	(revision 90)
@@ -4,7 +4,8 @@
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
+import java.util.ArrayList;
 import java.util.Collections;
+import java.util.Comparator;
 import java.util.HashMap;
-import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
@@ -15,4 +16,5 @@
 
 import com.framsticks.params.annotations.AutoAppendAnnotation;
+import com.framsticks.params.types.ProcedureParam;
 import com.framsticks.util.FramsticksException;
 import com.framsticks.util.lang.Pair;
@@ -31,5 +33,5 @@
 	private final static Logger log = Logger.getLogger(ReflectionAccess.class.getName());
 
-	protected final Class<?> reflectedClass;
+	protected final Class<?> javaClass;
 	protected final Backend backend;
 
@@ -41,7 +43,7 @@
 		protected static final Map<Pair<Class<?>, FramsClass>, Backend> synchronizedCache = Collections.synchronizedMap(new HashMap<Pair<Class<?>, FramsClass>, Backend>());
 
-		public static class ReflectedValueParam {
-			public ReflectedSetter setter;
-			public ReflectedGetter getter;
+
+		public interface ReflectedGetter {
+			public <T> T get(Object object, Class<T> type) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException;
 		}
 
@@ -50,18 +52,17 @@
 		}
 
-		public interface ReflectedGetter {
-			public abstract <T> T get(Object object, Class<T> type) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException;
-		}
-
-		protected final Map<ValueParam, ReflectedValueParam> params;
-		protected final List<Method> autoAppendMethods;
+		public interface ReflectedCaller {
+			public Object call(Object object, Object[] arguments) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException;
+		}
+
+		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 List<Method> autoAppendMethods = new ArrayList<>();
 
 		/**
 		 * @param params
 		 */
-		public Backend(Map<ValueParam, ReflectedValueParam> params, List<Method> autoAppendMethods) {
-			// this.params = Collections.unmodifiableMap(params);
-			this.params = params;
-			this.autoAppendMethods = autoAppendMethods;
+		public Backend() {
 		}
 
@@ -75,9 +76,27 @@
 
 			log.debug("constructing backend for " + id);
-			final Map<ValueParam, ReflectedValueParam> params = new HashMap<>();
-
-			Map<String, ParamCandidate> candidates = ParamCandidate.getAllCandidates(reflectedClass);
-
-			try {
+			backend = new Backend();
+
+			Map<String, ParamCandidate> candidates = ParamCandidate.getAllCandidates(reflectedClass).getCandidates();
+
+			try {
+				for (final ProcedureParam pp : filterInstanceof(framsClass.getParamEntries(), ProcedureParam.class)) {
+					if (!candidates.containsKey(pp.getId())) {
+						log.trace("java class does implement method " + pp);
+						continue;
+					}
+					ParamCandidate pc = candidates.get(pp.getId());
+					final Method method = pc.getCaller();
+
+					backend.callers.put(pp, new ReflectedCaller() {
+
+						@Override
+						public Object call(Object object, Object[] arguments) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
+							return method.invoke(object, arguments);
+						}
+					});
+
+				}
+
 				for (final ValueParam vp : filterInstanceof(framsClass.getParamEntries(), ValueParam.class)) {
 					if (!candidates.containsKey(vp.getId())) {
@@ -92,17 +111,15 @@
 					}
 
-					ReflectedValueParam rvp = new ReflectedValueParam();
-					params.put(vp, rvp);
 					final boolean primitive = pc.isPrimitive();
 					if (pc.getField() != null) {
 						final Field f = pc.getField();
-						rvp.getter = new ReflectedGetter() {
+						backend.getters.put(vp, new ReflectedGetter() {
 							@Override
 							public <T> T get(Object object, Class<T> type) throws IllegalArgumentException, IllegalAccessException {
 								return type.cast(f.get(object));
 							}
-						};
+						});
 						if (!pc.isFinal()) {
-							rvp.setter = new ReflectedSetter() {
+							backend.setters.put(vp, new ReflectedSetter() {
 								@Override
 								public <T> void set(Object object, T value) throws IllegalArgumentException, IllegalAccessException {
@@ -112,19 +129,19 @@
 									f.set(object, value);
 								}
-							};
+							});
 						}
 					} else {
 						final Method g = pc.getGetter();
 
-						rvp.getter = new ReflectedGetter() {
+						backend.getters.put(vp, new ReflectedGetter() {
 							@Override
 							public <T> T get(Object object, Class<T> type) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
 								return type.cast(g.invoke(object));
 							}
-						};
+						});
 
 						if (!pc.isFinal()) {
 							final Method s = pc.getSetter();
-							rvp.setter = new ReflectedSetter() {
+							backend.setters.put(vp, new ReflectedSetter() {
 								@Override
 								public <T> void set(Object object, T value) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
@@ -134,5 +151,5 @@
 									s.invoke(object, value);
 								}
-							};
+							});
 						}
 					}
@@ -141,6 +158,4 @@
 				throw e.arg("java class", reflectedClass).arg("framsClass", framsClass);
 			}
-
-			List<Method> autoAppendMethods = new LinkedList<>();
 
 			Class<?> javaClass = reflectedClass;
@@ -156,5 +171,5 @@
 						throw new ConstructionException().msg("invalid number of arguments in AutoAppend marked method").arg("method", m).arg("arguments", args.length);
 					}
-					autoAppendMethods.add(m);
+					backend.autoAppendMethods.add(m);
 				}
 
@@ -162,5 +177,20 @@
 			}
 
-			backend = new Backend(params, autoAppendMethods);
+			Collections.sort(backend.autoAppendMethods, new Comparator<Method>() {
+
+				@Override
+				public int compare(Method m0, Method m1) {
+					Class<?> arg0 = m0.getParameterTypes()[0];
+					Class<?> arg1 = m1.getParameterTypes()[0];
+					if (arg0.isAssignableFrom(arg1)) {
+						return 1;
+					}
+					if (arg1.isAssignableFrom(arg0)) {
+						return -1;
+					}
+					return 0;
+				}
+			});
+
 			synchronizedCache.put(id, backend);
 			return backend;
@@ -194,12 +224,8 @@
 	public ReflectionAccess(Class<?> reflectedClass, FramsClass framsClass) throws ConstructionException {
 		super(framsClass);
-		this.reflectedClass = reflectedClass;
+		this.javaClass = reflectedClass;
 		this.backend = Backend.getOrCreateFor(reflectedClass, framsClass);
-		// log.info("created ReflectionAccess " + this);
-	}
-
-	// private static String accessorName(boolean get, String id) {
-	//	return (get ? "get" : "set") + id.substring(0, 1).toUpperCase() + id.substring(1);
-	// }
+	}
+
 
 	@Override
@@ -211,5 +237,5 @@
 				}
 
-				return backend.params.get(param).getter.get(object, type);
+				return backend.getters.get(param).get(object, type);
 			} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
 				throw new FramsticksException().msg("failed to get").cause(e);
@@ -231,7 +257,7 @@
 					throw new FramsticksException().msg("no object set");
 				}
-				Backend.ReflectedSetter s = backend.params.get(param).setter;
+				Backend.ReflectedSetter s = backend.setters.get(param);
 				if (s == null) {
-					throw new FramsticksException().msg("trying to set final");
+					throw new FramsticksException().msg("trying to set unsettable");
 				}
 				s.set(object, value);
@@ -241,4 +267,29 @@
 		} catch (FramsticksException e) {
 			throw e.arg("param", param).arg("value", value).arg("access", this);
+		}
+	}
+
+	@Override
+	public Object call(String id, Object[] arguments) {
+		return call(framsClass.getParamEntry(id, ProcedureParam.class), arguments);
+	}
+
+	@Override
+	public Object call(ProcedureParam param, Object[] arguments) {
+		try {
+			try {
+				if (object == null) {
+					throw new FramsticksException().msg("no object set");
+				}
+				Backend.ReflectedCaller c = backend.callers.get(param);
+				if (c == null) {
+					throw new FramsticksException().msg("method is not bound");
+				}
+				return c.call(object, arguments);
+			} catch (IllegalArgumentException | IllegalAccessException | InvocationTargetException e) {
+				throw new FramsticksException().msg("failed to call").cause(e);
+			}
+		} catch (FramsticksException e) {
+			throw e.arg("param", param).arg("access", this);
 		}
 	}
@@ -273,5 +324,5 @@
 	@Override
 	public ReflectionAccess select(Object object) {
-		assert object == null || reflectedClass.isInstance(object);
+		assert object == null || javaClass.isInstance(object);
 		this.object = object;
 		return this;
@@ -302,5 +353,5 @@
 	@Override
 	public ReflectionAccess cloneAccess() throws ConstructionException {
-		return new ReflectionAccess(reflectedClass, framsClass);
+		return new ReflectionAccess(javaClass, framsClass);
 	}
 
@@ -308,9 +359,9 @@
 	public Object createAccessee() {
 		try {
-			return reflectedClass.newInstance();
+			return javaClass.newInstance();
 		} catch (InstantiationException | IllegalAccessException e) {
 			e.printStackTrace();
 		}
-		log.fatal("failed to create reflected object of class " + reflectedClass.getCanonicalName() + " for frams type " + framsClass.getId());
+		log.fatal("failed to create reflected object of class " + javaClass.getCanonicalName() + " for frams type " + framsClass.getId());
 		return null;
 	}
@@ -332,4 +383,5 @@
 			if (m.getParameterTypes()[0].isAssignableFrom(value.getClass())) {
 				try {
+					log.trace("auto appending with value " + value + " with method " + m);
 					m.invoke(object, value);
 					return true;
@@ -341,4 +393,5 @@
 		return false;
 	}
+
 }
 
Index: /java/main/src/main/java/com/framsticks/params/Registry.java
===================================================================
--- /java/main/src/main/java/com/framsticks/params/Registry.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/params/Registry.java	(revision 90)
@@ -4,50 +4,74 @@
 
 import com.framsticks.params.annotations.FramsClassAnnotation;
+import com.framsticks.params.annotations.ParamAnnotation;
 import com.framsticks.util.DoubleMap;
 import com.framsticks.util.FramsticksException;
 
+import java.util.HashMap;
+import java.util.Map;
 import java.util.Set;
+
+import javax.annotation.Nonnull;
 
 /**
  * Author: Piotr Śniegowski
  */
+@FramsClassAnnotation
 public class Registry {
 	private static final Logger log = Logger.getLogger(Registry.class.getName());
 
-	// protected void internalRegisterClass(FramsClass framsClass, @Nullable Class<?> javaClass) {
-	// 	assert framsClass.getName() != null;
-	// 	assert framsClass.getId() != null;
-	// 	infoCacheByName.put(framsClass.getName(), framsClass);
-	// 	infoCacheById.put(framsClass.getId(), framsClass);
-
-	// 	if (javaClass != null) {
-	// 		reflectedClasses.put(framsClass, javaClass);
-	// 		infoCacheByJavaName.put(javaClass.getCanonicalName(), framsClass);
-	// 	}
-	// }
 	protected final DoubleMap<String, Class<?>> javaClasses = new DoubleMap<>();
 	protected final DoubleMap<String, FramsClass> framsClasses = new DoubleMap<>();
+	protected final Map<Class<?>, FramsClass> javaToFramsAssociation = new HashMap<>();
 
-	public void registerReflectedClass(String name, String id, Class<?> reflectedClass) {
-		javaClasses.put(id, name, reflectedClass);
+	/**
+	 *
+	 */
+	public Registry() {
+		// registerAndBuild(Registry.class);
+		// registerAndBuild(FramsClass.class);
+		// registerAndBuild(Param.class);
 	}
 
-	public Registry registerAndBuild(Class<?> reflectedClass) {
-		register(reflectedClass);
-		putInfoIntoCache(FramsClass.build().forClass(reflectedClass));
+	public void registerReflectedClass(String name, String id, Class<?> javaClass) {
+		javaClasses.put(id, name, javaClass);
+	}
+
+	public void associate(Class<?> javaClass, FramsClass framsClass) {
+		javaToFramsAssociation.put(javaClass, framsClass);
+	}
+
+	public Registry registerAndBuild(Class<?> javaClass) {
+		register(javaClass);
+		associate(javaClass, putFramsClass(FramsClass.build().forClass(javaClass)));
 		return this;
 	}
 
-	public Registry register(Class<?> reflectedClass) {
-		FramsClassAnnotation a = reflectedClass.getAnnotation(FramsClassAnnotation.class);
+	public Registry register(Class<?> javaClass) {
+		FramsClassAnnotation a = javaClass.getAnnotation(FramsClassAnnotation.class);
 		if (a == null) {
-			throw new FramsticksException().msg("class is not annotated").arg("class", reflectedClass);
+			throw new FramsticksException().msg("class is not annotated").arg("class", javaClass);
 		}
 
-		registerReflectedClass(FramsClassBuilder.getName(a, reflectedClass), FramsClassBuilder.getId(a, reflectedClass), reflectedClass);
+		registerReflectedClass(FramsClassBuilder.getName(a, javaClass), FramsClassBuilder.getId(a, javaClass), javaClass);
 		return this;
 	}
 
-	public AccessInterface createAccess(String name, FramsClass framsClass) throws ConstructionException {
+	public @Nonnull ReflectionAccess createAccess(Class<?> javaClass) throws ConstructionException {
+		try {
+			if (!javaClasses.containsValue(javaClass)) {
+				throw new FramsticksException().msg("java class is not registered");
+			}
+			if (!javaToFramsAssociation.containsKey(javaClass)) {
+				throw new FramsticksException().msg("java class is not associated with any frams class");
+			}
+			return new ReflectionAccess(javaClass, javaToFramsAssociation.get(javaClass));
+		}
+		catch (FramsticksException e) {
+			throw new FramsticksException().msg("failed to create access for java class").arg("class", javaClass).cause(e);
+		}
+	}
+
+	public @Nonnull AccessInterface createAccess(String name, FramsClass framsClass) throws ConstructionException {
 		// assert framsClasses.containsValue(framsClass);
 		if (javaClasses.containsKey(name)) {
@@ -57,37 +81,34 @@
 	}
 
-	public void putInfoIntoCache(FramsClass framsClass) {
+	public FramsClass putFramsClass(FramsClass framsClass) {
 		log.debug("caching info for " + framsClass);
 		framsClasses.put(framsClass.getId(), framsClass.getName(), framsClass);
+		return framsClass;
 	}
 
-	public FramsClass getInfoFromCache(String identifier) {
-		if (identifier == null) {
-			return null;
-		}
+	public FramsClass getFramsClass(@Nonnull String identifier) {
 		return framsClasses.get(identifier);
 	}
 
-	public static AccessInterface wrapAccessWithListIfNeeded(CompositeParam param, AccessInterface access) {
-		if (access == null) {
-			return null;
-		}
+	public static @Nonnull AccessInterface wrapAccessWithListIfNeeded(@Nonnull CompositeParam param, @Nonnull AccessInterface access) {
 		return param.prepareAccessInterface(access);
 	}
 
-	public AccessInterface prepareAccess(CompositeParam param) throws ConstructionException {
+	public @Nonnull AccessInterface prepareAccess(CompositeParam param) throws ConstructionException {
 		return wrapAccessWithListIfNeeded(param, createAccess(param.getContainedTypeName()));
 	}
 
-	public AccessInterface createAccess(String name) throws ConstructionException {
-		if (name == null) {
-			return null;
+	public @Nonnull AccessInterface createAccess(@Nonnull String name) throws ConstructionException {
+		try {
+			FramsClass framsClass = getFramsClass(name);
+			if (framsClass == null) {
+				throw new ConstructionException().msg("framsclass is missing");
+			}
+
+			return createAccess(name, framsClass);
 		}
-		FramsClass framsClass = getInfoFromCache(name);
-		if (framsClass == null) {
-			return null;
+		catch (FramsticksException e) {
+			throw new FramsticksException().msg("failed to create access for name").arg("name", name).cause(e);
 		}
-
-		return createAccess(name, framsClass);
 	}
 
@@ -96,7 +117,22 @@
 	}
 
-	public Set<FramsClass> getInfoCache() {
+	public Set<FramsClass> getFramsClasses() {
 		return framsClasses.getValues();
 	}
 
+	@ParamAnnotation
+	public Map<String, FramsClass> getFramsClassesById() {
+		return framsClasses.getValuesById();
+	}
+
+	public void takeAllFrom(Registry source) {
+		for (Class<?> javaClass : source.getReflectedClasses()) {
+			register(javaClass);
+		}
+		for (FramsClass framsClass : source.getFramsClasses()) {
+			putFramsClass(framsClass);
+		}
+
+	}
+
 }
Index: /java/main/src/main/java/com/framsticks/params/SimpleAbstractAccess.java
===================================================================
--- /java/main/src/main/java/com/framsticks/params/SimpleAbstractAccess.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/params/SimpleAbstractAccess.java	(revision 90)
@@ -78,8 +78,8 @@
 	}
 
-	@Override
-	public Param getGroupMember(int gi, int n) {
-		return framsClass.getGroupMember(gi, n);
-	}
+	// @Override
+	// public Param getGroupMember(int gi, int n) {
+	// 	return framsClass.getGroupMember(gi, n);
+	// }
 
 	@Override
Index: /java/main/src/main/java/com/framsticks/params/UniqueListAccess.java
===================================================================
--- /java/main/src/main/java/com/framsticks/params/UniqueListAccess.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/params/UniqueListAccess.java	(revision 90)
@@ -45,5 +45,5 @@
 		}
 		//TODO list access here
-		return Param.build().id(id).name(elementAccess.getId()).type("o " + elementAccess.getId()).finish();
+		return Param.build().id(id).forAccess(elementAccess).finish();
 	}
 
Index: /java/main/src/main/java/com/framsticks/params/Util.java
===================================================================
--- /java/main/src/main/java/com/framsticks/params/Util.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/params/Util.java	(revision 90)
@@ -3,4 +3,6 @@
 import java.util.ArrayList;
 import java.util.List;
+
+import com.framsticks.util.FramsticksException;
 
 
@@ -22,8 +24,12 @@
 	}
 
-	public static List<Object> stripAccessInterface(List<AccessInterface> accesses) {
-		List<Object> result = new ArrayList<Object>();
+	public static <T> List<T> stripAccessInterface(List<AccessInterface> accesses, Class<T> type) {
+		List<T> result = new ArrayList<T>();
 		for (AccessInterface a : accesses) {
-			result.add(a.getSelected());
+			Object object = a.getSelected();
+			if (!type.isInstance(object)) {
+				throw new FramsticksException().msg("extracted object is of invalid type").arg("object", object).arg("desired", type).arg("actual", object.getClass()).arg("framsclass", a.getFramsClass());
+			}
+			result.add(type.cast(object));
 		}
 		return result;
Index: /java/main/src/main/java/com/framsticks/params/annotations/FramsClassAnnotation.java
===================================================================
--- /java/main/src/main/java/com/framsticks/params/annotations/FramsClassAnnotation.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/params/annotations/FramsClassAnnotation.java	(revision 90)
@@ -11,3 +11,5 @@
 	String name() default "";
 	String id() default "";
+
+	String[] order() default {};
 }
Index: /java/main/src/main/java/com/framsticks/params/annotations/ParamAnnotation.java
===================================================================
--- /java/main/src/main/java/com/framsticks/params/annotations/ParamAnnotation.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/params/annotations/ParamAnnotation.java	(revision 90)
@@ -6,4 +6,6 @@
 import java.lang.annotation.Target;
 
+import com.framsticks.params.Param;
+
 @Retention(RetentionPolicy.RUNTIME)
 @Target({ElementType.FIELD, ElementType.METHOD})
@@ -11,4 +13,16 @@
 	String name() default "";
 	String id() default "";
+
+	Class<? extends Param> paramType() default Param.class;
+	String stringType() default "";
+
+	String def() default "";
+	String min() default "";
+	String max() default "";
+
+	String help() default "";
+	// int flags() default 0;
+	int extra() default 0;
+	// String group() default "";
 }
 
Index: /java/main/src/main/java/com/framsticks/params/types/ObjectParam.java
===================================================================
--- /java/main/src/main/java/com/framsticks/params/types/ObjectParam.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/params/types/ObjectParam.java	(revision 90)
@@ -15,6 +15,9 @@
 public class ObjectParam extends CompositeParam {
 
+	protected final Class<?> storageType;
+
 	public ObjectParam(ParamBuilder builder) {
-		super(builder);
+		super(builder.fillStorageType(Object.class));
+		storageType = builder.getStorageType();
 	}
 
@@ -26,9 +29,12 @@
 	@Override
 	public Class<?> getStorageType() {
-		return Object.class;
+		return storageType;
 	}
 
 	@Override
 	public ReassignResult<Object> reassign(Object newValue, Object oldValue) throws CastFailure {
+		if (newValue != null && !storageType.isInstance(newValue)) {
+			throw new CastFailure();
+		}
 		return ReassignResult.create(newValue);
 	}
Index: /java/main/src/main/java/com/framsticks/params/types/ProcedureParam.java
===================================================================
--- /java/main/src/main/java/com/framsticks/params/types/ProcedureParam.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/params/types/ProcedureParam.java	(revision 90)
@@ -3,11 +3,7 @@
 import com.framsticks.params.Param;
 import com.framsticks.params.ParamBuilder;
-import com.framsticks.util.FramsticksException;
-import com.framsticks.util.lang.Strings;
+import com.framsticks.params.ValueParam;
 
-import java.util.ArrayList;
 import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
 
 import javax.annotation.concurrent.Immutable;
@@ -18,8 +14,6 @@
 @Immutable
 public class ProcedureParam extends Param {
-	private final Param resultType;
-	private final List<Param> argumentsType = new ArrayList<Param>();
-
-	private static Pattern addressPattern = Pattern.compile("^([^\\(]+)?\\(([^\\)]*)\\)$");
+	private final ValueParam resultType;
+	private final List<ValueParam> argumentsType;
 
 	/**
@@ -28,36 +22,7 @@
 	public ProcedureParam(ParamBuilder builder) {
 		super(builder);
-		String signature = builder.getProcedureSignature();
-		if (Strings.notEmpty(signature)) {
-			Matcher matcher = addressPattern.matcher(signature);
-			if (!matcher.matches()) {
-				throw new FramsticksException().msg("invalid signature");
-			}
-			String result = Strings.collapse(matcher.group(1));
-			resultType = (result != null) ? parseType(result, null) : null;
-			String arguments = matcher.group(2);
-			if (!Strings.notEmpty(arguments)) {
-				return;
-			}
-			for (String a : arguments.split(",")) {
-				int space = a.indexOf(' ');
-				String type;
-				String name;
-				if (space == -1) {
-					type = a;
-					name = null;
-				} else {
-					type = a.substring(0, space);
-					name = a.substring(space + 1);
-				}
-				argumentsType.add(parseType(type, name));
-			}
-		} else {
-			resultType = null;
-		}
-	}
-
-	protected static Param parseType(String type, String name) {
-		return Param.build().type(type).name(name).finish();
+		resultType = builder.getResultType();
+		argumentsType = builder.getArgumentsType();
+		assert argumentsType != null;
 	}
 
@@ -67,9 +32,9 @@
 	}
 
-	public Param getResultType() {
+	public ValueParam getResultType() {
 		return resultType;
 	}
 
-	public List<Param> getArgumentsType() {
+	public List<ValueParam> getArgumentsType() {
 		return argumentsType;
 	}
Index: /java/main/src/main/java/com/framsticks/parsers/F0Parser.java
===================================================================
--- /java/main/src/main/java/com/framsticks/parsers/F0Parser.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/parsers/F0Parser.java	(revision 90)
@@ -18,4 +18,5 @@
 import com.framsticks.params.Param;
 import com.framsticks.params.PrimitiveParam;
+import com.framsticks.util.FramsticksException;
 import com.framsticks.util.lang.Containers;
 import com.framsticks.util.lang.Pair;
@@ -82,6 +83,5 @@
 	 *             the parse exception
 	 */
-	public List<AccessInterface> parse() throws IOException,
-			ParseException {
+	public List<AccessInterface> parse() {
 
 		try (InputStreamReader reader = new InputStreamReader(is, "UTF-8")) {
@@ -114,4 +114,6 @@
 				result.add(0, processLine("m:"));
 			}
+		} catch (IOException e) {
+			throw new FramsticksException().msg("failed to parse f0").arg("parser", this).arg("schema", schema).cause(e);
 		}
 
Index: /java/main/src/main/java/com/framsticks/parsers/F0Writer.java
===================================================================
--- /java/main/src/main/java/com/framsticks/parsers/F0Writer.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/parsers/F0Writer.java	(revision 90)
@@ -44,5 +44,5 @@
 		for (ValueParam param : filterInstanceof(access.getParams(), ValueParam.class)) {
 			if (param instanceof CompositeParam) {
-				AccessInterface a = schema.getRegistry().prepareAccess((CompositeParam)param);
+				AccessInterface a = schema.getRegistry().prepareAccess((CompositeParam) param);
 				a.select(access.get((ValueParam) param, Object.class));
 				write(a);
@@ -78,4 +78,5 @@
 		sink.print(line).breakLine();
 	}
+
 	public void write() {
 		AccessInterface access = schema.getRegistry().createAccess("m");
Index: /java/main/src/main/java/com/framsticks/parsers/XmlLoader.java
===================================================================
--- /java/main/src/main/java/com/framsticks/parsers/XmlLoader.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/parsers/XmlLoader.java	(revision 90)
@@ -2,4 +2,6 @@
 
 import java.io.InputStream;
+import java.util.LinkedList;
+import java.util.List;
 
 import javax.xml.parsers.DocumentBuilder;
@@ -15,4 +17,5 @@
 import com.framsticks.params.AccessInterface;
 import com.framsticks.params.Registry;
+import com.framsticks.util.AutoBuilder;
 import com.framsticks.util.FramsticksException;
 
@@ -86,6 +89,16 @@
 			}
 
-			if (!access.tryAutoAppend(childObject)) {
-				throw new FramsticksException().msg("failed to auto append").arg("child", childObject).arg("parent", object);
+			List<Object> childrenObjects = new LinkedList<>();
+
+			if (childObject instanceof AutoBuilder) {
+				childrenObjects.addAll(((AutoBuilder) childObject).autoFinish());
+			} else {
+				childrenObjects.add(childObject);
+			}
+
+			for (Object child : childrenObjects) {
+				if (!access.tryAutoAppend(child)) {
+					throw new FramsticksException().msg("failed to auto append").arg("child", child).arg("parent", object);
+				}
 			}
 		}
@@ -112,5 +125,5 @@
 	}
 
-	public <T> T load(InputStream stream, Class<T> type) {
+	public <T> T load(Class<T> type, InputStream stream) {
 		registry.registerAndBuild(type);
 
Index: /java/main/src/main/java/com/framsticks/portals/Portal.java
===================================================================
--- /java/main/src/main/java/com/framsticks/portals/Portal.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/portals/Portal.java	(revision 90)
@@ -58,5 +58,5 @@
 				}
 				final String path = "/simulator/genepools/groups/0/genotypes";
-				instance.invokeLater(new RunAt<Instance>() {
+				instance.dispatch(new RunAt<Instance>() {
 					@Override
 					public void run() {
Index: /java/main/src/main/java/com/framsticks/remote/RecursiveFetcher.java
===================================================================
--- /java/main/src/main/java/com/framsticks/remote/RecursiveFetcher.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/remote/RecursiveFetcher.java	(revision 90)
@@ -52,5 +52,5 @@
 				if (childPath.isResolved() && instance.getInfoFromCache(childPath) != null) {
 					++dispatched;
-					instance.invokeLater(new RunAt<Instance>() {
+					instance.dispatch(new RunAt<Instance>() {
 						@Override
 						public void run() {
Index: /java/main/src/main/java/com/framsticks/remote/RemoteInstance.java
===================================================================
--- /java/main/src/main/java/com/framsticks/remote/RemoteInstance.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/remote/RemoteInstance.java	(revision 90)
@@ -12,4 +12,5 @@
 import com.framsticks.params.annotations.ParamAnnotation;
 import com.framsticks.params.types.EventParam;
+import com.framsticks.params.types.ProcedureParam;
 import com.framsticks.parsers.MultiParamLoader;
 import com.framsticks.core.Instance;
@@ -82,5 +83,5 @@
 						}
 
-						invokeLater(new RunAt<Instance>() {
+						dispatch(new RunAt<Instance>() {
 							@Override
 							public void run() {
@@ -103,5 +104,5 @@
 											@Override
 											public void call(List<File> files) {
-												invokeLater(new RunAt<Instance>() {
+												dispatch(new RunAt<Instance>() {
 													@Override
 													public void run() {
@@ -361,5 +362,5 @@
 				log.debug("subscribed for change event for " + path);
 				// subscription.setDispatcher(RemoteInstance.this);
-				RemoteInstance.this.invokeLater(new RunAt<Instance>() {
+				RemoteInstance.this.dispatch(new RunAt<Instance>() {
 					@Override
 					public void run() {
@@ -497,5 +498,4 @@
 	}
 
-
 	@Override
 	public void childChangedState(Joinable joinable, JoinableState state) {
@@ -503,4 +503,8 @@
 	}
 
+	@Override
+	public void call(Path path, ProcedureParam param, Object[] arguments, StateFunctor stateFunctor) {
+		throw new UnimplementedException();
+	}
 
 }
Index: /java/main/src/main/java/com/framsticks/running/ExternalProcess.java
===================================================================
--- /java/main/src/main/java/com/framsticks/running/ExternalProcess.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/running/ExternalProcess.java	(revision 90)
@@ -15,19 +15,26 @@
 
 import com.framsticks.core.Entity;
+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.Misc;
+import com.framsticks.util.dispatching.AbstractJoinable;
+import com.framsticks.util.dispatching.Dispatching;
+import com.framsticks.util.dispatching.Joinable;
+import com.framsticks.util.dispatching.JoinableParent;
+import com.framsticks.util.dispatching.JoinableState;
+import com.framsticks.util.dispatching.RunAt;
 import com.framsticks.util.dispatching.Thread;
 import com.framsticks.util.io.Encoding;
 
 @FramsClassAnnotation
-public class ExternalProcess extends Thread<ExternalProcess> implements Entity {
+public class ExternalProcess extends AbstractJoinable implements JoinableParent, Entity {
 	private static final Logger log = Logger.getLogger(ExternalProcess.class);
 
 	protected List<String> arguments = new ArrayList<>();
 	protected Process process;
-	protected ProcessBuilder builder = new ProcessBuilder();
-	protected Thread<ExternalProcess> readerThread;
+	protected final ProcessBuilder builder = new ProcessBuilder();
+	protected Thread<ExternalProcess> readerThread = new Thread<ExternalProcess>();
 
 	protected PrintWriter input;
@@ -37,4 +44,5 @@
 	protected final List<OutputListener> listeners = new LinkedList<>();
 
+	@AutoAppendAnnotation
 	public void addListener(OutputListener listener) {
 		synchronized (listeners) {
@@ -50,4 +58,5 @@
 		setName("process");
 		arguments.add(null);
+		builder.redirectErrorStream(true);
 	}
 
@@ -68,6 +77,5 @@
 	}
 
-	@Override
-	protected void routine() {
+	protected void readerTask() {
 
 		String line;
@@ -91,12 +99,11 @@
 			}
 			log.debug("process ended " + this);
-			process = null;
+			// process = null;
 		} catch (FramsticksException e) {
 			log.error("exception caught in process " + this, e);
 		}
 		interrupt();
+		// finish();
 	}
-
-
 
 	@ParamAnnotation
@@ -111,6 +118,5 @@
 
 	@Override
-	public void joinableStart() {
-		builder = new ProcessBuilder();
+	protected void joinableStart() {
 		log.debug("running process with arguments: " + arguments);
 		builder.command(arguments);
@@ -119,14 +125,23 @@
 			input = new PrintWriter(new OutputStreamWriter(process.getOutputStream(), Encoding.getDefaultCharset()));
 			output = new BufferedReader(new InputStreamReader(process.getInputStream(), Encoding.getDefaultCharset()));
+
 		} catch (IOException e) {
 			throw new FramsticksException().msg("failed to start process").cause(e);
 		}
-		super.joinableStart();
 
+		readerThread.dispatch(new RunAt<ExternalProcess>() {
+
+			@Override
+			public void run() {
+				readerTask();
+			}
+
+		});
+		Dispatching.use(readerThread, this);
 	}
 
 	@Override
 	public String toString() {
-		return super.toString() + "[" + Misc.returnNotNull(getCommand(), "?") + "]";
+		return getName() + "[" + Misc.returnNotNull(getCommand(), "?") + "]";
 	}
 
@@ -140,7 +155,39 @@
 	@Override
 	protected void joinableInterrupt() {
-		super.joinableInterrupt();
-		finish();
+		process.destroy();
+		Dispatching.drop(readerThread, this);
+		// finish();
 	}
 
+	@Override
+	@ParamAnnotation
+	public String getName() {
+		return readerThread.getName();
+	}
+
+	/**
+	 * @param name the name to set
+	 */
+	@ParamAnnotation
+	public void setName(String name) {
+		readerThread.setName(name);
+	}
+
+	@Override
+	protected void joinableFinish() {
+
+	}
+
+	@Override
+	protected void joinableJoin() throws InterruptedException {
+		Dispatching.join(readerThread);
+	}
+
+	@Override
+	public void childChangedState(Joinable joinable, JoinableState state) {
+		proceedToState(state);
+	}
+
+
+
 }
Index: /java/main/src/main/java/com/framsticks/running/FramsServer.java
===================================================================
--- /java/main/src/main/java/com/framsticks/running/FramsServer.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/running/FramsServer.java	(revision 90)
@@ -8,4 +8,5 @@
 
 	protected Integer port;
+	protected String path;
 
 	/**
@@ -14,8 +15,8 @@
 	public FramsServer() {
 		super();
-		setCommand("/home/psniegowski/mgr/Framsticks32rc5/frams.linux");
-		setDirectory("/home/psniegowski/mgr/Framsticks32rc5");
+		setPath(System.getProperties().get("user.home") + "/opt/framsticks");
 		setName("frams");
 	}
+
 
 	/**
@@ -35,7 +36,26 @@
 	}
 
+	/**
+	 * @return the path
+	 */
+	@ParamAnnotation
+	public String getPath() {
+		return path;
+	}
+
+	/**
+	 * @param path the path to set
+	 */
+	@ParamAnnotation
+	public void setPath(String path) {
+		this.path = path;
+		setCommand(path + "/frams.linux");
+		setDirectory(path);
+	}
+
 	@Override
-	public void joinableStart() {
+	protected void joinableStart() {
 		if (port != null) {
+			arguments.add("-n");
 			arguments.add("-p" + port);
 		}
Index: /java/main/src/main/java/com/framsticks/running/LoggingOutputListener.java
===================================================================
--- /java/main/src/main/java/com/framsticks/running/LoggingOutputListener.java	(revision 90)
+++ /java/main/src/main/java/com/framsticks/running/LoggingOutputListener.java	(revision 90)
@@ -0,0 +1,18 @@
+package com.framsticks.running;
+
+import org.apache.log4j.Logger;
+
+import com.framsticks.params.annotations.FramsClassAnnotation;
+
+@FramsClassAnnotation
+public class LoggingOutputListener implements OutputListener {
+	private static final Logger log =
+		Logger.getLogger(LoggingOutputListener.class);
+
+
+	@Override
+	public void onLineRead(String line) {
+		log.info(line);
+	}
+
+}
Index: /java/main/src/main/java/com/framsticks/util/AutoBuilder.java
===================================================================
--- /java/main/src/main/java/com/framsticks/util/AutoBuilder.java	(revision 90)
+++ /java/main/src/main/java/com/framsticks/util/AutoBuilder.java	(revision 90)
@@ -0,0 +1,9 @@
+package com.framsticks.util;
+
+import java.util.List;
+
+public interface AutoBuilder {
+
+	public List<Object> autoFinish();
+
+}
Index: /java/main/src/main/java/com/framsticks/util/DoubleMap.java
===================================================================
--- /java/main/src/main/java/com/framsticks/util/DoubleMap.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/util/DoubleMap.java	(revision 90)
@@ -50,3 +50,7 @@
 	}
 
+	public Map<K, V> getValuesById() {
+		return Collections.unmodifiableMap(byId);
+	}
+
 }
Index: /java/main/src/main/java/com/framsticks/util/Logging.java
===================================================================
--- /java/main/src/main/java/com/framsticks/util/Logging.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/util/Logging.java	(revision 90)
@@ -7,13 +7,13 @@
  */
 public abstract class Logging {
-    public static boolean log(Logger logger, String action, Object subject, Exception e) {
-        if (e != null) {
-            logger.error("failed to " + action + " " + subject + ": " + e);
-            return true;
-        }
-        if (logger.isDebugEnabled()) {
-            logger.debug("done: " + action + " " + subject);
-        }
-        return false;
-    }
+	public static boolean log(Logger logger, String action, Object subject, Exception e) {
+		if (e != null) {
+			logger.error("failed to " + action + " " + subject + ": ", e);
+			return true;
+		}
+		if (logger.isDebugEnabled()) {
+			logger.debug("done: " + action + " " + subject);
+		}
+		return false;
+	}
 }
Index: /java/main/src/main/java/com/framsticks/util/PeriodicTask.java
===================================================================
--- /java/main/src/main/java/com/framsticks/util/PeriodicTask.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/util/PeriodicTask.java	(revision 90)
@@ -16,10 +16,10 @@
 		this.period = period;
 		this.dispatcher = dispatcher;
-		dispatcher.invokeLater(this);
+		dispatcher.dispatch(this);
 	}
 
 
 	public void again() {
-		dispatcher.invokeLater(new Task<C>(System.currentTimeMillis() + period) {
+		dispatcher.dispatch(new Task<C>(System.currentTimeMillis() + period) {
 			@Override
 			public void run() {
Index: /java/main/src/main/java/com/framsticks/util/ResourceBuilder.java
===================================================================
--- /java/main/src/main/java/com/framsticks/util/ResourceBuilder.java	(revision 90)
+++ /java/main/src/main/java/com/framsticks/util/ResourceBuilder.java	(revision 90)
@@ -0,0 +1,41 @@
+package com.framsticks.util;
+
+import java.io.InputStream;
+
+import com.framsticks.params.annotations.ParamAnnotation;
+
+public abstract class ResourceBuilder<T> implements Builder<T> {
+
+	protected InputStream stream;
+
+	/**
+	 * @return the stream
+	 */
+	public InputStream getStream() {
+		return stream;
+	}
+
+	/**
+	 * @return the resource
+	 */
+	@ParamAnnotation
+	public String getResource() {
+		return resource;
+	}
+
+	/**
+	 * @param stream the stream to set
+	 */
+	public ResourceBuilder<T> stream(InputStream stream) {
+		this.stream = stream;
+		return this;
+	}
+
+	protected String resource;
+
+	@ParamAnnotation
+	public ResourceBuilder<T>  resource(String resource) {
+		this.resource = resource;
+		return stream(getClass().getResourceAsStream(resource));
+	}
+}
Index: /java/main/src/main/java/com/framsticks/util/UnimplementedException.java
===================================================================
--- /java/main/src/main/java/com/framsticks/util/UnimplementedException.java	(revision 90)
+++ /java/main/src/main/java/com/framsticks/util/UnimplementedException.java	(revision 90)
@@ -0,0 +1,6 @@
+package com.framsticks.util;
+
+@SuppressWarnings("serial")
+public class UnimplementedException extends FramsticksException {
+
+}
Index: /java/main/src/main/java/com/framsticks/util/dispatching/AbstractJoinable.java
===================================================================
--- /java/main/src/main/java/com/framsticks/util/dispatching/AbstractJoinable.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/util/dispatching/AbstractJoinable.java	(revision 90)
@@ -64,4 +64,5 @@
 				}
 			}
+			this.notifyAll();
 		}
 		report();
Index: /java/main/src/main/java/com/framsticks/util/dispatching/AtOnceDispatcher.java
===================================================================
--- /java/main/src/main/java/com/framsticks/util/dispatching/AtOnceDispatcher.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/util/dispatching/AtOnceDispatcher.java	(revision 90)
@@ -20,5 +20,5 @@
 
 	@Override
-	public final void invokeLater(RunAt<? extends C> runnable) {
+	public final void dispatch(RunAt<? extends C> runnable) {
 		runnable.run();
 	}
Index: /java/main/src/main/java/com/framsticks/util/dispatching/Dispatcher.java
===================================================================
--- /java/main/src/main/java/com/framsticks/util/dispatching/Dispatcher.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/util/dispatching/Dispatcher.java	(revision 90)
@@ -6,5 +6,5 @@
 public interface Dispatcher<C> {
 	public boolean isActive();
-	public void invokeLater(RunAt<? extends C> runnable);
+	public void dispatch(RunAt<? extends C> runnable);
 
 }
Index: /java/main/src/main/java/com/framsticks/util/dispatching/Dispatching.java
===================================================================
--- /java/main/src/main/java/com/framsticks/util/dispatching/Dispatching.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/util/dispatching/Dispatching.java	(revision 90)
@@ -15,15 +15,15 @@
 	}
 
-	public static <C> void invokeLaterOrNow(Dispatcher<C> dispatcher, RunAt<? extends C> runnable) {
+	public static <C> void dispatchIfNotActive(Dispatcher<C> dispatcher, RunAt<? extends C> runnable) {
 		if (dispatcher.isActive()) {
 			runnable.run();
 			return;
 		}
-		dispatcher.invokeLater(runnable);
+		dispatcher.dispatch(runnable);
 	}
 
 	//TODO RunAt StateFunctor
 	public static <C> void dispatchOk(Dispatcher<C> dispatcher, final StateFunctor stateFunctor) {
-		dispatcher.invokeLater(new RunAt<C>() {
+		dispatcher.dispatch(new RunAt<C>() {
 			@Override
 			public void run() {
@@ -39,15 +39,15 @@
 
 	public static <P, C> void invokeDispatch(Dispatcher<P> dispatcher, final Dispatcher<C> finalDispatcher, final RunAt<C> runnable) {
-		dispatcher.invokeLater(new RunAt<P>() {
+		dispatcher.dispatch(new RunAt<P>() {
 			@Override
 			public void run() {
-				finalDispatcher.invokeLater(runnable);
+				finalDispatcher.dispatch(runnable);
 			}
 		});
 	}
 
-	public static void sleep(int milliseconds) {
+	public static void sleep(double seconds) {
 		try {
-			java.lang.Thread.sleep(milliseconds, 0);
+			java.lang.Thread.sleep((long) (seconds * 1000));
 		} catch (InterruptedException e) {
 
@@ -58,5 +58,5 @@
 	public static void dispatcherGuardedInvoke(Joinable joinable, RunAt<?> runnable) {
 		if (joinable instanceof Dispatcher) {
-			invokeLaterOrNow(Dispatcher.class.cast(joinable), runnable);
+			dispatchIfNotActive(Dispatcher.class.cast(joinable), runnable);
 			return;
 		}
@@ -72,5 +72,4 @@
 		}
 	}
-
 
 	public static void drop(final Joinable joinable, final JoinableParent owner) {
@@ -106,5 +105,7 @@
 	public static void wait(Object object, long millis) {
 		try {
-			object.wait(millis);
+			synchronized (object) {
+				object.wait(millis);
+			}
 		} catch (InterruptedException e) {
 		}
@@ -112,5 +113,5 @@
 
 	public static void joinAbsolutely(Joinable joinable) {
-		log.info("joining absolutely " + joinable);
+		log.debug("joining absolutely " + joinable);
 		while (true) {
 			try {
@@ -120,11 +121,54 @@
 				// throw new FramsticksException().msg("failed to join").arg("dispatcher", dispatcher).cause(e);
 			}
-			log.info("waiting for " + joinable);
-			sleep(500);
+			log.debug("waiting for " + joinable);
+			wait(joinable, 500);
 		}
+	}
+
+	public interface Query<T> {
+		T get();
+	}
+
+	public static class QueryRunner<T, C> extends RunAt<C> {
+		protected final Query<T> query;
+		T result;
+		boolean ready = false;
+
+		/**
+		 * @param query
+		 */
+		public QueryRunner(Query<T> query) {
+			this.query = query;
+		}
+
+		@Override
+		public void run() {
+			result = query.get();
+			synchronized (this) {
+				ready = true;
+				this.notifyAll();
+			}
+		}
+
+		public T get() {
+			synchronized (this) {
+				while (!ready) {
+					try {
+						this.wait(100);
+					} catch (InterruptedException e) {
+					}
+				}
+			}
+			return result;
+		}
+	}
+
+	public static <T, C> T get(Dispatcher<C> dispatcher, Query<T> query) {
+		QueryRunner<T, C> runner = new QueryRunner<T, C>(query);
+		dispatcher.dispatch(runner);
+		return runner.get();
 	}
 
 
 
-
 }
Index: va/main/src/main/java/com/framsticks/util/dispatching/JoinableMonitor.java
===================================================================
--- /java/main/src/main/java/com/framsticks/util/dispatching/JoinableMonitor.java	(revision 89)
+++ 	(revision )
@@ -1,64 +1,0 @@
-package com.framsticks.util.dispatching;
-
-import org.apache.log4j.Logger;
-// import edu.umd.cs.findbugs.annotations.SuppressWarnings;
-import com.framsticks.util.dispatching.Dispatching;
-
-public class JoinableMonitor implements JoinableParent {
-	private static final Logger log =
-		Logger.getLogger(JoinableMonitor.class);
-
-	protected final Joinable joinable;
-
-	/**
-	 * @param joinable
-	 */
-	public JoinableMonitor(Joinable joinable) {
-		this.joinable = joinable;
-	}
-
-	public JoinableMonitor waitFor() {
-		log.debug(this + " is waiting");
-		synchronized (this) {
-			while (joinable.getState().ordinal() < JoinableState.FINISHING.ordinal()) {
-				Dispatching.wait(this, 100);
-			}
-		}
-		log.debug(this + " ended waiting");
-		return this;
-	}
-
-	public JoinableMonitor use() {
-		log.debug(this + " is using");
-		Dispatching.use(joinable, this);
-		return this;
-	}
-
-	public JoinableMonitor drop() {
-		log.debug(this + " is droping");
-		Dispatching.drop(joinable, this);
-		return this;
-	}
-
-	public JoinableMonitor join() {
-		log.debug(this + " is joining");
-		Dispatching.joinAbsolutely(joinable);
-		log.debug(this + " is joined");
-		return this;
-	}
-
-	@Override
-	// @SuppressWarnings("NN_NAKED_NOTIFY")
-	public void childChangedState(Joinable joinable, JoinableState state) {
-		synchronized (this) {
-			this.notify();
-		}
-		log.debug(this + " received notification about transition to " + state);
-	}
-
-	@Override
-	public String toString() {
-		return "monitor for " + joinable;
-	}
-
-}
Index: /java/main/src/main/java/com/framsticks/util/dispatching/Monitor.java
===================================================================
--- /java/main/src/main/java/com/framsticks/util/dispatching/Monitor.java	(revision 90)
+++ /java/main/src/main/java/com/framsticks/util/dispatching/Monitor.java	(revision 90)
@@ -0,0 +1,69 @@
+package com.framsticks.util.dispatching;
+
+import org.apache.log4j.Logger;
+// import edu.umd.cs.findbugs.annotations.SuppressWarnings;
+import com.framsticks.util.dispatching.Dispatching;
+
+public class Monitor implements JoinableParent {
+	private static final Logger log =
+		Logger.getLogger(Monitor.class);
+
+	protected final Joinable joinable;
+
+	/**
+	 * @param joinable
+	 */
+	public Monitor(Joinable joinable) {
+		this.joinable = joinable;
+	}
+
+	public Monitor useFor(double seconds) {
+		Dispatching.sleep(seconds);
+		return this;
+	}
+
+	public Monitor waitFor() {
+		log.debug(this + " is waiting");
+		synchronized (this) {
+			while (joinable.getState().ordinal() < JoinableState.FINISHING.ordinal()) {
+				Dispatching.wait(this, 100);
+			}
+		}
+		log.debug(this + " ended waiting");
+		return this;
+	}
+
+	public Monitor use() {
+		log.debug(this + " is using");
+		Dispatching.use(joinable, this);
+		return this;
+	}
+
+	public Monitor drop() {
+		log.debug(this + " is droping");
+		Dispatching.drop(joinable, this);
+		return this;
+	}
+
+	public Monitor join() {
+		log.debug(this + " is joining");
+		Dispatching.joinAbsolutely(joinable);
+		log.debug(this + " is joined");
+		return this;
+	}
+
+	@Override
+	// @SuppressWarnings("NN_NAKED_NOTIFY")
+	public void childChangedState(Joinable joinable, JoinableState state) {
+		synchronized (this) {
+			this.notify();
+		}
+		log.debug(this + " received notification about transition to " + state);
+	}
+
+	@Override
+	public String toString() {
+		return "monitor for " + joinable;
+	}
+
+}
Index: /java/main/src/main/java/com/framsticks/util/dispatching/RunAt.java
===================================================================
--- /java/main/src/main/java/com/framsticks/util/dispatching/RunAt.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/util/dispatching/RunAt.java	(revision 90)
@@ -7,5 +7,5 @@
 
 	public RunAt(Dispatcher<? super C> dispatcher) {
-		dispatcher.invokeLater(this);
+		dispatcher.dispatch(this);
 	}
 }
Index: /java/main/src/main/java/com/framsticks/util/dispatching/Thread.java
===================================================================
--- /java/main/src/main/java/com/framsticks/util/dispatching/Thread.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/util/dispatching/Thread.java	(revision 90)
@@ -6,5 +6,4 @@
 import java.util.ListIterator;
 
-import javax.annotation.OverridingMethodsMustInvokeSuper;
 
 import com.framsticks.params.annotations.ParamAnnotation;
@@ -31,7 +30,4 @@
 	}
 
-	@OverridingMethodsMustInvokeSuper
-	protected void firstTask() {
-	}
 
 	public Thread(java.lang.Thread thread) {
@@ -51,5 +47,4 @@
 	protected void routine() {
 		log.debug("starting thread " + this);
-		firstTask();
 		while (!java.lang.Thread.interrupted()) {
 			Task<? extends C> task;
@@ -78,5 +73,5 @@
 				task.run();
 			} catch (Exception e) {
-				log.error("error in thread: " + e);
+				log.error("error in thread: ", e);
 			}
 		}
@@ -115,5 +110,5 @@
 
 	@Override
-	public void invokeLater(final RunAt<? extends C> runnable) {
+	public void dispatch(final RunAt<? extends C> runnable) {
 		if (!(runnable instanceof Task)) {
 			enqueueTask(new Task<C>() {
Index: /java/main/src/main/java/com/framsticks/util/dispatching/ThrowableHandler.java
===================================================================
--- /java/main/src/main/java/com/framsticks/util/dispatching/ThrowableHandler.java	(revision 90)
+++ /java/main/src/main/java/com/framsticks/util/dispatching/ThrowableHandler.java	(revision 90)
@@ -0,0 +1,5 @@
+package com.framsticks.util.dispatching;
+
+public interface ThrowableHandler<T extends Throwable> {
+	public void handle(T throwable);
+}
Index: /java/main/src/main/java/com/framsticks/util/lang/Containers.java
===================================================================
--- /java/main/src/main/java/com/framsticks/util/lang/Containers.java	(revision 89)
+++ /java/main/src/main/java/com/framsticks/util/lang/Containers.java	(revision 90)
@@ -1,4 +1,5 @@
 package com.framsticks.util.lang;
 
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Iterator;
@@ -8,4 +9,7 @@
 import org.apache.commons.collections.functors.NotPredicate;
 import org.apache.commons.collections.iterators.FilterIterator;
+
+import com.framsticks.util.Builder;
+import com.framsticks.util.FramsticksException;
 
 /**
@@ -37,3 +41,18 @@
 		return new IterableIterator<T>(new FilterIterator(c.iterator(), new NotPredicate(new InstanceofPredicate(type))));
 	}
+
+	public static <T> T getFromList(List<T> list, int number, String name, Object context) {
+		if (number < 0 || number >= list.size()) {
+			throw new FramsticksException().msg("invalid " + name + " number").arg("number", number).arg("in", context);
+		}
+		return list.get(number);
+	}
+
+	public static <T> List<T> build(List<? extends Builder<T>> builders) {
+		List<T> result = new ArrayList<T>();
+		for (Builder<T> builder : builders) {
+			result.add(builder.finish());
+		}
+		return result;
+	}
 }
Index: /java/main/src/main/resources/configs/framsticks.xml
===================================================================
--- /java/main/src/main/resources/configs/framsticks.xml	(revision 89)
+++ /java/main/src/main/resources/configs/framsticks.xml	(revision 90)
@@ -3,9 +3,22 @@
 	<import class="com.framsticks.gui.Browser" />
 	<import class="com.framsticks.remote.RemoteInstance" />
+	<import class="com.framsticks.model.ModelPackage" />
+	<import class="com.framsticks.model.ModelBuilder" />
+	<import class="com.framsticks.model.f0.SchemaBuilder" />
+	<import class="com.framsticks.core.ObjectInstance" />
+	<import class="com.framsticks.test.TestClass" />
 	<Browser>
-		<RemoteInstance name="localhost:9009" address="localhost:9009" />
+		<RemoteInstance name="localhost:9009" address="localhost:9009">
+			<ModelPackage />
+		</RemoteInstance>
+		<ObjectInstance name="model">
+			<ModelBuilder resource="/examples/f0_example.txt" />
+		</ObjectInstance>
+		<ObjectInstance name="f0schema">
+			<SchemaBuilder />
+		</ObjectInstance>
+		<ObjectInstance name="test">
+			<TestClass />
+		</ObjectInstance>
 	</Browser>
-	<!-- <Browser name="other"> -->
-	<!-- 	<RemoteInstance name="localhost:9009" address="localhost:9009" /> -->
-	<!-- </Browser> -->
 </Framsticks>
Index: /java/main/src/main/resources/configs/log4j.properties
===================================================================
--- /java/main/src/main/resources/configs/log4j.properties	(revision 89)
+++ /java/main/src/main/resources/configs/log4j.properties	(revision 90)
@@ -29,4 +29,8 @@
 
 log4j.logger.com.framsticks=INFO
+# log4j.logger.com.framsticks.core.ObjectInstance=DEBUG
+# log4j.logger.com.framsticks.core.Instance=DEBUG
+log4j.logger.com.framsticks.gui.controls.ProcedureControl=DEBUG
+# log4j.logger.com.framsticks.params.ReflectionAccess=TRACE
 # log4j.logger.com.framsticks.util.dispatching.Dispatching=DEBUG
 # log4j.logger.com.framsticks.util.dispatching.AbstractJoinable=DEBUG
Index: /java/main/src/main/resources/examples/f0_example.txt
===================================================================
--- /java/main/src/main/resources/examples/f0_example.txt	(revision 89)
+++ /java/main/src/main/resources/examples/f0_example.txt	(revision 90)
@@ -12,9 +12,9 @@
 n:j=0,d=@:p=0.25
 n:p=1,d=Nu
-#c:0,2
-#c:0,2,5.4
-#c:1,0
-#c:2,0,3.4
-#c:0,1,4.5
-#c:1,0,5.6
-#c:2,1
+c:0,2
+c:0,2,5.4
+c:1,0
+c:2,0,3.4
+c:0,1,4.5
+c:1,0,5.6
+c:2,1
Index: /java/main/src/main/resources/parsers/f0def.xml
===================================================================
--- /java/main/src/main/resources/parsers/f0def.xml	(revision 89)
+++ /java/main/src/main/resources/parsers/f0def.xml	(revision 90)
@@ -11,4 +11,5 @@
   <PROP ID="joints" NAME="joints" GROUP="2" FLAGS="0" TYPE="l Joint" />
   <PROP ID="neurodefs" NAME="neurodefs" GROUP="2" FLAGS="0" TYPE="l NeuroDef" />
+  <PROP ID="neuroconns" NAME="neuroconns" GROUP="2" FLAGS="0" TYPE="l NeuroConn" />
  </CLASS>
 
@@ -158,5 +159,5 @@
   <NEUROPROP ID="noDim" NAME="number of degrees of freedom" TYPE="d" MIN="" MAX="" DEF="" />
   <NEUROPROP ID="params" NAME="parameters" TYPE="s" MIN="" MAX="" DEF="" />
- </NEUROCLASS> 
+ </NEUROCLASS>
 
  <NEUROCLASS ID="Sti" NAME="Sticky [EXPERIMENTAL!]" DESCRIPTION="" INPUTS="1" OUTPUT="0" LOCATION="1"  VISUALHINTS="16"  >
Index: /java/main/src/test/java/com/framsticks/core/ObjectInstanceTest.java
===================================================================
--- /java/main/src/test/java/com/framsticks/core/ObjectInstanceTest.java	(revision 90)
+++ /java/main/src/test/java/com/framsticks/core/ObjectInstanceTest.java	(revision 90)
@@ -0,0 +1,88 @@
+package com.framsticks.core;
+
+import java.util.ArrayList;
+
+import org.testng.annotations.BeforeClass;
+// import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.Test;
+
+import com.framsticks.model.Joint;
+import com.framsticks.model.Model;
+import com.framsticks.model.ModelBuilder;
+import com.framsticks.model.f0.Schema;
+import com.framsticks.model.f0.SchemaBuilder;
+import com.framsticks.test.TestConfiguration;
+import com.framsticks.util.dispatching.Dispatching;
+import com.framsticks.util.dispatching.Monitor;
+import com.framsticks.util.dispatching.RunAt;
+import com.framsticks.params.AccessInterface;
+import com.framsticks.params.ReflectionAccess;
+import com.framsticks.params.types.FloatParam;
+
+import static org.fest.assertions.Assertions.*;
+
+@Test
+public class ObjectInstanceTest extends TestConfiguration {
+
+	private Model model;
+	private Schema schema;
+	private ObjectInstance instance;
+	private Monitor monitor;
+
+	@BeforeClass
+	public void setUp() {
+		schema = new SchemaBuilder().stream(Schema.getDefaultDefinitionAsStream()).finish();
+		assertThat(schema.getFramsClasses().size()).isEqualTo(5);
+		assertThat(schema.getNeuroClasses().size()).isEqualTo(21);
+	}
+
+	@Test
+	public void loadModel() {
+		model = new ModelBuilder().schema(schema).stream(ObjectInstanceTest.class.getResourceAsStream("/parsers/f0_example.txt")).finish();
+
+		assertThat(model.getJoints().size()).isEqualTo(2);
+	}
+
+
+	@Test(dependsOnMethods = "loadModel", timeOut = 2000)
+	public void startInstance() {
+		instance = new ObjectInstance();
+		instance.getRegistry().takeAllFrom(schema.getRegistry());
+
+		instance.setRootObject(model);
+
+		monitor = new Monitor(instance);
+		monitor.use();
+
+		assertThat(Dispatching.get(instance, new Dispatching.Query<String>() {
+				@Override
+				public String get() {
+					return instance.getRootObject(Model.class).getParts().get(2).info;
+				}
+			})).isEqualTo("bla");
+
+		assertDispatch(instance, new RunAt<Instance>() {
+			@Override
+			public void run() {
+				assertThat(instance.getRootObject(Model.class).getNeuroDefinitions().get(2).details).isEqualTo("G");
+
+				Path path = instance.getPath("/");
+				assertThat(path.isResolved());
+				AccessInterface access = instance.bindAccess(path);
+				assertThat(access.get("se", Double.class)).isEqualTo(1.0);
+
+				assertThat(instance.bindAccess("/parts/2").getFramsClass().getParamEntry("m", FloatParam.class).getDef(Double.class)).isEqualTo(1.0);
+				assertThat(instance.bindAccess("/parts/2").getFramsClass().getParamEntry("m", FloatParam.class).getMax(Double.class)).isEqualTo(999.0);
+				assertThat(instance.bindAccess("/parts/2")).isInstanceOf(ReflectionAccess.class);
+				assertThat(instance.getPath("/neurodefs").getTopObject()).isInstanceOf(ArrayList.class);
+				assertThat(instance.getPath("/joints/1").getTopObject()).isInstanceOf(Joint.class);
+				assertThat(instance.bindAccess("/parts/2").get("i", String.class)).isEqualTo("bla");
+			}
+		});
+	}
+
+	@Test(dependsOnMethods = "startInstance", timeOut = 2000)
+	public void stoptInstance() {
+		monitor.useFor(1.0).drop().join();
+	}
+}
Index: /java/main/src/test/java/com/framsticks/gui/BrowserBaseTest.java
===================================================================
--- /java/main/src/test/java/com/framsticks/gui/BrowserBaseTest.java	(revision 90)
+++ /java/main/src/test/java/com/framsticks/gui/BrowserBaseTest.java	(revision 90)
@@ -0,0 +1,78 @@
+package com.framsticks.gui;
+
+import javax.swing.JFrame;
+
+import org.apache.log4j.Logger;
+import org.fest.swing.core.Robot;
+import org.fest.swing.edt.FailOnThreadViolationRepaintManager;
+import org.fest.swing.edt.GuiQuery;
+import org.fest.swing.fixture.FrameFixture;
+import org.fest.swing.fixture.JTreeFixture;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import com.framsticks.test.TestConfiguration;
+import com.framsticks.util.dispatching.Monitor;
+
+import static org.fest.assertions.Assertions.assertThat;
+import static org.fest.swing.edt.GuiActionRunner.executeInEDT;
+import static org.fest.swing.core.BasicRobot.robotWithNewAwtHierarchy;
+import org.fest.swing.edt.GuiActionRunner;
+
+@Test
+public abstract class BrowserBaseTest extends TestConfiguration {
+
+	private static final Logger log = Logger.getLogger(BrowserTest.class);
+
+	protected Monitor monitor;
+	protected Browser browser;
+	protected static Robot robot;
+	protected FrameFixture frame;
+	protected JTreeFixture tree;
+
+	static {
+		FailOnThreadViolationRepaintManager.install();
+		assertThat(executeInEDT()).isTrue();
+
+		robot = robotWithNewAwtHierarchy();
+	}
+
+	@BeforeClass(timeOut = 5000)
+	public void setUp() {
+
+		configureBrowser();
+
+		monitor = new Monitor(browser);
+
+		monitor.use();
+
+		frame = new FrameFixture(robot,
+				GuiActionRunner.execute(new GuiQuery<JFrame>() {
+					@Override
+					protected JFrame executeInEDT() throws Throwable {
+						return browser.getMainFrame().getSwing();
+					}
+				}));
+
+		tree = frame.tree("tree");
+		log.debug("frame fixture done");
+	}
+
+	protected abstract void configureBrowser();
+
+	protected void clickAndExpandPath(String path) {
+		tree.clickPath(path).expandPath(path);
+		robot.waitForIdle();
+	}
+
+	protected void waitForIdle() {
+		robot.waitForIdle();
+	}
+
+	@AfterClass(timeOut = 5000)
+	public void tearDown() {
+		monitor.drop().join();
+	}
+
+}
Index: /java/main/src/test/java/com/framsticks/gui/BrowserTest.java
===================================================================
--- /java/main/src/test/java/com/framsticks/gui/BrowserTest.java	(revision 89)
+++ /java/main/src/test/java/com/framsticks/gui/BrowserTest.java	(revision 90)
@@ -1,75 +1,37 @@
 package com.framsticks.gui;
 
-import javax.swing.JFrame;
+import static org.fest.assertions.Assertions.assertThat;
+import static org.fest.swing.edt.GuiActionRunner.execute;
+
 
 import org.apache.log4j.Logger;
-import org.fest.swing.edt.FailOnThreadViolationRepaintManager;
-import org.fest.swing.edt.GuiActionRunner;
-import org.fest.swing.edt.GuiQuery;
 import org.fest.swing.edt.GuiTask;
-import org.fest.swing.fixture.FrameFixture;
-import org.fest.swing.fixture.JTreeFixture;
-// import static org.fest.swing.edt.GuiActionRunner.*;
-import org.testng.annotations.*;
+import org.testng.annotations.Test;
 
+import com.framsticks.model.ModelPackage;
 import com.framsticks.remote.RemoteInstance;
-import com.framsticks.test.TestConfiguration;
-import com.framsticks.util.dispatching.Dispatching;
-import com.framsticks.util.dispatching.JoinableMonitor;
-// import com.framsticks.util.dispatching.Dispatching;
 
-import static org.fest.assertions.Assertions.*;
-import static org.fest.swing.core.BasicRobot.robotWithNewAwtHierarchy;
-import static org.fest.swing.edt.GuiActionRunner.*;
-import org.fest.swing.core.Robot;
+public class BrowserTest extends BrowserBaseTest {
 
-public class BrowserTest extends TestConfiguration {
 	private static final Logger log = Logger.getLogger(BrowserTest.class);
 
-	JoinableMonitor monitor;
-	Browser browser;
-	Robot robot;
-	FrameFixture frame;
+	RemoteInstance localhost;
 
-	@BeforeClass
-	public void setUp() {
-		FailOnThreadViolationRepaintManager.install();
-		assertThat(executeInEDT()).isTrue();
+	@Override
+	protected void configureBrowser() {
+		browser = new Browser();
 
-		robot = robotWithNewAwtHierarchy();
-
-		browser = new Browser();
-		monitor = new JoinableMonitor(browser);
-
-		RemoteInstance localhost = new RemoteInstance();
+		localhost = new RemoteInstance();
 		localhost.setName("localhost");
 		localhost.setAddress("localhost:9009");
+		localhost.usePackage(new ModelPackage());
 
 		browser.addInstance(localhost);
 
-		monitor.use();
-		// robot.waitForIdle();
-		frame = new FrameFixture(robot,
-				GuiActionRunner.execute(new GuiQuery<JFrame>() {
-					@Override
-					protected JFrame executeInEDT() throws Throwable {
-						return browser.getMainFrame().getSwing();
-					}
-				}));
-
-		log.info("frame fixture done");
-		// frame.show();
-		// log.info("frame fixture shown");
 	}
 
-	public void clickAndExpandPath(JTreeFixture tree, String path) {
-		tree.clickPath(path).expandPath(path);
-		robot.waitForIdle();
-	}
-
-	@Test
+	@Test(timeOut = 10000)
 	public void testShow() {
 		log.info("testing");
-		JTreeFixture tree = frame.tree("tree");
 		tree.clickRow(0).expandRow(0);
 		robot.waitForIdle();
@@ -81,54 +43,14 @@
 			@Override
 			protected void executeInEDT() throws Throwable {
-				assertThat(frame.panel("o Simulator").component().isVisible())
-						.isTrue();
+				assertThat(frame.panel("Simulator").component().isVisible()).isTrue();
 			}
 		});
 
-		clickAndExpandPath(tree, "localhost/simulator/genepools");
-		clickAndExpandPath(tree, "localhost/simulator/genepools/groups");
-		clickAndExpandPath(tree, "localhost/simulator/genepools/groups/Genotypes");
+		clickAndExpandPath("localhost/simulator/genepools");
+		clickAndExpandPath("localhost/simulator/genepools/groups");
+		clickAndExpandPath("localhost/simulator/genepools/groups/Genotypes");
+	}
 
 
 
-
-
-
-		// tree.clickPath("localhost/simulator/genepools/groups/Genotypes/genotypes");
-		// robot.waitForIdle();
-		// sleep(2);
-		// tree.expandPath("localhost/simulator/genepools/groups/Genotypes/genotypes");
-
-		// tree.expandRow(tree.component().getLeadSelectionRow() + 1);
-		// robot.waitForIdle();
-
-		// sleep(2);
-	}
-
-
-	@AfterClass
-	public void tearDown() {
-		log.info("before close");
-
-		monitor.drop();
-
-		Dispatching.joinAbsolutely(browser);
-		// frame.cleanUp();
-		// log.info("before close");
-		// browser.interrupt();
-
-		// try {
-		// 	// frame.close();
-		// } catch (Throwable t) {
-		// 	log.error("caught ", t);
-		// }
-		// log.info("after close");
-		// // frame.close();
-		// // frame.cleanUp();
-
-
-
-		// Dispatching.join(browser);
-	}
-
 }
Index: /java/main/src/test/java/com/framsticks/gui/ObjectInstanceBrowserTest.java
===================================================================
--- /java/main/src/test/java/com/framsticks/gui/ObjectInstanceBrowserTest.java	(revision 90)
+++ /java/main/src/test/java/com/framsticks/gui/ObjectInstanceBrowserTest.java	(revision 90)
@@ -0,0 +1,52 @@
+package com.framsticks.gui;
+
+import static org.fest.assertions.Assertions.assertThat;
+
+import org.testng.annotations.Test;
+
+import com.framsticks.core.Instance;
+import com.framsticks.core.ObjectInstance;
+import com.framsticks.model.Model;
+import com.framsticks.params.types.FloatParam;
+import com.framsticks.parsers.XmlLoader;
+import com.framsticks.util.dispatching.RunAt;
+
+@Test
+public class ObjectInstanceBrowserTest extends BrowserBaseTest {
+
+	ObjectInstance instance;
+
+	@Override
+	protected void configureBrowser() {
+		browser = new XmlLoader().load(Browser.class, getClass().getResourceAsStream("/configs/ObjectInstanceBrowserTest.xml"));
+
+		assertThat(browser.getInstances().size()).isEqualTo(1);
+		assertThat(browser.getInstances().get("model")).isInstanceOf(ObjectInstance.class);
+
+		instance = (ObjectInstance) browser.getInstances().get("model");
+	}
+
+	@Test(timeOut = 10000)
+	public void testShow() {
+		assertDispatch(instance, new RunAt<Instance>() {
+			@Override
+			public void run() {
+				assertThat(instance.getRootObject()).isInstanceOf(Model.class);
+			}
+		});
+
+		clickAndExpandPath("model");
+		clickAndExpandPath("model/parts");
+		clickAndExpandPath("model/parts/2");
+
+		assertDispatch(instance, new RunAt<Instance>() {
+			@Override
+			public void run() {
+				assertThat(instance.bindAccess("/parts/2").getFramsClass().getParamEntry("m", FloatParam.class).getMax(Double.class)).isEqualTo(999.0);
+			}
+		});
+
+	}
+
+
+}
Index: /java/main/src/test/java/com/framsticks/gui/ProcedureBrowserTest.java
===================================================================
--- /java/main/src/test/java/com/framsticks/gui/ProcedureBrowserTest.java	(revision 90)
+++ /java/main/src/test/java/com/framsticks/gui/ProcedureBrowserTest.java	(revision 90)
@@ -0,0 +1,93 @@
+
+package com.framsticks.gui;
+
+import static org.fest.assertions.Assertions.assertThat;
+
+import org.fest.swing.fixture.JPanelFixture;
+import org.testng.annotations.Test;
+
+import com.framsticks.core.Instance;
+import com.framsticks.core.ObjectInstance;
+import com.framsticks.params.AccessInterface;
+import com.framsticks.params.FramsClass;
+import com.framsticks.params.ReflectionAccess;
+import com.framsticks.params.types.StringParam;
+import com.framsticks.parsers.XmlLoader;
+import com.framsticks.test.TestClass;
+import com.framsticks.util.dispatching.RunAt;
+
+@Test
+public class ProcedureBrowserTest extends BrowserBaseTest {
+
+	ObjectInstance instance;
+
+	@Override
+	protected void configureBrowser() {
+		browser = new XmlLoader().load(Browser.class, getClass().getResourceAsStream("/configs/ProcedureBrowserTest.xml"));
+
+		assertThat(browser.getInstances().size()).isEqualTo(1);
+		assertThat(browser.getInstances().get("test")).isInstanceOf(ObjectInstance.class);
+
+		instance = (ObjectInstance) browser.getInstances().get("test");
+	}
+
+	@Test(timeOut = 10000)
+	public void testShow() {
+		assertDispatch(instance, new RunAt<Instance>() {
+			@Override
+			public void run() {
+				assertThat(instance.getRootObject()).isInstanceOf(TestClass.class);
+			}
+		});
+
+		clickAndExpandPath("test");
+
+		assertDispatch(instance, new RunAt<Instance>() {
+			@Override
+			public void run() {
+				assertThat(instance.bindAccess("/").getFramsClass().getParam("history")).isInstanceOf(StringParam.class);
+			}
+		});
+
+		// monitor.useFor(4.0);
+
+		assertDispatch(instance, new RunAt<Instance>() {
+			@Override
+			public void run() {
+				AccessInterface access = instance.bindAccess("/");
+				assertThat(access).isInstanceOf(ReflectionAccess.class);
+				FramsClass framsClass = access.getFramsClass();
+				assertThat(framsClass.getParamCount()).isEqualTo(4);
+				assertThat(framsClass.getParam(0).getId()).isEqualTo("name");
+				assertThat(framsClass.getParam(1).getId()).isEqualTo("history");
+				assertThat(framsClass.getParam(2).getId()).isEqualTo("appendHistory");
+				assertThat(framsClass.getParam(3).getId()).isEqualTo("resetHistory");
+
+				assertThat(access.get("history", String.class)).isEqualTo("");
+			}
+		});
+
+		// frame.panel("TestClass");
+		JPanelFixture appendHistory = frame.panel("TestClass").panel("appendHistory");
+		appendHistory.panel("arg0").textBox("value").enterText("argument");
+		appendHistory.button("call").click();
+		waitForIdle();
+
+		assertDispatch(instance, new RunAt<Instance>() {
+			@Override
+			public void run() {
+				assertThat(instance.bindAccess("/").get("history", String.class)).isEqualTo("argument|");
+			}
+		});
+
+		frame.panel("TestClass").panel("resetHistory").button("call").click();
+		waitForIdle();
+
+		assertDispatch(instance, new RunAt<Instance>() {
+			@Override
+			public void run() {
+				assertThat(instance.bindAccess("/").get("history", String.class)).isEqualTo("");
+			}
+		});
+	}
+}
Index: /java/main/src/test/java/com/framsticks/model/ModelPackageTest.java
===================================================================
--- /java/main/src/test/java/com/framsticks/model/ModelPackageTest.java	(revision 90)
+++ /java/main/src/test/java/com/framsticks/model/ModelPackageTest.java	(revision 90)
@@ -0,0 +1,66 @@
+package com.framsticks.model;
+
+import java.io.InputStream;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import com.framsticks.params.FramsClass;
+import com.framsticks.params.ReflectionAccess;
+import com.framsticks.params.SourceInterface;
+import com.framsticks.params.ValueParam;
+import com.framsticks.parsers.FileSource;
+import com.framsticks.parsers.Loaders;
+import com.framsticks.test.TestConfiguration;
+
+import static org.fest.assertions.Assertions.*;
+
+@Test
+public class ModelPackageTest extends TestConfiguration {
+
+	@Test(dataProvider = "classesList")
+	public void testFramsClass(Class<?> javaClass, String name, int paramCount, Object[][] paramsTests) throws InstantiationException, IllegalAccessException {
+		// log.info("testing " + name + " " + javaClass + " " + Package.class.getResource(filename));
+		String filename = "/info/" + name + ".info";
+		InputStream stream = ModelPackage.class.getResourceAsStream(filename);
+		assertThat(stream).describedAs("stream " + filename).isNotNull();
+
+		SourceInterface source = new FileSource(stream, filename);
+
+		assertThat(source.isClosed()).isFalse();
+		FramsClass framsClass = Loaders.loadFramsClass(source);
+		assertThat(framsClass).isNotNull();
+
+		assertThat(framsClass.getParamCount()).isEqualTo(paramCount);
+		ReflectionAccess access = new ReflectionAccess(javaClass, framsClass);
+		Object object = javaClass.newInstance();
+		access.select(object);
+
+		if (paramsTests != null) {
+			for (Object[] args : paramsTests) {
+				String paramName = (String )args[0];
+				Object defaultValue = args[1];
+
+				ValueParam param = framsClass.getParamEntry(paramName, ValueParam.class);
+				assertThat(param.getDef(Object.class)).isEqualTo(defaultValue);
+
+			}
+		}
+	}
+
+	@DataProvider
+	public Object[][] classesList() {
+		return new Object[][] {
+			{ MechPart.class, "MechPart", 20 , null},
+			{ Joint.class, "Joint", 16 , null},
+			{ MechJoint.class, "MechJoint", 10 , null},
+			{ Neuro.class, "Neuro", 21, null},
+			{ NeuroDefinition.class, "NeuroDef", 9, null},
+			{ Part.class, "Part", 18, new Object[][] {{"m", 1.0}}},
+			// { Model.class, "Model", null},
+			{ Creature.class, "Creature", 64, null},
+			{ Genotype.class, "Genotype", 37, null},
+			{ World.class, "World", 10, null}
+		};
+	}
+}
Index: va/main/src/test/java/com/framsticks/model/PackageTest.java
===================================================================
--- /java/main/src/test/java/com/framsticks/model/PackageTest.java	(revision 89)
+++ 	(revision )
@@ -1,54 +1,0 @@
-package com.framsticks.model;
-
-import java.io.InputStream;
-
-import org.testng.annotations.DataProvider;
-import org.testng.annotations.Test;
-
-import com.framsticks.params.FramsClass;
-import com.framsticks.params.ReflectionAccess;
-import com.framsticks.params.SourceInterface;
-import com.framsticks.parsers.FileSource;
-import com.framsticks.parsers.Loaders;
-import com.framsticks.test.TestConfiguration;
-
-import static org.fest.assertions.Assertions.*;
-
-@Test
-public class PackageTest extends TestConfiguration {
-
-	@Test(dataProvider = "classesList")
-	public void testFramsClass(Class<?> javaClass, String name, int paramCount) throws InstantiationException, IllegalAccessException {
-		// log.info("testing " + name + " " + javaClass + " " + Package.class.getResource(filename));
-		String filename = "/info/" + name + ".info";
-		InputStream stream = Package.class.getResourceAsStream(filename);
-		assertThat(stream).describedAs("stream " + filename).isNotNull();
-
-		SourceInterface source = new FileSource(stream, filename);
-
-		assertThat(source.isClosed()).isFalse();
-		FramsClass framsClass = Loaders.loadFramsClass(source);
-		assertThat(framsClass).isNotNull();
-
-		assertThat(framsClass.getParamCount()).isEqualTo(paramCount);
-		ReflectionAccess access = new ReflectionAccess(javaClass, framsClass);
-		Object object = javaClass.newInstance();
-		access.select(object);
-	}
-
-	@DataProvider
-	public Object[][] classesList() {
-		return new Object[][] {
-			{ MechPart.class, "MechPart", 20 },
-			{ Joint.class, "Joint", 16 },
-			{ MechJoint.class, "MechJoint", 10 },
-			{ Neuro.class, "Neuro", 21},
-			{ NeuroDef.class, "NeuroDef", 9},
-			{ Part.class, "Part", 18},
-			// { Model.class, "Model" },
-			{ Creature.class, "Creature", 64 },
-			{ Genotype.class, "Genotype", 37 },
-			{ World.class, "World", 10 }
-		};
-	}
-}
Index: /java/main/src/test/java/com/framsticks/model/f0/SchemaTest.java
===================================================================
--- /java/main/src/test/java/com/framsticks/model/f0/SchemaTest.java	(revision 89)
+++ /java/main/src/test/java/com/framsticks/model/f0/SchemaTest.java	(revision 90)
@@ -3,4 +3,5 @@
 import org.testng.annotations.*;
 
+import com.framsticks.params.FramsClass;
 import com.framsticks.params.types.FloatParam;
 import com.framsticks.test.TestConfiguration;
@@ -15,5 +16,5 @@
 	@Test
 	public void loadSchemaWithXmlLoader() {
-		Schema schema = Schema.load(Schema.getDefaultDefinitionAsStream());
+		Schema schema = new SchemaBuilder().stream(Schema.getDefaultDefinitionAsStream()).finish();
 		assertThat(schema.getFramsClasses().size()).isEqualTo(5);
 		assertThat(schema.getNeuroClasses().size()).isEqualTo(21);
@@ -23,5 +24,11 @@
 		assertThat(schema.getNeuroClass("VEye").getParamEntry("p", FloatParam.class).getMax(Double.class)).isEqualTo(10.0, delta(0.0));
 
-		assertThat(schema.getFramsClass("p").getParamEntry("as", FloatParam.class).getDef(Double.class)).isEqualTo(0.25, delta(0.0));
+		FramsClass partClass = schema.getFramsClass("p");
+		assertThat(partClass).isNotNull();
+		assertThat(partClass.getParamEntry("as", FloatParam.class).getDef(Double.class)).isEqualTo(0.25, delta(0.0));
+		assertThat(partClass.getGroupCount()).isEqualTo(3);
+		assertThat(partClass.getGroup(1).getName()).isEqualTo("Other properties");
+		assertThat(partClass.getGroup(1).getCount()).isEqualTo(7);
+		assertThat(partClass.getGroup(1).getParam(2)).isEqualTo(partClass.getParam("dn"));
 	}
 
Index: /java/main/src/test/java/com/framsticks/params/FramsClassBuilderTest.java
===================================================================
--- /java/main/src/test/java/com/framsticks/params/FramsClassBuilderTest.java	(revision 90)
+++ /java/main/src/test/java/com/framsticks/params/FramsClassBuilderTest.java	(revision 90)
@@ -0,0 +1,63 @@
+package com.framsticks.params;
+
+
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+import com.framsticks.params.types.ProcedureParam;
+import com.framsticks.params.types.StringParam;
+import com.framsticks.test.TestClass;
+import com.framsticks.test.TestConfiguration;
+import static org.fest.assertions.Assertions.*;
+
+@Test
+public class FramsClassBuilderTest extends TestConfiguration {
+
+	FramsClass framsClass;
+	ReflectionAccess access;
+	TestClass test;
+
+
+	@BeforeClass
+	public void setUp() {
+		test = new TestClass();
+		test.setName("test");
+		test.appendHistory("first");
+		framsClass = FramsClass.build().forClass(TestClass.class);
+	}
+
+	@Test
+	public void checkProcedureParams() {
+		assertThat(framsClass.getParamCount()).isEqualTo(4);
+
+		assertThat(framsClass.getParam("name")).isInstanceOf(StringParam.class);
+		assertThat(framsClass.getParam("history")).isInstanceOf(StringParam.class);
+
+		assertThat(framsClass.getParam("appendHistory")).isInstanceOf(ProcedureParam.class);
+		assertThat(framsClass.getParam("resetHistory")).isInstanceOf(ProcedureParam.class);
+		ProcedureParam appendHistory = framsClass.getParamEntry("appendHistory", ProcedureParam.class);
+		assertThat(appendHistory.getArgumentsType().size()).isEqualTo(1);
+		assertThat(appendHistory.getArgumentsType().get(0).getId()).isEqualTo("arg0");
+	}
+
+	@Test(dependsOnMethods = "checkProcedureParams")
+	public void callProcedures() {
+		access = new ReflectionAccess(TestClass.class, framsClass);
+
+		access.select(test);
+
+		assertThat(access.get("history", String.class)).isEqualTo("first|");
+		Object result = access.call("appendHistory", new Object[] {"second"});
+
+		assertThat(result).isInstanceOf(Integer.class);
+		assertThat(result).isEqualTo(13);
+		assertThat(access.get("history", String.class)).isEqualTo("first|second|");
+
+		result = access.call("resetHistory", null);
+		assertThat(result).isNull();
+
+		assertThat(access.get("history", String.class)).isEqualTo("");
+
+	}
+
+}
Index: /java/main/src/test/java/com/framsticks/parsers/F0ParserTest.java
===================================================================
--- /java/main/src/test/java/com/framsticks/parsers/F0ParserTest.java	(revision 89)
+++ /java/main/src/test/java/com/framsticks/parsers/F0ParserTest.java	(revision 90)
@@ -4,6 +4,6 @@
 
 import com.framsticks.model.*;
-import com.framsticks.model.Package;
 import com.framsticks.model.f0.Schema;
+import com.framsticks.model.f0.SchemaBuilder;
 import com.framsticks.params.*;
 import com.framsticks.params.types.FloatParam;
@@ -25,14 +25,25 @@
 	private Schema schema;
 	private List<AccessInterface> accesses;
-	private List<Object> objects;
+	private List<ModelComponent> components;
 	private Model model;
 
 	@BeforeClass
 	public void setUp() throws Exception {
-		schema = Schema.load(Schema.getDefaultDefinitionAsStream());
-		Package.register(schema.getRegistry());
+		schema = new SchemaBuilder().stream(Schema.getDefaultDefinitionAsStream()).finish();
 	}
 
 	@Test
+	public void checkFramsClasses() {
+		FramsClass modelClass = schema.getRegistry().getFramsClass("Model");
+		assertThat(modelClass).isNotNull();
+		assertThat(modelClass.getParam("se")).isInstanceOf(FloatParam.class);
+		// assertThat(modelClass.getParam("energ0")).isInstanceOf(FloatParam.class);
+		assertThat(modelClass.getParam("Vstyle")).isInstanceOf(StringParam.class);
+		assertThat(modelClass.getParamCount()).isEqualTo(6);
+		// assertThat();
+
+	}
+
+	@Test(dependsOnMethods = "checkFramsClasses")
 	public void primitiveParam() {
 		FramsClass joint = schema.getFramsClass("j");
@@ -43,15 +54,15 @@
 		assertThat(dx.getMin(Double.class)).isEqualTo(-2.0, delta(0.0));
 
-		assertThat(schema.getRegistry().getInfoFromCache("n").getParamEntry("d", StringParam.class).getDef(String.class)).isEqualTo("N");
+		assertThat(schema.getRegistry().getFramsClass("n").getParamEntry("d", StringParam.class).getDef(String.class)).isEqualTo("N");
 	}
 
-	@Test
+	@Test(dependsOnMethods = "primitiveParam")
 	public void readF0() throws IOException, ParseException {
 		assertThat(schema.getFramsClass("p")).isInstanceOf(FramsClass.class);
-		assertThat(schema.getRegistry().getInfoFromCache("p").getParamEntry("as", FloatParam.class).getDef(Double.class)).isEqualTo(0.25, delta(0.0));
+		assertThat(schema.getRegistry().getFramsClass("p").getParamEntry("as", FloatParam.class).getDef(Double.class)).isEqualTo(0.25, delta(0.0));
 
 		accesses = new F0Parser(schema, F0ParserTest.class.getResourceAsStream("/parsers/f0_example.txt")).parse();
 
-		assertThat(accesses.size()).isEqualTo(12);
+		assertThat(accesses.size()).isEqualTo(19);
 		assertThat(accesses.get(0).getSelected()).isInstanceOf(Model.class);
 		assertThat(accesses.get(5).get("i", String.class)).isEqualTo("1,2,3,\"dsadsa,,,,");
@@ -62,31 +73,37 @@
 	@Test(dependsOnMethods = {"readF0"})
 	public void stripAccessInterface() {
-		objects = Util.stripAccessInterface(accesses);
+		components = Util.stripAccessInterface(accesses, ModelComponent.class);
 
-		assertThat(objects.get(1)).isInstanceOf(Part.class);
-		assertThat(objects.get(4)).isInstanceOf(Joint.class);
-		assertThat(objects.get(6)).isInstanceOf(NeuroDef.class);
+		assertThat(components.get(1)).isInstanceOf(Part.class);
+		assertThat(components.get(4)).isInstanceOf(Joint.class);
+		assertThat(components.get(6)).isInstanceOf(NeuroDefinition.class);
+		assertThat(components.get(12)).isInstanceOf(NeuroConnection.class);
 	}
 
 	@Test(dependsOnMethods = {"stripAccessInterface"})
 	public void buildModel() {
-		model = Model.build(objects);
+		model = new ModelBuilder().addComponents(components).finish();
 
 		assertThat(model.getParts().size()).isEqualTo(3);
-		assertThat(model.getNeuroDefs().size()).isEqualTo(6);
+		assertThat(model.getNeuroDefinitions().size()).isEqualTo(6);
 		assertThat(model.getJoints().size()).isEqualTo(2);
-
-		assertThat(model.getJoints().get(0).part1).isEqualTo(0);
-		assertThat(model.getJoints().get(0).part2).isEqualTo(1);
-		assertThat(model.getNeuroDefs().size()).isEqualTo(6);
-		assertThat(model.getNeuroDefs().get(0).part).isEqualTo(1);
-		assertThat(model.getNeuroDefs().get(0).joint).isEqualTo(-1);
-		assertThat(model.getNeuroDefs().get(1).details).isEqualTo("|:p=0.25,r=1");
-		assertThat(model.getNeuroDefs().get(3).details).isEqualTo("N");
-		assertThat(model.getNeuroDefs().get(4).part).isEqualTo(-1);
+		assertThat(model.getNeuroConnections().size()).isEqualTo(7);
 
 		assertThat(model.getParts().get(1).getPosition().x).isEqualTo(2.0, delta(0.0));
 		assertThat(model.getParts().get(2).getPosition().sub(new Point3d(2.27236, -0.0792596, -0.958924)).length()).isLessThan(0.0001);
 		assertThat(model.getParts().get(2).getOrientation().y.sub(new Point3d(0.870277, -0.404792, 0.280644)).length()).isLessThan(0.0001);
+
+		assertThat(model.getJoints().get(0).part1).isEqualTo(0);
+		assertThat(model.getJoints().get(0).part2).isEqualTo(1);
+
+		assertThat(model.getNeuroDefinitions().get(0).part).isEqualTo(1);
+		assertThat(model.getNeuroDefinitions().get(0).joint).isEqualTo(-1);
+		assertThat(model.getNeuroDefinitions().get(1).details).isEqualTo("|:p=0.25,r=1");
+		assertThat(model.getNeuroDefinitions().get(3).details).isEqualTo("N");
+		assertThat(model.getNeuroDefinitions().get(4).part).isEqualTo(-1);
+
+		assertThat(model.getNeuroConnections().get(2).connectedNeuro).isEqualTo(0);
+		assertThat(model.getNeuroConnections().get(5).weight).isEqualTo(5.6, delta(0.0));
+
 	}
 
@@ -94,5 +111,4 @@
 	public void print() throws Exception {
 		ListSink sink = new ListSink();
-
 
 		new F0Writer(schema, model, sink).write();
@@ -110,4 +126,11 @@
 			"n:j=0,d=@:p=0.25",
 			"n:p=1,d=Nu",
+			"c:0,2",
+			"c:0,2,5.4",
+			"c:1,0",
+			"c:2,0,3.4",
+			"c:0,1,4.5",
+			"c:1,0,5.6",
+			"c:2,1",
 			"m:"
 		);
Index: /java/main/src/test/java/com/framsticks/running/ExternalProcessTest.java
===================================================================
--- /java/main/src/test/java/com/framsticks/running/ExternalProcessTest.java	(revision 89)
+++ /java/main/src/test/java/com/framsticks/running/ExternalProcessTest.java	(revision 90)
@@ -10,5 +10,5 @@
 
 import com.framsticks.test.TestConfiguration;
-import com.framsticks.util.dispatching.JoinableMonitor;
+import com.framsticks.util.dispatching.Monitor;
 
 import static org.fest.assertions.Assertions.*;
@@ -17,5 +17,5 @@
 public class ExternalProcessTest extends TestConfiguration {
 
-	@Test
+	@Test(timeOut = 1000)
 	public void runBash() throws InterruptedException {
 		final ExternalProcess process = new ExternalProcess();
@@ -31,5 +31,5 @@
 			}
 		});
-		JoinableMonitor monitor = new JoinableMonitor(process);
+		Monitor monitor = new Monitor(process);
 		monitor.use();
 
Index: /java/main/src/test/java/com/framsticks/running/FramsServerTest.java
===================================================================
--- /java/main/src/test/java/com/framsticks/running/FramsServerTest.java	(revision 89)
+++ /java/main/src/test/java/com/framsticks/running/FramsServerTest.java	(revision 90)
@@ -4,6 +4,6 @@
 
 import com.framsticks.core.Framsticks;
-import com.framsticks.remote.RemoteInstance;
 import com.framsticks.test.TestConfiguration;
+import com.framsticks.util.dispatching.Monitor;
 
 import static org.fest.assertions.Assertions.*;
@@ -12,11 +12,21 @@
 public class FramsServerTest extends TestConfiguration {
 
-	@Test
+	@Test(timeOut = 3000)
 	public void runServer() {
 		Framsticks framsticks = Framsticks.loadConfiguration(FramsServerTest.class.getResourceAsStream("/configs/FramsServerTest.xml"));
 
-		assertThat(framsticks.getObservables().size()).isEqualTo(2);
+		assertThat(framsticks.getObservables().size()).isEqualTo(1);
 		assertThat(framsticks.getObservables().get("frams")).isInstanceOf(FramsServer.class);
-		assertThat(framsticks.getObservables().get("remote")).isInstanceOf(RemoteInstance.class);
+		// assertThat(framsticks.getObservables().get("remote")).isInstanceOf(RemoteInstance.class);
+
+		new Monitor(framsticks).use().useFor(1.0).drop().join();
+
+		// monitor.use();
+
+		// Dispatching.sleep(1000);
+
+		// // monitor.waitFor();
+		// monitor.drop();
+		// monitor.join();
 
 		// framsticks.start();
Index: /java/main/src/test/java/com/framsticks/test/TestClass.java
===================================================================
--- /java/main/src/test/java/com/framsticks/test/TestClass.java	(revision 90)
+++ /java/main/src/test/java/com/framsticks/test/TestClass.java	(revision 90)
@@ -0,0 +1,56 @@
+package com.framsticks.test;
+
+import com.framsticks.params.annotations.FramsClassAnnotation;
+import com.framsticks.params.annotations.ParamAnnotation;
+import com.framsticks.params.types.ProcedureParam;
+
+@FramsClassAnnotation(order = {"name", "history", "appendHistory", "resetHistory"})
+public class TestClass {
+
+	protected String name = "test";
+	protected String history = "";
+
+	/**
+	 * @return the name
+	 */
+	@ParamAnnotation
+	public String getName() {
+		return name;
+	}
+
+	/**
+	 * @param name the name to set
+	 */
+	@ParamAnnotation
+	public void setName(String name) {
+		this.name = name;
+	}
+
+	/**
+	 * @return the history
+	 */
+	@ParamAnnotation
+	public String getHistory() {
+		return history;
+	}
+
+	/**
+	 * @param history the history to set
+	 */
+	@ParamAnnotation
+	public void setHistory(String history) {
+		this.history = history;
+	}
+
+	@ParamAnnotation(paramType = ProcedureParam.class)
+	public int appendHistory(String line) {
+		history = history + line + "|";
+		return history.length();
+	}
+
+	@ParamAnnotation(paramType = ProcedureParam.class)
+	public void resetHistory() {
+		history = "";
+	}
+
+}
Index: /java/main/src/test/java/com/framsticks/test/TestConfiguration.java
===================================================================
--- /java/main/src/test/java/com/framsticks/test/TestConfiguration.java	(revision 89)
+++ /java/main/src/test/java/com/framsticks/test/TestConfiguration.java	(revision 90)
@@ -1,3 +1,6 @@
 package com.framsticks.test;
+
+import java.util.LinkedList;
+import java.util.List;
 
 import org.apache.log4j.Logger;
@@ -5,8 +8,10 @@
 import org.testng.annotations.*;
 
+import com.framsticks.util.dispatching.Dispatcher;
+import com.framsticks.util.dispatching.RunAt;
+
 public class TestConfiguration {
 
-	private static final Logger log =
-		Logger.getLogger(TestConfiguration.class);
+	private static final Logger log = Logger.getLogger(TestConfiguration.class);
 
 	@BeforeClass
@@ -16,3 +21,70 @@
 	}
 
+	private final List<AsyncAssert<?>> asyncAssertions = new LinkedList<AsyncAssert<?>>();
+
+	public class AsyncAssert<C> extends RunAt<C> {
+		final RunAt<? extends C> runnable;
+		boolean done = false;
+		AssertionError assertion;
+
+		/**
+		 * @param runnable
+		 */
+		public AsyncAssert(RunAt<? extends C> runnable) {
+			this.runnable = runnable;
+		}
+
+		@Override
+		public void run() {
+			try {
+				runnable.run();
+			} catch (AssertionError e) {
+				assertion = e;
+			}
+			synchronized (this) {
+				done = true;
+				this.notifyAll();
+			}
+		}
+	}
+
+	public <C> void assertDispatch(Dispatcher<C> dispatcher, RunAt<? extends C> runnable) {
+		AsyncAssert<C> assertion = new AsyncAssert<C>(runnable);
+		synchronized (asyncAssertions) {
+			asyncAssertions.add(assertion);
+		}
+		dispatcher.dispatch(assertion);
+	}
+
+	@BeforeMethod
+	public void clearAsyncAsserts() {
+		synchronized (asyncAssertions) {
+			asyncAssertions.clear();
+		}
+	}
+
+	@AfterMethod(timeOut = 5000)
+	public void waitForAsyncAsserts() {
+		while (true) {
+			AsyncAssert<?> assertion;
+			synchronized (asyncAssertions) {
+				if (asyncAssertions.isEmpty()) {
+					return;
+				}
+				assertion = asyncAssertions.get(0);
+				asyncAssertions.remove(0);
+			}
+			synchronized (assertion) {
+				while (!assertion.done) {
+					try {
+						assertion.wait();
+					} catch (InterruptedException ignored) {
+					}
+				}
+				if (assertion.assertion != null) {
+					throw assertion.assertion;
+				}
+			}
+		}
+	}
 }
Index: /java/main/src/test/resources/configs/FramsServerTest.xml
===================================================================
--- /java/main/src/test/resources/configs/FramsServerTest.xml	(revision 89)
+++ /java/main/src/test/resources/configs/FramsServerTest.xml	(revision 90)
@@ -3,5 +3,8 @@
 	<import class="com.framsticks.running.FramsServer" />
 	<import class="com.framsticks.remote.RemoteInstance" />
-	<FramsServer name="frams" port="9008" />
-	<RemoteInstance name="remote" address="localhost:9008" />
+	<import class="com.framsticks.running.LoggingOutputListener" />
+	<FramsServer name="frams" port="9008">
+		<LoggingOutputListener />
+	</FramsServer>
+	<!-- <RemoteInstance name="remote" address="localhost:9008" /> -->
 </Framsticks>
Index: /java/main/src/test/resources/configs/ObjectInstanceBrowserTest.xml
===================================================================
--- /java/main/src/test/resources/configs/ObjectInstanceBrowserTest.xml	(revision 90)
+++ /java/main/src/test/resources/configs/ObjectInstanceBrowserTest.xml	(revision 90)
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Browser>
+	<import class="com.framsticks.model.ModelBuilder" />
+	<import class="com.framsticks.core.ObjectInstance" />
+	<import class="com.framsticks.model.ModelPackage" />
+	<ObjectInstance name="model">
+		<ModelBuilder resource="/examples/f0_example.txt" />
+	</ObjectInstance>
+</Browser>
Index: /java/main/src/test/resources/configs/ProcedureBrowserTest.xml
===================================================================
--- /java/main/src/test/resources/configs/ProcedureBrowserTest.xml	(revision 90)
+++ /java/main/src/test/resources/configs/ProcedureBrowserTest.xml	(revision 90)
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<Browser>
+	<import class="com.framsticks.core.ObjectInstance" />
+	<import class="com.framsticks.test.TestClass" />
+	<ObjectInstance name="test">
+		<TestClass />
+	</ObjectInstance>
+</Browser>
Index: /java/main/src/test/resources/info/Part.info
===================================================================
--- /java/main/src/test/resources/info/Part.info	(revision 89)
+++ /java/main/src/test/resources/info/Part.info	(revision 90)
@@ -3,109 +3,98 @@
 
 prop:
+id:x
 name:position.x
-id:x
 type:f
 flags:1024
 
 prop:
+id:y
 name:position.y
-id:y
 type:f
 flags:1024
 
 prop:
+id:z
 name:position.z
-id:z
 type:f
 flags:1024
 
 prop:
+id:m
 name:mass
-id:m
-type:f
-flags:0
+type:f 0.1 999.0 1.0
 
 prop:
+id:s
 name:size
-id:s
-type:f
-flags:0
+type:f 0.1 10.0 1.0
 
 prop:
+id:dn
 name:density
-id:dn
-type:f
-flags:0
+type:f 0.2 5.0 1.0
 
 prop:
+id:fr
 name:friction
-id:fr
-type:f
-flags:0
+type:f 0.0 4.0 0.4
 
 prop:
+id:ing
 name:ingestion
-id:ing
-type:f
-flags:0
+type:f 0.0 1.0 0.25
 
 prop:
+id:as
 name:assimilation
-id:as
-type:f
-flags:0
+type:f 0.0 1.0 0.25
 
 prop:
+id:rx
 name:rot.x
-id:rx
 type:f
-flags:0
 
 prop:
+id:ry
 name:rot.y
-id:ry
 type:f
 flags:1024
 
 prop:
+id:rz
 name:rot.z
-id:rz
 type:f
 flags:1024
 
 prop:
+id:i
 name:info
-id:i
 type:s
-flags:0
 
 prop:
+id:Vstyle
 name:vis_style
-id:Vstyle
-type:s
-flags:0
+type:s 0 -1 part
 
 prop:
+id:vs
 name:visual thickness
-id:vs
-type:f
-flags:0
+type:f 0.05 0.7 0.3
 
 prop:
+id:vr
 name:red component
-id:vr
-type:f
-flags:0
+type:f 0.0 1.0 0.5
 
 prop:
+id:vg
 name:green component
-id:vg
-type:f
+type:f 0.0 1.0 0.5
 flags:1024
 
 prop:
+id:vb
 name:blue component
-id:vb
-type:f
+type:f 0.0 1.0 0.5
 flags:1024
 
Index: /java/main/src/test/resources/log4j.properties
===================================================================
--- /java/main/src/test/resources/log4j.properties	(revision 89)
+++ /java/main/src/test/resources/log4j.properties	(revision 90)
@@ -27,6 +27,8 @@
 
 log4j.logger.com.framsticks=INFO
-# log4j.logger.com.framsticks.util.dispatching.JoinableMonitor=DEBUG
-# log4j.logger.com.framsticks.util.dispatching.Dispatching=DEBUG
+# log4j.logger.com.framsticks.parsers.F0Writer=TRACE
+# log4j.logger.com.framsticks.core.ObjectInstance=DEBUG
+# log4j.logger.com.framsticks.core.Instance=DEBUG
+# log4j.logger.com.framsticks.running=DEBUG
 # log4j.logger.com.framsticks.parsers.XmlLoader=DEBUG
 # log4j.logger.com.framsticks.parsers.MultiParamLoader=TRACE
Index: /java/main/src/test/resources/parsers/f0_example.txt
===================================================================
--- /java/main/src/test/resources/parsers/f0_example.txt	(revision 89)
+++ /java/main/src/test/resources/parsers/f0_example.txt	(revision 90)
@@ -12,9 +12,9 @@
 n:j=0,d=@:p=0.25
 n:p=1,d=Nu
-#c:0,2
-#c:0,2,5.4
-#c:1,0
-#c:2,0,3.4
-#c:0,1,4.5
-#c:1,0,5.6
-#c:2,1
+c:0,2
+c:0,2,5.4
+c:1,0
+c:2,0,3.4
+c:0,1,4.5
+c:1,0,5.6
+c:2,1
