Index: java/main/src/main/java/com/framsticks/core/Instance.java
===================================================================
--- java/main/src/main/java/com/framsticks/core/Instance.java	(revision 88)
+++ 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();
 	}
 
