diff --git a/compiler/LabComm.java b/compiler/LabComm.java
index 1334d2b24aa8ee7472c375487bda0b7202dbb679..c5a59b83bca2b93582425d400b29ad2b0d61134a 100644
--- a/compiler/LabComm.java
+++ b/compiler/LabComm.java
@@ -80,6 +80,7 @@ public class LabComm {
     String pythonFile = null;
     String prettyFile = null;
     String typeinfoFile = null;
+	String rapidFile = null;
 
     for (int i = 0 ; i < args.length ; i++) {
       if (fileName == null ||
@@ -119,6 +120,8 @@ public class LabComm {
 	prettyFile = args[i].substring(9);
       } else if (args[i].startsWith("--typeinfo=")) {
 	typeinfoFile = args[i].substring(11);
+      } else if (args[i].equals("--rapid")) {
+	rapidFile = coreName + ".sys";
       } else if (i == args.length - 1) {
 	fileName = args[i];
       } else {
@@ -192,6 +195,13 @@ public class LabComm {
 	  genPython(ast, pythonFile, prefix);
 	  prettyOnStdout = false;
 	}
+	if (rapidFile != null) {
+		if (verbose) {
+			System.err.println("Generating RAPID: " + rapidFile);
+		}
+		genRAPID(ast, rapidFile, coreName);
+		prettyOnStdout = false;
+	}
 	if (prettyFile != null) {
 	  if (verbose) { 
 	    System.err.println("Generating Pretty: " + prettyFile); 
@@ -290,6 +300,13 @@ public class LabComm {
     }
   }
 
+  private static void genRAPID(Program p, String filename, String prefix) {
+    try {
+      p.RAPID_gen(filename, prefix);
+    } catch (IOException e) {
+      System.err.println("IOException: " + filename + " " + e);
+    }
+  }
 
 
 }
diff --git a/compiler/RAPID_CodeGen.jrag b/compiler/RAPID_CodeGen.jrag
new file mode 100644
index 0000000000000000000000000000000000000000..9606105aec69274c4b08fa3d9bd181a1f35683d7
--- /dev/null
+++ b/compiler/RAPID_CodeGen.jrag
@@ -0,0 +1,355 @@
+
+aspect RAPID_env {
+	public class RAPID_env {
+		private String prefix;
+		private StringBuilder types;
+		private StringBuilder constants;
+		private StringBuilder procedures;
+		private PrintStream ps;
+
+		public RAPID_env(PrintStream ps, String prefix)
+		{
+			this.types = new StringBuilder();
+			this.constants = new StringBuilder();
+			this.procedures = new StringBuilder();
+			this.prefix = prefix;
+			this.ps = ps;
+		}
+
+		public String prefix() { return this.prefix; }
+
+		public String addRecord(String name, java.util.List<String> components)
+		{
+			String recordName = this.prefix + "_" + name;
+			types.append("\tRECORD " + recordName);
+			types.append("\n");
+			for (String c : components) {
+				types.append("\t\t" + c + "\n");
+			}
+			types.append("\tENDRECORD");
+			types.append("\n\n");
+			return recordName;
+		}
+
+		public void addConstant(String type, String name, String value) {
+			this.constants.append("\tLOCAL CONST " + type + " " + name +
+					" := " + value + ";\n");
+		}
+
+		public void addProc(String name, java.util.List<String> params,
+					java.util.List<String> stmts)
+		{
+			this.procedures.append("\tLOCAL PROC " + name + "(");
+			for (int i = 0; i < params.size(); i++) {
+				this.procedures.append(params.get(i));
+				if (i < params.size() - 1) {
+					this.procedures.append(", ");
+				}
+			}
+			this.procedures.append(")\n");
+			for (String stmt : stmts) {
+				this.procedures.append("\t\t" + stmt + "\n");
+			}
+			this.procedures.append("\tERROR\n\t\tRAISE ;\n\tENDPROC\n\n");
+		}
+
+		public void flush()
+		{
+			ps.println("MODULE " + prefix() + "(SYSMODULE)");
+			ps.println();
+			ps.print(types.toString());
+			ps.println();
+			ps.println("\tLOCAL CONST string prefix:=\"" + this.prefix + "\";");
+			ps.print(constants.toString());
+			ps.println();
+			ps.print(procedures.toString());
+			ps.println();
+			ps.print("ENDMODULE");
+		}
+	}
+}
+
+aspect RAPID_CodeGen {
+
+	public void ASTNode.RAPID_gen(RAPID_env env) {
+		throw new UnsupportedOperationException();
+	}
+
+	public void Program.RAPID_gen(String file, String prefix)
+			throws IOException
+	{
+		PrintStream ps = new PrintStream(new FileOutputStream(new File(file)));
+		RAPID_env env = new RAPID_env(ps, prefix);
+		RAPID_gen(env);
+	}
+
+	public void Program.RAPID_gen(RAPID_env env)
+	{
+		for (int i = 0; i < getNumDecl(); i++) {
+			getDecl(i).RAPID_gen(env);
+		}
+		env.flush();
+	}
+
+	public void Decl.RAPID_gen(RAPID_env env) {
+		throw new UnsupportedOperationException();
+	}
+
+	public void SampleDecl.RAPID_gen(RAPID_env env) {
+		// Add type declarations
+		String fullName = getType().RAPID_AddType(env, getName());
+		// Add signature constants
+		String sig_len_name = "signature_len_" + getName();
+		String sig_name = "signature_" + getName();
+		SignatureList sig = signature();
+		StringBuilder sb = new StringBuilder();
+		sb.append("[");
+		byte[] d = null;
+		int sig_len = 0;
+		for (int i = 0; i < sig.size(); i++) {
+			d = sig.getData(i);
+			for (int j = 0; d != null && j < d.length; j++) {
+				sb.append(d[j] + ",");
+				sig_len++;
+			}
+		}
+		sb.delete(sb.length() - 1, sb.length());
+		sb.append("]");
+		env.addConstant("num", sig_len_name, "" + sig_len);
+		env.addConstant("byte", sig_name + "{" + sig_len_name + "}",
+			sb.toString());
+		
+		// Add decode procedures
+		ArrayList<String> params = new ArrayList<String>();
+		ArrayList<String> stmts = new ArrayList<String>();
+		params.add("VAR LabComm_Decoder_Sample s");
+		params.add("string handler");
+		stmts.add("s.prefix := prefix;");
+		stmts.add("s.name := \"" + getName() + "\";");
+		stmts.add("s.handler := handler;");
+		env.addProc("Dec_Reg_" + getName(), params, stmts);	
+
+		params.clear();
+		stmts.clear();
+		params.add("VAR LabComm_Decoder_Sample s");
+		params.add("VAR rawbytes sig");
+		params.add("num user_id");
+		stmts.add("VAR byte tmp_sig{" + sig_len_name + "};");
+		stmts.add("IF RawBytesLen(sig)<>" + sig_len_name + " THEN");
+		stmts.add("\tRETURN;");
+		stmts.add("ENDIF");
+		stmts.add("FOR i FROM 1 TO " + sig_len_name + " DO");
+		stmts.add("\tUnpackRawBytes sig, i, tmp_sig{i}, \\Hex1;");
+		stmts.add("ENDFOR");
+		stmts.add("IF tmp_sig<>" + sig_name + " THEN");
+		stmts.add("\tRETURN;");
+		stmts.add("ENDIF");
+		stmts.add("s.user_id := user_id;");
+		env.addProc("Reg_If_Signature_Of_" + getName(), params, stmts);
+
+		params.clear();
+		stmts.clear();
+		params.add("VAR Decoder d");
+		params.add("VAR LabComm_Stream st");
+		params.add("VAR LabComm_Decoder_Sample s");
+		stmts.add("VAR " + fullName + " tmp;");
+		getType().RAPID_AddDecodeInstr(env, stmts, "tmp", "st");
+		stmts.add("% s.handler % tmp;");
+		env.addProc("Decode_And_Handle_" + getName(), params, stmts);
+
+		params.clear();
+		stmts.clear();
+		params.add("VAR Encoder e");
+		params.add("VAR LabComm_Stream st");
+		params.add("VAR LabComm_Encoder_Sample s");
+		stmts.add("s.prefix := prefix;");
+		stmts.add("s.name := \"" + getName() + "\";");
+		stmts.add("Encoder_Register_Sample e, st, s;");
+		env.addProc("Enc_Reg_" + getName(), params, stmts);
+
+		params.clear();
+		stmts.clear();
+		params.add("VAR Encoder e");
+		params.add("VAR LabComm_Stream s");
+		stmts.add("VAR rawbytes buffer;");
+		stmts.add("FOR i FROM 1 TO " + sig_len_name + " DO");
+		stmts.add("\tPackRawBytes " + sig_name +
+					"{i}, buffer, \\Network, i, \\Hex1;");
+		stmts.add("ENDFOR");
+		stmts.add("SocketSend s.soc, \\RawData:=buffer, \\NoOfBytes:=" +
+					sig_len_name + ";");
+		env.addProc("Encode_Signature_" + getName(), params, stmts);
+
+		params.clear();
+		stmts.clear();
+		params.add("VAR Encoder e");
+		params.add("VAR LabComm_Stream st");
+		params.add("VAR LabComm_Encoder_Sample s");
+		params.add("VAR " + fullName + " val");
+		stmts.add("Encode_Packed st, s.user_id;");
+		getType().RAPID_AddEncodeInstr(env, stmts, "val", "st");
+		env.addProc("Encode_" + getName(), params, stmts);
+	}
+
+	public String Type.RAPID_AddType(RAPID_env env, String name) {
+		throw new UnsupportedOperationException();
+	}
+
+	public String StructType.RAPID_AddType(RAPID_env env, String name) {
+		ArrayList<String> components = new ArrayList<String>();
+		for (int i = 0; i < getNumField(); i++) {
+			Field f = getField(i);
+			components.add(
+					f.getType().RAPID_AddType(env, name + "_" + f.getName()) +
+					" " + f.getName() + ";");
+		}
+		String typeName = env.addRecord(name, components);
+		return typeName;
+	}
+
+	public String FixedArrayType.RAPID_AddType(RAPID_env env, String name) {
+		String typeName = getType().RAPID_AddType(env, name + "_e");
+		if (getNumExp() > 1) {
+			throw new UnsupportedOperationException();
+		}
+		ArrayList<String> components = new ArrayList<String>();
+		for (int i = 1; i <= getExp(0).RAPID_getValue(); i++) {
+			components.add(typeName + " e" + i + ";");
+		}
+		String completeName = env.addRecord("list_" + name, components);
+		return completeName;
+	}
+
+	public String PrimType.RAPID_AddType(RAPID_env env, String name) {
+		if (getToken() == LABCOMM_SHORT ||
+			getToken() == LABCOMM_FLOAT ||
+			getToken() == LABCOMM_INT) {
+			return "num";
+		} else if (getToken() == LABCOMM_LONG) {
+			return "dnum";
+		} else if (getToken() == LABCOMM_STRING) {
+			return "string";
+		} else if (getToken() == LABCOMM_BOOLEAN) {
+			return "bool";
+		} else if (getToken() == LABCOMM_BYTE) {
+			return "byte";
+		}
+		throw new UnsupportedOperationException();
+	}
+
+	public void Type.RAPID_AddDecodeInstr(RAPID_env env,
+			java.util.List<String> instrs,
+			String var_name, String stream_name) {
+		throw new UnsupportedOperationException();
+	}
+
+	public void StructType.RAPID_AddDecodeInstr(RAPID_env env,
+			java.util.List<String> instrs,
+			String var_name, String stream_name) {
+		for (int i = 0; i < getNumField(); i++) {
+			getField(i).getType().RAPID_AddDecodeInstr(env, instrs,
+					var_name + "." + getField(i).getName(), stream_name);
+		}
+	}
+
+	public void FixedArrayType.RAPID_AddDecodeInstr(RAPID_env env,
+			java.util.List<String> instrs,
+			String var_name, String stream_name) {
+		for (int i = 1; i <= getExp(0).RAPID_getValue(); i++) {
+			getType().RAPID_AddDecodeInstr(env, instrs,
+					var_name + ".e" + i, stream_name);
+		}
+	}
+
+	public void PrimType.RAPID_AddDecodeInstr(RAPID_env env,
+			java.util.List<String> instrs,
+			String var_name, String stream_name) {
+		switch(getToken()) {
+			case LABCOMM_BYTE:
+				instrs.add("Decode_Byte " + stream_name + "," + var_name + ";");
+				break;
+			case LABCOMM_BOOLEAN:
+				instrs.add("Decode_Bool " + stream_name + "," + var_name + ";");
+				break;
+			case LABCOMM_SHORT:
+				instrs.add("Decode_Short " + stream_name + "," + var_name + ";");
+				break;
+			case LABCOMM_INT:
+				instrs.add("Decode_Int " + stream_name + "," + var_name + ";");
+				break;
+			case LABCOMM_LONG:
+				instrs.add("Decode_Long " + stream_name + "," + var_name + ";");
+				break;
+			case LABCOMM_FLOAT:
+				instrs.add("Decode_Float " + stream_name + "," + var_name + ";");
+				break;
+			case LABCOMM_STRING:
+				instrs.add("Decode_String " + stream_name + "," + var_name + ";");
+				break;
+			default:
+				throw new UnsupportedOperationException();
+		}
+	}
+
+	public void Type.RAPID_AddEncodeInstr(RAPID_env env,
+			java.util.List<String> instrs,
+			String var_name, String stream_name) {
+		throw new UnsupportedOperationException();
+	}
+
+	public void StructType.RAPID_AddEncodeInstr(RAPID_env env,
+			java.util.List<String> instrs,
+			String var_name, String stream_name) {
+		for (int i = 0; i < getNumField(); i++) {
+			getField(i).getType().RAPID_AddEncodeInstr(env, instrs,
+					var_name + "." + getField(i).getName(), stream_name);
+		}
+	}
+
+	public void FixedArrayType.RAPID_AddEncodeInstr(RAPID_env env,
+			java.util.List<String> instrs,
+			String var_name, String stream_name) {
+		for (int i = 1; i <= getExp(0).RAPID_getValue(); i++) {
+			getType().RAPID_AddEncodeInstr(env, instrs,
+					var_name + ".e" + i, stream_name);
+		}
+	}
+
+	public void PrimType.RAPID_AddEncodeInstr(RAPID_env env,
+			java.util.List<String> instrs,
+			String var_name, String stream_name) {
+		switch(getToken()) {
+			case LABCOMM_BYTE:
+				instrs.add("Encode_Byte " + stream_name + "," + var_name + ";");
+				break;
+			case LABCOMM_BOOLEAN:
+				instrs.add("Encode_Bool " + stream_name + "," + var_name + ";");
+				break;
+			case LABCOMM_SHORT:
+				instrs.add("Encode_Short " + stream_name + "," + var_name + ";");
+				break;
+			case LABCOMM_INT:
+				instrs.add("Encode_Int " + stream_name + "," + var_name + ";");
+				break;
+			case LABCOMM_LONG:
+				instrs.add("Encode_Long " + stream_name + "," + var_name + ";");
+				break;
+			case LABCOMM_FLOAT:
+				instrs.add("Encode_Float " + stream_name + "," + var_name + ";");
+				break;
+			case LABCOMM_STRING:
+				instrs.add("Encode_String " + stream_name + "," + var_name + ";");
+				break;
+			default:
+				throw new UnsupportedOperationException();
+		}
+	}
+
+	public int Exp.RAPID_getValue() {
+		throw new UnsupportedOperationException();
+	}
+
+	public int IntegerLiteral.RAPID_getValue() {
+		return Integer.parseInt(getValue());
+	}
+}
diff --git a/examples/robot/App.config b/examples/robot/App.config
new file mode 100644
index 0000000000000000000000000000000000000000..8e15646352ec1d9a84bbc6504ef6b46e16bf7823
--- /dev/null
+++ b/examples/robot/App.config
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<configuration>
+    <startup> 
+        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
+    </startup>
+</configuration>
\ No newline at end of file
diff --git a/examples/robot/Follow.mod b/examples/robot/Follow.mod
new file mode 100644
index 0000000000000000000000000000000000000000..fb86d9f6b81cb2104e9f1722828c4132f8046d2c
--- /dev/null
+++ b/examples/robot/Follow.mod
@@ -0,0 +1,49 @@
+MODULE Follow
+    PROC LCjt2jt(VAR LCRobot_jointtarget a, VAR jointtarget b)
+        b.robax.rax_1 := a.robax.rax_1;
+        b.robax.rax_2 := a.robax.rax_2;
+        b.robax.rax_3 := a.robax.rax_3;
+        b.robax.rax_4 := a.robax.rax_4;
+        b.robax.rax_5 := a.robax.rax_5;
+        b.robax.rax_6 := a.robax.rax_6;
+        
+        b.extax.eax_a := a.extax.eax_a;
+        b.extax.eax_b := a.extax.eax_b;
+        b.extax.eax_c := a.extax.eax_c;
+        b.extax.eax_d := a.extax.eax_d;
+        b.extax.eax_e := a.extax.eax_e;
+        b.extax.eax_f := a.extax.eax_f;
+    ENDPROC
+    
+    PROC handle_jointtarget(LCRobot_jointtarget val)
+        VAR jointtarget jt;
+        LCjt2jt val, jt;
+        MoveAbsJ jt, v100, z1, tool0, \WObj:=wobj0;
+    ENDPROC
+    
+    PROC main()
+        VAR LabComm_Stream st;
+        VAR socketdev srv;
+        SocketCreate srv;
+        SocketBind srv, "127.0.0.1", 51337;
+        SocketListen srv;
+        WHILE TRUE DO
+            SocketAccept srv, st.soc;
+            Receive_targets st;
+        ENDWHILE
+    ENDPROC
+    
+    PROC Receive_targets(VAR LabComm_Stream st)
+        VAR Decoder d;
+        VAR LabComm_Decoder_Sample s{1};
+        Init_Decoder d, st;
+        % "LCRobot:Dec_Reg_jointtarget" % s{1}, "handle_jointtarget";
+        WHILE TRUE DO
+            Decode_One d, st, s;
+        ENDWHILE
+    ERROR
+        SocketClose st.soc;
+        RETURN;
+    ENDPROC
+    
+ENDMODULE
\ No newline at end of file
diff --git a/examples/robot/LCRobot.lc b/examples/robot/LCRobot.lc
new file mode 100644
index 0000000000000000000000000000000000000000..971767d85e923881e5a3e5f28c66f3b302374a39
--- /dev/null
+++ b/examples/robot/LCRobot.lc
@@ -0,0 +1,38 @@
+sample struct {
+	struct {
+		float x;
+		float y;
+		float z;
+	} trans;
+	struct {
+		float q1;
+		float q2;
+		float q3;
+		float q4;
+	} rot;
+	struct {
+		short cf1;
+		short cf4;
+		short cf6;
+		short cfx;
+	} robconfig;
+} robtarget;
+
+sample struct {
+	struct {
+		float rax_1;
+		float rax_2;
+		float rax_3;
+		float rax_4;
+		float rax_5;
+		float rax_6;
+	} robax;
+	struct {
+		float eax_a;
+		float eax_b;
+		float eax_C;
+		float eax_d;
+		float eax_e;
+		float eax_f;
+	} extax;
+} jointtarget;
\ No newline at end of file
diff --git a/examples/robot/Program.cs b/examples/robot/Program.cs
new file mode 100644
index 0000000000000000000000000000000000000000..28fddc27a50c93ec91d9db5ced4ab3d58a215a01
--- /dev/null
+++ b/examples/robot/Program.cs
@@ -0,0 +1,52 @@
+using se.lth.control.labcomm;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Net;
+using System.Net.Sockets;
+using System.Text;
+using System.Threading;
+using System.Threading.Tasks;
+
+namespace RobotCtrl
+{
+    class Program
+    {
+
+        public static string IP_ADDRESS = "127.0.0.1";
+        public static int PORT = 51337;
+
+        static void Main(string[] args)
+        {
+            jointtarget val = new jointtarget { robax = new jointtarget.struct_robax(), extax = new jointtarget.struct_extax() };
+            TcpClient client = new TcpClient();
+            IPEndPoint serverEndPoint = new IPEndPoint(IPAddress.Parse(Program.IP_ADDRESS), Program.PORT);
+            try
+            {
+                client.Connect(serverEndPoint);
+                LabCommEncoder enc = new LabCommEncoderChannel(client.GetStream(), true);
+                jointtarget.register(enc);
+                jointtarget.encode(enc, val);
+                for (int i = 0; i < 10; i++)
+                {
+                    val.robax.rax_2 += 2;
+                    jointtarget.encode(enc, val);
+                }
+                for (int i = 0; i < 20; i++)
+                {
+                    val.robax.rax_2 -= 2;
+                    jointtarget.encode(enc, val);
+                }
+                for (int i = 0; i < 10; i++)
+                {
+                    val.robax.rax_2 += 2;
+                    jointtarget.encode(enc, val);
+                }
+            }
+            finally
+            {
+                client.Close();
+            }
+        }
+    }
+}
diff --git a/examples/robot/Properties/AssemblyInfo.cs b/examples/robot/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000000000000000000000000000000000..9fcb6df01cc550b0ff752365e1022ebfc962ec78
--- /dev/null
+++ b/examples/robot/Properties/AssemblyInfo.cs
@@ -0,0 +1,36 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("RobotCtrl")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("")]
+[assembly: AssemblyProduct("RobotCtrl")]
+[assembly: AssemblyCopyright("Copyright ©  2013")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("bd5ee6d6-1dff-4043-8ca9-b56a29116e61")]
+
+// Version information for an assembly consists of the following four values:
+//
+//      Major Version
+//      Minor Version 
+//      Build Number
+//      Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers 
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/examples/robot/RobotCtrl.csproj b/examples/robot/RobotCtrl.csproj
new file mode 100644
index 0000000000000000000000000000000000000000..7dcdcb0c06be2494f719ddb2d1d5f841fc7f3e2c
--- /dev/null
+++ b/examples/robot/RobotCtrl.csproj
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{F0051A25-4FFF-4421-A5CB-01B512D6CEC5}</ProjectGuid>
+    <OutputType>Exe</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>RobotCtrl</RootNamespace>
+    <AssemblyName>RobotCtrl</AssemblyName>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <PlatformTarget>AnyCPU</PlatformTarget>
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="System" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="System.Data.DataSetExtensions" />
+    <Reference Include="Microsoft.CSharp" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Xml" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="LCRobot.cs" />
+    <Compile Include="Program.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="App.config" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\lib\csharp\LabComm.csproj">
+      <Project>{755cd5a6-c48e-4d35-b0be-8ec0fde1a2a1}</Project>
+      <Name>LabComm</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
\ No newline at end of file
diff --git a/examples/robot/RobotCtrl.sln b/examples/robot/RobotCtrl.sln
new file mode 100644
index 0000000000000000000000000000000000000000..91ac48357dd6ccd7990024c02f01a74cab3b1b58
--- /dev/null
+++ b/examples/robot/RobotCtrl.sln
@@ -0,0 +1,26 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 2012
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RobotCtrl", "RobotCtrl.csproj", "{F0051A25-4FFF-4421-A5CB-01B512D6CEC5}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LabComm", "..\..\lib\csharp\LabComm.csproj", "{755CD5A6-C48E-4D35-B0BE-8EC0FDE1A2A1}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|Any CPU = Debug|Any CPU
+		Release|Any CPU = Release|Any CPU
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{F0051A25-4FFF-4421-A5CB-01B512D6CEC5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{F0051A25-4FFF-4421-A5CB-01B512D6CEC5}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{F0051A25-4FFF-4421-A5CB-01B512D6CEC5}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{F0051A25-4FFF-4421-A5CB-01B512D6CEC5}.Release|Any CPU.Build.0 = Release|Any CPU
+		{755CD5A6-C48E-4D35-B0BE-8EC0FDE1A2A1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{755CD5A6-C48E-4D35-B0BE-8EC0FDE1A2A1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{755CD5A6-C48E-4D35-B0BE-8EC0FDE1A2A1}.Release|Any CPU.ActiveCfg = Debug|Any CPU
+		{755CD5A6-C48E-4D35-B0BE-8EC0FDE1A2A1}.Release|Any CPU.Build.0 = Debug|Any CPU
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+EndGlobal
diff --git a/lib/RAPID/LabComm.sys b/lib/RAPID/LabComm.sys
new file mode 100644
index 0000000000000000000000000000000000000000..8d31dce0ebea49dafbe574ea63d74ff5dd49569b
--- /dev/null
+++ b/lib/RAPID/LabComm.sys
@@ -0,0 +1,317 @@
+MODULE LabComm(SYSMODULE)
+    
+    RECORD LabComm_Stream
+        socketdev soc;
+    ENDRECORD
+    
+    RECORD LabComm_Decoder_Sample
+        string prefix;
+        string name;
+        num user_id;
+        string handler;
+    ENDRECORD
+        
+    RECORD LabComm_Encoder_Sample
+        string prefix;
+        string name;
+        num user_id;
+    ENDRECORD
+    
+    RECORD Decoder
+        num user_id;
+    ENDRECORD
+    
+    RECORD Encoder
+        num next_user_id;
+    ENDRECORD
+    
+    ! LabComm constants
+    CONST string LabCommVersion := "LabComm2013";
+    CONST num SAMPLE_DECL:=2;
+    CONST num SAMPLE_DATA:=64;
+    
+    CONST num STRUCT_TYPE := 17;
+    CONST num ARRAY_TYPE := 16;
+    CONST num BYTE_TYPE := 37;
+    CONST num BOOL_TYPE := 37;
+    CONST num SHORT_TYPE := 34;
+    CONST num INT_TYPE := 37;
+    CONST num LONG_TYPE := 37;
+    CONST num FLOAT_TYPE := 37;
+    
+    ! Error declarations
+    CONST errnum INCORRECT_LABCOMM_VERSION := 50;
+    CONST errnum UNKNOWN_PACKET_TYPE := 51;
+    CONST errnum UNKNOWN_SAMPLE_TYPE := 52;
+    CONST errnum INCORRECT_SAMPLE_SIGNATURE := 53;
+    CONST errnum SAMPLE_TYPE_NOT_REGISTERED := 54;
+    CONST errnum IMPLEMENTATION_LIMIT_REACHED := 55;
+
+    PROC Decode_Packed(VAR LabComm_Stream s, VAR num v, \ VAR rawbytes collect)
+        VAR rawbytes buffer;
+        SocketReceive s.soc,\RawData:=buffer,\ReadNoOfBytes:=1;
+        UnpackRawBytes buffer,\Network,1,v,\IntX:=USINT;
+        IF Present(collect) THEN
+            CopyRawBytes buffer, 1, collect, (RawBytesLen(collect)+1);
+        ENDIF
+    ERROR
+        RAISE ;
+    ENDPROC
+    
+    PROC Encode_Packed(VAR LabComm_Stream s, num v)
+        VAR rawbytes buffer;
+        PackRawBytes v,buffer,\Network,1,\IntX:=USINT;
+        SocketSend s.soc,\RawData:=buffer,\NoOfBytes:=1;
+    ERROR
+        RAISE ;
+    ENDPROC
+    
+    PROC Decode_Boolean(VAR LabComm_Stream s, VAR bool v, \ VAR rawbytes collect)
+        VAR rawbytes buffer;
+        VAR num tmp;
+        SocketReceive s.soc,\RawData:=buffer,\ReadNoOfBytes:=1;
+        UnpackRawBytes buffer,\Network,1,tmp,\IntX:=USINT;
+        IF tmp = 0 THEN
+            v := FALSE;
+        ELSE
+            v := TRUE;
+        ENDIF
+        IF Present(collect) THEN
+            CopyRawBytes buffer, 1, collect, (RawBytesLen(collect)+1);
+        ENDIF
+    ERROR
+        RAISE ;
+    ENDPROC
+    
+    PROC Encode_Boolean(VAR LabComm_Stream s, bool v)
+        VAR rawbytes buffer;
+        VAR num tmp;
+        IF v THEN
+            tmp := 1;
+        ELSE
+            tmp := 0;
+        ENDIF
+        PackRawBytes tmp,buffer,\Network,1,\IntX:=USINT;
+        SocketSend s.soc,\RawData:=buffer,\NoOfBytes:=1;
+    ERROR
+        RAISE ;
+    ENDPROC
+    
+    PROC Decode_Byte(VAR LabComm_Stream s, VAR byte v, \ VAR rawbytes collect)
+        VAR rawbytes buffer;
+        SocketReceive s.soc,\RawData:=buffer,\ReadNoOfBytes:=1;
+        UnpackRawBytes buffer,\Network,1,v,\Hex1;
+        IF Present(collect) THEN
+            CopyRawBytes buffer, 1, collect, (RawBytesLen(collect)+1);
+        ENDIF
+    ERROR
+        RAISE ;
+    ENDPROC
+    
+    PROC Encode_Byte(VAR LabComm_Stream s, byte v)
+        VAR rawbytes buffer;
+        PackRawBytes v,buffer,\Network,1,\Hex1;
+        SocketSend s.soc,\RawData:=buffer,\NoOfBytes:=1;
+    ERROR
+        RAISE ;
+    ENDPROC
+    
+    PROC Decode_Short(VAR LabComm_Stream s,VAR num v, \ VAR rawbytes collect)
+        VAR rawbytes buffer;
+        SocketReceive s.soc,\RawData:=buffer,\ReadNoOfBytes:=2;
+        UnpackRawBytes buffer,\Network,1,v,\IntX:=INT;
+        IF Present(collect) THEN
+            CopyRawBytes buffer, 1, collect, (RawBytesLen(collect)+1);
+        ENDIF
+    ERROR
+        RAISE ;
+    ENDPROC
+
+    PROC Encode_Short(VAR LabComm_Stream s, num v)
+        VAR rawbytes buffer;
+        PackRawBytes v, buffer, \Network, 1, \IntX:=INT;
+        SocketSend s.soc, \RawData:=buffer, \NoOfBytes:=2;
+    ERROR
+        RAISE ;
+    ENDPROC
+    
+    PROC Decode_Integer(VAR LabComm_Stream s, VAR num v, \ VAR rawbytes collect)
+        VAR rawbytes buffer;
+        SocketReceive s.soc,\RawData:=buffer,\ReadNoOfBytes:=4;
+        UnpackRawBytes buffer,\Network,1,v,\IntX:=DINT;
+        IF Present(collect) THEN
+            CopyRawBytes buffer, 1, collect, (RawBytesLen(collect)+1);
+        ENDIF
+    ERROR
+        RAISE ;
+    ENDPROC
+    
+    PROC Encode_Integer(VAR LabComm_Stream s, num v)
+        VAR rawbytes buffer;
+        PackRawBytes v,buffer,\Network,1,\IntX:=DINT;
+        SocketSend s.soc,\RawData:=buffer,\NoOfBytes:=4;
+    ERROR
+        RAISE ;
+    ENDPROC
+    
+    PROC Decode_Long(VAR LabComm_Stream s, VAR dnum v, \ VAR rawbytes collect)
+        VAR rawbytes buffer;
+        SocketReceive s.soc,\RawData:=buffer,\ReadNoOfBytes:=8;
+        UnpackRawBytes buffer,\Network,1,v,\IntX:=LINT;
+        IF Present(collect) THEN
+            CopyRawBytes buffer, 1, collect, (RawBytesLen(collect)+1);
+        ENDIF
+    ERROR
+        RAISE ;
+    ENDPROC
+    
+    PROC Encode_Long(VAR LabComm_Stream s, dnum v)
+        VAR rawbytes buffer;
+        PackRawBytes v,buffer,\Network,1,\IntX:=LINT;
+        SocketSend s.soc,\RawData:=buffer,\NoOfBytes:=8;
+    ERROR
+        RAISE ;
+    ENDPROC
+    
+    PROC Decode_Float(VAR LabComm_Stream s,VAR num v, \ VAR rawbytes collect)
+        VAR rawbytes buffer;
+        SocketReceive s.soc,\RawData:=buffer,\ReadNoOfBytes:=4;
+        UnpackRawBytes buffer,\Network,1,v,\Float4;
+        IF Present(collect) THEN
+            CopyRawBytes buffer, 1, collect, (RawBytesLen(collect)+1);
+        ENDIF
+    ERROR
+        RAISE ;
+    ENDPROC
+       
+    PROC Encode_Float(VAR LabComm_Stream s, num v)
+        VAR rawbytes buffer;
+        PackRawBytes v, buffer,\Network,1,\Float4;
+        SocketSend s.soc,\RawData:=buffer,\NoOfBytes:=4;
+    ERROR
+        RAISE ;
+    ENDPROC
+
+    PROC Decode_String(VAR LabComm_Stream st,VAR string s, \ VAR rawbytes collect)
+        VAR rawbytes buffer;
+        VAR num length;
+        IF Present(collect) THEN
+            Decode_Packed st, length, \collect:=collect;
+        ELSE
+            Decode_Packed st, length;
+        ENDIF
+        SocketReceive st.soc,\Str:=s,\ReadNoOfBytes:=length;
+        IF Present(collect) THEN
+            PackRawBytes s, collect, (RawBytesLen(collect)+1), \ASCII;
+        ENDIF
+    ERROR
+        RAISE ;
+    ENDPROC
+    
+    PROC Encode_String(VAR LabComm_Stream st, string s)
+        VAR rawbytes buffer;
+        VAR num length;
+        length := StrLen(s);
+        Encode_Packed st, length;
+        SocketSend st.soc,\Str:=s,\NoOfBytes:=length;
+    ERROR
+        RAISE ;
+    ENDPROC
+    
+    PROC Encoder_Register_Sample(VAR Encoder e, VAR LabComm_Stream st, VAR LabComm_Encoder_Sample s)
+        s.user_id := e.next_user_id;
+        e.next_user_id := e.next_user_id + 1;
+        Encode_Packed st, SAMPLE_DECL;
+        Encode_Packed st, s.user_id;
+        Encode_String st, s.name;
+        % s.prefix + ":Encode_Signature_" + s.name % e, st;
+    ERROR
+        RAISE ;
+    ENDPROC
+    
+    PROC Collect_Array(VAR LabComm_Stream s, VAR rawbytes sig)
+        VAR num num_dim;
+        VAR num dims;
+        Decode_Packed s, num_dim, \collect:=sig;
+        FOR i FROM 1 TO num_dim DO
+            Decode_Packed s, dims, \collect:=sig;
+        ENDFOR
+        Collect_Signature s, sig;
+    ERROR
+        RAISE ;
+    ENDPROC
+    
+    PROC Collect_Struct(VAR LabComm_Stream s, VAR rawbytes sig)
+        VAR num num_elements;
+        VAR string tmp;
+        Decode_Packed s, num_elements, \collect:=sig;
+        FOR i FROM 1 TO num_elements DO
+            Decode_String s, tmp, \collect:=sig;
+            Collect_Signature s, sig;
+        ENDFOR
+    ERROR
+        RAISE ;
+    ENDPROC
+    
+    PROC Collect_Signature(VAR LabComm_Stream s, VAR rawbytes sig)
+        VAR num type_id;
+        Decode_Packed s, type_id, \collect:=sig;
+        TEST type_id
+        CASE STRUCT_TYPE:
+            Collect_Struct s, sig;
+        CASE ARRAY_TYPE:
+            Collect_Array s, sig;
+        CASE BYTE_TYPE, BOOL_TYPE, SHORT_TYPE, INT_TYPE, LONG_TYPE, SHORT_TYPE:
+        DEFAULT:
+            RAISE IMPLEMENTATION_LIMIT_REACHED;
+        ENDTEST
+    ERROR
+        RAISE ;
+    ENDPROC
+
+    PROC Decode_One(VAR Decoder d, VAR LabComm_Stream s, VAR LabComm_Decoder_Sample samples{*})
+        VAR rawbytes buffer;
+        VAR num packet_type;
+        VAR num user_id;
+        VAR string type_name;
+        Decode_Packed s, packet_type;
+        WHILE packet_type = SAMPLE_DECL DO
+            Decode_Packed s, user_id;
+            Decode_String s, type_name;
+            Collect_Signature s, buffer;
+            FOR i FROM 1 TO Dim(samples, 1) DO
+                % samples{i}.prefix + ":Reg_If_Signature_Of_" + samples{i}.name % samples{i}, buffer, user_id;
+            ENDFOR
+            Decode_Packed s, packet_type;
+        ENDWHILE
+        IF packet_type >= SAMPLE_DATA THEN
+            FOR i FROM 1 TO Dim(samples, 1) DO
+                IF samples{i}.user_id = packet_type THEN
+                    % samples{i}.prefix + ":Decode_And_Handle_" + samples{i}.name % d, s, samples{i};
+                ENDIF
+            ENDFOR
+            RETURN ;
+        ENDIF
+        RAISE UNKNOWN_PACKET_TYPE;
+    ERROR
+        RAISE ;
+    ENDPROC
+
+    PROC Init_Decoder(VAR Decoder d, VAR LabComm_Stream s)
+        VAR string version;
+        Decode_String s,version;
+        IF version<>LabCommVersion THEN
+            RAISE INCORRECT_LABCOMM_VERSION;
+        ENDIF
+    ERROR
+        RAISE ;
+    ENDPROC
+    
+    PROC Init_Encoder(VAR Encoder e, VAR LabComm_Stream s)
+        Encode_String s, LabCommVersion;
+        e.next_user_id := SAMPLE_DATA;
+    ERROR
+        RAISE ;
+    ENDPROC
+
+ENDMODULE
\ No newline at end of file
diff --git a/lib/RAPID/README b/lib/RAPID/README
new file mode 100644
index 0000000000000000000000000000000000000000..f296d4d0de253a5758efb8ce408c759c247f9c79
--- /dev/null
+++ b/lib/RAPID/README
@@ -0,0 +1,104 @@
+The implementation of LabComm in RAPID
+
+Limitations of this implementation:
+ - The type double is not available due to limitations in RAPID. There is a
+   non-integer type with 64 bits but there is not marshalling utilities for it.
+ - Variable sized arrays is not available. There is no dynamic allocation,
+   possible solution is a max-size array (1024) and a integervalue denoting the
+   size.
+ - A RECORD (struct) cannot contain an array, but fixed size arrays are
+   available both in structs and stand alone. The current implementation creates
+   a RECORD with one member for each index in the array. Not an omptimal
+   solution, the alternativ would be a seperate variable.
+ - Decoding and encoding is done directly from a TCP socket.
+ - Every generated procedure is namespaced by declaring them LOCAL to the
+   generated module. They must be called by using runtime binding of procedure
+   names ( % proc_name % arg1, arg2, ...;). The generated types are not
+   declared local.
+
+Usage:
+
+# Declare a stream, LabComm_Stream:
+	$ VAR LabComm_Stream st;
+This contains a socketdev wich must be created and connected or instatiated
+through an accept.
+	$ SocketCreate st.soc;
+	$ SocketConnect st.soc, "127.0.0.1", 55555;
+or
+	$ SocketAccept server_socket, st.soc;
+
+# Initiate Encoder and/or Decoder with the stream:
+	$ VAR Decoder d;
+	$ Init_Decoder d, st;
+
+	$ VAR Encoder e;
+	$ Init_Encoder e, st;
+This will read/write the version of LabComm to ensure compatibility, current
+version is "LabComm2013".
+
+# Initiate the labcomm samples:
+LabComm trusts the application to manage each sample. It requests the samples,
+as a list, when performing decoding or encoding.
+This is done through the generated code which implies the procedures are LOCAL
+and must be called with runtime bindings.
+When initiating a decoder sample the name of the callback procedure to receive
+such samples is suplied as a string.
+	$ PROC handle_samplename(prefix_samplename val)
+	$ ...
+	$ ENDPROC
+	$ VAR LabComm_Decoder_Sample ds{1};
+	$ % prefix:Dec_Reg_samplename % ds{1}, "handle_samplename";
+NOTE: The callback must be of type procedure and not function. Functions cannot
+be called with runtime bindings.
+
+When initiating an encoder sample the stream must be supplied to let the
+encoder send the sample signature.
+	$ VAR LabComm_Encoder_Sample es{1};
+	$ % prefix:Enc_Reg_samplename % e, st, es{1};
+
+# Encode and/or decode samples:
+	$ Decode_One d, st, ds;
+It returns as soon as any sample is decoded. The decoded sample is supplied as
+argument to the callback procedure registered with the corresponding sample.
+	$ VAR prefix_samplename val;
+	$ <init val>
+	$ % prefix:Encode_samplename % e, st, es{1}, val;
+
+# Complete example:
+
+## LabComm definition:
+example.lc >>
+sample struct {
+	short sum;
+	short terms[2];
+} foo;
+<< EOF
+
+## RAPID CODE
+PROC handle_foo(example_foo val)
+	IF val.sum = val.terms.e1 + val.terms.e2 THEN
+		TPWrite "Verification successfull!";
+	ELSE
+		TPWrite "Verification failed!";
+	ENDIF
+ENDPROC
+
+
+PROC main()
+	VAR Decoder d;
+	VAR Encoder e;
+	VAR LabComm_Stream st;
+	VAR LabComm_Encoder_Sample es{1};
+	VAR LabComm_Decoder_Sample ds{1};
+	VAR example_foo val := [2,[1,1]];
+	SocketCreate st.soc;
+	SocketConnect st.soc, "127.0.0.1", 55555;
+	Init_Decoder d, st;
+	Init_Encoder e, st;
+	% "example:Enc_Reg_foo" % e, st, es{1};
+	% "example:Dec_Reg_foo" % ds{1}, "handle_foo";
+	% "example:Encode_foo" % e, st, es{1}, val;
+	Decode_One d, st, ds;
+	SocketClose st.soc;
+ENDPROC
+
diff --git a/lib/csharp/LabComm.csproj b/lib/csharp/LabComm.csproj
new file mode 100644
index 0000000000000000000000000000000000000000..c6406ea5d3069279beb23378a5cec15524b6be46
--- /dev/null
+++ b/lib/csharp/LabComm.csproj
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <OutputType>Library</OutputType>
+    <AssemblyName>LabComm</AssemblyName>
+    <ProjectGuid>{755CD5A6-C48E-4D35-B0BE-8EC0FDE1A2A1}</ProjectGuid>
+    <!-- Properties which affect the build process -->
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)' == 'Debug'">
+    <OutputPath>bin\Debug\</OutputPath>
+  </PropertyGroup>
+  <ItemGroup>
+    <Compile Include="se\lth\control\labcomm\LabCommDispatcher.cs" />
+    <Compile Include="se\lth\control\labcomm\LabCommDecoderRegistry.cs" />
+    <Compile Include="se\lth\control\labcomm\LabComm.cs" />
+    <Compile Include="se\lth\control\labcomm\LabCommSample.cs" />
+    <Compile Include="se\lth\control\labcomm\LabCommHandler.cs" />
+    <Compile Include="se\lth\control\labcomm\LabCommEncoderRegistry.cs" />
+    <Compile Include="se\lth\control\labcomm\LabCommDecoder.cs" />
+    <Compile Include="se\lth\control\labcomm\LabCommType.cs" />
+    <Compile Include="se\lth\control\labcomm\LabCommEncoderChannel.cs" />
+    <Compile Include="se\lth\control\labcomm\LabCommEncoder.cs" />
+    <Compile Include="se\lth\control\labcomm\LabCommDecoderChannel.cs" />
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+</Project>
\ No newline at end of file