Index: /java/main/pom.xml
===================================================================
--- /java/main/pom.xml	(revision 77)
+++ /java/main/pom.xml	(revision 78)
@@ -15,5 +15,7 @@
 		</repository>
 	</repositories>
-
+	<properties>
+		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+	</properties>
 	<build>
 		<plugins>
@@ -58,4 +60,11 @@
 			<version>1.5.2</version>
 		</dependency>
+
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <version>4.8.1</version>
+            <scope>test</scope>
+        </dependency>
 		<!--dependency>
 		</dependency>
Index: /java/main/src/main/java/com/framsticks/core/Entity.java
===================================================================
--- /java/main/src/main/java/com/framsticks/core/Entity.java	(revision 77)
+++ /java/main/src/main/java/com/framsticks/core/Entity.java	(revision 78)
@@ -4,7 +4,4 @@
 import com.framsticks.util.Thread;
 import org.apache.log4j.Logger;
-
-import java.util.HashSet;
-import java.util.Set;
 
 /**
@@ -37,9 +34,9 @@
     }
 
-    public final void configurePublic() {
+    public final void configurePublic() throws Exception {
         configure();
     }
 
-    protected void configure() {
+    protected void configure() throws Exception {
 
     }
@@ -58,4 +55,11 @@
     }
 
+	public final void done() {
+		LOGGER.info("stopping entity");
+		if (owner != null) {
+			owner.onDone();
+		}
+	}
+
 
 }
Index: va/main/src/main/java/com/framsticks/core/EntityListener.java
===================================================================
--- /java/main/src/main/java/com/framsticks/core/EntityListener.java	(revision 77)
+++ 	(revision )
@@ -1,8 +1,0 @@
-package com.framsticks.core;
-
-/**
- * @author Piotr Sniegowski
- */
-public interface EntityListener {
-
-}
Index: /java/main/src/main/java/com/framsticks/core/EntityOwner.java
===================================================================
--- /java/main/src/main/java/com/framsticks/core/EntityOwner.java	(revision 78)
+++ /java/main/src/main/java/com/framsticks/core/EntityOwner.java	(revision 78)
@@ -0,0 +1,8 @@
+package com.framsticks.core;
+
+/**
+ * @author Piotr Sniegowski
+ */
+public interface EntityOwner {
+	void onDone();
+}
Index: /java/main/src/main/java/com/framsticks/core/Instance.java
===================================================================
--- /java/main/src/main/java/com/framsticks/core/Instance.java	(revision 77)
+++ /java/main/src/main/java/com/framsticks/core/Instance.java	(revision 78)
@@ -23,5 +23,4 @@
     protected Node root;
 
-	protected final Map<String, FramsClass> infoCache = new HashMap<String, FramsClass>();
     public Set<InstanceListener> listeners = new HashSet<InstanceListener>();
 
@@ -34,17 +33,43 @@
     protected void run() {
         super.run();
-        registerTypicalReflectedClasses();
+		com.framsticks.model.Package.register(registry);
     }
 
     @Override
-    protected void configure() {
+    protected void configure() throws Exception {
         super.configure();
     }
 
-    protected abstract void fetchInfo(Path path, Future<FramsClass> future);
-    public abstract void resolve(Path path, Future<Path> future);
-    public abstract void fetchValue(Path path, Param param, StateFunctor stateFunctor);
-    public abstract void fetchValues(Path path, StateFunctor stateFunctor);
-    protected abstract void tryRegisterOnChangeEvents(Path path);
+    protected void fetchInfo(Path path, Future<FramsClass> future) {
+		future.result(null, new UnsupportedOperationException());
+	}
+
+	public void resolve(Path path, Future<Path> future) {
+		assert isActive();
+		assert path.isOwner(this);
+		if (path.getTop().getObject() != null) {
+			future.result(path, null);
+			return;
+		}
+		AccessInterface access = bindAccess(path.getUnder());
+		Object object = access.get(path.getTop().getParam(), Object.class);
+		if (object == null) {
+			future.result(path, null);
+			return;
+		}
+		future.result(path.appendResolution(object), null);
+	}
+
+    public void fetchValue(Path path, Param param, StateFunctor stateFunctor) {
+		stateFunctor.call(null);
+	}
+
+    public void fetchValues(Path path, StateFunctor stateFunctor) {
+		stateFunctor.call(null);
+	}
+
+    protected void tryRegisterOnChangeEvents(Path path) {
+
+	}
 
 	public void storeValue(Path path, Param param, Object value, final StateFunctor stateFunctor) {
@@ -98,13 +123,4 @@
 	}
 
-	public void putInfoIntoCache(FramsClass framsClass) {
-        assert isActive();
-        if (infoCache.containsKey(framsClass.getId())) {
-            LOGGER.info("already cached " + framsClass);
-            return;
-        }
-        LOGGER.debug("caching info for " + framsClass);
-		infoCache.put(framsClass.getId(), framsClass);
-	}
 
     public final FramsClass getInfoFromCache(Path path) {
@@ -115,28 +131,8 @@
     public FramsClass getInfoFromCache(String id) {
         assert isActive();
-        if (id == null) {
-			return null;
-		}
-        if (infoCache.containsKey(id)) {
-            return infoCache.get(id);
-        }
-		return null;
-	}
-
-	protected final Map<String, Class> reflectedClasses = new HashMap<String, Class>();
-
-    public final void registerReflectedClass(String name, String className) {
-        assert isActive();
-        try {
-            registerReflectedClass(name, Class.forName(className));
-        } catch (ClassNotFoundException e) {
-            LOGGER.fatal("class not found during registration: " + e);
-        }
-    }
-
-    public void registerReflectedClass(String name, Class reflectedClass) {
-        assert isActive();
-        reflectedClasses.put(name, reflectedClass);
-	}
+		return registry.getInfoFromCache(id);
+	}
+
+	protected Registry registry = new Registry();
 
 	public AccessInterface createAccess(String name) {
@@ -150,9 +146,5 @@
 		}
 
-		if (reflectedClasses.containsKey(name)) {
-			return new ReflectionAccess(reflectedClasses.get(name), framsClass);
-		}
-
-		return new PropertiesAccess(framsClass);
+		return registry.createAccess(name, framsClass);
 	}
 
@@ -188,4 +180,5 @@
         AccessInterface access = prepareAccess(node.getParam());
         if (access == null) {
+			LOGGER.error("missing access for: " + node.getParam());
             return null;
         }
@@ -287,5 +280,5 @@
             }
         }
-        putInfoIntoCache(framsClass);
+        registry.putInfoIntoCache(framsClass);
         return framsClass;
     }
@@ -338,15 +331,4 @@
     }
 
-    public void registerTypicalReflectedClasses() {
-        registerReflectedClass("MechPart", "com.framsticks.model.MechPart");
-        registerReflectedClass("Joint", "com.framsticks.model.Joint");
-        registerReflectedClass("MechJoint", "com.framsticks.model.MechJoint");
-        registerReflectedClass("Neuro", "com.framsticks.model.Neuro");
-        registerReflectedClass("NeuroDef", "com.framsticks.model.NeuroDef");
-        registerReflectedClass("Part", "com.framsticks.model.Part");
-        registerReflectedClass("Creature", "com.framsticks.model.Creature");
-        registerReflectedClass("Genotype", "com.framsticks.model.Genotype");
-    }
-
     public static Iterator<String> splitPath(String path) {
         List<String> list = new LinkedList<String>();
@@ -359,3 +341,7 @@
     }
 
+	public Registry getRegistry() {
+		return registry;
+	}
 }
+
Index: /java/main/src/main/java/com/framsticks/core/LocalInstance.java
===================================================================
--- /java/main/src/main/java/com/framsticks/core/LocalInstance.java	(revision 77)
+++ /java/main/src/main/java/com/framsticks/core/LocalInstance.java	(revision 78)
@@ -45,5 +45,5 @@
 
     @Override
-    protected void configure() {
+    protected void configure() throws Exception {
         super.configure();
     }
@@ -97,34 +97,3 @@
     }
 
-
-
-    @Override
-    public void resolve(Path path, Future<Path> future) {
-        assert isActive();
-        assert path.isOwner(this);
-        if (path.getTop().getObject() != null) {
-            future.result(path, null);
-            return;
-        }
-        AccessInterface access = bindAccess(path.getUnder());
-        Object object = access.get(path.getTop().getParam(), Object.class);
-        if (object == null) {
-            future.result(path, null);
-            return;
-        }
-        future.result(path.appendResolution(object), null);
-    }
-
-
-    @Override
-    public void fetchValue(Path path, Param param, StateFunctor stateFunctor) {
-        stateFunctor.call(null);
-    }
-
-    @Override
-    public void fetchValues(Path path, StateFunctor stateFunctor) {
-        stateFunctor.call(null);
-    }
-
-
 }
Index: /java/main/src/main/java/com/framsticks/core/Parameters.java
===================================================================
--- /java/main/src/main/java/com/framsticks/core/Parameters.java	(revision 77)
+++ /java/main/src/main/java/com/framsticks/core/Parameters.java	(revision 78)
@@ -12,9 +12,13 @@
     protected String name;
     protected Dispatcher dispatcher;
+	protected EntityOwner owner;
 
-    public Parameters(Configuration config, String name, Dispatcher dispatcher) {
+
+
+    public Parameters(Configuration config, String name, Dispatcher dispatcher, EntityOwner owner) {
         this.config = config;
         this.name = name;
         this.dispatcher = dispatcher;
+		this.owner = owner;
     }
 
@@ -23,4 +27,5 @@
         name = parameters.name;
         dispatcher = parameters.dispatcher;
+		owner = parameters.owner;
     }
 
Index: /java/main/src/main/java/com/framsticks/core/Program.java
===================================================================
--- /java/main/src/main/java/com/framsticks/core/Program.java	(revision 77)
+++ /java/main/src/main/java/com/framsticks/core/Program.java	(revision 78)
@@ -6,6 +6,6 @@
 import org.apache.log4j.Logger;
 import org.apache.log4j.PropertyConfigurator;
-import sun.misc.Signal;
-import sun.misc.SignalHandler;
+//import sun.misc.Signal;
+//import sun.misc.SignalHandler;
 
 import java.lang.reflect.Constructor;
@@ -19,4 +19,5 @@
     private final static Logger LOGGER = Logger.getLogger(Program.class.getName());
 
+/*
     protected SignalHandler signalHandler = new SignalHandler() {
         @Override
@@ -26,4 +27,5 @@
         }
     };
+*/
 
     protected Entity entity;
@@ -34,6 +36,6 @@
     public Program(String name) {
         super(name, java.lang.Thread.currentThread());
-        Signal.handle(new Signal("INT"), signalHandler);
-        Signal.handle(new Signal("TERM"), signalHandler);
+//        Signal.handle(new Signal("INT"), signalHandler);
+//        Signal.handle(new Signal("TERM"), signalHandler);
     }
 
@@ -44,6 +46,5 @@
             Class type = Class.forName(typeName);
             Constructor constructor = type.getConstructor(Parameters.class);
-            Entity entity = (Entity) constructor.newInstance(parameters);
-            return entity;
+            return (Entity) constructor.newInstance(parameters);
         } catch (Exception e) {
             LOGGER.error("failed to instantiate: " + e);
@@ -96,6 +97,16 @@
         }
 
-        entity = configureEntity(new Parameters(config.subset("com.framsticks.entity"), "main", null));
-        entity.configurePublic();
+        entity = configureEntity(new Parameters(config.subset("com.framsticks.entity"), "main", null, new EntityOwner() {
+			@Override
+			public void onDone() {
+				LOGGER.info("exiting");
+				Runtime.getRuntime().exit(0);
+			}
+		}));
+		try {
+	        entity.configurePublic();
+		} catch (Exception e) {
+			LOGGER.fatal("exception caught during configuration: " + e);
+		}
         LOGGER.info("all entities were configured");
         entity.start();
Index: /java/main/src/main/java/com/framsticks/diagnostics/Diagnostics.java
===================================================================
--- /java/main/src/main/java/com/framsticks/diagnostics/Diagnostics.java	(revision 77)
+++ /java/main/src/main/java/com/framsticks/diagnostics/Diagnostics.java	(revision 78)
@@ -23,5 +23,5 @@
 
     @Override
-    protected void configure() {
+    protected void configure() throws Exception {
 
         super.configure();
Index: /java/main/src/main/java/com/framsticks/dumping/FileInstance.java
===================================================================
--- /java/main/src/main/java/com/framsticks/dumping/FileInstance.java	(revision 77)
+++ /java/main/src/main/java/com/framsticks/dumping/FileInstance.java	(revision 78)
@@ -53,15 +53,4 @@
     }
 
-
-    @Override
-    protected void fetchInfo(Path path, Future<FramsClass> future) {
-        future.result(null, new UnsupportedOperationException());
-    }
-
-    @Override
-    protected void tryRegisterOnChangeEvents(Path path) {
-    }
-
-
     @Override
     public String toString() {
Index: /java/main/src/main/java/com/framsticks/dumping/SaveStream.java
===================================================================
--- /java/main/src/main/java/com/framsticks/dumping/SaveStream.java	(revision 77)
+++ /java/main/src/main/java/com/framsticks/dumping/SaveStream.java	(revision 78)
@@ -37,7 +37,16 @@
         this.instance = instance;
         this.stateFunctor = stateFunctor;
-        dispatched = 1;
-        write(root);
+		dispatchWrite(root);
     }
+
+	protected void dispatchWrite(final Path path) {
+		++dispatched;
+		instance.invokeLater(new Runnable() {
+			@Override
+			public void run() {
+				write(path);
+			}
+		});
+	}
 
     protected void finished() {
@@ -53,4 +62,5 @@
         } else {
             AccessInterface access = instance.bindAccess(path);
+			assert access != null;
             FramsClass framsClass = access.getFramsClass();
             assert framsClass != null;
@@ -76,11 +86,5 @@
                     final Path childPath = path.appendNode(new Node(childParam, access.get(childParam, Object.class)));
                     if (childPath.isResolved() && instance.getInfoFromCache(childPath) != null) {
-                        ++dispatched;
-                        instance.invokeLater(new Runnable() {
-                            @Override
-                            public void run() {
-                                write(childPath);
-                            }
-                        });
+						dispatchWrite(childPath);
                     }
                 }
@@ -92,5 +96,3 @@
         }
     }
-
-
 }
Index: /java/main/src/main/java/com/framsticks/examples/GenotypeBrowser.java
===================================================================
--- /java/main/src/main/java/com/framsticks/examples/GenotypeBrowser.java	(revision 78)
+++ /java/main/src/main/java/com/framsticks/examples/GenotypeBrowser.java	(revision 78)
@@ -0,0 +1,69 @@
+package com.framsticks.examples;
+
+import com.framsticks.core.Instance;
+import com.framsticks.core.Node;
+import com.framsticks.core.Parameters;
+import com.framsticks.core.Path;
+import com.framsticks.model.*;
+import com.framsticks.model.Package;
+import com.framsticks.params.*;
+import com.framsticks.params.types.CompositeParam;
+import com.framsticks.parsers.F0Parser;
+import com.framsticks.parsers.Schema;
+import org.apache.log4j.Logger;
+
+import java.util.List;
+
+/**
+ * Author: Piotr Śniegowski
+ */
+public class GenotypeBrowser extends Instance {
+
+	private static final Logger LOGGER = Logger.getLogger(Instance.class.getName());
+	protected Schema schema;
+
+
+	public GenotypeBrowser(Parameters parameters) {
+		super(parameters);
+		LOGGER.info("model builder created");
+	}
+
+	@Override
+	protected void configure() throws Exception {
+		super.configure();
+		schema = new Schema(Schema.getDefaultDefinitionAsStream());
+		this.registry = schema.getRegistry();
+		Package.register(this.getRegistry());
+
+		registry.putInfoIntoCache(new FramsClass("ModelBuilderRoot", "ModelBuilderRoot", null)
+				.append(new ParamBuilder().setType("o Model").setId("f0genotype").setName("f0genotype").build())
+				.append(new ParamBuilder().setType("o F0Model").setId("f0model").setName("f0model").build())
+		);
+		root = new Node((CompositeParam)new ParamBuilder().setType("o ModelBuilderRoot").setId(name).setName("Instance").build(), PropertiesAccess.createPropertiesMap());
+	}
+
+	@Override
+	protected void run() {
+		assert isActive();
+
+		try {
+			List<AccessInterface> accesses = new F0Parser(schema, GenotypeBrowser.class.getResourceAsStream("/examples/f0_example.txt")).parse();
+			List<Object> objects = Util.stripAccessInterface(accesses);
+			F0Genotype f0Genotype = F0Genotype.build(objects);
+			F0Model f0Model = F0Model.build(f0Genotype);
+
+			for (String n : new String[] {"MechPart", "MechJoint", "Neuro"}) {
+				registry.putInfoIntoCache(FramsClass.readFromStream(GenotypeBrowser.class.getResourceAsStream("/info/" + n + ".info")));
+			}
+			AccessInterface rootAccess = bindAccess(new Path(this, "/"));
+
+			rootAccess.set("f0genotype", f0Genotype);
+			rootAccess.set("f0model", f0Model);
+
+		} catch (Exception e) {
+			LOGGER.error("exception caught: " + e);
+		}
+		//done();
+	}
+
+}
Index: /java/main/src/main/java/com/framsticks/gui/Browser.java
===================================================================
--- /java/main/src/main/java/com/framsticks/gui/Browser.java	(revision 77)
+++ /java/main/src/main/java/com/framsticks/gui/Browser.java	(revision 78)
@@ -45,5 +45,5 @@
 
     @Override
-    protected void configure() {
+    protected void configure() throws Exception {
         super.configure();
     }
Index: /java/main/src/main/java/com/framsticks/gui/Frame.java
===================================================================
--- /java/main/src/main/java/com/framsticks/gui/Frame.java	(revision 77)
+++ /java/main/src/main/java/com/framsticks/gui/Frame.java	(revision 78)
@@ -1,4 +1,5 @@
 package com.framsticks.gui;
 
+import com.framsticks.core.Node;
 import com.framsticks.core.Path;
 import com.framsticks.gui.view.*;
@@ -12,4 +13,5 @@
 import javax.swing.tree.*;
 import java.awt.*;
+import java.awt.datatransfer.StringSelection;
 import java.awt.event.ActionEvent;
 import java.awt.event.MouseAdapter;
@@ -75,4 +77,12 @@
         treePopupMenu.add(new JMenuItem("Refresh"));
         treePopupMenu.add(new JMenuItem("Open in new frame as root"));
+		addNodeActionToTreePopupMenu("Copy path to clipboard", new NodeAction() {
+			@Override
+			public void actionPerformed(TreeNode treeNode) {
+				Path path = treeNode.getInstancePath();
+				StringSelection selection = new StringSelection(path.toString());
+				getToolkit().getSystemClipboard().setContents(selection, selection);
+			}
+		});
         //this.add(createMenuItem("Add to favourites", null));
         //this.add(createMenuItem("Remove from favourites", null));
Index: /java/main/src/main/java/com/framsticks/gui/TreeNode.java
===================================================================
--- /java/main/src/main/java/com/framsticks/gui/TreeNode.java	(revision 77)
+++ /java/main/src/main/java/com/framsticks/gui/TreeNode.java	(revision 78)
@@ -124,4 +124,7 @@
         LOGGER.debug("updating children of " + this);
         AccessInterface access = p.getInstance().bindAccess(p.getTop());
+		if (access == null) {
+			return;
+		}
         final List<Path> childrenPaths = new LinkedList<Path>();
         /**Prepare path for each child.*/
@@ -210,5 +213,4 @@
     }
 
-
 	public final Panel getPanel() {
         assert frame.isActive();
@@ -222,5 +224,7 @@
         }
         AccessInterface access = p.getInstance().bindAccess(p);
-        assert access != null;
+		if (access == null) {
+			return;
+		}
         StringBuilder t = new StringBuilder();
         /** html formatting is used here, since tooltips in swing do not support simple \n line breaks */
@@ -494,4 +498,9 @@
 
 		return true;
+	}
+
+	public Path getInstancePath() {
+		assert frame.isActive();
+		return path;
 	}
 
Index: /java/main/src/main/java/com/framsticks/hosting/ServerInstance.java
===================================================================
--- /java/main/src/main/java/com/framsticks/hosting/ServerInstance.java	(revision 77)
+++ /java/main/src/main/java/com/framsticks/hosting/ServerInstance.java	(revision 78)
@@ -30,8 +30,8 @@
 
     @Override
-    protected void configure() {
+    protected void configure() throws Exception {
         super.configure();
 
-        Parameters p = new Parameters(config.subset("hosted.entity"), "hosted", this);
+        Parameters p = new Parameters(config.subset("hosted.entity"), "hosted", this, null);
         hosted = Program.configureEntity(p);
         if (hosted == null) {
@@ -49,6 +49,7 @@
             return null;
         }
-        if (infoCache.containsKey(id)) {
-            return infoCache.get(id);
+		FramsClass cached = registry.getInfoFromCache(id);
+        if (cached != null) {
+			return cached;
         }
         try {
@@ -56,6 +57,6 @@
             FramsClass framsClass = new FramsClass.Constructor(nativeClass, id).getResult();
 
-            registerReflectedClass(id, nativeClass);
-            putInfoIntoCache(framsClass);
+            registry.registerReflectedClass(null, id, nativeClass);
+            registry.putInfoIntoCache(framsClass);
             return framsClass;
         } catch (ClassNotFoundException ignored) {
Index: /java/main/src/main/java/com/framsticks/model/BaseJoint.java
===================================================================
--- /java/main/src/main/java/com/framsticks/model/BaseJoint.java	(revision 78)
+++ /java/main/src/main/java/com/framsticks/model/BaseJoint.java	(revision 78)
@@ -0,0 +1,38 @@
+package com.framsticks.model;
+
+import com.framsticks.util.Point3d;
+
+/**
+ * Author: Piotr Śniegowski
+ */
+public class BaseJoint {
+
+	/** stif */
+	public Double stiffness;
+	public Double getStif() { return stiffness; }
+	public void setStif(Double stif) { stiffness = stif; }
+
+	/** rotstif */
+	public Double rotationStiffness;
+	public Double getRotstif() { return rotationStiffness; }
+	public void setRotstif(Double rotstif) { rotationStiffness = rotstif; }
+
+	/** rx, ry, rz*/
+	public double rx, ry, rz;
+
+	public Point3d getRotation() { return new Point3d(rx, ry, rz); }
+	public void setRotation(Point3d r) { rx = r.x; ry = r.y; rz = r.z; }
+
+	/** dx, dy, dz*/
+	public double dx, dy, dz;
+
+	public Point3d getDelta() { return new Point3d(dx, dy, dz); }
+	public void setDelta(Point3d d) { dx = d.x; dy = d.y; dz = d.z; }
+
+	public void copyFrom(BaseJoint j) {
+		stiffness = j.stiffness;
+		rotationStiffness = j.rotationStiffness;
+		setRotation(j.getRotation());
+		setDelta(j.getDelta());
+	}
+}
Index: /java/main/src/main/java/com/framsticks/model/BaseNeuro.java
===================================================================
--- /java/main/src/main/java/com/framsticks/model/BaseNeuro.java	(revision 78)
+++ /java/main/src/main/java/com/framsticks/model/BaseNeuro.java	(revision 78)
@@ -0,0 +1,16 @@
+package com.framsticks.model;
+
+/**
+ * Author: Piotr Śniegowski
+ */
+public class BaseNeuro {
+	/** inputCount */
+	public Integer inputCount;
+	public Integer getGetInputCount() { return inputCount; }
+	public void setGetInputCount(Integer getInputCount) { inputCount = getInputCount; }
+
+
+	public void copyFrom(BaseNeuro n) {
+		inputCount = n.inputCount;
+	}
+}
Index: /java/main/src/main/java/com/framsticks/model/BasePart.java
===================================================================
--- /java/main/src/main/java/com/framsticks/model/BasePart.java	(revision 78)
+++ /java/main/src/main/java/com/framsticks/model/BasePart.java	(revision 78)
@@ -0,0 +1,37 @@
+package com.framsticks.model;
+
+import com.framsticks.util.Point3d;
+
+/**
+ * Author: Piotr Śniegowski
+ */
+public class BasePart {
+	/** x, y, z */
+	public double x, y, z;
+
+	public Point3d getPosition() { return new Point3d(x, y, z); }
+	public void setPosition(Point3d p) { x = p.x; y = p.y; z = p.z; }
+
+	/** m */
+	public Double mass = 0.0;
+	public Double getM() { return mass; }
+	public void setM(Double m) { mass = m; }
+
+	/** s */
+	public Double size = 0.0;
+	public Double getS() { return size; }
+	public void setS(Double s) { size = s; }
+
+	/** fr */
+	public Double friction;
+	public Double getFr() { return friction; }
+	public void setFr(Double fr) { friction = fr; }
+
+
+	public void copyFrom(BasePart p) {
+		setPosition(p.getPosition());
+		mass = p.mass;
+		size = p.size;
+		friction = p.friction;
+	}
+}
Index: /java/main/src/main/java/com/framsticks/model/Creature.java
===================================================================
--- /java/main/src/main/java/com/framsticks/model/Creature.java	(revision 77)
+++ /java/main/src/main/java/com/framsticks/model/Creature.java	(revision 78)
@@ -1,6 +1,6 @@
 package com.framsticks.model;
 
-import com.framsticks.model.MechPart;
-import com.framsticks.model.Joint;
+import com.framsticks.params.FramsClass;
+import com.framsticks.util.Orientation;
 import com.framsticks.util.Point3d;
 
@@ -8,5 +8,5 @@
 import java.util.List;
 
-public class Creature {
+public class Creature extends F0Model {
 	public String name;
 
@@ -94,35 +94,21 @@
 	public void setVertpos(Double c_vertpos) { averageVerticalPosition = c_vertpos; }
 
-	public Point3d position = new Point3d();
+	/** pos_x, pos_y, pos_z*/
+	public double pos_x, pos_y, pos_z;
 
-	public Double getPos_x() { return position.x; }
-	public void setPos_x(Double pos_x) { position.x = pos_x; }
+	public Point3d getPosition() { return new Point3d(pos_x, pos_y, pos_z) ; }
+	public void setPosition(Point3d pos) { pos_x = pos.x; pos_y = pos.y; pos_z = pos.z; }
 
-	public Double getPos_y() { return position.y; }
-	public void setPos_y(Double pos_y) { position.y = pos_y; }
+	public double size_x, size_y, size_z;
 
-	public Double getPos_z() { return position.z; }
-	public void setPos_z(Double pos_z) { position.z = pos_z; }
+	public Point3d getBoundingBox() { return new Point3d(size_x, size_y, size_z) ; }
+	public void setBoundingBox(Point3d size) { size_x = size.x; size_y = size.y; size_z = size.z; }
 
-	public Point3d boundingBox = new Point3d();
-	public Double getSize_x() { return boundingBox.x; }
-	public void setSize_x(Double size_x) { boundingBox.x = size_x; }
 
-	public Double getSize_y() { return boundingBox.y; }
-	public void setSize_y(Double size_y) { boundingBox.y = size_y; }
+	/** center_x, center_y, center_z*/
+	public double center_x, center_y, center_z;
 
-	public Double getSize_z() { return boundingBox.z; }
-	public void setSize_z(Double size_z) { boundingBox.z = size_z; }
-
-	public Point3d center = new Point3d();
-
-	public Double getCenter_x() { return center.x; }
-	public void setCenter_x(Double center_x) { center.x = center_x; }
-
-	public Double getCenter_y() { return center.y; }
-	public void setCenter_y(Double center_y) { center.y = center_y; }
-
-	public Double getCenter_z() { return center.z; }
-	public void setCenter_z(Double center_z) { center.z = center_z; }
+	public Point3d getCenter() { return new Point3d(center_x, center_y, center_z) ; }
+	public void setCenter(Point3d center) { center_x = center.x; center_y = center.y; center_z = center.z; }
 
 	public Integer getNumparts() { return parts.size(); }
@@ -161,9 +147,18 @@
 	public final List<NeuroDef> neurodefs = new ArrayList<NeuroDef>();
 
-	public final List<MechPart> mechparts = new ArrayList<MechPart>();
-	public final List<MechJoint> mechjoints = new ArrayList<MechJoint>();
-	public final List<Neuro> neurons = new ArrayList<Neuro>();
+
+
+	public final List<Part> getParts() { return parts; }
+	public final List<Joint> getJoints() { return joints; }
+	public final List<NeuroDef> getNeuroDefs() { return neurodefs; }
 
 
 
+	public static void constructFramsClass(FramsClass.Constructor constructor) {
+		constructor.field("name");
+		constructor.field("parts");
+		constructor.field("joints");
+		constructor.field("neurodefs");
+	}
+
 }
Index: /java/main/src/main/java/com/framsticks/model/F0Genotype.java
===================================================================
--- /java/main/src/main/java/com/framsticks/model/F0Genotype.java	(revision 78)
+++ /java/main/src/main/java/com/framsticks/model/F0Genotype.java	(revision 78)
@@ -0,0 +1,75 @@
+package com.framsticks.model;
+
+import com.framsticks.util.Casting;
+import com.framsticks.util.Containers;
+import org.apache.log4j.Logger;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Author: Piotr Śniegowski
+ */
+public class F0Genotype {
+
+	private final static Logger LOGGER = Logger.getLogger(F0Genotype.class);
+
+	public Double startingEnergy;
+	public Double getEnerg0() { return startingEnergy; }
+	public void setEnerg0(Double energ0) { startingEnergy = energ0; }
+
+	public Double getSe() { return startingEnergy; }
+	public void setSe(Double se) { startingEnergy = se; }
+
+	/** Vstyle */
+	public String visualizationStyle;
+	public String getVstyle() { return visualizationStyle; }
+	public void setVstyle(String Vstyle) { visualizationStyle = Vstyle; }
+
+	public final List<Part> parts = new ArrayList<Part>();
+	public final List<Joint> joints = new ArrayList<Joint>();
+	public final List<NeuroDef> neurodefs = new ArrayList<NeuroDef>();
+
+	public Double getNumparts() { return (double)parts.size(); }
+	public Double getNumjoints() { return (double)joints.size(); }
+	public Double getNumneurons() { return (double)neurodefs.size(); }
+
+	//this is impossible to use, because numparts field is marked as readonly
+	public void setNumparts(Double numparts) { Containers.resizeList(parts, (int) (double) numparts); }
+	public void setNumjoints(Double numjoints) { Containers.resizeList(joints, (int)(double)numjoints); }
+	public void setNumneurons(Double numneurons) { Containers.resizeList(neurodefs, (int)(double)numneurons); }
+
+	public List<Part> getParts() { return parts; }
+	public List<Joint> getJoints() { return joints; }
+	public List<NeuroDef> getNeuroDefs() { return neurodefs; }
+
+	public static F0Genotype build(List<Object> objects) {
+		Iterator<Object> i = objects.iterator();
+		if (!i.hasNext()) {
+			return null;
+		}
+		F0Genotype f0Genotype = Casting.tryCast(F0Genotype.class, i.next());
+		if (f0Genotype == null) {
+			LOGGER.fatal("first object is not a Model");
+			return null;
+		}
+		while (i.hasNext()) {
+			Object object = i.next();
+			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;
+			}
+			LOGGER.error("invalid class: " + object.getClass().getCanonicalName());
+		}
+		return f0Genotype;
+	}
+}
Index: /java/main/src/main/java/com/framsticks/model/F0Model.java
===================================================================
--- /java/main/src/main/java/com/framsticks/model/F0Model.java	(revision 78)
+++ /java/main/src/main/java/com/framsticks/model/F0Model.java	(revision 78)
@@ -0,0 +1,59 @@
+package com.framsticks.model;
+
+import com.framsticks.params.FramsClass;
+import com.framsticks.util.Orientation;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Author: Piotr Śniegowski
+ */
+public class F0Model {
+
+	public final List<MechPart> mechparts = new ArrayList<MechPart>();
+	public final List<MechJoint> mechjoints = new ArrayList<MechJoint>();
+	public final List<Neuro> neurons = new ArrayList<Neuro>();
+
+	public final List<MechPart> getMechParts() { return mechparts; }
+	public final List<MechJoint> getMechJoints() { return mechjoints; }
+	public final List<Neuro> getNeurons() { return neurons; }
+
+	public static void constructFramsClass(FramsClass.Constructor constructor) {
+		constructor.field("mechparts");
+		constructor.field("mechjoints");
+		constructor.field("neurons");
+	}
+
+	public static F0Model build(F0Genotype f0Genotype) {
+		F0Model model = new F0Model();
+
+		for (Part p : f0Genotype.getParts()) {
+			/** based on c++ Model::build*/
+			MechPart mp = new MechPart();
+			mp.setPosition(p.getPosition());
+			mp.setOrientation(new Orientation().rotate(p.getRotation()));
+			mp.copyFrom(p);
+			model.mechparts.add(mp);
+		}
+		for (Joint j : f0Genotype.getJoints()) {
+			/** based on c++ Joint::attachToParts*/
+			MechPart mp1 = model.mechparts.get(j.getP1());
+			MechPart mp2 = model.mechparts.get(j.getP2());
+			assert mp1 != null && mp2 != null;
+			MechJoint mj = new MechJoint();
+			mj.copyFrom(j);
+			Orientation o = new Orientation().rotate(j.getRotation());
+			mp2.setOrientation(mp1.getOrientation().transform(o));
+			mp2.setPosition(mp2.getOrientation().transform(j.getDelta()).add(mp1.getPosition()));
+			model.mechjoints.add(mj);
+		}
+		for (NeuroDef nd : f0Genotype.getNeuroDefs()) {
+			Neuro n = new Neuro();
+			n.copyFrom(nd);
+			model.neurons.add(n);
+		}
+
+		return model;
+	}
+}
Index: /java/main/src/main/java/com/framsticks/model/Genotype.java
===================================================================
--- /java/main/src/main/java/com/framsticks/model/Genotype.java	(revision 77)
+++ /java/main/src/main/java/com/framsticks/model/Genotype.java	(revision 78)
@@ -2,10 +2,9 @@
 
 
-import com.framsticks.util.Containers;
+import org.apache.log4j.Logger;
 
-import java.util.ArrayList;
-import java.util.List;
+public class Genotype extends F0Genotype {
+	private final static Logger LOGGER = Logger.getLogger(Genotype.class);
 
-public class Genotype {
 	public String name;
 	public String genotype;
@@ -15,8 +14,4 @@
 	public Double getSimi() { return similarity; }
 	public void setSimi(Double simi) { similarity = simi; }
-
-	public Double startingEnergy;
-	public Double getEnerg0() { return startingEnergy; }
-	public void setEnerg0(Double energ0) { startingEnergy = energ0; }
 
 	public Double brainConnections;
@@ -40,5 +35,4 @@
 	public Double velocity;
 	public Double distance;
-
 
 	public Double verticalVelocity;
@@ -78,16 +72,4 @@
 	public String uid;
 
-	public final List<Part> parts = new ArrayList<Part>();
-	public final List<Joint> joints = new ArrayList<Joint>();
-	public final List<NeuroDef> neurodefs = new ArrayList<NeuroDef>();
+}
 
-
-    public Double getNumparts() { return (double)parts.size(); }
-	public Double getNumjoints() { return (double)joints.size(); }
-	public Double getNumneurons() { return (double)neurodefs.size(); }
-
-    //this is impossible to use, because numparts field is marked as readonly
-    public void setNumparts(Double numparts) { Containers.resizeList(parts, (int)(double)numparts); }
-    public void setNumjoints(Double numjoints) { Containers.resizeList(joints, (int)(double)numjoints); }
-    public void setNumneurons(Double numneurons) { Containers.resizeList(neurodefs, (int)(double)numneurons); }
-}
Index: /java/main/src/main/java/com/framsticks/model/Joint.java
===================================================================
--- /java/main/src/main/java/com/framsticks/model/Joint.java	(revision 77)
+++ /java/main/src/main/java/com/framsticks/model/Joint.java	(revision 78)
@@ -8,69 +8,31 @@
  * All accessors are used by ReflectionAccess.
  */
-public class Joint {
+public class Joint extends BaseJoint {
 
+	/** i */
+	public String info;
+	public String getI() { return info; }
+	public void setI(String i) { info = i; }
+
+	/** p1 */
+	public Integer part1;
 	public void setP1(Integer p1) { part1 = p1; }
 	public Integer getP1() { return part1; }
+
+	/** p2 */
+	public Integer part2;
 	public void setP2(Integer p2) { part2 = p2; }
 	public Integer getP2() { return part2; }
 
-	public void setDx(Double dx) { delta.x = dx; }
-	public void setDy(Double dy) { delta.y = dy; }
-	public void setDz(Double dz) { delta.z = dz; }
 
-	public Double getDx() { return delta.x; }
-	public Double getDy() { return delta.y; }
-	public Double getDz() { return delta.z; }
-
-	public void setRx(Double rx) { rotation.x = rx; }
-	public void setRy(Double ry) { rotation.y = ry; }
-	public void setRz(Double rz) { rotation.z = rz; }
-
-	public Double getRx() { return rotation.x; }
-	public Double getRy() { return rotation.y; }
-	public Double getRz() { return rotation.z; }	
-
+	/** stam */
+	public Double stamina;
 	public Double getStam() { return stamina; }
 	public void setStam(Double stam) { stamina = stam; }
 
-	public Double getStif() { return stiffness; }
-	public void setStif(Double stif) { stiffness = stif; }
-
-	public Double getRotstif() { return rotationStiffness; }
-	public void setRotstif(Double rotstif) { rotationStiffness = rotstif; }
-
-	public String getI() { return info; }
-	public void setI(String i) { info = i; }
-
-	public String getVstyle() { return visualizationStyle; }
-	public void setVstyle(String Vstyle) { visualizationStyle = Vstyle; }
-
-	/** p1 */
-	public Integer part1;
-
-	/** p2 */
-	public Integer part2;
-
-	/** dx, dy, dz*/
-	public final Point3d delta = new Point3d();
-
-	/** rx, ry, rz*/
-	public final Point3d rotation = new Point3d();
-
-	/** stam */
-	public Double stamina;
-
-	/** stif */
-	public Double stiffness;
-
-	/** rotstif */
-	public Double rotationStiffness;
-
-	/** i */
-	public String info;
 
 	/** Vstyle */
 	public String visualizationStyle;
-
-
+	public String getVstyle() { return visualizationStyle; }
+	public void setVstyle(String Vstyle) { visualizationStyle = Vstyle; }
 }
Index: /java/main/src/main/java/com/framsticks/model/MechJoint.java
===================================================================
--- /java/main/src/main/java/com/framsticks/model/MechJoint.java	(revision 77)
+++ /java/main/src/main/java/com/framsticks/model/MechJoint.java	(revision 78)
@@ -6,52 +6,14 @@
  * @author Piotr Sniegowski
  */
-public class MechJoint {
-	/** rx, ry, rz*/
-	public final Point3d rotation = new Point3d();
-
-	/** dx, dy, dz*/
-	public final Point3d delta = new Point3d();
-
-	/** stif */
-	public Double stiffness;
-
-	/** rotstif */
-	public Double rotationStiffness;
+public class MechJoint extends BaseJoint {
 
 	/** stress */
 	public Double stress;
+	public Double getStress() { return stress; }
+	public void setStress(Double stress) { this.stress = stress; }
 
 	/** rotstress */
 	public Double rotationStress;
-
-	public Double getRx() { return rotation.x; }
-	public void setRx(Double rx) { rotation.x = rx; }
-
-	public Double getRy() { return rotation.y; }
-	public void setRy(Double ry) { rotation.y = ry; }
-
-	public Double getRz() { return rotation.z; }
-	public void setRz(Double rz) { rotation.z = rz; }
-
-	public Double getDx() { return delta.x; }
-	public void setDx(Double dx) { delta.x = dx; }
-
-	public Double getDy() { return delta.y; }
-	public void setDy(Double dy) { delta.y = dy; }
-
-	public Double getDz() { return delta.z; }
-	public void setDz(Double dz) { delta.z = dz; }
-
-	public Double getStif() { return stiffness; }
-	public void setStif(Double stif) { stiffness = stif; }
-
-	public Double getRotstif() { return rotationStiffness; }
-	public void setRotstif(Double rotstif) { rotationStiffness = rotstif; }
-
-	public Double getStress() { return stress; }
-	public void setStress(Double stress) { this.stress = stress; }
-
 	public Double getRotstress() { return rotationStress; }
 	public void setRotstress(Double rotstress) { rotationStress = rotstress; }
-
 }
Index: /java/main/src/main/java/com/framsticks/model/MechPart.java
===================================================================
--- /java/main/src/main/java/com/framsticks/model/MechPart.java	(revision 77)
+++ /java/main/src/main/java/com/framsticks/model/MechPart.java	(revision 78)
@@ -6,83 +6,32 @@
 /*
  */
-public class MechPart {
-
-	/** x, y, z */
-	public final Point3d position = new Point3d();
-
-	/** m */
-	public Double mass = 0.0;
-
-	/** s */
-	public Double size = 0.0;
+public class MechPart extends BasePart {
 
 	/** vol */
 	public Double volume = 0.0;
-
-	/** fr */
-	public Double friction = 0.0;
-
-	/** vx, vy, vz */
-	public final Point3d velocity = new Point3d();
-
-    /** oxx, oxy, oxz, oyx, oyy, oyz, ozx, ozy, ozz*/
-    public final Orientation orientation = new Orientation();
-
-	public Double getX() { return position.x; }
-	public void setX(Double x) { position.x = x; }
-
-	public Double getY() { return position.y; }
-	public void setY(Double y) { position.y = y; }
-
-	public Double getZ() { return position.z; }
-	public void setZ(Double z) { position.z = z; }
-
-	public Double getM() { return mass; }
-	public void setM(Double m) { mass = m; }
-
-	public Double getS() { return size; }
-	public void setS(Double s) { size = s; }
-
 	public Double getVol() { return volume; }
 	public void setVol(Double vol) { volume = vol; }
 
-	public Double getFr() { return friction; }
-	public void setFr(Double fr) { friction = fr; }
+	/** vx, vy, vz*/
+	public double vx, vy, vz;
 
-	public Double getVx() { return velocity.x; }
-	public void setVx(Double vx) { velocity.x = vx; }
+	public Point3d getVelocity() { return new Point3d(vx, vy, vz); }
+	public void setVelocity(Point3d v) { vx = v.x; vy = v.y; vz = v.z; }
 
-	public Double getVy() { return velocity.y; }
-	public void setVy(Double vy) { velocity.y = vy; }
+    public double oxx, oxy, oxz, oyx, oyy, oyz, ozx, ozy, ozz;
 
-	public Double getVz() { return velocity.z; }
-	public void setVz(Double vz) { velocity.z = vz; }
+	public Orientation getOrientation() { return new Orientation(new Point3d(oxx, oxy, oxz), new Point3d(oyx, oyy, oyz), new Point3d(ozx, ozy, ozz)); }
 
-	public Double getOxx() { return orientation.x.x; }
-	public void setOxx(Double oxx) { orientation.x.x = oxx; }
-
-	public Double getOxy() { return orientation.x.y; }
-	public void setOxy(Double oxy) { orientation.x.y = oxy; }
-
-	public Double getOxz() { return orientation.x.z; }
-	public void setOxz(Double oxz) { orientation.x.z = oxz; }
-
-	public Double getOyx() { return orientation.y.x; }
-	public void setOyx(Double oyx) { orientation.y.x = oyx; }
-
-	public Double getOyy() { return orientation.y.y; }
-	public void setOyy(Double oyy) { orientation.y.y = oyy; }
-
-	public Double getOyz() { return orientation.y.z; }
-	public void setOyz(Double oyz) { orientation.y.z = oyz; }
-
-	public Double getOzx() { return orientation.z.x; }
-	public void setOzx(Double ozx) { orientation.z.x = ozx; }
-
-	public Double getOzy() { return orientation.z.y; }
-	public void setOzy(Double ozy) { orientation.z.y = ozy; }
-
-	public Double getOzz() { return orientation.z.z; }
-	public void setOzz(Double ozz) { orientation.z.z = ozz; }
+	public void setOrientation(Orientation o) {
+		oxx = o.x.x;
+		oxy = o.x.y;
+		oxz = o.x.z;
+		oyx = o.y.x;
+		oyy = o.y.y;
+		oyz = o.y.z;
+		ozx = o.z.x;
+		ozy = o.z.y;
+		ozz = o.z.z;
+	}
 
 }
Index: /java/main/src/main/java/com/framsticks/model/Neuro.java
===================================================================
--- /java/main/src/main/java/com/framsticks/model/Neuro.java	(revision 77)
+++ /java/main/src/main/java/com/framsticks/model/Neuro.java	(revision 78)
@@ -6,11 +6,7 @@
  * @author Piotr Sniegowski
  */
-public class Neuro {
+public class Neuro extends BaseNeuro {
 
 	public Integer channelCount;
-
-	public Integer inputCount;
-	public Integer getGetInputCount() { return inputCount; }
-	public void setGetInputCount(Integer getInputCount) { inputCount = getInputCount; }
 
 	public Double inputSum;
@@ -26,16 +22,8 @@
 	public Boolean hold;
 
+	public double position_x, position_y, position_z;
 
-	/** position_x, position_y, position_z*/
-	public final Point3d position = new Point3d();
-
-	public Double getPosition_x() { return position.x; }
-	public void setPosition_x(Double position_x) { position.x = position_x; }
-
-	public Double getPosition_y() { return position.y; }
-	public void setPosition_y(Double position_y) { position.y = position_y; }
-
-	public Double getPosition_z() { return position.z; }
-	public void setPosition_z(Double position_z) { position.z = position_z; }
+	public Point3d getPosition() { return new Point3d(position_x, position_y, position_z); }
+	public void setPosition(Point3d p) { position_x = p.x; position_y = p.y; position_z = p.z; }
 
 }
Index: /java/main/src/main/java/com/framsticks/model/NeuroDef.java
===================================================================
--- /java/main/src/main/java/com/framsticks/model/NeuroDef.java	(revision 77)
+++ /java/main/src/main/java/com/framsticks/model/NeuroDef.java	(revision 78)
@@ -4,5 +4,5 @@
  * @author Piotr Sniegowski
  */
-public class NeuroDef {
+public class NeuroDef extends BaseNeuro {
 
 	/** p */
@@ -21,7 +21,4 @@
 	public String visualizationStyle;
 
-	/** getInputCount */
-	public Integer inputCount;
-
 	public Integer getP() { return part; }
 	public void setP(Integer p) { part = p; }
@@ -39,6 +36,4 @@
 	public void setVstyle(String Vstyle) { visualizationStyle = Vstyle; }
 
-	public Integer getGetInputCount() { return inputCount; }
-	public void setGetInputCount(Integer getInputCount) { inputCount = getInputCount; }
 
 
Index: /java/main/src/main/java/com/framsticks/model/Package.java
===================================================================
--- /java/main/src/main/java/com/framsticks/model/Package.java	(revision 78)
+++ /java/main/src/main/java/com/framsticks/model/Package.java	(revision 78)
@@ -0,0 +1,27 @@
+package com.framsticks.model;
+
+import com.framsticks.params.FramsClass;
+import com.framsticks.params.Registry;
+import com.framsticks.util.Orientation;
+import com.framsticks.util.Point3d;
+
+/**
+ * Author: Piotr Śniegowski
+ */
+public class Package {
+	public static void register(Registry registry) {
+		registry.registerReflectedClass("MechPart", null, "com.framsticks.model.MechPart");
+		registry.registerReflectedClass("Joint", "j", "com.framsticks.model.Joint");
+		registry.registerReflectedClass("MechJoint", null, "com.framsticks.model.MechJoint");
+		registry.registerReflectedClass("Neuro", null, "com.framsticks.model.Neuro");
+		registry.registerReflectedClass("NeuroDef", "n", "com.framsticks.model.NeuroDef");
+		registry.registerReflectedClass("Part", "p", "com.framsticks.model.Part");
+		registry.registerReflectedClass("Model", "m", "com.framsticks.model.F0Genotype");
+		registry.registerReflectedClass("F0Model", null, "com.framsticks.model.F0Model");
+		registry.registerReflectedClass("F0Genotype", null, "com.framsticks.model.F0Genotype");
+		registry.registerReflectedClass("Creature", null, "com.framsticks.model.Creature");
+		registry.registerReflectedClass("Genotype", null, "com.framsticks.model.Genotype");
+
+		registry.putInfoIntoCache(new FramsClass.Constructor(F0Model.class, "F0Model").getResult());
+	}
+}
Index: /java/main/src/main/java/com/framsticks/model/Part.java
===================================================================
--- /java/main/src/main/java/com/framsticks/model/Part.java	(revision 77)
+++ /java/main/src/main/java/com/framsticks/model/Part.java	(revision 78)
@@ -7,23 +7,14 @@
  * The Class Part.
  */
-public class Part {
-
-	/** x, y, z*/
-	public final Point3d position = new Point3d();
+public class Part extends BasePart {
 
 	/** rx, ry, rz*/
-	public final Point3d rotation = new Point3d();
+	public double rx, ry, rz;
 
-	/** m */
-	public Double mass;
-
-	/** s */
-	public Double size;
+	public Point3d getRotation() { return new Point3d(rx, ry, rz); }
+	public void setRotation(Point3d r) { rx = r.x; ry = r.y; rz = r.z; }
 
 	/** dn */
 	public Double density;
-
-	/** fr */
-	public Double friction;
 
 	/** ing */
@@ -39,24 +30,7 @@
 	public String visualizationStyle;
 
-	public Double getX() { return position.x; }
-	public void setX(Double x) { position.x = x; }
-
-	public Double getY() { return position.y; }
-	public void setY(Double y) { position.y = y; }
-
-	public Double getZ() { return position.z; }
-	public void setZ(Double z) { position.z = z; }
-
-	public Double getM() { return mass; }
-	public void setM(Double m) { mass = m; }
-
-	public Double getS() { return size; }
-	public void setS(Double s) { size = s; }
-
 	public Double getDn() { return density; }
 	public void setDn(Double dn) { density = dn; }
 
-	public Double getFr() { return friction; }
-	public void setFr(Double fr) { friction = fr; }
 
 	public Double getIng() { return ingestion; }
@@ -65,13 +39,4 @@
 	public Double getAs() { return assimilation; }
 	public void setAs(Double as) { assimilation = as; }
-
-	public Double getRx() { return rotation.x; }
-	public void setRx(Double rx) { rotation.x = rx; }
-
-	public Double getRy() { return rotation.y; }
-	public void setRy(Double ry) { rotation.y = ry; }
-
-	public Double getRz() { return rotation.z; }
-	public void setRz(Double rz) { rotation.z = rz; }
 
 	public String getI() { return info; }
Index: /java/main/src/main/java/com/framsticks/observers/Observer.java
===================================================================
--- /java/main/src/main/java/com/framsticks/observers/Observer.java	(revision 77)
+++ /java/main/src/main/java/com/framsticks/observers/Observer.java	(revision 78)
@@ -30,5 +30,5 @@
 
     @Override
-    protected void configure() {
+    protected void configure() throws Exception {
         super.configure();
         for (String name : config.getStringArray("endpoints")) {
@@ -38,5 +38,5 @@
             }
             Configuration c = config.subset("endpoints." + name);
-            Parameters p = new Parameters(c.subset("entity"), name, null);
+            Parameters p = new Parameters(c.subset("entity"), name, null, null);
             Entity e = Program.configureEntity(p);
             Instance i = Casting.tryCast(Instance.class, e);
Index: /java/main/src/main/java/com/framsticks/params/AccessInterface.java
===================================================================
--- /java/main/src/main/java/com/framsticks/params/AccessInterface.java	(revision 77)
+++ /java/main/src/main/java/com/framsticks/params/AccessInterface.java	(revision 78)
@@ -80,15 +80,4 @@
 
 	/**
-	 * Load values from single line String.
-	 * 
-	 * @param line
-	 *            the line with values
-	 * @return the list of not severe exceptions which occurred while loading
-	 * @throws Exception
-	 *             the severe exception occurred while loading
-	 */
-	List<Exception> load2(String line) throws Exception;
-
-	/**
 	 * Removes all the properties values.
 	 */
@@ -107,3 +96,4 @@
     FramsClass getFramsClass();
 
+
 }
Index: /java/main/src/main/java/com/framsticks/params/FramsClass.java
===================================================================
--- /java/main/src/main/java/com/framsticks/params/FramsClass.java	(revision 77)
+++ /java/main/src/main/java/com/framsticks/params/FramsClass.java	(revision 78)
@@ -5,8 +5,11 @@
 import com.framsticks.params.types.FloatParam;
 import com.framsticks.params.types.StringParam;
+import com.framsticks.parsers.FileSource;
+import com.framsticks.parsers.Loaders;
 import com.framsticks.util.Casting;
 import org.apache.log4j.Logger;
 
 import javax.lang.model.element.TypeElement;
+import java.io.InputStream;
 import java.lang.reflect.*;
 import java.util.*;
@@ -58,5 +61,5 @@
 
 	public Collection<Param> getParamEntries() {
-		return paramEntryMap.values();
+		return paramList;
 	}
 
@@ -214,4 +217,10 @@
                 }
             }
+			if (rawType.equals(List.class)) {
+				Type containedType = p.getActualTypeArguments()[0];
+				if (containedType instanceof Class) {
+					return "l " + ((Class) containedType).getCanonicalName();
+				}
+			}
             return null;
         }
@@ -234,7 +243,9 @@
     public static final String GENERATE_HELP_PREFIX = "automatically generated from: ";
 
-
-
-    public static class Constructor {
+	public static FramsClass readFromStream(InputStream stream) {
+		return Loaders.loadFramsClass(new FileSource(stream));
+	}
+
+	public static class Constructor {
         protected final FramsClass result;
         protected Class currentClass;
@@ -249,4 +260,5 @@
                 currentClass = currentClass.getSuperclass();
             }
+			currentClass = src;
         }
 
@@ -254,4 +266,11 @@
             return result;
         }
+
+		public Constructor allFields() {
+			for (Field f : currentClass.getFields()) {
+				field(f.getName());
+			}
+			return this;
+		}
 
         public Constructor method(String name, Class<?> ... arguments) {
Index: /java/main/src/main/java/com/framsticks/params/ListAccess.java
===================================================================
--- /java/main/src/main/java/com/framsticks/params/ListAccess.java	(revision 77)
+++ /java/main/src/main/java/com/framsticks/params/ListAccess.java	(revision 78)
@@ -73,9 +73,4 @@
 	}
 
-	@Override
-	public List<Exception> load2(String line) throws Exception {
-		return null;
-	}
-
 	public AccessInterface getElementAccess() {
 		return elementAccess;
Index: /java/main/src/main/java/com/framsticks/params/Param.java
===================================================================
--- /java/main/src/main/java/com/framsticks/params/Param.java	(revision 77)
+++ /java/main/src/main/java/com/framsticks/params/Param.java	(revision 78)
@@ -109,5 +109,5 @@
         } catch (ClassCastException e) {
             throw new ClassCastException("property \"" + name
-                    + "\" getType is \"" + value.getClass().getName()
+                    + "\" type is \"" + value.getClass().getName()
                     + "\", not \"" + type.getName() + "\"");
         }
Index: /java/main/src/main/java/com/framsticks/params/PropertiesAccess.java
===================================================================
--- /java/main/src/main/java/com/framsticks/params/PropertiesAccess.java	(revision 77)
+++ /java/main/src/main/java/com/framsticks/params/PropertiesAccess.java	(revision 78)
@@ -20,7 +20,10 @@
     @Override
 	public Map<String, Object> createAccessee() {
+		return PropertiesAccess.createPropertiesMap();
+	}
+
+	public static Map<String, Object> createPropertiesMap() {
 		return new HashMap<String, Object>();
 	}
-
 
 	public PropertiesAccess(FramsClass framsClass) {
@@ -83,5 +86,3 @@
 
 
-
-
 }
Index: /java/main/src/main/java/com/framsticks/params/ReflectionAccess.java
===================================================================
--- /java/main/src/main/java/com/framsticks/params/ReflectionAccess.java	(revision 77)
+++ /java/main/src/main/java/com/framsticks/params/ReflectionAccess.java	(revision 78)
@@ -3,4 +3,6 @@
 import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Type;
 import java.util.List;
 
@@ -43,9 +45,9 @@
 			String id = param.getId();
 			try {
-				return type.cast(object.getClass().getField(id).get(object));
+				return type.cast(reflectedClass.getField(id).get(object));
 			} catch (NoSuchFieldException ignored) {
 			}
 			try {
-				return type.cast(object.getClass().getMethod(accessorName(true, id)).invoke(object));
+				return type.cast(reflectedClass.getMethod(accessorName(true, id)).invoke(object));
 			} catch (NoSuchMethodException ex) {
 				//ex.printStackTrace();
@@ -68,5 +70,5 @@
 	}
 
-	private <T> void setValue(Param param, T val) {
+	private <T> void setValue(Param param, T value) {
 		if (object == null) {
 			return;
@@ -75,16 +77,21 @@
 			String id = param.getId();
 			try {
-				object.getClass().getField(id).set(object, val);
+				Field f = reflectedClass.getField(id);
+				Class t = f.getType();
+				if (Modifier.isFinal(f.getModifiers())) {
+					return;
+				}
+				if (value != null || (!t.isPrimitive())) {
+					f.set(object, value);
+				}
 				return;
 			} catch (NoSuchFieldException ignored) {
 			}
 			try {
-				object.getClass().getMethod(accessorName(false, id), new Class[]{val.getClass()}).invoke(object, val);
-			} catch (InvocationTargetException e) {
-				//e.printStackTrace();
+				reflectedClass.getMethod(accessorName(false, id), new Class[]{param.getStorageType()}).invoke(object, value);
+			} catch (InvocationTargetException ignored) {
 			} catch (NoSuchMethodException ignored) {
 			}
-		} catch (IllegalAccessException ex) {
-			LOGGER.warn("illegal access error occurred while trying to access returnedObject");
+		} catch (Exception ex) {
 			ex.printStackTrace();
 		}
@@ -103,14 +110,9 @@
 		resetErrors();
 
-		Field[] fields;
 		try {
-			// TODO: conceptually invalid - should clean only fields that are specified in FramsClass
-			fields = object.getClass().getFields();
-
-			for (Field field : fields) {
-				field.set(object, null);
+			for (Param p : framsClass.getParamEntries()) {
+				setValue(p, p.getDef(Object.class));
 			}
-		} catch (IllegalAccessException ex) {
-			LOGGER.warn("IllegalAccessException thrown while trying to reset object values");
+		} catch (IllegalArgumentException ex) {
 			ex.printStackTrace();
 		}
@@ -125,4 +127,5 @@
 	@Override
 	public void select(Object object) {
+		assert object == null || reflectedClass.isInstance(object);
 		this.object = object;
 	}
@@ -166,5 +169,4 @@
         }
         LOGGER.fatal("failed to create reflected object of class " + reflectedClass.getCanonicalName() + " for frams type " + framsClass.getId());
-
         return null;
     }
Index: /java/main/src/main/java/com/framsticks/params/Registry.java
===================================================================
--- /java/main/src/main/java/com/framsticks/params/Registry.java	(revision 78)
+++ /java/main/src/main/java/com/framsticks/params/Registry.java	(revision 78)
@@ -0,0 +1,65 @@
+package com.framsticks.params;
+
+import org.apache.log4j.Logger;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Author: Piotr Śniegowski
+ */
+public class Registry {
+	private static final Logger LOGGER = Logger.getLogger(Registry.class.getName());
+
+	protected final Map<String, Class> reflectedClasses = new HashMap<String, Class>();
+	protected final Map<String, String> invertedReflectedClasses = new HashMap<String, String>();
+	protected final Map<String, FramsClass> infoCache = new HashMap<String, FramsClass>();
+
+	public final void registerReflectedClass(String name, String id, String className) {
+		try {
+			registerReflectedClass(name, id, Class.forName(className));
+		} catch (ClassNotFoundException e) {
+			LOGGER.fatal("class not found during registration: " + e);
+		}
+	}
+
+	public void registerReflectedClass(String name, String id, Class reflectedClass) {
+		if (name != null) {
+			reflectedClasses.put(name, reflectedClass);
+			invertedReflectedClasses.put(reflectedClass.getCanonicalName(), name);
+		}
+		if (id != null) {
+			reflectedClasses.put(id, reflectedClass);
+		}
+	}
+
+	public AccessInterface createAccess(String name, FramsClass framsClass) {
+		if (reflectedClasses.containsKey(name)) {
+			return new ReflectionAccess(reflectedClasses.get(name), framsClass);
+		}
+		return new PropertiesAccess(framsClass);
+	}
+
+	public void putInfoIntoCache(FramsClass framsClass) {
+		if (infoCache.containsKey(framsClass.getId())) {
+			LOGGER.info("already cached " + framsClass);
+			return;
+		}
+		LOGGER.debug("caching info for " + framsClass);
+		infoCache.put(framsClass.getId(), framsClass);
+		infoCache.put(framsClass.getName(), framsClass);
+	}
+
+	public FramsClass getInfoFromCache(String id) {
+		if (id == null) {
+			return null;
+		}
+		if (infoCache.containsKey(id)) {
+			return infoCache.get(id);
+		}
+		if (invertedReflectedClasses.containsKey(id)) {
+			return getInfoFromCache(invertedReflectedClasses.get(id));
+		}
+		return null;
+	}
+}
Index: /java/main/src/main/java/com/framsticks/params/SimpleAbstractAccess.java
===================================================================
--- /java/main/src/main/java/com/framsticks/params/SimpleAbstractAccess.java	(revision 77)
+++ /java/main/src/main/java/com/framsticks/params/SimpleAbstractAccess.java	(revision 78)
@@ -38,17 +38,13 @@
 		this.framsClass = framsClass;
 	}
-
-
-
-
     /**
 	 * Simple String key, value class.
 	 */
-	private static class Entry {
-
-		String key;
-		String value;
-
-		Entry(String key, String value) {
+	public static class Entry {
+
+		public final String key;
+		public final String value;
+
+		public Entry(String key, String value) {
 			this.key = key;
 			this.value = value;
@@ -331,5 +327,4 @@
 
         Entry entry;
-
         while ((entry = readEntry(source)) != null) {
             Param param = getParam(entry.key);
@@ -351,138 +346,6 @@
     }
 
-    @Override
-	public List<Exception> load2(String line) throws Exception {
-		this.clearValues();
-
-		// list of not terminable exceptions that occured
-		List<Exception> exceptions = new ArrayList<Exception>();
-
-		int indexOfColon = line.indexOf(':');
-		if (indexOfColon < 0)
-			indexOfColon = line.length();
-		String classId = line.substring(0, indexOfColon).trim();
-		if (!getId().equals(classId))
-			throw new Exception(
-					"Inappropriate getId of param interface (class), specified \""
-							+ classId + "\" while should be \"" + getId()
-							+ "\"");
-		String parameters;
-		if (indexOfColon == line.length())
-			parameters = "";
-		else
-			parameters = line.substring(indexOfColon + 1);
-
-		// tokenize
-		boolean doubleQuotes = false;
-		char previousChar = ',';
-		List<Entry> result = new ArrayList<Entry>();
-		StringBuilder stringBuilder = new StringBuilder();
-		String key = "";
-		if (parameters.trim().length() > 0) {
-			for (char currentChar : parameters.toCharArray()) {
-				if (!doubleQuotes && currentChar == '=' && "".equals(key)) {
-					key = stringBuilder.toString();
-					stringBuilder = new StringBuilder();
-				} else if (!doubleQuotes && currentChar == ',') {
-					if (previousChar == ',') {
-						result.add(new Entry(key.trim(), null));
-					} else {
-						result.add(new Entry(key.trim(), stringBuilder
-								.toString().trim()));
-					}
-					stringBuilder = new StringBuilder();
-					key = "";
-				} else if (currentChar == '"') {
-					if (previousChar == '\\') {
-						stringBuilder.deleteCharAt(stringBuilder.length() - 1);
-						stringBuilder.append(currentChar);
-					} else
-						doubleQuotes = !doubleQuotes;
-				} else {
-					stringBuilder.append(currentChar);
-				}
-
-				previousChar = currentChar;
-			}
-
-			String last = stringBuilder.toString().trim();
-			// if (last.length() > 0 || previousChar == '\"'
-			// || previousChar == ':')
-			result.add(new Entry(key.trim(), last));
-
-			if (doubleQuotes)
-				throw new Exception(
-						"Double quotes expected while end of line met");
-		}
-
-		// if successfully parsed set all necessary values
-
-		//TODO: name omitting
-		Param currentParam = null;
-		boolean illegallyOmittedName = false;
-		for (Entry pair : result) {
-			try {
-
-				if (pair.key != null && !"".equals(pair.key)) {
-					Param param = getParam(pair.key);
-					if (param == null) {
-						illegallyOmittedName = true;
-						throw new Exception("No parameter with such id: "
-								+ pair.key);
-					} else {
-						currentParam = param;
-						illegallyOmittedName = false;
-					}
-				} else if (illegallyOmittedName
-						|| (currentParam.getFlags() & Flags.CANOMITNAME) == 0) {
-					throw new Exception(
-							"Parameter with offset: "
-									+ currentParam
-									+ " is not set, "
-									+ "because it's definition or definition of one of the previous params "
-									+ "does not contain flag, which allow to skip the getName (flag 1024)");
-				}
-
-				if (pair.value != null) {
-					int setFlag = this.set(currentParam, pair.value);
-					if ((setFlag & Flags.PSET_HITMIN) != 0) {
-						exceptions.add(createBoundaryHitException(currentParam, pair.value, Flags.PSET_HITMIN));
-					}
-
-					if ((setFlag & Flags.PSET_HITMAX) != 0) {
-						exceptions.add(createBoundaryHitException(currentParam, pair.value, Flags.PSET_HITMAX));
-					}
-
-					if ((setFlag & Flags.PSET_RONLY) != 0) {
-						throw (new Exception(
-								"Tried to set a read-only attribute \""
-										+ currentParam.getId()
-										+ "\" in class \"" + getId() + "\""));
-					}
-				}
-
-			} catch (Exception e) {
-				exceptions.add(e);
-			//} finally {
-			//  currentProperty++;
-			}
-		}
-		return exceptions;
-	}
-
-	private Exception createBoundaryHitException(Param param, String value, int flag) {
-		boolean minimum = (flag & Flags.PSET_HITMIN) != 0;
-		String boundary = (minimum ? param.getMin(Object.class) : param.getMax(Object.class)).toString();
-		String name =  (minimum ? "minimum" : "maximum");
-		return new Exception("Tried to set attribute \""
-				+ param.getId()
-				+ "\" in class \""
-				+ getId()
-				+ "\" to value which exceeds " + name + " ("
-				+ value
-				+ "), truncated to: "
-				+ boundary);
-	}
-	
+
+
 	protected abstract <T> void internalSet(Param param, T value);
 
Index: /java/main/src/main/java/com/framsticks/params/Util.java
===================================================================
--- /java/main/src/main/java/com/framsticks/params/Util.java	(revision 77)
+++ /java/main/src/main/java/com/framsticks/params/Util.java	(revision 78)
@@ -1,3 +1,6 @@
 package com.framsticks.params;
+
+import java.util.ArrayList;
+import java.util.List;
 
 /**
@@ -14,3 +17,25 @@
         return result.toString();
     }
+	public static List<Object> stripAccessInterface(List<AccessInterface> accesses) {
+		List<Object> result = new ArrayList<Object>();
+		for (AccessInterface a : accesses) {
+			result.add(a.getSelected());
+		}
+		return result;
+	}
+	public static int copyParams(AccessInterface to, AccessInterface from) {
+		int copied = 0;
+		for (Param f : from.getParams()) {
+			Param t = from.getParam(f.getId());
+			if (t == null) {
+				continue;
+			}
+			if (to.getClass() != f.getClass()) {
+				continue;
+			}
+			to.set(t, from.get(f, Object.class));
+			++copied;
+		}
+		return copied;
+	}
 }
Index: /java/main/src/main/java/com/framsticks/parsers/F0Parser.java
===================================================================
--- /java/main/src/main/java/com/framsticks/parsers/F0Parser.java	(revision 78)
+++ /java/main/src/main/java/com/framsticks/parsers/F0Parser.java	(revision 78)
@@ -0,0 +1,258 @@
+package com.framsticks.parsers;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.text.ParseException;
+import java.util.ArrayList;
+import java.util.List;
+
+import com.framsticks.model.F0Genotype;
+import static com.framsticks.params.SimpleAbstractAccess.*;
+
+import com.framsticks.params.Flags;
+import com.framsticks.params.Param;
+import com.framsticks.util.Exceptions;
+import com.framsticks.util.Pair;
+import com.framsticks.util.Strings;
+import org.apache.log4j.Logger;
+
+import com.framsticks.params.FramsClass;
+import com.framsticks.params.AccessInterface;
+
+/**
+ * The class Parser is used to parse genotype encoded in f0 representation.
+ */
+public class F0Parser {
+
+	private final static Logger LOGGER = Logger.getLogger(F0Parser.class);
+
+	/** The schema proper for f0 representation. */
+	protected final Schema schema;
+	protected final InputStream is;
+	protected final List<AccessInterface> result = new ArrayList<AccessInterface>();
+	int lineNumber = 0;
+
+	public F0Parser(Schema schema, InputStream is) {
+		assert schema != null;
+		assert is != null;
+		this.schema = schema;
+		this.is = is;
+	}
+
+	protected AccessInterface processLine(String line) {
+		try {
+
+			Pair<String, String> p = Strings.splitIntoPair(line, ':', "");
+			String classId = p.first.trim();
+			FramsClass framsClass = schema.getRegistry().getInfoFromCache(classId);
+			if (framsClass == null) {
+				throw new Exception("unknown class id: " + classId);
+			}
+			AccessInterface access = schema.getRegistry().createAccess(classId, framsClass);
+			access.select(access.createAccessee());
+			for (Exception e : loadFromLine(access, p.second)) {
+				warn(lineNumber, "however entry was added", e);
+			}
+			return access;
+		} catch (Exception e) {
+			warn(lineNumber, "entry was not added", e);
+		}
+		return null;
+	}
+
+	/**
+	 * Parses the stream with genotype in f0 representation. The correctness of
+	 * genotype is checked. IO and syntax exceptions interrupts parsing and no
+	 * result is returned. Other exceptions, connected with schema validation
+	 * cause that certain object or it's parameter is ignored (appropriate
+	 * communicate informs user about it). Inappropriate values in numeric
+	 * fields (bigger than maximum or smaller than minimum values) are
+	 * communicated by warnings and set to minimum / maximum value.
+	 * 
+	 * @return the list
+	 * @throws IOException
+	 *             Signals that an I/O exception has occurred.
+	 * @throws ParseException
+	 *             the parse exception
+	 */
+	public List<AccessInterface> parse() throws IOException,
+			ParseException {
+
+		InputStreamReader reader = null;
+		try {
+			reader = new InputStreamReader(is, "UTF-8");
+			BufferedReader br = new BufferedReader(reader);
+			while (br.ready()) {
+				++lineNumber;
+				String line = br.readLine();
+				line = (line == null ? "" : line.trim());
+				if (lineNumber == 1) {
+					if (!"//0".equals(line)) {
+						LOGGER.warn("stream should begin with \"//0\" in the first line");
+					} else {
+						continue;
+					}
+				}
+				if (line.equals("")) {
+					continue;
+				}
+				if (line.startsWith("#")) {
+					continue;
+				}
+				AccessInterface access = processLine(line);
+				if (access != null) {
+					result.add(access);
+				}
+			}
+
+			/** If no 'm' (Model) line was found, than simulate it on the beginning of the result.*/
+			if (result.isEmpty() || !(result.get(0) instanceof F0Genotype)) {
+				result.add(0, processLine("m:"));
+			}
+		} finally {
+			if (reader != null) {
+				reader.close();
+			}
+		}
+
+		return result;
+	}
+
+	private static void warn(int lineNumber, String message, Exception e) {
+		LOGGER.warn("in line " + lineNumber + " the following error occurred (" + message + "): " + e + "\n" + Exceptions.printStackTrace(e));
+	}
+
+	/** Breaks string into entries.*/
+	public List<Entry> breakIntoEntries(String parameters) throws Exception {
+		// tokenize
+		boolean inQuotes = false;
+		char previousChar = ',';
+		List<Entry> result = new ArrayList<Entry>();
+		StringBuilder stringBuilder = new StringBuilder();
+		String key = null;
+		if (parameters.trim().length() > 0) {
+			for (char currentChar : parameters.toCharArray()) {
+				if (!inQuotes && (currentChar == '=') && (key == null)) {
+					key = stringBuilder.toString().trim();
+					stringBuilder = new StringBuilder();
+				} else if (!inQuotes && currentChar == ',') {
+					if (previousChar == ',') {
+						result.add(new Entry(key, null));
+					} else {
+						result.add(new Entry(key, stringBuilder.toString().trim()));
+					}
+					stringBuilder = new StringBuilder();
+					key = null;
+				} else if (currentChar == '"') {
+					if (previousChar == '\\') {
+						stringBuilder.deleteCharAt(stringBuilder.length() - 1);
+						stringBuilder.append(currentChar);
+					} else {
+						inQuotes = !inQuotes;
+					}
+				} else {
+					stringBuilder.append(currentChar);
+				}
+
+				previousChar = currentChar;
+			}
+
+			result.add(new Entry(key, stringBuilder.toString().trim()));
+
+			if (inQuotes) {
+				throw new Exception("Double quotes expected while end of line met");
+			}
+		}
+		return result;
+	}
+
+	public List<Exception> loadFromLine(AccessInterface access, String parameters) throws Exception {
+
+		List<Entry> entries = breakIntoEntries(parameters);
+
+		List<Exception> exceptions = new ArrayList<Exception>();
+
+		Param[] params = access.getParams().toArray(new Param[] {null});
+		if (params.length == 0) {
+			return exceptions;
+		}
+		for (Param p : params) {
+			Object def = p.getDef(Object.class);
+			if (def != null) {
+				access.set(p, def);
+			}
+		}
+
+		int number = -1;
+		Integer nextParamNumber = 0;
+		for (Entry pair : entries) {
+			++number;
+			try {
+				Param currentParam;
+				if (pair.key != null) {
+					currentParam = access.getParam(pair.key);
+					if (currentParam == null) {
+						nextParamNumber = null;
+						throw new Exception("no parameter with such id: " + pair.key);
+					}
+				} else {
+					if (nextParamNumber == null || ((params[nextParamNumber].getFlags() & Flags.CANOMITNAME) == 0)) {
+						nextParamNumber = null;
+						throw new Exception(
+								"parameter with offset: "
+										+ number
+										+ " is not set, "
+										+ "because it's definition or definition of the previous param "
+										+ "does not contain flag, which allows to skip the name (flag 1024)");
+					}
+					currentParam = params[nextParamNumber];
+				}
+
+				if (currentParam != null) {
+					if (pair.value != null) {
+						int setFlag = access.set(currentParam, pair.value);
+						if ((setFlag & Flags.PSET_HITMIN) != 0) {
+							exceptions.add(createBoundaryHitException(access, currentParam, pair.value, Flags.PSET_HITMIN));
+						}
+
+						if ((setFlag & Flags.PSET_HITMAX) != 0) {
+							exceptions.add(createBoundaryHitException(access, currentParam, pair.value, Flags.PSET_HITMAX));
+						}
+
+						if ((setFlag & Flags.PSET_RONLY) != 0) {
+							throw (new Exception("tried to set a read-only attribute \""
+								+ currentParam.getId()
+								+ "\" in class \"" + access.getId() + "\""));
+						}
+					}
+					nextParamNumber = null;
+					for (int j = params.length - 1; j > 0; --j) {
+						if (params[j - 1] == currentParam) {
+							nextParamNumber = j;
+						}
+					}
+				}
+
+			} catch (Exception e) {
+				exceptions.add(e);
+			}
+		}
+		return exceptions;
+	}
+
+	private static Exception createBoundaryHitException(AccessInterface access, Param param, String value, int flag) {
+		boolean minimum = (flag & Flags.PSET_HITMIN) != 0;
+		String boundary = (minimum ? param.getMin(Object.class) : param.getMax(Object.class)).toString();
+		String name =  (minimum ? "minimum" : "maximum");
+		return new Exception("Tried to set attribute \""
+				+ param.getId()
+				+ "\" in class \""
+				+ access.getId()
+				+ "\" to value which exceeds " + name + " ("
+				+ value
+				+ "), truncated to: "
+				+ boundary);
+	}
+}
Index: /java/main/src/main/java/com/framsticks/parsers/FileSource.java
===================================================================
--- /java/main/src/main/java/com/framsticks/parsers/FileSource.java	(revision 77)
+++ /java/main/src/main/java/com/framsticks/parsers/FileSource.java	(revision 78)
@@ -3,7 +3,5 @@
 import com.framsticks.params.SourceInterface;
 
-import java.io.BufferedReader;
-import java.io.FileReader;
-import java.io.IOException;
+import java.io.*;
 
 
@@ -17,4 +15,9 @@
 		this.filename = filename;
         reader = new BufferedReader(new FileReader(filename));
+	}
+
+	public FileSource(InputStream stream) {
+		filename = "<stream>";
+		reader = new BufferedReader(new InputStreamReader(stream));
 	}
 
Index: va/main/src/main/java/com/framsticks/parsers/Parser.java
===================================================================
--- /java/main/src/main/java/com/framsticks/parsers/Parser.java	(revision 77)
+++ 	(revision )
@@ -1,114 +1,0 @@
-package com.framsticks.parsers;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.text.ParseException;
-import java.util.ArrayList;
-import java.util.List;
-
-import com.framsticks.params.PropertiesAccess;
-import org.apache.log4j.Logger;
-
-import com.framsticks.params.FramsClass;
-import com.framsticks.params.AccessInterface;
-
-/**
- * The class Parser is used to parse genotype encoded in f0 representation.
- */
-public class Parser {
-
-	private final static Logger logger = Logger.getLogger(Parser.class);
-
-	/** The schema proper for f0 representation. */
-	private Schema schema;
-
-	public Parser(Schema schema) {
-		if (schema == null)
-			throw new NullPointerException(
-					"Schema object passed to Parser object cannot be null!");
-		this.schema = schema;
-	}
-
-	/**
-	 * Parses the stream with genotype in f0 representation. The correctness of
-	 * genotype is checked. IO and syntax exceptions interrupts parsing and no
-	 * result is returned. Other exceptions, connected with schema validation
-	 * cause that certain object or it's parameter is ignored (appropriate
-	 * communicate informs user about it). Inappropriate values in numeric
-	 * fields (bigger than maximum or smaller than minimum values) are
-	 * communicated by warnings and set to minimum / maximum value.
-	 * 
-	 * @param is
-	 *            the is
-	 * @return the list
-	 * @throws IOException
-	 *             Signals that an I/O exception has occurred.
-	 * @throws ParseException
-	 *             the parse exception
-	 */
-	public List<AccessInterface> parse(InputStream is) throws IOException,
-			ParseException {
-		List<AccessInterface> result = new ArrayList<AccessInterface>();
-
-		InputStreamReader isr = null;
-		try {
-			isr = new InputStreamReader(is, "UTF-8");
-			BufferedReader br = new BufferedReader(isr);
-			int l = 0;
-			while (br.ready()) {
-				String line = br.readLine();
-				if (line == null)
-					line = "";
-				else
-					line = line.trim();
-				if (l == 0) {
-					if (!"//0".equals(line)) {
-						logger.warn("stream should begin with \"//0\" in first line");
-					} else {
-						l++;
-						continue;
-					}
-				}
-				if (line.equals("")) {
-					l++;
-					continue;
-				}
-				try {
-					int indexOfColon = line.indexOf(':');
-					if (indexOfColon < 0) {
-						indexOfColon = line.length();
-					}
-					String classId = line.substring(0, indexOfColon).trim();
-					FramsClass framsClass = schema.getMainClasses()
-							.get(classId);
-					if (framsClass == null)
-						throw new Exception("Unknown class getId: " + classId);
-					PropertiesAccess propertiesParam = new PropertiesAccess(framsClass);
-                    propertiesParam.select(propertiesParam.createAccessee());
-					List<Exception> exceptions = propertiesParam.load2(line);
-					for (Exception e : exceptions) {
-						logger.warn("In line "
-										+ Integer.valueOf(l + 1)
-										+ " the following error occured (however entry was added): "
-										+ e.getMessage());
-					}
-					result.add(propertiesParam);
-				} catch (Exception e) {
-					logger.warn("In line "
-									+ Integer.valueOf(l + 1)
-									+ " the following error occured (entry was not added): "
-									+ e.getMessage());
-				} finally {
-					l++;
-				}
-			}
-		} finally {
-			if (isr != null)
-				isr.close();
-		}
-
-		return result;
-	}
-}
Index: /java/main/src/main/java/com/framsticks/parsers/Schema.java
===================================================================
--- /java/main/src/main/java/com/framsticks/parsers/Schema.java	(revision 77)
+++ /java/main/src/main/java/com/framsticks/parsers/Schema.java	(revision 78)
@@ -1,4 +1,6 @@
 package com.framsticks.parsers;
 
+import java.io.File;
+import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStream;
@@ -8,7 +10,7 @@
 import java.util.Map.Entry;
 
-import com.framsticks.params.FramsClass;
-import com.framsticks.params.Param;
+import com.framsticks.params.*;
 import com.framsticks.params.types.DecimalParam;
+import com.framsticks.params.types.FloatParam;
 import com.framsticks.params.types.StringParam;
 import org.apache.log4j.Logger;
@@ -19,6 +21,4 @@
 
 import com.framsticks.leftovers.f0.NeuroClass;
-import com.framsticks.params.Group;
-import com.framsticks.params.ParamBuilder;
 import org.w3c.dom.Document;
 import org.w3c.dom.NamedNodeMap;
@@ -39,21 +39,12 @@
 	private final static Logger logger = Logger.getLogger(Schema.class);
 
-	/** The main classes (such as part, joint, etc.) */
-	private Map<String, FramsClass> mainClasses = new HashMap<String, FramsClass>();
+	protected final Registry registry = new Registry();
 
 	/** The neuro classes (classess representing different types of neurons). */
 	private Map<String, NeuroClass> neuroClasses = new HashMap<String, NeuroClass>();
 
-	// TODO: definition can be changed
-	/**
-	 * Instantiates a new schema with usage of f0def.xml file stored in
-	 * resources.
-	 * 
-	 * @throws Exception
-	 *             the exception if one occured while reading the stream
-	 */
-	public Schema() throws Exception {
-		this(Thread.currentThread().getContextClassLoader()
-				.getResourceAsStream("f0def.xml"));
+	public static InputStream getDefaultDefinitionAsStream() {
+		//return new FileInputStream(new File(Schema.class.getResource("/parsers/f0def.xml").getPath()));
+		return Schema.class.getResourceAsStream("/parsers/f0def.xml");
 	}
 
@@ -61,10 +52,10 @@
 	 * Instantiates a new schema.
 	 * 
-	 * @param xmlStream
+	 * @param inputStream
 	 *            the xml stream with schema
 	 * @throws Exception
-	 *             the exception if one occured while reading the stream
-	 */
-	public Schema(InputStream xmlStream) throws Exception {
+	 *             the exception if one occurred while reading the stream
+	 */
+	public Schema(InputStream inputStream) throws Exception {
 
 		DocumentBuilderFactory factory;
@@ -75,5 +66,5 @@
 			db = factory.newDocumentBuilder();
 
-			Document document = db.parse(xmlStream);
+			Document document = db.parse(inputStream);
 			NodeList classes = document.getElementsByTagName("CLASS");
 
@@ -81,5 +72,5 @@
 				Node classNode = classes.item(i);
 				FramsClass framsClass = processClass(classNode);
-				mainClasses.put(framsClass.getId(), framsClass);
+				registry.putInfoIntoCache(framsClass);
 			}
 
@@ -106,5 +97,5 @@
 							symbolGlymph[j] = Integer.parseInt(sgha[j]);
 						} catch (NumberFormatException e) {
-							logger.error("an error occured while parsing symbol glymph, class getId: "
+							logger.error("an error occurred while parsing symbol glymph, class getId: "
 									+ framsClass.getId()
 									+ ", glymph offset: " + j);
@@ -119,11 +110,11 @@
 
 		} catch (IOException e) {
-			logger.fatal("unexpected exception occured: ", e);
+			logger.fatal("unexpected exception occurred: ", e);
 			throw e;
 		} catch (ParserConfigurationException e) {
-			logger.fatal("unexpected exception occured: ", e);
+			logger.fatal("unexpected exception occurred: ", e);
 			throw e;
 		} catch (SAXException e) {
-			logger.fatal("unexpected exception occured: ", e);
+			logger.fatal("unexpected exception occurred: ", e);
 			throw e;
 		}
@@ -140,11 +131,15 @@
 	 */
 	private static int getIntAttribute(NamedNodeMap attributes, String name) {
+		String v = getAttribute(attributes, name);
+		if (v == null) {
+			return 0;
+		}
 		try {
-			return Integer.parseInt(getAttribute(attributes, name));
+			return Integer.parseInt(v);
 		} catch (NullPointerException e) {
 			return 0;
 		} catch (NumberFormatException e) {
 			logger.fatal("attribute " + name
-					+ " should be numeric (it is not)");
+					+ " should be numeric: " + v);
 			return 0;
 		}
@@ -186,5 +181,5 @@
 	 *             the exception in case of any error
 	 */
-	private FramsClass processClass(Node classNode) throws Exception {
+	private static FramsClass processClass(Node classNode) throws Exception {
 		String classId = null;
 		String className = "";
@@ -200,6 +195,5 @@
 		classDescription = getAttributeFromNode("DESCRIPTION", classNode);
 
-		FramsClass framsClass = new FramsClass(classId, className,
-				classDescription);
+		FramsClass framsClass = new FramsClass(classId, className, classDescription);
 
 		NodeList classProperties = classNode.getChildNodes();
@@ -210,12 +204,11 @@
 			if ("GROUP".equals(node.getNodeName())) {
 				NamedNodeMap attributes = node.getAttributes();
-				String name = attributes.getNamedItem("NAME") == null ? null
-						: attributes.getNamedItem("NAME").getNodeValue();
-				if (name == null)
-					logger.warn("Group getName in class \"" + classId + "\" ("
+				String name = getAttribute(attributes, "NAME");
+				if (name == null) {
+					logger.warn("Group name in class \"" + classId + "\" ("
 							+ className + ") is undefined");
-				else
+				} else {
 					framsClass.appendGroup(new Group(name));
-
+				}
 			} else if ("PROP".equals(node.getNodeName())
 					|| "NEUROPROP".equals(node.getNodeName())) {
@@ -232,5 +225,5 @@
 
 	/**
-	 * It analyses the single property within the clas
+	 * It analyses the single property within the class
 	 * 
 	 * @param attributes
@@ -242,5 +235,5 @@
 	 *             the exception in case of any error
 	 */
-	private Param processParameter(NamedNodeMap attributes, String classId)
+	private static Param processParameter(NamedNodeMap attributes, String classId)
 			throws Exception {
 
@@ -315,5 +308,5 @@
 				}
 			}
-			builder.setType(DecimalParam.class);
+			builder.setType(FloatParam.class);
 			builder.setMin(minMaxDefDouble.get("MIN"));
 			builder.setMax(minMaxDefDouble.get("MAX"));
@@ -330,7 +323,4 @@
 	}
 
-	public Map<String, FramsClass> getMainClasses() {
-		return Collections.unmodifiableMap(mainClasses);
-	}
 
 	public Map<String, NeuroClass> getNeuroClasses() {
@@ -338,3 +328,8 @@
 	}
 
+	public final Registry getRegistry() {
+		return registry;
+	}
+
+
 }
Index: /java/main/src/main/java/com/framsticks/portals/Portal.java
===================================================================
--- /java/main/src/main/java/com/framsticks/portals/Portal.java	(revision 77)
+++ /java/main/src/main/java/com/framsticks/portals/Portal.java	(revision 78)
@@ -36,5 +36,5 @@
 
     @Override
-    protected void configure() {
+    protected void configure() throws Exception {
         super.configure();
     }
Index: /java/main/src/main/java/com/framsticks/util/Exceptions.java
===================================================================
--- /java/main/src/main/java/com/framsticks/util/Exceptions.java	(revision 78)
+++ /java/main/src/main/java/com/framsticks/util/Exceptions.java	(revision 78)
@@ -0,0 +1,15 @@
+package com.framsticks.util;
+
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+/**
+ * Author: Piotr Śniegowski
+ */
+public class Exceptions {
+	public static String printStackTrace(Throwable throwable) {
+		StringWriter w = new StringWriter();
+		throwable.printStackTrace(new PrintWriter(w));
+		return w.getBuffer().toString();
+	}
+}
Index: /java/main/src/main/java/com/framsticks/util/Orientation.java
===================================================================
--- /java/main/src/main/java/com/framsticks/util/Orientation.java	(revision 77)
+++ /java/main/src/main/java/com/framsticks/util/Orientation.java	(revision 78)
@@ -9,10 +9,71 @@
     public final Point3d z;
 
-    public Orientation() {
-        x = new Point3d();
-        y = new Point3d();
-        z = new Point3d();
-    }
+	public Orientation(Point3d x, Point3d y, Point3d z) {
+		this.x = x;
+		this.y = y;
+		this.z = z;
+	}
+
+	public Orientation() {
+		x = new Point3d(1, 0, 0);
+		y = new Point3d(0, 1, 0);
+		z = new Point3d(0, 0, 1);
+	}
+
+	/** based on c++ void Orient::transform(Pt3D& target,const Pt3D &s) const */
+	public Point3d transform(Point3d source) {
+		Point3d.Builder b = new Point3d.Builder();
+		for (int i = 0; i < 3; ++i) {
+			double v = 0;
+			for (int j = 0; j < 3; ++j) {
+				v += source.get(j) * this.get(j).get(i);
+			}
+			b.set(i, v);
+		}
+		return b.build();
+	}
+
+	/** based on c++ void Orient::transform(Orient& target,const Orient& src) const */
+	public Orientation transform(Orientation source) {
+		return new Orientation(transform(source.x), transform(source.y), transform(source.z));
+	}
+
+	protected static Point3d rotate2D(double sin, double cos, Point3d p, int a0, int a1, int im) {
+		Point3d.Builder b = new Point3d.Builder();
+		b.set(a0, cos * p.get(a0) - sin * p.get(a1));
+		b.set(a1, sin * p.get(a0) + cos * p.get(a1));
+		b.set(im, p.get(im));
+		return b.build();
+	}
+
+	/** based on c++ Orient::rotate(const Pt3D &v) */
+	public Orientation rotate(Point3d v) {
+		Point3d[] p = new Point3d[] {x, y, z};
+
+		for (int i = 0; i < 3; ++i) {
+			double sin = Math.sin(v.get(i));
+			double cos = Math.cos(v.get(i));
+
+			for (int j = 0; j < 3; ++j) {
+				p[j] = rotate2D(sin, cos, p[j], i == 0 ? 1 : 0, i == 2 ? 1 : 2, i);
+			}
+		}
+		return new Orientation(p[0], p[1], p[2]);
+	}
+
+	final Point3d get(int i) {
+		switch (i) {
+			case 0: return x;
+			case 1: return y;
+			case 2: return z;
+		}
+		assert false;
+		return null;
+	}
 
 
+	@Override
+	public final String toString() {
+		return x + " | " + y + " | " + z;
+	}
 }
Index: /java/main/src/main/java/com/framsticks/util/Point3d.java
===================================================================
--- /java/main/src/main/java/com/framsticks/util/Point3d.java	(revision 77)
+++ /java/main/src/main/java/com/framsticks/util/Point3d.java	(revision 78)
@@ -6,7 +6,7 @@
 public class Point3d
 {
-	public Double x;
-	public Double y;
-	public Double z;
+	public final double x;
+	public final double y;
+	public final double z;
 
 	public Point3d() {
@@ -16,5 +16,5 @@
 	}
 
-	public Point3d(Double x, Double y, Double z) {
+	public Point3d(double x, double y, double z) {
 		this.x = x;
 		this.y = y;
@@ -22,8 +22,46 @@
 	}
 
+	public Point3d(Point3d p) {
+		x = p.x;
+		y = p.y;
+		z = p.z;
+	}
+
 	@Override
-	public String toString() {
-		//return new StringBuilder().append(x).append(" ").append(y).append(" ").append("z").toString();
+	public final String toString() {
 		return x + " " + y + " " + z;
 	}
+
+	public final double get(int i) {
+		switch (i) {
+			case 0: return x;
+			case 1: return y;
+			case 2: return z;
+		}
+		assert false;
+		return 0;
+	}
+
+
+	public final Point3d add(Point3d p) {
+		return new Point3d(x + p.x, y + p.y, z + p.z);
+	}
+
+	public final Point3d sub(Point3d p) {
+		return new Point3d(x - p.x, y - p.y, z - p.z);
+	}
+
+	public final double length() {
+		return Math.sqrt(x * x + y * y + z * z);
+	}
+
+	public static class Builder {
+		double[] a = new double[3];
+
+		public Point3d build() { return new Point3d(a[0], a[1], a[2]); }
+
+		public final void set(int i, double v) {
+			a[i] = v;
+		}
+	}
 }
Index: va/main/src/main/java/com/framsticks/util/ProgramArguments.java
===================================================================
--- /java/main/src/main/java/com/framsticks/util/ProgramArguments.java	(revision 77)
+++ 	(revision )
@@ -1,65 +1,0 @@
-package com.framsticks.util;
-
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-/**
- * @author Piotr Sniegowski
- */
-public class ProgramArguments {
-
-	private final Map<String, List<String>> arguments = new HashMap<String, List<String>>();
-
-	public ProgramArguments(String[] args) {
-		int a = 0;
-		while (a < args.length) {
-			if (args[a].startsWith("--")) {
-				String argumentName = args[a].substring(2);
-
-				String argumentValue;
-				if (a + 1 < args.length && (!args[a + 1].startsWith("--"))) {
-					argumentValue = args[a + 1];
-					a += 2;
-				} else {
-					argumentValue = null;
-					a += 1;
-				}
-
-				List<String> argumentValues;
-				if (arguments.containsKey(argumentName)) {
-					argumentValues = arguments.get(argumentName);
-				} else {
-					argumentValues = new ArrayList<String>();
-					arguments.put(argumentName, argumentValues);
-				}
-				argumentValues.add(argumentValue);
-			}
-		}
-
-	}
-
-	public void forEach(String argument, UnaryFunctor<Boolean, String> functor) {
-		if (!arguments.containsKey(argument)) {
-			return;
-		}
-		for (String v : arguments.get(argument)) {
-			if (!functor.call(v)) {
-				break;
-			}
-		}
-	}
-
-	public String getSingle(String argument, String defValue) {
-		if (!arguments.containsKey(argument)) {
-			return defValue;
-		}
-		List<String> values = arguments.get(argument);
-		if (values.size() != 1) {
-			return defValue;
-		}
-		return values.get(0);
-	}
-
-}
Index: /java/main/src/main/java/com/framsticks/viewer/SimpleViewer.java
===================================================================
--- /java/main/src/main/java/com/framsticks/viewer/SimpleViewer.java	(revision 78)
+++ /java/main/src/main/java/com/framsticks/viewer/SimpleViewer.java	(revision 78)
@@ -0,0 +1,14 @@
+package com.framsticks.viewer;
+
+import com.framsticks.core.Entity;
+import com.framsticks.core.Parameters;
+
+/**
+ * Author: Piotr Śniegowski
+ */
+public class SimpleViewer extends Entity {
+
+	public SimpleViewer(Parameters parameters) {
+		super(parameters);
+	}
+}
Index: /java/main/src/main/java/com/framsticks/visualization/Viewer.java
===================================================================
--- /java/main/src/main/java/com/framsticks/visualization/Viewer.java	(revision 77)
+++ /java/main/src/main/java/com/framsticks/visualization/Viewer.java	(revision 78)
@@ -1,5 +1,4 @@
 package com.framsticks.visualization;
 
-import com.framsticks.communication.Connection;
 import com.framsticks.model.World;
 import com.sun.j3d.loaders.IncorrectFormatException;
@@ -22,14 +21,10 @@
 import java.awt.event.ActionListener;
 import java.io.FileNotFoundException;
-import java.util.ArrayList;
 
 import org.apache.log4j.Logger;
 
-
-
 public class Viewer {
-    static final long serialVersionUID = 1;
-
-    private static Logger logger = Logger.getLogger(Viewer.class);
+
+    private static Logger LOGGER = Logger.getLogger(Viewer.class);
 
     Canvas3D canvas3d;
@@ -45,10 +40,6 @@
     private JCheckBoxMenuItem autorefreshItem;
 
-	private Connection connection;
-    ArrayList<String> args;
-
-    public Viewer(ArrayList<String> args, JMenuBar menuBar) {
+    public Viewer(JMenuBar menuBar) {
         super();
-        this.args = args;
         this.menuBar = menuBar;
         loggingItem = new JCheckBoxMenuItem("Logging");
@@ -56,5 +47,4 @@
 
         init();
-
     }
 
@@ -261,11 +251,4 @@
     }
 
-
-
-
-    public void setCommunication(Connection connection) {
-        this.connection = connection;
-    }
-
     public void rebuildViewMenu(Object creatures) {
 
Index: /java/main/src/main/resources/configs/framsticks.properties
===================================================================
--- /java/main/src/main/resources/configs/framsticks.properties	(revision 77)
+++ /java/main/src/main/resources/configs/framsticks.properties	(revision 78)
@@ -1,11 +1,11 @@
 com.framsticks.entities.browser.class=com.framsticks.gui.Browser
-#com.framsticks.entities.browser.endpoints=localhost,dump,remote_portal
 com.framsticks.entities.browser.size.width=1500
 com.framsticks.entities.browser.size.height=800
-com.framsticks.entities.browser.endpoints=localhost,dump
+com.framsticks.entities.browser.endpoints=localhost,dump,genotype_browser
 com.framsticks.entities.browser.endpoints.dump.entity.class=com.framsticks.dumping.FileInstance
 com.framsticks.entities.browser.endpoints.dump.entity.filename=dumps/localhost:9009__.param
 com.framsticks.entities.browser.endpoints.localhost.entity.mount=com.framsticks.entities.localhost
 com.framsticks.entities.browser.endpoints.remote_portal.entity.mount=com.framsticks.entities.remote_portal
+com.framsticks.entities.browser.endpoints.genotype_browser.entity.mount=com.framsticks.entities.genotype_browser
 
 com.framsticks.entities.diagnostics.class=com.framsticks.diagnostics.Diagnostics
@@ -30,3 +30,5 @@
 com.framsticks.entities.hosted_portal.hosted.entity.mount=com.framsticks.entities.portal
 
-#com.framsticks.entity=browser
+com.framsticks.entities.genotype_browser.class=com.framsticks.examples.GenotypeBrowser
+
+com.framsticks.entity.mount = com.framsticks.entities.browser
Index: /java/main/src/main/resources/configs/log4j.properties
===================================================================
--- /java/main/src/main/resources/configs/log4j.properties	(revision 77)
+++ /java/main/src/main/resources/configs/log4j.properties	(revision 78)
@@ -3,5 +3,5 @@
 # -------------------------------------------------------------------
 #log4j.rootLogger=INFO, STDOUT, FILE
-log4j.rootLogger=DEBUG, STDOUT, FILE
+log4j.rootLogger=DEBUG, STDOUT
 
 
@@ -27,9 +27,4 @@
 log4j.appender.STDOUT.layout.ConversionPattern=%d{ABSOLUTE} [%-5p] [%t] %c -- %m%n
 
-# File appender
-log4j.appender.FILE=org.apache.log4j.FileAppender
-log4j.appender.FILE.File=${user.home}/frams_network_client.log
-log4j.appender.FILE.layout=org.apache.log4j.PatternLayout
-log4j.appender.FILE.layout.ConversionPattern=%d{ABSOLUTE} [%-5p] [%t] %c -- %m%n
 
 log4j.logger.com.framsticks=INFO
Index: /java/main/src/main/resources/examples/f0_example.txt
===================================================================
--- /java/main/src/main/resources/examples/f0_example.txt	(revision 78)
+++ /java/main/src/main/resources/examples/f0_example.txt	(revision 78)
@@ -0,0 +1,20 @@
+//0
+
+p:
+p:i=,Vstyle=
+p:m=1,i="bla"
+j:0,1,dx=2
+j:1,2,dx=1,rx=3,i="1,2,3,\"dsadsa,,,,",rx=8,,9,ry=5,6
+n:p=1
+n:j=0,d="|:p=0.25,r=1"
+n:j=0,d=G
+n:p=1
+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
Index: /java/main/src/main/resources/info/Creature.info
===================================================================
--- /java/main/src/main/resources/info/Creature.info	(revision 78)
+++ /java/main/src/main/resources/info/Creature.info	(revision 78)
@@ -0,0 +1,423 @@
+class:
+id:Creature
+
+prop:
+name:Name
+id:name
+type:s
+flags:0
+
+prop:
+name:Genotype
+id:genotype
+type:s
+flags:0
+
+prop:
+name:Info
+id:info
+type:s
+help:Additional info or comments
+flags:0
+
+prop:
+name:group
+id:group
+type:x
+flags:33
+
+prop:
+name:Generation
+id:gnum
+type:d
+flags:0
+
+prop:
+name:Build problems
+id:buildproblems
+type:d
+flags:32
+
+prop:
+name:Starting energy
+id:energ0
+type:f
+flags:0
+
+prop:
+name:Idle power consumption
+id:idleen
+type:f
+flags:0
+
+prop:
+name:Energy
+id:energy
+type:f
+flags:0
+
+prop:
+name:Energy income
+id:energy_p
+type:f
+flags:0
+
+prop:
+name:Energy costs
+id:energy_m
+type:f
+flags:0
+
+prop:
+name:Energy balance
+id:energy_b
+type:f
+flags:0
+
+prop:
+name:Performance calculation
+id:perf
+type:d
+help:Initial value of this property is taken from Population.enableperf
+flags:0
+
+prop:
+name:NN enabled
+id:nnenabled
+type:d 0 1
+flags:0
+
+prop:
+name:Body simulation
+id:bodysim
+type:d 0 1
+help:~
+(Physical) body simulation can be disabled for individual objects which makes them immovable. Disabled objects can still participate in collisions depending on their collisions masks.
+
+Bugs: the standard collision handler does not work for disabled objects when ODE simulation is used. It means that these objects won't physically interact with other objects. The custom (scripting) handlers work as expected.~
+flags:0
+
+prop:
+name:Self-collisions
+id:selfcol
+type:d 0 1
+help:Enable/disable detection of self-collisions (within a creature body). They can only occur when using the ODE simulation engine. If enabled, the creature will have its sticks collide during lifespan.
+flags:0
+
+prop:
+name:Self-collisions
+id:selfcolstate
+type:d 0 1
+help:Current self-collision state
+flags:35
+
+prop:
+name:Life span
+id:lifespan
+type:d
+flags:0
+
+prop:
+name:Distance
+id:distance
+type:f
+flags:0
+
+prop:
+name:Velocity
+id:c_velocity
+type:f
+flags:0
+
+prop:
+name:Vertical velocity
+id:c_vertvelocity
+type:f
+flags:0
+
+prop:
+name:Vertical position
+id:c_vertpos
+type:f
+flags:0
+
+prop:
+name:Avg. velocity
+id:velocity
+type:f
+flags:0
+
+prop:
+name:Avg. vertical position
+id:vertpos
+type:f
+flags:0
+
+prop:
+name:Avg. vertical velocity
+id:vertvel
+type:f
+flags:0
+
+prop:
+name:position.x
+id:pos_x
+type:f
+help:(pos_x,pos_y,pos_z) is the point of minimal coordinates ("bottom left corner") of the creature, including imaginary Part sizes (Part.s, usually 1.0). See also: Creature.moveAbs
+flags:3
+
+prop:
+name:position.y
+id:pos_y
+type:f
+help:See Creature.pos_x
+flags:3
+
+prop:
+name:position.z
+id:pos_z
+type:f
+help:See Creature.pos_x
+flags:3
+
+prop:
+name:bounding box x size
+id:size_x
+type:f
+help:~
+(size_x,size_y,size_z) are dimensions of the axis-aligned bounding box of the creature, including the imaginary part sizes (Part.s, usually 1.0). A creature consisting of a single default Part has the size of (2.0,2.0,2.0) - twice the Part.s value (like a sphere diameter is twice its radius).
+See also: Creature.moveAbs~
+flags:3
+
+prop:
+name:bounding box y size
+id:size_y
+type:f
+help:See Creature.size_x
+flags:3
+
+prop:
+name:bounding box z size
+id:size_z
+type:f
+help:See Creature.size_x
+flags:3
+
+prop:
+name:center.x
+id:center_x
+type:f
+help:Center of gravity
+flags:3
+
+prop:
+name:center.y
+id:center_y
+type:f
+help:Center of gravity
+flags:3
+
+prop:
+name:center.z
+id:center_z
+type:f
+help:Center of gravity
+flags:3
+
+prop:
+name:number of parts
+id:numparts
+type:d
+flags:3
+
+prop:
+name:number of joints
+id:numjoints
+type:d
+flags:3
+
+prop:
+name:number of neurons
+id:numneurons
+type:d
+flags:3
+
+prop:
+name:User field 1
+id:user1
+type:x
+flags:0
+
+prop:
+name:User field 2
+id:user2
+type:x
+flags:0
+
+prop:
+name:User field 3
+id:user3
+type:x
+flags:0
+
+prop:
+name:move
+id:move
+type:p
+help:Shift the creature by a given vector.
+flags:32
+
+prop:
+name:move to absolute location
+id:moveAbs
+type:p
+help:~
+Moves the creature so that its origin (pos_x,pos_y,pos_z) is placed at the given location. The origin is the point of minimal coordinates ("bottom left corner"), including imaginary part sizes (Part.s, usually 1.0).
+Assuming a simple single-stick creature "X" having parts at (0,0,0) and (1,0,0),
+
+origin (pos_x,pos_y,pos_z) = (-1,-1,-1)
+size (size_x,size_y,size_z) = (3,2,2)
+
+The following example places the bottom of a creature at a given location (x,y,z):
+Creature.moveAbs(x-(Creature.size_x/2),y-(Creature.size_y/2),z-1.0)
+(assuming that the part size is 1.0)~
+flags:32
+
+prop:
+name:move in local coordinates
+id:moveLocal
+type:p
+help:Local coordinates are measured with respect to the position and orientation of the first Part
+flags:32
+
+prop:
+name:return world coordinates
+id:localToWorld
+type:p
+help:Local coordinates are measured with respect to the position and orientation of the first Part
+flags:32
+
+prop:
+name:return local coordinates
+id:worldToLocal
+type:p
+help:Local coordinates are measured with respect to the position and orientation of the first Part
+flags:32
+
+prop:
+name:rotate
+id:rotate
+type:p
+help:Rotate the creature around X, Y and Z axes. Should only be used immediately after creating a new creature (before the first simulation step is performed for this creature), otherwise further simulation can be disturbed.
+flags:32
+
+prop:
+name:rotate in local coordinates
+id:rotateLocal
+type:p
+help:Rotate the creature around (local) X, Y and Z axes. Should only be used immediately after creating a new creature (before the first simulation step is performed for this creature), otherwise further simulation can be disturbed.
+flags:32
+
+prop:
+name:getPart (static Model information)
+id:getPart
+type:p
+flags:32
+
+prop:
+name:getJoint (static Model information)
+id:getJoint
+type:p
+flags:32
+
+prop:
+name:getNeuroDef
+id:getNeuroDef
+type:p
+flags:32
+
+prop:
+name:getMechPart (current properties)
+id:getMechPart
+type:p
+flags:32
+
+prop:
+name:getMechJoint (current properties)
+id:getMechJoint
+type:p
+flags:32
+
+prop:
+name:getNeuro
+id:getNeuro
+type:p
+flags:32
+
+prop:
+name:Collision mask (self)
+id:selfmask
+type:db
+flags:32
+
+prop:
+name:Collision mask (other)
+id:othermask
+type:db
+flags:32
+
+prop:
+name:currentGeometryAsF0
+id:currentGeometryAsF0
+type:p
+flags:32
+
+prop:
+name:#
+id:uid
+type:s
+flags:33
+
+prop:
+name:Index
+id:index
+type:d
+help:Index of this Creature in its Population.
+flags:1
+
+prop:
+name:Model Parts
+id:parts
+type:l Part
+flags:0
+
+prop:
+name:Model Joints
+id:joints
+type:l Joint
+flags:0
+
+prop:
+name:Neuron Definitions
+id:neurodefs
+type:l NeuroDef
+flags:0
+
+prop:
+name:Simulated Parts
+id:mechparts
+type:l MechPart
+flags:0
+
+prop:
+name:Simulated Joints
+id:mechjoints
+type:l MechJoint
+flags:0
+
+prop:
+name:Live Neurons
+id:neurons
+type:l Neuro
+flags:0
+
Index: /java/main/src/main/resources/info/Genotype.info
===================================================================
--- /java/main/src/main/resources/info/Genotype.info	(revision 78)
+++ /java/main/src/main/resources/info/Genotype.info	(revision 78)
@@ -0,0 +1,232 @@
+class:
+id:Genotype
+
+prop:
+name:Name
+id:name
+type:s
+flags:0
+
+prop:
+name:Genotype
+id:genotype
+type:s
+flags:0
+
+prop:
+name:Info
+id:info
+type:s
+help:Additional information or comments
+flags:0
+
+prop:
+name:Similarity
+id:simi
+type:f
+flags:3
+
+prop:
+name:Starting energy
+id:energ0
+type:f
+flags:3
+
+prop:
+name:Body parts (deprecated; use numparts)
+id:strsiz
+type:f
+flags:35
+
+prop:
+name:Body joints (deprecated; use numjoints)
+id:strjoints
+type:f
+flags:35
+
+prop:
+name:Brain size (deprecated; use numneurons)
+id:nnsiz
+type:f
+flags:35
+
+prop:
+name:Brain connections (deprecated; use numconnections)
+id:nncon
+type:f
+flags:35
+
+prop:
+name:Body parts
+id:numparts
+type:f
+flags:3
+
+prop:
+name:Body joints
+id:numjoints
+type:f
+flags:3
+
+prop:
+name:Brain size
+id:numneurons
+type:f
+flags:3
+
+prop:
+name:Brain connections
+id:numconnections
+type:f
+flags:3
+
+prop:
+name:Ordinal number
+id:num
+type:d
+flags:0
+
+prop:
+name:Generation
+id:gnum
+type:d
+flags:0
+
+prop:
+name:Deprecated; use instances
+id:popsiz
+type:d
+flags:32
+
+prop:
+name:Instances
+id:instances
+type:d
+help:Copies of this genotype
+flags:2
+
+prop:
+name:Life span
+id:lifespan
+type:f
+help:Average life span
+flags:0
+
+prop:
+name:Velocity
+id:velocity
+type:f
+help:Average velocity
+flags:0
+
+prop:
+name:Distance
+id:distance
+type:f
+flags:0
+
+prop:
+name:Vertical velocity
+id:vertvel
+type:f
+flags:0
+
+prop:
+name:Vertical position
+id:vertpos
+type:f
+flags:0
+
+prop:
+name:Fitness
+id:fit
+type:f
+flags:3
+
+prop:
+name:Final fitness
+id:fit2
+type:f
+help:Fitness shifted by (avg-n*stddev)
+flags:3
+
+prop:
+name:f0 genotype
+id:f0genotype
+type:s
+help:converted to f0 genotype
+flags:3
+
+prop:
+name:Conversion backtrace [1]
+id:convtrace1
+type:s
+flags:3
+
+prop:
+name:User field 1
+id:user1
+type:x
+flags:0
+
+prop:
+name:User field 2
+id:user2
+type:x
+flags:0
+
+prop:
+name:User field 3
+id:user3
+type:x
+flags:0
+
+prop:
+name:Mutate
+id:mutate
+type:p
+flags:0
+
+prop:
+name:Valid
+id:isValid
+type:d 0 1
+flags:35
+
+prop:
+name:get normalized property
+id:getNormalized
+type:p
+flags:35
+
+prop:
+name:#
+id:uid
+type:s
+help:Unique identifier
+flags:33
+
+prop:
+name:Model object
+id:getModel
+type:p
+flags:35
+
+prop:
+name:Model Parts
+id:parts
+type:l Part
+flags:0
+
+prop:
+name:Model Joints
+id:joints
+type:l Joint
+flags:0
+
+prop:
+name:Neuron Definitions
+id:neurodefs
+type:l NeuroDef
+flags:0
+
Index: /java/main/src/main/resources/info/Joint.info
===================================================================
--- /java/main/src/main/resources/info/Joint.info	(revision 78)
+++ /java/main/src/main/resources/info/Joint.info	(revision 78)
@@ -0,0 +1,99 @@
+class:
+id:Joint
+
+prop:
+name:part1 ref#
+id:p1
+type:d
+flags:1024
+
+prop:
+name:part2 ref#
+id:p2
+type:d
+flags:1024
+
+prop:
+name:rotation.x
+id:rx
+type:f
+flags:0
+
+prop:
+name:rotation.y
+id:ry
+type:f
+flags:1024
+
+prop:
+name:rotation.z
+id:rz
+type:f
+flags:1024
+
+prop:
+name:delta.x
+id:dx
+type:f
+flags:0
+
+prop:
+name:delta.y
+id:dy
+type:f
+flags:1024
+
+prop:
+name:delta.z
+id:dz
+type:f
+flags:1024
+
+prop:
+name:stiffness
+id:stif
+type:f
+flags:0
+
+prop:
+name:rotation stiffness
+id:rotstif
+type:f
+flags:0
+
+prop:
+name:stamina
+id:stam
+type:f
+flags:0
+
+prop:
+name:info
+id:i
+type:s
+flags:0
+
+prop:
+name:vis_style
+id:Vstyle
+type:s
+flags:0
+
+prop:
+name:red component
+id:vr
+type:f
+flags:0
+
+prop:
+name:green component
+id:vg
+type:f
+flags:1024
+
+prop:
+name:blue component
+id:vb
+type:f
+flags:1024
+
Index: /java/main/src/main/resources/info/MechJoint.info
===================================================================
--- /java/main/src/main/resources/info/MechJoint.info	(revision 78)
+++ /java/main/src/main/resources/info/MechJoint.info	(revision 78)
@@ -0,0 +1,63 @@
+class:
+id:MechJoint
+
+prop:
+name:rotation.x
+id:rx
+type:f
+flags:0
+
+prop:
+name:rotation.y
+id:ry
+type:f
+flags:0
+
+prop:
+name:rotation.z
+id:rz
+type:f
+flags:0
+
+prop:
+name:delta.x
+id:dx
+type:f
+flags:0
+
+prop:
+name:delta.y
+id:dy
+type:f
+flags:0
+
+prop:
+name:delta.z
+id:dz
+type:f
+flags:0
+
+prop:
+name:stiffness
+id:stif
+type:f
+flags:0
+
+prop:
+name:rotation stiffness
+id:rotstif
+type:f
+flags:0
+
+prop:
+name:
+id:stress
+type:f
+flags:1
+
+prop:
+name:
+id:rotstress
+type:f
+flags:1
+
Index: /java/main/src/main/resources/info/MechPart.info
===================================================================
--- /java/main/src/main/resources/info/MechPart.info	(revision 78)
+++ /java/main/src/main/resources/info/MechPart.info	(revision 78)
@@ -0,0 +1,123 @@
+class:
+id:MechPart
+
+prop:
+name:position.x
+id:x
+type:f
+flags:0
+
+prop:
+name:position.y
+id:y
+type:f
+flags:0
+
+prop:
+name:position.z
+id:z
+type:f
+flags:0
+
+prop:
+name:mass
+id:m
+type:f
+flags:0
+
+prop:
+name:size
+id:s
+type:f
+flags:0
+
+prop:
+name:volume
+id:vol
+type:f
+flags:0
+
+prop:
+name:friction
+id:fr
+type:f
+flags:0
+
+prop:
+name:velocity.x
+id:vx
+type:f
+flags:0
+
+prop:
+name:velocity.y
+id:vy
+type:f
+flags:0
+
+prop:
+name:velocity.z
+id:vz
+type:f
+flags:0
+
+prop:
+name:orientation.x.x
+id:oxx
+type:f
+flags:0
+
+prop:
+name:orientation.x.y
+id:oxy
+type:f
+flags:0
+
+prop:
+name:orientation.x.z
+id:oxz
+type:f
+flags:0
+
+prop:
+name:orientation.y.x
+id:oyx
+type:f
+flags:0
+
+prop:
+name:orientation.y.y
+id:oyy
+type:f
+flags:0
+
+prop:
+name:orientation.y.z
+id:oyz
+type:f
+flags:0
+
+prop:
+name:orientation.z.x
+id:ozx
+type:f
+flags:0
+
+prop:
+name:orientation.z.y
+id:ozy
+type:f
+flags:0
+
+prop:
+name:orientation.z.z
+id:ozz
+type:f
+flags:0
+
+prop:
+name:apply force
+id:applyForce
+type:p
+flags:0
+
Index: /java/main/src/main/resources/info/Neuro.info
===================================================================
--- /java/main/src/main/resources/info/Neuro.info	(revision 78)
+++ /java/main/src/main/resources/info/Neuro.info	(revision 78)
@@ -0,0 +1,140 @@
+class:
+id:Neuro
+
+prop:
+name:Get input signal
+id:getInputState
+type:p
+flags:0
+
+prop:
+name:Get input weight
+id:getInputWeight
+type:p
+flags:0
+
+prop:
+name:Get weighted input signal
+id:getWeightedInputState
+type:p
+flags:0
+
+prop:
+name:Get signal sum
+id:getInputSum
+type:p
+flags:0
+
+prop:
+name:Get weighted signal sum
+id:getWeightedInputSum
+type:p
+help:Uses any number of inputs starting with the specified input. getWeightedInputSum(0)=weightedInputSum
+flags:0
+
+prop:
+name:Get input count
+id:getInputCount
+type:d
+flags:0
+
+prop:
+name:Full signal sum
+id:inputSum
+type:f
+flags:0
+
+prop:
+name:Full weighted signal sum
+id:weightedInputSum
+type:f
+flags:0
+
+prop:
+name:Get channel count for input
+id:getInputChannelCount
+type:p
+flags:0
+
+prop:
+name:Get input signal from channel
+id:getInputStateChannel
+type:p
+flags:0
+
+prop:
+name:Get weighted input signal from channel
+id:getWeightedInputStateChannel
+type:p
+flags:0
+
+prop:
+name:Neuron state (channel 0)
+id:state
+type:f
+help:~
+When read, returns the current neuron state.
+When written, sets the 'internal' neuron state that will become current in the next step.
+Typically you should use this field, and not currState.~
+flags:0
+
+prop:
+name:Number of output channels
+id:channelCount
+type:d
+flags:0
+
+prop:
+name:Get state for channel
+id:getStateChannel
+type:p
+flags:0
+
+prop:
+name:Set state for channel
+id:setStateChannel
+type:p
+flags:0
+
+prop:
+name:Hold state
+id:hold
+type:d 0 1
+help:"Holding" means keeping the neuron state as is, blocking the regular neuron operation. This is useful when your script needs to inject some control signals into the NN. Without "holding", live neurons would be constantly overwriting your changes, and the rest of the NN could see inconsistent states, depending on the connections. Setting hold=1 ensures the neuron state will be only set by you, and not by the neuron. The enforced signal value can be set using Neuro.currState before or after setting hold=1. Set hold=0 to resume normal operation.
+flags:0
+
+prop:
+name:Current neuron state (channel 0)
+id:currState
+type:f
+help:~
+When read, it behaves just like the 'state' field.
+When written, changes the current neuron state immediately, which disturbs the regular synchronous NN operation.
+This feature should only be used while controlling the neuron 'from outside' (like a neuro probe) and not in the neuron definition. See also: Neuro.hold~
+flags:0
+
+prop:
+name:Set current neuron state for channel
+id:setCurrStateChannel
+type:p
+help:Analogous to "currState".
+flags:0
+
+prop:
+name:Position x
+id:position_x
+type:f
+flags:0
+
+prop:
+name:Position y
+id:position_y
+type:f
+flags:0
+
+prop:
+name:Position z
+id:position_z
+type:f
+flags:0
+
Index: /java/main/src/main/resources/info/NeuroDef.info
===================================================================
--- /java/main/src/main/resources/info/NeuroDef.info	(revision 78)
+++ /java/main/src/main/resources/info/NeuroDef.info	(revision 78)
@@ -0,0 +1,57 @@
+class:
+id:NeuroDef
+
+prop:
+name:part ref#
+id:p
+type:d
+flags:0
+
+prop:
+name:joint ref#
+id:j
+type:d
+flags:0
+
+prop:
+name:item details
+id:d
+type:s
+flags:0
+
+prop:
+name:info
+id:i
+type:s
+flags:0
+
+prop:
+name:vis_style
+id:Vstyle
+type:s
+flags:0
+
+prop:
+name:input count
+id:getInputCount
+type:d
+flags:3
+
+prop:
+name:get input neuron
+id:getInputNeuroDef
+type:p
+flags:3
+
+prop:
+name:get input neuron index
+id:getInputNeuroIndex
+type:p
+flags:3
+
+prop:
+name:get input weight
+id:getInputWeight
+type:p
+flags:3
+
Index: /java/main/src/main/resources/info/Part.info
===================================================================
--- /java/main/src/main/resources/info/Part.info	(revision 78)
+++ /java/main/src/main/resources/info/Part.info	(revision 78)
@@ -0,0 +1,111 @@
+class:
+id:Part
+
+prop:
+name:position.x
+id:x
+type:f
+flags:1024
+
+prop:
+name:position.y
+id:y
+type:f
+flags:1024
+
+prop:
+name:position.z
+id:z
+type:f
+flags:1024
+
+prop:
+name:mass
+id:m
+type:f
+flags:0
+
+prop:
+name:size
+id:s
+type:f
+flags:0
+
+prop:
+name:density
+id:dn
+type:f
+flags:0
+
+prop:
+name:friction
+id:fr
+type:f
+flags:0
+
+prop:
+name:ingestion
+id:ing
+type:f
+flags:0
+
+prop:
+name:assimilation
+id:as
+type:f
+flags:0
+
+prop:
+name:rot.x
+id:rx
+type:f
+flags:0
+
+prop:
+name:rot.y
+id:ry
+type:f
+flags:1024
+
+prop:
+name:rot.z
+id:rz
+type:f
+flags:1024
+
+prop:
+name:info
+id:i
+type:s
+flags:0
+
+prop:
+name:vis_style
+id:Vstyle
+type:s
+flags:0
+
+prop:
+name:visual thickness
+id:vs
+type:f
+flags:0
+
+prop:
+name:red component
+id:vr
+type:f
+flags:0
+
+prop:
+name:green component
+id:vg
+type:f
+flags:1024
+
+prop:
+name:blue component
+id:vb
+type:f
+flags:1024
+
Index: /java/main/src/main/resources/parsers/f0def.xml
===================================================================
--- /java/main/src/main/resources/parsers/f0def.xml	(revision 78)
+++ /java/main/src/main/resources/parsers/f0def.xml	(revision 78)
@@ -0,0 +1,202 @@
+<!DOCTYPE F0CLASSES>
+<F0CLASSES>
+
+ <CLASS ID="m" NAME="Model">
+  <GROUP NAME="Properties" />
+  <GROUP NAME="Visual" />
+  <GROUP NAME="Elements" />
+  <PROP ID="se" NAME="startenergy" GROUP="0" FLAGS="0" TYPE="f" DEF="1.0" />
+  <PROP ID="Vstyle" NAME="vis_style" GROUP="1" FLAGS="0" TYPE="s" MIN="0" MAX="-1" DEF="" />
+  <PROP ID="parts" NAME="parts" GROUP="2" FLAGS="0" TYPE="l Part" />
+  <PROP ID="joints" NAME="joints" GROUP="2" FLAGS="0" TYPE="l Joint" />
+  <PROP ID="neurodefs" NAME="neurodefs" GROUP="2" FLAGS="0" TYPE="l NeuroDef" />
+ </CLASS>
+
+ <CLASS ID="p" NAME="Part">
+  <GROUP NAME="Geometry" />
+  <GROUP NAME="Other properties" />
+  <GROUP NAME="Visual" />
+  <PROP ID="x" NAME="position.x" GROUP="0" FLAGS="1024" TYPE="f" />
+  <PROP ID="y" NAME="position.y" GROUP="0" FLAGS="1024" TYPE="f" />
+  <PROP ID="z" NAME="position.z" GROUP="0" FLAGS="1024" TYPE="f" />
+  <PROP ID="m" XTRA="1" NAME="mass" GROUP="1" FLAGS="0" TYPE="f" MIN="0.1" MAX="999.0" DEF="1.0" />
+  <PROP ID="s" NAME="size" GROUP="1" FLAGS="0" TYPE="f" MIN="0.1" MAX="10.0" DEF="1.0" />
+  <PROP ID="dn" XTRA="1" NAME="density" GROUP="1" FLAGS="0" TYPE="f" MIN="0.2" MAX="5.0" DEF="1.0" />
+  <PROP ID="fr" XTRA="1" NAME="friction" GROUP="1" FLAGS="0" TYPE="f" MIN="0.0" MAX="4.0" DEF="0.4" />
+  <PROP ID="ing" XTRA="1" NAME="ingestion" GROUP="1" FLAGS="0" TYPE="f" MIN="0.0" MAX="1.0" DEF="0.25" />
+  <PROP ID="as" XTRA="1" NAME="assimilation" GROUP="1" FLAGS="0" TYPE="f" MIN="0.0" MAX="1.0" DEF="0.25" />
+  <PROP ID="rx" NAME="rot.x" GROUP="0" FLAGS="0" TYPE="f" />
+  <PROP ID="ry" NAME="rot.y" GROUP="0" FLAGS="1024" TYPE="f" />
+  <PROP ID="rz" NAME="rot.z" GROUP="0" FLAGS="1024" TYPE="f" />
+  <PROP ID="i" NAME="info" GROUP="1" FLAGS="0" TYPE="s" />
+  <PROP ID="Vstyle" NAME="vis_style" GROUP="2" FLAGS="0" TYPE="s" MIN="0" MAX="-1" DEF="part" />
+ </CLASS>
+
+ <CLASS ID="j" NAME="Joint">
+  <GROUP NAME="Connections" />
+  <GROUP NAME="Geometry" />
+  <GROUP NAME="Other properties" />
+  <GROUP NAME="Visual" />
+  <PROP ID="p1" NAME="part1 ref#" GROUP="0" FLAGS="1024" TYPE="d" MIN="-1" MAX="999999" DEF="-1" />
+  <PROP ID="p2" NAME="part2 ref#" GROUP="0" FLAGS="1024" TYPE="d" MIN="-1" MAX="999999" DEF="-1" />
+  <PROP ID="rx" NAME="rotation.x" GROUP="1" FLAGS="0" TYPE="f" />
+  <PROP ID="ry" NAME="rotation.y" GROUP="1" FLAGS="1024" TYPE="f" />
+  <PROP ID="rz" NAME="rotation.z" GROUP="1" FLAGS="1024" TYPE="f" />
+  <PROP ID="dx" NAME="delta.x" GROUP="1" FLAGS="0" TYPE="f" MIN="-2" MAX="2" DEF="0" />
+  <PROP ID="dy" NAME="delta.y" GROUP="1" FLAGS="1024" TYPE="f" MIN="-2" MAX="2" DEF="0" />
+  <PROP ID="dz" NAME="delta.z" GROUP="1" FLAGS="1024" TYPE="f" MIN="-2" MAX="2" DEF="0" />
+  <PROP ID="stif" XTRA="1" NAME="stiffness" GROUP="2" FLAGS="0" TYPE="f" MIN="0.0" MAX="1.0" DEF="1.0" />
+  <PROP ID="rotstif" XTRA="1" NAME="rotation stiffness" GROUP="2" FLAGS="0" TYPE="f" MIN="0.0" MAX="1.0" DEF="1.0" />
+  <PROP ID="stam" NAME="stamina" GROUP="2" FLAGS="0" TYPE="f" MIN="0.0" MAX="1.0" DEF="0.25" />
+  <PROP ID="i" NAME="info" GROUP="2" FLAGS="0" TYPE="s" />
+  <PROP ID="Vstyle" NAME="vis_style" GROUP="3" FLAGS="0" TYPE="s" MIN="0" MAX="-1" DEF="joint" />
+ </CLASS>
+
+
+
+ <CLASS ID="n" NAME="NeuroDef">
+  <GROUP NAME="Connections" />
+  <GROUP NAME="Other" />
+  <GROUP NAME="Visual" />
+  <PROP ID="p" NAME="part ref#" GROUP="0" FLAGS="0" TYPE="d" MIN="-1" MAX="999999" DEF="-1" />
+  <PROP ID="j" NAME="joint ref#" GROUP="0" FLAGS="0" TYPE="d" MIN="-1" MAX="999999" DEF="-1" />
+  <PROP ID="d" NAME="item details" GROUP="1" FLAGS="0" TYPE="s" DEF="N"/>
+  <PROP ID="i" NAME="info" GROUP="1" FLAGS="0" TYPE="s" />
+  <PROP ID="Vstyle" NAME="vis_style" GROUP="2" FLAGS="0" TYPE="s" MIN="0" MAX="-1" />
+  <!--PROP ID="getInputCount" NAME="input count" GROUP="0" FLAGS="1+2" TYPE="d" /-->
+  <!--PROP ID="getInputNeuroDef" NAME="get input neuron" GROUP="0" FLAGS="1+2" TYPE="p oNeuroDef(d)" /-->
+  <!--PROP ID="getInputNeuroIndex" NAME="get input neuron index" GROUP="0" FLAGS="1+2" TYPE="p d(d)" /-->
+  <!--PROP ID="getInputWeight" NAME="get input weight" GROUP="0" FLAGS="1+2" TYPE="p f(d)" /-->
+  <!--PROP ID="classObject" NAME="neuron class" GROUP="0" FLAGS="1+2" TYPE="o NeuroClass" /-->
+ </CLASS>
+
+ <CLASS ID="c" NAME="NeuroConn">
+  <GROUP NAME="Connection" />
+  <GROUP NAME="Other" />
+  <PROP ID="n1" NAME="this neuro ref#" GROUP="0" FLAGS="1024" TYPE="d" MIN="-1" MAX="999999" DEF="-1" />
+  <PROP ID="n2" NAME="connected neuro ref#" GROUP="0" FLAGS="1024" TYPE="d" MIN="-1" MAX="999999" DEF="-1" />
+  <PROP ID="w" NAME="weight" GROUP="0" FLAGS="1024" TYPE="f" MIN="-999999" MAX="999999" DEF="1.0" />
+  <PROP ID="i" NAME="info" GROUP="1" FLAGS="0" TYPE="s" />
+ </CLASS>
+
+ <NEUROCLASS ID="N" NAME="Neuron" DESCRIPTION="Standard neuron" INPUTS="-1" OUTPUT="1" LOCATION="0"  VISUALHINTS="2"  >
+
+  <NEUROPROP ID="in" NAME="Inertia" TYPE="f" MIN="0.0" MAX="1.0" DEF="0.8" />
+  <NEUROPROP ID="fo" NAME="Force" TYPE="f" MIN="0.0" MAX="999.0" DEF="0.04" />
+  <NEUROPROP ID="si" NAME="Sigmoid" TYPE="f" MIN="-99999.0" MAX="99999.0" DEF="2.0" />
+  <NEUROPROP ID="s" NAME="State" TYPE="f" MIN="-1.0" MAX="1.0" DEF="0.0" />
+ </NEUROCLASS>
+
+ <NEUROCLASS ID="Nu" NAME="Unipolar neuron [EXPERIMENTAL!]" DESCRIPTION="Works like standard neuron (N) but the output value is scaled to 0...+1 instead of -1...+1.\nHaving 0 as one of the saturation states should help in &quot;gate circuits&quot;, where input signal is passed through or blocked depending on the other singal." INPUTS="-1" OUTPUT="1" LOCATION="0"  >
+  <NEUROPROP ID="in" NAME="Inertia" TYPE="f" MIN="0.0" MAX="1.0" DEF="0.8" />
+  <NEUROPROP ID="fo" NAME="Force" TYPE="f" MIN="0.0" MAX="999.0" DEF="0.04" />
+  <NEUROPROP ID="si" NAME="Sigmoid" TYPE="f" MIN="-99999.0" MAX="99999.0" DEF="2.0" />
+  <NEUROPROP ID="s" NAME="State" TYPE="f" MIN="-1.0" MAX="1.0" DEF="0.0" />
+ </NEUROCLASS>
+
+ <NEUROCLASS ID="G" NAME="Gyroscope" DESCRIPTION="Equilibrium sensor.\n0=the stick is horizontal\n+1/-1=the stick is vertical" INPUTS="0" OUTPUT="1" LOCATION="2"  VISUALHINTS="32"  SYMBOL="8,7,100,50,90,50,90,40,70,40,80,50,70,60,90,60,90,50,12,43,24,48,24,48,19,38,19,38,24,43,24,43,54,48,54,48,64,43,69,38,64,38,54,43,54,5,63,69,58,74,48,79,38,79,28,74,23,69,1,43,79,43,74,1,23,69,26,66,1,63,69,60,66,1,55,76,53,73,1,31,75,33,72"  >
+
+
+ </NEUROCLASS>
+
+ <NEUROCLASS ID="T" NAME="Touch" DESCRIPTION="Touch sensor.\n-1=no contact\n0=just touching\n>0=pressing, value depends on the force applied" INPUTS="0" OUTPUT="1" LOCATION="1"  VISUALHINTS="32"  SYMBOL="2,7,100,50,90,50,90,40,70,40,80,50,70,60,90,60,90,50,11,75,50,65,50,60,55,55,45,50,55,45,45,40,50,35,50,30,45,25,50,30,55,35,50"  >
+
+
+  <NEUROPROP ID="r" NAME="Range" TYPE="f" MIN="0.0" MAX="1.0" DEF="1.0" />
+ </NEUROCLASS>
+
+ <NEUROCLASS ID="S" NAME="Smell" DESCRIPTION="Smell sensor. Aggregated &quot;smell of energy&quot; experienced from all energy objects (creatures and food pieces).\nClose objects have bigger influence than the distant ones: for each energy source, its partial feeling is proportional to its energy/(distance^2)" INPUTS="0" OUTPUT="1" LOCATION="1"  VISUALHINTS="32"  SYMBOL="5,7,100,50,90,50,90,40,70,40,80,50,70,60,90,60,90,50,3,10,40,15,45,15,55,10,60,5,20,30,25,35,30,45,30,55,25,65,20,70,4,15,35,20,40,22,50,20,60,15,65,5,75,50,50,50,45,45,40,50,45,55,50,50"  >
+
+
+ </NEUROCLASS>
+
+ <NEUROCLASS ID="*" NAME="Constant" DESCRIPTION="Constant value" INPUTS="0" OUTPUT="1" LOCATION="0"  VISUALHINTS="1"  SYMBOL="4,4,26,27,26,73,73,73,73,27,26,27,1,73,50,100,50,1,56,68,46,68,2,41,47,51,32,51,68"  >
+
+
+ </NEUROCLASS>
+
+ <NEUROCLASS ID="|" NAME="Bend muscle" DESCRIPTION="" INPUTS="1" OUTPUT="0" LOCATION="2"  VISUALHINTS="86"  SYMBOL="6,5,25,40,35,40,45,50,35,60,25,60,25,40,4,65,85,65,50,75,50,75,85,65,85,3,65,56,49,29,57,24,72,50,4,68,53,70,53,70,55,68,55,68,53,5,50,21,60,15,70,14,79,15,87,20,81,10,1,86,20,77,21"  >
+
+
+  <NEUROPROP ID="p" NAME="power" TYPE="f" MIN="0.01" MAX="1.0" DEF="0.25" />
+  <NEUROPROP ID="r" NAME="bending range" TYPE="f" MIN="0.0" MAX="1.0" DEF="1.0" />
+ </NEUROCLASS>
+
+ <NEUROCLASS ID="@" NAME="Rotation muscle" DESCRIPTION="" INPUTS="1" OUTPUT="0" LOCATION="2"  VISUALHINTS="150"  SYMBOL="5,5,25,40,35,40,45,50,35,60,25,60,25,40,4,65,85,65,50,75,50,75,85,65,85,1,69,10,77,17,10,59,15,57,17,57,22,60,26,69,27,78,26,82,21,82,16,79,12,69,10,80,6,3,65,50,65,20,75,20,75,50"  >
+
+
+  <NEUROPROP ID="p" NAME="power" TYPE="f" MIN="0.01" MAX="1.0" DEF="1.0" />
+ </NEUROCLASS>
+
+ <NEUROCLASS ID="D" NAME="Differentiate" DESCRIPTION="Calculate the difference between the current and previous input value. Multiple inputs are aggregated with respect to their weights" INPUTS="-1" OUTPUT="1" LOCATION="0"  SYMBOL="3,3,25,0,25,100,75,50,25,0,1,75,50,100,50,3,44,42,51,57,36,57,44,42"  >
+
+ </NEUROCLASS>
+
+ <NEUROCLASS ID="Fuzzy" NAME="Fuzzy system [EXPERIMENTAL!]" DESCRIPTION="Refer to publications to learn more about this neuron." INPUTS="-1" OUTPUT="1" LOCATION="0"  SYMBOL="5,2,30,65,37,37,44,65,3,37,65,44,37,51,37,58,65,2,51,65,58,37,65,65,6,100,50,70,50,70,25,25,10,25,90,70,75,70,50,1,70,65,25,65"  >
+
+  <NEUROPROP ID="ns" NAME="number of fuzzy sets" TYPE="d" MIN="1" MAX="" DEF="" />
+  <NEUROPROP ID="nr" NAME="number of rules" TYPE="d" MIN="1" MAX="" DEF="" />
+  <NEUROPROP ID="fs" NAME="fuzzy sets" TYPE="s" MIN="0" MAX="-1" DEF="0" />
+  <NEUROPROP ID="fr" NAME="fuzzy rules" TYPE="s" MIN="0" MAX="-1" DEF="0" />
+ </NEUROCLASS>
+
+ <NEUROCLASS ID="VEye" NAME="Vector Eye [EXPERIMENTAL!]" DESCRIPTION="Refer to publications to learn more about this neuron." INPUTS="1" OUTPUT="1" LOCATION="1"  SYMBOL="11,7,100,50,90,50,90,40,70,40,80,50,70,60,90,60,90,50,14,70,50,65,40,60,35,45,30,30,30,15,35,10,40,5,50,10,60,15,65,30,70,45,70,60,65,65,60,70,50,8,38,67,28,62,23,52,28,42,38,37,48,42,53,52,48,62,38,67,4,33,52,38,47,43,52,38,57,33,52,5,70,50,60,40,45,35,30,35,15,40,5,50,1,53,33,58,22,1,62,36,68,26,1,45,30,47,19,1,35,30,35,19,1,27,31,24,20,1,18,34,12,24"  >
+
+  <NEUROPROP ID="tx" NAME="target.x" TYPE="f" MIN="" MAX="" DEF="" />
+  <NEUROPROP ID="ty" NAME="target.y" TYPE="f" MIN="" MAX="" DEF="" />
+  <NEUROPROP ID="tz" NAME="target.z" TYPE="f" MIN="" MAX="" DEF="" />
+  <NEUROPROP ID="ts" NAME="target shape" TYPE="s" MIN="0" MAX="-1" DEF="0" />
+  <NEUROPROP ID="p" NAME="perspective" TYPE="f" MIN="0.1" MAX="10.0" DEF="1.0" />
+  <NEUROPROP ID="s" NAME="scale" TYPE="f" MIN="0.1" MAX="100.0" DEF="1.0" />
+  <NEUROPROP ID="h" NAME="show hidden lines" TYPE="d" MIN="0" MAX="1" DEF="0" />
+  <NEUROPROP ID="o" NAME="output lines count (each line needs four channels)" TYPE="d" MIN="0" MAX="99" DEF="0" />
+  <NEUROPROP ID="d" NAME="debug" TYPE="d" MIN="0" MAX="1" DEF="0" />
+ </NEUROCLASS>
+
+ <NEUROCLASS ID="VMotor" NAME="Visual-Motor Cortex [EXPERIMENTAL!]" DESCRIPTION="Must be connected to the VEye and properly set up. Refer to publications to learn more about this neuron." INPUTS="-1" OUTPUT="1" LOCATION="0"  >
+  <NEUROPROP ID="noIF" NAME="number of basic features" TYPE="d" MIN="" MAX="" DEF="" />
+  <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 ID="Sti" NAME="Sticky [EXPERIMENTAL!]" DESCRIPTION="" INPUTS="1" OUTPUT="0" LOCATION="1"  VISUALHINTS="16"  >
+
+ </NEUROCLASS>
+
+ <NEUROCLASS ID="LMu" NAME="Linear muscle [EXPERIMENTAL!]" DESCRIPTION="" INPUTS="1" OUTPUT="0" LOCATION="2"  VISUALHINTS="16"  >
+
+  <NEUROPROP ID="p" NAME="power" TYPE="f" MIN="0.01" MAX="1.0" DEF="1.0" />
+ </NEUROCLASS>
+
+ <NEUROCLASS ID="Water" NAME="Water detector" DESCRIPTION="Output signal:\n0=on or above water surface\n1=under water (deeper than 1)\n0..1=in the transient area just below water surface" INPUTS="0" OUTPUT="1" LOCATION="1"  VISUALHINTS="32"  >
+
+ </NEUROCLASS>
+
+ <NEUROCLASS ID="Energy" NAME="Energy level" DESCRIPTION="The current energy level divided by the initial energy level.\nUsually falls from initial 1.0 down to 0.0 and then the creature dies. It can rise above 1.0 if enough food is ingested" INPUTS="0" OUTPUT="1" LOCATION="0"  VISUALHINTS="32"  >
+
+ </NEUROCLASS>
+
+ <NEUROCLASS ID="Ch" NAME="Channelize" DESCRIPTION="Combines all input signals into a single multichannel output; Note: ChSel and ChMux are the only neurons which support multiple channels. Other neurons discard everything except the first channel." INPUTS="-1" OUTPUT="1" LOCATION="0"  SYMBOL="10,4,25,0,25,100,75,70,75,30,25,0,1,75,50,100,50,1,70,50,55,50,1,30,80,55,50,1,30,20,55,50,1,30,35,55,50,1,30,45,55,50,1,30,55,55,50,1,61,53,65,47,1,30,65,55,50"  >
+
+ </NEUROCLASS>
+
+ <NEUROCLASS ID="ChMux" NAME="Channel multiplexer" DESCRIPTION="Outputs the selected channel from the second (multichannel) input. The first input is used as the selector value (-1=select first channel, .., 1=last channel)" INPUTS="2" OUTPUT="1" LOCATION="0"  SYMBOL="7,4,25,0,25,100,75,70,75,30,25,0,1,75,50,100,50,1,70,50,55,50,3,50,55,55,50,50,45,50,55,3,30,67,45,67,45,50,50,50,1,35,70,39,64,2,30,33,53,33,53,48"  >
+
+ </NEUROCLASS>
+
+ <NEUROCLASS ID="ChSel" NAME="Channel selector" DESCRIPTION="Outputs a single channel (selected by the &quot;ch&quot; parameter) from multichannel input" INPUTS="1" OUTPUT="1" LOCATION="0"  SYMBOL="6,4,25,0,25,100,75,70,75,30,25,0,1,75,50,100,50,1,70,50,55,50,3,50,55,55,50,50,45,50,55,1,30,50,50,50,1,35,53,39,47"  >
+
+  <NEUROPROP ID="ch" NAME="channel" TYPE="d" MIN="" MAX="" DEF="" />
+ </NEUROCLASS>
+
+ <NEUROCLASS ID="Rnd" NAME="Random noise" DESCRIPTION="Generates random noise (subsequent random values in the range of -1..+1)" INPUTS="0" OUTPUT="1" LOCATION="0"  >
+ </NEUROCLASS>
+
+ <NEUROCLASS ID="Sin" NAME="Sinus generator" DESCRIPTION="Output frequency = f0+input" INPUTS="1" OUTPUT="1" LOCATION="0"  SYMBOL="3,12,75,50,71,37,62,28,50,25,37,28,28,37,25,50,28,62,37,71,50,75,62,71,71,62,75,50,1,75,50,100,50,5,35,50,40,35,45,35,55,65,60,65,65,50"  >
+
+  <NEUROPROP ID="f0" NAME="base frequency" TYPE="f" MIN="-1.0" MAX="1.0" DEF="0.06283185307" />
+  <NEUROPROP ID="t" NAME="time" TYPE="f" MIN="0" MAX="6.283185307" DEF="0" />
+ </NEUROCLASS>
+
+
+</F0CLASSES>
Index: /java/main/src/test/java/com/framsticks/parsers/F0ParserTest.java
===================================================================
--- /java/main/src/test/java/com/framsticks/parsers/F0ParserTest.java	(revision 78)
+++ /java/main/src/test/java/com/framsticks/parsers/F0ParserTest.java	(revision 78)
@@ -0,0 +1,77 @@
+package com.framsticks.parsers;
+
+import com.framsticks.model.*;
+import com.framsticks.model.Package;
+import com.framsticks.params.*;
+import com.framsticks.params.types.FloatParam;
+import com.framsticks.util.Point3d;
+import org.apache.log4j.PropertyConfigurator;
+import org.junit.Test;
+
+import java.util.List;
+
+import static org.junit.Assert.*;
+
+/**
+ * Author: Piotr Śniegowski
+ */
+public class F0ParserTest {
+
+	@Test
+	public void testParser() throws Exception {
+		PropertyConfigurator.configure(getClass().getResource("/log4j.properties"));
+		//testing schema
+		Schema schema = new Schema(Schema.getDefaultDefinitionAsStream());
+
+		{
+			FramsClass joint = schema.getRegistry().getInfoFromCache("j");
+			Param dx = joint.getParamEntry("dx");
+			assertEquals(FloatParam.class, dx.getClass());
+			assertEquals(21, schema.getNeuroClasses().size());
+			assertEquals("delta.x", dx.getName());
+			assertEquals(-2.0, dx.getMin(Double.class), 0.0);
+		}
+
+		Package.register(schema.getRegistry());
+		//testing parser
+		List<AccessInterface> accesses = new F0Parser(schema, F0ParserTest.class.getResourceAsStream("/parsers/f0_example.txt")).parse();
+
+		{
+			assertEquals(12, accesses.size());
+			assertTrue(accesses.get(0).getSelected() instanceof F0Genotype);
+			assertEquals("1,2,3,\"dsadsa,,,,", accesses.get(5).get("i", String.class));
+			assertEquals("|:p=0.25,r=1", accesses.get(7).get("d", String.class));
+			assertEquals("@:p=0.25", accesses.get(10).get("d", String.class));
+		}
+
+		List<Object> objects = Util.stripAccessInterface(accesses);
+		{
+			assertEquals(Part.class, objects.get(1).getClass());
+			assertEquals(Joint.class, objects.get(4).getClass());
+			assertEquals(NeuroDef.class, objects.get(6).getClass());
+		}
+
+		F0Genotype f0Genotype = Genotype.build(objects);
+		{
+			assertEquals(3, f0Genotype.getParts().size());
+			assertEquals(6, f0Genotype.getNeuroDefs().size());
+			assertEquals(2, f0Genotype.getJoints().size());
+
+			assertEquals(new Integer(0), f0Genotype.getJoints().get(0).part1);
+			assertEquals(new Integer(1), f0Genotype.getJoints().get(0).part2);
+			assertEquals(new Integer(1), f0Genotype.getNeuroDefs().get(0).part);
+			assertEquals(new Integer(-1), f0Genotype.getNeuroDefs().get(0).joint);
+			assertEquals("|:p=0.25,r=1", f0Genotype.getNeuroDefs().get(1).details);
+			assertEquals("N", f0Genotype.getNeuroDefs().get(3).details);
+			assertEquals(new Integer(-1), f0Genotype.getNeuroDefs().get(4).part);
+		}
+
+		F0Model f0model = F0Model.build(f0Genotype);
+		{
+			assertEquals(2.0, f0model.getMechParts().get(1).getPosition().x, 0.0);
+			assertTrue(f0model.getMechParts().get(2).getPosition().sub(new Point3d(2.27236, -0.0792596, -0.958924)).length() < 0.0001);
+			assertTrue(f0model.getMechParts().get(2).getOrientation().y.sub(new Point3d(0.870277, -0.404792, 0.280644)).length() < 0.0001);
+		}
+
+	}
+}
Index: /java/main/src/test/resources/log4j.properties
===================================================================
--- /java/main/src/test/resources/log4j.properties	(revision 78)
+++ /java/main/src/test/resources/log4j.properties	(revision 78)
@@ -0,0 +1,28 @@
+# -------------------------------------------------------------------
+# Global logger configuration
+# -------------------------------------------------------------------
+#log4j.rootLogger=INFO, STDOUT, FILE
+log4j.rootLogger=DEBUG, STDOUT
+
+
+# -------------------------------------------------------------------
+# Disable certain libraries from spamming the output
+# -------------------------------------------------------------------
+
+# Apache commons
+log4j.logger.org.apache.commons=WARN
+
+# HttpClient
+log4j.logger.httpclient=WARN
+
+# -------------------------------------------------------------------
+# Define appenders.
+# -------------------------------------------------------------------
+
+# A plain console appender
+log4j.appender.STDOUT=org.apache.log4j.ConsoleAppender
+log4j.appender.STDOUT.Target=System.out
+log4j.appender.STDOUT.layout=org.apache.log4j.PatternLayout
+log4j.appender.STDOUT.layout.ConversionPattern=%d{ABSOLUTE} [%-5p] [%t] %c -- %m%n
+
+log4j.logger.com.framsticks=INFO
Index: /java/main/src/test/resources/parsers/f0_example.txt
===================================================================
--- /java/main/src/test/resources/parsers/f0_example.txt	(revision 78)
+++ /java/main/src/test/resources/parsers/f0_example.txt	(revision 78)
@@ -0,0 +1,20 @@
+//0
+
+p:
+p:i=,Vstyle=
+p:m=1,i="bla"
+j:0,1,dx=2
+j:1,2,dx=1,rx=3,i="1,2,3,\"dsadsa,,,,",rx=8,,9,ry=5,6
+n:p=1
+n:j=0,d="|:p=0.25,r=1"
+n:j=0,d=G
+n:p=1
+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
