Index: /java/main/pom.xml
===================================================================
--- /java/main/pom.xml	(revision 85)
+++ /java/main/pom.xml	(revision 86)
@@ -19,4 +19,10 @@
 	</properties>
 	<dependencies>
+		<dependency>
+			<groupId>org.javatuples</groupId>
+			<artifactId>javatuples</artifactId>
+			<version>1.2</version>
+			<scope>compile</scope>
+		</dependency>
 		<dependency>
 			<groupId>com.google.code.findbugs</groupId>
@@ -90,4 +96,13 @@
 			<plugin>
 				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-surefire-plugin</artifactId>
+				<version>2.9</version>
+				<configuration>
+					<useFile>false</useFile>
+				</configuration>
+			</plugin>
+
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
 				<artifactId>maven-compiler-plugin</artifactId>
 				<version>3.0</version>
Index: /java/main/src/main/java/com/framsticks/core/Entity.java
===================================================================
--- /java/main/src/main/java/com/framsticks/core/Entity.java	(revision 85)
+++ /java/main/src/main/java/com/framsticks/core/Entity.java	(revision 86)
@@ -3,5 +3,6 @@
 import javax.annotation.OverridingMethodsMustInvokeSuper;
 
-import com.framsticks.params.FramsClass;
+import com.framsticks.params.annotations.FramsClassAnnotation;
+import com.framsticks.params.annotations.ParamAnnotation;
 import com.framsticks.util.dispatching.Thread;
 import com.framsticks.util.dispatching.Dispatcher;
@@ -14,8 +15,10 @@
  * @author Piotr Sniegowski
  */
+@FramsClassAnnotation
 public abstract class Entity implements Dispatcher<Entity> {
 
-	private final static Logger log = Logger.getLogger(Entity.class.getName());
+	private final static Logger log = Logger.getLogger(Entity.class);
 
+	@ParamAnnotation
 	protected String name = "entity";
 	protected EntityOwner owner;
@@ -109,6 +112,3 @@
 	}
 
-	public static void constructFramsClass(FramsClass.Constructor constructor) {
-		constructor.method("getName");
-	}
 }
Index: /java/main/src/main/java/com/framsticks/core/Instance.java
===================================================================
--- /java/main/src/main/java/com/framsticks/core/Instance.java	(revision 85)
+++ /java/main/src/main/java/com/framsticks/core/Instance.java	(revision 86)
@@ -23,5 +23,4 @@
 	private static final Logger log = Logger.getLogger(Instance.class.getName());
 
-
 	protected Node root;
 
@@ -34,5 +33,5 @@
 	protected void run() {
 		super.run();
-		root = new Node((CompositeParam)Param.build().name("Instance").id(name).type("o").finish(), null);
+		root = new Node((CompositeParam) Param.build().name("Instance").id(name).type("o").finish(), null);
 		com.framsticks.model.Package.register(registry);
 	}
@@ -112,5 +111,4 @@
 	}
 
-
 	protected void fireListChange(Path path, ListChange change) {
 		assert isActive();
@@ -127,10 +125,8 @@
 	}
 
-
 	public final FramsClass getInfoFromCache(Path path) {
 		return getInfoFromCache(path.getTop().getParam().getContainedTypeName());
 	}
 
-
 	public FramsClass getInfoFromCache(String id) {
 		assert isActive();
@@ -140,9 +136,8 @@
 	protected Registry registry = new Registry();
 
-	public AccessInterface createAccess(String name) {
+	public AccessInterface createAccess(String name) throws ConstructionException {
 		assert isActive();
 		return registry.createAccess(name);
 	}
-
 
 	// TODO: make ValueParam
@@ -165,11 +160,11 @@
 	public final AccessInterface bindAccess(Node node) {
 		assert node.getObject() != null;
-		AccessInterface access = registry.prepareAccess(node.getParam());
-		if (access == null) {
-			log.error("missing access for: " + node.getParam());
-			return null;
-		}
-		access.select(node.getObject());
-		return access;
+
+		try {
+			return registry.prepareAccess(node.getParam()).select(node.getObject());
+		} catch (ConstructionException e) {
+			log.error("failed to bind access for " + node.getParam() + ": " + e);
+		}
+		return null;
 	}
 
Index: /java/main/src/main/java/com/framsticks/gui/controls/Control.java
===================================================================
--- /java/main/src/main/java/com/framsticks/gui/controls/Control.java	(revision 85)
+++ /java/main/src/main/java/com/framsticks/gui/controls/Control.java	(revision 86)
@@ -1,8 +1,12 @@
 package com.framsticks.gui.controls;
 
+import java.awt.BorderLayout;
+
+import javax.swing.JComponent;
+import javax.swing.JPanel;
+
+import com.framsticks.gui.Frame;
 import com.framsticks.params.Flags;
 import com.framsticks.params.Param;
-import javax.swing.*;
-import java.awt.*;
 
 /**
Index: /java/main/src/main/java/com/framsticks/hosting/ServerInstance.java
===================================================================
--- /java/main/src/main/java/com/framsticks/hosting/ServerInstance.java	(revision 85)
+++ /java/main/src/main/java/com/framsticks/hosting/ServerInstance.java	(revision 86)
@@ -3,5 +3,7 @@
 import com.framsticks.core.*;
 import com.framsticks.params.CompositeParam;
+import com.framsticks.params.ConstructionException;
 import com.framsticks.params.FramsClass;
+import com.framsticks.params.FramsClassBuilder;
 import com.framsticks.params.Param;
 import com.framsticks.core.LocalInstance;
@@ -42,5 +44,5 @@
 		hosted.setName("hosted");
 		hosted.configure(hostedConfig);
-		root = new Node((CompositeParam)Param.build().name("root").id("root").type("o" + hosted.getClass().getCanonicalName()).finish(), hosted);
+		root = new Node((CompositeParam) Param.build().name("root").id("root").type("o" + hosted.getClass().getCanonicalName()).finish(), hosted);
 	}
 
@@ -57,5 +59,10 @@
 		try {
 			Class<?> nativeClass = Class.forName(id);
-			FramsClass framsClass = new FramsClass.Constructor(nativeClass, id).getResult();
+			FramsClass framsClass = FramsClassBuilder.buildForClass(nativeClass);
+
+			if (!framsClass.getId().equals(id)) {
+				log.error("no matching id");
+				return null;
+			}
 
 			registry.registerReflectedClass(null, id, nativeClass);
@@ -63,4 +70,6 @@
 			return framsClass;
 		} catch (ClassNotFoundException ignored) {
+		} catch (ConstructionException e) {
+			log.error("failed to use info from cache: " + e);
 		}
 
Index: /java/main/src/main/java/com/framsticks/model/BaseJoint.java
===================================================================
--- /java/main/src/main/java/com/framsticks/model/BaseJoint.java	(revision 85)
+++ /java/main/src/main/java/com/framsticks/model/BaseJoint.java	(revision 86)
@@ -1,4 +1,5 @@
 package com.framsticks.model;
 
+import com.framsticks.params.annotations.ParamAnnotation;
 import com.framsticks.util.math.Point3d;
 
@@ -8,15 +9,11 @@
 public class BaseJoint {
 
-	/** stif */
-	public Double stiffness;
-	public Double getStif() { return stiffness; }
-	public void setStif(Double stif) { stiffness = stif; }
+	@ParamAnnotation(id = "stif")
+	public double stiffness;
 
-	/** rotstif */
-	public Double rotationStiffness;
-	public Double getRotstif() { return rotationStiffness; }
-	public void setRotstif(Double rotstif) { rotationStiffness = rotstif; }
+	@ParamAnnotation(id = "rotstif")
+	public double rotationStiffness;
 
-	/** rx, ry, rz*/
+	@ParamAnnotation
 	public double rx, ry, rz;
 
@@ -24,5 +21,5 @@
 	public void setRotation(Point3d r) { rx = r.x; ry = r.y; rz = r.z; }
 
-	/** dx, dy, dz*/
+	@ParamAnnotation
 	public double dx, dy, dz;
 
Index: /java/main/src/main/java/com/framsticks/model/BaseNeuro.java
===================================================================
--- /java/main/src/main/java/com/framsticks/model/BaseNeuro.java	(revision 85)
+++ /java/main/src/main/java/com/framsticks/model/BaseNeuro.java	(revision 86)
@@ -1,3 +1,5 @@
 package com.framsticks.model;
+
+import com.framsticks.params.annotations.ParamAnnotation;
 
 /**
@@ -5,8 +7,7 @@
  */
 public class BaseNeuro {
-	/** inputCount */
-	public Integer inputCount;
-	public Integer getGetInputCount() { return inputCount; }
-	public void setGetInputCount(Integer getInputCount) { inputCount = getInputCount; }
+
+	@ParamAnnotation(id = "getInputCount")
+	public int inputCount;
 
 
Index: /java/main/src/main/java/com/framsticks/model/BasePart.java
===================================================================
--- /java/main/src/main/java/com/framsticks/model/BasePart.java	(revision 85)
+++ /java/main/src/main/java/com/framsticks/model/BasePart.java	(revision 86)
@@ -1,4 +1,5 @@
 package com.framsticks.model;
 
+import com.framsticks.params.annotations.ParamAnnotation;
 import com.framsticks.util.math.Orientation;
 import com.framsticks.util.math.Point3d;
@@ -8,5 +9,6 @@
  */
 public class BasePart {
-	/** x, y, z */
+
+	@ParamAnnotation
 	public double x, y, z;
 
@@ -14,20 +16,14 @@
 	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; }
+	@ParamAnnotation(id = "m")
+	public double mass = 0.0;
 
-	/** s */
-	public Double size = 0.0;
-	public Double getS() { return size; }
-	public void setS(Double s) { size = s; }
+	@ParamAnnotation(id = "s")
+	public double size = 0.0;
 
-	/** fr */
-	public Double friction;
-	public Double getFr() { return friction; }
-	public void setFr(Double fr) { friction = fr; }
+	@ParamAnnotation(id = "fr")
+	public double friction;
 
-
+	@ParamAnnotation
 	public double oxx, oxy, oxz, oyx, oyy, oyz, ozx, ozy, ozz;
 
Index: /java/main/src/main/java/com/framsticks/model/Creature.java
===================================================================
--- /java/main/src/main/java/com/framsticks/model/Creature.java	(revision 85)
+++ /java/main/src/main/java/com/framsticks/model/Creature.java	(revision 86)
@@ -1,5 +1,6 @@
 package com.framsticks.model;
 
-import com.framsticks.params.FramsClass;
+import com.framsticks.params.annotations.FramsClassAnnotation;
+import com.framsticks.params.annotations.ParamAnnotation;
 import com.framsticks.util.math.Point3d;
 
@@ -7,91 +8,80 @@
 import java.util.List;
 
+@FramsClassAnnotation
 public class Creature {
+
+	@ParamAnnotation
 	public String name;
 
+	@ParamAnnotation
 	public String genotype;
 
+	@ParamAnnotation
 	public String info;
 
+	@ParamAnnotation
 	public Object group;
 
-	public Integer generation;
-	public Integer getGnum() { return generation; }
-	public void setGnum(Integer gnum) { generation = gnum; }
+	@ParamAnnotation(id = "gnum")
+	public int generation;
 
-	public Integer buildProblems;
-	public Integer getBuildproblems() { return buildProblems; }
-	public void setBuildproblems(Integer buildproblems) { buildProblems = buildproblems; }
+	@ParamAnnotation(id = "buildproblems")
+	public int buildProblems;
 
-	public Double startingEnergy;
-	public Double getEnerg0() { return startingEnergy; }
-	public void setEnerg0(Double energ0) { startingEnergy = energ0; }
+	@ParamAnnotation(id = "energ0")
+	public double startingEnergy;
 
-	public Double idlePowerConsumption;
-	public Double getIdleen() { return idlePowerConsumption; }
-	public void setIdleen(Double idleen) { idlePowerConsumption = idleen; }
+	@ParamAnnotation(id = "idleen")
+	public double idlePowerConsumption;
 
-	public Double energy;
+	@ParamAnnotation
+	public double energy;
 
-	public Double energyIncome;
-	public Double getEnergy_p() { return energyIncome; }
-	public void setEnergy_p(Double energy_p) { energyIncome = energy_p; }
+	@ParamAnnotation(id = "energy_p")
+	public double energyIncome;
 
-	public Double energyCosts;
-	public Double getEnergy_m() { return energyCosts; }
-	public void setEnergy_m(Double energy_m) { energyCosts = energy_m; }
+	@ParamAnnotation(id = "energy_m")
+	public double energyCosts;
 
-	public Double energyBalance;
-	public Double getEnergy_b() { return energyBalance; }
-	public void setEnergy_b(Double energy_b) { energyBalance = energy_b; }
+	@ParamAnnotation(id = "energy_b")
+	public double energyBalance;
 
-	public Integer performanceCalculation;
-	public Integer getPerf() { return performanceCalculation; }
-	public void setPerf(Integer perf) { performanceCalculation = perf; }
+	@ParamAnnotation(id = "perf")
+	public int performanceCalculation;
 
-	public Boolean neuralNetworkEnabled;
+	@ParamAnnotation(id = "nnenabled")
+	public boolean neuralNetworkEnabled;
 
-	public Boolean getNnenabled() { return neuralNetworkEnabled; }
-	public void setNnenabled(Boolean nnenabled) { neuralNetworkEnabled = nnenabled; }
+	@ParamAnnotation(id = "bodysim")
+	public boolean bodySimulation;
 
-	public Boolean bodySimulation;
-	public Boolean getBodysim() { return bodySimulation; }
-	public void setBodysim(Boolean bodysim) { bodySimulation = bodysim; }
+	@ParamAnnotation(id = "selfcol")
+	public boolean selfCollisions;
 
-	public Boolean selfCollisions;
-	public Boolean getSelfcol() { return selfCollisions; }
-	public void setSelfcol(Boolean selfcol) { selfCollisions = selfcol; }
+	@ParamAnnotation(id = "lifespan")
+	public int lifeSpan;
 
-	public Integer lifeSpan;
-	public Integer getLifespan() { return lifeSpan; }
-	public void setLifespan(Integer lifespan) { lifeSpan = lifespan; }
+	@ParamAnnotation
+	public double distance;
 
-	public Double distance;
+	@ParamAnnotation(id = "c_velocity")
+	public double currentVelocity;
 
-	public Double currentVelocity;
-	public Double getC_velocity() { return currentVelocity; }
-	public void setC_velocity(Double c_velocity) { currentVelocity = c_velocity; }
+	@ParamAnnotation(id = "c_vertvelocity")
+	public double currentVerticalVelocity;
 
-	public Double currentVerticalVelocity;
-	public Double getC_vertvelocity() { return currentVerticalVelocity; }
-	public void setC_vertvelocity(Double c_vertvelocity) { currentVerticalVelocity = c_vertvelocity; }
+	@ParamAnnotation(id = "c_vertpos")
+	public double currentVerticalPosition;
 
-	public Double currentVerticalPosition;
-	public Double getC_vertpos() { return currentVerticalPosition; }
-	public void setC_vertpos(Double c_vertpos) { currentVerticalPosition = c_vertpos; }
+	@ParamAnnotation(id = "velocity")
+	public double averageVelocity;
 
-	public Double averageVelocity;
-	public Double getVelocity() { return averageVelocity; }
-	public void setVelocity(Double c_velocity) { averageVelocity = c_velocity; }
+	@ParamAnnotation(id = "vertvel")
+	public double averageVerticalVelocity;
 
-	public Double averageVerticalVelocity;
-	public Double getVertvel() { return averageVerticalVelocity; }
-	public void setVertvel(Double c_vertvelocity) { averageVerticalVelocity = c_vertvelocity; }
+	@ParamAnnotation(id = "vertpos")
+	public double averageVerticalPosition;
 
-	public Double averageVerticalPosition;
-	public Double getVertpos() { return averageVerticalPosition; }
-	public void setVertpos(Double c_vertpos) { averageVerticalPosition = c_vertpos; }
-
-	/** pos_x, pos_y, pos_z*/
+	@ParamAnnotation
 	public double pos_x, pos_y, pos_z;
 
@@ -99,4 +89,5 @@
 	public void setPosition(Point3d pos) { pos_x = pos.x; pos_y = pos.y; pos_z = pos.z; }
 
+	@ParamAnnotation
 	public double size_x, size_y, size_z;
 
@@ -106,4 +97,5 @@
 
 	/** center_x, center_y, center_z*/
+	@ParamAnnotation
 	public double center_x, center_y, center_z;
 
@@ -111,37 +103,55 @@
 	public void setCenter(Point3d center) { center_x = center.x; center_y = center.y; center_z = center.z; }
 
-	public Integer getNumparts() { return parts.size(); }
-	public void setNumparts(Integer numparts) { }
+	@ParamAnnotation
+	public int getNumparts() { return parts.size(); }
+	@ParamAnnotation
+	public void setNumparts(int numparts) { }
 
-	public Integer getNumjoints() { return joints.size(); }
-	public void setNumjoints(Integer numjoints) { }
+	@ParamAnnotation
+	public int getNumjoints() { return joints.size(); }
+	@ParamAnnotation
+	public void setNumjoints(int numjoints) { }
 
-	public Integer getNumneurons() { return neurons.size(); }
-	public void setNumneurons(Integer numneurons) { }
+	@ParamAnnotation
+	public int getNumneurons() { return neurons.size(); }
+	@ParamAnnotation
+	public void setNumneurons(int numneurons) { }
 
 	public Object[] userFields = new Object[3];
+	@ParamAnnotation
 	public Object getUser1() { return userFields[0]; }
+	@ParamAnnotation
 	public void setUser1(Object user1) { userFields[0] = user1; }
 
+	@ParamAnnotation
 	public Object getUser2() { return userFields[1]; }
+	@ParamAnnotation
 	public void setUser2(Object user2) { userFields[1] = user2; }
 
+	@ParamAnnotation
 	public Object getUser3() { return userFields[2]; }
+	@ParamAnnotation
 	public void setUser3(Object user3) { userFields[2] = user3; }
 
-	public Integer selfCollisionMask;
-	public Integer getSelfmask() { return selfCollisionMask; }
-	public void setSelfmask(Integer selfmask) { selfCollisionMask = selfmask; }
+	@ParamAnnotation(id = "selfmask")
+	public int selfCollisionMask;
 
-	public Integer otherCollisionMask;
-	public Integer getOthermask() { return otherCollisionMask; }
-	public void setOthermask(Integer othermask) { otherCollisionMask = othermask; }
+	@ParamAnnotation(id = "othermask")
+	public int otherCollisionMask;
 
+	@ParamAnnotation(id = "selfcolstate")
+	public boolean selfCollisionsState;
+
+	@ParamAnnotation
 	public String uid;
 
-	public Integer index;
+	@ParamAnnotation
+	public int index;
 
+	@ParamAnnotation
 	public final List<Part> parts = new ArrayList<Part>();
+	@ParamAnnotation
 	public final List<Joint> joints = new ArrayList<Joint>();
+	@ParamAnnotation
 	public final List<NeuroDef> neurodefs = new ArrayList<NeuroDef>();
 
@@ -150,6 +160,9 @@
 	public final List<NeuroDef> getNeuroDefs() { return neurodefs; }
 
+	@ParamAnnotation
 	public final List<MechPart> mechparts = new ArrayList<MechPart>();
+	@ParamAnnotation
 	public final List<MechJoint> mechjoints = new ArrayList<MechJoint>();
+	@ParamAnnotation
 	public final List<Neuro> neurons = new ArrayList<Neuro>();
 
@@ -158,15 +171,3 @@
 	public final List<Neuro> getNeurons() { return neurons; }
 
-
-
-	public static void constructFramsClass(FramsClass.Constructor constructor) {
-		constructor.field("name");
-		constructor.field("parts");
-		constructor.field("joints");
-		constructor.field("neurodefs");
-		constructor.field("mechparts");
-		constructor.field("mechjoints");
-		constructor.field("neurons");
-	}
-
 }
Index: /java/main/src/main/java/com/framsticks/model/Genotype.java
===================================================================
--- /java/main/src/main/java/com/framsticks/model/Genotype.java	(revision 85)
+++ /java/main/src/main/java/com/framsticks/model/Genotype.java	(revision 86)
@@ -1,74 +1,115 @@
 package com.framsticks.model;
+
+import com.framsticks.params.annotations.FramsClassAnnotation;
+import com.framsticks.params.annotations.ParamAnnotation;
 
 
 // import org.apache.log4j.Logger;
 
+@FramsClassAnnotation
 public class Genotype extends Model {
 	// private final static Logger log = Logger.getLogger(Genotype.class);
 
+	@ParamAnnotation
 	public String name;
+
+	@ParamAnnotation
 	public String genotype;
+
+	@ParamAnnotation
 	public String info;
 
-	public Double similarity;
-	public Double getSimi() { return similarity; }
-	public void setSimi(Double simi) { similarity = simi; }
+	@ParamAnnotation(id = "simi")
+	public double similarity;
 
-	public Double brainConnections;
-	public Double getNumconnections() { return brainConnections; }
-	public void setNumconnections(Double numconnections) { brainConnections = numconnections; }
+	@ParamAnnotation(id = "numconnections")
+	public double brainConnections;
 
-    public Integer ordinalNumber;
-	public Integer getNum() { return ordinalNumber; }
-	public void setNum(Integer num) { ordinalNumber = num; }
+	@ParamAnnotation(id = "num")
+	public int ordinalNumber;
 
-    public Integer generation;
-	public Integer getGnum() { return generation; }
-	public void setGnum(Integer gnum) { generation = gnum; }
+	@ParamAnnotation(id = "gnum")
+	public int generation;
 
-	public Integer instances;
+	@ParamAnnotation
+	public int instances;
 
-	public Integer lifeSpan;
-	public Integer getLifespan() { return lifeSpan; }
-	public void setLifespan(Integer lifespan) { lifeSpan = lifespan; }
+	@ParamAnnotation(id = "lifespan")
+	public double lifeSpan;
 
-	public Double velocity;
-	public Double distance;
+	@ParamAnnotation
+	public double velocity;
 
-	public Double verticalVelocity;
-	public Double getVertvel() { return verticalVelocity; }
-	public void setVertvel(Double vertvel) { verticalVelocity = vertvel; }
+	@ParamAnnotation
+	public double distance;
 
-	public Double verticalPosition;
-	public Double getVertpos() { return verticalPosition; }
-	public void setVertpos(Double vertpos) { verticalPosition = vertpos; }
+	@ParamAnnotation(id = "vertvel")
+	public double verticalVelocity;
 
-	public Double fitness;
-	public Double getFit() { return fitness; }
-	public void setFit(Double fit) { fitness = fit; }
+	@ParamAnnotation(id = "vertpos")
+	public double verticalPosition;
 
-	public Double finalFitness;
-	public Double getFit2() { return finalFitness; }
-	public void setFit2(Double fit2) { finalFitness = fit2; }
+	@ParamAnnotation(id = "fit")
+	public double fitness;
 
+	@ParamAnnotation(id = "fit2")
+	public double finalFitness;
+
+	@ParamAnnotation(id = "f0genotype")
 	public String genotypeInF0;
-	public String getF0genotype() { return genotypeInF0; }
-	public void setF0genotype(String f0genotype) { genotypeInF0 = f0genotype; }
 
+	@ParamAnnotation(id = "convtrace1")
 	public String conversionBacktrace;
-	public String getConvtrace1() { return conversionBacktrace; }
-	public void setConvtrace1(String convtrace1) { conversionBacktrace = convtrace1; }
+
+	@ParamAnnotation
+	public boolean isValid;
 
 	public Object[] userFields = new Object[3];
+	@ParamAnnotation
 	public Object getUser1() { return userFields[0]; }
+	@ParamAnnotation
 	public void setUser1(Object user1) { userFields[0] = user1; }
 
+	@ParamAnnotation
 	public Object getUser2() { return userFields[1]; }
+	@ParamAnnotation
 	public void setUser2(Object user2) { userFields[1] = user2; }
 
+	@ParamAnnotation
 	public Object getUser3() { return userFields[2]; }
+	@ParamAnnotation
 	public void setUser3(Object user3) { userFields[2] = user3; }
 
+	@ParamAnnotation
 	public String uid;
+
+	@ParamAnnotation
+	public double getStrsiz() { return getNumparts(); }
+	@ParamAnnotation
+	public void setStrsiz(double strsiz) { setNumparts(strsiz); }
+
+
+	@ParamAnnotation
+	public double getStrjoints() { return getNumjoints(); }
+	@ParamAnnotation
+	public void setStrjoints(double strjoints) { setNumjoints(strjoints); }
+
+
+	@ParamAnnotation
+	public double getNnsiz() { return getNumneurons(); }
+	@ParamAnnotation
+	public void setNnsiz(double nnsiz) { setNumneurons(nnsiz); }
+
+
+	@ParamAnnotation
+	public double getNncon() { return brainConnections; }
+	@ParamAnnotation
+	public void setNncon(double nncon) { this.brainConnections = nncon; }
+
+	@ParamAnnotation
+	public int getPopsiz() { return instances; }
+	@ParamAnnotation
+	public void setPopsiz(int popsiz) { this.instances = popsiz; }
+
 
 }
Index: /java/main/src/main/java/com/framsticks/model/Joint.java
===================================================================
--- /java/main/src/main/java/com/framsticks/model/Joint.java	(revision 85)
+++ /java/main/src/main/java/com/framsticks/model/Joint.java	(revision 86)
@@ -1,3 +1,6 @@
 package com.framsticks.model;
+
+import com.framsticks.params.annotations.FramsClassAnnotation;
+import com.framsticks.params.annotations.ParamAnnotation;
 
 /**
@@ -6,31 +9,24 @@
  * All accessors are used by ReflectionAccess.
  */
+@FramsClassAnnotation(id = "j")
 public class Joint extends BaseJoint {
 
-	/** i */
+	@ParamAnnotation(id = "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; }
+	@ParamAnnotation(id = "p1")
+	public int part1;
 
-	/** p2 */
-	public Integer part2;
-	public void setP2(Integer p2) { part2 = p2; }
-	public Integer getP2() { return part2; }
+	@ParamAnnotation(id = "p2")
+	public int part2;
 
+	@ParamAnnotation(id = "stam")
+	public double stamina;
 
-	/** stam */
-	public Double stamina;
-	public Double getStam() { return stamina; }
-	public void setStam(Double stam) { stamina = stam; }
+	@ParamAnnotation(id = "Vstyle")
+	public String visualizationStyle;
 
+	@ParamAnnotation
+	public double vr, vg, vb;
 
-	/** 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 85)
+++ /java/main/src/main/java/com/framsticks/model/MechJoint.java	(revision 86)
@@ -1,17 +1,17 @@
 package com.framsticks.model;
+
+import com.framsticks.params.annotations.FramsClassAnnotation;
+import com.framsticks.params.annotations.ParamAnnotation;
 
 /**
  * @author Piotr Sniegowski
  */
+@FramsClassAnnotation
 public class MechJoint extends BaseJoint {
 
-	/** stress */
-	public Double stress;
-	public Double getStress() { return stress; }
-	public void setStress(Double stress) { this.stress = stress; }
+	@ParamAnnotation
+	public double stress;
 
-	/** rotstress */
-	public Double rotationStress;
-	public Double getRotstress() { return rotationStress; }
-	public void setRotstress(Double rotstress) { rotationStress = rotstress; }
+	@ParamAnnotation(id = "rotstress")
+	public double rotationStress;
 }
Index: /java/main/src/main/java/com/framsticks/model/MechPart.java
===================================================================
--- /java/main/src/main/java/com/framsticks/model/MechPart.java	(revision 85)
+++ /java/main/src/main/java/com/framsticks/model/MechPart.java	(revision 86)
@@ -1,16 +1,17 @@
 package com.framsticks.model;
 
+import com.framsticks.params.annotations.FramsClassAnnotation;
+import com.framsticks.params.annotations.ParamAnnotation;
 import com.framsticks.util.math.Point3d;
 
 /*
  */
+@FramsClassAnnotation
 public class MechPart extends BasePart {
 
-	/** vol */
-	public Double volume = 0.0;
-	public Double getVol() { return volume; }
-	public void setVol(Double vol) { volume = vol; }
+	@ParamAnnotation(id = "vol")
+	public double volume = 0.0;
 
-	/** vx, vy, vz*/
+	@ParamAnnotation
 	public double vx, vy, vz;
 
Index: /java/main/src/main/java/com/framsticks/model/Model.java
===================================================================
--- /java/main/src/main/java/com/framsticks/model/Model.java	(revision 85)
+++ /java/main/src/main/java/com/framsticks/model/Model.java	(revision 86)
@@ -1,4 +1,6 @@
 package com.framsticks.model;
 
+import com.framsticks.params.annotations.FramsClassAnnotation;
+import com.framsticks.params.annotations.ParamAnnotation;
 import com.framsticks.util.lang.Casting;
 import com.framsticks.util.lang.Containers;
@@ -14,32 +16,45 @@
  * Author: Piotr Śniegowski
  */
+@FramsClassAnnotation(id = "m")
 public class Model {
 
 	private final static Logger log = Logger.getLogger(Model.class);
 
-	public Double startingEnergy;
-	public Double getEnerg0() { return startingEnergy; }
-	public void setEnerg0(Double energ0) { startingEnergy = energ0; }
+	@ParamAnnotation(id = "se")
+	public double startingEnergy;
 
-	public Double getSe() { return startingEnergy; }
-	public void setSe(Double se) { startingEnergy = se; }
+	@ParamAnnotation
+	public double getEnerg0() { return startingEnergy; }
+	@ParamAnnotation
+	public void setEnerg0(double energ0) { startingEnergy = energ0; }
 
-	/** Vstyle */
+
+	@ParamAnnotation(id = "Vstyle")
 	public String visualizationStyle;
-	public String getVstyle() { return visualizationStyle; }
-	public void setVstyle(String Vstyle) { visualizationStyle = Vstyle; }
 
+	@ParamAnnotation
 	public final List<Part> parts = new ArrayList<Part>();
+
+	@ParamAnnotation
 	public final List<Joint> joints = new ArrayList<Joint>();
+
+	@ParamAnnotation
 	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(); }
+	//TODO: why those methods returns and accepts doubles?
+	@ParamAnnotation
+	public double getNumparts() { return (double)parts.size(); }
+	@ParamAnnotation
+	public double getNumjoints() { return (double)joints.size(); }
+	@ParamAnnotation
+	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); }
+	@ParamAnnotation
+	public void setNumparts(double numparts) { Containers.resizeList(parts, (int) (double) numparts); }
+	@ParamAnnotation
+	public void setNumjoints(double numjoints) { Containers.resizeList(joints, (int)(double)numjoints); }
+	@ParamAnnotation
+	public void setNumneurons(double numneurons) { Containers.resizeList(neurodefs, (int)(double)numneurons); }
 
 	public List<Part> getParts() { return parts; }
@@ -78,6 +93,6 @@
 		for (Joint j : f0Genotype.getJoints()) {
 			/** based on c++ Joint::attachToParts*/
-			Part p1 = f0Genotype.parts.get(j.getP1());
-			Part p2 = f0Genotype.parts.get(j.getP2());
+			Part p1 = f0Genotype.parts.get(j.part1);
+			Part p2 = f0Genotype.parts.get(j.part2);
 			assert p1 != null && p2 != null;
 			Orientation o = new Orientation().rotate(j.getRotation());
Index: /java/main/src/main/java/com/framsticks/model/Neuro.java
===================================================================
--- /java/main/src/main/java/com/framsticks/model/Neuro.java	(revision 85)
+++ /java/main/src/main/java/com/framsticks/model/Neuro.java	(revision 86)
@@ -1,4 +1,6 @@
 package com.framsticks.model;
 
+import com.framsticks.params.annotations.FramsClassAnnotation;
+import com.framsticks.params.annotations.ParamAnnotation;
 import com.framsticks.util.math.Point3d;
 
@@ -6,20 +8,26 @@
  * @author Piotr Sniegowski
  */
+@FramsClassAnnotation
 public class Neuro extends BaseNeuro {
 
-	public Integer channelCount;
+	@ParamAnnotation
+	public int channelCount;
 
-	public Double inputSum;
+	@ParamAnnotation
+	public double inputSum;
 
-	public Double weightedInputSum;
+	@ParamAnnotation
+	public double weightedInputSum;
 
-	public Double state;
+	@ParamAnnotation
+	public double state;
 
-	public Double currentState;
-	public Double getCurrState() { return currentState; }
-	public void setCurrState(Double currState) { currentState = currState; }
+	@ParamAnnotation(id = "currState")
+	public double currentState;
 
-	public Boolean hold;
+	@ParamAnnotation
+	public boolean hold;
 
+	@ParamAnnotation
 	public double position_x, position_y, position_z;
 
Index: /java/main/src/main/java/com/framsticks/model/NeuroDef.java
===================================================================
--- /java/main/src/main/java/com/framsticks/model/NeuroDef.java	(revision 85)
+++ /java/main/src/main/java/com/framsticks/model/NeuroDef.java	(revision 86)
@@ -1,40 +1,27 @@
 package com.framsticks.model;
+
+import com.framsticks.params.annotations.FramsClassAnnotation;
+import com.framsticks.params.annotations.ParamAnnotation;
 
 /**
  * @author Piotr Sniegowski
  */
+@FramsClassAnnotation(id = "n")
 public class NeuroDef extends BaseNeuro {
 
-	/** p */
-	public Integer part;
+	@ParamAnnotation(id = "p")
+	public int part;
 
-	/** j */
-	public Integer joint;
+	@ParamAnnotation(id = "j")
+	public int joint;
 
-	/** d */
+	@ParamAnnotation(id = "d")
 	public String details;
 
-	/** i */
+	@ParamAnnotation(id = "i")
 	public String info;
 
-	/** Vstyle */
+	@ParamAnnotation(id = "Vstyle")
 	public String visualizationStyle;
 
-	public Integer getP() { return part; }
-	public void setP(Integer p) { part = p; }
-
-	public Integer getJ() { return joint; }
-	public void setJ(Integer j) { joint = j; }
-
-	public String getD() { return details; }
-	public void setD(String d) { details = d; }
-
-	public String getI() { return info; }
-	public void setI(String i) { info = i; }
-
-	public String getVstyle() { return visualizationStyle; }
-	public void setVstyle(String Vstyle) { visualizationStyle = Vstyle; }
-
-
-
 }
Index: /java/main/src/main/java/com/framsticks/model/Package.java
===================================================================
--- /java/main/src/main/java/com/framsticks/model/Package.java	(revision 85)
+++ /java/main/src/main/java/com/framsticks/model/Package.java	(revision 86)
@@ -8,14 +8,15 @@
 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.Model");
-		registry.registerReflectedClass("Creature", null, "com.framsticks.model.Creature");
-		registry.registerReflectedClass("Genotype", null, "com.framsticks.model.Genotype");
-
+		registry
+			.register(MechPart.class)
+			.register(Joint.class)
+			.register(MechJoint.class)
+			.register(Neuro.class)
+			.register(NeuroDef.class)
+			.register(Part.class)
+			.register(Model.class)
+			.register(Creature.class)
+			.register(Genotype.class)
+			.register(World.class);
 	}
 }
Index: /java/main/src/main/java/com/framsticks/model/Part.java
===================================================================
--- /java/main/src/main/java/com/framsticks/model/Part.java	(revision 85)
+++ /java/main/src/main/java/com/framsticks/model/Part.java	(revision 86)
@@ -2,4 +2,6 @@
 
 
+import com.framsticks.params.annotations.FramsClassAnnotation;
+import com.framsticks.params.annotations.ParamAnnotation;
 import com.framsticks.util.math.Point3d;
 
@@ -7,41 +9,34 @@
  * The Class Part.
  */
+@FramsClassAnnotation(id = "p")
 public class Part extends BasePart {
 
-	/** rx, ry, rz*/
+	@ParamAnnotation
 	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; }
 
-	/** dn */
-	public Double density;
+	@ParamAnnotation(id = "dn")
+	public double density;
 
-	/** ing */
-	public Double ingestion;
+	@ParamAnnotation(id = "ing")
+	public double ingestion;
 
-	/** as */
-	public Double assimilation;
+	@ParamAnnotation(id = "as")
+	public double assimilation;
 
-	/** i */
+	@ParamAnnotation(id = "i")
 	public String info;
 
-	/** Vstyle */
+	@ParamAnnotation(id = "Vstyle")
 	public String visualizationStyle;
 
-	public Double getDn() { return density; }
-	public void setDn(Double dn) { density = dn; }
+	@ParamAnnotation(id = "vs")
+	public double visualThickness;
 
-	public Double getIng() { return ingestion; }
-	public void setIng(Double ing) { ingestion = ing; }
-
-	public Double getAs() { return assimilation; }
-	public void setAs(Double as) { assimilation = as; }
-
-	public String getI() { return info; }
-	public void setI(String i) { info = i; }
-
-	public String getVstyle() { return visualizationStyle; }
-	public void setVstyle(String vstyle) { visualizationStyle = vstyle; }
+	@ParamAnnotation
+	public double vr, vg, vb;
 
 }
Index: /java/main/src/main/java/com/framsticks/model/World.java
===================================================================
--- /java/main/src/main/java/com/framsticks/model/World.java	(revision 85)
+++ /java/main/src/main/java/com/framsticks/model/World.java	(revision 86)
@@ -1,11 +1,37 @@
 package com.framsticks.model;
 
+import com.framsticks.params.annotations.FramsClassAnnotation;
+import com.framsticks.params.annotations.ParamAnnotation;
+
+@FramsClassAnnotation
 public class World {
 
-	public Integer wrldbnd;
-	public Double wrldwat;
-	public String faces;
+	@ParamAnnotation(id = "wrldbnd")
+	public int boundaries;
+
+	@ParamAnnotation(id = "wrldwat")
+	public double waterLevel;
 
 
+	@ParamAnnotation(id = "wrldtyp")
+	public int type;
+
+	@ParamAnnotation(id = "wrldsiz")
+	public double size;
+
+	@ParamAnnotation(id = "wrldmap")
+	public String map;
+
+	@ParamAnnotation(id = "wrldg")
+	public double gravity;
+
+	@ParamAnnotation(id = "simtype")
+	public int simulationEngine;
+
+	@ParamAnnotation(id = "nnspeed")
+	public double neuralNetworkSimulationSpeed;
+
+	@ParamAnnotation
+	public String faces;
 	/*
 	public static ReflectionAccess createReflection()
Index: /java/main/src/main/java/com/framsticks/observers/Endpoint.java
===================================================================
--- /java/main/src/main/java/com/framsticks/observers/Endpoint.java	(revision 85)
+++ /java/main/src/main/java/com/framsticks/observers/Endpoint.java	(revision 86)
@@ -4,5 +4,6 @@
 import com.framsticks.core.InstanceListener;
 import com.framsticks.core.Path;
-import com.framsticks.params.FramsClass;
+import com.framsticks.params.annotations.FramsClassAnnotation;
+import com.framsticks.params.annotations.ParamAnnotation;
 import com.framsticks.core.ListChange;
 import com.framsticks.util.dispatching.Dispatcher;
@@ -13,9 +14,13 @@
  * @author Piotr Sniegowski
  */
+@FramsClassAnnotation
 public class Endpoint implements Dispatcher<Instance>, InstanceListener {
 	private final static Logger log = Logger.getLogger(Endpoint.class.getName());
 
+	@ParamAnnotation
 	protected Instance instance;
 	protected Observer observer;
+
+	@ParamAnnotation
 	protected String name;
 
@@ -80,7 +85,4 @@
 	}
 
-	public static void constructFramsClass(FramsClass.Constructor constructor) {
-		constructor.method("getName").method("getInstance");
-	}
 
 }
Index: /java/main/src/main/java/com/framsticks/observers/Observer.java
===================================================================
--- /java/main/src/main/java/com/framsticks/observers/Observer.java	(revision 85)
+++ /java/main/src/main/java/com/framsticks/observers/Observer.java	(revision 86)
@@ -4,5 +4,6 @@
 import com.framsticks.core.Instance;
 import com.framsticks.core.Program;
-import com.framsticks.params.FramsClass;
+import com.framsticks.params.annotations.FramsClassAnnotation;
+import com.framsticks.params.annotations.ParamAnnotation;
 import com.framsticks.util.lang.Casting;
 import org.apache.commons.configuration.Configuration;
@@ -14,4 +15,5 @@
  * @author Piotr Sniegowski
  */
+@FramsClassAnnotation
 public abstract class Observer extends Entity {
 
@@ -21,4 +23,5 @@
 	}
 
+	@ParamAnnotation
 	protected final Map<String, Endpoint> endpoints = new HashMap<String, Endpoint>();
 
@@ -68,7 +71,4 @@
 	}
 
-	public static void constructFramsClass(FramsClass.Constructor constructor) {
-		constructor.method("getEndpoints");
-	}
 
 
Index: /java/main/src/main/java/com/framsticks/params/AccessInterface.java
===================================================================
--- /java/main/src/main/java/com/framsticks/params/AccessInterface.java	(revision 85)
+++ /java/main/src/main/java/com/framsticks/params/AccessInterface.java	(revision 86)
@@ -66,5 +66,5 @@
 	Object getSelected();
 
-	AccessInterface cloneAccess();
+	AccessInterface cloneAccess() throws ConstructionException;
 
 	Object createAccessee();
Index: /java/main/src/main/java/com/framsticks/params/ArrayListAccess.java
===================================================================
--- /java/main/src/main/java/com/framsticks/params/ArrayListAccess.java	(revision 85)
+++ /java/main/src/main/java/com/framsticks/params/ArrayListAccess.java	(revision 86)
@@ -20,5 +20,5 @@
 
 	@Override
-	public ArrayListAccess cloneAccess() {
+	public ArrayListAccess cloneAccess() throws ConstructionException {
 		return new ArrayListAccess(elementAccess.cloneAccess());
 	}
Index: /java/main/src/main/java/com/framsticks/params/ConstructionException.java
===================================================================
--- /java/main/src/main/java/com/framsticks/params/ConstructionException.java	(revision 86)
+++ /java/main/src/main/java/com/framsticks/params/ConstructionException.java	(revision 86)
@@ -0,0 +1,8 @@
+package com.framsticks.params;
+
+import com.framsticks.util.FramsticksException;
+
+@SuppressWarnings("serial")
+public class ConstructionException extends FramsticksException {
+
+}
Index: /java/main/src/main/java/com/framsticks/params/FramsClass.java
===================================================================
--- /java/main/src/main/java/com/framsticks/params/FramsClass.java	(revision 85)
+++ /java/main/src/main/java/com/framsticks/params/FramsClass.java	(revision 86)
@@ -1,14 +1,11 @@
 package com.framsticks.params;
 
-import com.framsticks.params.types.StringParam;
-import com.framsticks.parsers.FileSource;
-import com.framsticks.parsers.Loaders;
-import com.framsticks.util.lang.Casting;
-
-import org.apache.log4j.Logger;
-
-import java.io.InputStream;
-import java.lang.reflect.*;
+import com.framsticks.params.annotations.FramsClassAnnotation;
+import com.framsticks.params.annotations.ParamAnnotation;
+// import com.framsticks.util.FramsticksException;
+
 import java.util.*;
+
+import javax.annotation.Nonnull;
 
 /**
@@ -24,12 +21,6 @@
  * @author Piotr Sniegowski
  */
+@FramsClassAnnotation(id = "class", name = "class")
 public final class FramsClass {
-
-	private final static Logger log = Logger.getLogger(FramsClass.class
-			.getName());
-
-	/**
-	 * The Class which represents group.
-	 */
 
 	/** The offset of the parameter (applied for newly added parameter). */
@@ -62,4 +53,5 @@
 
 	public FramsClass() {
+
 	}
 
@@ -77,4 +69,7 @@
 	 */
 	public FramsClass append(Param param) {
+		// if (param.hasFlag(Flags.USERHIDDEN)) {
+		// 	return this;
+		// }
 		paramEntryMap.put(param.getId(), param);
 		//paramEntryMap.put(param.getInternalId(), param);
@@ -104,4 +99,5 @@
 	}
 
+	@ParamAnnotation(id = "desc")
 	public String getDescription() {
 		return description;
@@ -130,9 +126,9 @@
 
 	/**
-	 * Gets the group getName.
+	 * Gets the group name.
 	 *
 	 * @param gi
 	 *            the offset of group
-	 * @return the group getName
+	 * @return the group name
 	 */
 	public String getGroupName(int gi) {
@@ -142,8 +138,10 @@
 	}
 
+	@ParamAnnotation
 	public String getId() {
 		return id;
 	}
 
+	@ParamAnnotation
 	public String getName() {
 		return name;
@@ -152,4 +150,16 @@
 	public String getNiceName() {
 		return name != null ? name : id;
+	}
+
+	public <T extends Param> T castedParam(@Nonnull final Param param, @Nonnull final Class<T> type, Object name) {
+		if (param == null) {
+			return null;
+			// throw new FramsticksException().msg("param is missing").arg("name", name).arg("in", this);
+		}
+		if (!type.isInstance(param)) {
+			return null;
+			// throw new FramsticksException().msg("wrong type of param").arg("actual", param.getClass()).arg("requested", type).arg("in", this);
+		}
+		return type.cast(param);
 	}
 
@@ -161,9 +171,6 @@
 	 * @return the param entry
 	 */
-	public <T extends Param> T getParamEntry(int i, Class<T> type) {
-		if (i < 0 || i >= paramList.size()) {
-			return null;
-		}
-		return Casting.tryCast(type, paramList.get(i));
+	public <T extends Param> T getParamEntry(final int i, @Nonnull final Class<T> type) {
+		return castedParam(getParam(i), type, i);
 	}
 
@@ -175,6 +182,20 @@
 	 * @return the param entry
 	 */
-	public <T extends Param> T getParamEntry(String id, Class<T> type) {
-		return Casting.tryCast(type, paramEntryMap.get(id));
+	public <T extends Param> T getParamEntry(@Nonnull final String id, @Nonnull final Class<T> type) {
+		return castedParam(getParam(id), type, id);
+	}
+
+	public Param getParam(int i) {
+		if (i < 0 || i >= paramList.size()) {
+			return null;
+		}
+		return paramList.get(i);
+	}
+
+	public Param getParam(String id) {
+		if (!paramEntryMap.containsKey(id)) {
+			return null;
+		}
+		return paramEntryMap.get(id);
 	}
 
@@ -188,143 +209,17 @@
 	}
 
-	public static FramsClass getFramsClass() {
-		return new FramsClass("class", "class", null)
-			.append(Param.build().id("name").name("Name").type(StringParam.class))
-			.append(Param.build().id("id").name("id").type(StringParam.class))
-			.append(Param.build().id("desc").name("Description").type(StringParam.class));
-	}
-
+	@ParamAnnotation
 	public void setId(String id) {
 		this.id = id;
 	}
 
+	@ParamAnnotation
 	public void setName(String name) {
 		this.name = name;
 	}
 
+	@ParamAnnotation(id = "desc")
 	public void setDescription(String description) {
 		this.description = description;
 	}
-
-	public static String getParamTypeForNativeType(Type type) {
-		if (type instanceof ParameterizedType) {
-			ParameterizedType p = (ParameterizedType) type;
-			Type rawType = p.getRawType();
-			if (rawType.equals(Map.class)) {
-				Type containedType = p.getActualTypeArguments()[1];
-				//TODO uid should be passed along during construction
-				if (containedType instanceof Class) {
-					return "l " + ((Class<?>) containedType).getCanonicalName()
-							+ " name";
-				}
-			}
-			if (rawType.equals(List.class)) {
-				Type containedType = p.getActualTypeArguments()[0];
-				if (containedType instanceof Class) {
-					return "l " + ((Class<?>) containedType).getCanonicalName();
-				}
-			}
-			return null;
-		}
-
-		if (type.equals(Integer.class)) {
-			return "d";
-		}
-		if (type.equals(String.class)) {
-			return "s";
-		}
-		if (type.equals(Double.class)) {
-			return "f";
-		}
-		if (type instanceof Class) {
-			return "o " + ((Class<?>) type).getCanonicalName();
-		}
-		return null;
-	}
-
-	public static final String GENERATE_HELP_PREFIX = "automatically generated from: ";
-
-	public static FramsClass readFromStream(InputStream stream) {
-		return Loaders.loadFramsClass(new FileSource(stream));
-	}
-
-	public static class Constructor {
-		protected final FramsClass result;
-		protected Class<?> currentClass;
-
-		public Constructor(Class<?> src, String name) {
-			result = new FramsClass(name, name, GENERATE_HELP_PREFIX
-					+ src.toString());
-			currentClass = src;
-			while (currentClass != null) {
-				try {
-					currentClass.getMethod("constructFramsClass", Constructor.class).invoke(null, this);
-				} catch (IllegalAccessException | IllegalArgumentException
-						| InvocationTargetException | NoSuchMethodException
-						| SecurityException e) {
-					log.debug("failed to use constructFramsClass static method (skipping): ", e);
-				}
-				currentClass = currentClass.getSuperclass();
-			}
-			currentClass = src;
-		}
-
-		public final FramsClass getResult() {
-			return result;
-		}
-
-		public Constructor allFields() {
-			for (Field f : currentClass.getFields()) {
-				field(f.getName());
-			}
-			return this;
-		}
-
-		public Constructor method(String name, Class<?> ... arguments) {
-			try {
-				Method method = currentClass.getMethod(name, arguments);
-				if (!Modifier.isPublic(method.getModifiers())) {
-					return this;
-				}
-				String returnParamClass = getParamTypeForNativeType(method.getGenericReturnType());
-				if (returnParamClass == null) {
-					return this;
-				}
-				Class<?>[] args = method.getParameterTypes();
-				if (args.length == 0) {
-					if (method.getName().startsWith("get")) {
-						String fieldName = method.getName().substring(3, 4).toLowerCase() + method.getName().substring(4);
-						Param param = Param.build().type(returnParamClass).name(fieldName).id(fieldName).help(GENERATE_HELP_PREFIX + method.toString()).finish();
-						assert param != null;
-						result.append(param);
-						return this;
-					}
-					return this;
-				}
-				return this;
-			} catch (NoSuchMethodException e) {
-				log.fatal("method " + name + " was not found in " + currentClass.toString());
-			}
-			return this;
-		}
-		public Constructor field(String name) {
-			try {
-				Field field = currentClass.getField(name);
-				if (!Modifier.isPublic(field.getModifiers())) {
-					return this;
-				}
-				String paramClass = getParamTypeForNativeType(field.getGenericType());
-				if (paramClass == null) {
-					return this;
-				}
-				Param param = Param.build().type(paramClass).name(field.getName()).id(field.getName()).help(GENERATE_HELP_PREFIX + field.toString()).finish();
-				assert param != null;
-				result.append(param);
-				return this;
-			} catch (NoSuchFieldException e) {
-				log.fatal("field " + name + " was not found in " + currentClass.toString());
-			}
-			return this;
-		}
-	}
 }
Index: /java/main/src/main/java/com/framsticks/params/FramsClassBuilder.java
===================================================================
--- /java/main/src/main/java/com/framsticks/params/FramsClassBuilder.java	(revision 86)
+++ /java/main/src/main/java/com/framsticks/params/FramsClassBuilder.java	(revision 86)
@@ -0,0 +1,161 @@
+package com.framsticks.params;
+
+import java.io.InputStream;
+import java.lang.reflect.Field;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.log4j.Logger;
+
+import com.framsticks.params.annotations.FramsClassAnnotation;
+import com.framsticks.params.annotations.ParamAnnotation;
+import com.framsticks.parsers.FileSource;
+import com.framsticks.parsers.Loaders;
+import com.framsticks.util.lang.Strings;
+
+public class FramsClassBuilder {
+	private static final Logger log =
+		Logger.getLogger(FramsClassBuilder.class);
+
+
+	public static String getName(FramsClassAnnotation fca, Class<?> javaClass) {
+		return fca.name().equals("") ? javaClass.getSimpleName() : fca.name();
+	}
+
+	public static String getId(FramsClassAnnotation fca, Class<?> javaClass) {
+		return fca.id().equals("") ? javaClass.getSimpleName() : fca.id();
+	}
+
+	public static String getParamTypeForNativeType(Type type) {
+		if (type instanceof ParameterizedType) {
+			ParameterizedType p = (ParameterizedType) type;
+			Type rawType = p.getRawType();
+			Type containedType = null;
+			//TODO make implementation here
+			boolean map = false;
+			if (rawType.equals(Map.class)) {
+				containedType = p.getActualTypeArguments()[1];
+				map = true;
+			} else if (rawType.equals(List.class)) {
+				containedType = p.getActualTypeArguments()[0];
+			}
+			if (!(containedType instanceof Class)) {
+				return null;
+			}
+			Class<?> containedClass = (Class<?>) containedType;
+			StringBuilder b = new StringBuilder();
+			b.append("l ");
+			FramsClassAnnotation fca = containedClass.getAnnotation(FramsClassAnnotation.class);
+			if (fca == null) {
+				log.error("the class is not annotated: " + containedClass);
+				return null;
+			}
+			b.append(getName(fca, containedClass));
+			if (map) {
+				b.append(" name");
+			}
+
+			return b.toString();
+		}
+
+		if (type.equals(Integer.class) || type.equals(int.class)) {
+			return "d";
+		}
+		if (type.equals(String.class)) {
+			return "s";
+		}
+		if (type.equals(Double.class) || type.equals(double.class)) {
+			return "f";
+		}
+		if (type.equals(Boolean.class) || type.equals(boolean.class)) {
+			return "d 0 1";
+		}
+		if (type.equals(Object.class)) {
+			return "x";
+		}
+		if (type instanceof Class) {
+			return "o " + ((Class<?>) type).getCanonicalName();
+		}
+		return null;
+	}
+
+	public static final String GENERATE_HELP_PREFIX = "automatically generated from: ";
+
+	public static FramsClass readFromStream(InputStream stream) {
+		return Loaders.loadFramsClass(new FileSource(stream));
+	}
+
+	// public static Class<? extends Param> getParamType(@Nonnull Class<?> c) {
+	//	if (c.equals(Integer.class)) {
+	//		return DecimalParam.class;
+	//	}
+	//	if (c.equals(Double.class)) {
+	//		return FloatParam.class;
+	//	}
+	//	if (c.equals(String.class)) {
+	//		return StringParam.class;
+	//	}
+	//	if (c.equals(Object.class)) {
+	//		return UniversalParam.class;
+	//	}
+	//	return null;
+	// }
+
+	public static String extractIdOf(Member member) {
+		if (member instanceof Field) {
+			return member.getName();
+		}
+		if (member instanceof Method) {
+			Method m = (Method) member;
+			String n = m.getName();
+			int argsNum = m.getParameterTypes().length;
+			if (argsNum == 0) {
+				return n.startsWith("get") ? Strings.uncapitalize(n.substring(3)) : n;
+			}
+			if (argsNum == 1) {
+				return n.startsWith("set") ? Strings.uncapitalize(n.substring(3)) : n;
+			}
+			log.error("invalid number of arguments");
+			return null;
+		}
+		log.error("invalid kind of member");
+		return null;
+	}
+	public static String getName(ParamAnnotation annotation, Member member) {
+		return annotation.name().equals("") ? Strings.capitalize(extractIdOf(member)) : annotation.name();
+	}
+
+	public static String getId(ParamAnnotation annotation, Member member) {
+		return annotation.id().equals("") ? extractIdOf(member) : annotation.id();
+	}
+
+	public static ParamBuilder fill(ParamBuilder builder, Member member, ParamAnnotation annotation) {
+		return builder
+			.id(getId(annotation, member))
+			.name(getName(annotation, member));
+
+	}
+
+	public static FramsClass buildForClass(Class<?> javaClass) throws ConstructionException {
+
+		FramsClassAnnotation fca = javaClass.getAnnotation(FramsClassAnnotation.class);
+		if (fca == null) {
+			log.error(javaClass.getName() + " is not annotated with FramsClassAnnotation");
+			return null;
+		}
+
+		FramsClass framsClass = new FramsClass(getId(fca, javaClass), getName(fca, javaClass), "");
+
+		Map<String, ParamCandidate> candidates = ParamCandidate.getAllCandidates(javaClass);
+
+		for (ParamCandidate pc : candidates.values()) {
+			framsClass.append(Param.build().id(pc.getId()).name(pc.getName()).type(getParamTypeForNativeType(pc.getType())).flags(pc.getFlags()));
+		}
+
+		return framsClass;
+	}
+}
Index: /java/main/src/main/java/com/framsticks/params/ListSource.java
===================================================================
--- /java/main/src/main/java/com/framsticks/params/ListSource.java	(revision 85)
+++ /java/main/src/main/java/com/framsticks/params/ListSource.java	(revision 86)
@@ -1,4 +1,5 @@
 package com.framsticks.params;
 
+import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.List;
@@ -7,19 +8,22 @@
 
 	private Iterator<String> iterator = null;
-    //private final List<String> source;
+	//private final List<String> source;
 
 	public ListSource(List<String> source) {
-        //this.source = source;
-        iterator = source.iterator();
+		//this.source = source;
+		iterator = source.iterator();
 	}
 
-    @Override
+	@Override
 	public String getFilename() {
 		return "<net>";
 	}
 
-    @Override
-    public String readLine() {
-        assert iterator != null;
+	@Override
+	public String readLine() {
+		// if (iterator == null) {
+		//	return null;
+		// }
+		assert iterator != null;
 		if (iterator.hasNext()) {
 			return iterator.next();
@@ -28,17 +32,30 @@
 	}
 
-    @Override
-    public String demangleInclude(String include) {
+	@Override
+	public String demangleInclude(String include) {
 		return null;
 	}
 
-    @Override
-    public SourceInterface openInclude(String include) {
+	@Override
+	public SourceInterface openInclude(String include) {
 		return null;
 	}
 
-    @Override
-    public void close() {
-        iterator = null;
+	@Override
+	public void close() {
+		iterator = null;
+	}
+
+	public static ListSource createFrom(String... lines) {
+		List<String> list = new ArrayList<String>();
+		for (String l : lines) {
+			list.add(l);
+		}
+		return new ListSource(list);
+	}
+
+	@Override
+	public boolean isClosed() {
+		return iterator == null;
 	}
 }
Index: /java/main/src/main/java/com/framsticks/params/Param.java
===================================================================
--- /java/main/src/main/java/com/framsticks/params/Param.java	(revision 85)
+++ /java/main/src/main/java/com/framsticks/params/Param.java	(revision 86)
@@ -1,3 +1,4 @@
 package com.framsticks.params;
+
 
 import com.framsticks.params.types.DecimalParam;
Index: /java/main/src/main/java/com/framsticks/params/ParamBuilder.java
===================================================================
--- /java/main/src/main/java/com/framsticks/params/ParamBuilder.java	(revision 85)
+++ /java/main/src/main/java/com/framsticks/params/ParamBuilder.java	(revision 86)
@@ -1,4 +1,6 @@
 package com.framsticks.params;
 
+import com.framsticks.params.annotations.FramsClassAnnotation;
+import com.framsticks.params.annotations.ParamAnnotation;
 import com.framsticks.params.types.*;
 import com.framsticks.util.lang.Numbers;
@@ -8,4 +10,5 @@
 import java.util.ArrayList;
 import java.util.Arrays;
+
 
 /**
@@ -18,4 +21,5 @@
  */
 
+@FramsClassAnnotation(name = "prop", id = "prop")
 public class ParamBuilder {
 	private final static Logger log = Logger.getLogger(ParamBuilder.class.getName());
@@ -28,9 +32,9 @@
 	private static final String FLAGS_FIELD = "flags";
 
-	/** The parameter getId. */
+	/** The parameter id. */
 	private String id;
 
 	/**
-	 * The parameter internal getId. It's set by a user to use user's own getId in
+	 * The parameter internal id. It's set by a user to use user's own id in
 	 * code
 	 */
@@ -40,20 +44,21 @@
 	private Integer group = 0;
 
-	/** The getFlags stored as a bit sum. */
+	/** The flags stored as a bit sum. */
 	private Integer flags = 0;
 
-	/** The parameter getName. */
+	/** The parameter name. */
 	private String name;
 
-	/** The getHelp (description) concerning parameter. */
+	/** The help (description) concerning parameter. */
 	private String help;
 
-	/** The getType of parameter. */
+	/** The type of parameter. */
 	private Class<? extends Param> paramType;
 
 	private Param param;
 	private PrimitiveParam primitiveParam;
-
-	ParamBuilder() {
+	private String typeString;
+
+	public ParamBuilder() {
 	}
 
@@ -76,4 +81,5 @@
 	}
 
+	@ParamAnnotation
 	public ParamBuilder id(String id) {
 		this.id = id;
@@ -87,8 +93,10 @@
 			primitiveParam = (PrimitiveParam) param;
 		}
+		typeString = param.getFramsTypeName();
 		return this;
 	}
 
 	public <T extends Param> ParamBuilder type(Class<T> type) {
+		assert type != null;
 		try {
 			return internalSetType(type, type.newInstance());
@@ -104,4 +112,12 @@
 
 
+	/**
+	 * @return the id
+	 */
+	@ParamAnnotation
+	public String getId() {
+		return id;
+	}
+
 	public ParamBuilder setInternalId(String internalId) {
 		this.internalId = internalId;
@@ -109,4 +125,5 @@
 	}
 
+	@ParamAnnotation
 	public ParamBuilder group(Integer group) {
 		this.group = group;
@@ -114,4 +131,5 @@
 	}
 
+	@ParamAnnotation
 	public ParamBuilder flags(Integer flags) {
 		this.flags = flags;
@@ -119,4 +137,5 @@
 	}
 
+	@ParamAnnotation
 	public ParamBuilder name(String name) {
 		this.name = name;
@@ -143,5 +162,7 @@
 	}
 
+	@ParamAnnotation
 	public ParamBuilder type(String type) {
+		typeString = type;
 
 		log.trace("parsing type: " + type);
@@ -233,7 +254,45 @@
 	}
 
+	@ParamAnnotation
 	public ParamBuilder help(String help) {
 		this.help = help;
 		return this;
+	}
+
+	/**
+	 * @return the group
+	 */
+	@ParamAnnotation
+	public Integer getGroup() {
+		return group;
+	}
+
+	/**
+	 * @return the flags
+	 */
+	@ParamAnnotation
+	public Integer getFlags() {
+		return flags;
+	}
+
+	/**
+	 * @return the name
+	 */
+	@ParamAnnotation
+	public String getName() {
+		return name;
+	}
+
+	/**
+	 * @return the help
+	 */
+	@ParamAnnotation
+	public String getHelp() {
+		return help;
+	}
+
+	@ParamAnnotation
+	public String getType() {
+		return typeString;
 	}
 
@@ -328,13 +387,4 @@
 
 
-	public static FramsClass getFramsClass() {
-		return new FramsClass("prop", "prop", null)
-			.append(Param.build().id("name").name("Name").type(StringParam.class))
-			.append(Param.build().id("id").name("Id").type(StringParam.class))
-			.append(Param.build().id("type").name("Type").type(StringParam.class))
-			.append(Param.build().id("help").name("Help").type(StringParam.class))
-			.append(Param.build().id("group").name("Group").type(DecimalParam.class))
-			.append(Param.build().id("flags").name("Flags").type(DecimalParam.class));
-	}
 
 }
Index: /java/main/src/main/java/com/framsticks/params/ParamCandidate.java
===================================================================
--- /java/main/src/main/java/com/framsticks/params/ParamCandidate.java	(revision 86)
+++ /java/main/src/main/java/com/framsticks/params/ParamCandidate.java	(revision 86)
@@ -0,0 +1,279 @@
+package com.framsticks.params;
+
+import java.lang.reflect.AnnotatedElement;
+import java.lang.reflect.Array;
+import java.lang.reflect.Field;
+import java.lang.reflect.GenericArrayType;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import com.framsticks.params.annotations.ParamAnnotation;
+
+public class ParamCandidate {
+
+	public class OneTime<T> {
+		protected final String name;
+		T value;
+
+		/**
+		 * @param name
+		 */
+		public OneTime(String name) {
+			this.name = name;
+		}
+
+		final void set(T value) {
+			if (this.value == null) {
+				this.value = value;
+				return;
+			}
+			if (!this.value.equals(value)) {
+				throw new ConstructionException().msg("already set")
+					.arg("name", name)
+					.arg("in", ParamCandidate.this)
+					.arg("already", this.value)
+					.arg("now", value);
+			}
+		}
+
+		public final T get() {
+			return value;
+		}
+
+		public final boolean has() {
+			return value != null;
+		}
+
+		@Override
+		public String toString() {
+			return value == null ? "<null>" : value.toString();
+		}
+
+
+	}
+
+	protected final String id;
+	protected final OneTime<String> name = new OneTime<>("name");
+	protected final OneTime<Type> type = new OneTime<>("type");
+	protected final OneTime<Field> field = new OneTime<>("field");
+	protected final OneTime<Method> setter = new OneTime<>("setter");
+	protected final OneTime<Method> getter = new OneTime<>("getter");
+
+	/**
+	 * @param id
+	 */
+	public ParamCandidate(String id) {
+		this.id = id;
+	}
+
+	/**
+	 * @return the id
+	 */
+	public String getId() {
+		return id;
+	}
+
+	/**
+	 * @return the name
+	 */
+	public String getName() {
+		return name.get();
+	}
+
+	/**
+	 * @return the type
+	 */
+	public Type getType() {
+		return type.get();
+	}
+
+	public Class<?> getRawType() {
+		return getRawClass(type.get());
+	}
+
+	void setType(Type type) {
+		this.type.set(type);
+	}
+
+
+	/**
+	 * @return the field
+	 */
+	public Field getField() {
+		return field.get();
+	}
+
+	/**
+	 * @return the setter
+	 */
+	public Method getSetter() {
+		return setter.get();
+	}
+
+	/**
+	 * @return the getter
+	 */
+	public Method getGetter() {
+		return getter.get();
+	}
+
+	void validate() throws ConstructionException {
+		try {
+			if (isPublic(field)) {
+				if (getter.has()) {
+					throw new ConstructionException().msg("getter and public field coexist");
+				}
+				return;
+			}
+			if (field.has()) {
+				if (setter.has()) {
+					throw new ConstructionException().msg("setter and field coexist");
+				}
+			}
+
+			if (getter.get() == null) {
+				throw new ConstructionException().msg("missing getter");
+			}
+		} catch (ConstructionException e) {
+			throw e.arg("in", this);
+		}
+	}
+
+	boolean isFinal() {
+		if (Collection.class.isAssignableFrom(getRawType())) {
+			return false;
+		}
+		if (setter.has()) {
+			return false;
+		}
+		if (field.has()) {
+			return Modifier.isFinal(field.get().getModifiers());
+		}
+		return true;
+	}
+
+	boolean isReadOnly() {
+		if (Collection.class.isAssignableFrom(getRawType())) {
+			return false;
+		}
+		if (isPublic(setter)) {
+			return false;
+		}
+		if (isPublic(field)) {
+			return Modifier.isFinal(field.get().getModifiers());
+		}
+		return true;
+	}
+
+	void add(Member member, String name) {
+		this.name.set(name);
+		if (member instanceof Field) {
+			this.field.set((Field) member);
+			setType(field.get().getGenericType());
+			return;
+		}
+		if (member instanceof Method) {
+			Method m = (Method) member;
+			Type[] ps = m.getGenericParameterTypes();
+			if (ps.length == 0) {
+				getter.set(m);
+				setType(m.getGenericReturnType());
+				return;
+			}
+			if (ps.length == 1) {
+				setter.set(m);
+				setType(ps[0]);
+				return;
+			}
+			throw new ConstructionException().msg("invalid number of arguments").arg("method", m).arg("in", this);
+		}
+		throw new ConstructionException().msg("invalid kind of member").arg("member", member).arg("in", this);
+	}
+
+	public boolean isPrimitive() {
+		return getRawType().isPrimitive();
+	}
+
+	public int getFlags() {
+		int f = 0;
+		if (isReadOnly()) {
+			f |= Flags.READONLY;
+		}
+		return f;
+	}
+
+	@Override
+	public String toString() {
+		return id;
+	}
+
+	public static boolean isPublic(Member member) {
+		return Modifier.isPublic(member.getModifiers());
+	}
+
+	public static boolean isPublic(OneTime<? extends Member> v) {
+		return v.has() ? isPublic(v.get()) : false;
+	}
+
+	public static <M extends Member & AnnotatedElement> void filterParamsCandidates(Map<String, ParamCandidate> params, M[] members) {
+		for (M m : members) {
+			ParamAnnotation pa = m.getAnnotation(ParamAnnotation.class);
+			if (pa == null) {
+				continue;
+			}
+			// if (!isPublic(m)) {
+			// 	throw new ConstructionException().msg("field is not public").arg("field", m);
+			// }
+			String id = FramsClassBuilder.getId(pa, m);
+			ParamCandidate pc = null;
+			if (params.containsKey(id)) {
+				pc = params.get(id);
+			} else {
+				pc = new ParamCandidate(id);
+				params.put(id, pc);
+			}
+			pc.add(m, FramsClassBuilder.getName(pa, m));
+
+		}
+	}
+
+	public static Map<String, ParamCandidate> getAllCandidates(Class<?> javaClass) throws ConstructionException {
+		Map<String, ParamCandidate> candidates = new HashMap<>();
+
+		while (javaClass != null) {
+			filterParamsCandidates(candidates, javaClass.getDeclaredFields());
+			filterParamsCandidates(candidates, javaClass.getDeclaredMethods());
+
+			javaClass = javaClass.getSuperclass();
+		}
+
+		for (ParamCandidate pc : candidates.values()) {
+			pc.validate();
+		}
+
+		return candidates;
+	}
+
+	public static Class<?> getRawClass(final Type type) {
+		if (Class.class.isInstance(type)) {
+			return Class.class.cast(type);
+		}
+		if (ParameterizedType.class.isInstance(type)) {
+			final ParameterizedType parameterizedType = ParameterizedType.class.cast(type);
+			return getRawClass(parameterizedType.getRawType());
+		} else if (GenericArrayType.class.isInstance(type)) {
+			GenericArrayType genericArrayType = GenericArrayType.class.cast(type);
+			Class<?> c = getRawClass(genericArrayType.getGenericComponentType());
+			return Array.newInstance(c, 0).getClass();
+		} else {
+			return null;
+		}
+	}
+
+};
Index: /java/main/src/main/java/com/framsticks/params/ReflectionAccess.java
===================================================================
--- /java/main/src/main/java/com/framsticks/params/ReflectionAccess.java	(revision 85)
+++ /java/main/src/main/java/com/framsticks/params/ReflectionAccess.java	(revision 86)
@@ -3,10 +3,13 @@
 import java.lang.reflect.Field;
 import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Modifier;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.Map;
 
 import org.apache.log4j.Logger;
 
-import com.framsticks.util.lang.Containers;
-
+import com.framsticks.util.FramsticksException;
+
+import static com.framsticks.util.lang.Containers.*;
 
 /**
@@ -19,48 +22,138 @@
  */
 public class ReflectionAccess extends SimpleAbstractAccess {
-	private final static Logger log = Logger.getLogger(ReflectionAccess.class.getName());
+	private final static Logger log = Logger.getLogger(ReflectionAccess.class
+			.getName());
 
 	protected final Class<?> reflectedClass;
 	private Object object;
 
-	public ReflectionAccess(Class<?> reflectedClass, FramsClass framsClass) {
+
+	protected interface ReflectedSetter {
+		public <T> void set(Object object, T value) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException;
+	}
+
+	protected interface ReflectedGetter {
+		public abstract <T> T get(Object object, Class<T> type) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException;
+	}
+
+	protected static class ReflectedValueParam {
+		public ReflectedSetter setter;
+		public ReflectedGetter getter;
+	}
+
+	protected final Map<ValueParam, ReflectedValueParam> reflectedValueParams = new HashMap<>();
+
+	public ReflectionAccess(Class<?> reflectedClass) throws ConstructionException {
+		this(reflectedClass, FramsClassBuilder.buildForClass(reflectedClass));
+	}
+
+	public static boolean typeMatch(Class<?> a, Class<?> b) {
+		assert !b.isPrimitive();
+		if (!a.isPrimitive()) {
+			return a.equals(b);
+		}
+
+		if (a.equals(int.class)) {
+			return b.equals(Integer.class);
+		}
+		if (a.equals(double.class)) {
+			return b.equals(Double.class);
+		}
+		if (a.equals(boolean.class)) {
+			return b.equals(Boolean.class);
+		}
+		assert false;
+		return false;
+	}
+
+	public ReflectionAccess(Class<?> reflectedClass, FramsClass framsClass) throws ConstructionException {
 		this.reflectedClass = reflectedClass;
 		setFramsClass(framsClass);
-	}
-
-	private static String accessorName(boolean get, String id) {
-		return (get ? "get"  : "set") + id.substring(0, 1).toUpperCase() + id.substring(1);
-	}
+
+		Map<String, ParamCandidate> candidates = ParamCandidate.getAllCandidates(reflectedClass);
+
+		try {
+			for (final ValueParam vp : filterInstanceof(framsClass.getParamEntries(), ValueParam.class)) {
+				if (!candidates.containsKey(vp.getId())) {
+					throw new ConstructionException().msg("missing candidate for param").arg("param", vp);
+				}
+				ParamCandidate pc = candidates.get(vp.getId());
+				if (pc.isReadOnly() && !vp.hasFlag(Flags.READONLY)) {
+					throw new ConstructionException().msg("readonly state conflict").arg("param", vp);
+				}
+				if (!typeMatch(pc.getRawType(), vp.getStorageType())) {
+					throw new ConstructionException().msg("types mismatch for param").arg("param", vp).arg("candidate", pc.getType()).arg("storage", vp.getStorageType());
+				}
+
+				ReflectedValueParam rvp = new ReflectedValueParam();
+				reflectedValueParams.put(vp, rvp);
+				final boolean primitive = pc.isPrimitive();
+				if (pc.getField() != null) {
+					final Field f = pc.getField();
+					rvp.getter = new ReflectedGetter() {
+						@Override
+						public <T> T get(Object object, Class<T> type) throws IllegalArgumentException, IllegalAccessException {
+							return type.cast(f.get(object));
+						}
+					};
+					if (!pc.isFinal()) {
+						rvp.setter = new ReflectedSetter() {
+							@Override
+							public <T> void set(Object object, T value) throws IllegalArgumentException, IllegalAccessException {
+								if (value == null && primitive) {
+									throw new FramsticksException().msg("setting null to primitive value");
+								}
+								f.set(object, value);
+							}
+						};
+					}
+				} else {
+					final Method g = pc.getGetter();
+
+					rvp.getter = new ReflectedGetter() {
+						@Override
+						public <T> T get(Object object, Class<T> type) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
+							return type.cast(g.invoke(object));
+						}
+					};
+
+					if (!pc.isFinal()) {
+						final Method s = pc.getSetter();
+						rvp.setter = new ReflectedSetter() {
+							@Override
+							public <T> void set(Object object, T value) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
+								if (value == null && primitive) {
+									throw new FramsticksException().msg("setting null to primitive value");
+								}
+								s.invoke(object, value);
+							}
+						};
+					}
+				}
+			}
+		} catch (ConstructionException e) {
+			throw e.arg("java class", reflectedClass).arg("framsClass", framsClass);
+		}
+	}
+
+	// private static String accessorName(boolean get, String id) {
+	//	return (get ? "get" : "set") + id.substring(0, 1).toUpperCase() + id.substring(1);
+	// }
 
 	@Override
 	public <T> T get(ValueParam param, Class<T> type) {
-		if (object == null) {
-			return null;
-		}
-		try {
-			//TODO: use internal id, if present
-			String id = param.getId();
+		try {
 			try {
-				return type.cast(reflectedClass.getField(id).get(object));
-			} catch (NoSuchFieldException ignored) {
-			}
-			try {
-				return type.cast(reflectedClass.getMethod(accessorName(true, id)).invoke(object));
-			} catch (NoSuchMethodException | InvocationTargetException ex) {
-				//e.printStackTrace();
-			}
-			try {
-				return type.cast(reflectedClass.getMethod(id).invoke(object));
-			} catch (NoSuchMethodException | InvocationTargetException ex) {
-				//e.printStackTrace();
-			}
-
-		} catch (IllegalAccessException e) {
-			log.warn("illegal access error occurred while trying to access returnedObject");
-			e.printStackTrace();
-		} catch (ClassCastException ignored) {
-
-		}
-		return null;
+				if (object == null) {
+					throw new FramsticksException().msg("no object set");
+				}
+
+				return reflectedValueParams.get(param).getter.get(object, type);
+			} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
+				throw new FramsticksException().msg("failed to get").cause(e);
+			}
+		} catch (FramsticksException e) {
+			throw e.arg("param", param).arg("type", type).arg("access", this);
+		}
 	}
 
@@ -71,31 +164,19 @@
 
 	private <T> void setValue(ValueParam param, T value) {
-		if (object == null) {
-			return;
-		}
-		try {
-			String id = param.getId();
+		try {
 			try {
-				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 {
-				reflectedClass.getMethod(accessorName(false, id), new Class[]{param.getStorageType()}).invoke(object, value);
-			} catch (InvocationTargetException | NoSuchMethodException ignored) {
-			}
-			try {
-				reflectedClass.getMethod(id, new Class[]{param.getStorageType()}).invoke(object, value);
-			} catch (InvocationTargetException | NoSuchMethodException ignored) {
-			}
-		} catch (Exception ex) {
-			ex.printStackTrace();
+				if (object == null) {
+					throw new FramsticksException().msg("no object set");
+				}
+				ReflectedSetter s = reflectedValueParams.get(param).setter;
+				if (s == null) {
+					throw new FramsticksException().msg("trying to set final");
+				}
+				s.set(object, value);
+			} catch (IllegalArgumentException | IllegalAccessException | InvocationTargetException e) {
+				throw new FramsticksException().msg("failed to set").cause(e);
+			}
+		} catch (FramsticksException e) {
+			throw e.arg("param", param).arg("value", value).arg("access", this);
 		}
 	}
@@ -114,5 +195,5 @@
 
 		try {
-			for (ValueParam p : Containers.filterInstanceof(framsClass.getParamEntries(), ValueParam.class)) {
+			for (ValueParam p : filterInstanceof(framsClass.getParamEntries(), ValueParam.class)) {
 				setValue(p, p.getDef(Object.class));
 			}
@@ -159,5 +240,5 @@
 
 	@Override
-	public ReflectionAccess cloneAccess() {
+	public ReflectionAccess cloneAccess() throws ConstructionException {
 		return new ReflectionAccess(reflectedClass, framsClass);
 	}
@@ -173,3 +254,15 @@
 		return null;
 	}
+
+	@Override
+	public String toString() {
+		StringBuilder b = new StringBuilder();
+		b.append(framsClass);
+		if (object != null) {
+			b.append("(").append(object).append(")");
+		}
+		return b.toString();
+	}
+
 }
+
Index: /java/main/src/main/java/com/framsticks/params/Registry.java
===================================================================
--- /java/main/src/main/java/com/framsticks/params/Registry.java	(revision 85)
+++ /java/main/src/main/java/com/framsticks/params/Registry.java	(revision 86)
@@ -2,4 +2,6 @@
 
 import org.apache.log4j.Logger;
+
+import com.framsticks.params.annotations.FramsClassAnnotation;
 
 import java.util.HashMap;
@@ -35,5 +37,17 @@
 	}
 
-	public AccessInterface createAccess(String name, FramsClass framsClass) {
+	public Registry register(Class<?> reflectedClass) {
+		FramsClassAnnotation a = reflectedClass.getAnnotation(FramsClassAnnotation.class);
+		if (a == null) {
+			log.error("class is not annotated: " + reflectedClass);
+			return this;
+		}
+
+		registerReflectedClass(FramsClassBuilder.getName(a, reflectedClass), FramsClassBuilder.getId(a, reflectedClass), reflectedClass);
+
+		return this;
+	}
+
+	public AccessInterface createAccess(String name, FramsClass framsClass) throws ConstructionException {
 		if (reflectedClasses.containsKey(name)) {
 			return new ReflectionAccess(reflectedClasses.get(name), framsClass);
@@ -66,15 +80,15 @@
 
 	public static AccessInterface wrapAccessWithListIfNeeded(CompositeParam param, AccessInterface access) {
-        if (access == null) {
+		if (access == null) {
 			return null;
 		}
-        return param.prepareAccessInterface(access);
+		return param.prepareAccessInterface(access);
 	}
 
-    public AccessInterface prepareAccess(CompositeParam param) {
-        return wrapAccessWithListIfNeeded(param, createAccess(param.getContainedTypeName()));
-    }
+	public AccessInterface prepareAccess(CompositeParam param) throws ConstructionException {
+		return wrapAccessWithListIfNeeded(param, createAccess(param.getContainedTypeName()));
+	}
 
-	public AccessInterface createAccess(String name) {
+	public AccessInterface createAccess(String name) throws ConstructionException {
 		if (name == null) {
 			return null;
Index: /java/main/src/main/java/com/framsticks/params/SimpleAbstractAccess.java
===================================================================
--- /java/main/src/main/java/com/framsticks/params/SimpleAbstractAccess.java	(revision 85)
+++ /java/main/src/main/java/com/framsticks/params/SimpleAbstractAccess.java	(revision 86)
@@ -65,10 +65,10 @@
 	@Override
 	public Param getParam(int i) {
-		return framsClass.getParamEntry(i, Param.class);
+		return framsClass.getParam(i);
 	}
 
 	@Override
 	public Param getParam(String id) {
-		return framsClass.getParamEntry(id, Param.class);
+		return framsClass.getParam(id);
 	}
 
@@ -80,28 +80,20 @@
 	@Override
 	public <T> T get(int i, Class<T> type) {
-		Param p = getParam(i);
-		assert p instanceof ValueParam;
-		return get((ValueParam) p, type);
+		return get(framsClass.getParamEntry(i, ValueParam.class), type);
 	}
 
 	@Override
 	public <T> T get(String id, Class<T> type) {
-		Param p = getParam(id);
-		assert p instanceof ValueParam;
-		return get((ValueParam) p, type);
+		return get(framsClass.getParamEntry(id, ValueParam.class), type);
+	}
+
+	@Override
+	public <T> int set(int i, T value) {
+		return set(framsClass.getParamEntry(i, ValueParam.class), value);
 	}
 
 	@Override
 	public <T> int set(String id, T value) {
-		Param p = getParam(id);
-		assert p instanceof ValueParam;
-		return set((ValueParam) p, value);
-	}
-
-	@Override
-	public <T> int set(int i, T value) {
-		Param p = getParam(i);
-		assert p instanceof ValueParam;
-		return set((ValueParam) p, value);
+		return set(framsClass.getParamEntry(id, ValueParam.class), value);
 	}
 
@@ -115,5 +107,5 @@
 			ReassignResult<?> result = param.reassign(value, oldValue);
 			Object casted = result.getValue();
-			if (casted != oldValue) {
+			if (!casted.equals(oldValue)) {
 				internalSet(param, casted);
 			}
Index: /java/main/src/main/java/com/framsticks/params/SimpleSource.java
===================================================================
--- /java/main/src/main/java/com/framsticks/params/SimpleSource.java	(revision 85)
+++ /java/main/src/main/java/com/framsticks/params/SimpleSource.java	(revision 86)
@@ -6,10 +6,10 @@
 public class SimpleSource implements SourceInterface {
 
-	final String content;
+	String content;
 	int cursor;
 
 	public SimpleSource(String content) {
 		this.content = content;
-        cursor = 0;
+		cursor = 0;
 	}
 
@@ -21,4 +21,5 @@
 	@Override
 	public String readLine() {
+		assert !isClosed();
 		if (cursor >= content.length()) {
 			return null;
@@ -45,5 +46,12 @@
 	@Override
 	public void close() {
+		content = null;
+	}
 
+	//TODO no magic numbers
+	@Override
+	public boolean isClosed() {
+		return content != null;
 	}
+
 }
Index: /java/main/src/main/java/com/framsticks/params/SourceInterface.java
===================================================================
--- /java/main/src/main/java/com/framsticks/params/SourceInterface.java	(revision 85)
+++ /java/main/src/main/java/com/framsticks/params/SourceInterface.java	(revision 86)
@@ -7,3 +7,4 @@
 	SourceInterface openInclude(String include);
 	void close();
+	boolean isClosed();
 }
Index: /java/main/src/main/java/com/framsticks/params/Util.java
===================================================================
--- /java/main/src/main/java/com/framsticks/params/Util.java	(revision 85)
+++ /java/main/src/main/java/com/framsticks/params/Util.java	(revision 86)
@@ -3,4 +3,5 @@
 import java.util.ArrayList;
 import java.util.List;
+
 
 import static com.framsticks.util.lang.Containers.filterInstanceof;
@@ -44,3 +45,4 @@
 		return copied;
 	}
+
 }
Index: /java/main/src/main/java/com/framsticks/params/annotations/FramsClassAnnotation.java
===================================================================
--- /java/main/src/main/java/com/framsticks/params/annotations/FramsClassAnnotation.java	(revision 86)
+++ /java/main/src/main/java/com/framsticks/params/annotations/FramsClassAnnotation.java	(revision 86)
@@ -0,0 +1,13 @@
+package com.framsticks.params.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.TYPE)
+public @interface FramsClassAnnotation {
+	String name() default "";
+	String id() default "";
+}
Index: /java/main/src/main/java/com/framsticks/params/annotations/ParamAnnotation.java
===================================================================
--- /java/main/src/main/java/com/framsticks/params/annotations/ParamAnnotation.java	(revision 86)
+++ /java/main/src/main/java/com/framsticks/params/annotations/ParamAnnotation.java	(revision 86)
@@ -0,0 +1,14 @@
+package com.framsticks.params.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Retention(RetentionPolicy.RUNTIME)
+@Target({ElementType.FIELD, ElementType.METHOD})
+public @interface ParamAnnotation {
+	String name() default "";
+	String id() default "";
+}
+
Index: /java/main/src/main/java/com/framsticks/parsers/F0Parser.java
===================================================================
--- /java/main/src/main/java/com/framsticks/parsers/F0Parser.java	(revision 85)
+++ /java/main/src/main/java/com/framsticks/parsers/F0Parser.java	(revision 86)
@@ -17,5 +17,4 @@
 import com.framsticks.params.PrimitiveParam;
 import com.framsticks.util.lang.Containers;
-import com.framsticks.util.lang.Exceptions;
 import com.framsticks.util.lang.Pair;
 import com.framsticks.util.lang.Strings;
@@ -119,5 +118,5 @@
 
 	private static void warn(int lineNumber, String message, Exception e) {
-		log.warn("in line " + lineNumber + " the following error occurred (" + message + "): " + e + "\n" + Exceptions.printStackTrace(e));
+		log.warn("in line " + lineNumber + " the following error occurred (" + message + "): " + e);
 	}
 
Index: /java/main/src/main/java/com/framsticks/parsers/FileSource.java
===================================================================
--- /java/main/src/main/java/com/framsticks/parsers/FileSource.java	(revision 85)
+++ /java/main/src/main/java/com/framsticks/parsers/FileSource.java	(revision 86)
@@ -9,8 +9,8 @@
 public class FileSource implements SourceInterface {
 
-	private final BufferedReader reader;
+	private BufferedReader reader;
 	private final String filename;
 
-	protected FileSource(InputStream stream, String filename) {
+	public FileSource(InputStream stream, String filename) {
 		this.filename = filename;
 		this.reader = new BufferedReader(new InputStreamReader(stream, Encoding.getFramsticksCharset()));
@@ -28,4 +28,5 @@
 	public String readLine()
 	{
+		assert !isClosed();
 		try
 		{
@@ -80,4 +81,10 @@
 
 		}
+		reader = null;
+	}
+
+	@Override
+	public boolean isClosed() {
+		return reader == null;
 	}
 
Index: /java/main/src/main/java/com/framsticks/parsers/Loaders.java
===================================================================
--- /java/main/src/main/java/com/framsticks/parsers/Loaders.java	(revision 85)
+++ /java/main/src/main/java/com/framsticks/parsers/Loaders.java	(revision 86)
@@ -2,5 +2,5 @@
 
 import com.framsticks.params.*;
-import org.apache.log4j.Logger;
+// import org.apache.log4j.Logger;
 
 /**
@@ -9,7 +9,7 @@
 public class Loaders {
 
-	private static final Logger log = Logger.getLogger(Loaders.class.getName());
+	// private static final Logger log = Logger.getLogger(Loaders.class.getName());
 
-	public static FramsClass loadFramsClass(SourceInterface source) {
+	public static FramsClass loadFramsClass(SourceInterface source) throws ConstructionException {
 		MultiParamLoader loader = new MultiParamLoader();
 		loader.setNewSource(source);
@@ -17,6 +17,6 @@
 		FramsClass result = new FramsClass();
 
-		AccessInterface framsClassAccess = new ReflectionAccess(FramsClass.class, FramsClass.getFramsClass());
-		AccessInterface paramBuilderAccess = new ReflectionAccess(ParamBuilder.class, ParamBuilder.getFramsClass());
+		AccessInterface framsClassAccess = new ReflectionAccess(FramsClass.class, FramsClassBuilder.buildForClass(FramsClass.class));
+		AccessInterface paramBuilderAccess = new ReflectionAccess(ParamBuilder.class, FramsClassBuilder.buildForClass(ParamBuilder.class));
 		framsClassAccess.select(result);
 		loader.addAccessInterface(framsClassAccess);
@@ -41,10 +41,6 @@
 			return result;
 		} catch (Exception e) {
-			log.error("an error occurred while loading class description: " + e + " before " + source.readLine());
-			e.printStackTrace();
+			throw new ConstructionException().msg("an error occurred while loading class description").arg("before", loader.getCurrentLine()).cause(e);
 		}
-		return null;
-
-
 	}
 }
Index: /java/main/src/main/java/com/framsticks/parsers/MultiParamLoader.java
===================================================================
--- /java/main/src/main/java/com/framsticks/parsers/MultiParamLoader.java	(revision 85)
+++ /java/main/src/main/java/com/framsticks/parsers/MultiParamLoader.java	(revision 86)
@@ -9,6 +9,5 @@
 
 public class MultiParamLoader {
-	private final static Logger logger = Logger
-			.getLogger(MultiParamLoader.class.getName());
+	private final static Logger log = Logger.getLogger(MultiParamLoader.class);
 
 	/**
@@ -56,5 +55,10 @@
 	 * Status of current execution.
 	 */
-	private Status status;
+	private Status status = Status.None;
+
+	private void setStatus(Status status) {
+		log.trace("changing status: " + this.status.toString() + " -> " + status.toString());
+		this.status = status;
+	}
 
 	/**
@@ -62,4 +66,6 @@
 	 */
 	private SourceInterface currentSource;
+
+	protected String currentLine;
 
 
@@ -86,4 +92,11 @@
 	private String lastUnknownObjectName;
 
+	/**
+	 * @return the currentLine
+	 */
+	public String getCurrentLine() {
+		return currentLine;
+	}
+
 	public MultiParamLoader() {
 
@@ -94,5 +107,5 @@
 	 */
 	public Status go() throws Exception {
-		logger.trace("go");
+		log.trace("go");
 
 		while (!isFinished()) {
@@ -106,8 +119,8 @@
 
 			// read data
-			String line = currentSource.readLine();
+			currentLine = currentSource.readLine();
 
 			// end of file
-			if (line == null) {
+			if (currentLine == null) {
 				if (!returnFromIncluded()) {
 					finish();
@@ -117,24 +130,30 @@
 				}
 			}
+			log.trace("read line: " + currentLine);
 
 			// empty line
-			if (line.length() == 0) {
+			if (currentLine.length() == 0) {
 				continue;
 			}
 
 			// check if some file should be included
-			if (isIncludeLine(line) == LoopAction.Continue) {
+			if (isIncludeLine(currentLine) == LoopAction.Continue) {
 				continue;
 			}
 
 			// check if should break on comment
-			if (isCommentLine(line) == LoopAction.Break) {
+			if (isCommentLine(currentLine) == LoopAction.Break) {
 				break;
 			}
 
 			// get class getName
-			if (changeCurrentParamInterface(line) == LoopAction.Break) {
+			LoopAction action = changeCurrentParamInterface(currentLine);
+			if (action == LoopAction.Break) {
 				break;
 			}
+			if (action == LoopAction.Continue) {
+				continue;
+			}
+			log.warn("unknown line: " + currentLine);
 		}
 
@@ -145,4 +164,5 @@
 	 * Checks whether the reader found a known or unknown object and execution
 	 * should be passed to it.
+	 * @throws Exception
 	 */
 	private LoopAction tryReadObject() throws Exception {
@@ -150,7 +170,8 @@
 				|| (status == Status.BeforeUnknown && lastAccessInterface != null)) {
 			// found object - let it load data
-            if (lastAccessInterface.getSelected() == null) {
-                lastAccessInterface.select(lastAccessInterface.createAccessee());
-            }
+			if (lastAccessInterface.getSelected() == null) {
+				lastAccessInterface.select(lastAccessInterface.createAccessee());
+			}
+			log.trace("loading into " + lastAccessInterface);
 			lastAccessInterface.load(currentSource);
 
@@ -162,9 +183,9 @@
 			return LoopAction.Continue;
 		} else if (status == Status.BeforeUnknown) {
-			logger.info("Omitting unknown object: " + lastUnknownObjectName);
+			log.warn("omitting unknown object: " + lastUnknownObjectName);
 
 			// found unknown object
 			emptyParam.load(currentSource);
-			status = Status.AfterObject;
+			setStatus(Status.AfterObject);
 
 			return LoopAction.Continue;
@@ -185,5 +206,5 @@
 					int beg = line.indexOf('\"');
 					if (beg == -1) {
-						logger.info("Wanted to include some file, but the format is incorrect");
+						log.info("Wanted to include some file, but the format is incorrect");
 						return LoopAction.Continue;
 					}
@@ -192,5 +213,5 @@
 					int end = includeFileName.indexOf('\"');
 					if (end == -1) {
-						logger.info("Wanted to include some file, but the format is incorrect");
+						log.info("Wanted to include some file, but the format is incorrect");
 						return LoopAction.Continue;
 					}
@@ -235,12 +256,16 @@
 			if (lastAccessInterface != null) {
 				if (isBreakCondition(Status.BeforeObject)) {
-					logger.info("Breaking before object");
+					log.debug("breaking before object");
 					return LoopAction.Break;
+				} else {
+					return LoopAction.Continue;
 				}
 			} else {
 				lastUnknownObjectName = typeName;
 				if (isBreakCondition(Status.BeforeUnknown)) {
-					logger.info("Breaking before unknown");
+					log.debug("breaking before unknown");
 					return LoopAction.Break;
+				} else {
+					return LoopAction.Continue;
 				}
 			}
@@ -279,9 +304,10 @@
 
 	private void finish() {
+		log.trace("finishing");
 		if (currentSource != null) {
 			currentSource.close();
 		}
 
-		status = Status.Finished;
+		setStatus(Status.Finished);
 	}
 
@@ -291,8 +317,8 @@
 
 	public boolean setNewSource(SourceInterface source) {
-		logger.debug("switching current source to " + source.getFilename() + "...");
+		log.debug("switching current source to " + source.getFilename() + "...");
 
 		currentSource = source;
-		status = Status.Loading;
+		setStatus(Status.Loading);
 
 		return true;
@@ -311,10 +337,10 @@
 		// check if it is already included and break if it is
 		if (isAlreadyIncluded(includeFilename)) {
-			logger.debug("circular reference ignored (" + includeFilename
+			log.debug("circular reference ignored (" + includeFilename
 					+ ")");
 			return;
 		}
 
-		logger.info("including file " + includeFilename + "...");
+		log.info("including file " + includeFilename + "...");
 
 		SourceInterface newSource = currentSource.openInclude(includeFilename);
@@ -335,5 +361,5 @@
 		for (String file : fileStack) {
 			if (filename.equals(file)) {
-				logger.warn("file " + filename + " was already included");
+				log.warn("file " + filename + " was already included");
 				return true;
 			}
@@ -366,14 +392,15 @@
 	 */
 	private boolean isBreakCondition(Status condition) {
-		status = condition;
+		setStatus(condition);
 		return breakConditions.contains(condition);
 	}
 
 	public Object returnObject() {
+		assert lastAccessInterface != null;
 		Object result = lastAccessInterface.getSelected();
 		if (result == null) {
 			return null;
 		}
-        lastAccessInterface.select(null);
+		lastAccessInterface.select(null);
 		return result;
 	}
Index: /java/main/src/main/java/com/framsticks/parsers/Savers.java
===================================================================
--- /java/main/src/main/java/com/framsticks/parsers/Savers.java	(revision 85)
+++ /java/main/src/main/java/com/framsticks/parsers/Savers.java	(revision 86)
@@ -10,6 +10,6 @@
 	public static void saveFramsClass(SinkInterface sink, FramsClass framsClass) {
 
-		AccessInterface framsClassAccess = new ReflectionAccess(FramsClass.class, FramsClass.getFramsClass());
-		AccessInterface paramAccess = new ReflectionAccess(Param.class, Param.getFramsClass());
+		AccessInterface framsClassAccess = new ReflectionAccess(FramsClass.class);
+		AccessInterface paramAccess = new ReflectionAccess(Param.class);
 		framsClassAccess.select(framsClass);
 		framsClassAccess.save(sink);
Index: /java/main/src/main/java/com/framsticks/portals/Portal.java
===================================================================
--- /java/main/src/main/java/com/framsticks/portals/Portal.java	(revision 85)
+++ /java/main/src/main/java/com/framsticks/portals/Portal.java	(revision 86)
@@ -2,5 +2,6 @@
 
 import com.framsticks.observers.Observer;
-import com.framsticks.params.FramsClass;
+import com.framsticks.params.annotations.FramsClassAnnotation;
+import com.framsticks.params.annotations.ParamAnnotation;
 import com.framsticks.util.PeriodicTask;
 import org.apache.log4j.Logger;
@@ -10,8 +11,10 @@
  * @author Piotr Sniegowski
  */
+@FramsClassAnnotation
 public class Portal extends Observer {
 
 	private final static Logger log = Logger.getLogger(Portal.class.getName());
 
+	@ParamAnnotation
 	public Integer counter = 0;
 
@@ -38,10 +41,8 @@
 	}
 
+	@ParamAnnotation(id = "counter_squared", name = "Counter Squared")
 	public Double getCounterSquared() {
 		return (double)(counter * counter);
 	}
 
-	public static void constructFramsClass(FramsClass.Constructor constructor) {
-		constructor.method("getCounterSquared").field("counter");
-	}
 }
Index: /java/main/src/main/java/com/framsticks/util/FramsticksException.java
===================================================================
--- /java/main/src/main/java/com/framsticks/util/FramsticksException.java	(revision 86)
+++ /java/main/src/main/java/com/framsticks/util/FramsticksException.java	(revision 86)
@@ -0,0 +1,54 @@
+package com.framsticks.util;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import com.framsticks.util.lang.Delimeted;
+import com.framsticks.util.lang.Pair;
+
+@SuppressWarnings("serial")
+public class FramsticksException extends RuntimeException {
+
+	protected List<Pair<String, Object>> arguments;
+	protected String message;
+
+	public FramsticksException() {
+		super("framsticks exception");
+	}
+
+	public FramsticksException msg(String message) {
+		this.message = message;
+		return this;
+	}
+
+	public FramsticksException cause(Throwable cause) {
+		initCause(cause);
+		return this;
+	}
+
+	public FramsticksException arg(String header, Object argument) {
+		if (arguments == null) {
+			arguments = new ArrayList<>();
+		}
+		arguments.add(new Pair<String, Object>(header, argument));
+		return this;
+	}
+
+	public String getMessage() {
+		StringBuilder b = new StringBuilder();
+		if (message != null) {
+			b.append(message);
+		}
+		if (arguments != null) {
+			if (message != null) {
+				b.append(" ");
+			}
+			Delimeted d = new Delimeted(", ", "");
+			d.append(arguments.iterator());
+
+			b.append("(").append(d.build()).append(")");
+		}
+		return b.toString();
+	}
+
+}
Index: /java/main/src/main/java/com/framsticks/util/lang/Containers.java
===================================================================
--- /java/main/src/main/java/com/framsticks/util/lang/Containers.java	(revision 85)
+++ /java/main/src/main/java/com/framsticks/util/lang/Containers.java	(revision 86)
@@ -4,5 +4,7 @@
 import java.util.Iterator;
 import java.util.List;
+
 import org.apache.commons.collections.functors.InstanceofPredicate;
+import org.apache.commons.collections.functors.NotPredicate;
 import org.apache.commons.collections.iterators.FilterIterator;
 
@@ -20,22 +22,18 @@
 	}
 
-	@SuppressWarnings("unchecked")
 	public static <T> Iterable<T> filterInstanceof(Iterator<? super T> i, Class<T> type) {
 		return new IterableIterator<T>(new FilterIterator(i, new InstanceofPredicate(type)));
 	}
 
-	@SuppressWarnings("unchecked")
 	public static <T> Iterable<T> filterInstanceof(Iterable<? super T> i, Class<T> type) {
 		return new IterableIterator<T>(new FilterIterator(i.iterator(), new InstanceofPredicate(type)));
 	}
 
-	@SuppressWarnings("unchecked")
 	public static <T> Iterable<T> filterInstanceof(Collection<? super T> c, Class<T> type) {
 		return new IterableIterator<T>(new FilterIterator(c.iterator(), new InstanceofPredicate(type)));
 	}
 
-	// @SuppressWarnings("unchecked")
-	// public static <T> Iterable<T> filterNotInstanceof(Collection<T> c, Class<? extends T> type) {
-	// 	return new IterableIterator<T>(new FilterIterator(c.iterator(), new NotPredicate(new InstanceofPredicate(type))));
-	// }
+	public static <T> Iterable<T> filterNotInstanceof(Collection<T> c, Class<? extends T> type) {
+		return new IterableIterator<T>(new FilterIterator(c.iterator(), new NotPredicate(new InstanceofPredicate(type))));
+	}
 }
Index: /java/main/src/main/java/com/framsticks/util/lang/Delimeted.java
===================================================================
--- /java/main/src/main/java/com/framsticks/util/lang/Delimeted.java	(revision 85)
+++ /java/main/src/main/java/com/framsticks/util/lang/Delimeted.java	(revision 86)
@@ -1,3 +1,5 @@
 package com.framsticks.util.lang;
+
+import java.util.Iterator;
 
 import org.apache.commons.collections.Closure;
@@ -27,4 +29,11 @@
 	}
 
+	public final Delimeted append(Iterator<?> i) {
+		while (i.hasNext()) {
+			append(i.next());
+		}
+		return this;
+	}
+
 	public final String build() {
 		return (builder != null ? builder.toString() : empty);
Index: /java/main/src/main/java/com/framsticks/util/lang/IterableIterator.java
===================================================================
--- /java/main/src/main/java/com/framsticks/util/lang/IterableIterator.java	(revision 85)
+++ /java/main/src/main/java/com/framsticks/util/lang/IterableIterator.java	(revision 86)
@@ -30,6 +30,7 @@
 	// }
 
+
 	@SuppressWarnings("unchecked")
-	public IterableIterator(Iterator<? extends T> i) {
+	public IterableIterator(Iterator<?> i) {
 		this.i = (Iterator<T>) i;
 	}
Index: /java/main/src/main/java/com/framsticks/util/lang/Pair.java
===================================================================
--- /java/main/src/main/java/com/framsticks/util/lang/Pair.java	(revision 85)
+++ /java/main/src/main/java/com/framsticks/util/lang/Pair.java	(revision 86)
@@ -15,5 +15,5 @@
 	@Override
 	public String toString() {
-		return Strings.toStringNullProof(first) + " " + Strings.toStringNullProof(second);
+		return Strings.toStringNullProof(first) + " : " + Strings.toStringNullProof(second);
 	}
 
Index: /java/main/src/main/java/com/framsticks/util/lang/Strings.java
===================================================================
--- /java/main/src/main/java/com/framsticks/util/lang/Strings.java	(revision 85)
+++ /java/main/src/main/java/com/framsticks/util/lang/Strings.java	(revision 86)
@@ -42,3 +42,11 @@
 		}
 	}
+
+	public static String capitalize(String input) {
+		return input.substring(0, 1).toUpperCase() + input.substring(1);
+	}
+
+	public static String uncapitalize(String input) {
+		return input.substring(0, 1).toLowerCase() + input.substring(1);
+	}
 }
Index: /java/main/src/test/java/com/framsticks/model/CreatureTest.java
===================================================================
--- /java/main/src/test/java/com/framsticks/model/CreatureTest.java	(revision 86)
+++ /java/main/src/test/java/com/framsticks/model/CreatureTest.java	(revision 86)
@@ -0,0 +1,54 @@
+package com.framsticks.model;
+
+import org.testng.annotations.Test;
+
+import com.framsticks.params.FramsClass;
+import com.framsticks.params.FramsClassBuilder;
+import com.framsticks.params.ReflectionAccess;
+import com.framsticks.params.types.ArrayListParam;
+import com.framsticks.params.types.DecimalParam;
+import com.framsticks.params.types.StringParam;
+import com.framsticks.test.TestConfiguration;
+
+import static org.fest.assertions.Assertions.*;
+
+@Test
+public class CreatureTest extends TestConfiguration {
+
+	FramsClass framsClass;
+	ArrayListParam partsParam;
+	ReflectionAccess access;
+	Creature creature;
+
+	@Test
+	public void testFramsClass() {
+		framsClass = FramsClassBuilder.buildForClass(Creature.class);
+
+		assertThat(framsClass).describedAs("framsClass").isNotNull();
+		assertThat(framsClass.getParam("name")).describedAs("name").isInstanceOf(StringParam.class);
+		assertThat(framsClass.getParam("parts")).describedAs("parts").isInstanceOf(ArrayListParam.class);
+		partsParam = framsClass.getParamEntry("parts", ArrayListParam.class);
+		assertThat(partsParam).describedAs("partsParam").isNotNull();
+		assertThat(partsParam).isInstanceOf(ArrayListParam.class);
+		assertThat(partsParam.getContainedTypeName()).isEqualTo("Part");
+		assertThat(framsClass.getParam("gnum")).isInstanceOf(DecimalParam.class);
+	}
+
+	@Test
+	public void testReflectionAccess() throws IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException {
+		access = new ReflectionAccess(Creature.class, framsClass);
+		Object object = access.createAccessee();
+		assertThat(object).isInstanceOf(Creature.class);
+		access.select(object);
+
+		creature = (Creature) object;
+		access.set("gnum", new Integer(1));
+		// Creature.class.getField("generation").set(creature, 1);
+		assertThat(creature.generation).isEqualTo(1);
+
+
+	}
+
+
+
+}
Index: /java/main/src/test/java/com/framsticks/model/PackageTest.java
===================================================================
--- /java/main/src/test/java/com/framsticks/model/PackageTest.java	(revision 86)
+++ /java/main/src/test/java/com/framsticks/model/PackageTest.java	(revision 86)
@@ -0,0 +1,54 @@
+package com.framsticks.model;
+
+import java.io.InputStream;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+import com.framsticks.params.FramsClass;
+import com.framsticks.params.ReflectionAccess;
+import com.framsticks.params.SourceInterface;
+import com.framsticks.parsers.FileSource;
+import com.framsticks.parsers.Loaders;
+import com.framsticks.test.TestConfiguration;
+
+import static org.fest.assertions.Assertions.*;
+
+@Test
+public class PackageTest extends TestConfiguration {
+
+	@Test(dataProvider = "classesList")
+	public void testFramsClass(Class<?> javaClass, String name, int paramCount) throws InstantiationException, IllegalAccessException {
+		// log.info("testing " + name + " " + javaClass + " " + Package.class.getResource(filename));
+		String filename = "/info/" + name + ".info";
+		InputStream stream = Package.class.getResourceAsStream(filename);
+		assertThat(stream).describedAs("stream " + filename).isNotNull();
+
+		SourceInterface source = new FileSource(stream, filename);
+
+		assertThat(source.isClosed()).isFalse();
+		FramsClass framsClass = Loaders.loadFramsClass(source);
+		assertThat(framsClass).isNotNull();
+
+		assertThat(framsClass.getParamCount()).isEqualTo(paramCount);
+		ReflectionAccess access = new ReflectionAccess(javaClass, framsClass);
+		Object object = javaClass.newInstance();
+		access.select(object);
+	}
+
+	@DataProvider
+	public Object[][] classesList() {
+		return new Object[][] {
+			{ MechPart.class, "MechPart", 20 },
+			{ Joint.class, "Joint", 16 },
+			{ MechJoint.class, "MechJoint", 10 },
+			{ Neuro.class, "Neuro", 21},
+			{ NeuroDef.class, "NeuroDef", 9},
+			{ Part.class, "Part", 18},
+			// { Model.class, "Model" },
+			{ Creature.class, "Creature", 64 },
+			{ Genotype.class, "Genotype", 37 },
+			{ World.class, "World", 10 }
+		};
+	}
+}
Index: /java/main/src/test/java/com/framsticks/params/ParamBuilderTest.java
===================================================================
--- /java/main/src/test/java/com/framsticks/params/ParamBuilderTest.java	(revision 86)
+++ /java/main/src/test/java/com/framsticks/params/ParamBuilderTest.java	(revision 86)
@@ -0,0 +1,50 @@
+package com.framsticks.params;
+
+import org.testng.annotations.Test;
+
+import com.framsticks.params.types.FloatParam;
+import com.framsticks.params.types.StringParam;
+import com.framsticks.parsers.MultiParamLoader;
+import com.framsticks.test.TestConfiguration;
+import static org.fest.assertions.Assertions.*;
+
+@Test
+public class ParamBuilderTest extends TestConfiguration {
+
+	ParamBuilder builder;
+	FramsClass builderFramsClass;
+	AccessInterface access;
+
+	@Test
+	public void createBuilderFramsClass() {
+		builderFramsClass = FramsClassBuilder.buildForClass(ParamBuilder.class);
+
+		assertThat(builderFramsClass.getParamCount()).isEqualTo(6);
+		assertThat(builderFramsClass.getName()).isEqualTo("prop");
+		assertThat(builderFramsClass.getId()).isEqualTo("prop");
+		assertThat(builderFramsClass.getParamEntry("id", Param.class)).isInstanceOf(StringParam.class);
+	}
+
+	@Test(dependsOnMethods = { "createBuilderFramsClass" })
+	public void loadParam() throws Exception {
+		access = new ReflectionAccess(ParamBuilder.class, builderFramsClass);
+		SourceInterface source = ListSource.createFrom("prop:", "id:v", "name:variable", "type:f", "help:just a testing variable", "");
+
+		MultiParamLoader loader = new MultiParamLoader();
+		loader.setNewSource(source);
+		loader.addAccessInterface(access);
+		loader.addBreakCondition(MultiParamLoader.Status.AfterObject);
+
+		MultiParamLoader.Status status = loader.go();
+
+		assertThat(status).isEqualTo(MultiParamLoader.Status.AfterObject);
+		Object object = loader.returnObject();
+		assertThat(object).isInstanceOf(ParamBuilder.class);
+
+		builder = (ParamBuilder) object;
+
+		Param param = builder.finish();
+		assertThat(param).isInstanceOf(FloatParam.class);
+	}
+
+}
Index: /java/main/src/test/resources/info/Creature.info
===================================================================
--- /java/main/src/test/resources/info/Creature.info	(revision 86)
+++ /java/main/src/test/resources/info/Creature.info	(revision 86)
@@ -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/test/resources/info/Genotype.info
===================================================================
--- /java/main/src/test/resources/info/Genotype.info	(revision 86)
+++ /java/main/src/test/resources/info/Genotype.info	(revision 86)
@@ -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/test/resources/info/Joint.info
===================================================================
--- /java/main/src/test/resources/info/Joint.info	(revision 86)
+++ /java/main/src/test/resources/info/Joint.info	(revision 86)
@@ -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/test/resources/info/MechJoint.info
===================================================================
--- /java/main/src/test/resources/info/MechJoint.info	(revision 86)
+++ /java/main/src/test/resources/info/MechJoint.info	(revision 86)
@@ -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/test/resources/info/MechPart.info
===================================================================
--- /java/main/src/test/resources/info/MechPart.info	(revision 86)
+++ /java/main/src/test/resources/info/MechPart.info	(revision 86)
@@ -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/test/resources/info/Neuro.info
===================================================================
--- /java/main/src/test/resources/info/Neuro.info	(revision 86)
+++ /java/main/src/test/resources/info/Neuro.info	(revision 86)
@@ -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/test/resources/info/NeuroDef.info
===================================================================
--- /java/main/src/test/resources/info/NeuroDef.info	(revision 86)
+++ /java/main/src/test/resources/info/NeuroDef.info	(revision 86)
@@ -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/test/resources/info/Part.info
===================================================================
--- /java/main/src/test/resources/info/Part.info	(revision 86)
+++ /java/main/src/test/resources/info/Part.info	(revision 86)
@@ -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/test/resources/info/World.info
===================================================================
--- /java/main/src/test/resources/info/World.info	(revision 86)
+++ /java/main/src/test/resources/info/World.info	(revision 86)
@@ -0,0 +1,74 @@
+class:
+id:World
+
+prop:
+id:wrldtyp
+name:Type
+type:d 0 2 0 ~Flat surface~Blocks~Height field
+
+prop:
+id:wrldsiz
+name:Size
+type:f 10 1000 20
+help:Side length of the world
+
+prop:
+id:wrldmap
+name:Map
+type:s 1
+help:~
+Description of the world (Type: Blocks or Heighfield). Enter
+   r <sizex> <sizey> [seed]
+to generate a random landscape, or
+   m <sizex> <sizey> digits
+   M <sizex> <sizey> numbers
+to provide height values.
+
+See also the WorldMap object.~
+
+prop:
+id:wrldwat
+name:Water level
+type:f -20 50 -1
+
+prop:
+id:wrldbnd
+name:Boundaries
+type:d 0 2 1 ~None~Fence~Teleport
+
+prop:
+id:wrldg
+name:Gravity
+type:f 0 10 1
+help:~
+You can adjust gravity for your experiments.
+The "official" setting used to evaluate and compare creatures is 1.~
+
+prop:
+id:wrldchg
+name:Trigger world update
+type:p()
+flags:32
+
+prop:
+id:simtype
+name:Simulation engine
+type:d 0 1 0 ~MechaStick~ODE
+help:~
+MechaStick is a fast and simple primary Framsticks simulation engine.
+ODE is Open Dynamics Engine by Russel Smith et al.
+
+NOTE: switching between simulation engines causes removal of all objects in the world (e.g. creatures).~
+
+prop:
+id:nnspeed
+name:NN speed
+type:f 0 1000 1
+help:Number of neural network simulation steps in each physics simulation step
+
+prop:
+id:faces
+name:Faces
+type:s
+help:ground geometry
+
Index: /java/main/src/test/resources/log4j.properties
===================================================================
--- /java/main/src/test/resources/log4j.properties	(revision 85)
+++ /java/main/src/test/resources/log4j.properties	(revision 86)
@@ -27,4 +27,5 @@
 
 log4j.logger.com.framsticks=INFO
+# log4j.logger.com.framsticks.parsers.MultiParamLoader=TRACE
 # log4j.logger.com.framsticks.gui.controls.SliderControl=TRACE
 # log4j.logger.com.framsticks.communication.ClientConnection=DEBUG
