Index: java/main/src/test/java/com/framsticks/core/FramsticksTest.java
===================================================================
--- java/main/src/test/java/com/framsticks/core/FramsticksTest.java	(revision 88)
+++ java/main/src/test/java/com/framsticks/core/FramsticksTest.java	(revision 88)
@@ -0,0 +1,26 @@
+package com.framsticks.core;
+
+import java.io.InputStream;
+
+import org.testng.annotations.Test;
+
+import com.framsticks.gui.Browser;
+import com.framsticks.test.TestConfiguration;
+
+import static org.fest.assertions.Assertions.*;
+
+@Test
+public class FramsticksTest extends TestConfiguration {
+
+	@Test
+	public void testConfiguration() {
+		InputStream stream = FramsticksTest.class.getResourceAsStream("/configs/test.xml");
+		assertThat(stream).isNotNull();
+
+		Framsticks framsticks = Framsticks.loadConfiguration(stream);
+		assertThat(framsticks).isNotNull();
+		assertThat(framsticks.getObservables().size()).isEqualTo(1);
+		assertThat(framsticks.getObservables().get("browser")).isInstanceOf(Browser.class);
+	}
+
+}
Index: java/main/src/test/java/com/framsticks/core/ProgramTest.java
===================================================================
--- java/main/src/test/java/com/framsticks/core/ProgramTest.java	(revision 87)
+++ 	(revision )
@@ -1,24 +1,0 @@
-package com.framsticks.core;
-
-import java.io.InputStream;
-
-import org.testng.annotations.Test;
-
-// import com.framsticks.gui.Browser;
-import com.framsticks.test.TestConfiguration;
-
-import static org.fest.assertions.Assertions.*;
-
-@Test
-public class ProgramTest extends TestConfiguration {
-
-	@Test
-	public void testConfiguration() {
-		InputStream stream = ProgramTest.class.getResourceAsStream("/configs/test.xml");
-		assertThat(stream).isNotNull();
-
-
-		//assertThat(object).isInstanceOf(Browser.class);
-	}
-
-}
Index: java/main/src/test/java/com/framsticks/gui/BrowserTest.java
===================================================================
--- java/main/src/test/java/com/framsticks/gui/BrowserTest.java	(revision 87)
+++ java/main/src/test/java/com/framsticks/gui/BrowserTest.java	(revision 88)
@@ -3,5 +3,4 @@
 import javax.swing.JFrame;
 
-import org.apache.commons.configuration.PropertiesConfiguration;
 import org.apache.log4j.Logger;
 import org.fest.swing.edt.FailOnThreadViolationRepaintManager;
@@ -16,4 +15,7 @@
 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.*;
@@ -25,4 +27,5 @@
 	private static final Logger log = Logger.getLogger(BrowserTest.class);
 
+	JoinableMonitor monitor;
 	Browser browser;
 	Robot robot;
@@ -37,5 +40,5 @@
 
 		browser = new Browser();
-		browser.configure(new PropertiesConfiguration());
+		monitor = new JoinableMonitor(browser);
 
 		RemoteInstance localhost = new RemoteInstance();
@@ -43,7 +46,7 @@
 		localhost.setAddress("localhost:9009");
 
-		browser.addEndpointForInstance(localhost);
+		browser.addInstance(localhost);
 
-		browser.start();
+		monitor.use();
 		// robot.waitForIdle();
 		frame = new FrameFixture(robot,
@@ -51,5 +54,5 @@
 					@Override
 					protected JFrame executeInEDT() throws Throwable {
-						return browser.getMainFrame();
+						return browser.getMainFrame().getSwing();
 					}
 				}));
@@ -86,4 +89,10 @@
 		clickAndExpandPath(tree, "localhost/simulator/genepools/groups");
 		clickAndExpandPath(tree, "localhost/simulator/genepools/groups/Genotypes");
+
+
+
+
+
+
 		// tree.clickPath("localhost/simulator/genepools/groups/Genotypes/genotypes");
 		// robot.waitForIdle();
@@ -97,16 +106,28 @@
 	}
 
-	public void sleep(int seconds) {
-		try {
-			Thread.sleep(seconds * 1000, 0);
-		} catch (InterruptedException e) {
-			e.printStackTrace();
-		}
-	}
 
 	@AfterClass
 	public void tearDown() {
-		// frame.close();
-		frame.cleanUp();
+		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/model/f0/SchemaTest.java
===================================================================
--- java/main/src/test/java/com/framsticks/model/f0/SchemaTest.java	(revision 88)
+++ java/main/src/test/java/com/framsticks/model/f0/SchemaTest.java	(revision 88)
@@ -0,0 +1,28 @@
+package com.framsticks.model.f0;
+
+import org.testng.annotations.*;
+
+import com.framsticks.params.types.FloatParam;
+import com.framsticks.test.TestConfiguration;
+import com.framsticks.model.f0.Schema;
+
+import static org.fest.assertions.Delta.*;
+
+import static org.fest.assertions.Assertions.*;
+
+public class SchemaTest extends TestConfiguration {
+
+	@Test
+	public void loadSchemaWithXmlLoader() {
+		Schema schema = Schema.load(Schema.getDefaultDefinitionAsStream());
+		assertThat(schema.getFramsClasses().size()).isEqualTo(5);
+		assertThat(schema.getNeuroClasses().size()).isEqualTo(21);
+
+		assertThat(schema.getNeuroClass("|").getName()).isEqualTo("Bend muscle");
+		assertThat(schema.getNeuroClass("VEye").getParam("p")).isInstanceOf(FloatParam.class);
+		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));
+	}
+
+}
Index: java/main/src/test/java/com/framsticks/params/ParamBuilderTest.java
===================================================================
--- java/main/src/test/java/com/framsticks/params/ParamBuilderTest.java	(revision 87)
+++ java/main/src/test/java/com/framsticks/params/ParamBuilderTest.java	(revision 88)
@@ -20,5 +20,5 @@
 		builderFramsClass = FramsClass.build().forClass(ParamBuilder.class);
 
-		assertThat(builderFramsClass.getParamCount()).isEqualTo(6);
+		assertThat(builderFramsClass.getParamCount()).isEqualTo(10);
 		assertThat(builderFramsClass.getName()).isEqualTo("prop");
 		assertThat(builderFramsClass.getId()).isEqualTo("prop");
Index: java/main/src/test/java/com/framsticks/parsers/F0ParserTest.java
===================================================================
--- java/main/src/test/java/com/framsticks/parsers/F0ParserTest.java	(revision 87)
+++ java/main/src/test/java/com/framsticks/parsers/F0ParserTest.java	(revision 88)
@@ -5,4 +5,5 @@
 import com.framsticks.model.*;
 import com.framsticks.model.Package;
+import com.framsticks.model.f0.Schema;
 import com.framsticks.params.*;
 import com.framsticks.params.types.FloatParam;
@@ -29,5 +30,5 @@
 	@BeforeClass
 	public void setUp() throws Exception {
-		schema = new Schema(Schema.getDefaultDefinitionAsStream());
+		schema = Schema.load(Schema.getDefaultDefinitionAsStream());
 		Package.register(schema.getRegistry());
 	}
@@ -35,5 +36,5 @@
 	@Test
 	public void primitiveParam() {
-		FramsClass joint = schema.getRegistry().getInfoFromCache("j");
+		FramsClass joint = schema.getFramsClass("j");
 		PrimitiveParam<?> dx = joint.getParamEntry("dx", PrimitiveParam.class);
 		assertThat(dx).isInstanceOf(FloatParam.class);
@@ -47,4 +48,7 @@
 	@Test
 	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));
+
 		accesses = new F0Parser(schema, F0ParserTest.class.getResourceAsStream("/parsers/f0_example.txt")).parse();
 
@@ -75,4 +79,5 @@
 		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);
@@ -89,4 +94,6 @@
 	public void print() throws Exception {
 		ListSink sink = new ListSink();
+
+
 		new F0Writer(schema, model, sink).write();
 
Index: java/main/src/test/java/com/framsticks/parsers/SchemaTest.java
===================================================================
--- java/main/src/test/java/com/framsticks/parsers/SchemaTest.java	(revision 87)
+++ 	(revision )
@@ -1,23 +1,0 @@
-package com.framsticks.parsers;
-
-import org.testng.annotations.*;
-
-import com.framsticks.params.Registry;
-import com.framsticks.test.TestConfiguration;
-
-import static org.fest.assertions.Assertions.*;
-
-public class SchemaTest extends TestConfiguration {
-
-	Schema schema;
-	Registry registry;
-
-	@Test
-	public void loadSchema() {
-		schema = new Schema(Schema.getDefaultDefinitionAsStream());
-		registry = schema.getRegistry();
-		// Package.register(schema.getRegistry());
-		assertThat(registry.getInfoCache().size()).isEqualTo(5);
-	}
-
-}
Index: java/main/src/test/java/com/framsticks/running/ExternalProcessTest.java
===================================================================
--- java/main/src/test/java/com/framsticks/running/ExternalProcessTest.java	(revision 88)
+++ java/main/src/test/java/com/framsticks/running/ExternalProcessTest.java	(revision 88)
@@ -0,0 +1,49 @@
+package com.framsticks.running;
+
+
+// import java.util.Arrays;
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
+
+import org.testng.annotations.Test;
+
+import com.framsticks.test.TestConfiguration;
+import com.framsticks.util.dispatching.JoinableMonitor;
+
+import static org.fest.assertions.Assertions.*;
+
+@Test
+public class ExternalProcessTest extends TestConfiguration {
+
+	@Test
+	public void runBash() throws InterruptedException {
+		final ExternalProcess process = new ExternalProcess();
+		process.setCommand("bash");
+
+		final List<String> input = Arrays.asList("test", "another line");
+		final List<String> output = new LinkedList<>();
+
+		process.addListener(new OutputListener() {
+			@Override
+			public void onLineRead(String line) {
+				output.add(line);
+			}
+		});
+		JoinableMonitor monitor = new JoinableMonitor(process);
+		monitor.use();
+
+		for (String l : input) {
+			process.getInput().println("echo " + l);
+		}
+
+		process.getInput().close();
+
+		monitor.waitFor();
+		monitor.drop();
+		monitor.join();
+
+		assertThat(output).isEqualTo(input);
+	}
+
+}
Index: java/main/src/test/java/com/framsticks/running/FramsServerTest.java
===================================================================
--- java/main/src/test/java/com/framsticks/running/FramsServerTest.java	(revision 88)
+++ java/main/src/test/java/com/framsticks/running/FramsServerTest.java	(revision 88)
@@ -0,0 +1,28 @@
+package com.framsticks.running;
+
+import org.testng.annotations.Test;
+
+import com.framsticks.core.Framsticks;
+import com.framsticks.remote.RemoteInstance;
+import com.framsticks.test.TestConfiguration;
+
+import static org.fest.assertions.Assertions.*;
+
+@Test
+public class FramsServerTest extends TestConfiguration {
+
+	@Test
+	public void runServer() {
+		Framsticks framsticks = Framsticks.loadConfiguration(FramsServerTest.class.getResourceAsStream("/configs/FramsServerTest.xml"));
+
+		assertThat(framsticks.getObservables().size()).isEqualTo(2);
+		assertThat(framsticks.getObservables().get("frams")).isInstanceOf(FramsServer.class);
+		assertThat(framsticks.getObservables().get("remote")).isInstanceOf(RemoteInstance.class);
+
+		// framsticks.start();
+
+		// framsticks.waitForObservables();
+
+	}
+
+}
Index: java/main/src/test/java/com/framsticks/test/TestConfiguration.java
===================================================================
--- java/main/src/test/java/com/framsticks/test/TestConfiguration.java	(revision 87)
+++ java/main/src/test/java/com/framsticks/test/TestConfiguration.java	(revision 88)
@@ -11,7 +11,7 @@
 
 	@BeforeClass
-	public static void setUpConfiguration() {
+	public void setUpConfiguration() {
 		PropertyConfigurator.configure(TestConfiguration.class.getResource("/log4j.properties"));
-		log.info("logging configured");
+		log.info("testing " + this.getClass());
 	}
 
