diff --git a/.gitignore b/.gitignore
index dc459a3210b50406a6481e3208af3dbb3ee200a3..adb9932f542594f5180aa9d6319032cbc9aff013 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,59 +1,4 @@
 *~
 *.class
 *.o
-lib/c/liblabcomm.a
-lib/c/liblabcomm.so
-lib/c/liblabcomm.so.1
-lib/c/liblabcomm2006.so.1
-lib/c/liblabcomm2006.so
-lib/c/liblabcomm2006.a
-lib/c/liblabcomm2014.so.1
-lib/c/liblabcomm2014.so
-lib/c/liblabcomm2014.a
-lib/c/20*/test/test_labcomm
-lib/c/20*/test/test_labcomm_basic_type_encoding
-lib/c/20*/test/test_labcomm_copy
-lib/c/20*/test/test_labcomm_generated_encoding
-lib/c/20*/test/test_labcomm_pthread_scheduler
-lib/c/20*/test/test_signature_numbers
-compiler/gen/
-compiler/AST/
-compiler/labcomm_compiler.jar
-compiler/labcomm2006_compiler.jar
-compiler/labcomm2014_compiler.jar
-examples/simple/encoded_data
-examples/simple/encoded_data06
-examples/simple/gen
-examples/simple/gen06
 *.pyc
-examples/twoway/gen/
-examples/duck_typing/gen/
-lib/csharp/labcomm.dll
-lib/java/gen/
-lib/java/labcomm*.jar
-examples/simple/example_decoder
-examples/simple/example_decoder06
-examples/simple/example_encoder
-examples/simple/example_encoder06
-ExampleDecoder.exe ExampleEncoder.exe
-examples/user_types/gen/
-examples/user_types/encoded_data_c 
-examples/user_types/encoded_data_cs 
-examples/user_types/encoded_data_j 
-examples/user_types/encoded_data_p
-examples/wiki_example/data.java
-examples/wiki_example/example.c
-examples/wiki_example/example.cs
-examples/wiki_example/example.encoded
-examples/wiki_example/example.h
-examples/wiki_example/example.py
-examples/wiki_example/log_message.java
-examples/wiki_example/example_encoder
-examples/user_types/ExampleDecoder.exe
-examples/user_types/ExampleEncoder.exe
-doc/tech_report.aux
-doc/tech_report.blg
-doc/tech_report.bbl
-doc/tech_report.log
-doc/tech_report.pdf
-doc/tech_report.fdb_latexmk
diff --git a/Makefile b/Makefile
index 981832dc34f5fbf4c480bd375eb6d03f63d7c55f..77f3305be42cf3bf750fbed64aa4c60ae740427e 100644
--- a/Makefile
+++ b/Makefile
@@ -1,30 +1,35 @@
-SUBDIRS=compiler lib test examples
+SUBDIRS=compiler lib test examples packaging
 export LABCOMM_JAR=$(shell pwd)/compiler/labcomm_compiler.jar
 export LABCOMM=java -jar $(LABCOMM_JAR) 
 
-all: $(SUBDIRS:%=make-%)
+.PHONY: all
+all: $(SUBDIRS:%=all-%)
 
-.PHONY: make-%
-make-%:
-	LD_LIBRARY_PATH=`pwd`/lib/c $(MAKE) -C $* -e 
+.PHONY: all-%
+all-%:
+	LD_LIBRARY_PATH=`pwd`/lib/c $(MAKE) -C $*
 
 .PHONY: test
 test: $(SUBDIRS:%=test-%)
 
 .PHONY: test-%
 test-%:
-	LD_LIBRARY_PATH=`pwd`/lib/c $(MAKE) -C $* -e test
+	LD_LIBRARY_PATH=`pwd`/lib/c $(MAKE) -C $* test
 
 .PHONY: clean
 clean: $(SUBDIRS:%=clean-%)
 
 .PHONY: clean-%
 clean-%:
-	$(MAKE) -C $* -e clean
+	$(MAKE) -C $* clean
 
 .PHONY: distclean
-distclean: $(SUBDIRS:%=distclean-%)
+distclean: clean $(SUBDIRS:%=distclean-%)
 
 .PHONY: distclean-%
 distclean-%:
-	$(MAKE) -C $* -e distclean
+	$(MAKE) -C $* distclean
+
+.PHONY: srpm
+srpm:
+	make -C packaging $@
diff --git a/compiler/.gitignore b/compiler/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..fb3995c874769be543f53f991762b1b77c16fc06
--- /dev/null
+++ b/compiler/.gitignore
@@ -0,0 +1,4 @@
+gen
+labcomm2006_compiler.jar
+labcomm2014_compiler.jar
+labcomm_compiler.jar
diff --git a/compiler/2006/C_CodeGen.jrag b/compiler/2006/C_CodeGen.jrag
index 26346d4f2c6e7f83766288a0a71650be84602f08..2fd45b192385847e511939149846d5e1a5c5651e 100644
--- a/compiler/2006/C_CodeGen.jrag
+++ b/compiler/2006/C_CodeGen.jrag
@@ -187,8 +187,8 @@ aspect C_CodeGen {
     out.println("*/");
     env.println("");
     env.println("");
-    env.println("#ifndef __LABCOMM_" + env.lcName + "_H__"); 
-    env.println("#define __LABCOMM_" + env.lcName + "_H__");
+    env.println("#ifndef __LABCOMM2006_" + env.lcName + "_H__"); 
+    env.println("#define __LABCOMM2006_" + env.lcName + "_H__");
     env.println("");
 
     // Include
@@ -270,18 +270,20 @@ aspect C_Type {
   }
 
   public void TypeDecl.C_emitType(C_env env) {
-    env.println("#ifndef PREDEFINED_" + env.prefix + getName());
+    env.println("#ifndef LABCOMM_DEFINED_" + env.prefix + getName());
     env.print("typedef ");
     getType().C_emitType(env, env.prefix + getName());
     env.println(";");
+    env.println("#define LABCOMM_DEFINED_" + env.prefix + getName());
     env.println("#endif");
   }
 
   public void SampleDecl.C_emitType(C_env env) {
-    env.println("#ifndef PREDEFINED_" + env.prefix + getName());
+    env.println("#ifndef LABCOMM_DEFINED_" + env.prefix + getName());
     env.print("typedef ");
     getType().C_emitType(env, env.prefix + getName());
     env.println(";");
+    env.println("#define LABCOMM_DEFINED_" + env.prefix + getName());
     env.println("#endif");
     env.println("extern const struct labcomm"+env.verStr+"_signature " +
                 "*labcomm"+env.verStr+"_signature_" + env.prefix + getName() + 
@@ -1143,9 +1145,6 @@ aspect C_Encoder {
     env.println(")");
     env.println("{");
     env.indent();
-    C_emitUserTypeDeps(env, null, false); //XXX HERE BE DRAGONS
-                                          //currently set to false to turn off
-                                          //outputting of code
     env.println("return labcomm"+env.verStr+"_internal_encoder_register(");
     env.indent();
     env.println("e,");
@@ -1196,42 +1195,6 @@ aspect C_EncoderIoctl {
 
 }
 
-aspect C_TypeDependencies {
-  public void Decl.C_emitUserTypeDeps(C_env env, String via, boolean outputCode) {
-    if( hasDependencies() ) {
-        Iterator<Decl> it = type_dependencies().iterator();
-        while(it.hasNext()) {
-            Decl t = it.next();
-
-            t.C_emitUserTypeDeps(env, t.getName(), outputCode);
-            if(outputCode) {
-               System.out.println("Decl.C_emitUserTypeDeps registering "+t.getName());
-               env.println("labcomm"+env.verStr+"_encoder_register_"+env.prefix + t.getName()+"(e);");
-            } else {  // Just output a comment
-	        String refpath = (via == null) ? "directly" : "indirectly via "+via;
-	       env.println(" //Depends ("+refpath+") on "+t.getName() );
-            }
-        }
-    } 
-  }
-  public void Decl.C_emitUserTypeRefs(C_env env, String via, boolean outputCode) {
-    if( isReferenced() ) {
-        Iterator<Decl> it = type_references().iterator();
-        while(it.hasNext()) {
-            Decl t = it.next();
-
-            t.C_emitUserTypeRefs(env, t.getName(), outputCode);
-            if(outputCode) {
-               env.println("labcomm"+env.verStr+"_encoder_register_"+env.prefix + t.getName()+"(e);");
-            } else {  // Just output a comment
-	        String refpath = (via == null) ? "directly" : "indirectly via "+via;
-	       env.println(" //Is referenced ("+refpath+")  by "+t.getName() );
-            }
-        }
-    } 
-  }
-}
-
 aspect C_Signature {
 
   public void ASTNode.C_emitSignature(C_env env) {
diff --git a/compiler/2014/CS_CodeGen.jrag b/compiler/2014/CS_CodeGen.jrag
index e1da497f2601fa68727e527a94e6f90287e804df..69f50b6f98a488e197f9756b4420df0e5decdc4c 100644
--- a/compiler/2014/CS_CodeGen.jrag
+++ b/compiler/2014/CS_CodeGen.jrag
@@ -210,7 +210,7 @@ aspect CS_CodeGen {
       env.indent();
     }
     env.println("using System;");
-    env.println("using se.lth.control.labcomm;");
+    env.println("using se.lth.control.labcomm2014;");
     for (int i = 0; i < getNumDecl(); i++) {
       Decl d = getDecl(i);
       try {
diff --git a/compiler/2014/C_CodeGen.jrag b/compiler/2014/C_CodeGen.jrag
index b7aae053368fb4659ec23e4d363b7bdf52c083d9..9b7cac5c4da04e4260db1c02baff5b8e5fdd9663 100644
--- a/compiler/2014/C_CodeGen.jrag
+++ b/compiler/2014/C_CodeGen.jrag
@@ -192,7 +192,7 @@ aspect C_CodeGen {
     env.println("");
 
     // Include
-    env.println("#include \"labcomm"+env.verStr+".h\"");
+    env.println("#include \"labcomm2014.h\"");
     for (int i = 0 ; i < includes.size() ; i++) {
       env.println("#include \"" + includes.get(i) + "\"");
     }
@@ -208,8 +208,8 @@ aspect C_CodeGen {
     C_env env = new C_env("", lcName, prefix, out, version);
 
     // Include
-    env.println("#include \"labcomm"+env.verStr+".h\"");
-    env.println("#include \"labcomm"+env.verStr+"_private.h\"");
+    env.println("#include \"labcomm2014.h\"");
+    env.println("#include \"labcomm2014_private.h\"");
     for (int i = 0 ; i < includes.size() ; i++) {
       env.println("#include \"" + includes.get(i) + "\"");
     }
@@ -270,21 +270,23 @@ aspect C_Type {
   }
 
   public void TypeDecl.C_emitType(C_env env) {
-    env.println("#ifndef PREDEFINED_" + env.prefix + getName());
+    env.println("#ifndef LABCOMM_DEFINED_" + env.prefix + getName());
     env.print("typedef ");
     getType().C_emitType(env, env.prefix + getName());
     env.println(";");
+    env.println("#define LABCOMM_DEFINED_" + env.prefix + getName());
     env.println("#endif");
   }
 
   public void SampleDecl.C_emitType(C_env env) {
-    env.println("#ifndef PREDEFINED_" + env.prefix + getName());
+    env.println("#ifndef LABCOMM_DEFINED_" + env.prefix + getName());
     env.print("typedef ");
     getType().C_emitType(env, env.prefix + getName());
     env.println(";");
+    env.println("#define LABCOMM_DEFINED_" + env.prefix + getName());
     env.println("#endif");
-    env.println("extern const struct labcomm"+env.verStr+"_signature " +
-                "*labcomm"+env.verStr+"_signature_" + env.prefix + getName() + 
+    env.println("extern const struct labcomm2014_signature " +
+                "*labcomm2014_signature_" + env.prefix + getName() + 
                 ";");
   }
 
@@ -309,7 +311,7 @@ aspect C_Type {
       case LABCOMM_DOUBLE: { env.print("double"); } break;
       case LABCOMM_STRING: { env.print("char*"); } break;
       case LABCOMM_SAMPLE: { 
-        env.print("const struct labcomm_signature *"); 
+        env.print("const struct labcomm2014_signature *"); 
       } break;
     }
     env.print(" " + name);
@@ -381,10 +383,10 @@ aspect C_Declarations {
   }
 
   public void SampleDecl.C_emitDecoderDeclaration(C_env env) {
-    env.println("int labcomm"+env.verStr+"_decoder_register_" + 
+    env.println("int labcomm2014_decoder_register_" + 
 		env.prefix + getName() + "(");
     env.indent();
-    env.println("struct labcomm"+env.verStr+"_decoder *d,");
+    env.println("struct labcomm2014_decoder *d,");
     env.println("void (*handler)(");
     env.indent();
     env.println(env.prefix + getName() + " *v,");
@@ -395,9 +397,9 @@ aspect C_Declarations {
     env.unindent();
     env.println(");");
 
-    env.println("int labcomm"+env.verStr+"_decoder_ioctl_" + env.prefix + getName() + "(");
+    env.println("int labcomm2014_decoder_ioctl_" + env.prefix + getName() + "(");
     env.indent();
-    env.println("struct labcomm"+env.verStr+"_decoder *d,");
+    env.println("struct labcomm2014_decoder *d,");
     env.println("int ioctl_action,");
     env.println("...");
     env.unindent();
@@ -406,26 +408,26 @@ aspect C_Declarations {
   
   public void Decl.C_emitEncoderDeclaration(C_env env) {
   }
-//
+
   public void SampleDecl.C_emitEncoderDeclaration(C_env env) {
-    env.println("int labcomm"+env.verStr+"_encoder_register_" + 
+    env.println("int labcomm2014_encoder_register_" + 
 		env.prefix + getName() + "(");
     env.indent();
-    env.println("struct labcomm"+env.verStr+"_encoder *e);");
+    env.println("struct labcomm2014_encoder *e);");
     env.unindent();
 
-    env.println("int labcomm"+env.verStr+"_encode_" + env.prefix + getName() + "(");
+    env.println("int labcomm2014_encode_" + env.prefix + getName() + "(");
     env.indent();
-    env.println("struct labcomm"+env.verStr+"_encoder *e");
+    env.println("struct labcomm2014_encoder *e");
     if(!isVoid() ) {
         env.println(", "+env.prefix + getName() + " *v");
     }
     env.unindent();
     env.println(");");
 
-    env.println("int labcomm"+env.verStr+"_encoder_ioctl_" + env.prefix + getName() + "(");
+    env.println("int labcomm2014_encoder_ioctl_" + env.prefix + getName() + "(");
     env.indent();
-    env.println("struct labcomm"+env.verStr+"_encoder *e,");
+    env.println("struct labcomm2014_encoder *e,");
     env.println("int ioctl_action,");
     env.println("...");
     env.unindent();
@@ -487,7 +489,7 @@ aspect C_Decoder {
     env = env.nestStruct("v");
     env.println("static void decode_" + env.prefix + getName() + "(");
     env.indent();
-    env.println("struct labcomm"+env.verStr+"_reader *r,");
+    env.println("struct labcomm2014_reader *r,");
     env.println("void (*handle)(");
     env.indent();
     env.println(env.prefix + getName() + " *v,");
@@ -526,11 +528,11 @@ aspect C_Decoder {
     env.print(env.qualid + " = ");
     switch (getToken()) {
       case LABCOMM_SAMPLE: { 
-        env.println("labcomm_internal_decoder_index_to_signature(" +
-                    "r->decoder, labcomm"+env.verStr+"_read_int(r));");
+        env.println("labcomm2014_internal_decoder_index_to_signature(" +
+                    "r->decoder, labcomm2014_read_int(r));");
       } break;
       default: {
-        env.println("labcomm"+env.verStr+"_read_" + getName() + "(r);");
+        env.println("labcomm2014_read_" + getName() + "(r);");
       }; break;
     }
   }
@@ -578,7 +580,7 @@ aspect C_Decoder {
   }
 
   public void VariableSize.C_emitDecoderDecodeLimit(C_env env, int i) {
-    env.println(env.qualid + ".n_" + i + " = labcomm"+env.verStr+"_read_packed32(r);");
+    env.println(env.qualid + ".n_" + i + " = labcomm2014_read_packed32(r);");
   }
 
   public void ArrayType.C_emitDecoderDecodeLimit(C_env env) {
@@ -592,7 +594,7 @@ aspect C_Decoder {
 
   public void VariableArrayType.C_emitDecoderArrayAllocate(C_env env) {
     env.print(env.qualid + 
-              ".a = labcomm"+env.verStr+"_memory_alloc(r->memory, 1, sizeof(" + 
+              ".a = labcomm2014_memory_alloc(r->memory, 1, sizeof(" + 
 	      env.qualid + ".a[0])");
     for (int i = 0 ; i < getNumExp() ; i++) {
       env.print(" * " + getExp(i).C_getLimit(env, i));
@@ -610,7 +612,7 @@ aspect C_Decoder {
 
   public void PrimType.C_emitDecoderDeallocation(C_env env) {
     if (C_isDynamic()) {
-      env.println("labcomm"+env.verStr+"_memory_free(r->memory, 1, " + 
+      env.println("labcomm2014_memory_free(r->memory, 1, " + 
                   env.qualid + ");");
     }
   }
@@ -656,7 +658,7 @@ aspect C_Decoder {
 
   public void VariableArrayType.C_emitDecoderDeallocation(C_env env) {
     super.C_emitDecoderDeallocation(env);
-    env.println("labcomm"+env.verStr+"_memory_free(r->memory, 1, " + 
+    env.println("labcomm2014_memory_free(r->memory, 1, " + 
                 env.qualid + ".a);");
   }
 
@@ -674,10 +676,10 @@ aspect C_Decoder {
   }
 
   public void SampleDecl.C_emitDecoderRegisterHandler(C_env env) {
-    env.println("int labcomm"+env.verStr+"_decoder_register_" + 
+    env.println("int labcomm2014_decoder_register_" + 
 		env.prefix + getName() + "(");
     env.indent();
-    env.println("struct labcomm"+env.verStr+"_decoder *d,");
+    env.println("struct labcomm2014_decoder *d,");
     env.println("void (*handler)(");
     env.indent();
     env.println(env.prefix + getName() + " *v,");
@@ -689,12 +691,12 @@ aspect C_Decoder {
     env.println(")");
     env.println("{");
     env.indent();
-    env.println("return labcomm"+env.verStr+"_internal_decoder_register(");
+    env.println("return labcomm2014_internal_decoder_register(");
     env.indent();
     env.println("d,");
     env.println("&signature_" + env.prefix + getName() + ",");
-    env.println("(labcomm"+env.verStr+"_decoder_function)decode_" + env.prefix + getName() + ",");
-    env.println("(labcomm"+env.verStr+"_handler_function)handler,");
+    env.println("(labcomm2014_decoder_function)decode_" + env.prefix + getName() + ",");
+    env.println("(labcomm2014_handler_function)handler,");
     env.println("context");
     env.unindent();
     env.println(");");
@@ -709,10 +711,10 @@ aspect C_copy {
   private void SampleDecl.C_emitCopyFunctionParam(C_env env, String src,
 						  String dst)
   {
-    env.println("void labcomm" + env.verStr + "_copy_" +
+    env.println("void labcomm2014_copy_" +
                 env.prefix + getName() + "(");
     env.indent();
-    env.println("struct labcomm" + env.verStr + "_memory *mem,");
+    env.println("struct labcomm2014_memory *mem,");
     env.println(env.prefix + getName() + " *" + dst + ",");
     env.println(env.prefix + getName() + " *" + src);
     env.unindent();
@@ -763,9 +765,8 @@ aspect C_copy {
   public void PrimType.C_emitCopy(C_env env_src, C_env env_dst) {
     if (C_isDynamic()) {
       env_src.println(String.format(
-	  "%s%s = labcomm%s_memory_alloc(mem, 1, strlen(%s%s)+1);",
+	  "%s%s = labcomm2014_memory_alloc(mem, 1, strlen(%s%s)+1);",
 	  env_dst.accessor(), env_dst.qualid,
-          env_src.verStr,
 	  env_src.accessor(), env_src.qualid));
       env_src.println(String.format(
 	  "memcpy(%s%s, %s%s, strlen(%s%s)+1);",
@@ -841,8 +842,7 @@ aspect C_copy {
 							C_env env_dst)
   {
     env_src.print(env_dst.qualid + env_dst.memberAccessor() +
-                  "a = labcomm" + env_src.verStr +
-                  "_memory_alloc(mem, 1, sizeof(" +
+                  "a = labcomm2014_memory_alloc(mem, 1, sizeof(" +
 		  env_src.qualid + env_src.memberAccessor() + "a[0])");
     for (int i = 0 ; i < getNumExp() ; i++) {
       env_src.print(" * " + getExp(i).C_getLimit(env_src, i));
@@ -855,10 +855,10 @@ aspect C_copy {
   private void SampleDecl.C_emitCopyDeallocationFunctionParam(C_env env,
 							      String par)
   {
-    env.println("void labcomm" + env.verStr + "_copy_free_" +
+    env.println("void labcomm2014_copy_free_" +
                 env.prefix + getName() + "(");
     env.indent();
-    env.println("struct labcomm" + env.verStr + "_memory *mem,");
+    env.println("struct labcomm2014_memory *mem,");
     env.println(env.prefix + getName() + " *" + par);
     env.unindent();
     env.print(")");
@@ -905,7 +905,7 @@ aspect C_copy {
 
   public void PrimType.C_emitCopyDeallocation(C_env env) {
     if (C_isDynamic()) {
-      env.println("labcomm" + env.verStr + "_memory_free(mem, 1, " +
+      env.println("labcomm2014_memory_free(mem, 1, " +
                   env.accessor() + env.qualid + ");");
     }
   }
@@ -951,7 +951,7 @@ aspect C_copy {
 
   public void VariableArrayType.C_emitCopyDeallocation(C_env env) {
     super.C_emitCopyDeallocation(env);
-    env.println("labcomm" + env.verStr + "_memory_free(mem, 1, " +
+    env.println("labcomm2014_memory_free(mem, 1, " +
                 env.qualid + env.memberAccessor() + "a);");
   }
 
@@ -973,9 +973,9 @@ aspect C_DecoderIoctl {
   }
 
   public void SampleDecl.C_emitDecoderIoctl(C_env env) {
-    env.println("int labcomm"+env.verStr+"_decoder_ioctl_" + env.prefix + getName() + "(");
+    env.println("int labcomm2014_decoder_ioctl_" + env.prefix + getName() + "(");
     env.indent();
-    env.println("struct labcomm"+env.verStr+"_decoder *d,");
+    env.println("struct labcomm2014_decoder *d,");
     env.println("int ioctl_action,");
     env.println("...");
     env.unindent();
@@ -985,7 +985,7 @@ aspect C_DecoderIoctl {
     env.println("int result;");
     env.println("va_list va;");
     env.println("va_start(va, ioctl_action);");
-    env.println("result = labcomm"+env.verStr+"_internal_decoder_ioctl(");
+    env.println("result = labcomm2014_internal_decoder_ioctl(");
     env.indent();
     env.println("d, &signature_" + env.prefix + getName() + ", ");
     env.println("ioctl_action, va);");
@@ -1014,7 +1014,7 @@ aspect C_Encoder {
     env = env.nestStruct("(*v)");
     env.println("static int encode_" + env.prefix + getName() + "(");
     env.indent();
-    env.println("struct labcomm"+env.verStr+"_writer *w");
+    env.println("struct labcomm2014_writer *w");
     if(!isVoid() ) {
         env.println(", "+env.prefix + getName() + " *v");
     }
@@ -1029,8 +1029,8 @@ aspect C_Encoder {
     env.println("}");
 
     // Typesafe encode wrapper
-    env.println("int labcomm"+env.verStr+"_encode_" + env.prefix + getName() + "(");
-    env.println("struct labcomm"+env.verStr+"_encoder *e");
+    env.println("int labcomm2014_encode_" + env.prefix + getName() + "(");
+    env.println("struct labcomm2014_encoder *e");
     if(!isVoid() ) {
         env.println(", "+env.prefix + getName() + " *v");
     }
@@ -1038,9 +1038,9 @@ aspect C_Encoder {
     env.println(")");
     env.println("{");
     env.indent();
-    env.println("return labcomm"+env.verStr+"_internal_encode(e, &signature_" + 
+    env.println("return labcomm2014_internal_encode(e, &signature_" + 
 		env.prefix + getName() + 
-		", (labcomm"+env.verStr+"_encoder_function)encode_" + 
+		", (labcomm2014_encoder_function)encode_" + 
                 env.prefix + getName() +
 		(!isVoid()?", v":", NULL")+");");
     env.unindent();
@@ -1061,12 +1061,12 @@ aspect C_Encoder {
     env.print("result = ");
     switch (getToken()) {
       case LABCOMM_SAMPLE: { 
-        env.println("labcomm"+env.verStr+"_write_int(w, " + 
-                    "labcomm_internal_encoder_signature_to_index(w->encoder, " +
+        env.println("labcomm2014_write_int(w, " + 
+                    "labcomm2014_internal_encoder_signature_to_index(w->encoder, " +
                     env.qualid + "));");
       } break;
       default: {
-        env.println("labcomm"+env.verStr+"_write_" + getName() + 
+        env.println("labcomm2014_write_" + getName() + 
                     "(w, " + env.qualid + ");");
       } break;
     }
@@ -1115,7 +1115,7 @@ aspect C_Encoder {
   }
 
   public void VariableSize.C_emitEncoderEncodeLimit(C_env env, int i) {
-    env.println("labcomm"+env.verStr+"_write_packed32(w, " + env.qualid + ".n_" + i + ");");
+    env.println("labcomm2014_write_packed32(w, " + env.qualid + ".n_" + i + ");");
   }
 
   public void ArrayType.C_emitEncoderEncodeLimit(C_env env) {
@@ -1130,15 +1130,43 @@ aspect C_Encoder {
   		    " not declared");
   }
   
+  protected void Decl.C_emitEncoderTypeRegister(C_env env) {
+    env.println("int labcomm2014_encoder_type_register_" + 
+		env.prefix + getName() + "(");
+    env.indent();
+    env.println("struct labcomm2014_encoder *e");
+    env.unindent();
+    env.println(")");
+    env.println("{");
+    env.indent();
+    env.println("//TODO: add error handling for dependencies");
+
+    C_emitUserTypeDeps(env, null, true); 
+
+    if(!isSampleDecl() || hasDependencies()) {
+      env.println("return labcomm2014_internal_encoder_type_register(");
+      env.indent();
+      env.println("e,");
+      env.println("&signature_" + env.prefix + getName() + "");
+      env.unindent();
+      env.println(");");
+    } else {
+      env.println("// the type has no dependencies, do nothing");
+      env.println("return 0;");
+    }
+    env.unindent();
+    env.println("}");
+  }
   public void TypeDecl.C_emitEncoderRegisterHandler(C_env env) {
-    // do nothing for type decls
+    C_emitEncoderTypeRegister(env);
   }
   
   public void SampleDecl.C_emitEncoderRegisterHandler(C_env env) {
-    env.println("int labcomm"+env.verStr+"_encoder_register_" + 
+    C_emitEncoderTypeRegister(env);
+    env.println("int labcomm2014_encoder_register_" + 
 		env.prefix + getName() + "(");
     env.indent();
-    env.println("struct labcomm"+env.verStr+"_encoder *e");
+    env.println("struct labcomm2014_encoder *e");
     env.unindent();
     env.println(")");
     env.println("{");
@@ -1146,17 +1174,28 @@ aspect C_Encoder {
     C_emitUserTypeDeps(env, null, false); //XXX HERE BE DRAGONS
                                           //currently set to false to turn off
                                           //outputting of code
-    env.println("return labcomm"+env.verStr+"_internal_encoder_register(");
+    env.println("int result = labcomm2014_internal_encoder_register(");
     env.indent();
     env.println("e,");
     env.println("&signature_" + env.prefix + getName() + ",");
-    env.println("(labcomm"+env.verStr+"_encoder_function)encode_" + env.prefix + getName());
+    env.println("(labcomm2014_encoder_function)encode_" + env.prefix + getName());
     env.unindent();
     env.println(");");
+    env.println("if(result >= 0) {\n");
+    env.indent();
+    env.println("labcomm2014_encoder_type_register_" + env.prefix + getName()+"(e);");
+    env.println("labcomm2014_internal_encoder_type_bind(");
+    env.indent();
+    env.println("e,");
+    env.println("&signature_" + env.prefix + getName() + ",");
+    env.println( (hasDependencies() ? "1" : "0")  + ");");
+    env.unindent();
+    env.println("}");
+    env.unindent();
+    env.println("return result;");
     env.unindent();
     env.println("}");
   }
-
 }
 
 aspect C_EncoderIoctl {
@@ -1171,9 +1210,9 @@ aspect C_EncoderIoctl {
   }
 
   public void SampleDecl.C_emitEncoderIoctl(C_env env) {
-    env.println("int labcomm"+env.verStr+"_encoder_ioctl_" + env.prefix + getName() + "(");
+    env.println("int labcomm2014_encoder_ioctl_" + env.prefix + getName() + "(");
     env.indent();
-    env.println("struct labcomm"+env.verStr+"_encoder *e,");
+    env.println("struct labcomm2014_encoder *e,");
     env.println("int ioctl_action,");
     env.println("...");
     env.unindent();
@@ -1183,7 +1222,7 @@ aspect C_EncoderIoctl {
     env.println("int result;");
     env.println("va_list va;");
     env.println("va_start(va, ioctl_action);");
-    env.println("result = labcomm"+env.verStr+"_internal_encoder_ioctl(");
+    env.println("result = labcomm2014_internal_encoder_ioctl(");
     env.indent();
     env.println("e, &signature_" + env.prefix + getName() + ", ");
     env.println("ioctl_action, va);");
@@ -1205,8 +1244,7 @@ aspect C_TypeDependencies {
 
             t.C_emitUserTypeDeps(env, t.getName(), outputCode);
             if(outputCode) {
-               System.out.println("Decl.C_emitUserTypeDeps registering "+t.getName());
-               env.println("labcomm"+env.verStr+"_encoder_register_"+env.prefix + t.getName()+"(e);");
+               env.println("labcomm2014_encoder_type_register_"+env.prefix + t.getName()+"(e);");
             } else {  // Just output a comment
 	        String refpath = (via == null) ? "directly" : "indirectly via "+via;
 	       env.println(" //Depends ("+refpath+") on "+t.getName() );
@@ -1214,6 +1252,7 @@ aspect C_TypeDependencies {
         }
     } 
   }
+
   public void Decl.C_emitUserTypeRefs(C_env env, String via, boolean outputCode) {
     if( isReferenced() ) {
         Iterator<Decl> it = type_references().iterator();
@@ -1222,7 +1261,7 @@ aspect C_TypeDependencies {
 
             t.C_emitUserTypeRefs(env, t.getName(), outputCode);
             if(outputCode) {
-               env.println("labcomm"+env.verStr+"_encoder_register_"+env.prefix + t.getName()+"(e);");
+               env.println("labcomm2014_encoder_type_register_"+env.prefix + t.getName()+"(e);");
             } else {  // Just output a comment
 	        String refpath = (via == null) ? "directly" : "indirectly via "+via;
 	       env.println(" //Is referenced ("+refpath+")  by "+t.getName() );
@@ -1245,26 +1284,15 @@ aspect C_Signature {
   eq TypeDecl.C_DeclTypeString() = "LABCOMM_TYPEDEF";
 
   public void Decl.C_emitSignature(C_env env) {
-    C_emitFlatSignature(env);
-//
-//  if( false && (isReferenced() || isSampleDecl())){ 
-//    Signature signature = getSignature();
-//    signature.C_emitSignature(env, !isSampleDecl());
-//  } else {
-//    env.println("// not emitting signature for "+getName()+isReferenced()+isSampleDecl());  
-//  }
-//  if(env.versionHasMetaData()) { 
-//    if(isReferenced() || isSampleDecl()){
-//        env.println("(int (*)(void *))labcomm"+env.verStr+"_signature_" + 
-//	 	env.prefix + getName() + "_emit_signature");
-//    } else {
-//        env.println("NULL");  // HERE BE DRAGONS! Is it worth the size saving to skip emitting the emit_signature function for unused types?
-//                              //                  The code won't likely end up in a target system anyway?
-//    }
-//  }
-//  env.unindent();
-//  env.println(" };");
-//
+    if( (true || isReferenced() || isSampleDecl())){
+      Signature signature = getSignature();
+      signature.C_emitSignature(env, !isSampleDecl());
+      C_emitFlatSignature(env);
+    } else {
+      env.println("// not emitting signature for " + getName() +
+                  "referenced=" + isReferenced() +
+                  "sampledecl=" + isSampleDecl());
+    }
   }
 
   public void ASTNode.C_emitFlatSignature(C_env env) {
@@ -1273,7 +1301,25 @@ aspect C_Signature {
                     " not declared");
   }
 
-  public void Decl.C_emitFlatSignature(C_env env) {
+  public void TypeDecl.C_emitFlatSignature(C_env env) {
+    C_emitSizeofValue(env);
+    env.println("static struct labcomm2014_signature " +
+                "signature_" + env.prefix + getName() + " = {");
+    env.indent();
+    env.println("\"" + getName() + "\",");
+    //env.println("sizeof_" + env.prefix + getName() + ",");
+    //HERE BE DRAGONS? do we need sizeof for typedefs?
+    env.println("NULL,");
+    env.println("0,");
+    env.println("NULL,");
+    env.println("0,"); // index
+    env.println("sizeof(signature_tree_" + env.prefix + getName() + "),");
+    env.println("signature_tree_" + env.prefix + getName() + "");
+    env.unindent();
+    env.println(" };");
+    env.println("const struct labcomm2014_signature " +
+                "*labcomm2014_signature_" + env.prefix + getName() + 
+                " = &signature_" + env.prefix + getName() + ";");
   }
 
   public void SampleDecl.C_emitFlatSignature(C_env env){
@@ -1297,18 +1343,20 @@ aspect C_Signature {
     env.println("};");
 
     C_emitSizeofValue(env);
-    env.println("static struct labcomm"+env.verStr+"_signature " +
+    env.println("static struct labcomm2014_signature " +
                 "signature_" + env.prefix + getName() + " = {");
     env.indent();
     env.println("\"" + getName() + "\",");
     env.println("sizeof_" + env.prefix + getName() + ",");
     env.println("sizeof(signature_bytes_" + env.prefix + getName() + "),");
     env.println("signature_bytes_" + env.prefix + getName() + ",");
-    env.println("0");
+    env.println("0,"); // index
+    env.println("sizeof(signature_tree_" + env.prefix + getName() + "),");
+    env.println("signature_tree_" + env.prefix + getName() + "");
     env.unindent();
     env.println(" };");
-    env.println("const struct labcomm"+env.verStr+"_signature " +
-                "*labcomm"+env.verStr+"_signature_" + env.prefix + getName() + 
+    env.println("const struct labcomm2014_signature " +
+                "*labcomm2014_signature_" + env.prefix + getName() + 
                 " = &signature_" + env.prefix + getName() + ";");
   }
 
@@ -1319,28 +1367,29 @@ aspect C_Signature {
     public abstract void SignatureLine.C_emitSignature(C_env env, boolean decl);
 
     public void TypeRefSignatureLine.C_emitSignature(C_env env, boolean isDecl){ 
-      //env.print(getIndentString());
-      //env.println("LABCOMM_SIGDEF_SIGNATURE(labcomm"+env.verStr+"_signature_" + env.prefix + decl.getName() +"),");
+      env.print(getIndentString());
+    //  env.println("LABCOMM_SIGDEF_SIGNATURE(labcomm2014_signature_" + env.prefix + decl.getName() +"),");
+      env.println("LABCOMM_SIGDEF_SIGNATURE(signature_" + env.prefix + decl.getName() +"),");
     }
 
     public void DataSignatureLine.C_emitSignature(C_env env, boolean decl){ 
-       //   String comment = getComment();
-       //   if (comment != null && comment.length() > 0) {
-       //     env.println(getIndentString() + "// " + comment);
-       //   }
-       //   byte[] data = getData(env.version);
-       //   if (data != null && data.length > 0) {
-       //     env.print(getIndentString());
-       //     env.print("LABCOMM_SIGDEF_BYTES("+data.length+", \"");
-       //     for (int j = 0 ; j < data.length ; j++) {
-       //       byte d = data[j];
-       //       //if(d>='a'&&d<='z' || d>='A'&&d<='Z'|| d>='0'&&d<='9'  )
-       //       //  env.print(""+(char)d);
-       //       //else
-       //       env.print("\\x"+Integer.toHexString(d));
-       //     }
-       //     env.println("\"),");
-       // }
+          String comment = getComment();
+          if (comment != null && comment.length() > 0) {
+            env.println(getIndentString() + "// " + comment);
+          }
+          byte[] data = getData(env.version);
+          if (data != null && data.length > 0) {
+            env.print(getIndentString());
+            env.print("LABCOMM_SIGDEF_BYTES("+data.length+", \"");
+            for (int j = 0 ; j < data.length ; j++) {
+              byte d = data[j];
+              //if(d>='a'&&d<='z' || d>='A'&&d<='Z'|| d>='0'&&d<='9'  )
+              //  env.print(""+(char)d);
+              //else
+              env.print("\\x"+Integer.toHexString(d));
+            }
+            env.println("\"),");
+        }
     }
 //
 //
@@ -1348,8 +1397,8 @@ aspect C_Signature {
 //        if (data != null) {
 //            for (int j = 0 ; j < data.length ; j++) {
 //                env.print(getIndentString());
-//                //env.print("printf(\"labcomm"+env.verStr+"_write_byte( w, (unsigned char)"+ String.format("0x%02X ", data[j]) +")\\n\"); ");
-//                env.print("labcomm"+env.verStr+"_write_byte( w, (unsigned char)"+ String.format("0x%02X ", data[j]) +"); ");
+//                //env.print("printf(\"labcomm2014_write_byte( w, (unsigned char)"+ String.format("0x%02X ", data[j]) +")\\n\"); ");
+//                env.print("labcomm2014_write_byte( w, (unsigned char)"+ String.format("0x%02X ", data[j]) +"); ");
 //                env.println("if (result != 0) { return result; }");
 //            }
 //            env.println();
@@ -1357,18 +1406,18 @@ aspect C_Signature {
 //
 //}
   public void SignatureList.C_emitSignature(C_env env, boolean decl) { 
-//  env.println("static struct labcomm_signature_data signature_tree_" + 
-//  	 env.prefix + parentDecl().getName() + "[] = {");
-//  env.indent();
-//  for (int i = 0 ; i < size() ; i++) {
-//    SignatureLine l = getSignatureLine(i);
-//    l.C_emitSignature(env, decl);
-//  }
-//  
-//  env.println("LABCOMM_SIGDEF_END");
-//  env.println("};");
-//  env.unindent();
-//  env.println();
+  env.println("static struct labcomm2014_signature_data signature_tree_" + 
+  	 env.prefix + parentDecl().getName() + "[] = {");
+  env.indent();
+  for (int i = 0 ; i < size() ; i++) {
+    SignatureLine l = getSignatureLine(i);
+    l.C_emitSignature(env, decl);
+  }
+  
+  env.println("LABCOMM_SIGDEF_END");
+  env.println("};");
+  env.unindent();
+  env.println();
   }
 
 
@@ -1392,11 +1441,11 @@ aspect C_Signature {
 //      }
 //    }
 //    env.println("};");
-//    env.println("struct labcomm"+env.verStr+"_signature labcomm"+env.verStr+"_signature_" + 
+//    env.println("struct labcomm2014_signature labcomm2014_signature_" + 
 //		env.prefix + getName() + " = {");
 //    env.indent();
 //    env.println("LABCOMM_SAMPLE, \"" + getName() + "\",");
-//    env.println("(int (*)(struct labcomm"+env.verStr+"_signature *, void *))labcomm"+env.verStr+"_sizeof_" + 
+//    env.println("(int (*)(struct labcomm2014_signature *, void *))labcomm2014_sizeof_" + 
 //		env.prefix + getName() + ",");
 //    env.println("sizeof(signature_bytes_" + env.prefix + getName() + "),");
 //    env.println("signature_bytes_" + env.prefix + getName() + ",");
@@ -1431,11 +1480,15 @@ aspect C_Constructor {
     env.println("}"); 
   }
 
-  public void Decl.C_emitConstructor(C_env env) {
+  public void TypeDecl.C_emitConstructor(C_env env) {
+    if (isReferenced()) {
+      env.println("labcomm2014_set_local_index(&signature_" +
+                  env.prefix + getName() + ");");
+    }
   }
-//XXX
+
   public void SampleDecl.C_emitConstructor(C_env env) {
-    env.println("labcomm"+env.verStr+"_set_local_index(&signature_" + 
+    env.println("labcomm2014_set_local_index(&signature_" + 
 		env.prefix + getName() + ");");
   }
 
@@ -1458,7 +1511,7 @@ aspect C_Sizeof {
   }
 
   public void SampleDecl.C_emitSizeofDeclaration(C_env env) {
-    env.println("extern int labcomm"+env.verStr+"_sizeof_" + env.prefix + getName() +
+    env.println("extern int labcomm2014_sizeof_" + env.prefix + getName() +
         "(" + env.prefix + getName() + " *v);");
   }
 
@@ -1471,11 +1524,11 @@ aspect C_Sizeof {
 
   public void SampleDecl.C_emitSizeof(C_env env) {
     env = env.nestStruct("(*v)");
-    env.println("int labcomm"+env.verStr+"_sizeof_" + env.prefix + getName() +
+    env.println("int labcomm2014_sizeof_" + env.prefix + getName() +
         "(" + env.prefix + getName() + " *v)");
     env.println("{");
     env.indent();
-    env.println("return labcomm"+env.verStr+"_internal_sizeof(" +
+    env.println("return labcomm2014_internal_sizeof(" +
                 "&signature_" + env.prefix + getName() +
                 ", v);");
     env.unindent();
@@ -1561,7 +1614,7 @@ aspect C_Sizeof {
     switch (getToken()) {
       case LABCOMM_STRING: { 
         env.print("{ int l = strlen(" + env.qualid + "); ");
-    env.println("result += labcomm"+env.verStr+"_size_packed32(l) + l; }"); 
+    env.println("result += labcomm2014_size_packed32(l) + l; }"); 
       } break;
       default: { 
     throw new Error(this.getClass().getName() + 
@@ -1594,7 +1647,7 @@ aspect C_Sizeof {
   }
 
   public void VariableSize.C_emitSizeof(C_env env, int i) {
-    env.println("result += labcomm"+env.verStr+"_size_packed32(" + 
+    env.println("result += labcomm2014_size_packed32(" + 
                 env.qualid + env.memberAccessor() + "n_" + i + ");");
   }
 
diff --git a/compiler/2014/FlatSignature.jrag b/compiler/2014/FlatSignature.jrag
index 2a9ca4dd9c48fadfabceecebf215e808d10e0597..b96c119ce386f0a0d2b7e9e2c1edb001050e5f27 100644
--- a/compiler/2014/FlatSignature.jrag
+++ b/compiler/2014/FlatSignature.jrag
@@ -21,9 +21,9 @@ aspect FlatSignature {
     getType().flatSignature(list);
   }
 
-  public void SampleRefType.flatSignature(SignatureList list) {
-    list.addInt(LABCOMM_SAMPLE_REF, "sample");
-  }
+//  public void SampleRefType.flatSignature(SignatureList list) {
+//    list.addInt(LABCOMM_SAMPLE_REF, "sample");
+//  }
 
   public void VoidType.flatSignature(SignatureList list) {
     list.addInt(LABCOMM_STRUCT, "void");
@@ -96,9 +96,9 @@ aspect FlatSignature {
     return getType().signatureComment() + " '" + getName() +"'";
   }
 
-  public String SampleRefType.signatureComment() {
-    return "sample";
-  }
+//  public String SampleRefType.signatureComment() {
+//    return "sample";
+//  }
 
   public String PrimType.signatureComment() {
     return getName();
diff --git a/compiler/2014/Java_CodeGen.jrag b/compiler/2014/Java_CodeGen.jrag
index 478a0ac4222f5cebdff8af2168197784e79543d8..cb0f6281c0cd375a0a356b081aa5607dc4e9a90b 100644
--- a/compiler/2014/Java_CodeGen.jrag
+++ b/compiler/2014/Java_CodeGen.jrag
@@ -79,7 +79,7 @@ aspect Java_CodeGenEnv {
 
     private Java_env(int version, int indent) {
       this.version = version;
-      this.verStr = LabCommVersion.versionString(version);
+      this.verStr = "2014";
       this.indent = indent;
     }
 
@@ -454,10 +454,10 @@ aspect Java_Class {
     env.println();
   }
 
-  //public void TypeDecl.Java_emitSignature(Java_env env) {
-  //  Signature signature = getSignature();
-  //  signature.Java_emitSignature(env, true);
-  //}
+  public void TypeDecl.Java_emitSignature(Java_env env) {
+    Signature signature = getSignature();
+    signature.Java_emitSignature(env, true);
+  }
 
   public void Decl.Java_emitSignature(Java_env env) {
     //always emit the flat signature, as it is needed
@@ -465,10 +465,10 @@ aspect Java_Class {
     //the type_ids of dependent types. Therefore, flat sigs
     //are used for matching
     Java_emitFlatSignature(env);
-    //if(isReferenced() || isSampleDecl()){
-    //  Signature signature = getSignature();
-    //  signature.Java_emitSignature(env, !isSampleDecl());
-    //}
+    if(isReferenced() || (isSampleDecl() && hasDependencies() )){
+      Signature signature = getSignature();
+      signature.Java_emitSignature(env, !isSampleDecl());
+    }
   }
 
   public void Decl.Java_emitFlatSignature(Java_env env){
@@ -497,7 +497,8 @@ aspect Java_Class {
 
   //XXX TODO: refactor: split into a static class ("TypeDefSingleton"?)and a (smaller) dispatcher
   public void Decl.Java_emitDispatcher(Java_env env, boolean isSample) {
-    String genericStr = ""; //env.versionHasMetaData()?"<"+getName()+">":""; 
+    // String genericStr = ""; //env.versionHasMetaData()?"<"+getName()+">":""; 
+    String genericStr = "<"+getName()+">"; 
     env.println("private static Dispatcher dispatcher = new Dispatcher();");
     env.println();
     env.println("public SampleDispatcher getDispatcher() {");
@@ -544,16 +545,20 @@ aspect Java_Class {
     env.println("return "+isSample+";");
     env.unindent();
     env.println("}");
-//    env.println("public boolean hasStaticSignature() {");
-//    env.indent();
-//    env.println("return "+!hasDependencies()+";");
-//    env.unindent();
-//    env.println("}");
+    env.println("public boolean hasDependencies() {");
+    env.indent();
+    env.println("return "+hasDependencies()+";");
+    env.unindent();
+    env.println("}");
     env.println();
     env.println("/** return the flat signature. */");
     env.println("public byte[] getSignature() {");
     env.indent();
-    env.println("return signature;");
+    if(isSample) {
+        env.println("return signature;");
+    } else {
+        env.println("throw new Error(\"a TYPE_DEF has no flat signature\");");
+    }
     env.unindent();
     env.println("}");
     env.println();
@@ -563,15 +568,16 @@ aspect Java_Class {
 //    env.unindent();
 //    env.println("}");
 //    env.println();
-//    env.println("public void encodeSignatureMetadata(Encoder e, int index) throws IOException{");
-//    env.indent();
-//    env.println("e.encodePacked32(Constant.TYPE_DEF);");
-//    env.println("e.encodePacked32(index);");
-//    env.println("e.encodeString(getName());");
-//    env.println("emitSignature(e);");
-//    env.unindent();
-//    env.println("}");
-//    env.println();
+    env.println("public void encodeTypeDef(Encoder e, int index) throws IOException{");
+    env.indent();
+    if(!isSample || hasDependencies()) {
+      env.println("emitSignature(e);");
+    } else {
+      env.println("// the type has no dependencies, do nothing");
+    }
+    env.unindent();
+    env.println("}");
+    env.println();
     env.println("public boolean canDecodeAndHandle() {");
     env.indent();
     env.println("return "+isSample+";");
diff --git a/compiler/2014/LabComm.ast b/compiler/2014/LabComm.ast
index 904cc17eb4fe26462b674394a81df391be9690dd..d3d5e592fc95cb38bf9fd3844d8b3ad2d3cb9081 100644
--- a/compiler/2014/LabComm.ast
+++ b/compiler/2014/LabComm.ast
@@ -1,39 +1,37 @@
 Program ::= Decl*;
 
-//TODO: Add signatures to the abstract grammar, so that
-//they can be extended and refined by more than one aspect.
-//sketch:
-Signature		::= SignatureList FlatSignatureList:SignatureList; 
-SignatureList		::= SignatureLine*;
-abstract SignatureLine 	::= <Indent:int> <Comment:String>; 
-abstract DataSignatureLine : SignatureLine;
-ByteArraySignatureLine : DataSignatureLine ::= <Data:byte[]>;
-IntSignatureLine : DataSignatureLine ::= <Data:int>;
-StringSignatureLine : DataSignatureLine ::= <Data:String>;
-TypeRefSignatureLine   	: SignatureLine ::= Decl;
-
-
-//abstract Decl ::= Type <Name:String>;
-// the signature list be defined as  a non-terminal attribute:
 abstract Decl ::= Type <Name:String> /Signature/;
-TypeDecl : Decl;
+
+TypeDecl   : Decl;
 SampleDecl : Decl;
 
+//Signatures are in the abstract grammar, so that
+//they can be extended and refined by aspects.
+
+Signature                 ::= SignatureList FlatSignatureList:SignatureList; 
+SignatureList             ::= SignatureLine*;
+abstract SignatureLine 	  ::= <Indent:int> <Comment:String>; 
+abstract DataSignatureLine : SignatureLine;
+ByteArraySignatureLine     : DataSignatureLine ::= <Data:byte[]>;
+IntSignatureLine           : DataSignatureLine ::= <Data:int>;
+StringSignatureLine        : DataSignatureLine ::= <Data:String>;
+TypeRefSignatureLine       : SignatureLine     ::= Decl;
+
 Field ::= Type <Name:String>;
 
 abstract Type;
-VoidType          : Type;
-SampleRefType     : Type;
-PrimType          : Type ::= <Name:String> <Token:int>;
-UserType          : Type ::= <Name:String>;
-StructType        : Type ::= Field*;
-ParseArrayType    : Type ::= Type Dim*;
-abstract ArrayType :Type ::= Type Exp*;
-VariableArrayType : ArrayType;
-FixedArrayType    : ArrayType;
+VoidType           : Type;
+//SampleRefType      : Type;
+PrimType           : Type ::= <Name:String> <Token:int>;
+UserType           : Type ::= <Name:String>;
+StructType         : Type ::= Field*;
+ParseArrayType     : Type ::= Type Dim*;
+abstract ArrayType : Type ::= Type Exp*;
+VariableArrayType  : ArrayType;
+FixedArrayType     : ArrayType;
 
 Dim ::= Exp*;
 
 abstract Exp;
 IntegerLiteral : Exp ::= <Value:String>;
-VariableSize : Exp;
+VariableSize   : Exp;
diff --git a/compiler/2014/PrettyPrint.jrag b/compiler/2014/PrettyPrint.jrag
index a7fa877109c55e7ad17f64ab1385f8d9638ad662..3808c952309d375c828023c199472d2e6b9e43de 100644
--- a/compiler/2014/PrettyPrint.jrag
+++ b/compiler/2014/PrettyPrint.jrag
@@ -68,9 +68,9 @@ aspect PrettyPrint {
     out.print("void");
   }
 
-  public void SampleRefType.ppPrefix(PrintStream out) { 
-    out.print("sample");
-  }
+//  public void SampleRefType.ppPrefix(PrintStream out) { 
+//    out.print("sample");
+//  }
 
   public void PrimType.ppPrefix(PrintStream out) { 
     out.print(getName());
diff --git a/compiler/2014/Python_CodeGen.jrag b/compiler/2014/Python_CodeGen.jrag
index 17203b88ea5c2c0e833c791f4036189f16bf8b46..f780c96206b3bc18dfaaabc562e2ceb62a2cbde7 100644
--- a/compiler/2014/Python_CodeGen.jrag
+++ b/compiler/2014/Python_CodeGen.jrag
@@ -80,24 +80,23 @@ aspect Python_CodeGen {
     env.println("#!/usr/bin/python");
     env.println("# Auto generated " + baseName);
     env.println();
-    env.println("import labcomm");
-    env.println("import StringIO");
+    env.println("import labcomm2014");
     env.println();
     Python_genTypes(env);
-    //env.println("typedef = [");
-    //env.indent();
-    //for (int i = 0 ; i < getNumDecl() ; i++) {
-    //  getDecl(i).Python_genTypedefListEntry(env);
-    //}
-    //env.unindent();
-    //env.println("]");
-    env.println("sample = [");
+    env.println("typedef = tuple([");
+    env.indent();
+    for (int i = 0 ; i < getNumDecl() ; i++) {
+      getDecl(i).Python_genTypedefListEntry(env);
+    }
+    env.unindent();
+    env.println("])");
+    env.println("sample = tuple([");
     env.indent();
     for (int i = 0 ; i < getNumDecl() ; i++) {
       getDecl(i).Python_genSampleListEntry(env);
     }
     env.unindent();
-    env.println("]");
+    env.println("])");
   }
 
 }
@@ -117,23 +116,21 @@ aspect PythonTypes {
   }
 
   public void TypeDecl.Python_genSignature(Python_env env) {
-/*
     env.println("class " + getName() + "(object):");
     env.indent();
-    env.println("signature = labcomm.typedef('" + getName() + "',");
+    env.println("signature = labcomm2014.typedef('" + getName() + "',");
     env.indent();
     getType().Python_genSignature(env);
     env.unindent();
     env.println(")");
     env.unindent();
     env.println();
-*/
   }
 
   public void SampleDecl.Python_genSignature(Python_env env) {
     env.println("class " + getName() + "(object):");
     env.indent();
-    env.println("signature = labcomm.sample('" + getName() + "', ");
+    env.println("signature = labcomm2014.sample('" + getName() + "', ");
     env.indent();
     getType().Python_genSignature(env);
     env.unindent();
@@ -143,7 +140,8 @@ aspect PythonTypes {
   }
 
   public void UserType.Python_genSignature(Python_env env) {
-    lookupType(getName()).getType().Python_genSignature(env);
+    env.println(getName() + ".signature");
+    // lookupType(getName()).getType().Python_genSignature(env);
   }
 
   public void Type.Python_genSignature(Python_env env) {
@@ -154,20 +152,20 @@ aspect PythonTypes {
 
   public void PrimType.Python_genSignature(Python_env env) {
     switch (getToken()) {
-      case LABCOMM_BOOLEAN: { env.print("labcomm.BOOLEAN()"); } break;
-      case LABCOMM_BYTE: { env.print("labcomm.BYTE()"); } break;
-      case LABCOMM_SHORT: { env.print("labcomm.SHORT()"); } break;
-      case LABCOMM_INT: { env.print("labcomm.INTEGER()"); } break;
-      case LABCOMM_LONG: { env.print("labcomm.LONG()"); } break;
-      case LABCOMM_FLOAT: { env.print("labcomm.FLOAT()"); } break;
-      case LABCOMM_DOUBLE: { env.print("labcomm.DOUBLE()"); } break;
-      case LABCOMM_STRING: { env.print("labcomm.STRING()"); } break;
-      case LABCOMM_SAMPLE: { env.print("labcomm.SAMPLE()"); } break;
+      case LABCOMM_BOOLEAN: { env.print("labcomm2014.BOOLEAN()"); } break;
+      case LABCOMM_BYTE: { env.print("labcomm2014.BYTE()"); } break;
+      case LABCOMM_SHORT: { env.print("labcomm2014.SHORT()"); } break;
+      case LABCOMM_INT: { env.print("labcomm2014.INTEGER()"); } break;
+      case LABCOMM_LONG: { env.print("labcomm2014.LONG()"); } break;
+      case LABCOMM_FLOAT: { env.print("labcomm2014.FLOAT()"); } break;
+      case LABCOMM_DOUBLE: { env.print("labcomm2014.DOUBLE()"); } break;
+      case LABCOMM_STRING: { env.print("labcomm2014.STRING()"); } break;
+      case LABCOMM_SAMPLE: { env.print("labcomm2014.SAMPLE()"); } break;
     }
   }
 
   public void ArrayType.Python_genSignature(Python_env env) {
-    env.print("labcomm.array([");
+    env.print("labcomm2014.array([");
     for (int i = 0 ; i < getNumExp() ; i++) {
       if (i > 0) { env.print(", "); }
       env.print(getExp(i).Python_getValue());
@@ -180,7 +178,7 @@ aspect PythonTypes {
   }
 
   public void StructType.Python_genSignature(Python_env env) {
-    env.println("labcomm.struct([");
+    env.println("labcomm2014.struct([");
     env.indent();
     for (int i = 0 ; i < getNumField() ; i++) {
       if (i > 0) { env.println(","); }
@@ -191,7 +189,7 @@ aspect PythonTypes {
   }
 
   public void VoidType.Python_genSignature(Python_env env) {
-    env.println("labcomm.struct([])");
+    env.println("labcomm2014.struct([])");
   }
 
   public void Field.Python_genSignature(Python_env env) {
@@ -204,14 +202,14 @@ aspect PythonTypes {
   }
 
   public void TypeDecl.Python_genTypedefListEntry(Python_env env) {
-    env.println("('" + getName() + "', " + getName() + ".signature),");
+    env.println(getName() + ",");
   }
 
   public void Decl.Python_genSampleListEntry(Python_env env) {
   }
 
   public void SampleDecl.Python_genSampleListEntry(Python_env env) {
-    env.println("('" + getName() + "', " + getName() + ".signature),");
+    env.println(getName()+ ",");
   }
 
   public String Exp.Python_getValue() {
diff --git a/compiler/2014/Signature.jrag b/compiler/2014/Signature.jrag
index 5395095487bde26c2df7a19b0ea4f452144995d9..b32e53580aa900e31357333904aeeb115180bcf0 100644
--- a/compiler/2014/Signature.jrag
+++ b/compiler/2014/Signature.jrag
@@ -158,7 +158,6 @@ aspect Signature {
   }
 
   public void TypeDecl.genSigLineForDecl(SignatureList list, boolean decl) {
-     //System.out.println("************ TypeDecl.genSigLine("+decl+").... for "+getName());
     if(decl){
       getType().genSigLineForDecl(list, decl);
     }else{
@@ -167,7 +166,6 @@ aspect Signature {
   }
 
   public void SampleDecl.genSigLineForDecl(SignatureList list, boolean decl) {
-     //System.out.println("************ SampleDecl.genSigLine("+decl+").... for "+getName());
     getType().genSigLineForDecl(list, decl);
   }
 
@@ -176,25 +174,20 @@ aspect Signature {
     list.addInt(0, null);
   }
 
-  public void SampleRefType.genSigLineForDecl(SignatureList list, boolean decl) {
-    list.addInt(LABCOMM_SAMPLE_REF, "sample");
-  }
+//  public void SampleRefType.genSigLineForDecl(SignatureList list, boolean decl) {
+//    list.addInt(LABCOMM_SAMPLE_REF, "sample");
+//  }
   public void PrimType.genSigLineForDecl(SignatureList list, boolean decl) {
     list.addInt(getToken(), null);
   }
 
+  /* For UserType, the decl parameter is ignored, as a UserType
+   * will always be a TypeRef
+   */
   public void UserType.genSigLineForDecl(SignatureList list, boolean decl) {
-    if(decl){
-     //System.out.println("************ UserType.genSigLine("+decl+").... for "+getName());
-      TypeDecl thet=lookupType(getName());
-      //System.out.println("************ thet: "+thet.getName() +":"+thet.getType());
-      thet.genSigLineForDecl(list, decl);
-    }else{
-     //System.out.println("************ UserType.genSigLine("+decl+").... for "+getName());
+      
       TypeDecl thet = lookupType(getName());
-     // System.out.println("************ thet: "+thet.getName() +":"+thet.getType());
       list.addTypeRef(thet, null);
-    }
   }
 
   public void ArrayType.genSigLineForDecl(SignatureList list, boolean decl) {
diff --git a/compiler/Makefile b/compiler/Makefile
index 24444404faab2dea0ba5243135daec08a28828f2..f9353420fff395a687f06dac758c2382c131f72a 100644
--- a/compiler/Makefile
+++ b/compiler/Makefile
@@ -1,4 +1,16 @@
-all: 
+.PHONY: all
+all: ant-all
 
-%:
+.PHONY: test
+test: ant-test
+
+.PHONY: clean
+clean: ant-clean
+	rm -f *~
+
+.PHONY: distclean
+distclean: clean
+
+.PHONY: ant-%
+ant-%:
 	ant $*
diff --git a/compiler/labcomm b/compiler/labcomm
new file mode 100755
index 0000000000000000000000000000000000000000..604b83a9e365b4a6dc36adc4faca54a3be2b2f1d
--- /dev/null
+++ b/compiler/labcomm
@@ -0,0 +1,2 @@
+#!/bin/sh
+java -jar /lib/labcomm_compiler.jar "$@"
diff --git a/compiler/labcomm2006 b/compiler/labcomm2006
new file mode 100755
index 0000000000000000000000000000000000000000..77c38e83155b13cda559d5a152dc3147e436c554
--- /dev/null
+++ b/compiler/labcomm2006
@@ -0,0 +1,2 @@
+#!/bin/sh
+java -jar /lib/labcomm2006_compiler.jar "$@"
diff --git a/compiler/labcomm2014 b/compiler/labcomm2014
new file mode 100755
index 0000000000000000000000000000000000000000..901a413a2575e4361fbdbd53925a9f4b9074f231
--- /dev/null
+++ b/compiler/labcomm2014
@@ -0,0 +1,2 @@
+#!/bin/sh
+java -jar /lib/labcomm2014_compiler.jar "$@"
diff --git a/doc/.gitignore b/doc/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..df2a6e60dbf0dc336f4bc67ea1ef1b99119b2bda
--- /dev/null
+++ b/doc/.gitignore
@@ -0,0 +1,7 @@
+tech_report.aux
+tech_report.bbl
+tech_report.blg
+tech_report.fdb_latexmk
+tech_report.fls
+tech_report.log
+tech_report.pdf
\ No newline at end of file
diff --git a/doc/tech_report.tex b/doc/tech_report.tex
index 244cdd1709754b17bef8146644af900739e897f9..651076d99809b5d5fd7068e1147f4b24ad6c4207 100644
--- a/doc/tech_report.tex
+++ b/doc/tech_report.tex
@@ -169,6 +169,22 @@ language covering most common use-cases.
   sample string a_string;
 \end{verbatim}
 
+\subsection{The void type}
+
+There is a type, \verb+void+, which can be used to send
+a sample that contains no data. 
+
+\begin{verbatim}
+typedef void an_empty_type;
+
+sample an_empty_type no_data1;
+sample void no_data2;
+\end{verbatim}
+
+\verb+void+ type can may not be used as a field in a struct or
+the element type of an array.
+
+
 \subsection{Arrays}
 
 \begin{verbatim}
@@ -198,7 +214,46 @@ only arrays of arrays.
   } a_struct;
 \end{verbatim}
 
-\section{User defined types}
+\subsection{Sample type refereces}
+
+In addition to the primitive types, a sample may contain
+a reference to a sample type. References are declared using
+the \verb+sample+ keyword.
+
+Examples:
+
+\begin{verbatim}
+sample sample a_ref;
+
+sample sample ref_list[4];
+
+sample struct { 
+    sample ref1;
+    sample ref2;
+    int x;
+    int y;
+} refs_and_ints;
+\end{verbatim}
+
+Sample references are need to be registered on both encoder and decoder
+side, using the functions
+
+\begin{verbatim}
+int labcomm_decoder_sample_ref_register(
+    struct labcomm_decoder *decoder\nonumber
+    const struct labcomm_signature *signature);
+
+int labcomm_encoder_sample_ref_register(
+    struct labcomm_encoder *encoder\nonumber
+    const struct labcomm_signature *signature);
+\end{verbatim}
+
+The value of an unregistered sample reference will be decoded as \verb+null+.
+
+\subsection{User defined types}
+
+User defined types are declared with the \verb+typedef+ reserved word,
+and can then be used in type and sample declarations.
 
 \begin{verbatim}
   typedef struct {
@@ -382,6 +437,11 @@ come from two independent number series. To identify which
 \verb+TYPE_DECL+ a particular \verb+SAMPLE_DECL+ corresponds to, the
 \verb+TYPE_BINDING+ packet is used.
 
+For sample types that do not depend on any typedefs, no \verb+TYPE_DECL+
+is sent, and the \verb+TYPE_BINDING+ binds the sample id to the special
+value zero to indicate that the type definition is identical to the
+flattened signature.
+
 \subsection{Example}
 
 The labcomm declaration
@@ -429,6 +489,42 @@ not required to do so. However, if multiple \verb+TYPE_DECL+ packets are
 sent for the same \verb+typedef+, the encoder must use the same
 \verb+type_id+.
 
+\subsection{Decoding in-band type descriptions}
+
+In LabComm, the in-band data descriptions are equivalent to \footnote{in
+the sense that they contain all information needed to recreate} the data
+description source (i.e., the ``.lc-file'').
+%
+As the type declarations (a.k.a. \emph{signatures}) are written before
+sample data on every channel, they can be used to interpret data with
+an unknown (by the receiver) format.
+
+The libraries provide functionality to subscribe to (i.e., register a
+\emph{handler} for) sample and type declarations.
+
+On the low level, the handler receives an instance of the signature
+data structure corresponding to the received declaration.
+
+
+For higher-level processing, the Java library provides the
+\verb+ASTbuilder+ class, which builds an abstract syntax tree in
+the internal representation of the LabComm compiler.
+That enables the user to use the complete functionality of the
+LabComm compiler, e.g. code generation,  on declarations received in a
+LabComm stream. 
+
+
+In combination with on-the-fly compilation and class-loading (or
+linking) that makes it possible to dynamically create handlers for
+previously unknown data types. Thereby, it enables dynamic configuration
+of LabComm endpoints in static languages without the overhead of
+interpreting signatures (at the one-time cost of code generation and
+compilation).
+
+
+
+
+
 
 
 \section{Ideas/Discussion}:
@@ -443,6 +539,234 @@ Java primitive types. However, it is unlikely that the entire range is actually
 way of supporting the common cases is to include run-time checks for overflow in the Java encoders
 and decoders.
 
+\section{Related work}
+  
+Two in-band self-descibing communication protocols are Apache
+Avro\cite{avro} and EDN, the extensible data notation developed for
+Clojure and Datomic\cite{EDN}.
+
+EDN encodes \emph{values} as UTF-8 strings. The documentation says
+``edn is a system for the conveyance of values. It is not a type system,
+and has no schemas.'' That said, it is \emph{extensible} in the sense
+that it has a special \emph{dispatch charachter}, \verb+#+, which can  
+be used to add a \emph{tag} to a value. A tag indicates a semantic
+interpretation of a value, and that allows the reader to support
+handlers for specific tags, enabling functionality similar to that of
+labcomm.
+
+\subsection{Apache Avro}
+
+Apache Avro is similar to LabComm in that it has a textual language
+for declaring data, a binary protocol for transmitting data, and code
+generation for several languages.
+
+Avro is a larger system, including RPC \emph{protocols}, support for
+using different \emph{codecs} for data compression, and \emph{schema
+resolution} to support handling schema evolution and transparent 
+interoperability between different versions of a schema.
+
+\subsubsection*{Data types} 
+
+In the table, the Avro type names are listed, and matched to the
+corresponding LabComm type:
+
+\begin{tabular}{|l|c|c|}
+\hline
+  Type &            Labcomm  &               Avro \\
+  \hline Primitive types \\ \hline
+
+int    &         4 bytes     &           varint  \\
+long   &         8 bytes     &           varint  \\
+float  &         4 bytes     &           4 bytes \\
+long   &         8 bytes     &           8 bytes \\
+string &         varint + utf8[]   &     varint + utf8[] \\ 
+bytes  &         varint + byte[]   &     varint + byte[]\\
+
+  \hline Complex types  \\ \hline
+
+struct/record &  concat of fields     &  concat of fields \\ 
+arrays        &  varIdx[] : elements  &  block[]          \\
+map           &    n/a                &  block[]          \\
+union         &   n/a                 & (varint idx) : value \\
+fixed         &   byte[n]             &  the number of bytes declared in
+the schema\\
+\hline
+\end{tabular}
+
+  where 
+
+\begin{verbatim}  
+  block ::= (varint count) : elem[count]      [*1]
+  count == 0 --> no more blocks
+
+
+[*1] for arrays, count == 0 --> end of array
+     if count < 0, there are |count| elements
+     preceded by a varint block_size to allow
+     fast skipping
+\end{verbatim}  
+
+In maps, keys are strings, and values  according to the schema.
+
+In unions, the index indicates the kind of value and the
+value is encoded according to the schema.
+
+Note that the Avro data type \verb+bytes+ corresponds to the
+LabComm declaration \verb+byte[_]+, i.e. a varaible length byte array.
+
+\subsubsection*{the wire protocol}
+
+\begin{tabular}{|l|c|c|}
+  \hline
+  What & LabComm & Avro \\ \hline
+  Data description & Binary signature & JSON schema \\
+  Signature sent only once pre connection& posible & possible \\
+  Signature sent with each sample & possible & possible \\
+  Data encoding & binary & binary \\
+  \hline
+\end{tabular}
+
+
+Both avro and labcomm use varints when encoding data, similar in that
+they both send a sequence of bytes containing 7 bit chunks (with the
+eight bit signalling more chunks to come), but they differ in range,
+endianness and signedness.
+
+\begin{verbatim}
+                LabComm                 Avro
+                unsigned 32 bit         signed zig-zag coding
+                most significant chunk  least significant chunk
+                first                   first
+
+                0   ->  00               0  ->  00
+                1   ->  01              -1  ->  01
+                2   ->  02               1  ->  02
+                    ...                 -2  ->  03
+                                         2  ->  04
+                                            ...
+                127 ->  7f              -64 ->  7f
+                128 ->  81 00            64 ->  80 01
+                129 ->  81 01           -65 ->  81 01
+                130 ->  81 02            65 ->  82 01
+                    ...                     ...   
+\end{verbatim}
+
+\paragraph{Avro Object Container Files} can be seen as a counterpart
+  to a LabComm channel: 
+Avro includes a simple object container file format. A file has a
+schema, and all objects stored in the file must be written according to
+that schema, using binary encoding. Objects are stored in blocks that
+may be compressed. Syncronization markers are used between blocks to
+permit efficient splitting of files, and enable detection of 
+corrupt blocks.
+
+
+The major difference is the sync markers that LabComm does not have, as
+LabComm assumes that, while the transport may drop packets, there will
+be no bit errors in a received packet. If data integrity is required,
+that is delegated to the reader and writer for the particular transport.
+
+\subsubsection{Representation of hierarchical data types}
+
+For a type that contains fields of other user types, like
+\begin{verbatim}
+typedef struct {
+  int x;
+  int y;
+} Point;
+
+sample struct {
+  Point start;
+  Point end;
+} line;
+\end{verbatim}
+
+LabComm encodes both the flattened signature and the 
+typedef which allows the hierarchical type structure to be
+reconstructed.
+%
+The avro encoding is quite similar. 
+The \verb+Line+ example, corresponds to the two schemas
+\begin{verbatim}
+{"namespace": "example.avro",
+ "type": "record",
+ "name": "Point",
+ "fields": [
+     {"name": "x", "type": "int"},
+     {"name": "y", "type": "int"}
+ ]
+}
+\end{verbatim}
+and
+\begin{verbatim}
+{"namespace": "example.avro",
+ "type": "record",
+ "name": "Line",
+ "fields": [
+     {"name": "start", "type": "Point"},
+     {"name": "end",   "type": "Point"}
+ ]
+}
+\end{verbatim}
+which is encoded in an Object Container File as
+\begin{verbatim}
+{"type":"record",
+ "name":"Line",
+ "namespace":"example.avro",
+ "fields":[{"name":"start",
+            "type":{"type":"record",
+                    "name":"Point",
+                    "fields":[{"name":"x","type":"int"},
+                              {"name":"y","type":"int"}]}},
+           {"name":"end",
+            "type":"Point"}
+ ]
+}
+\end{verbatim}
+\subsubsection{Fetures not in LabComm} 
+
+Avro has a set of features with no counterpart in LabComm. They include
+
+\paragraph{Codecs.}
+
+Avro has multiple codecs (for compression of the data):
+
+    \begin{verbatim}
+    Required Codecs:
+    - null : The "null" codec simply passes through data uncompressed.
+
+    - deflate : The "deflate" codec writes the data block using the deflate
+                algorithm as specified in RFC 1951, and typically implemented using the
+                zlib library. Note that this format (unlike the "zlib format" in RFC
+                1950) does not have a checksum.
+
+    Optional Codecs
+
+    - snappy:   The "snappy" codec uses Google's Snappy compression library. Each
+                compressed block is followed by the 4-byte, big-endian CRC32 checksum of
+                the uncompressed data in the block.
+
+    \end{verbatim}
+
+  \paragraph{Schema Resolution.} The main objective of LabComm is to
+    ensure correct operation at run-time. Therefore, a LabComm decoder
+    requires the signatures for each handled sample to match exactly.
+
+    Avro, on the other hand, supports the evolution of schemas and
+    provides support for reading data where the ordering of fields
+    differ (but names and types are the same), numerical types differ
+    but can be
+    \emph{promoted} (E.g., \verb+int+ can be promoted to \verb+long+,
+    \verb+float+, or \verb+double+.), and record fields have been added
+    or removed (but are nullable or have default values).
+
+    \paragraph{Schema fingerprints.} Avro defines a \emph{Parsing
+    Canonical Form} to define when two JSON schemas are ``the same''.
+    To reduce the overhead when, e.g., tagging data with the schema
+    there is support for creating a \emph{fingerprint} using 64/128/256
+    bit hashing, in combination with a centralized repository for
+    fingerprint/schema pairs.
+
 \bibliography{refs}{}
 \bibliographystyle{plain}
 
@@ -464,6 +788,7 @@ Field ::= Type <Name:String>;
 
 abstract Type;
 VoidType          : Type;
+SampleRefType     : Type;
 PrimType          : Type ::= <Name:String> <Token:int>;
 UserType          : Type ::= <Name:String>;
 StructType        : Type ::= Field*;
@@ -502,61 +827,70 @@ first.
 
 The built-in data types are encoded as follows:
 \begin{lstlisting}[basicstyle=\footnotesize\ttfamily]
-||Type      ||Encoding/Size                                      ||
-||----------||---------------------------------------------------||
-||boolean   ||  8 bits                                           ||
-||byte      ||  8 bits                                           ||
-||short     || 16 bits                                           ||
-||integer   || 32 bits                                           ||
-||long      || 64 bits                                           ||
-||float     || 32 bits                                           ||
-||double    || 64 bits                                           ||
-||string    || length (varint), followed by UTF8 encoded string  ||
-||array     || each variable index (varint),                     ||
-||          || followed by encoded elements                      ||
-||struct    || concatenation of encoding of each element         ||
-||          || in declaration order                              ||
+||Type       ||Encoding/Size                                      ||
+||-----------||---------------------------------------------------||
+||boolean    ||  8 bits                                           ||
+||byte       ||  8 bits                                           ||
+||short      || 16 bits                                           ||
+||integer    || 32 bits                                           ||
+||long       || 64 bits                                           ||
+||float      || 32 bits                                           ||
+||double     || 64 bits                                           ||
+||sample_ref || 32 bits                                           ||
+||string     || length (varint), followed by UTF8 encoded string  ||
+||array      || each variable index (varint),                     ||
+||           || followed by encoded elements                      ||
+||struct     || concatenation of encoding of each element         ||
+||           || in declaration order                              ||
 \end{lstlisting}
-
+\pagebreak
 \subsection{Protocol grammar}
 \label{sec:ConcreteGrammar}
 \begin{lstlisting}[basicstyle=\footnotesize\ttfamily]
-<packet>       := <id> <length> ( <version>      | 
-                                  <type_decl>    | 
-                                  <sample_decl>  |
-                                  <type_binding> |
-                                  <sample_data> )
-<version>      := <string>
-<sample_decl>  := <sample_id> <string> <type>
-<type_decl>    := <type_id> <string> <type>
-<type_binding> := <sample_id> <type_id>
-<user_id>      := 0x40..0xffffffff  
+<packet>          := <id> <length> ( <version>      | 
+                                     <type_decl>    | 
+                                     <sample_decl>  |
+                                     <sample_ref>   |
+                                     <type_binding> |
+                                     <sample_data> )
+<version>         := <string>
+<sample_decl>     := <sample_id> <string> <type>
+<sample_ref>      := <sample_id> <string> <type>
+<type_decl>       := <type_id> <string> <type>
+<type_binding>    := <sample_id> <type_id>
+<user_id>         := 0x40..0xffffffff  
 <sample_id> : <user_id>
 <type_id>   : <user_id>
-<string>       := <string_length> <char>*
-<string_length>:= 0x00..0xffffffff  
-<char>         := any UTF-8 char
-<type>         := <length> ( <basic_type> | <array_decl> | <struct_decl> | <type_id> )
-<basic_type>   := ( <boolean_type> | <byte_type> | <short_type> |
-                  <integer_type> | <long_type> | <float_type> |
-                  <double_type> | <string_type> )
-<boolean_type> := 0x20 
-<byte_type>    := 0x21 
-<short_type>   := 0x22 
-<integer_type> := 0x23 
-<long_type>    := 0x24 
-<float_type>   := 0x25 
-<double_type>  := 0x26 
-<string_type>  := 0x27 
-<array_decl>   := 0x10  <number_of_indices> <indices> <type>
-<number_of_indices> := 0x00..0xffffffff  
-<indices>      := ( <variable_index> | <fixed_index> )*
-<variable_index> := 0x00  
-<fixed_index>  := 0x01..0xffffffff  
-<struct_decl>  := 0x11  <number_of_fields> <field>*
-<number_of_fields> := 0x00..0xffffffff  
-<field>        := <string> <type>
-<sample_data>  := packed sample data sent in network order, with
+<string>          := <string_length> <char>*
+<string_length>   := 0x00..0xffffffff  
+<char>            := any UTF-8 char
+<type>            := <length> ( <basic_type>  | 
+                                <array_decl>  | 
+                                <struct_decl> | 
+                                <type_id> )
+<basic_type>      := ( <void_type> | <boolean_type> | <byte_type> | <short_type> |
+                     <integer_type> | <long_type> | <float_type> |
+                     <double_type> | <string_type> | <sample_ref_type>)
+
+<void_type>       := <struct_decl> 0 //void is encoded as empty struct
+<boolean_type>    := 0x20 
+<byte_type>       := 0x21 
+<short_type>      := 0x22 
+<integer_type>    := 0x23 
+<long_type>       := 0x24 
+<float_type>      := 0x25 
+<double_type>     := 0x26 
+<string_type>     := 0x27 
+<sample_ref_type> := 0x28 
+<array_decl>      := 0x10  <nbr_of_indices> <indices> <type>
+<nbr_of_indices>  := 0x00..0xffffffff  
+<indices>         := ( <variable_index> | <fixed_index> )*
+<variable_index>  := 0x00  
+<fixed_index>     := 0x01..0xffffffff  
+<struct_decl>     := 0x11  <nbr_of_fields> <field>*
+<nbr_of_fields>   := 0x00..0xffffffff  
+<field>           := <string> <type>
+<sample_data>     := packed sample data sent in network order, with
                   primitive type elements encoded according to
                   the sizes above
 \end{lstlisting}
@@ -566,8 +900,9 @@ The labcomm sytem packet ids are:
 \begin{lstlisting}[basicstyle=\footnotesize\ttfamily]
 version:      0x01 
 sample_decl:  0x02 
-type_decl:    0x03 
-type_binding: 0x04          
+sample_ref:   0x03 
+type_decl:    0x04 
+type_binding: 0x05          
 \end{lstlisting}
 Note that since the signature transmitted in a \verb+<sample_def>+ is
 flattened, the \verb+<type>+ transmitted in a \verb+<sample_def>+ may
diff --git a/examples/duck_typing/.gitignore b/examples/duck_typing/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..4f62b849d56cd043cb9725fe73e9f49522d3d931
--- /dev/null
+++ b/examples/duck_typing/.gitignore
@@ -0,0 +1 @@
+gen
diff --git a/examples/duck_typing/duck_typing.py b/examples/duck_typing/duck_typing.py
index 3138e47fc40467d23007f5a3273f64fca0ed6a11..c918ab510e3f6f1d6eaa451a8c34298ebbea3507 100755
--- a/examples/duck_typing/duck_typing.py
+++ b/examples/duck_typing/duck_typing.py
@@ -1,6 +1,6 @@
 #!/usr/bin/python
 
-import labcomm
+import labcomm2014
 import animal
 import StringIO
 
@@ -10,7 +10,7 @@ class Animal:
 
 if __name__ == '__main__':
     buf = StringIO.StringIO()
-    encoder = labcomm.Encoder(labcomm.StreamWriter(buf))
+    encoder = labcomm2014.Encoder(labcomm2014.StreamWriter(buf))
     encoder.add_decl(animal.cow.signature)
     encoder.add_decl(animal.dog.signature)
     encoder.add_decl(animal.duck.signature)
@@ -22,7 +22,7 @@ if __name__ == '__main__':
     theAnimal.says = 'Quack'
     encoder.encode(theAnimal, animal.duck.signature)
     buf.seek(0)
-    decoder = labcomm.Decoder(labcomm.StreamReader(buf))
+    decoder = labcomm2014.Decoder(labcomm2014.StreamReader(buf))
     try:
         while True:
             value,decl = decoder.decode()
diff --git a/examples/dynamic/test/DynamicPart.java b/examples/dynamic/test/DynamicPart.java
index a3137220ca98e8e00ddf25a6b879d2406d3817c6..5e98f51082f6be5c50516d94cfb54bd485836d32 100644
--- a/examples/dynamic/test/DynamicPart.java
+++ b/examples/dynamic/test/DynamicPart.java
@@ -18,10 +18,10 @@ import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.Map;
 
-import se.lth.control.labcomm.Decoder;
-import se.lth.control.labcomm.DecoderChannel;
-import se.lth.control.labcomm.Encoder;
-import se.lth.control.labcomm.EncoderChannel;
+import se.lth.control.labcomm2014.Decoder;
+import se.lth.control.labcomm2014.DecoderChannel;
+import se.lth.control.labcomm2014.Encoder;
+import se.lth.control.labcomm2014.EncoderChannel;
 import AST.Parser;
 import AST.Scanner;
 import AST.Program;
diff --git a/examples/dynamic/test/StaticDecoder.java b/examples/dynamic/test/StaticDecoder.java
index c1c06d3b90a06270ceaaa0b492fc580a4c1dcd07..1286b009651813137f6660745990b4c90539b9b5 100644
--- a/examples/dynamic/test/StaticDecoder.java
+++ b/examples/dynamic/test/StaticDecoder.java
@@ -6,7 +6,7 @@ import gen.bar;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.InputStream;
-import se.lth.control.labcomm.DecoderChannel;
+import se.lth.control.labcomm2014.DecoderChannel;
 
 
 public class StaticDecoder implements foo.Handler, bar.Handler
diff --git a/examples/dynamic/test/StaticEncoder.java b/examples/dynamic/test/StaticEncoder.java
index 4ea48be4e2e94daf915caac4bb4a2ac2a0ad33f5..0bfb5340d8e9b8c84c0764a1d2bf7f9fe0425ca1 100644
--- a/examples/dynamic/test/StaticEncoder.java
+++ b/examples/dynamic/test/StaticEncoder.java
@@ -2,7 +2,7 @@ package test;
 import java.io.File;
 import java.io.FileOutputStream;
 import java.io.OutputStream;
-import se.lth.control.labcomm.EncoderChannel;
+import se.lth.control.labcomm2014.EncoderChannel;
 
 import gen.foo;
 import gen.bar;
diff --git a/examples/dynamic/test/TestLabCommCompiler.java b/examples/dynamic/test/TestLabCommCompiler.java
index fe9f5e659633cf036698e2c531a1a295dc99bf32..b0783456c36e03c103485c1e19c6adcdd54ed9f5 100644
--- a/examples/dynamic/test/TestLabCommCompiler.java
+++ b/examples/dynamic/test/TestLabCommCompiler.java
@@ -16,10 +16,10 @@ import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.Map;
 
-import se.lth.control.labcomm.Decoder;
-import se.lth.control.labcomm.DecoderChannel;
-import se.lth.control.labcomm.Encoder;
-import se.lth.control.labcomm.EncoderChannel;
+import se.lth.control.labcomm2014.Decoder;
+import se.lth.control.labcomm2014.DecoderChannel;
+import se.lth.control.labcomm2014.Encoder;
+import se.lth.control.labcomm2014.EncoderChannel;
 import AST.Parser;
 import AST.Scanner;
 import AST.Program;
diff --git a/examples/dynamic/test/TestLabcommGen.java b/examples/dynamic/test/TestLabcommGen.java
index 7ff4e03a3f12cee2e4c321b90f6ef067d397ac76..b35f5023a561f994ec5d8d5125917265eee7028c 100644
--- a/examples/dynamic/test/TestLabcommGen.java
+++ b/examples/dynamic/test/TestLabcommGen.java
@@ -18,10 +18,10 @@ import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.Map;
 
-import se.lth.control.labcomm.Decoder;
-import se.lth.control.labcomm.DecoderChannel;
-import se.lth.control.labcomm.Encoder;
-import se.lth.control.labcomm.EncoderChannel;
+import se.lth.control.labcomm2014.Decoder;
+import se.lth.control.labcomm2014.DecoderChannel;
+import se.lth.control.labcomm2014.Encoder;
+import se.lth.control.labcomm2014.EncoderChannel;
 import AST.Parser;
 import AST.Scanner;
 import AST.Program;
diff --git a/examples/jgrafchart/labcommTCPtest/client/TestClient.java b/examples/jgrafchart/labcommTCPtest/client/TestClient.java
index 66fa1342e470b12c1516ceacdd89a85b4a7d0616..acc2a368c1a1351f614a886c61e7342a2c0f332b 100644
--- a/examples/jgrafchart/labcommTCPtest/client/TestClient.java
+++ b/examples/jgrafchart/labcommTCPtest/client/TestClient.java
@@ -6,8 +6,8 @@ import java.io.OutputStream;
 import java.net.Socket;
 import java.net.UnknownHostException;
 
-import se.lth.control.labcomm.DecoderChannel;
-import se.lth.control.labcomm.EncoderChannel;
+import se.lth.control.labcomm2014.DecoderChannel;
+import se.lth.control.labcomm2014.EncoderChannel;
 import labcommTCPtest.gen.foo;
 import labcommTCPtest.gen.foo.Handler;
 
diff --git a/examples/jgrafchart/labcommTCPtest/client/TestClientSingleshot.java b/examples/jgrafchart/labcommTCPtest/client/TestClientSingleshot.java
index 9601bcabcf45d174367aeeb61229ccc3dfeb8d25..1bf43e7297a7358260150971a2a9b8bec90f8230 100644
--- a/examples/jgrafchart/labcommTCPtest/client/TestClientSingleshot.java
+++ b/examples/jgrafchart/labcommTCPtest/client/TestClientSingleshot.java
@@ -6,8 +6,8 @@ import java.io.OutputStream;
 import java.net.Socket;
 import java.net.UnknownHostException;
 
-import se.lth.control.labcomm.DecoderChannel;
-import se.lth.control.labcomm.EncoderChannel;
+import se.lth.control.labcomm2014.DecoderChannel;
+import se.lth.control.labcomm2014.EncoderChannel;
 import labcommTCPtest.gen.FooSample;
 import labcommTCPtest.gen.FooSample.Handler;
 
diff --git a/examples/jgrafchart/labcommTCPtest/server/TestServer.java b/examples/jgrafchart/labcommTCPtest/server/TestServer.java
index 4b95a362a6a1784407336df5b5eab411f2e25f1d..35053120d1e915f775180c6cdad00bc2a815d17d 100644
--- a/examples/jgrafchart/labcommTCPtest/server/TestServer.java
+++ b/examples/jgrafchart/labcommTCPtest/server/TestServer.java
@@ -8,8 +8,8 @@ import java.lang.reflect.Method;
 import java.net.ServerSocket;
 import java.net.Socket;
 
-import se.lth.control.labcomm.DecoderChannel;
-import se.lth.control.labcomm.EncoderChannel;
+import se.lth.control.labcomm2014.DecoderChannel;
+import se.lth.control.labcomm2014.EncoderChannel;
 import labcommTCPtest.gen.foo;
 import labcommTCPtest.gen.foo.Handler;
 
diff --git a/examples/robot/Program.cs b/examples/robot/Program.cs
index 56cfb271d07a42885f8e5790b2eed23adebbc894..49a0a925070f3f1a2feca2b5bcb9356574019235 100644
--- a/examples/robot/Program.cs
+++ b/examples/robot/Program.cs
@@ -1,4 +1,4 @@
-using se.lth.control.labcomm;
+using se.lth.control.labcomm2014;
 using System;
 using System.Collections.Generic;
 using System.Linq;
diff --git a/examples/simple/.gitignore b/examples/simple/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..b2b1fa399069a6a87eeb68da5c1a10216afa9d09
--- /dev/null
+++ b/examples/simple/.gitignore
@@ -0,0 +1,8 @@
+encoded_data
+encoded_data06
+example_decoder
+example_decoder06
+example_encoder
+example_encoder06
+gen
+gen06
diff --git a/examples/simple/Decoder.java b/examples/simple/Decoder.java
index 48dd3edfa2cb6b9501890f17f62f3b9df79047fb..0adc7776fe7a18fe81cb3004a656d2d303f3925f 100644
--- a/examples/simple/Decoder.java
+++ b/examples/simple/Decoder.java
@@ -2,7 +2,7 @@ import java.io.File;
 import java.io.FileInputStream;
 import java.io.InputStream;
 
-import se.lth.control.labcomm.DecoderChannel;
+import se.lth.control.labcomm2014.DecoderChannel;
 
 public class Decoder
   implements theTwoInts.Handler, anotherTwoInts.Handler, IntString.Handler, TwoArrays.Handler, TwoFixedArrays.Handler, doavoid.Handler
diff --git a/examples/simple/Encoder.java b/examples/simple/Encoder.java
index d70384cee5fe7452d4cb413db3c7c6ef09f9e7a1..061e91ff7e33e771853416ea37b1c13e003bf958 100644
--- a/examples/simple/Encoder.java
+++ b/examples/simple/Encoder.java
@@ -2,7 +2,7 @@ import java.io.File;
 import java.io.FileOutputStream;
 import java.io.OutputStream;
 
-import se.lth.control.labcomm.EncoderChannel;
+import se.lth.control.labcomm2014.EncoderChannel;
 
 /**
  * Simple encoder 
@@ -16,12 +16,14 @@ public class Encoder
     throws Exception 
   {
     encoder = new EncoderChannel(out);
+    doavoid.register(encoder);
     theTwoInts.register(encoder);
     IntString.register(encoder);
     TwoArrays.register(encoder);
   }
 
   public void doEncode() throws java.io.IOException {
+
     TwoInts x = new TwoInts();
     x.a = 17;
     x.b = 42;
@@ -35,6 +37,9 @@ public class Encoder
 //    ta.variable = new int[][] {{1,2},{0x11,0x12},{0x21,0x22},{0x31,0x32}};
     ta.variable = new int[][] {{1,2, 3, 4},{0x21,0x22,0x23,0x24}};
 
+    System.out.println("Encoding doavoid");
+    doavoid.encode(encoder);
+
     System.out.println("Encoding theTwoInts, a="+x.a+", b="+x.b);
     theTwoInts.encode(encoder, x);
 
diff --git a/examples/simple/EncoderIS.java b/examples/simple/EncoderIS.java
new file mode 100644
index 0000000000000000000000000000000000000000..4bdb99b8b1aa7f5332d1bebc3a1c9268c850e505
--- /dev/null
+++ b/examples/simple/EncoderIS.java
@@ -0,0 +1,53 @@
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+
+import se.lth.control.labcomm2014.EncoderChannel;
+
+/**
+ * Simple encoder 
+ */
+public class EncoderIS 
+{
+
+  EncoderChannel encoder;
+
+  public EncoderIS(OutputStream out) 
+    throws Exception 
+  {
+    encoder = new EncoderChannel(out);
+//    doavoid.register(encoder);
+//    theTwoInts.register(encoder);
+    IntString.register(encoder);
+//    TwoArrays.register(encoder);
+  }
+
+  public void doEncodeIS() throws java.io.IOException {
+    IntString a = new IntString();
+    a.x = 17;
+    a.s = "A string";
+
+    IntString b = new IntString();
+    b.x = 9;
+    b.s = "Hej";
+
+    IntString c = new IntString();
+    c.x = 133742;
+    c.s = "Thirteenthirtysevenfourtytwo";
+
+    System.out.println("Encoding IntStrings");
+    IntString.encode(encoder, a);
+    IntString.encode(encoder, b);
+    IntString.encode(encoder, c);
+  }
+
+
+  public static void main(String[] arg) throws Exception {
+    FileOutputStream fos = new FileOutputStream(arg[0]);
+    EncoderIS example = new EncoderIS(fos);
+    example.doEncodeIS();
+    fos.close();
+  }
+
+}
+
diff --git a/examples/simple/example_decoder.c b/examples/simple/example_decoder.c
index 122745d62aebe4ea9831dfbf4280d4f267e40425..493ae34c483543fe0d624589690e492c984edb16 100644
--- a/examples/simple/example_decoder.c
+++ b/examples/simple/example_decoder.c
@@ -1,13 +1,17 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
-#include <labcomm_fd_reader.h>
-#include <labcomm_default_error_handler.h>
-#include <labcomm_default_memory.h>
-#include <labcomm_default_scheduler.h>
+#include <labcomm2014_fd_reader.h>
+#include <labcomm2014_default_error_handler.h>
+#include <labcomm2014_default_memory.h>
+#include <labcomm2014_default_scheduler.h>
 #include "gen/simple.h"
 #include <stdio.h>
 
+static void handle_simple_doavoid(simple_doavoid *v, void *context) {
+  printf("Got a void.\n");
+}
+
 static void handle_simple_theTwoInts(simple_TwoInts *v,void *context) {
   printf("Got theTwoInts. a=%d, b=%d\n", v->a, v->b);
 }
@@ -53,32 +57,33 @@ static void handle_simple_TwoFixedArrays(simple_TwoFixedArrays *d,void *context)
 
 int main(int argc, char *argv[]) {
   int fd;
-  struct labcomm_decoder *decoder;
+  struct labcomm2014_decoder *decoder;
   void  *context = NULL;
 
   char *filename = argv[1];
   printf("C decoder reading from %s\n", filename);
   fd = open(filename, O_RDONLY);
-  decoder = labcomm_decoder_new(labcomm_fd_reader_new(
-				  labcomm_default_memory, fd, 1), 
-				labcomm_default_error_handler, 
-				labcomm_default_memory,
-				labcomm_default_scheduler);
+  decoder = labcomm2014_decoder_new(labcomm2014_fd_reader_new(
+				  labcomm2014_default_memory, fd, 1), 
+				labcomm2014_default_error_handler, 
+				labcomm2014_default_memory,
+				labcomm2014_default_scheduler);
   if (!decoder) { 
     printf("Failed to allocate decoder %s:%d\n", __FUNCTION__, __LINE__);
     return 1;
   }
 
-  labcomm_decoder_register_simple_theTwoInts(decoder, handle_simple_theTwoInts, context);
-  labcomm_decoder_register_simple_anotherTwoInts(decoder, handle_simple_anotherTwoInts, context);
-  labcomm_decoder_register_simple_IntString(decoder, handle_simple_IntString, context);
-  labcomm_decoder_register_simple_TwoArrays(decoder, handle_simple_TwoArrays, context);
-  labcomm_decoder_register_simple_TwoFixedArrays(decoder, handle_simple_TwoFixedArrays, context);
+  labcomm2014_decoder_register_simple_doavoid(decoder, handle_simple_doavoid, context);
+  labcomm2014_decoder_register_simple_theTwoInts(decoder, handle_simple_theTwoInts, context);
+  labcomm2014_decoder_register_simple_anotherTwoInts(decoder, handle_simple_anotherTwoInts, context);
+  labcomm2014_decoder_register_simple_IntString(decoder, handle_simple_IntString, context);
+  labcomm2014_decoder_register_simple_TwoArrays(decoder, handle_simple_TwoArrays, context);
+  labcomm2014_decoder_register_simple_TwoFixedArrays(decoder, handle_simple_TwoFixedArrays, context);
 
   printf("Decoding:\n");
-  labcomm_decoder_run(decoder);
+  labcomm2014_decoder_run(decoder);
   printf("--- End Of File ---:\n");
-  labcomm_decoder_free(decoder);
+  labcomm2014_decoder_free(decoder);
 
   return 0;
 }
diff --git a/examples/simple/example_encoder.c b/examples/simple/example_encoder.c
index ea77e11ca026daa100b5b19d6c8449d72c1ba6cf..c13e83dae1f7e80831d7a554f974a201b7a89495 100644
--- a/examples/simple/example_encoder.c
+++ b/examples/simple/example_encoder.c
@@ -1,53 +1,53 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
-#include <labcomm_fd_writer.h>
-#include <labcomm_default_error_handler.h>
-#include <labcomm_default_memory.h>
-#include <labcomm_default_scheduler.h>
+#include <labcomm2014_fd_writer.h>
+#include <labcomm2014_default_error_handler.h>
+#include <labcomm2014_default_memory.h>
+#include <labcomm2014_default_scheduler.h>
 #include "gen/simple.h"
 #include <stdio.h>
 
 int main(int argc, char *argv[]) {
   int fd;
-  struct labcomm_encoder *encoder;
+  struct labcomm2014_encoder *encoder;
 
   char *filename = argv[1];
   printf("C encoder writing to %s\n", filename);
   fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0644);
-  encoder = labcomm_encoder_new(labcomm_fd_writer_new(
-				  labcomm_default_memory, fd, 1), 
-				labcomm_default_error_handler, 
-				labcomm_default_memory,
-				labcomm_default_scheduler);
-  labcomm_encoder_register_simple_doavoid(encoder);
-  labcomm_encoder_register_simple_theTwoInts(encoder);
-  labcomm_encoder_register_simple_anotherTwoInts(encoder);
-  labcomm_encoder_register_simple_IntString(encoder);
-
-  labcomm_encode_simple_doavoid(encoder);
+  encoder = labcomm2014_encoder_new(labcomm2014_fd_writer_new(
+				  labcomm2014_default_memory, fd, 1), 
+				labcomm2014_default_error_handler, 
+				labcomm2014_default_memory,
+				labcomm2014_default_scheduler);
+  labcomm2014_encoder_register_simple_doavoid(encoder);
+  labcomm2014_encoder_register_simple_theTwoInts(encoder);
+  labcomm2014_encoder_register_simple_anotherTwoInts(encoder);
+  labcomm2014_encoder_register_simple_IntString(encoder);
+
+  labcomm2014_encode_simple_doavoid(encoder);
 
   simple_IntString is;
   is.x = 24;
   is.s = "Hello, LabComm!";
   printf("Encoding IntString, x=%d, s=%s\n", is.x, is.s);
-  labcomm_encode_simple_IntString(encoder, &is);
+  labcomm2014_encode_simple_IntString(encoder, &is);
 
   simple_theTwoInts ti;
   ti.a = 13;
   ti.b = 37;
   printf("Encoding theTwoInts, a=%d, b=%d\n", ti.a, ti.b);
-  labcomm_encode_simple_theTwoInts(encoder, &ti);
+  labcomm2014_encode_simple_theTwoInts(encoder, &ti);
 
   simple_anotherTwoInts ati;
   ati.a = 23;
   ati.b = 47;
   printf("Encoding anotherTwoInts, a=%d, b=%d\n", ati.a, ati.b);
-  labcomm_encode_simple_anotherTwoInts(encoder, &ati);
+  labcomm2014_encode_simple_anotherTwoInts(encoder, &ati);
 
   int foo[20];
 
-  labcomm_encoder_register_simple_TwoArrays(encoder);
+  labcomm2014_encoder_register_simple_TwoArrays(encoder);
 
   simple_TwoArrays ta;
   ta.fixed.a[0] = 17;
@@ -61,12 +61,12 @@ int main(int argc, char *argv[]) {
   }
 
   printf("Encoding TwoArrays...\n");
-  labcomm_encode_simple_TwoArrays(encoder, &ta);
+  labcomm2014_encode_simple_TwoArrays(encoder, &ta);
 
   ti.a = 23;
   ti.b = 47;
   printf("Encoding theTwoInts, a=%d, b=%d\n", ti.a, ti.b);
-  labcomm_encode_simple_theTwoInts(encoder, &ti);
+  labcomm2014_encode_simple_theTwoInts(encoder, &ti);
 
 
   simple_TwoFixedArrays tfa;
@@ -82,8 +82,8 @@ int main(int argc, char *argv[]) {
   tfa.b.a[1][2] = 63;
 
   printf("Encoding TwoFixedArrays...\n");
-  labcomm_encoder_register_simple_TwoFixedArrays(encoder);
-  labcomm_encode_simple_TwoFixedArrays(encoder, &tfa);
+  labcomm2014_encoder_register_simple_TwoFixedArrays(encoder);
+  labcomm2014_encode_simple_TwoFixedArrays(encoder, &tfa);
 
   return 0;
 }
diff --git a/examples/simple/example_encoder.py b/examples/simple/example_encoder.py
index c89f1348841dafb81e0eb2ba5e20c53c5606b79b..49063c839a4d36b78db258c122809e34fb24ebcb 100755
--- a/examples/simple/example_encoder.py
+++ b/examples/simple/example_encoder.py
@@ -1,12 +1,12 @@
 #!/usr/bin/python
 
-import labcomm
+import labcomm2014
 import sys
 import simple
 
 if __name__ == '__main__':
     version = sys.argv[2] if len(sys.argv) == 3 else "LabComm2014"
-    encoder = labcomm.Encoder(labcomm.StreamWriter(open(sys.argv[1], 'w')), version)
+    encoder = labcomm2014.Encoder(labcomm2014.StreamWriter(open(sys.argv[1], 'w')), version)
     encoder.add_decl(simple.theTwoInts.signature)
     encoder.add_decl(simple.IntString.signature)
     foo = simple.theTwoInts()
diff --git a/examples/tcp/example_tcp_client_decoder.py b/examples/tcp/example_tcp_client_decoder.py
index bf4f921b5572ffd757a21e37661e47dff0e5eff8..99d305c9a4a055b65b3de53a7c327ab38f52331c 100755
--- a/examples/tcp/example_tcp_client_decoder.py
+++ b/examples/tcp/example_tcp_client_decoder.py
@@ -5,9 +5,9 @@ import sys
 import socket
 import rwsocket
 
-if not any('labcomm' in p for p in sys.path):
+if not any('labcomm2014' in p for p in sys.path):
     sys.path.append('../../lib/python')
-import labcomm
+import labcomm2014
 
 
 if __name__ == "__main__":
@@ -19,7 +19,7 @@ if __name__ == "__main__":
     sock.connect(addr)
     print "Connected!"
 
-    d = labcomm.Decoder(labcomm.StreamReader(sock))
+    d = labcomm2014.Decoder(labcomm2014.StreamReader(sock))
 
     while True:
         try:
diff --git a/examples/tcp/labcommTCPtest/client/TestClient.java b/examples/tcp/labcommTCPtest/client/TestClient.java
index fcd621e5f0749184d271602054b1d84c151074d8..42844f74583346fca0f0485b7c869fd179c5fdd6 100644
--- a/examples/tcp/labcommTCPtest/client/TestClient.java
+++ b/examples/tcp/labcommTCPtest/client/TestClient.java
@@ -6,8 +6,8 @@ import java.io.OutputStream;
 import java.net.Socket;
 import java.net.UnknownHostException;
 
-import se.lth.control.labcomm.DecoderChannel;
-import se.lth.control.labcomm.EncoderChannel;
+import se.lth.control.labcomm2014.DecoderChannel;
+import se.lth.control.labcomm2014.EncoderChannel;
 import labcommTCPtest.gen.FooSample;
 import labcommTCPtest.gen.FooSample.Handler;
 
diff --git a/examples/tcp/labcommTCPtest/client/TestClientSingleshot.java b/examples/tcp/labcommTCPtest/client/TestClientSingleshot.java
index 9601bcabcf45d174367aeeb61229ccc3dfeb8d25..1bf43e7297a7358260150971a2a9b8bec90f8230 100644
--- a/examples/tcp/labcommTCPtest/client/TestClientSingleshot.java
+++ b/examples/tcp/labcommTCPtest/client/TestClientSingleshot.java
@@ -6,8 +6,8 @@ import java.io.OutputStream;
 import java.net.Socket;
 import java.net.UnknownHostException;
 
-import se.lth.control.labcomm.DecoderChannel;
-import se.lth.control.labcomm.EncoderChannel;
+import se.lth.control.labcomm2014.DecoderChannel;
+import se.lth.control.labcomm2014.EncoderChannel;
 import labcommTCPtest.gen.FooSample;
 import labcommTCPtest.gen.FooSample.Handler;
 
diff --git a/examples/tcp/labcommTCPtest/server/OneShotServer.java b/examples/tcp/labcommTCPtest/server/OneShotServer.java
index b79b93e7d8f14d7eac194207d7914c17187fc113..647ed19d59b4ccf975066772d34e549aa1130590 100644
--- a/examples/tcp/labcommTCPtest/server/OneShotServer.java
+++ b/examples/tcp/labcommTCPtest/server/OneShotServer.java
@@ -6,8 +6,8 @@ import java.io.OutputStream;
 import java.net.Socket;
 import java.net.ServerSocket;
 
-import se.lth.control.labcomm.DecoderChannel;
-import se.lth.control.labcomm.EncoderChannel;
+import se.lth.control.labcomm2014.DecoderChannel;
+import se.lth.control.labcomm2014.EncoderChannel;
 import labcommTCPtest.gen.FooSample;
 
 public class OneShotServer {//implements Handler {
diff --git a/examples/tcp/labcommTCPtest/server/TestServer.java b/examples/tcp/labcommTCPtest/server/TestServer.java
index 441bac4df2d1d4a08eda8322c0c2717b0e886521..e17dabdbf36973d5f0240e00f22c5ec1f5663942 100644
--- a/examples/tcp/labcommTCPtest/server/TestServer.java
+++ b/examples/tcp/labcommTCPtest/server/TestServer.java
@@ -8,8 +8,8 @@ import java.lang.reflect.Method;
 import java.net.ServerSocket;
 import java.net.Socket;
 
-import se.lth.control.labcomm.DecoderChannel;
-import se.lth.control.labcomm.EncoderChannel;
+import se.lth.control.labcomm2014.DecoderChannel;
+import se.lth.control.labcomm2014.EncoderChannel;
 import labcommTCPtest.gen.FooSample;
 import labcommTCPtest.gen.FooSample.Handler;
 
diff --git a/examples/twoway/.gitignore b/examples/twoway/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..4f62b849d56cd043cb9725fe73e9f49522d3d931
--- /dev/null
+++ b/examples/twoway/.gitignore
@@ -0,0 +1 @@
+gen
diff --git a/examples/twoway/client.c b/examples/twoway/client.c
index 0166a3553616ca1858aafebc8a2adb3935f332f0..f0e54472a442bfd8fb8339783e85994e930fdbf6 100644
--- a/examples/twoway/client.c
+++ b/examples/twoway/client.c
@@ -36,12 +36,12 @@
 #include <sys/socket.h>
 #include <sys/types.h>
 #include <unistd.h>
-#include <labcomm.h>
-#include <labcomm_fd_reader.h>
-#include <labcomm_fd_writer.h>
-#include <labcomm_default_error_handler.h>
-#include <labcomm_default_memory.h>
-#include <labcomm_pthread_scheduler.h>
+#include <labcomm2014.h>
+#include <labcomm2014_fd_reader.h>
+#include <labcomm2014_fd_writer.h>
+#include <labcomm2014_default_error_handler.h>
+#include <labcomm2014_default_memory.h>
+#include <labcomm2014_pthread_scheduler.h>
 #include "decimating.h"
 #include "introspecting.h"
 #include "gen/types.h"
@@ -63,13 +63,13 @@ static void handle_Product(int32_t *value, void *context)
 
 static void *run_decoder(void *context)
 {
-  struct labcomm_decoder *decoder = context;
+  struct labcomm2014_decoder *decoder = context;
   int result;
 
-  labcomm_decoder_register_types_Sum(decoder, handle_Sum, NULL);
-  labcomm_decoder_register_types_Diff(decoder, handle_Diff, NULL);
+  labcomm2014_decoder_register_types_Sum(decoder, handle_Sum, NULL);
+  labcomm2014_decoder_register_types_Diff(decoder, handle_Diff, NULL);
   do {
-    result = labcomm_decoder_decode_one(decoder);
+    result = labcomm2014_decoder_decode_one(decoder);
   } while (result >= 0);
   return NULL;
 }
@@ -87,10 +87,10 @@ int main(int argc, char *argv[])
   struct introspecting *introspecting;
   char *hostname;
   int port;
-  struct labcomm_scheduler *scheduler;
-  struct labcomm_decoder *decoder;
-  struct labcomm_encoder *encoder;
-  struct labcomm_time *next;
+  struct labcomm2014_scheduler *scheduler;
+  struct labcomm2014_decoder *decoder;
+  struct labcomm2014_encoder *encoder;
+  struct labcomm2014_time *next;
   int32_t i, j;
 
   hostname = argv[1];
@@ -128,13 +128,13 @@ int main(int argc, char *argv[])
   
   nodelay = 1;
   setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &nodelay, sizeof(nodelay));
-  scheduler = labcomm_pthread_scheduler_new(labcomm_default_memory);
-  decimating = decimating_new(labcomm_fd_reader_new(labcomm_default_memory, 
+  scheduler = labcomm2014_pthread_scheduler_new(labcomm2014_default_memory);
+  decimating = decimating_new(labcomm2014_fd_reader_new(labcomm2014_default_memory, 
 						    fd, 1),
-			      labcomm_fd_writer_new(labcomm_default_memory, 
+			      labcomm2014_fd_writer_new(labcomm2014_default_memory, 
 						    fd, 0),
-			      labcomm_default_error_handler,
-			      labcomm_default_memory,
+			      labcomm2014_default_error_handler,
+			      labcomm2014_default_memory,
 			      scheduler);
   if (decimating == NULL) {
     /* Warning: might leak reader and writer at this point */
@@ -142,45 +142,45 @@ int main(int argc, char *argv[])
   }
   introspecting = introspecting_new(decimating->reader,
 				    decimating->writer,
-				    labcomm_default_error_handler,
-				    labcomm_default_memory,
+				    labcomm2014_default_error_handler,
+				    labcomm2014_default_memory,
 				    scheduler);
   if (introspecting == NULL) {
     /* Warning: might leak reader and writer at this point */
     goto out;
   }
-  decoder = labcomm_decoder_new(introspecting->reader, 
-				labcomm_default_error_handler,
-				labcomm_default_memory,
+  decoder = labcomm2014_decoder_new(introspecting->reader, 
+				labcomm2014_default_error_handler,
+				labcomm2014_default_memory,
 				scheduler);
-  encoder = labcomm_encoder_new(introspecting->writer, 
-				labcomm_default_error_handler,
-				labcomm_default_memory,
+  encoder = labcomm2014_encoder_new(introspecting->writer, 
+				labcomm2014_default_error_handler,
+				labcomm2014_default_memory,
 				scheduler);
   pthread_t rdt;
   pthread_create(&rdt, NULL, run_decoder, decoder);  
-  labcomm_encoder_register_types_A(encoder);
-  labcomm_encoder_register_types_B(encoder);
-  labcomm_encoder_register_types_Terminate(encoder);
+  labcomm2014_encoder_register_types_A(encoder);
+  labcomm2014_encoder_register_types_B(encoder);
+  labcomm2014_encoder_register_types_Terminate(encoder);
 
-  err = labcomm_decoder_ioctl_types_Sum(decoder, SET_DECIMATION, 2);
-  err = labcomm_decoder_ioctl_types_Diff(decoder, SET_DECIMATION, 4);
+  err = labcomm2014_decoder_ioctl_types_Sum(decoder, SET_DECIMATION, 2);
+  err = labcomm2014_decoder_ioctl_types_Diff(decoder, SET_DECIMATION, 4);
 
-  next = labcomm_scheduler_now(scheduler);
+  next = labcomm2014_scheduler_now(scheduler);
   for (i = 0 ; i < 4 ; i++) {
     if (i == 2) {
-      labcomm_decoder_register_types_Product(decoder, handle_Product, NULL);
+      labcomm2014_decoder_register_types_Product(decoder, handle_Product, NULL);
     }
     for (j = 0 ; j < 4 ; j++) {
       printf("\nA=%d B=%d: ", i, j);
-      labcomm_encode_types_A(encoder, &i);
-      labcomm_encode_types_B(encoder, &j);
-      labcomm_time_add_usec(next, 100000);
-      labcomm_scheduler_sleep(scheduler, next);
+      labcomm2014_encode_types_A(encoder, &i);
+      labcomm2014_encode_types_B(encoder, &j);
+      labcomm2014_time_add_usec(next, 100000);
+      labcomm2014_scheduler_sleep(scheduler, next);
     }
   }
   printf("\n");
-  labcomm_encode_types_Terminate(encoder);
+  labcomm2014_encode_types_Terminate(encoder);
 out:
   return 0;
   
diff --git a/examples/twoway/decimating.c b/examples/twoway/decimating.c
index ea3cfab03d0c3544511a62845c64ec36e4ec4a17..705f4cec837bdd8aeeb4585881f8bd19ec09449a 100644
--- a/examples/twoway/decimating.c
+++ b/examples/twoway/decimating.c
@@ -23,18 +23,18 @@
 #include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include "labcomm_private.h"
+#include "labcomm2014_private.h"
 #include "decimating.h"
 #include "gen/decimating_messages.h"
 
 struct decimating_private {
   struct decimating decimating;
-  struct labcomm_error_handler *error;
-  struct labcomm_memory *memory;
-  struct labcomm_scheduler *scheduler;
+  struct labcomm2014_error_handler *error;
+  struct labcomm2014_memory *memory;
+  struct labcomm2014_scheduler *scheduler;
   int encoder_initialized;
-  struct labcomm_reader_action_context reader_action_context;
-  struct labcomm_writer_action_context writer_action_context;
+  struct labcomm2014_reader_action_context reader_action_context;
+  struct labcomm2014_writer_action_context writer_action_context;
   LABCOMM_SIGNATURE_ARRAY_DEF(writer_decimation, 
 			      struct decimation {
 				int n;
@@ -50,25 +50,25 @@ static void set_decimation(
   struct decimating_private *decimating = context;
   struct decimation *decimation;
 
-  labcomm_scheduler_data_lock(decimating->scheduler);
+  labcomm2014_scheduler_data_lock(decimating->scheduler);
   decimation = LABCOMM_SIGNATURE_ARRAY_REF(decimating->memory,
 					   decimating->writer_decimation, 
 					   struct decimation, 
 					   value->signature_index);
   decimation->n = value->decimation;
   decimation->current = 0;
-  labcomm_scheduler_data_unlock(decimating->scheduler);
+  labcomm2014_scheduler_data_unlock(decimating->scheduler);
 }
 
 static int wrap_reader_alloc(
-  struct labcomm_reader *r, 
-  struct labcomm_reader_action_context *action_context)
+  struct labcomm2014_reader *r, 
+  struct labcomm2014_reader_action_context *action_context)
 {
   struct decimating_private *decimating = action_context->context;
   
-  labcomm_decoder_register_decimating_messages_set_decimation(
+  labcomm2014_decoder_register_decimating_messages_set_decimation(
     r->decoder, set_decimation, decimating);
-  return labcomm_reader_alloc(r, action_context->next);
+  return labcomm2014_reader_alloc(r, action_context->next);
 }
 
 struct send_set_decimation {
@@ -80,11 +80,11 @@ struct send_set_decimation {
 static void send_set_decimation(void *arg)
 {
   struct send_set_decimation *msg = arg;
-  struct labcomm_memory *memory = msg->decimating->memory;
+  struct labcomm2014_memory *memory = msg->decimating->memory;
 
-  labcomm_encode_decimating_messages_set_decimation(
+  labcomm2014_encode_decimating_messages_set_decimation(
     msg->decimating->decimating.writer->encoder, &msg->set_decimation);
-  labcomm_memory_free(memory, 1, msg);
+  labcomm2014_memory_free(memory, 1, msg);
 }
 
 static void enqueue_decimation(struct decimating_private *decimating,
@@ -92,21 +92,21 @@ static void enqueue_decimation(struct decimating_private *decimating,
 			       int amount) 
 {
   struct send_set_decimation *msg;
-  msg = labcomm_memory_alloc(decimating->memory, 1, sizeof(*msg));
+  msg = labcomm2014_memory_alloc(decimating->memory, 1, sizeof(*msg));
   if (msg) {
     msg->decimating = decimating;
     msg->set_decimation.decimation = amount;
     msg->set_decimation.signature_index = remote_index;
     
-    labcomm_scheduler_enqueue(decimating->scheduler, 0, 
+    labcomm2014_scheduler_enqueue(decimating->scheduler, 0, 
 			      send_set_decimation, msg);
   }
 }
 
 static int wrap_reader_start(
-  struct labcomm_reader *r, 
-  struct labcomm_reader_action_context *action_context,
-  int local_index, int remote_index, const struct labcomm_signature *signature,
+  struct labcomm2014_reader *r, 
+  struct labcomm2014_reader_action_context *action_context,
+  int local_index, int remote_index, const struct labcomm2014_signature *signature,
   void *value)
 {
   struct decimating_private *decimating = action_context->context;
@@ -114,26 +114,26 @@ static int wrap_reader_start(
   if (value == NULL) {
     int *decimation, amount;
     
-    labcomm_scheduler_data_lock(decimating->scheduler);
+    labcomm2014_scheduler_data_lock(decimating->scheduler);
     decimation = LABCOMM_SIGNATURE_ARRAY_REF(decimating->memory,
 					     decimating->reader_decimation, 
 					     int,
 					     local_index);
     amount = *decimation;
-    labcomm_scheduler_data_unlock(decimating->scheduler);
+    labcomm2014_scheduler_data_unlock(decimating->scheduler);
     if (remote_index != 0 && amount != 0) {
       enqueue_decimation(decimating, remote_index, amount);
     }
   }
-  return labcomm_reader_start(r, action_context->next, 
+  return labcomm2014_reader_start(r, action_context->next, 
                               local_index, remote_index, signature, value);
 }
 
 static int wrap_reader_ioctl(
-  struct labcomm_reader *r,   
-  struct labcomm_reader_action_context *action_context,
+  struct labcomm2014_reader *r,   
+  struct labcomm2014_reader_action_context *action_context,
   int local_index, int remote_index,
-  const struct labcomm_signature *signature, 
+  const struct labcomm2014_signature *signature, 
   uint32_t action, va_list args)
 {
   struct decimating_private *decimating = action_context->context;
@@ -147,26 +147,26 @@ static int wrap_reader_ioctl(
     amount = va_arg(va, int);
     va_end(va);
    
-    labcomm_scheduler_data_lock(decimating->scheduler);
+    labcomm2014_scheduler_data_lock(decimating->scheduler);
     decimation = LABCOMM_SIGNATURE_ARRAY_REF(decimating->memory,
 					     decimating->reader_decimation, 
 					     int,
 					     local_index);
     *decimation = amount;
-    labcomm_scheduler_data_unlock(decimating->scheduler);
+    labcomm2014_scheduler_data_unlock(decimating->scheduler);
     if (remote_index) {
       enqueue_decimation(decimating, remote_index, amount);
     }
     
   } else {
-    return labcomm_reader_ioctl(r, action_context->next,
+    return labcomm2014_reader_ioctl(r, action_context->next,
 				local_index, remote_index, signature, 
 				action, args);
   }
   return 0;
 }
 
-struct labcomm_reader_action decimating_reader_action = {
+struct labcomm2014_reader_action decimating_reader_action = {
   .alloc = wrap_reader_alloc,
   .free = NULL,
   .start = wrap_reader_start,
@@ -179,25 +179,25 @@ static void register_signatures(void *context)
 {
   struct decimating_private *decimating = context;
 
-  labcomm_encoder_register_decimating_messages_set_decimation(
+  labcomm2014_encoder_register_decimating_messages_set_decimation(
     decimating->decimating.writer->encoder);
 }
 
 static int wrap_writer_alloc(
-  struct labcomm_writer *w, 
-  struct labcomm_writer_action_context *action_context)
+  struct labcomm2014_writer *w, 
+  struct labcomm2014_writer_action_context *action_context)
 {
   struct decimating_private *decimating = action_context->context;
 
-  labcomm_scheduler_enqueue(decimating->scheduler, 
+  labcomm2014_scheduler_enqueue(decimating->scheduler, 
 			    0, register_signatures, decimating);
-  return labcomm_writer_alloc(w, action_context->next);
+  return labcomm2014_writer_alloc(w, action_context->next);
 }
 
 static int wrap_writer_start(
-  struct labcomm_writer *w, 
-  struct labcomm_writer_action_context *action_context, 
-  int index, const struct labcomm_signature *signature,
+  struct labcomm2014_writer *w, 
+  struct labcomm2014_writer_action_context *action_context, 
+  int index, const struct labcomm2014_signature *signature,
   void *value)
 {
   struct decimating_private *decimating = action_context->context;
@@ -207,7 +207,7 @@ static int wrap_writer_start(
   if (index < LABCOMM_USER) {
     result = 0;
   } else {
-    labcomm_scheduler_data_lock(decimating->scheduler);
+    labcomm2014_scheduler_data_lock(decimating->scheduler);
     decimation = LABCOMM_SIGNATURE_ARRAY_REF(decimating->memory, 
                                              decimating->writer_decimation, 
                                              struct decimation, index);
@@ -218,16 +218,16 @@ static int wrap_writer_start(
       decimation->current = 0;
       result = 0;
     }
-    labcomm_scheduler_data_unlock(decimating->scheduler);
+    labcomm2014_scheduler_data_unlock(decimating->scheduler);
   }
   if (result == 0) {
-    result = labcomm_writer_start(w, action_context->next,
+    result = labcomm2014_writer_start(w, action_context->next,
 				 index, signature, value);
   }
   return result;
 }
 
-struct labcomm_writer_action decimating_writer_action = {
+struct labcomm2014_writer_action decimating_writer_action = {
   .alloc = wrap_writer_alloc,
   .free = NULL, 
   .start = wrap_writer_start,
@@ -237,11 +237,11 @@ struct labcomm_writer_action decimating_writer_action = {
 };
 
 struct decimating *decimating_new(
-  struct labcomm_reader *reader,
-  struct labcomm_writer *writer,
-  struct labcomm_error_handler *error,
-  struct labcomm_memory *memory,
-  struct labcomm_scheduler *scheduler)
+  struct labcomm2014_reader *reader,
+  struct labcomm2014_writer *writer,
+  struct labcomm2014_error_handler *error,
+  struct labcomm2014_memory *memory,
+  struct labcomm2014_scheduler *scheduler)
 {
   struct decimating_private *result;
 
diff --git a/examples/twoway/decimating.h b/examples/twoway/decimating.h
index cdfedd7a5417dab9360d96add30e01b14ca13c9e..3d91c675e036c0548f0121f88db35aca2891f1b8 100644
--- a/examples/twoway/decimating.h
+++ b/examples/twoway/decimating.h
@@ -1,20 +1,20 @@
 #ifndef __DECIMATING_H__
 #define __DECIMATING_H__
 
-#include <labcomm.h>
-#include <labcomm_ioctl.h>
+#include <labcomm2014.h>
+#include <labcomm2014_ioctl.h>
 
 struct decimating {
-  struct labcomm_reader *reader;
-  struct labcomm_writer *writer;
+  struct labcomm2014_reader *reader;
+  struct labcomm2014_writer *writer;
 };
 
 extern struct decimating *decimating_new(
-  struct labcomm_reader *reader,
-  struct labcomm_writer *writer,
-  struct labcomm_error_handler *error,
-  struct labcomm_memory *memory,
-  struct labcomm_scheduler *scheduler);
+  struct labcomm2014_reader *reader,
+  struct labcomm2014_writer *writer,
+  struct labcomm2014_error_handler *error,
+  struct labcomm2014_memory *memory,
+  struct labcomm2014_scheduler *scheduler);
 
 #define SET_DECIMATION LABCOMM_IOSW('d',0,int)
 
diff --git a/examples/twoway/introspecting.c b/examples/twoway/introspecting.c
index 3c64c191eda23acb92bfb0d3ef373b2887e0e742..87bffeb4f6b4a6c7dc6eb135e1a8245e95c700f4 100644
--- a/examples/twoway/introspecting.c
+++ b/examples/twoway/introspecting.c
@@ -23,18 +23,18 @@
 #include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include "labcomm_private.h"
+#include "labcomm2014_private.h"
 #include "introspecting.h"
 #include "gen/introspecting_messages.h"
 
 struct introspecting_private {
   struct introspecting introspecting;
-  struct labcomm_error_handler *error;
-  struct labcomm_memory *memory;
-  struct labcomm_scheduler *scheduler;
+  struct labcomm2014_error_handler *error;
+  struct labcomm2014_memory *memory;
+  struct labcomm2014_scheduler *scheduler;
 
-  struct labcomm_reader_action_context reader_action_context;
-  struct labcomm_writer_action_context writer_action_context;
+  struct labcomm2014_reader_action_context reader_action_context;
+  struct labcomm2014_writer_action_context writer_action_context;
   LABCOMM_SIGNATURE_ARRAY_DEF(remote, 
 			      struct remote {
 				char *name;
@@ -44,13 +44,13 @@ struct introspecting_private {
   LABCOMM_SIGNATURE_ARRAY_DEF(local, 
 			      struct local {
 				enum introspecting_status status;
-				const struct labcomm_signature *signature;
+				const struct labcomm2014_signature *signature;
 			      });
 };
 
 static struct local *get_local(struct introspecting_private *introspecting,
 			       int index,
-			       const struct labcomm_signature *signature)
+			       const struct labcomm2014_signature *signature)
 {
   /* Called with data_lock held */
   struct local *local;
@@ -91,7 +91,7 @@ static void handles_signature(
   struct introspecting_private *introspecting = context;
   struct remote *remote;
 
-  labcomm_scheduler_data_lock(introspecting->scheduler);
+  labcomm2014_scheduler_data_lock(introspecting->scheduler);
   remote = LABCOMM_SIGNATURE_ARRAY_REF(introspecting->memory,
 				       introspecting->remote, 
 				       struct remote, 
@@ -119,25 +119,25 @@ static void handles_signature(
       }
     }
   }
-  labcomm_scheduler_data_unlock(introspecting->scheduler);
+  labcomm2014_scheduler_data_unlock(introspecting->scheduler);
 }
 
 static int wrap_reader_alloc(
-  struct labcomm_reader *r, 
-  struct labcomm_reader_action_context *action_context)
+  struct labcomm2014_reader *r, 
+  struct labcomm2014_reader_action_context *action_context)
 {
   struct introspecting_private *introspecting = action_context->context;
 
-  labcomm_decoder_register_introspecting_messages_handles_signature(
+  labcomm2014_decoder_register_introspecting_messages_handles_signature(
     introspecting->introspecting.reader->decoder, 
     handles_signature, introspecting);
-  return labcomm_reader_alloc(r, action_context->next);
+  return labcomm2014_reader_alloc(r, action_context->next);
 }
 
 struct handles_signature {
   struct introspecting_private *introspecting;
   int index;
-  const struct labcomm_signature *signature;
+  const struct labcomm2014_signature *signature;
 };
 
 static void send_handles_signature(void *arg)
@@ -149,14 +149,14 @@ static void send_handles_signature(void *arg)
   handles_signature.name = h->signature->name;
   handles_signature.signature.n_0 = h->signature->size;
   handles_signature.signature.a = h->signature->signature;
-  labcomm_encode_introspecting_messages_handles_signature(
+  labcomm2014_encode_introspecting_messages_handles_signature(
     h->introspecting->introspecting.writer->encoder, &handles_signature);
 }
 
 static int wrap_reader_start(
-  struct labcomm_reader *r, 
-  struct labcomm_reader_action_context *action_context,
-  int local_index, int remote_index, const struct labcomm_signature *signature,
+  struct labcomm2014_reader *r, 
+  struct labcomm2014_reader_action_context *action_context,
+  int local_index, int remote_index, const struct labcomm2014_signature *signature,
   void *value)
 {
   struct introspecting_private *introspecting = action_context->context;
@@ -164,23 +164,23 @@ static int wrap_reader_start(
   if (value == NULL) {
     struct handles_signature *handles_signature;
 
-    handles_signature = labcomm_memory_alloc(introspecting->memory, 1,
+    handles_signature = labcomm2014_memory_alloc(introspecting->memory, 1,
 					     sizeof(*handles_signature));
     handles_signature->introspecting = introspecting;
     handles_signature->index = local_index;
     handles_signature->signature = signature;
-    labcomm_scheduler_enqueue(introspecting->scheduler, 
+    labcomm2014_scheduler_enqueue(introspecting->scheduler, 
 			      0, send_handles_signature, handles_signature);
   }
-  return labcomm_reader_start(r, action_context->next, 
+  return labcomm2014_reader_start(r, action_context->next, 
 			      local_index, remote_index, signature, value);
 }
 
  void encode_handles_signature(
-  struct labcomm_encoder *encoder,
+  struct labcomm2014_encoder *encoder,
   void *context)
 {
-  const struct labcomm_signature *signature = context;
+  const struct labcomm2014_signature *signature = context;
   introspecting_messages_handles_signature handles_signature;
   int index = 0;
 
@@ -189,11 +189,11 @@ static int wrap_reader_start(
   handles_signature.signature.n_0 = signature->size;
   handles_signature.signature.a = signature->signature;
 
-  labcomm_encode_introspecting_messages_handles_signature(
+  labcomm2014_encode_introspecting_messages_handles_signature(
     NULL, &handles_signature);
 }
 
-struct labcomm_reader_action introspecting_reader_action = {
+struct labcomm2014_reader_action introspecting_reader_action = {
   .alloc = wrap_reader_alloc,
   .free = NULL,
   .start = wrap_reader_start,
@@ -206,25 +206,25 @@ static void register_encoder_signatures(void *context)
 {
   struct introspecting_private *introspecting = context;
 
-  labcomm_encoder_register_introspecting_messages_handles_signature(
+  labcomm2014_encoder_register_introspecting_messages_handles_signature(
     introspecting->introspecting.writer->encoder);
 }
 
 static int wrap_writer_alloc(
-  struct labcomm_writer *w, 
-  struct labcomm_writer_action_context *action_context)
+  struct labcomm2014_writer *w, 
+  struct labcomm2014_writer_action_context *action_context)
 {
   struct introspecting_private *introspecting = action_context->context;
 
-  labcomm_scheduler_enqueue(introspecting->scheduler, 
+  labcomm2014_scheduler_enqueue(introspecting->scheduler, 
 			    0, register_encoder_signatures, introspecting);
-  return labcomm_writer_alloc(w, action_context->next);
+  return labcomm2014_writer_alloc(w, action_context->next);
 }
 
 static int wrap_writer_start(
-  struct labcomm_writer *w, 
-  struct labcomm_writer_action_context *action_context, 
-  int index, const struct labcomm_signature *signature,
+  struct labcomm2014_writer *w, 
+  struct labcomm2014_writer_action_context *action_context, 
+  int index, const struct labcomm2014_signature *signature,
   void *value)
 {
   struct introspecting_private *introspecting = action_context->context;
@@ -232,18 +232,18 @@ static int wrap_writer_start(
   if (index >= LABCOMM_USER && value == NULL) {
     struct local *local;
 
-    labcomm_scheduler_data_lock(introspecting->scheduler);
+    labcomm2014_scheduler_data_lock(introspecting->scheduler);
     local = get_local(introspecting, index, signature);
     local->status = introspecting_registered;
-    labcomm_scheduler_data_unlock(introspecting->scheduler);
+    labcomm2014_scheduler_data_unlock(introspecting->scheduler);
   }
-  return labcomm_writer_start(w, action_context->next, index, signature, value);
+  return labcomm2014_writer_start(w, action_context->next, index, signature, value);
 }
 
 static int wrap_writer_ioctl(
-  struct labcomm_writer *w, 
-  struct labcomm_writer_action_context *action_context, 
-  int index, const struct labcomm_signature *signature, 
+  struct labcomm2014_writer *w, 
+  struct labcomm2014_writer_action_context *action_context, 
+  int index, const struct labcomm2014_signature *signature, 
   uint32_t ioctl_action, va_list args)
 {
   struct introspecting_private *introspecting = action_context->context;
@@ -253,20 +253,20 @@ static int wrap_writer_ioctl(
       struct local *local;
       int result;
 
-      labcomm_scheduler_data_lock(introspecting->scheduler);
+      labcomm2014_scheduler_data_lock(introspecting->scheduler);
       local = get_local(introspecting, index, signature);
       result = local->status;
-      labcomm_scheduler_data_unlock(introspecting->scheduler);
+      labcomm2014_scheduler_data_unlock(introspecting->scheduler);
       return result;
     }
     default: {
-      return labcomm_writer_ioctl(w, action_context->next, index, signature, 
+      return labcomm2014_writer_ioctl(w, action_context->next, index, signature, 
 				  ioctl_action, args);  
     } break;
   }
 }
 
-struct labcomm_writer_action introspecting_writer_action = {
+struct labcomm2014_writer_action introspecting_writer_action = {
   .alloc = wrap_writer_alloc,
   .free = NULL, 
   .start = wrap_writer_start,
@@ -276,11 +276,11 @@ struct labcomm_writer_action introspecting_writer_action = {
 };
 
 extern struct introspecting *introspecting_new(
-  struct labcomm_reader *reader,
-  struct labcomm_writer *writer,
-  struct labcomm_error_handler *error,
-  struct labcomm_memory *memory,
-  struct labcomm_scheduler *scheduler)
+  struct labcomm2014_reader *reader,
+  struct labcomm2014_writer *writer,
+  struct labcomm2014_error_handler *error,
+  struct labcomm2014_memory *memory,
+  struct labcomm2014_scheduler *scheduler)
 {
   struct introspecting_private *result;
 
diff --git a/examples/twoway/introspecting.h b/examples/twoway/introspecting.h
index 984670deef5bc7a4c1bfc554ef47b05846e294b8..bcd3be787865f1fa7a5d488cb48027845d108b93 100644
--- a/examples/twoway/introspecting.h
+++ b/examples/twoway/introspecting.h
@@ -23,22 +23,22 @@
 #ifndef __INTROSPECTING_H__
 #define __INTROSPECTING_H__
 
-#include <labcomm.h>
-#include <labcomm_ioctl.h>
-#include <labcomm_fd_reader.h>
-#include <labcomm_fd_writer.h>
+#include <labcomm2014.h>
+#include <labcomm2014_ioctl.h>
+#include <labcomm2014_fd_reader.h>
+#include <labcomm2014_fd_writer.h>
 
 struct introspecting {
-  struct labcomm_reader *reader;
-  struct labcomm_writer *writer;
+  struct labcomm2014_reader *reader;
+  struct labcomm2014_writer *writer;
 };
 
 extern struct introspecting *introspecting_new(
-  struct labcomm_reader *reader,
-  struct labcomm_writer *writer,
-  struct labcomm_error_handler *error,
-  struct labcomm_memory *memory,
-  struct labcomm_scheduler *scheduler);
+  struct labcomm2014_reader *reader,
+  struct labcomm2014_writer *writer,
+  struct labcomm2014_error_handler *error,
+  struct labcomm2014_memory *memory,
+  struct labcomm2014_scheduler *scheduler);
 
 #define HAS_SIGNATURE LABCOMM_IOS('i',2)
 enum introspecting_status { introspecting_unknown, 
diff --git a/examples/twoway/server.c b/examples/twoway/server.c
index e6eaac0ad7b2b254c65ec3ab46628ead6e0dd621..152f8a9f6a7d92e56e0fbb3d0a40678c7cdae361 100644
--- a/examples/twoway/server.c
+++ b/examples/twoway/server.c
@@ -33,11 +33,11 @@
 #include <sys/socket.h>
 #include <sys/types.h>
 #include <unistd.h>
-#include <labcomm_default_error_handler.h>
-#include <labcomm_default_memory.h>
-#include <labcomm_pthread_scheduler.h>
-#include <labcomm_fd_reader.h>
-#include <labcomm_fd_writer.h>
+#include <labcomm2014_default_error_handler.h>
+#include <labcomm2014_default_memory.h>
+#include <labcomm2014_pthread_scheduler.h>
+#include <labcomm2014_fd_reader.h>
+#include <labcomm2014_fd_writer.h>
 #include "decimating.h"
 #include "introspecting.h"
 #include "gen/types.h"
@@ -49,9 +49,9 @@ struct client {
   struct sockaddr_in adr;
   unsigned int adrlen;
   int32_t A, B, Sum, Diff, Product;
-  struct labcomm_decoder *decoder;
-  struct labcomm_encoder *encoder;
-  struct labcomm_scheduler *scheduler;
+  struct labcomm2014_decoder *decoder;
+  struct labcomm2014_encoder *encoder;
+  struct labcomm2014_scheduler *scheduler;
 };
 
 static void handle_A(int32_t *value, void *context)
@@ -67,22 +67,22 @@ static void handle_B(int32_t *value, void *context)
   int status;
 
   client->B = *value;
-  status = labcomm_encoder_ioctl_types_Product(client->encoder, HAS_SIGNATURE);
+  status = labcomm2014_encoder_ioctl_types_Product(client->encoder, HAS_SIGNATURE);
   switch (status) {
     case introspecting_unregistered:
-      labcomm_encoder_register_types_Product(client->encoder);
+      labcomm2014_encoder_register_types_Product(client->encoder);
       /* fall through */
     case introspecting_registered:
       client->Product = client->A * client->B;
-      labcomm_encode_types_Product(client->encoder, &client->Product);
+      labcomm2014_encode_types_Product(client->encoder, &client->Product);
       break;
     default:
       break;
   }
   client->Sum = client->A + client->B;
   client->Diff = client->A - client->B;
-  labcomm_encode_types_Sum(client->encoder, &client->Sum);
-  labcomm_encode_types_Diff(client->encoder, &client->Diff);
+  labcomm2014_encode_types_Sum(client->encoder, &client->Sum);
+  labcomm2014_encode_types_Diff(client->encoder, &client->Diff);
 }
 
 static void handle_Terminate(types_Terminate *value, void *context)
@@ -95,14 +95,14 @@ static void *run_decoder(void *arg)
   struct client *client = arg;
   int result;
 
-  labcomm_decoder_register_types_A(client->decoder, handle_A, client);
-  labcomm_decoder_register_types_B(client->decoder, handle_B, client);
-  labcomm_decoder_register_types_Terminate(client->decoder, handle_Terminate, 
+  labcomm2014_decoder_register_types_A(client->decoder, handle_A, client);
+  labcomm2014_decoder_register_types_B(client->decoder, handle_B, client);
+  labcomm2014_decoder_register_types_Terminate(client->decoder, handle_Terminate, 
 					   NULL);
   do {
-    result = labcomm_decoder_decode_one(client->decoder);
+    result = labcomm2014_decoder_decode_one(client->decoder);
   } while (result >= 0);
-  labcomm_scheduler_wakeup(client->scheduler);
+  labcomm2014_scheduler_wakeup(client->scheduler);
   return NULL;
 }
 
@@ -115,13 +115,13 @@ static void *run_client(void *arg)
   printf("Client start\n");
   client->A = 0;
   client->B = 0;
-  client->scheduler = labcomm_pthread_scheduler_new(labcomm_default_memory);
-  decimating = decimating_new(labcomm_fd_reader_new(labcomm_default_memory,
+  client->scheduler = labcomm2014_pthread_scheduler_new(labcomm2014_default_memory);
+  decimating = decimating_new(labcomm2014_fd_reader_new(labcomm2014_default_memory,
 						    client->fd, 1),
-			      labcomm_fd_writer_new(labcomm_default_memory,
+			      labcomm2014_fd_writer_new(labcomm2014_default_memory,
 						    client->fd, 0),
-			      labcomm_default_error_handler,
-			      labcomm_default_memory,
+			      labcomm2014_default_error_handler,
+			      labcomm2014_default_memory,
 			      client->scheduler);
   if (decimating == NULL) {
     /* Warning: might leak reader and writer at this point */
@@ -129,26 +129,26 @@ static void *run_client(void *arg)
   }
   introspecting = introspecting_new(decimating->reader,
 				    decimating->writer,
-				    labcomm_default_error_handler,
-				    labcomm_default_memory,
+				    labcomm2014_default_error_handler,
+				    labcomm2014_default_memory,
 				    client->scheduler);
   if (introspecting == NULL) {
     /* Warning: might leak reader and writer at this point */
     goto out;
   }
-  client->decoder = labcomm_decoder_new(introspecting->reader,
-				    labcomm_default_error_handler,
-				    labcomm_default_memory,
+  client->decoder = labcomm2014_decoder_new(introspecting->reader,
+				    labcomm2014_default_error_handler,
+				    labcomm2014_default_memory,
 				    client->scheduler);
-  client->encoder = labcomm_encoder_new(introspecting->writer,
-				    labcomm_default_error_handler,
-				    labcomm_default_memory,
+  client->encoder = labcomm2014_encoder_new(introspecting->writer,
+				    labcomm2014_default_error_handler,
+				    labcomm2014_default_memory,
 				    client->scheduler);
   pthread_t rdt;
   pthread_create(&rdt, NULL, run_decoder, client);  
-  labcomm_encoder_register_types_Sum(client->encoder);
-  labcomm_encoder_register_types_Diff(client->encoder);
-  labcomm_scheduler_sleep(client->scheduler, NULL);
+  labcomm2014_encoder_register_types_Sum(client->encoder);
+  labcomm2014_encoder_register_types_Diff(client->encoder);
+  labcomm2014_scheduler_sleep(client->scheduler, NULL);
   printf("Awoken\n");
   pthread_join(rdt, NULL);
 out:
diff --git a/examples/user_types/.gitignore b/examples/user_types/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..711968fb67b7a45c107a2b3a0dcf57484f1f9c2f
--- /dev/null
+++ b/examples/user_types/.gitignore
@@ -0,0 +1,10 @@
+gen
+labcomm2014.dll
+ExampleDecoder.exe
+ExampleEncoder.exe
+encoded_data_c
+encoded_data_cs
+encoded_data_j
+encoded_data_p
+example_decoder
+example_encoder
diff --git a/examples/user_types/Decoder.java b/examples/user_types/Decoder.java
index bdb17374517015db59e66c02c3144b9d9bf886bc..a0e7521a08bfd41867e4371bf6651657bca0303c 100644
--- a/examples/user_types/Decoder.java
+++ b/examples/user_types/Decoder.java
@@ -1,22 +1,46 @@
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.InputStream;
+import java.io.IOException;
 
-import se.lth.control.labcomm.DecoderChannel;
+import se.lth.control.labcomm2014.DecoderChannel;
+import se.lth.control.labcomm2014.TypeDef;
+import se.lth.control.labcomm2014.TypeDefParser;
+//import se.lth.control.labcomm2014.TypeBinding;
 
 public class Decoder
-  implements twoLines.Handler
-
+  implements twoLines.Handler,
+//             TypeDef.Handler,
+//             TypeBinding.Handler,
+             TypeDefParser.TypeDefListener,
+             twoInts.Handler,
+             theFirstInt.Handler,
+             theSecondInt.Handler,
+             doavoid.Handler,
+             intAndRef.Handler
 {
 
-  DecoderChannel decoder;
+  private DecoderChannel decoder;
+  private TypeDefParser tdp;
 
   public Decoder(InputStream in) 
     throws Exception 
   {
     decoder = new DecoderChannel(in);
+    doavoid.register(decoder, this);
+    twoInts.register(decoder, this);
     twoLines.register(decoder, this);
+    theFirstInt.register(decoder, this);
+    theSecondInt.register(decoder, this);
+    intAndRef.register(decoder, this);
+    doavoid.registerSampleRef(decoder);
+    this.tdp = TypeDefParser.registerTypeDefParser(decoder); 
+ //   TypeDef.register(decoder, this);
+ //   TypeBinding.register(decoder, this);
 
+        
+    tdp.addListener(this);
+    
     try {
       System.out.println("Running decoder.");
       decoder.run();
@@ -33,6 +57,48 @@ public class Decoder
     return "Line from "+genPoint(l.start)+" to "+genPoint(l.end);
   }
 
+//  public void handle_TypeDef(TypeDef d) throws java.io.IOException {
+//    System.out.println("Got TypeDef: "+d.getName()+"("+d.getIndex()+")");
+//  }
+//
+//  public void handle_TypeBinding(TypeBinding d) throws java.io.IOException {
+//    System.out.println("Got TypeBinding: "+d.getSampleIndex()+" --> "+d.getTypeIndex()+"");
+//  }
+
+  public void onTypeDef(TypeDefParser.ParsedTypeDef d) {
+    System.out.println("ontype_def: ");
+    System.out.print((d.isSampleDef()?"sample ":"typedef ")+d);
+    System.out.println(" "+d.getName()+";");
+    //for(byte b: d.getSignature()) {
+    //   System.out.print(Integer.toHexString(b)+" ");
+    //}
+    //System.out.println(); 
+    //try {
+    //   tdp.parseSignature(d.getIndex());
+    //} catch(IOException ex) { ex.printStackTrace();}   
+  }
+
+  public void handle_doavoid() throws java.io.IOException {
+    System.out.println("Got a void.");
+  }
+
+  public void handle_twoInts(twoInts d) throws java.io.IOException {
+    System.out.print("Got twoInts: ");
+    System.out.println(d.a +", "+d.b);
+  }
+
+  public void handle_theFirstInt(int d) throws java.io.IOException {
+    System.out.println("Got theFirstInt: "+d);
+  }
+
+  public void handle_theSecondInt(int d) throws java.io.IOException {
+    System.out.println("Got theSecondInt: "+d);
+  }
+
+  public void handle_intAndRef(intAndRef d) throws java.io.IOException {
+    System.out.println("Got intAndRef: "+d.x+", "+d.reference);
+  }
+
   public void handle_twoLines(twoLines d) throws java.io.IOException {
     System.out.print("Got twoLines: ");
     System.out.println("Line l1: "+genLine(d.l1));
diff --git a/examples/user_types/Encoder.java b/examples/user_types/Encoder.java
index aa2f80e9617aa3b47b468f4d46469573743a8bc9..58f6cd0a8e57191f9337a3e2771a89b05bb1e31d 100644
--- a/examples/user_types/Encoder.java
+++ b/examples/user_types/Encoder.java
@@ -2,7 +2,7 @@ import java.io.File;
 import java.io.FileOutputStream;
 import java.io.OutputStream;
 
-import se.lth.control.labcomm.EncoderChannel;
+import se.lth.control.labcomm2014.EncoderChannel;
 
 /**
  * Simple encoder 
@@ -16,10 +16,37 @@ public class Encoder
     throws Exception 
   {
     encoder = new EncoderChannel(out);
+    doavoid.register(encoder);
+    twoInts.register(encoder);
     twoLines.register(encoder);
+    theFirstInt.register(encoder);
+    theSecondInt.register(encoder);
+    intAndRef.register(encoder);
+    doavoid.registerSampleRef(encoder);
   }
 
   public void doEncode() throws java.io.IOException {
+    System.out.println("Encoding doavoid");
+    doavoid.encode(encoder);
+      
+    intAndRef iar = new intAndRef();
+    iar.x = 17;
+    iar.reference = doavoid.class;
+
+    System.out.println("Encoding intAndRef");
+    intAndRef.encode(encoder, iar);
+
+    twoInts ti = new twoInts();
+    ti.a = 12;
+    ti.b = 21;
+
+    System.out.println("Encoding twoInts");
+    twoInts.encode(encoder, ti);
+      
+    System.out.println("Encoding the Ints");
+    theFirstInt.encode(encoder, 71);
+    theSecondInt.encode(encoder, 24);
+
     twoLines x = new twoLines();
     line l1 = new line();
     point p11 = new point();
diff --git a/examples/user_types/ExampleDecoder.cs b/examples/user_types/ExampleDecoder.cs
index 1b6bc0d2ae2e96e3e5213afaadddbbf10245f286..77666728c6e59b68b105677090166e8749a2e6a2 100644
--- a/examples/user_types/ExampleDecoder.cs
+++ b/examples/user_types/ExampleDecoder.cs
@@ -1,49 +1,87 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.IO;
-using se.lth.control.labcomm;
-
-namespace user_types
-{
-    class Decoder : twoLines.Handler 
-    {
-        DecoderChannel dec;
-
-        public Decoder(Stream stream)
-        {
-            dec = new DecoderChannel(stream);
-            twoLines.register(dec, this);
-            try
-            {
-                Console.WriteLine("Running decoder.");
-                dec.run();
-            }
-            catch (EndOfStreamException)
-            {
-                Console.WriteLine("EOF reached");
-            }
-        }
-
-        private string genPoint(point p)
-        {
-            return "(" + p.x.val + ", " + p.y.val + ")";
-        }
-        private String genLine(line l)
-        {
-            return "Line from " + genPoint(l.start) + " to " + genPoint(l.end);
-        }
-        public void handle(twoLines d)
-        {
-            Console.WriteLine("Got twoLines: ");
-            Console.WriteLine("Line l1: "+genLine(d.l1));
-            Console.WriteLine("Line l2: " + genLine(d.l2));
-        }
-
-        static void Main(string[] args)
-        {
-            new Decoder(new FileStream(args[0], FileMode.Open));
-        }
-    }
-}
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.IO;
+using se.lth.control.labcomm2014;
+
+namespace user_types
+{
+    class Decoder : twoLines.Handler, 
+                    twoInts.Handler, 
+                    theFirstInt.Handler, 
+                    theSecondInt.Handler,
+                    doavoid.Handler,
+                    intAndRef.Handler
+    {
+        DecoderChannel dec;
+
+        public Decoder(Stream stream)
+        {
+            dec = new DecoderChannel(stream);
+            twoLines.register(dec, this);
+            twoInts.register(dec, this);
+            theFirstInt.register(dec, this);
+            theSecondInt.register(dec, this);
+            doavoid.register(dec, this);
+            intAndRef.register(dec, this);
+            doavoid.registerSampleRef(dec);
+            try
+            {
+                Console.WriteLine("Running decoder.");
+                dec.run();
+            }
+            catch (EndOfStreamException)
+            {
+                Console.WriteLine("EOF reached");
+            }
+        }
+
+        private string genPoint(point p)
+        {
+            return "(" + p.x.val + ", " + p.y.val + ")";
+        }
+        private String genLine(line l)
+        {
+            return "Line from " + genPoint(l.start) + " to " + genPoint(l.end);
+        }
+        public void handle(twoLines d)
+        {
+            Console.WriteLine("Got twoLines: ");
+            Console.WriteLine("Line l1: "+genLine(d.l1));
+            Console.WriteLine("Line l2: " + genLine(d.l2));
+        }
+
+        public void handle(twoInts d)
+        {
+            Console.WriteLine("Got twoInts: ");
+            Console.WriteLine("a: "+d.a);
+            Console.WriteLine("b: "+d.b);
+        }
+
+        void theFirstInt.Handler.handle(int d)
+        {
+            Console.WriteLine("Got theFirstInt: "+d);
+        }
+
+        void theSecondInt.Handler.handle(int d)
+        {
+            Console.WriteLine("Got theSecondInt: "+d);
+        }
+
+        void doavoid.Handler.handle()
+        {
+            Console.WriteLine("Got a void.");
+        }
+
+        void intAndRef.Handler.handle(intAndRef d)
+        {
+            Console.WriteLine("Got intAndRef: "+d.x+" : "+d.reference);
+        }
+
+        static void Main(string[] args)
+        {
+            new Decoder(new FileStream(args[0], FileMode.Open));
+        }
+    }
+}
diff --git a/examples/user_types/ExampleEncoder.cs b/examples/user_types/ExampleEncoder.cs
index c2e2fa9dfa087345cb714441d90075270797c386..d9cfc77635896c4415588a4f0948df0fb938d3b7 100644
--- a/examples/user_types/ExampleEncoder.cs
+++ b/examples/user_types/ExampleEncoder.cs
@@ -1,85 +1,85 @@
-using System;
-using System.IO;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using se.lth.control.labcomm;
-
-namespace user_types
-{
-    public class Encoder
-    {
-        private EncoderChannel enc;
-        public Encoder(Stream stream)
-        {
-            enc = new EncoderChannel(stream);
-            twoLines.register(enc);
-        }
-
-        public void doEncode()
-        {
-            twoLines x = new twoLines();
-            line l1 = new line();
-            point p11 = new point();
-            coord c11x = new coord();
-            coord c11y = new coord();
-            c11x.val = 11;
-            c11y.val = 99;
-            p11.x = c11x;
-            p11.y = c11y;
-
-            l1.start = p11;
-
-            point p12 = new point();
-            coord c12x = new coord();
-            coord c12y = new coord();
-            c12x.val = 22;
-            c12y.val = 88;
-            p12.x = c12x;
-            p12.y = c12y;
-
-            l1.end = p12;
-
-            line l2 = new line();
-            point p21 = new point();
-            coord c21x = new coord();
-            coord c21y = new coord();
-            c21x.val = 17;
-            c21y.val = 42;
-            p21.x = c21x;
-            p21.y = c21y;
-
-            l2.start = p21;
-
-            point p22 = new point();
-            coord c22x = new coord();
-            coord c22y = new coord();
-            c22x.val = 13;
-            c22y.val = 37;
-            p22.x = c22x;
-            p22.y = c22y;
-
-            l2.end = p22;
-
-            foo f = new foo();
-            f.a = 10;
-            f.b = 20;
-            f.c = false;
-
-            x.l1 = l1;
-            x.l2 = l2;
-            x.f = f;
-
-            Console.WriteLine("Encoding theTwoLines");
-            twoLines.encode(enc, x);
-        }
-
-        static void Main(string[] args)
-        {
-            FileStream stream = new FileStream(args[0],FileMode.Create);
-            Encoder example = new Encoder(stream);
-            example.doEncode();
-            stream.Close();
-        }
-    }
-}
+using System;
+using System.IO;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using se.lth.control.labcomm2014;
+
+namespace user_types
+{
+    public class Encoder
+    {
+        private EncoderChannel enc;
+        public Encoder(Stream stream)
+        {
+            enc = new EncoderChannel(stream);
+            twoLines.register(enc);
+        }
+
+        public void doEncode()
+        {
+            twoLines x = new twoLines();
+            line l1 = new line();
+            point p11 = new point();
+            coord c11x = new coord();
+            coord c11y = new coord();
+            c11x.val = 11;
+            c11y.val = 99;
+            p11.x = c11x;
+            p11.y = c11y;
+
+            l1.start = p11;
+
+            point p12 = new point();
+            coord c12x = new coord();
+            coord c12y = new coord();
+            c12x.val = 22;
+            c12y.val = 88;
+            p12.x = c12x;
+            p12.y = c12y;
+
+            l1.end = p12;
+
+            line l2 = new line();
+            point p21 = new point();
+            coord c21x = new coord();
+            coord c21y = new coord();
+            c21x.val = 17;
+            c21y.val = 42;
+            p21.x = c21x;
+            p21.y = c21y;
+
+            l2.start = p21;
+
+            point p22 = new point();
+            coord c22x = new coord();
+            coord c22y = new coord();
+            c22x.val = 13;
+            c22y.val = 37;
+            p22.x = c22x;
+            p22.y = c22y;
+
+            l2.end = p22;
+
+            foo f = new foo();
+            f.a = 10;
+            f.b = 20;
+            f.c = false;
+
+            x.l1 = l1;
+            x.l2 = l2;
+            x.f = f;
+
+            Console.WriteLine("Encoding theTwoLines");
+            twoLines.encode(enc, x);
+        }
+
+        static void Main(string[] args)
+        {
+            FileStream stream = new FileStream(args[0],FileMode.Create);
+            Encoder example = new Encoder(stream);
+            example.doEncode();
+            stream.Close();
+        }
+    }
+}
diff --git a/examples/user_types/Makefile b/examples/user_types/Makefile
index 4af38f677bad712cd6a0701411555d2104d65229..3edbeea1fa722f6a3e6d4b16fc9eb9818109297b 100644
--- a/examples/user_types/Makefile
+++ b/examples/user_types/Makefile
@@ -1,15 +1,16 @@
 LCDIR=../..
-LCCJAR=${LCDIR}/compiler/labcomm2014_compiler.jar  # the LabComm compiler
-LCLJAR=${LCDIR}/lib/java/labcomm2014.jar  # the LabComm library
+LCCJAR=${LCDIR}/compiler/labcomm2014_compiler.jar# the LabComm compiler
+LCLJAR=${LCDIR}/lib/java/labcomm2014.jar# the LabComm library
 
 EXECUTABLES=example_encoder example_decoder \
-	    Encoder.class Decoder.class \
+	    Encoder.class Decoder.class TDDecoder.class \
 	    ExampleEncoder.exe ExampleDecoder.exe
+
 include ${LCDIR}/lib/c/os_compat.mk
 
 GENDIR=gen
 
-.PHONY: all cleanbuild clean distclean build run allall buildcs runwcs
+.PHONY: all cleanbuild clean distclean build run allall buildcs runwcs runjastadd
 
 all: cleanbuild run
 
@@ -33,15 +34,15 @@ ${LCLJAR} :
 
 cleanbuild: clean build
 
-labcomm.dll:
-	ln -sf ../../lib/csharp/labcomm.dll $@
+labcomm2014.dll:
+	ln -sf ../../lib/csharp/labcomm2014.dll $@
 
-ExampleEncoder.exe: ExampleEncoder.cs gen/test.cs labcomm.dll Makefile
-	mcs -out:$@ $(filter %.cs, $^) -lib:../../lib/csharp/ -r:labcomm
+ExampleEncoder.exe: ExampleEncoder.cs gen/test.cs labcomm2014.dll Makefile
+	mcs -out:$@ $(filter %.cs, $^) -lib:../../lib/csharp/ -r:labcomm2014
 	chmod a+x $@
 
-ExampleDecoder.exe: ExampleDecoder.cs gen/test.cs labcomm.dll Makefile
-	mcs -out:$@ $(filter %.cs, $^) -lib:../../lib/csharp/ -r:labcomm
+ExampleDecoder.exe: ExampleDecoder.cs gen/test.cs labcomm2014.dll Makefile
+	mcs -out:$@ $(filter %.cs, $^) -lib:../../lib/csharp/ -r:labcomm2014
 	chmod a+x $@
 
 build : 
@@ -49,6 +50,7 @@ build :
 	java -jar ${LCDIR}/compiler/labcomm_compiler.jar --java=${GENDIR} --c=${GENDIR}/test.c --h=${GENDIR}/test.h  --python=${GENDIR}/test.py --cs=${GENDIR}/test.cs test.lc 
 
 	javac -cp ${LCDIR}/lib/java/labcomm2014.jar:. ${GENDIR}/*.java Encoder.java Decoder.java
+	javac -cp ${LCDIR}/lib/java/labcomm2014.jar:${LCCJAR}:${GENDIR}:. TDDecoder.java
 
 	${CC} ${CFLAGS} ${LDFLAGS} -Wall -Werror -Wno-unused-function \
 	    -I. -I${LCDIR}/lib/c/2014 -L${LCDIR}/lib/c \
@@ -122,7 +124,7 @@ runwcs: build ExampleEncoder.exe ExampleDecoder.exe
 	@PYTHONPATH=${LCDIR}/lib/python ../wiki_example/example_decoder.py encoded_data_j LabComm2014
 
 	@echo "************ running C# decoder: *****************"
-	@LD_LIBRARY_PATH=${LCDIR}/lib/c/ ./ExampleDecoder.exe encoded_data_j
+	@LD_LIBRARY_PATH=${LCDIR}/lib/c/ mono ./ExampleDecoder.exe encoded_data_j
 
 	@echo "************ running C encoder: *****************"
 	@LD_LIBRARY_PATH=${LCDIR}/lib/c/ ./example_encoder encoded_data_c
@@ -137,7 +139,7 @@ runwcs: build ExampleEncoder.exe ExampleDecoder.exe
 	@PYTHONPATH=${LCDIR}/lib/python ../wiki_example/example_decoder.py encoded_data_c LabComm2014
 
 	@echo "************ running C# decoder: *****************"
-	@./ExampleDecoder.exe encoded_data_c
+	@mono ./ExampleDecoder.exe encoded_data_c
 
 	@echo "************ running python encoder: *****************"
 	@PYTHONPATH=${LCDIR}/lib/python:${GENDIR} ./example_encoder.py encoded_data_p LabComm2014
@@ -152,10 +154,10 @@ runwcs: build ExampleEncoder.exe ExampleDecoder.exe
 	PYTHONPATH=${LCDIR}/lib/python ../wiki_example/example_decoder.py encoded_data_p LabComm2014
 
 	@echo "************ running C# decoder: *****************"
-	@./ExampleDecoder.exe encoded_data_p
+	@mono ./ExampleDecoder.exe encoded_data_p
 
 	@echo "************ running C# encoder: *****************"
-	@./ExampleEncoder.exe encoded_data_cs
+	@mono ./ExampleEncoder.exe encoded_data_cs
 
 	@echo "************ running Java  decoder: *****************"
 	@java -cp .:${LCDIR}/lib/java/labcomm2014.jar:${GENDIR} Decoder encoded_data_cs
@@ -167,8 +169,19 @@ runwcs: build ExampleEncoder.exe ExampleDecoder.exe
 	@PYTHONPATH=${LCDIR}/lib/python ../wiki_example/example_decoder.py encoded_data_cs LabComm2014
 
 	@echo "************ running C# decoder: *****************"
-	@./ExampleDecoder.exe encoded_data_cs
+	@mono ./ExampleDecoder.exe encoded_data_cs
+
+runjastadd: cleanbuild
+	@echo
+	@echo "********************************************"
+	@echo "***   ************ running example with JastAdd unparsing  ***"
+	@echo "********************************************"
+	@echo
+
+	@java -cp .:${LCDIR}/lib/java/labcomm2014.jar:${GENDIR} Encoder encoded_data_j
 
+	@echo "************ running Java  TypeDefdecoder: *****************"
+	java -cp .:${LCDIR}/lib/java/labcomm2014.jar:${LCCJAR}:${GENDIR} TDDecoder encoded_data_j
 
 
 clean:
diff --git a/examples/user_types/TDDecoder.java b/examples/user_types/TDDecoder.java
new file mode 100644
index 0000000000000000000000000000000000000000..1c56a72eba5a351cd918b4e073da0158ffe99f8e
--- /dev/null
+++ b/examples/user_types/TDDecoder.java
@@ -0,0 +1,139 @@
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.io.IOException;
+
+import se.lth.control.labcomm2014.DecoderChannel;
+import se.lth.control.labcomm2014.TypeDef;
+import se.lth.control.labcomm2014.TypeDefParser;
+import se.lth.control.labcomm2014.ASTbuilder;
+//import se.lth.control.labcomm2014.TypeBinding;
+
+import se.lth.control.labcomm2014.compiler.Program;
+import java.io.FileOutputStream;
+import java.io.PrintStream;
+
+import java.util.Vector;
+import java.util.LinkedList;
+import java.util.Iterator;
+
+
+public class TDDecoder
+  implements twoLines.Handler,
+//             TypeDef.Handler,
+//             TypeBinding.Handler,
+             TypeDefParser.TypeDefListener,
+             twoInts.Handler,
+             theFirstInt.Handler,
+             theSecondInt.Handler,
+             doavoid.Handler,
+             intAndRef.Handler
+{
+
+  private DecoderChannel decoder;
+  private TypeDefParser tdp;
+
+  public TDDecoder(InputStream in) 
+    throws Exception 
+  {
+    decoder = new DecoderChannel(in);
+    twoInts.register(decoder, this);
+    twoLines.register(decoder, this);
+    theFirstInt.register(decoder, this);
+    theSecondInt.register(decoder, this);
+    doavoid.register(decoder, this);
+    intAndRef.register(decoder, this);
+    doavoid.registerSampleRef(decoder);
+    this.tdp = TypeDefParser.registerTypeDefParser(decoder); 
+ //   TypeDef.register(decoder, this);
+ //   TypeBinding.register(decoder, this);
+
+        
+    tdp.addListener(this);
+    
+    try {
+      System.out.println("Running decoder.");
+      decoder.run();
+    } catch (java.io.EOFException e) {
+	System.out.println("Decoder reached end of file.");
+    }
+  }
+
+  private String genPoint(point p) {
+    return "("+p.x.val+", "+p.y.val+")";
+  }
+
+  private String genLine(line l) {
+    return "Line from "+genPoint(l.start)+" to "+genPoint(l.end);
+  }
+
+//  public void handle_TypeDef(TypeDef d) throws java.io.IOException {
+//    System.out.println("Got TypeDef: "+d.getName()+"("+d.getIndex()+")");
+//  }
+//
+//  public void handle_TypeBinding(TypeBinding d) throws java.io.IOException {
+//    System.out.println("Got TypeBinding: "+d.getSampleIndex()+" --> "+d.getTypeIndex()+"");
+//  }
+
+  public void onTypeDef(TypeDefParser.ParsedTypeDef d) {
+    if(d.isSampleDef()){
+        System.out.println("onTypeDef (sample): ");
+        ASTbuilder v = new ASTbuilder();
+        Program p = v.makeProgram((TypeDefParser.ParsedSampleDef) d);
+        try {
+                //FileOutputStream f = new FileOutputStream("/tmp/foopp"+d.getName()+".txt");
+                //PrintStream out = new PrintStream(f);
+                p.pp(System.out);
+                //p.C_genC(System.out, new Vector(), "lcname", "prefix", 2014);
+                //p.J_gen(out, "testpackage", 2014);
+                //out.close();
+        } catch (Throwable e) {
+                System.err.println("Exception: " + e);
+                e.printStackTrace();
+        }
+    }
+    //System.out.println(" "+d.getName()+";");
+    //for(byte b: d.getSignature()) {
+    //   System.out.print(Integer.toHexString(b)+" ");
+    //}
+    //System.out.println(); 
+    //try {
+    //   tdp.parseSignature(d.getIndex());
+    //} catch(IOException ex) { ex.printStackTrace();}   
+  }
+
+  public void handle_twoInts(twoInts d) throws java.io.IOException {
+    System.out.print("Got twoInts: ");
+    System.out.println(d.a +", "+d.b);
+  }
+
+  public void handle_theFirstInt(int d) throws java.io.IOException {
+    System.out.println("Got theFirstInt: "+d);
+  }
+
+  public void handle_theSecondInt(int d) throws java.io.IOException {
+    System.out.println("Got theSecondInt: "+d);
+  }
+
+  public void handle_doavoid() throws java.io.IOException {
+    System.out.println("Got a void.");
+  }
+
+  public void handle_intAndRef(intAndRef d) throws java.io.IOException {
+    System.out.println("Got intAndRef: "+d.x+", "+d.reference);
+  }
+
+  public void handle_twoLines(twoLines d) throws java.io.IOException {
+    System.out.print("Got twoLines: ");
+    System.out.println("Line l1: "+genLine(d.l1));
+    System.out.println("              Line l2: "+genLine(d.l2));
+  }
+
+
+  public static void main(String[] arg) throws Exception {
+    TDDecoder example = new TDDecoder(
+      new FileInputStream(new File(arg[0]))
+    );
+  }
+}
+
diff --git a/examples/user_types/example_decoder.c b/examples/user_types/example_decoder.c
index 1edc52ff2bb0ac37c009d705d0226123d5f67adb..5d6062e0b02a21645b091f0c731a2dc5998c3cd3 100644
--- a/examples/user_types/example_decoder.c
+++ b/examples/user_types/example_decoder.c
@@ -1,15 +1,43 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
-#include <labcomm_fd_reader.h>
-#include <labcomm_default_error_handler.h>
-#include <labcomm_default_memory.h>
-#include <labcomm_default_scheduler.h>
+#include <labcomm2014_fd_reader.h>
+#include <labcomm2014_default_error_handler.h>
+#include <labcomm2014_default_memory.h>
+#include <labcomm2014_default_scheduler.h>
 #include "gen/test.h"
 #include <stdio.h>
 
+static void handle_test_doavoid(test_doavoid *v,void *context) {
+  printf("Got a void.\n"); 
+}
+
+static void handle_test_intAndRef(test_intAndRef *v,void *context) {
+  printf("Got intAndRef. (%d : %s) \n", v->x, v->reference->name); 
+}
+
+static void handle_test_twoInts(test_twoInts *v,void *context) {
+  printf("Got twoInts. (%d,%d) \n", v->a, v->b); 
+}
+
+static void handle_test_theFirstInt(int *v,void *context) {
+  printf("Got theFirstInt. (%d) \n", *v); 
+}
+
+static void handle_test_theSecondInt(int *v,void *context) {
+  printf("Got theSecondInt. (%d) \n", *v); 
+}
+
+static void handle_type_def(struct labcomm2014_raw_type_def *v,void *context) {
+  printf("Got type_def. (0x%x) %s\n", v->index, v->name); 
+}
+
+static void handle_type_binding(struct labcomm2014_type_binding *v,void *context) {
+  printf("Got type binding. 0x%x --> 0x%x\n", v->sample_index, v->type_index); 
+}
+
 static void handle_test_twoLines(test_twoLines *v,void *context) {
-  printf("Got theTwoInts. (%d,%d) -> (%d,%d), (%d,%d) -> (%d,%d)\n", v->l1.start.x.val, v->l1.start.y.val, 
+  printf("Got twoLines. (%d,%d) -> (%d,%d), (%d,%d) -> (%d,%d)\n", v->l1.start.x.val, v->l1.start.y.val, 
                                                                      v->l1.end.x.val, v->l1.end.y.val,    
                                                                      v->l2.start.x.val, v->l2.start.y.val,
                                                                      v->l2.end.x.val, v->l2.end.y.val);    
@@ -17,28 +45,37 @@ static void handle_test_twoLines(test_twoLines *v,void *context) {
 
 int main(int argc, char *argv[]) {
   int fd;
-  struct labcomm_decoder *decoder;
+  struct labcomm2014_decoder *decoder;
   void  *context = NULL;
 
   char *filename = argv[1];
   printf("C decoder reading from %s\n", filename);
   fd = open(filename, O_RDONLY);
-  decoder = labcomm_decoder_new(labcomm_fd_reader_new(
-				  labcomm_default_memory, fd, 1), 
-				labcomm_default_error_handler, 
-				labcomm_default_memory,
-				labcomm_default_scheduler);
+  decoder = labcomm2014_decoder_new(labcomm2014_fd_reader_new(
+				  labcomm2014_default_memory, fd, 1), 
+				labcomm2014_default_error_handler, 
+				labcomm2014_default_memory,
+				labcomm2014_default_scheduler);
   if (!decoder) { 
     printf("Failed to allocate decoder %s:%d\n", __FUNCTION__, __LINE__);
     return 1;
   }
 
-  labcomm_decoder_register_test_twoLines(decoder, handle_test_twoLines, context);
+  labcomm2014_decoder_register_test_doavoid(decoder, handle_test_doavoid, context);
+  labcomm2014_decoder_register_test_intAndRef(decoder, handle_test_intAndRef, context);
+  labcomm2014_decoder_sample_ref_register(decoder,labcomm2014_signature_test_doavoid );
+
+  labcomm2014_decoder_register_test_twoInts(decoder, handle_test_twoInts, context);
+  labcomm2014_decoder_register_test_theFirstInt(decoder, handle_test_theFirstInt, context);
+  labcomm2014_decoder_register_test_theSecondInt(decoder, handle_test_theSecondInt, context);
+  labcomm2014_decoder_register_test_twoLines(decoder, handle_test_twoLines, context);
+  labcomm2014_decoder_register_labcomm2014_type_def(decoder, handle_type_def, context);
+  labcomm2014_decoder_register_labcomm2014_type_binding(decoder, handle_type_binding, context);
 
   printf("Decoding:\n");
-  labcomm_decoder_run(decoder);
+  labcomm2014_decoder_run(decoder);
   printf("--- End Of File ---:\n");
-  labcomm_decoder_free(decoder);
+  labcomm2014_decoder_free(decoder);
 
   return 0;
 }
diff --git a/examples/user_types/example_encoder.c b/examples/user_types/example_encoder.c
index 3c76dcd49b325624d4c6ee34659fc292d1412e72..6c1d1ef834fbc7518d3306b9e3a575d02ea2de31 100644
--- a/examples/user_types/example_encoder.c
+++ b/examples/user_types/example_encoder.c
@@ -1,26 +1,26 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
-#include <labcomm_fd_writer.h>
-#include <labcomm_default_error_handler.h>
-#include <labcomm_default_memory.h>
-#include <labcomm_default_scheduler.h>
+#include <labcomm2014_fd_writer.h>
+#include <labcomm2014_default_error_handler.h>
+#include <labcomm2014_default_memory.h>
+#include <labcomm2014_default_scheduler.h>
 #include "gen/test.h"
 #include <stdio.h>
 
 int main(int argc, char *argv[]) {
   int fd;
-  struct labcomm_encoder *encoder;
+  struct labcomm2014_encoder *encoder;
 
   char *filename = argv[1];
   printf("C encoder writing to %s\n", filename);
   fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0644);
-  encoder = labcomm_encoder_new(labcomm_fd_writer_new(
-				  labcomm_default_memory, fd, 1), 
-				labcomm_default_error_handler, 
-				labcomm_default_memory,
-				labcomm_default_scheduler);
-  labcomm_encoder_register_test_twoLines(encoder);
+  encoder = labcomm2014_encoder_new(labcomm2014_fd_writer_new(
+				  labcomm2014_default_memory, fd, 1), 
+				labcomm2014_default_error_handler, 
+				labcomm2014_default_memory,
+				labcomm2014_default_scheduler);
+  labcomm2014_encoder_register_test_twoLines(encoder);
 
   test_twoLines tl;
 
@@ -34,7 +34,7 @@ int main(int argc, char *argv[]) {
   tl.l2.end.y.val = 23;
  
   printf("Encoding twoLines...\n");
-  labcomm_encode_test_twoLines(encoder, &tl);
+  labcomm2014_encode_test_twoLines(encoder, &tl);
 
   return 0;
 }
diff --git a/examples/user_types/example_encoder.py b/examples/user_types/example_encoder.py
index cdd2135ef8d971fd36e9cbee282871f0474672ca..9ef288604a08782a2ff77c06d3ae403cf8559ea5 100755
--- a/examples/user_types/example_encoder.py
+++ b/examples/user_types/example_encoder.py
@@ -1,12 +1,12 @@
 #!/usr/bin/python
 
-import labcomm
+import labcomm2014
 import sys
 import test
 
 if __name__ == '__main__':
     version = sys.argv[2] if len(sys.argv) == 3 else "LabComm2014"
-    encoder = labcomm.Encoder(labcomm.StreamWriter(open(sys.argv[1], 'w')), version)
+    encoder = labcomm2014.Encoder(labcomm2014.StreamWriter(open(sys.argv[1], 'w')), version)
     encoder.add_decl(test.twoLines.signature)
     tl = dict(
         l1=dict(
diff --git a/examples/user_types/test.lc b/examples/user_types/test.lc
index d2225394b890937f471e6984a8122aff11b3d51b..75497b4df01e761d47efba7dd95cc7bb1611fcf9 100644
--- a/examples/user_types/test.lc
+++ b/examples/user_types/test.lc
@@ -2,6 +2,16 @@ typedef struct {
   int val;
 } coord;
 
+typedef int anInt;
+
+typedef void avoid;
+sample avoid doavoid;
+
+sample struct {
+  int x;
+  sample reference;
+} intAndRef;
+
 typedef struct {
   coord x;
   coord y;
@@ -23,3 +33,11 @@ sample struct {
   line l2;
   foo  f;
 } twoLines;
+
+sample struct {
+  int a;
+  int b;
+} twoInts;
+
+sample anInt theFirstInt;
+sample anInt theSecondInt;
diff --git a/examples/wiki_example/.gitignore b/examples/wiki_example/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..f6cc4eceff7e31458c8187a2b186930e86270a76
--- /dev/null
+++ b/examples/wiki_example/.gitignore
@@ -0,0 +1,10 @@
+data.java
+example.c
+example.cs
+example.encoded
+example.h
+example.javaencoded
+example.py
+example_encoder
+log_message.java
+
diff --git a/examples/wiki_example/example_decoder.py b/examples/wiki_example/example_decoder.py
index 03b01c7955e8205c50159bd2587bc53e9893fd67..b9ab94294a73b34b5a309978b6a5a9bcd9f754f1 100755
--- a/examples/wiki_example/example_decoder.py
+++ b/examples/wiki_example/example_decoder.py
@@ -1,11 +1,11 @@
 #!/usr/bin/python
 
-import labcomm
+import labcomm2014
 import sys
 
 if __name__ == "__main__":
     version = sys.argv[2] if len(sys.argv) == 3 else "LabComm2014"
-    d = labcomm.Decoder(labcomm.StreamReader(open(sys.argv[1])), version)
+    d = labcomm2014.Decoder(labcomm2014.StreamReader(open(sys.argv[1])), version)
 
     while True:
         try:
diff --git a/examples/wiki_example/example_decoder_encoder.java b/examples/wiki_example/example_decoder_encoder.java
index 252cc1d8411ad59259dd445930f74b8f1ff61e2f..be630947be0cb0d10d8c6c68d8cdb2f1b3c7521b 100644
--- a/examples/wiki_example/example_decoder_encoder.java
+++ b/examples/wiki_example/example_decoder_encoder.java
@@ -4,8 +4,8 @@ import java.io.FileOutputStream;
 import java.io.InputStream;
 import java.io.OutputStream;
 
-import se.lth.control.labcomm.DecoderChannel;
-import se.lth.control.labcomm.EncoderChannel;
+import se.lth.control.labcomm2014.DecoderChannel;
+import se.lth.control.labcomm2014.EncoderChannel;
 
 public class example_decoder_encoder 
   implements data.Handler, log_message.Handler 
diff --git a/examples/wiki_example/example_encoder.c b/examples/wiki_example/example_encoder.c
index 3983a1380ee5230ac3045dca9225222ca56b4925..ee82c7a27fb77394849aebbb07c8cca3154d52a0 100644
--- a/examples/wiki_example/example_encoder.c
+++ b/examples/wiki_example/example_encoder.c
@@ -1,24 +1,24 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
-#include <labcomm.h>
-#include <labcomm_default_memory.h>
-#include <labcomm_fd_reader.h>
-#include <labcomm_fd_writer.h>
+#include <labcomm2014.h>
+#include <labcomm2014_default_memory.h>
+#include <labcomm2014_fd_reader.h>
+#include <labcomm2014_fd_writer.h>
 #include "example.h"
 
 int main(int argc, char *argv[]) {
   int fd;
-  struct labcomm_encoder *encoder;
-  struct labcomm_writer *labcomm_fd_writer;
+  struct labcomm2014_encoder *encoder;
+  struct labcomm2014_writer *labcomm2014_fd_writer;
   int i, j;
 
   fd = open("example.encoded", O_WRONLY|O_CREAT|O_TRUNC, 0644);
-  labcomm_fd_writer = labcomm_fd_writer_new(labcomm_default_memory, fd, 1);
-  encoder = labcomm_encoder_new(labcomm_fd_writer, NULL, 
-                                labcomm_default_memory, NULL);
-  labcomm_encoder_register_example_log_message(encoder);
-  labcomm_encoder_register_example_data(encoder);
+  labcomm2014_fd_writer = labcomm2014_fd_writer_new(labcomm2014_default_memory, fd, 1);
+  encoder = labcomm2014_encoder_new(labcomm2014_fd_writer, NULL, 
+                                labcomm2014_default_memory, NULL);
+  labcomm2014_encoder_register_example_log_message(encoder);
+  labcomm2014_encoder_register_example_data(encoder);
   for (i = 0 ; i < argc ; i++) {
     example_log_message message;
 
@@ -29,12 +29,12 @@ int main(int argc, char *argv[]) {
       message.line.a[j].last = (j == message.line.n_0 - 1);
       message.line.a[j].data = argv[j + 1];
     }
-    labcomm_encode_example_log_message(encoder, &message);
+    labcomm2014_encode_example_log_message(encoder, &message);
     free(message.line.a);
   }
   for (i = 0 ; i < argc ; i++) {
     float f = i;
-    labcomm_encode_example_data(encoder, &f);
+    labcomm2014_encode_example_data(encoder, &f);
   }
   return 0;
 }
diff --git a/examples/wiki_example/run b/examples/wiki_example/run
index e3477ea720ff97ebc29ac2339cbcdcae121752ce..276d46b4292c6d0aa635c243713f17fe0ec4f903 100755
--- a/examples/wiki_example/run
+++ b/examples/wiki_example/run
@@ -16,9 +16,9 @@ gcc -Wall -Werror -o example_encoder -I../../lib/c/2014 \
     example.c \
     ../../lib/c/liblabcomm2014.a || exit 1
 
-javac -cp ../../lib/java:. *.java || exit 1
+javac -cp ../../lib/java/labcomm.jar:. *.java || exit 1
 
 # Run through all executables (c->java->Python)
 ./example_encoder one two || exit 1
-java -cp ../../lib/java:. example_decoder_encoder example.encoded example.javaencoded || exit 1
+java -cp ../../lib/java/labcomm.jar:. example_decoder_encoder example.encoded example.javaencoded || exit 1
 PYTHONPATH=../../lib/python ./example_decoder.py example.javaencoded || exit 1
diff --git a/lib/Makefile b/lib/Makefile
index 5a16cabc12bef5a6c8d0ccfc8b0812bfde26ed92..c275249f5b118f369e6b1cda15a01300be2b121d 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -1,19 +1,29 @@
-all:
-	cd c ; make
-	cd csharp ; make
-	cd java ; make
-
-test:
-	$(MAKE) -C c test
-
-clean:
-	cd c ; make clean
-	cd csharp ; make clean
-	cd java ; make clean
-	$(MAKE) -C python clean
-
-distclean:
-	cd c ; make distclean
-	cd csharp ; make clean
-	cd java ; make clean
-	$(MAKE) -C python clean
+SUBDIRS=c csharp java python
+
+.PHONY: all
+all: $(SUBDIRS:%=make-%)
+
+.PHONY: make-%
+make-%:
+	$(MAKE) -C $*
+
+.PHONY: test
+test: $(SUBDIRS:%=test-%)
+
+.PHONY: test-%
+test-%:
+	$(MAKE) -C $* test
+
+.PHONY: clean
+clean: $(SUBDIRS:%=clean-%)
+
+.PHONY: clean-%
+clean-%:
+	$(MAKE) -C $* clean
+
+.PHONY: distclean
+distclean: clean $(SUBDIRS:%=distclean-%)
+
+.PHONY: distclean-%
+distclean-%:
+	$(MAKE) -C $* distclean
diff --git a/lib/c/.gitignore b/lib/c/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..4c36eb5c1878d88d3c542f0a8e3ca2a4d5ad02ac
--- /dev/null
+++ b/lib/c/.gitignore
@@ -0,0 +1,9 @@
+liblabcomm.a
+liblabcomm.so
+liblabcomm.so.1
+liblabcomm2006.so.1
+liblabcomm2006.so
+liblabcomm2006.a
+liblabcomm2014.so.1
+liblabcomm2014.so
+liblabcomm2014.a
diff --git a/lib/c/2006/labcomm2006.c b/lib/c/2006/labcomm2006.c
index 8f628cfccd6b10dda2635577cfd6c150e7ec4625..badfe4765fe3bd6e3e802c070caa35f0eaf64b16 100644
--- a/lib/c/2006/labcomm2006.c
+++ b/lib/c/2006/labcomm2006.c
@@ -138,9 +138,9 @@ int labcomm2006_writer_ioctl(struct labcomm2006_writer *w,
 
 
 static const char *labcomm2006_error_string[] = { 
-#define LABCOMM_ERROR(name, description) description ,
+#define LABCOMM2006_ERROR(name, description) description ,
 #include "labcomm2006_error.h"
-#undef LABCOMM_ERROR
+#undef LABCOMM2006_ERROR
 };
 static const int labcomm2006_error_string_count = (sizeof(labcomm2006_error_string) / 
 					       sizeof(labcomm2006_error_string[0]));
@@ -237,12 +237,12 @@ void *labcomm2006_signature_array_ref(struct labcomm2006_memory *memory,
   }
 }
 
-static int local_index = 0x40;
+static int local_index = LABCOMM_USER;
 
 void labcomm2006_set_local_index(struct labcomm2006_signature *signature)
 {
   if (signature->index != 0) {
-    labcomm2006_error_fatal_global(LABCOMM_ERROR_SIGNATURE_ALREADY_SET,
+    labcomm2006_error_fatal_global(LABCOMM2006_ERROR_SIGNATURE_ALREADY_SET,
                                    "Signature already set: %s", signature->name);
   }
   signature->index = local_index;
@@ -252,7 +252,7 @@ void labcomm2006_set_local_index(struct labcomm2006_signature *signature)
 int labcomm2006_get_local_index(const struct labcomm2006_signature *signature)
 {
   if (signature->index == 0) {
-    labcomm2006_error_fatal_global(LABCOMM_ERROR_SIGNATURE_NOT_SET,
+    labcomm2006_error_fatal_global(LABCOMM2006_ERROR_SIGNATURE_NOT_SET,
                                    "Signature not set: %s", signature->name);
   }
   return signature->index;
diff --git a/lib/c/2006/labcomm2006.h b/lib/c/2006/labcomm2006.h
index 1ea5aae4f1f030134b6a6ea5727d8a8b491fc29e..9958b17eb78f392b5385ba910b32287bacea7d83 100644
--- a/lib/c/2006/labcomm2006.h
+++ b/lib/c/2006/labcomm2006.h
@@ -1,5 +1,5 @@
 /*
-  labcomm.h -- user interface for handling encoding and decoding of
+  labcomm2006.h -- user interface for handling encoding and decoding of
                labcomm samples.
 
   Copyright 2006-2013 Anders Blomdell <anders.blomdell@control.lth.se>
@@ -20,8 +20,8 @@
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-#ifndef _LABCOMM_H_
-#define _LABCOMM_H_
+#ifndef __LABCOMM2006_H__
+#define __LABCOMM2006_H__
 
 #include <stdarg.h>
 
diff --git a/lib/c/2006/labcomm2006_decoder.c b/lib/c/2006/labcomm2006_decoder.c
index 885f67edbaad8328fbca09adba30d84683a66e19..2ae181d624dbfff1df9e927c6f4cd6766ff2a437 100644
--- a/lib/c/2006/labcomm2006_decoder.c
+++ b/lib/c/2006/labcomm2006_decoder.c
@@ -91,7 +91,7 @@ static int collect_flat_signature(
   result = decoder->reader->error;
   if (result < 0) { goto out; }
   if (type >= LABCOMM_USER) {
-    decoder->on_error(LABCOMM_ERROR_UNIMPLEMENTED_FUNC, 3,
+    decoder->on_error(LABCOMM2006_ERROR_UNIMPLEMENTED_FUNC, 3,
 			"Implement %s ... (1) for type 0x%x\n", __FUNCTION__, type);
   } else {
     labcomm2006_write_packed32(writer, type); 
@@ -132,7 +132,7 @@ static int collect_flat_signature(
       } break;
       default: {
 	result = -ENOSYS;
-        decoder->on_error(LABCOMM_ERROR_UNIMPLEMENTED_FUNC, 3,
+        decoder->on_error(LABCOMM2006_ERROR_UNIMPLEMENTED_FUNC, 3,
 				"Implement %s (2) for type 0x%x...\n", __FUNCTION__, type);
       } break;
     }
@@ -250,7 +250,7 @@ static int decode_typedef_or_sample(struct labcomm2006_decoder *d, int kind)
     d->on_new_datatype(d, &signature);
     result = -ENOENT;
   } else if (entry->index && entry->index != remote_index) {
-    d->on_error(LABCOMM_ERROR_DEC_INDEX_MISMATCH, 5, 
+    d->on_error(LABCOMM2006_ERROR_DEC_INDEX_MISMATCH, 5, 
 		"%s(): index mismatch '%s' (id=0x%x != 0x%x)\n", 
 		__FUNCTION__, signature.name, entry->index, remote_index);
     result = -ENOENT;
diff --git a/lib/c/2006/labcomm2006_default_error_handler.h b/lib/c/2006/labcomm2006_default_error_handler.h
index b8254f81c596d2aefa1e2898cdc0d50dab9c3b48..b00d988475209d17b4cf10fa819c98868a9ca7bd 100644
--- a/lib/c/2006/labcomm2006_default_error_handler.h
+++ b/lib/c/2006/labcomm2006_default_error_handler.h
@@ -18,7 +18,11 @@
   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
+#ifndef __LABCOMM2006_DEFAULT_ERROR_HANDLER_H__
+#define __LABCOMM2006_DEFAULT_ERROR_HANDLER_H__
 
 #include "labcomm2006.h"
 
 extern struct labcomm2006_error_handler *labcomm2006_default_error_handler;
+
+#endif
diff --git a/lib/c/2006/labcomm2006_default_memory.h b/lib/c/2006/labcomm2006_default_memory.h
index 4f46f42714ed9336ef3bd379ec9d13f0da5f282c..ba369881632847dd469591fdf60fc6d6b13e4849 100644
--- a/lib/c/2006/labcomm2006_default_memory.h
+++ b/lib/c/2006/labcomm2006_default_memory.h
@@ -18,9 +18,12 @@
   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
+#ifndef __LABCOMM2006_DEFAULT_MEMORY_H__
+#define __LABCOMM2006_DEFAULT_MEMORY_H__
 
 #include <stdlib.h>
 #include "labcomm2006.h"
 
 extern struct labcomm2006_memory *labcomm2006_default_memory;
 
+#endif
diff --git a/lib/c/2006/labcomm2006_default_scheduler.h b/lib/c/2006/labcomm2006_default_scheduler.h
index bd271f041f68b4d6d381bcfc57eada00ab005b62..becd93673d6f411d150496b4101feda361736b67 100644
--- a/lib/c/2006/labcomm2006_default_scheduler.h
+++ b/lib/c/2006/labcomm2006_default_scheduler.h
@@ -18,7 +18,11 @@
   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
+#ifndef __LABCOMM2006_DEFAULT_SCHEDULER_H__
+#define __LABCOMM2006_DEFAULT_SCHEDULER_H__
 
 #include "labcomm2006.h"
 
 extern struct labcomm2006_scheduler *labcomm2006_default_scheduler;
+
+#endif
diff --git a/lib/c/2006/labcomm2006_dynamic_buffer_writer.h b/lib/c/2006/labcomm2006_dynamic_buffer_writer.h
index c0ab9d0861cb5d84e7bc81352f9301b6ca322722..3611640112b09133b5c98bc887f688243ec9ce01 100644
--- a/lib/c/2006/labcomm2006_dynamic_buffer_writer.h
+++ b/lib/c/2006/labcomm2006_dynamic_buffer_writer.h
@@ -19,8 +19,8 @@
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-#ifndef _LABCOMM_DYNAMIC_BUFFER_READER_WRITER_H_
-#define _LABCOMM_DYNAMIC_BUFFER_READER_WRITER_H_
+#ifndef __LABCOMM2006_DYNAMIC_BUFFER_READER_WRITER_H__
+#define __LABCOMM2006_DYNAMIC_BUFFER_READER_WRITER_H__
 
 #include "labcomm2006.h"
 
diff --git a/lib/c/2006/labcomm2006_error.h b/lib/c/2006/labcomm2006_error.h
index 27a0e726b78e8a3a17809206702a76279a1d91eb..526545ec918cda988567ba8b59e582437a5d63a4 100644
--- a/lib/c/2006/labcomm2006_error.h
+++ b/lib/c/2006/labcomm2006_error.h
@@ -19,13 +19,13 @@
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-#ifndef __LABCOMM_ERROR_H__
-#define __LABCOMM_ERROR_H__
+#ifndef __LABCOMM2006_ERROR_H__
+#define __LABCOMM2006_ERROR_H__
 
 enum labcomm2006_error {
-#define LABCOMM_ERROR(name, description) name ,
+#define LABCOMM2006_ERROR(name, description) name ,
 #include "labcomm2006_error.h"
-#undef LABCOMM_ERROR
+#undef LABCOMM2006_ERROR
 };
 
 struct labcomm2006_error_handler;
@@ -41,28 +41,28 @@ void labcomm2006_error_fatal_global(enum labcomm2006_error error,
 			 
 #endif
 
-#ifdef LABCOMM_ERROR
+#ifdef LABCOMM2006_ERROR
 
-LABCOMM_ERROR(LABCOMM_ERROR_SIGNATURE_ALREADY_SET, 
-	      "Signature has already been set")
-LABCOMM_ERROR(LABCOMM_ERROR_SIGNATURE_NOT_SET, 
-	      "Signature has not been set")
+LABCOMM2006_ERROR(LABCOMM2006_ERROR_SIGNATURE_ALREADY_SET,
+                  "Signature has already been set")
+LABCOMM2006_ERROR(LABCOMM2006_ERROR_SIGNATURE_NOT_SET,
+                  "Signature has not been set")
 
-LABCOMM_ERROR(LABCOMM_ERROR_ENC_NO_REG_SIGNATURE, 
-	      "Encoder has no registration for this signature")
-LABCOMM_ERROR(LABCOMM_ERROR_ENC_BUF_FULL,
-	      "The labcomm buffer is full")
-LABCOMM_ERROR(LABCOMM_ERROR_DEC_UNKNOWN_DATATYPE,
-	      "Decoder: Unknown datatype")
-LABCOMM_ERROR(LABCOMM_ERROR_DEC_INDEX_MISMATCH, 
-	      "Decoder: index mismatch")
-LABCOMM_ERROR(LABCOMM_ERROR_DEC_TYPE_NOT_FOUND,
-	      "Decoder: type not found")
-LABCOMM_ERROR(LABCOMM_ERROR_UNIMPLEMENTED_FUNC,
-	      "This function is not yet implemented")
-LABCOMM_ERROR(LABCOMM_ERROR_MEMORY,
-	      "Could not allocate memory")
-LABCOMM_ERROR(LABCOMM_ERROR_USER_DEF,     
-	      "User defined error")
+LABCOMM2006_ERROR(LABCOMM2006_ERROR_ENC_NO_REG_SIGNATURE,
+                  "Encoder has no registration for this signature")
+LABCOMM2006_ERROR(LABCOMM2006_ERROR_ENC_BUF_FULL,
+                  "The labcomm buffer is full")
+LABCOMM2006_ERROR(LABCOMM2006_ERROR_DEC_UNKNOWN_DATATYPE,
+                  "Decoder: Unknown datatype")
+LABCOMM2006_ERROR(LABCOMM2006_ERROR_DEC_INDEX_MISMATCH,
+                  "Decoder: index mismatch")
+LABCOMM2006_ERROR(LABCOMM2006_ERROR_DEC_TYPE_NOT_FOUND,
+                  "Decoder: type not found")
+LABCOMM2006_ERROR(LABCOMM2006_ERROR_UNIMPLEMENTED_FUNC,
+                  "This function is not yet implemented")
+LABCOMM2006_ERROR(LABCOMM2006_ERROR_MEMORY,
+                  "Could not allocate memory")
+LABCOMM2006_ERROR(LABCOMM2006_ERROR_USER_DEF,
+                  "User defined error")
 
 #endif
diff --git a/lib/c/2006/labcomm2006_fd_reader.h b/lib/c/2006/labcomm2006_fd_reader.h
index 066ac81b15503a5f1ed80236c23a3a2d750d2711..408bf9fe2eaea02f81924f20f18bd3a3d5d601b0 100644
--- a/lib/c/2006/labcomm2006_fd_reader.h
+++ b/lib/c/2006/labcomm2006_fd_reader.h
@@ -1,3 +1,4 @@
+
 /*
   labcomm2006_fd_reader.c -- a reader for unix style file-descriptors
 
@@ -19,8 +20,8 @@
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-#ifndef _LABCOMM_FD_READER_H_
-#define _LABCOMM_FD_READER_H_
+#ifndef __LABCOMM2006_FD_READER_H__
+#define __LABCOMM2006_FD_READER_H__
 
 #include "labcomm2006.h"
 
diff --git a/lib/c/2006/labcomm2006_fd_writer.h b/lib/c/2006/labcomm2006_fd_writer.h
index 56fda84f8d839103bfe5e1d1860e319c10b7782e..8df9d08a3d1035b17d39d8c6f7bc6b3b72eaf40f 100644
--- a/lib/c/2006/labcomm2006_fd_writer.h
+++ b/lib/c/2006/labcomm2006_fd_writer.h
@@ -19,8 +19,8 @@
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-#ifndef _LABCOMM_FD_WRITER_H_
-#define _LABCOMM_FD_WRITER_H_
+#ifndef __LABCOMM2006_FD_WRITER_H__
+#define __LABCOMM2006_FD_WRITER_H__
 
 #include "labcomm2006.h"
 
diff --git a/lib/c/2006/labcomm2006_ioctl.h b/lib/c/2006/labcomm2006_ioctl.h
index 22794babca46cf928d0b4b03bcc72a6913cd61ab..3fabcd2547a2d781102f77d435d3ec6aee537a2a 100644
--- a/lib/c/2006/labcomm2006_ioctl.h
+++ b/lib/c/2006/labcomm2006_ioctl.h
@@ -19,8 +19,8 @@
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-#ifndef __LABCOMM_IOCTL_H__
-#define __LABCOMM_IOCTL_H__
+#ifndef __LABCOMM2006_IOCTL_H__
+#define __LABCOMM2006_IOCTL_H__
 
 #include "labcomm2006.h"
 
@@ -84,23 +84,14 @@
   LABCOMM_IOC(LABCOMM_IOC_NOSIG,LABCOMM_IOC_NONE,type,nr,0)
 #define LABCOMM_IOR(type,nr,size)					\
   LABCOMM_IOC(LABCOMM_IOC_NOSIG,LABCOMM_IOC_READ,type,nr,sizeof(size))
-/* FIXME: add flag to differentiate between size and nargs */
-#define LABCOMM_IORN(type,nr,nargs)					\
-  LABCOMM_IOC(LABCOMM_IOC_NOSIG,LABCOMM_IOC_READ,type,nr,nargs)
 #define LABCOMM_IOW(type,nr,size)					\
   LABCOMM_IOC(LABCOMM_IOC_NOSIG,LABCOMM_IOC_WRITE,type,nr,sizeof(size))
-#define LABCOMM_IOWN(type,nr,nargs)					\
-  LABCOMM_IOC(LABCOMM_IOC_NOSIG,LABCOMM_IOC_WRITE,type,nr,nargs)
 #define LABCOMM_IOS(type,nr)					\
   LABCOMM_IOC(LABCOMM_IOC_USESIG,LABCOMM_IOC_READ,type,nr,0)
 #define LABCOMM_IOSR(type,nr,size)					\
   LABCOMM_IOC(LABCOMM_IOC_USESIG,LABCOMM_IOC_READ,type,nr,sizeof(size))
-#define LABCOMM_IOSRN(type,nr,nargs)					\
-  LABCOMM_IOC(LABCOMM_IOC_USESIG,LABCOMM_IOC_READ,type,nr,nargs)
 #define LABCOMM_IOSW(type,nr,size)					\
   LABCOMM_IOC(LABCOMM_IOC_USESIG,LABCOMM_IOC_WRITE,type,nr,sizeof(size))
-#define LABCOMM_IOSWN(type,nr,nargs)					\
-  LABCOMM_IOC(LABCOMM_IOC_USESIG,LABCOMM_IOC_WRITE,type,nr,nargs)
 
 #define LABCOMM_IOCTL_WRITER_GET_BYTES_WRITTEN \
   LABCOMM_IOR(0,1,int)
diff --git a/lib/c/2006/labcomm2006_private.h b/lib/c/2006/labcomm2006_private.h
index 4c3361026bf8e3c83af75fcca44cdebec43453b5..c3bd51d5e817231f4d35bfa4c743dd94fb2ffe70 100644
--- a/lib/c/2006/labcomm2006_private.h
+++ b/lib/c/2006/labcomm2006_private.h
@@ -20,8 +20,8 @@
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-#ifndef _LABCOMM_PRIVATE_H_
-#define _LABCOMM_PRIVATE_H_
+#ifndef __LABCOMM2006_PRIVATE_H__
+#define __LABCOMM2006_PRIVATE_H__
 
 #ifdef LABCOMM_COMPAT
   #include LABCOMM_COMPAT
@@ -42,7 +42,7 @@
 #define LABCOMM_SAMPLE   0x02
 #define LABCOMM_ARRAY    0x10
 #define LABCOMM_STRUCT   0x11
-#define LABCOMM_USER     0x80   /* ..0xffffffff */
+#define LABCOMM_USER     0x40   /* ..0xffffffff */
 
 /*
  * Predefined primitive type indices
@@ -241,7 +241,7 @@ static inline char *labcomm2006_read_string(struct labcomm2006_reader *r)
   length = labcomm2006_read_packed32(r);
   result = labcomm2006_memory_alloc(r->memory, 1, length + 1);
   if (!result) {
-    labcomm2006_on_error_fprintf(LABCOMM_ERROR_MEMORY, 4, "%d byte at %s:%d",
+    labcomm2006_on_error_fprintf(LABCOMM2006_ERROR_MEMORY, 4, "%d byte at %s:%d",
                      length+1, __FUNCTION__, __LINE__);
     return NULL;
   }
diff --git a/lib/c/2006/labcomm2006_pthread_scheduler.h b/lib/c/2006/labcomm2006_pthread_scheduler.h
index 101cfde4fe142522b061791472ec7146f3e4de46..ab22b21f4cd980cb90bf86417c35985c59ac3ee7 100644
--- a/lib/c/2006/labcomm2006_pthread_scheduler.h
+++ b/lib/c/2006/labcomm2006_pthread_scheduler.h
@@ -19,8 +19,8 @@
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-#ifndef _LABCOMM_PTHREAD_SCHEDULER_H_
-#define _LABCOMM_PTHREAD_SCHEDULER_H_
+#ifndef __LABCOMM2006_PTHREAD_SCHEDULER_H__
+#define __LABCOMM2006_PTHREAD_SCHEDULER_H__
 
 #include "labcomm2006.h"
 
diff --git a/lib/c/2006/labcomm2006_scheduler.h b/lib/c/2006/labcomm2006_scheduler.h
index d4ea80d78707c0c171a43bf7014db6ad4387718a..0c332c1698905b2c4e0541667b82ed231e90213f 100644
--- a/lib/c/2006/labcomm2006_scheduler.h
+++ b/lib/c/2006/labcomm2006_scheduler.h
@@ -19,8 +19,8 @@
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-#ifndef _LABCOMM_SCHEDULER_H_
-#define _LABCOMM_SCHEDULER_H_
+#ifndef __LABCOMM2006_SCHEDULER_H__
+#define __LABCOMM2006_SCHEDULER_H__
 
 #ifdef LABCOMM_COMPAT
   #include LABCOMM_COMPAT
diff --git a/lib/c/2006/labcomm2006_scheduler_private.h b/lib/c/2006/labcomm2006_scheduler_private.h
index 1c80b365712de1148b329d2a2c3fde3366bd7e1f..f6f955596cc63aaf6484318c8a3364ec37be4c1b 100644
--- a/lib/c/2006/labcomm2006_scheduler_private.h
+++ b/lib/c/2006/labcomm2006_scheduler_private.h
@@ -19,8 +19,8 @@
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-#ifndef _LABCOMM_SCHEDULER_PRIVATE_H_
-#define _LABCOMM_SCHEDULER_PRIVATE_H_
+#ifndef __LABCOMM2006_SCHEDULER_PRIVATE_H__
+#define __LABCOMM2006_SCHEDULER_PRIVATE_H__
 
 #ifdef LABCOMM_COMPAT
  #include LABCOMM_COMPAT
diff --git a/lib/c/2006/labcomm_compat_vxworks.h b/lib/c/2006/labcomm_compat_vxworks.h
index ca3b0998a373a4a2dd1bb9be5dfdf317b8e875df..2918567139cef9f2a82c2921f0177a02de65e11b 100644
--- a/lib/c/2006/labcomm_compat_vxworks.h
+++ b/lib/c/2006/labcomm_compat_vxworks.h
@@ -1,5 +1,5 @@
-#ifndef _LABCOMM2006_COMPAT_VXWORKS_H_
-#define _LABCOMM2006_COMPAT_VXWORKS_H_
+#ifndef __LABCOMM2006_COMPAT_VXWORKS_H__
+#define __LABCOMM2006_COMPAT_VXWORKS_H__
 
 #ifndef __VXWORKS__
 #error "__VXWORKS__" not defined
diff --git a/lib/c/2006/test/.gitignore b/lib/c/2006/test/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..4f62b849d56cd043cb9725fe73e9f49522d3d931
--- /dev/null
+++ b/lib/c/2006/test/.gitignore
@@ -0,0 +1 @@
+gen
diff --git a/lib/c/2014/Makefile b/lib/c/2014/Makefile
index 6742429773437384c38c06148fc6af2bd9f78dc5..0e7aca58883a707d7c97d46dfe987ec7e5738305 100644
--- a/lib/c/2014/Makefile
+++ b/lib/c/2014/Makefile
@@ -1,5 +1,5 @@
 ## Macros
-VERSION=
+VERSION=2014
 LIBVERSION=2014
 
 include ../os_compat.mk
@@ -20,6 +20,7 @@ OBJS=labcomm$(VERSION).o \
      labcomm$(VERSION)_decoder.o \
      labcomm$(VERSION)_dynamic_buffer_writer.o \
      labcomm$(VERSION)_fd_reader.o \
+	 labcomm$(VERSION)_type_signature.o \
      labcomm$(VERSION)_fd_writer.o \
      labcomm$(VERSION)_pthread_scheduler.o 
 
@@ -29,8 +30,12 @@ ifeq ($(LABCOMM_EXPERIMENTAL),true)
 	    experimental/labcomm_thr_reader_writer.o \
 	    experimental/ThrottleDrv/ethernet_drv.o \
 	    experimental/ThrottleDrv/throttle_drv.o \
-	    experimental/labcomm_udp_reader_writer.o\
-	    experimental/labcomm_sig_parser.o 
+	    experimental/labcomm_udp_reader_writer.o
+endif
+
+# Enable experimental objects by `make LABCOMM_SIG_PARSER=true`
+ifeq ($(LABCOMM_SIG_PARSER),true)
+    OBJS += experimental/labcomm_sig_parser.o 
 endif
 
 LABCOMM_JAR=../../../compiler/labcomm$(LIBVERSION)_compiler.jar
@@ -83,8 +88,8 @@ distclean: clean
 ../liblabcomm$(LIBVERSION).a: $(OBJS)
 	ar -r $@ $^
 
-# Enable experimental objects by `make LABCOMM_EXPERIMENTAL=true`
-ifeq ($(LABCOMM_EXPERIMENTAL),true)
+# Enable sig parser objects by `make LABCOMM_SIG_PARSER=true`
+ifeq ($(LABCOMM_SIG_PARSER),true)
 experimental/test_sig_parser : experimental/labcomm_sig_parser.o experimental/test_sig_parser.c
 endif
 
diff --git a/lib/c/2014/experimental/labcomm_sig_parser.c b/lib/c/2014/experimental/labcomm_sig_parser.c
index 7c4a586717e1944a1d9db016d24fd21fbf4cb3f4..75e9771e53f0fa85df6577b6aee8ef6707ba7609 100644
--- a/lib/c/2014/experimental/labcomm_sig_parser.c
+++ b/lib/c/2014/experimental/labcomm_sig_parser.c
@@ -15,8 +15,6 @@
  * - The RETURN_STRINGS and where/if to allocate strings is to be decided, it
  *   is currently not used
  *
- * - TYPE_DECL is not tested (is it ever sent?)
- *
  * - The dynamic allocation of the parser is not quite dynamic, the sizes are
  *   set through the init function, and are then static.
  *   This should be adapted when allocation is parameterized/user-definable
@@ -66,7 +64,7 @@ static int unpack_varint(unsigned char *buf,
         unsigned char cont = TRUE;
 
         do {
-                char c = buf[idx+i];
+                unsigned char c = buf[idx+i];
                 res = (res << 7) | (c & 0x7f);
                 cont = c & 0x80;
                 i++;
@@ -218,6 +216,7 @@ void getStr(labcomm_sig_parser_t *b, unsigned char *dest, size_t size) {
 	if( size > rem )
 		size = rem;
 	strncpy((char *)dest, (char *)&b->c[b->idx], size);
+    dest[size] = 0;
 	b->idx += size;
 }
 
@@ -271,6 +270,7 @@ static size_t labcomm_sizeof_primitive(unsigned int type)
 			return 2;
 		case TYPE_INTEGER :
 		case TYPE_FLOAT :
+		case TYPE_SAMPLE_REF :
 			return 4;
 		case TYPE_LONG :
 		case TYPE_DOUBLE :
@@ -340,7 +340,65 @@ int encoded_size_parse_sig(struct labcomm_signature *sig, void *sample)
 	return -1;
 }
 
-static int accept_signature(labcomm_sig_parser_t *d)
+static int accept_signature(labcomm_sig_parser_t *d, 
+                            labcomm_type type,
+                            unsigned int start,
+                            unsigned int uid, char *name)
+{
+    get_varint(d); // ignore sig len
+    VERBOSE_PRINTF("\ntype = ");
+    accept_type(d);
+    //printf(" : ");
+    //unsigned int dt = pop(d);
+#ifdef USE_TYPE_AND_SIZE
+    unsigned int type = pop_val(d);
+    unsigned int enc_size = pop_val(d);
+#else
+    pop_val(d); // unsigned int type
+    pop_val(d); // unsigned int enc_size
+#endif
+    if(type != PKG_SAMPLE_DECL) {
+        if(type == PKG_SAMPLE_REF) {
+            INFO_PRINTF("accept_signature: ignoring sample ref\n");
+            return TRUE;
+        } else if (type == PKG_TYPE_DECL) {
+            INFO_PRINTF("accept_signature: ignoring typedef\n");
+            return TRUE;
+        } else {
+            error("decl is neither sample, ref, or typedef???");
+            return FALSE;
+        }
+    }
+    unsigned int end = d->idx;
+    unsigned int len = end-start;
+
+    struct labcomm_signature *newsig = get_sig_t(d, uid);
+//		newsig->type = type;
+    if(len <= d->max_sig_len) {
+        d->signatures_length[uid-LABCOMM_USER] = len;
+        memcpy(d->signatures[uid-LABCOMM_USER], &d->c[start], len);
+        newsig->size = len;
+        newsig->signature = d->signatures[uid-LABCOMM_USER];
+        newsig->name = name;
+    } else {
+        error("sig longer than max length (this ought to be dynamic...)");
+    }
+    VERBOSE_PRINTF("signature for uid %x: %s (start=%x,end=%x,len=%d)\n", uid, get_signature_name(d, uid), start,end, len);
+    INFO_PRINTF("accept_signature: %s\n", newsig->name);
+#ifdef LABCOMM_EXPERIMENTAL_CACHED_ENCODED_SIZE
+    if(! d->current_decl_is_varsize) {
+        newsig->cached_encoded_size = enc_size;
+        newsig->encoded_size = encoded_size_static;
+        INFO_PRINTF(".... is static size = %d\n", enc_size);
+    } else {
+        newsig->cached_encoded_size = -1;
+        newsig->encoded_size = encoded_size_parse_sig;
+        INFO_PRINTF(".... is variable size\n");
+    }
+#endif
+    return TRUE;
+}
+static int accept_decl(labcomm_sig_parser_t *d, labcomm_type type)
 {
 	if(accept_user_id(d)) {
 		unsigned int uid = pop_val(d);
@@ -354,54 +412,24 @@ static int accept_signature(labcomm_sig_parser_t *d)
 		free(str);
 #endif
 		unsigned char lenlen = labcomm_varint_sizeof(nlen);
-        get_varint(d); // ignore sig len
-		VERBOSE_PRINTF("\ntype = ");
-		accept_type(d);
-		//printf(" : ");
-		//unsigned int dt = pop(d);
-#ifdef USE_TYPE_AND_SIZE
-		unsigned int type = pop_val(d);
-		unsigned int enc_size = pop_val(d);
-#else
-		pop_val(d); // unsigned int type
-		pop_val(d); // unsigned int enc_size
-#endif
-		unsigned int end = d->idx;
-		unsigned int len = end-start;
-
-		struct labcomm_signature *newsig = get_sig_t(d, uid);
-//		newsig->type = type;
-		if(len <= d->max_sig_len) {
-			d->signatures_length[uid-LABCOMM_USER] = len;
-			memcpy(d->signatures[uid-LABCOMM_USER], &d->c[start], len);
-			newsig->size = len;
-			newsig->signature = d->signatures[uid-LABCOMM_USER];
-		} else {
-			error("sig longer than max length (this ought to be dynamic...)");
-		}
 
+        if(type != PKG_SAMPLE_DECL) {
+            // don't record typedefs and samplerefs (for now)
+            // to avoid number clashes with sample defs
+            // in the parser struct 
+            return accept_signature(d, type, start, uid, (char *) &d->c[nstart+lenlen]);
+        }
 		if(nlen < d->max_name_len) { // leave 1 byte for terminating NULL
+            char *name;
 			d->signatures_name_length[uid-LABCOMM_USER] = nlen;
 			memcpy(d->signatures_name[uid-LABCOMM_USER], &d->c[nstart+lenlen], nlen);
 			d->signatures_name[uid-LABCOMM_USER][nlen]=0;
-			newsig->name = d->signatures_name[uid-LABCOMM_USER];
+			name = d->signatures_name[uid-LABCOMM_USER];
+            return accept_signature(d, type, start, uid, name);
 		} else {
 			error("sig name longer than max length (this ought to be dynamic...");
+            return FALSE;
 		}
-		VERBOSE_PRINTF("signature for uid %x: %s (start=%x,end=%x, nlen=%d,len=%d)\n", uid, get_signature_name(d, uid), start,end, nlen, len);
-		INFO_PRINTF("SIG: %s\n", newsig->name);
-#ifdef LABCOMM_EXPERIMENTAL_CACHED_ENCODED_SIZE
-		if(! d->current_decl_is_varsize) {
-			newsig->cached_encoded_size = enc_size;
-			newsig->encoded_size = encoded_size_static;
-			INFO_PRINTF(".... is static size = %d\n", enc_size);
-		} else {
-			newsig->cached_encoded_size = -1;
-			newsig->encoded_size = encoded_size_parse_sig;
-			INFO_PRINTF(".... is variable size\n");
-		}
-#endif
-		return TRUE;
 	} else {
 		error("sample_decl with uid < LABCOMM_USER");
 		return FALSE;
@@ -412,7 +440,7 @@ static int accept_signature(labcomm_sig_parser_t *d)
 int accept_packet(labcomm_sig_parser_t *d) {
         size_t nbytes;
         unsigned int type = peek_varint(d, &nbytes) ;
-    if(type == VERSION ) {
+    if(type == PKG_VERSION ) {
 		advancen(d, nbytes);//consume type field
         get_varint(d); //ignore length field
 		VERBOSE_PRINTF("got version.\n");
@@ -422,19 +450,37 @@ int accept_packet(labcomm_sig_parser_t *d) {
             char *str = (char *) pop_ptr(d);
             free(str);
 #endif
-    }else if(type == TYPE_DECL ) {
-		//XXX is this used? If so, is it correct?
+	} else if (type == PKG_SAMPLE_DECL) {
+		d->current_decl_is_varsize = FALSE; // <-- a conveniance flag in labcomm_sig_parser_t
 		advancen(d, nbytes);
+		VERBOSE_PRINTF("sample_decl ");
+        get_varint(d); //ignore length field
+		accept_decl(d, type);
+	} else if (type == PKG_SAMPLE_REF) {
 		d->current_decl_is_varsize = FALSE; // <-- a conveniance flag in labcomm_sig_parser_t
-		VERBOSE_PRINTF("type_decl ");
+		advancen(d, nbytes);
+		VERBOSE_PRINTF("sample_ref ");
         get_varint(d); //ignore length field
-		accept_signature(d);
-	} else if (type == SAMPLE_DECL) {
+		accept_decl(d, type);
+    }else if(type == PKG_TYPE_DECL ) {
 		d->current_decl_is_varsize = FALSE; // <-- a conveniance flag in labcomm_sig_parser_t
+		advancen(d, nbytes);//consume type field
+		VERBOSE_PRINTF("type_decl ");
+        get_varint(d); //ignore length field
+		accept_decl(d, type);
+	} else if (type == PKG_TYPE_BINDING) {
+		VERBOSE_PRINTF("type_binding ");
 		advancen(d, nbytes);
-		VERBOSE_PRINTF("sample_decl ");
         get_varint(d); //ignore length field
-		accept_signature(d);
+#ifdef VERBOSE        
+        int sid = 
+#endif            
+            get_varint(d); //ignore sample id field
+#ifdef VERBOSE        
+        int tid =
+#endif            
+            get_varint(d); //ignore type id field
+		VERBOSE_PRINTF("sid=0x%x, tid=0x%x\n ", sid, tid);
 	} else if(type >= LABCOMM_USER) {
 #ifdef EXIT_WHEN_RECEIVING_DATA
 		printf("*** got sample data, exiting\n");
@@ -447,7 +493,7 @@ int accept_packet(labcomm_sig_parser_t *d) {
         error("got unknown type (<LABCOMM_USER)");
 		exit(1);
 #else
-        int len = get_varint(d); //ignore length field
+        int len = get_varint(d); // length field
         printf("got unknown tag: 0x%x, skipping %d bytes\n",type, len);
         advancen(d, len);
 #endif
@@ -464,13 +510,14 @@ static int accept_user_id(labcomm_sig_parser_t *d){
 		push_val(d, uid);
 		return TRUE;
 	} else {
+        error("uid < LABCOMM_USER");
 		return FALSE;
 	}
 }
 
 static int accept_string(labcomm_sig_parser_t *d){
 	unsigned int len = get_varint(d);
-	unsigned char *str=malloc(len);
+	unsigned char *str=malloc(len+1); // len is without terminating null
 	getStr(d, str, len);
 	VERBOSE_PRINTF("%s", str);
 #ifdef RETURN_STRINGS
@@ -527,6 +574,11 @@ static int accept_type(labcomm_sig_parser_t *d){
 			labcomm_sig_parser_t_set_varsize(d);
 			push_val(d, 0);
 			break;
+		case TYPE_SAMPLE_REF :
+			VERBOSE_PRINTF("sample\n");
+			advancen(d, nbytes);
+			push_val(d,  4);
+			break;
 		case ARRAY_DECL :
 			accept_array_decl(d);
 			pop_val(d); // ignore element type
@@ -537,7 +589,10 @@ static int accept_type(labcomm_sig_parser_t *d){
 			// push(d, pop(d) is a NOP --> leave size on stack
 			break;
 		default :
-			printf("accept_type default (type==%x) should not happen\n", type);
+            //should we distinguish between SAMPLE_DEF and TYPE_DEF here?
+			//printf("accept_type default (type==%x) should not happen\n", type);
+			VERBOSE_PRINTF("user type 0x%x\n",type);
+			advancen(d, nbytes);
 			push_val(d, 0);
 			push_val(d, type);
 			return FALSE;
@@ -601,7 +656,11 @@ static int accept_struct_decl(labcomm_sig_parser_t *d){
 	if(tid == STRUCT_DECL) {
 		advancen(d, nbytes);
 		unsigned int nf = get_varint(d);
-		VERBOSE_PRINTF("%d field struct:\n", nf);
+        if(nf == 0) {
+            VERBOSE_PRINTF("void\n");
+        } else {
+            VERBOSE_PRINTF("%d field struct:\n", nf);
+        }
 		int i;
 #ifdef USE_UNUSED_VARS
 		int numVar=0;
@@ -708,7 +767,7 @@ static int skip_array(labcomm_sig_parser_t *d, unsigned char *sig, int len, int
 
 int skip_struct(labcomm_sig_parser_t *d, unsigned char *sig, unsigned int len, int *pos) {
 	size_t nbytes;
-	unsigned int nFields = unpack_varint(sig,*pos, &nbytes);
+	int nFields = unpack_varint(sig,*pos, &nbytes);
 	*pos += nbytes;
 	unsigned int i;
 	unsigned int skipped=0;
@@ -719,7 +778,7 @@ int skip_struct(labcomm_sig_parser_t *d, unsigned char *sig, unsigned int len, i
 #ifdef DEBUG
 		VERBOSE_PRINTF("field #%d:\n----namelen==%d\n",i,namelen);
 		char name[namelen+1]; //HERE BE DRAGONS. alloca?
-		strncpy(name, sig+*pos+nbytes, namelen);
+		strncpy(name, (const char *)sig+*pos+nbytes, namelen);
 		name[namelen]=0;
 		VERBOSE_PRINTF("----name = %s\n",name);
 #endif
@@ -797,7 +856,7 @@ int skip_type(unsigned int type, labcomm_sig_parser_t *d,
 }
 #else
 int skip_type(unsigned int type, labcomm_sig_parser_t *d,
-		unsigned char *sig, unsigned int len, int *pos)
+		const char *sig, unsigned int len, int *pos)
 {
 	int skipped=0;
 	VERBOSE_PRINTF("skip_type %x\n", type);
@@ -849,7 +908,7 @@ int skip_packed_sample_data(labcomm_sig_parser_t *d, struct labcomm_signature *s
 	unsigned int skipped = 0;	//skipped byte counter
 	while(pos < sig->size) {
 		size_t nbytes;
-		unsigned int type = unpack_varint(sig->signature,pos, &nbytes);
+		int type = unpack_varint(sig->signature,pos, &nbytes);
 		pos+=nbytes;
 		skipped += skip_type(type, d, sig->signature, sig->size, &pos);
 	}
diff --git a/lib/c/2014/experimental/labcomm_sig_parser.h b/lib/c/2014/experimental/labcomm_sig_parser.h
index b40a534ef5461e9b12f79fe3af8053842d4011e4..46a1d1e41ba7e68379437f2e3b3bdd1f563b0b4c 100644
--- a/lib/c/2014/experimental/labcomm_sig_parser.h
+++ b/lib/c/2014/experimental/labcomm_sig_parser.h
@@ -8,14 +8,18 @@
 #ifndef LABCOMM_SIG_PARSER_H
 #define LABCOMM_SIG_PARSER_H
 
+#include "../labcomm.h"
 #include "../labcomm_private.h"
 
-#undef DEBUG 
-#undef QUIET_STACK	   // don't print anything for push/pop
+#define DEBUG 
+#define QUIET_STACK	   // don't print anything for push/pop
 #undef DEBUG_STACK_VERBOSE // dump stack, otherwise just print value of top
 
 #undef QUIET 		//just print type and size when skipping data
-// #undef VERBOSE 		// print in great detail
+#define VERBOSE 		// print in great detail
+
+
+#undef SKIP_BY_PARSING
 
 #undef STATIC_ALLOCATION  //dynamic allocation not completely implemented
 
@@ -24,6 +28,7 @@
 #define MAX_SIGNATURES 16
 #define MAX_NAME_LEN 32 
 #define MAX_SIG_LEN 128
+#define TYPEDEF_BASE MAX_SIGNATURES
 
 #endif
 
@@ -43,21 +48,24 @@ typedef struct {
 	size_t max_signatures;                 // set by init(...)
 	size_t max_name_len;
 	size_t max_sig_len; 
+    // arrays for signatures and typedefs
+    // signatures start at index 0
+    // typedefs start at index MAX_SIGNATURES
 #ifdef STATIC_ALLOCATION
-	struct labcomm_signature sig_ts[MAX_SIGNATURES];
+	struct labcomm_signature sig_ts[2*MAX_SIGNATURES];
 
-	unsigned int signatures_length[MAX_SIGNATURES];
-	unsigned int signatures_name_length[MAX_SIGNATURES];
-	unsigned char signatures_name[MAX_SIGNATURES][MAX_NAME_LEN]; 
-	unsigned char signatures[MAX_SIGNATURES][MAX_SIG_LEN];
+	unsigned int signatures_length[2*MAX_SIGNATURES];
+	unsigned int signatures_name_length[2*MAX_SIGNATURES];
+	unsigned char signatures_name[2*MAX_SIGNATURES][MAX_NAME_LEN]; 
+	unsigned char signatures[2*MAX_SIGNATURES][MAX_SIG_LEN];
 #else
-	struct labcomm_signature *sig_ts;           // [MAX_SIGNATURES]
+	struct labcomm_signature *sig_ts;           // [2*MAX_SIGNATURES]
 
-	unsigned int *signatures_length;       // [MAX_SIGNATURES]
-	unsigned char **signatures;            // [MAX_SIGNATURES][MAX_SIG_LEN];
+	unsigned int *signatures_length;       // [2*MAX_SIGNATURES]
+	unsigned char **signatures;            // [2*MAX_SIGNATURES][MAX_SIG_LEN];
 
-	unsigned int *signatures_name_length;  // [MAX_SIGNATURES]
-	char **signatures_name;       // [MAX_SIGNATURES][MAX_NAME_LEN];
+	unsigned int *signatures_name_length;  // [2*MAX_SIGNATURES]
+	char **signatures_name;       // [2*MAX_SIGNATURES][MAX_NAME_LEN];
 #endif
 
 } labcomm_sig_parser_t;
@@ -104,17 +112,12 @@ int skip_packed_sample_data(labcomm_sig_parser_t *p, struct labcomm_signature *s
 
 #undef RETURN_STRINGS  //  not really tested
 
-#ifndef TRUE
-
-#define FALSE 0
-#define TRUE 1
-
-#endif
-
 typedef enum{
-        VERSION = LABCOMM_VERSION,
-        SAMPLE_DECL = LABCOMM_SAMPLE_DEF,
-        TYPE_DECL = LABCOMM_TYPEDEF,
+        PKG_VERSION = LABCOMM_VERSION,
+        PKG_SAMPLE_DECL = LABCOMM_SAMPLE_DEF,
+        PKG_SAMPLE_REF = LABCOMM_SAMPLE_REF,
+        PKG_TYPE_DECL = LABCOMM_TYPE_DEF,
+        PKG_TYPE_BINDING = LABCOMM_TYPE_BINDING,
 
         ARRAY_DECL = LABCOMM_ARRAY,
         STRUCT_DECL = LABCOMM_STRUCT,
@@ -126,6 +129,7 @@ typedef enum{
         TYPE_LONG  = LABCOMM_LONG,
         TYPE_FLOAT  = LABCOMM_FLOAT,
         TYPE_DOUBLE  = LABCOMM_DOUBLE,
-        TYPE_STRING  = LABCOMM_STRING
+        TYPE_STRING  = LABCOMM_STRING,
+        TYPE_SAMPLE_REF  = LABCOMM_REF
 } labcomm_type ;
 #endif
diff --git a/lib/c/2014/labcomm.h b/lib/c/2014/labcomm.h
deleted file mode 100644
index 4bc6b6cb881f3a16be1780d97adbdeb972dee73c..0000000000000000000000000000000000000000
--- a/lib/c/2014/labcomm.h
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
-  labcomm.h -- user interface for handling encoding and decoding of
-               labcomm samples.
-
-  Copyright 2006-2013 Anders Blomdell <anders.blomdell@control.lth.se>
-
-  This file is part of LabComm.
-
-  LabComm is free software: you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation, either version 3 of the License, or
-  (at your option) any later version.
-
-  LabComm is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _LABCOMM_H_
-#define _LABCOMM_H_
-
-#include <stdarg.h>
-
-#ifdef LABCOMM_COMPAT
-  #include LABCOMM_COMPAT
-#else
-  #include <stdint.h>
-  #include <unistd.h>
-#endif
-
-#include "labcomm_error.h"
-#include "labcomm_scheduler.h"
-
-/* Forward declaration */
-struct labcomm_encoder;
-struct labcomm_decoder;
-
-/*
- * Signature entry
- */
-struct labcomm_signature {
-  char *name;
-  int (*encoded_size)(void *); /* void* refers to sample_data */
-  int size;
-  unsigned char *signature; 
-  int index;
-#ifdef LABCOMM_EXPERIMENTAL_CACHED_ENCODED_SIZE
-  int cached_encoded_size; // -1 if not initialized or type is variable size
-#endif
-};
-
-/*
- * Error handling.
- */
-
-/* The callback prototype for error handling.
- * First parameter is the error ID.
- * The second paramters is the number of va_args that comes after this 
- * one. If none it should be 0.
- * Optionaly other paramters can be supplied depending on what is needed 
- * for this error ID.
- */
-typedef void (*labcomm_error_handler_callback)(enum labcomm_error error_id, 
-					       size_t nbr_va_args, ...); 
-
-/* Default error handler, prints message to stderr. 
- * Extra info about the error can be supplied as char* as VA-args. Especially user defined errors should supply a describing string. if nbr_va_args > 1 the first variable argument must be a printf format string and the possibly following arguments are passed as va_args to vprintf. 
- */
-void labcomm2014_on_error_fprintf(enum labcomm_error error_id, size_t nbr_va_args, ...);
-
-/* Register a callback for the error handler for this encoder. */
-void labcomm_register_error_handler_encoder(struct labcomm_encoder *encoder, labcomm_error_handler_callback callback);
-
-/* Register a callback for the error handler for this decoder. */
-void labcomm_register_error_handler_decoder(struct labcomm_decoder *decoder, labcomm_error_handler_callback callback);
-
-/* Get a string describing the supplied standrad labcomm error. */
-const char *labcomm_error_get_str(enum labcomm_error error_id);
-
-typedef int (*labcomm_handle_new_datatype_callback)(
-  struct labcomm_decoder *decoder,
-  struct labcomm_signature *sig);
-
-void labcomm_decoder_register_new_datatype_handler(struct labcomm_decoder *d,
-		labcomm_handle_new_datatype_callback on_new_datatype);
-
-/*
- * Dynamic memory handling
- *   lifetime == 0     memory that will live for as long as the 
- *                     encoder/decoder or that are allocated/deallocated 
- *                     during the communication setup phase
- *   otherwise         memory will live for approximately this number of
- *                     sent/received samples
- */
-struct labcomm_memory;
-
-void *labcomm_memory_alloc(struct labcomm_memory *m, int lifetime, size_t size);
-void *labcomm_memory_realloc(struct labcomm_memory *m, int lifetime, 
-			     void *ptr, size_t size);
-void labcomm_memory_free(struct labcomm_memory *m, int lifetime, void *ptr);
-
-/*
- * Decoder
- */
-struct labcomm_reader;
-
-struct labcomm_decoder *labcomm_decoder_new(
-  struct labcomm_reader *reader,
-  struct labcomm_error_handler *error,
-  struct labcomm_memory *memory,
-  struct labcomm_scheduler *scheduler);
-void labcomm_decoder_free(
-  struct labcomm_decoder *decoder);
-int labcomm_decoder_decode_one(
-  struct labcomm_decoder *decoder);
-void labcomm_decoder_run(
-  struct labcomm_decoder *decoder);
-int labcomm_decoder_sample_ref_register(
-  struct labcomm_decoder *decoder,
-  const struct labcomm_signature *signature);
-
-/* See labcomm_ioctl.h for predefined ioctl_action values */
-int labcomm_decoder_ioctl(struct labcomm_decoder *decoder, 
-			  uint32_t ioctl_action,
-			  ...);
-
-/*
- * Encoder
- */
-struct labcomm_writer;
-
-struct labcomm_encoder *labcomm_encoder_new(
-  struct labcomm_writer *writer,
-  struct labcomm_error_handler *error,
-  struct labcomm_memory *memory,
-  struct labcomm_scheduler *scheduler);
-void labcomm_encoder_free(
-  struct labcomm_encoder *encoder);
-int labcomm_encoder_sample_ref_register(
-  struct labcomm_encoder *encoder,
-  const struct labcomm_signature *signature);
-
-/* See labcomm_ioctl.h for predefined ioctl_action values */
-int labcomm_encoder_ioctl(struct labcomm_encoder *encoder, 
-			  uint32_t ioctl_action,
-			  ...);
-
-#define LABCOMM_VOID ((void*)1)
-
-#endif
diff --git a/lib/c/2014/labcomm.c b/lib/c/2014/labcomm2014.c
similarity index 50%
rename from lib/c/2014/labcomm.c
rename to lib/c/2014/labcomm2014.c
index a1994aff1ec08e7356295f4d3dcd6d12408e9446..c2285e8fd5f5590140ea14c026b787fbd2ae7a61 100644
--- a/lib/c/2014/labcomm.c
+++ b/lib/c/2014/labcomm2014.c
@@ -1,6 +1,6 @@
 /*
-  labcomm.c -- runtime for handling encoding and decoding of
-               labcomm samples.
+  labcomm2014.c -- runtime for handling encoding and decoding of
+               labcomm2014 samples.
 
   Copyright 2006-2013 Anders Blomdell <anders.blomdell@control.lth.se>
 
@@ -32,10 +32,10 @@
 #include <stdarg.h>
 #include <stddef.h>
 
-#include "labcomm.h"
-#include "labcomm_private.h"
-#include "labcomm_ioctl.h"
-#include "labcomm_dynamic_buffer_writer.h"
+#include "labcomm2014.h"
+#include "labcomm2014_private.h"
+#include "labcomm2014_ioctl.h"
+#include "labcomm2014_dynamic_buffer_writer.h"
 
 /* Unwrapping reader/writer functions */
 #define UNWRAP_ac(rw, ac, ...) ac
@@ -47,89 +47,89 @@
     UNWRAP_ac( __VA_ARGS__) = UNWRAP_ac(__VA_ARGS__)->next;		\
   }
 
-int labcomm_reader_alloc(struct labcomm_reader *r, 
-                         struct labcomm_reader_action_context *action_context)
+int labcomm2014_reader_alloc(struct labcomm2014_reader *r,
+                         struct labcomm2014_reader_action_context *action_context)
 {
   UNWRAP(alloc, r, action_context);
 }
 
-int labcomm_reader_free(struct labcomm_reader *r, 
-                        struct labcomm_reader_action_context *action_context)
+int labcomm2014_reader_free(struct labcomm2014_reader *r,
+                        struct labcomm2014_reader_action_context *action_context)
 {
   UNWRAP(free, r, action_context);
 }
 
-int labcomm_reader_start(struct labcomm_reader *r, 
-                         struct labcomm_reader_action_context *action_context,
+int labcomm2014_reader_start(struct labcomm2014_reader *r,
+                         struct labcomm2014_reader_action_context *action_context,
 			 int local_index, int remote_index,
-			 const struct labcomm_signature *signature,
+			 const struct labcomm2014_signature *signature,
 			 void *value)
 {
   UNWRAP(start, r, action_context, local_index, remote_index, signature, value);
 }
 
-int labcomm_reader_end(struct labcomm_reader *r, 
-                       struct labcomm_reader_action_context *action_context)
+int labcomm2014_reader_end(struct labcomm2014_reader *r,
+                       struct labcomm2014_reader_action_context *action_context)
 {
   UNWRAP(end, r, action_context);
 }
 
-int labcomm_reader_fill(struct labcomm_reader *r, 
-                        struct labcomm_reader_action_context *action_context)
+int labcomm2014_reader_fill(struct labcomm2014_reader *r,
+                        struct labcomm2014_reader_action_context *action_context)
 {
   UNWRAP(fill, r, action_context);
 }
 
-int labcomm_reader_ioctl(struct labcomm_reader *r, 
-                         struct labcomm_reader_action_context *action_context,
+int labcomm2014_reader_ioctl(struct labcomm2014_reader *r,
+                         struct labcomm2014_reader_action_context *action_context,
                          int local_index, int remote_index,
-                         const struct labcomm_signature *signature, 
+                         const struct labcomm2014_signature *signature,
                          uint32_t ioctl_action, va_list args)
 {
-  UNWRAP(ioctl, r, action_context, 
+  UNWRAP(ioctl, r, action_context,
 	 local_index, remote_index, signature, ioctl_action, args);
 }
 
-int labcomm_writer_alloc(struct labcomm_writer *w, 
-                         struct labcomm_writer_action_context *action_context)
+int labcomm2014_writer_alloc(struct labcomm2014_writer *w,
+                         struct labcomm2014_writer_action_context *action_context)
 {
   UNWRAP(alloc, w, action_context);
 }
 
-int labcomm_writer_free(struct labcomm_writer *w, 
-                        struct labcomm_writer_action_context *action_context)
+int labcomm2014_writer_free(struct labcomm2014_writer *w,
+                        struct labcomm2014_writer_action_context *action_context)
 {
   UNWRAP(free, w, action_context);
 }
 
-int labcomm_writer_start(struct labcomm_writer *w, 
-                         struct labcomm_writer_action_context *action_context,
-                         int index, const struct labcomm_signature *signature,
+int labcomm2014_writer_start(struct labcomm2014_writer *w,
+                         struct labcomm2014_writer_action_context *action_context,
+                         int index, const struct labcomm2014_signature *signature,
                          void *value)
 {
   UNWRAP(start, w, action_context, index, signature, value);
 }
 
-int labcomm_writer_end(struct labcomm_writer *w, 
-                       struct labcomm_writer_action_context *action_context)
+int labcomm2014_writer_end(struct labcomm2014_writer *w,
+                       struct labcomm2014_writer_action_context *action_context)
 {
   UNWRAP(end, w, action_context);
-} 
+}
 
-int labcomm_writer_flush(struct labcomm_writer *w, 
-                         struct labcomm_writer_action_context *action_context)
+int labcomm2014_writer_flush(struct labcomm2014_writer *w,
+                         struct labcomm2014_writer_action_context *action_context)
 {
   UNWRAP(flush, w, action_context);
-} 
+}
 
-int labcomm_writer_ioctl(struct labcomm_writer *w, 
-                         struct labcomm_writer_action_context *action_context, 
-                         int index, 
-                         const struct labcomm_signature *signature, 
+int labcomm2014_writer_ioctl(struct labcomm2014_writer *w,
+                         struct labcomm2014_writer_action_context *action_context,
+                         int index,
+                         const struct labcomm2014_signature *signature,
                          uint32_t ioctl_action, va_list args)
 {
   UNWRAP(ioctl, w, action_context, index, signature, ioctl_action, args);
-} 
+}
 
 #undef UNWRAP
 #undef UNWRAP_ac
@@ -137,29 +137,29 @@ int labcomm_writer_ioctl(struct labcomm_writer *w,
 
 
 
-static const char *labcomm_error_string[] = { 
-#define LABCOMM_ERROR(name, description) description ,
-#include "labcomm_error.h"
-#undef LABCOMM_ERROR
+static const char *labcomm2014_error_string[] = {
+#define LABCOMM2014_ERROR(name, description) description ,
+#include "labcomm2014_error.h"
+#undef LABCOMM2014_ERROR
 };
-static const int labcomm_error_string_count = (sizeof(labcomm_error_string) / 
-					       sizeof(labcomm_error_string[0]));
+static const int labcomm2014_error_string_count = (sizeof(labcomm2014_error_string) /
+					       sizeof(labcomm2014_error_string[0]));
 
 
-const char *labcomm_error_get_str(enum labcomm_error error_id)
+const char *labcomm2014_error_get_str(enum labcomm2014_error error_id)
 {
   const char *error_str = NULL;
   // Check if this is a known error ID.
-  if (error_id < labcomm_error_string_count) {
-    error_str = labcomm_error_string[error_id];
+  if (error_id < labcomm2014_error_string_count) {
+    error_str = labcomm2014_error_string[error_id];
   }
   return error_str;
 }
 
-void labcomm2014_on_error_fprintf(enum labcomm_error error_id, size_t nbr_va_args, ...)
+void labcomm20142014_on_error_fprintf(enum labcomm2014_error error_id, size_t nbr_va_args, ...)
 {
 #ifndef LABCOMM_NO_STDIO
-  const char *err_msg = labcomm_error_get_str(error_id); // The final string to print.
+  const char *err_msg = labcomm2014_error_get_str(error_id); // The final string to print.
   if (err_msg == NULL) {
     err_msg = "Error with an unknown error ID occured.";
   }
@@ -175,9 +175,9 @@ void labcomm2014_on_error_fprintf(enum labcomm_error error_id, size_t nbr_va_arg
    fprintf(stderr, "}\n");
 
    va_end(arg_pointer);
- } 
+ }
 #else
- ; // If labcomm can't be compiled with stdio the user will have to make an own error callback functionif he/she needs error reporting.
+ ; // If labcomm2014 can't be compiled with stdio the user will have to make an own error callback functionif he/she needs error reporting.
 #endif
 }
 
@@ -199,16 +199,16 @@ static void dump(void *p, int size, int first, int last)
 }
 #endif
 
-void *labcomm_signature_array_ref(struct labcomm_memory *memory,
+void *labcomm2014_signature_array_ref(struct labcomm2014_memory *memory,
 				  int *first, int *last, void **data,
 				  int size, int index)
 {
   if (*first == 0 && *last == 0) {
     *first = index;
     *last = index + 1;
-    *data = labcomm_memory_alloc(memory, 0, size);
-    if (*data) { 
-      memset(*data, 0, size); 
+    *data = labcomm2014_memory_alloc(memory, 0, size);
+    if (*data) {
+      memset(*data, 0, size);
     }
   } else if (index < *first || *last <= index) {
     void *old_data = *data;
@@ -218,15 +218,15 @@ void *labcomm_signature_array_ref(struct labcomm_memory *memory,
     *first = (index<old_first)?index:old_first;
     *last = (old_last<=index)?index+1:old_last;
     n = (*last - *first);
-    *data = labcomm_memory_alloc(memory, 0, n * size);
+    *data = labcomm2014_memory_alloc(memory, 0, n * size);
     if (*data) {
       memset(*data, 0, n * size);
-      memcpy(*data + (old_first - *first) * size, 
-	     old_data, 
+      memcpy(*data + (old_first - *first) * size,
+	     old_data,
 	     (old_last - old_first) * size);
     }
 //    dump(old_data, size, old_first, old_last);
-    labcomm_memory_free(memory, 0, old_data);
+    labcomm2014_memory_free(memory, 0, old_data);
   }
   if (*data) {
 //    dump(*data, size, *first, *last);
@@ -236,33 +236,38 @@ void *labcomm_signature_array_ref(struct labcomm_memory *memory,
   }
 }
 
-static int local_index = 0x40;
+static int local_index = LABCOMM_USER;
 
-void labcomm_set_local_index(struct labcomm_signature *signature)
+void labcomm2014_set_local_index(struct labcomm2014_signature *signature)
 {
   if (signature->index != 0) {
-    labcomm_error_fatal_global(LABCOMM_ERROR_SIGNATURE_ALREADY_SET,
+    labcomm2014_error_fatal_global(LABCOMM2014_ERROR_SIGNATURE_ALREADY_SET,
 			       "Signature already set: %s\n", signature->name);
   }
   signature->index = local_index;
   local_index++;
 }
 
-int labcomm_get_local_index(const struct labcomm_signature *signature)
+int labcomm2014_get_local_index(const struct labcomm2014_signature *signature)
 {
   if (signature->index == 0) {
-    labcomm_error_fatal_global(LABCOMM_ERROR_SIGNATURE_NOT_SET,
+    labcomm2014_error_fatal_global(LABCOMM2014_ERROR_SIGNATURE_NOT_SET,
 			       "Signature not set: %s\n", signature->name);
   }
   return signature->index;
 }
 
-int labcomm_internal_sizeof(const struct labcomm_signature *signature,
+int labcomm2014_get_local_type_index(const struct labcomm2014_signature *signature)
+{
+    return labcomm2014_get_local_index(signature);
+}
+
+int labcomm2014_internal_sizeof(const struct labcomm2014_signature *signature,
                             void *v)
 {
   int length = signature->encoded_size(v);
-  return (labcomm_size_packed32(signature->index) +
-          labcomm_size_packed32(length) +
+  return (labcomm2014_size_packed32(signature->index) +
+          labcomm2014_size_packed32(length) +
           length);
 }
 
diff --git a/lib/c/2014/labcomm2014.h b/lib/c/2014/labcomm2014.h
new file mode 100644
index 0000000000000000000000000000000000000000..5492b1e230b183c0a3d876570fad0fd342e616eb
--- /dev/null
+++ b/lib/c/2014/labcomm2014.h
@@ -0,0 +1,138 @@
+/*
+  labcomm2014.h -- user interface for handling encoding and decoding of
+               labcomm2014 samples.
+
+  Copyright 2006-2013 Anders Blomdell <anders.blomdell@control.lth.se>
+
+  This file is part of LabComm.
+
+  LabComm is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  LabComm is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __LABCOMM_H__
+#define __LABCOMM_H__
+
+#include <stdarg.h>
+
+#ifdef LABCOMM_COMPAT
+  #include LABCOMM_COMPAT
+#else
+  #include <stdint.h>
+  #include <unistd.h>
+#endif
+
+#include "labcomm2014_error.h"
+#include "labcomm2014_scheduler.h"
+
+/* Forward declaration */
+struct labcomm2014_encoder;
+struct labcomm2014_decoder;
+
+#include "labcomm2014_type_signature.h"
+/*
+ * Error handling.
+ */
+
+/* The callback prototype for error handling.
+ * First parameter is the error ID.
+ * The second paramters is the number of va_args that comes after this 
+ * one. If none it should be 0.
+ * Optionaly other paramters can be supplied depending on what is needed 
+ * for this error ID.
+ */
+typedef void (*labcomm2014_error_handler_callback)(enum labcomm2014_error error_id, 
+					       size_t nbr_va_args, ...); 
+
+/* Default error handler, prints message to stderr. 
+ * Extra info about the error can be supplied as char* as VA-args. Especially user defined errors should supply a describing string. if nbr_va_args > 1 the first variable argument must be a printf format string and the possibly following arguments are passed as va_args to vprintf. 
+ */
+void labcomm20142014_on_error_fprintf(enum labcomm2014_error error_id, size_t nbr_va_args, ...);
+
+/* Register a callback for the error handler for this encoder. */
+void labcomm2014_register_error_handler_encoder(struct labcomm2014_encoder *encoder, labcomm2014_error_handler_callback callback);
+
+/* Register a callback for the error handler for this decoder. */
+void labcomm2014_register_error_handler_decoder(struct labcomm2014_decoder *decoder, labcomm2014_error_handler_callback callback);
+
+/* Get a string describing the supplied standrad labcomm2014 error. */
+const char *labcomm2014_error_get_str(enum labcomm2014_error error_id);
+
+typedef int (*labcomm2014_handle_new_datatype_callback)(
+  struct labcomm2014_decoder *decoder,
+  struct labcomm2014_signature *sig);
+
+/*
+ * Dynamic memory handling
+ *   lifetime == 0     memory that will live for as long as the 
+ *                     encoder/decoder or that are allocated/deallocated 
+ *                     during the communication setup phase
+ *   otherwise         memory will live for approximately this number of
+ *                     sent/received samples
+ */
+struct labcomm2014_memory;
+
+void *labcomm2014_memory_alloc(struct labcomm2014_memory *m, int lifetime, size_t size);
+void *labcomm2014_memory_realloc(struct labcomm2014_memory *m, int lifetime, 
+			     void *ptr, size_t size);
+void labcomm2014_memory_free(struct labcomm2014_memory *m, int lifetime, void *ptr);
+
+/*
+ * Decoder
+ */
+struct labcomm2014_reader;
+
+struct labcomm2014_decoder *labcomm2014_decoder_new(
+  struct labcomm2014_reader *reader,
+  struct labcomm2014_error_handler *error,
+  struct labcomm2014_memory *memory,
+  struct labcomm2014_scheduler *scheduler);
+void labcomm2014_decoder_free(
+  struct labcomm2014_decoder *decoder);
+int labcomm2014_decoder_decode_one(
+  struct labcomm2014_decoder *decoder);
+void labcomm2014_decoder_run(
+  struct labcomm2014_decoder *decoder);
+int labcomm2014_decoder_sample_ref_register(
+  struct labcomm2014_decoder *decoder,
+  const struct labcomm2014_signature *signature);
+
+/* See labcomm2014_ioctl.h for predefined ioctl_action values */
+int labcomm2014_decoder_ioctl(struct labcomm2014_decoder *decoder, 
+			  uint32_t ioctl_action,
+			  ...);
+
+/*
+ * Encoder
+ */
+struct labcomm2014_writer;
+
+struct labcomm2014_encoder *labcomm2014_encoder_new(
+  struct labcomm2014_writer *writer,
+  struct labcomm2014_error_handler *error,
+  struct labcomm2014_memory *memory,
+  struct labcomm2014_scheduler *scheduler);
+void labcomm2014_encoder_free(
+  struct labcomm2014_encoder *encoder);
+int labcomm2014_encoder_sample_ref_register(
+  struct labcomm2014_encoder *encoder,
+  const struct labcomm2014_signature *signature);
+
+/* See labcomm2014_ioctl.h for predefined ioctl_action values */
+int labcomm2014_encoder_ioctl(struct labcomm2014_encoder *encoder, 
+			  uint32_t ioctl_action,
+			  ...);
+
+#define LABCOMM_VOID ((void*)1)
+
+#endif
diff --git a/lib/c/2014/labcomm_compat_arm_cortexm3.h b/lib/c/2014/labcomm2014_compat_arm_cortexm3.h
similarity index 100%
rename from lib/c/2014/labcomm_compat_arm_cortexm3.h
rename to lib/c/2014/labcomm2014_compat_arm_cortexm3.h
diff --git a/lib/c/2014/labcomm_compat_osx.h b/lib/c/2014/labcomm2014_compat_osx.h
similarity index 100%
rename from lib/c/2014/labcomm_compat_osx.h
rename to lib/c/2014/labcomm2014_compat_osx.h
diff --git a/lib/c/2014/labcomm_compat_vxworks.h b/lib/c/2014/labcomm2014_compat_vxworks.h
similarity index 100%
rename from lib/c/2014/labcomm_compat_vxworks.h
rename to lib/c/2014/labcomm2014_compat_vxworks.h
diff --git a/lib/c/2014/labcomm2014_decoder.c b/lib/c/2014/labcomm2014_decoder.c
new file mode 100644
index 0000000000000000000000000000000000000000..8d3f79b7e84ff100ff520ec952917f54cb439cfd
--- /dev/null
+++ b/lib/c/2014/labcomm2014_decoder.c
@@ -0,0 +1,665 @@
+/*
+  labcomm2014_decoder.c -- runtime for handling decoding of labcomm2014 samples.
+
+  Copyright 2006-2013 Anders Blomdell <anders.blomdell@control.lth.se>
+
+  This file is part of LabComm.
+
+  LabComm is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  LabComm is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+#define CURRENT_VERSION "LabComm2014"
+
+#include <errno.h>
+#include "labcomm2014.h"
+#include "labcomm2014_private.h"
+#include "labcomm2014_ioctl.h"
+#include "labcomm2014_dynamic_buffer_writer.h"
+
+#ifdef DEBUG
+#define DEBUG_FPRINTF(str, ...) fprintf(str, ##__VA_ARGS__)
+#else
+#define DEBUG_FPRINTF(str, ...)
+#endif
+
+#ifdef DECODER_DEBUG
+#define DECODER_DEBUG_FPRINTF(str, ...) fprintf(str, ##__VA_ARGS__) 
+#else
+#define DECODER_DEBUG_FPRINTF(str, ...)
+#endif
+
+struct sample_entry {
+  int remote_index;
+  const struct labcomm2014_signature *signature;
+  labcomm2014_decoder_function decode;
+  labcomm2014_handler_function handler;
+  void *context;
+};
+
+struct labcomm2014_decoder {
+  struct labcomm2014_reader *reader;
+  int reader_allocated;
+  int version_ok;
+  struct labcomm2014_error_handler *error;
+  struct labcomm2014_memory *memory;
+  struct labcomm2014_scheduler *scheduler;
+  labcomm2014_error_handler_callback on_error;
+  labcomm2014_handle_new_datatype_callback on_new_datatype;
+  LABCOMM_SIGNATURE_ARRAY_DEF(local, struct sample_entry);
+  LABCOMM_SIGNATURE_ARRAY_DEF(remote_to_local, int);
+  LABCOMM_SIGNATURE_ARRAY_DEF(local_ref, const struct labcomm2014_signature *);
+  LABCOMM_SIGNATURE_ARRAY_DEF(remote_to_local_ref, int);
+};
+
+struct labcomm2014_decoder *labcomm2014_decoder_new(
+  struct labcomm2014_reader *reader,
+  struct labcomm2014_error_handler *error,
+  struct labcomm2014_memory *memory,
+  struct labcomm2014_scheduler *scheduler)
+{
+  struct labcomm2014_decoder *result;
+
+  result = labcomm2014_memory_alloc(memory, 0, sizeof(*result));
+  if (result) {
+    result->reader = reader;
+    result->reader->decoder = result;
+    result->reader->data = 0;
+    result->reader->data_size = 0;
+    result->reader->count = 0;
+    result->reader->pos = 0;
+    result->reader->error = 0;
+    result->reader_allocated = 0;
+    result->version_ok = 0;
+    result->error = error;
+    result->memory = memory;
+    result->scheduler = scheduler;
+    result->on_error = labcomm20142014_on_error_fprintf;
+    LABCOMM_SIGNATURE_ARRAY_INIT(result->local, struct sample_entry);
+    LABCOMM_SIGNATURE_ARRAY_INIT(result->remote_to_local, int);
+    LABCOMM_SIGNATURE_ARRAY_INIT(result->local_ref, 
+                                 const struct labcomm2014_signature*);
+    LABCOMM_SIGNATURE_ARRAY_INIT(result->remote_to_local_ref, int);
+  }
+  return result;
+}
+
+void labcomm2014_decoder_free(struct labcomm2014_decoder* d)
+{
+  struct labcomm2014_memory *memory = d->memory;
+
+  labcomm2014_reader_free(d->reader, d->reader->action_context);
+  LABCOMM_SIGNATURE_ARRAY_FREE(memory, d->local, struct sample_entry);
+  LABCOMM_SIGNATURE_ARRAY_FREE(memory, d->remote_to_local, int);
+  LABCOMM_SIGNATURE_ARRAY_FREE(memory, d->local_ref, 
+                               const struct labcomm2014_signature*);
+  LABCOMM_SIGNATURE_ARRAY_FREE(memory, d->remote_to_local_ref, int);
+  labcomm2014_memory_free(memory, 0, d);
+}
+
+static int handle_sample_def(struct labcomm2014_decoder *d, int remote_index,
+                             const struct labcomm2014_signature *signature)
+{
+  int result;
+  int i;
+  const struct labcomm2014_signature *local_signature = NULL;
+  int local_index = 0;
+
+  labcomm2014_scheduler_data_lock(d->scheduler);
+  LABCOMM_SIGNATURE_ARRAY_FOREACH(d->local, struct sample_entry, i) {
+    struct sample_entry *s;
+    int *remote_to_local;
+
+    result = -ENOENT;
+    s = LABCOMM_SIGNATURE_ARRAY_REF(d->memory, 
+                                    d->local, struct sample_entry, i);
+    if (s->signature &&
+        s->signature->size == signature->size &&
+        strcmp(s->signature->name, signature->name) == 0 &&
+        memcmp((void*)s->signature->signature, (void*)signature->signature,
+	       signature->size) == 0) {
+      s->remote_index = remote_index;
+      local_signature = s->signature;
+      local_index = i;
+      remote_to_local = LABCOMM_SIGNATURE_ARRAY_REF(d->memory,
+                                                    d->remote_to_local, int,
+                                                    remote_index);
+      *remote_to_local = i;
+      result = remote_index;
+      break;
+    }
+  }
+  labcomm2014_scheduler_data_unlock(d->scheduler);
+  if (local_signature) {
+    labcomm2014_reader_start(d->reader, d->reader->action_context,
+                         local_index, remote_index, local_signature,
+                         NULL);
+    labcomm2014_reader_end(d->reader, d->reader->action_context);
+  }
+  return result;
+}
+
+static int handle_sample_ref(struct labcomm2014_decoder *d, int remote_index,
+                             const struct labcomm2014_signature *signature)
+{
+  int result;
+  int i;
+
+  labcomm2014_scheduler_data_lock(d->scheduler);
+  LABCOMM_SIGNATURE_ARRAY_FOREACH(d->local_ref, const struct labcomm2014_signature *, i) {
+    const struct labcomm2014_signature *s;
+    int *remote_to_local_ref;
+
+    result = -ENOENT;
+    s = LABCOMM_SIGNATURE_ARRAY_GET(d->local_ref, const struct labcomm2014_signature *, i, 0);
+    if (s &&
+        s->signature &&
+        s->size == signature->size &&
+        strcmp(s->name, signature->name) == 0 &&
+        memcmp((void*)s->signature, (void*)signature->signature, signature->size) == 0) {
+      remote_to_local_ref = LABCOMM_SIGNATURE_ARRAY_REF(d->memory,
+                                                        d->remote_to_local_ref, int,
+                                                        remote_index);
+      *remote_to_local_ref = i;
+      result = remote_index;
+      break;
+    }
+  }
+  labcomm2014_scheduler_data_unlock(d->scheduler);
+  return result;
+}
+
+static int decoder_skip(struct labcomm2014_decoder *d, int len, int tag)
+{
+  int i;
+  DECODER_DEBUG_FPRINTF(stdout, "got tag 0x%x, skipping %d bytes\n", tag, len);
+  for(i = 0; i <len; i++){
+    DECODER_DEBUG_FPRINTF(stderr, ".");
+    labcomm2014_read_byte(d->reader);
+    if (d->reader->error < 0) {
+      DECODER_DEBUG_FPRINTF(stderr, "\nerror while skipping: %d\n",  d->reader->error);
+      return d->reader->error;
+    }
+  }
+  DECODER_DEBUG_FPRINTF(stderr, "\n");
+  return tag;
+}
+
+static int decode_sample_def_or_ref(struct labcomm2014_decoder *d, int kind)
+{
+  int result;
+  struct labcomm2014_signature signature;
+  int i, remote_index;
+
+  remote_index = labcomm2014_read_packed32(d->reader);
+  if (d->reader->error < 0) {
+    result = d->reader->error;
+    goto out;
+  }
+  signature.name = labcomm2014_read_string(d->reader);
+  if (d->reader->error < 0) {
+    result = d->reader->error;
+    goto out;
+  }
+  signature.size = labcomm2014_read_packed32(d->reader);
+  if (d->reader->error < 0) {
+    result = d->reader->error;
+    goto free_signature_name;
+  }
+  signature.signature = labcomm2014_memory_alloc(d->memory, 1,  signature.size);
+  if (d->reader->error < 0) {
+    result = d->reader->error;
+    goto free_signature_name;
+  }
+  for (i = 0 ; i < signature.size ; i++) {
+    signature.signature[i] = labcomm2014_read_byte(d->reader);
+    if (d->reader->error < 0) {
+      result = d->reader->error;
+      goto free_signature_signature;
+    }
+  }
+  switch (kind) {
+    case LABCOMM_SAMPLE_DEF: {
+      result = handle_sample_def(d, remote_index, &signature);
+      break;
+    } 
+    case LABCOMM_SAMPLE_REF: {
+      result = handle_sample_ref(d, remote_index, &signature);
+      if (result == -ENOENT) {
+        /* Dummy value to silently continue */
+        result = LABCOMM_SAMPLE_REF;
+      }
+      break;
+    } 
+    default:
+      result = -EINVAL;
+  }
+free_signature_signature:
+  labcomm2014_memory_free(d->memory, 1,  signature.signature);
+free_signature_name:
+  labcomm2014_memory_free(d->memory, 0, signature.name);
+out:
+  return result;
+}
+
+struct call_handler_context {
+  struct labcomm2014_reader *reader;
+  int local_index;
+  int remote_index;
+  const struct labcomm2014_signature *signature;
+  labcomm2014_handler_function handler;
+  void *context;
+};
+
+static void call_handler(void *value, void *context)
+{
+  struct call_handler_context *wrap = context;
+
+  if (wrap->reader->error >= 0) {
+    labcomm2014_reader_start(wrap->reader, wrap->reader->action_context,
+			 wrap->local_index, wrap->remote_index, wrap->signature,
+			 value);
+    wrap->handler(value, wrap->context);
+    labcomm2014_reader_end(wrap->reader, wrap->reader->action_context);
+  }
+}
+
+static void reader_alloc(struct labcomm2014_decoder *d)
+{
+  if (!d->reader_allocated) {
+    d->reader_allocated = 1;
+    labcomm2014_reader_alloc(d->reader, d->reader->action_context);
+  }
+}
+
+/* d        - decoder to read from
+   registry - decoder to lookup signatures (registry != d only if
+                nesting decoders, e.g., when decoding pragma)
+   len      - length of the labcomm2014 packet )
+*/
+static int decode_pragma(struct labcomm2014_decoder *d,
+		         struct labcomm2014_decoder *registry,
+		         int len)
+{
+  char *pragma_type;
+  int result;
+  pragma_type = labcomm2014_read_string(d->reader);
+  if (d->reader->error < 0) {
+    result = d->reader->error;
+    goto out;
+  }
+  int bytes = labcomm2014_size_string(pragma_type);
+  int psize = len-bytes;
+  result = decoder_skip(d, psize, LABCOMM_PRAGMA);
+out:
+  return result;
+}
+
+static labcomm2014_decoder_function lookup_h(struct labcomm2014_decoder *d,
+		                         struct call_handler_context *wrap,
+		                         int remote_index,
+					 int **local_index)
+{
+  labcomm2014_decoder_function do_decode = NULL;
+  labcomm2014_scheduler_data_lock(d->scheduler);
+  *local_index = LABCOMM_SIGNATURE_ARRAY_REF(d->memory,
+      				      d->remote_to_local, int,
+      				      remote_index);
+  if (**local_index != 0) {
+    struct sample_entry *entry;
+
+    entry = LABCOMM_SIGNATURE_ARRAY_REF(d->memory,
+      				  d->local, struct sample_entry,
+      				  **local_index);
+    wrap->local_index = **local_index;
+    wrap->signature = entry->signature;
+    wrap->handler = entry->handler;
+    wrap->context = entry->context;
+    do_decode = entry->decode;
+  }
+  labcomm2014_scheduler_data_unlock(d->scheduler);
+  return do_decode;
+}
+/* d            - decoder to read from
+   registry     - decoder to lookup signatures (registry != d only if
+                    nesting decoders, e.g., when decoding pragma)
+   remote_index -  received type index )
+*/
+static int decode_and_handle(struct labcomm2014_decoder *d,
+		             struct labcomm2014_decoder *registry,
+		             int remote_index)
+{
+  int result;
+  int *local_index;
+  struct call_handler_context wrap = {
+    .reader = d->reader,
+    .remote_index = remote_index,
+    .signature = NULL,
+    .handler = NULL,
+    .context = NULL,
+  };
+  labcomm2014_decoder_function do_decode = lookup_h(registry, &wrap, remote_index, &local_index);
+  result = *local_index;
+  if (do_decode) {
+    do_decode(d->reader, call_handler, &wrap);
+    if (d->reader->error < 0) {
+      result = d->reader->error;
+    }
+  } else {
+    result = -ENOENT;
+  }
+  return result;
+}
+int labcomm2014_decoder_decode_one(struct labcomm2014_decoder *d)
+{
+  int result, remote_index, length;
+
+  reader_alloc(d);
+  remote_index = labcomm2014_read_packed32(d->reader);
+  if (d->reader->error < 0) {
+    result = d->reader->error;
+    goto out;
+  }
+  length = labcomm2014_read_packed32(d->reader);
+  if (d->reader->error < 0) {
+    result = d->reader->error;
+    goto out;
+  }
+  if (remote_index == LABCOMM_VERSION) {
+    char *version = labcomm2014_read_string(d->reader);
+    if (d->reader->error < 0) {
+      result = d->reader->error;
+      goto out;
+    }
+    if (strcmp(version, CURRENT_VERSION) == 0) {
+      result = LABCOMM_VERSION;
+      d->version_ok = 1;
+    } else {
+      result = -ECONNRESET;
+    }  
+    labcomm2014_memory_free(d->memory, 1,  version);
+  } else if (! d->version_ok) {
+    DEBUG_FPRINTF(stderr, "No VERSION %d %d\n", remote_index, length);
+    result = -ECONNRESET;
+  } else if (remote_index == LABCOMM_SAMPLE_DEF) {
+    result = decode_sample_def_or_ref(d, LABCOMM_SAMPLE_DEF); 
+  } else if (remote_index == LABCOMM_SAMPLE_REF) {
+    result = decode_sample_def_or_ref(d, LABCOMM_SAMPLE_REF); 
+  } else if (remote_index == LABCOMM_TYPE_DEF) {
+    result = decode_and_handle(d, d, remote_index);
+    if(result == -ENOENT) { 
+        //No handler for type_defs, skip
+        result = decoder_skip(d, length, remote_index);
+    }
+  } else if (remote_index == LABCOMM_TYPE_BINDING) {
+    result = decode_and_handle(d, d, remote_index);
+    if(result == -ENOENT) { 
+        //No handler for type_bindings, skip
+        result = decoder_skip(d, length, remote_index);
+    }
+  } else if (remote_index == LABCOMM_PRAGMA) {
+    result = decode_pragma(d, d, length);
+  } else if (remote_index < LABCOMM_USER) {
+    DECODER_DEBUG_FPRINTF(stderr, "SKIP %d %d\n", remote_index, length);
+    result = decoder_skip(d, length, remote_index);
+  } else {
+    result = decode_and_handle(d, d, remote_index);
+  }
+out:   
+  return result;
+}
+
+void labcomm2014_decoder_run(struct labcomm2014_decoder *d)
+{
+  while (labcomm2014_decoder_decode_one(d) > 0) {
+  }
+}
+
+int labcomm2014_decoder_ioctl(struct labcomm2014_decoder *d, 
+			  uint32_t action,
+			  ...)
+{
+  int result;  
+  va_list va;
+    
+  va_start(va, action);
+  result = labcomm2014_reader_ioctl(d->reader, 
+				d->reader->action_context,
+				0, 0, NULL, action, va);
+  va_end(va);
+  return result;
+}
+
+int labcomm2014_decoder_sample_ref_register(
+  struct labcomm2014_decoder *d,
+  const struct labcomm2014_signature *signature)
+{
+  int local_index, *remote_to_local_ref;
+  const struct labcomm2014_signature **s;
+
+  local_index = labcomm2014_get_local_index(signature);
+  if (local_index <= 0) { goto out; }
+  labcomm2014_scheduler_data_lock(d->scheduler);
+  s = LABCOMM_SIGNATURE_ARRAY_REF(d->memory, 
+                                  d->local_ref, 
+                                  const struct labcomm2014_signature*, local_index);
+  if (s == NULL) { local_index = -ENOMEM; goto unlock; };
+  if (*s) { goto unlock; }
+  *s = signature;	
+  remote_to_local_ref = LABCOMM_SIGNATURE_ARRAY_REF(d->memory, 
+                                                    d->remote_to_local_ref, 
+                                                    int, local_index);
+  *remote_to_local_ref = 0;
+unlock:
+  labcomm2014_scheduler_data_unlock(d->scheduler);
+out:
+  return local_index;
+}
+
+int labcomm2014_internal_decoder_ioctl(struct labcomm2014_decoder *d, 
+				   const struct labcomm2014_signature *signature,
+				   uint32_t action, va_list va)
+{
+  int result;
+  int local_index, remote_index;
+
+  local_index = labcomm2014_get_local_index(signature);
+  labcomm2014_scheduler_data_lock(d->scheduler);
+  remote_index = LABCOMM_SIGNATURE_ARRAY_REF(d->memory,
+					     d->local,
+					     struct sample_entry,
+					     local_index)->remote_index;
+  labcomm2014_scheduler_data_unlock(d->scheduler);
+  result = labcomm2014_reader_ioctl(d->reader, d->reader->action_context,
+				local_index, remote_index, 
+				signature, action, va);
+  return result;
+}
+
+#ifndef LABCOMM_NO_TYPEDECL
+//// Code for allowing user code to handle type_defs 
+//// (should perhaps be moved to another file)
+
+static void decode_raw_type_def(
+  struct labcomm2014_reader *r,
+  void (*handle)(
+    struct labcomm2014_raw_type_def *v,
+    void *context
+  ),
+  void *context
+)
+{
+  struct labcomm2014_raw_type_def v;
+  v.index = labcomm2014_read_packed32(r);
+  if (r->error < 0) { goto out; }
+  v.name  = labcomm2014_read_string(r);
+  if (r->error < 0) { goto free_name; }
+  v.length = labcomm2014_read_packed32(r);
+  if (r->error < 0) { goto free_name; }
+  int i;
+  v.signature_data = labcomm2014_memory_alloc(r->memory, 1, v.length);
+  if(v.signature_data) {
+    for(i=0; i<v.length; i++) {
+      v.signature_data[i] = labcomm2014_read_byte(r);
+      if (r->error < 0) { goto free_sig; }
+    }  
+    handle(&v, context);
+    }
+free_sig:
+  labcomm2014_memory_free(r->memory, 1, v.signature_data);
+free_name:
+  labcomm2014_memory_free(r->memory, 1, v.name);
+out:
+  return;
+}
+int labcomm2014_decoder_register_labcomm2014_type_def(
+  struct labcomm2014_decoder *d,
+  void (*handler)(
+    struct labcomm2014_raw_type_def *v,
+    void *context
+  ),
+  void *context
+)
+{
+  int tag = LABCOMM_TYPE_DEF;
+  struct sample_entry *entry;
+  int *remote_to_local;
+ 
+  labcomm2014_scheduler_data_lock(d->scheduler);
+  entry = LABCOMM_SIGNATURE_ARRAY_REF(d->memory,
+				      d->local, struct sample_entry,
+				      tag);
+  if (entry == NULL) { tag = -ENOMEM; goto unlock; }
+  entry->remote_index = tag;
+  entry->signature = NULL;
+  entry->decode = (labcomm2014_decoder_function) decode_raw_type_def;
+  entry->handler =(labcomm2014_handler_function) handler;
+  entry->context = context;
+
+  remote_to_local = LABCOMM_SIGNATURE_ARRAY_REF(d->memory,
+                                                    d->remote_to_local, int,
+                                                    tag);
+  *remote_to_local = tag;
+unlock:
+  labcomm2014_scheduler_data_unlock(d->scheduler);
+
+  return tag;
+}
+
+
+static void decode_type_binding(
+  struct labcomm2014_reader *r,
+  void (*handle)(
+    struct labcomm2014_type_binding *v,
+    void *context
+  ),
+  void *context
+)
+{
+  struct labcomm2014_type_binding v;
+  v.sample_index = labcomm2014_read_packed32(r);
+  if (r->error < 0) { goto out; }
+  v.type_index = labcomm2014_read_packed32(r);
+  if (r->error < 0) { goto out; }
+  handle(&v, context);
+out:
+  return;
+}
+
+int labcomm2014_decoder_register_labcomm2014_type_binding(
+  struct labcomm2014_decoder *d,
+  void (*handler)(
+    struct labcomm2014_type_binding *v,
+    void *context
+  ),
+  void *context
+)
+{
+  int tag = LABCOMM_TYPE_BINDING;
+  struct sample_entry *entry;
+  int *remote_to_local;
+ 
+  labcomm2014_scheduler_data_lock(d->scheduler);
+  entry = LABCOMM_SIGNATURE_ARRAY_REF(d->memory,
+				      d->local, struct sample_entry,
+				      tag);
+  if (entry == NULL) { tag = -ENOMEM; goto unlock; }
+  entry->remote_index = tag;
+  entry->signature = NULL;
+  entry->decode = (labcomm2014_decoder_function) decode_type_binding;
+  entry->handler =(labcomm2014_handler_function) handler;
+  entry->context = context;
+
+  remote_to_local = LABCOMM_SIGNATURE_ARRAY_REF(d->memory,
+                                                    d->remote_to_local, int,
+                                                    tag);
+  *remote_to_local = tag;
+unlock:
+  labcomm2014_scheduler_data_unlock(d->scheduler);
+
+  return tag;
+}
+
+//// End type_def handling
+#endif
+
+int labcomm2014_internal_decoder_register(
+  struct labcomm2014_decoder *d,
+  const struct labcomm2014_signature *signature,
+  labcomm2014_decoder_function decode, 
+  labcomm2014_handler_function handler,
+  void *context)
+{
+  int local_index;
+  struct sample_entry *entry;
+ 
+  reader_alloc(d);
+  local_index = labcomm2014_get_local_index(signature);
+  if (local_index <= 0) { goto out; }
+  labcomm2014_reader_start(d->reader, d->reader->action_context,
+		       local_index, 0, signature,
+		       NULL);
+  labcomm2014_reader_end(d->reader, d->reader->action_context);
+
+  labcomm2014_scheduler_data_lock(d->scheduler);
+  entry = LABCOMM_SIGNATURE_ARRAY_REF(d->memory,
+				      d->local, struct sample_entry,
+				      local_index);
+  if (entry == NULL) { local_index = -ENOMEM; goto unlock; }
+  entry->remote_index = 0;
+  entry->signature = signature;
+  entry->decode = decode;
+  entry->handler = handler;
+  entry->context = context;
+unlock:
+  labcomm2014_scheduler_data_unlock(d->scheduler);
+out:
+  return local_index;
+}
+
+const struct labcomm2014_signature *labcomm2014_internal_decoder_index_to_signature(
+  struct labcomm2014_decoder *d, int index)
+{
+  const struct labcomm2014_signature *result = 0;
+  int local_index;
+
+  labcomm2014_scheduler_data_lock(d->scheduler);
+  local_index = LABCOMM_SIGNATURE_ARRAY_GET(d->remote_to_local_ref, 
+                                            int, index, 0);
+  if (local_index) {
+    result = LABCOMM_SIGNATURE_ARRAY_GET(d->local_ref, 
+                                         const struct labcomm2014_signature*, 
+                                         local_index, 0);
+  }
+  labcomm2014_scheduler_data_unlock(d->scheduler);
+  return result;
+}
diff --git a/lib/c/2014/labcomm_default_error_handler.c b/lib/c/2014/labcomm2014_default_error_handler.c
similarity index 88%
rename from lib/c/2014/labcomm_default_error_handler.c
rename to lib/c/2014/labcomm2014_default_error_handler.c
index 61e04dd6d5153f360b4564364c3b37ee67a171af..ae9fe30323823573ae4bb51b27c13e47f7c12114 100644
--- a/lib/c/2014/labcomm_default_error_handler.c
+++ b/lib/c/2014/labcomm2014_default_error_handler.c
@@ -19,6 +19,6 @@
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-#include "labcomm.h"
+#include "labcomm2014.h"
 
-struct labcomm_error_handler *labcomm_default_error_handler = NULL;
+struct labcomm2014_error_handler *labcomm2014_default_error_handler = NULL;
diff --git a/lib/c/2014/labcomm_default_error_handler.h b/lib/c/2014/labcomm2014_default_error_handler.h
similarity index 79%
rename from lib/c/2014/labcomm_default_error_handler.h
rename to lib/c/2014/labcomm2014_default_error_handler.h
index 4cd642a9e2f986f31ce085d6fc775fa8d7312fb2..420cb4032605b12c1437504399b378020339175d 100644
--- a/lib/c/2014/labcomm_default_error_handler.h
+++ b/lib/c/2014/labcomm2014_default_error_handler.h
@@ -18,7 +18,11 @@
   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
+#ifndef __LABCOMM2014_DEFAULT_ERROR_HANDLER_H__
+#define __LABCOMM2014_DEFAULT_ERROR_HANDLER_H__
 
-#include "labcomm.h"
+#include "labcomm2014.h"
 
-extern struct labcomm_error_handler *labcomm_default_error_handler;
+extern struct labcomm2014_error_handler *labcomm2014_default_error_handler;
+
+#endif
diff --git a/lib/c/2014/labcomm_default_memory.c b/lib/c/2014/labcomm2014_default_memory.c
similarity index 73%
rename from lib/c/2014/labcomm_default_memory.c
rename to lib/c/2014/labcomm2014_default_memory.c
index d6b13c52621352a3658e2ce51d20b9e4d92b7274..17dee8adf48871c0e9fbab15b560c8a23477e9ee 100644
--- a/lib/c/2014/labcomm_default_memory.c
+++ b/lib/c/2014/labcomm2014_default_memory.c
@@ -20,30 +20,30 @@
 */
 
 #include <stdlib.h>
-#include "labcomm.h"
-#include "labcomm_private.h"
+#include "labcomm2014.h"
+#include "labcomm2014_private.h"
 
-void *default_alloc(struct labcomm_memory *m, int lifetime, size_t size)
+void *default_alloc(struct labcomm2014_memory *m, int lifetime, size_t size)
 {
   return malloc(size);
 }
 
-void *default_realloc(struct labcomm_memory *m, int lifetime, 
+void *default_realloc(struct labcomm2014_memory *m, int lifetime, 
 		      void *ptr, size_t size)
 {
   return realloc(ptr, size);
 }
 
-void default_free(struct labcomm_memory *m, int lifetime, void *ptr)
+void default_free(struct labcomm2014_memory *m, int lifetime, void *ptr)
 {
   free(ptr);
 }
 
-struct labcomm_memory memory = {
+struct labcomm2014_memory memory = {
   .alloc = default_alloc,
   .realloc = default_realloc,
   .free = default_free,
   .context = NULL
 };
 
-struct labcomm_memory *labcomm_default_memory = &memory;
+struct labcomm2014_memory *labcomm2014_default_memory = &memory;
diff --git a/lib/c/2014/labcomm_default_memory.h b/lib/c/2014/labcomm2014_default_memory.h
similarity index 82%
rename from lib/c/2014/labcomm_default_memory.h
rename to lib/c/2014/labcomm2014_default_memory.h
index 8b22301ed7c9e9bdaf8bf13f98661af264b864d3..57947fb6e286a3b1a43913d0a35da564157539be 100644
--- a/lib/c/2014/labcomm_default_memory.h
+++ b/lib/c/2014/labcomm2014_default_memory.h
@@ -18,9 +18,12 @@
   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
+#ifndef __LABCOMM2014_DEFAULT_MEMORY_H__
+#define __LABCOMM2014_DEFAULT_MEMORY_H__
 
 #include <stdlib.h>
-#include "labcomm.h"
+#include "labcomm2014.h"
 
-extern struct labcomm_memory *labcomm_default_memory;
+extern struct labcomm2014_memory *labcomm2014_default_memory;
 
+#endif
diff --git a/lib/c/2014/labcomm_default_scheduler.c b/lib/c/2014/labcomm2014_default_scheduler.c
similarity index 67%
rename from lib/c/2014/labcomm_default_scheduler.c
rename to lib/c/2014/labcomm2014_default_scheduler.c
index a567b61ebddd8a6d611e020dede1c927b09fd28e..f1fd3d6b4155c6d9e0bf29c6375c26c4bc7241a6 100644
--- a/lib/c/2014/labcomm_default_scheduler.c
+++ b/lib/c/2014/labcomm2014_default_scheduler.c
@@ -21,11 +21,11 @@
 
 #include <stdio.h>
 #include <stdlib.h>
-#include "labcomm_default_scheduler.h"
-#include "labcomm_scheduler.h"
-#include "labcomm_scheduler_private.h"
+#include "labcomm2014_default_scheduler.h"
+#include "labcomm2014_scheduler.h"
+#include "labcomm2014_scheduler_private.h"
 
-static int scheduler_free(struct labcomm_scheduler *s)
+static int scheduler_free(struct labcomm2014_scheduler *s)
 {
   fprintf(stderr, "%s:%d %s %s", __FILE__, __LINE__, __FUNCTION__,
 	  "not implemented");
@@ -33,27 +33,27 @@ static int scheduler_free(struct labcomm_scheduler *s)
   return 0;
 }
  
-static int scheduler_writer_lock(struct labcomm_scheduler *s)
+static int scheduler_writer_lock(struct labcomm2014_scheduler *s)
 {
   return 0;
 }
  
-static int scheduler_writer_unlock(struct labcomm_scheduler *s)
+static int scheduler_writer_unlock(struct labcomm2014_scheduler *s)
 {
   return 0;
 }
 
-static int scheduler_data_lock(struct labcomm_scheduler *s)
+static int scheduler_data_lock(struct labcomm2014_scheduler *s)
 {
   return 0;
 }
  
-static int scheduler_data_unlock(struct labcomm_scheduler *s)
+static int scheduler_data_unlock(struct labcomm2014_scheduler *s)
 {
   return 0;
 }
 
-static struct labcomm_time *scheduler_now(struct labcomm_scheduler *s)
+static struct labcomm2014_time *scheduler_now(struct labcomm2014_scheduler *s)
 {
   fprintf(stderr, "%s:%d %s %s", __FILE__, __LINE__, __FUNCTION__,
 	  "not implemented");
@@ -61,8 +61,8 @@ static struct labcomm_time *scheduler_now(struct labcomm_scheduler *s)
   return NULL;
 }
  
-static int scheduler_sleep(struct labcomm_scheduler *s,
-			   struct labcomm_time *t)
+static int scheduler_sleep(struct labcomm2014_scheduler *s,
+			   struct labcomm2014_time *t)
 {
   fprintf(stderr, "%s:%d %s %s", __FILE__, __LINE__, __FUNCTION__,
 	  "not implemented");
@@ -70,7 +70,7 @@ static int scheduler_sleep(struct labcomm_scheduler *s,
   return 0;
 }
 
-static int scheduler_wakeup(struct labcomm_scheduler *s)
+static int scheduler_wakeup(struct labcomm2014_scheduler *s)
 {
   fprintf(stderr, "%s:%d %s %s", __FILE__, __LINE__, __FUNCTION__,
 	  "not implemented");
@@ -78,7 +78,7 @@ static int scheduler_wakeup(struct labcomm_scheduler *s)
   return 0;
 }
 
-static int scheduler_enqueue(struct labcomm_scheduler *s,
+static int scheduler_enqueue(struct labcomm2014_scheduler *s,
 			     uint32_t delay,
 			     void (*deferred)(void *context),
 			     void *context)
@@ -89,7 +89,7 @@ static int scheduler_enqueue(struct labcomm_scheduler *s,
   return 0;
 }
 
-static const struct labcomm_scheduler_action scheduler_action = {
+static const struct labcomm2014_scheduler_action scheduler_action = {
   .free = scheduler_free,
   .writer_lock = scheduler_writer_lock,
   .writer_unlock = scheduler_writer_unlock,
@@ -101,9 +101,9 @@ static const struct labcomm_scheduler_action scheduler_action = {
   .enqueue = scheduler_enqueue  
 };
 
-static struct labcomm_scheduler scheduler = {
+static struct labcomm2014_scheduler scheduler = {
   .action = &scheduler_action,
   .context = NULL
 };
 
-struct labcomm_scheduler *labcomm_default_scheduler = &scheduler;
+struct labcomm2014_scheduler *labcomm2014_default_scheduler = &scheduler;
diff --git a/lib/c/2014/labcomm_default_scheduler.h b/lib/c/2014/labcomm2014_default_scheduler.h
similarity index 80%
rename from lib/c/2014/labcomm_default_scheduler.h
rename to lib/c/2014/labcomm2014_default_scheduler.h
index 923ea20f26fe8c587dc0c97447592b738a4b0b8b..db416f37d66c284d783223f18b0ac5ed0734dbf5 100644
--- a/lib/c/2014/labcomm_default_scheduler.h
+++ b/lib/c/2014/labcomm2014_default_scheduler.h
@@ -18,7 +18,11 @@
   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
+#ifndef __LABCOMM2014_DEFAULT_SCHEDULER_H__
+#define __LABCOMM2014_DEFAULT_SCHEDULER_H__
 
-#include "labcomm.h"
+#include "labcomm2014.h"
 
-extern struct labcomm_scheduler *labcomm_default_scheduler;
+extern struct labcomm2014_scheduler *labcomm2014_default_scheduler;
+
+#endif
diff --git a/lib/c/2014/labcomm_dynamic_buffer_writer.c b/lib/c/2014/labcomm2014_dynamic_buffer_writer.c
similarity index 57%
rename from lib/c/2014/labcomm_dynamic_buffer_writer.c
rename to lib/c/2014/labcomm2014_dynamic_buffer_writer.c
index 32501e129e0756482167b95acc77b9159515cf6a..c2098625eaa72e50dba1344e410df085a5c4228e 100644
--- a/lib/c/2014/labcomm_dynamic_buffer_writer.c
+++ b/lib/c/2014/labcomm2014_dynamic_buffer_writer.c
@@ -1,5 +1,5 @@
 /*
-  labcomm_dynamic_buffer_writer.c -- LabComm dynamic memory writer.
+  labcomm2014_dynamic_buffer_writer.c -- LabComm dynamic memory writer.
 
   Copyright 2006-2013 Anders Blomdell <anders.blomdell@control.lth.se>
 
@@ -22,17 +22,17 @@
 #include <errno.h>
 #include <stdlib.h>
 #include <stdarg.h>
-#include "labcomm.h"
-#include "labcomm_private.h"
-#include "labcomm_ioctl.h"
-#include "labcomm_dynamic_buffer_writer.h"
+#include "labcomm2014.h"
+#include "labcomm2014_private.h"
+#include "labcomm2014_ioctl.h"
+#include "labcomm2014_dynamic_buffer_writer.h"
 
-static int dyn_alloc(struct labcomm_writer *w, 
-		     struct labcomm_writer_action_context *action_context)
+static int dyn_alloc(struct labcomm2014_writer *w, 
+		     struct labcomm2014_writer_action_context *action_context)
 {
   w->data_size = 1000;
   w->count = w->data_size;
-  w->data = labcomm_memory_alloc(w->memory, 1, w->data_size);
+  w->data = labcomm2014_memory_alloc(w->memory, 1, w->data_size);
   if (w->data == NULL) {
     w->error = -ENOMEM;
   }
@@ -41,29 +41,29 @@ static int dyn_alloc(struct labcomm_writer *w,
   return w->error;
 }
 
-static int dyn_free(struct labcomm_writer *w, 
-		    struct labcomm_writer_action_context *action_context)
+static int dyn_free(struct labcomm2014_writer *w, 
+		    struct labcomm2014_writer_action_context *action_context)
 {
-  labcomm_memory_free(w->memory, 1, w->data);
+  labcomm2014_memory_free(w->memory, 1, w->data);
   w->data = 0;
   w->data_size = 0;
   w->count = 0;
   w->pos = 0;
-  labcomm_memory_free(w->memory, 0, action_context->context);
+  labcomm2014_memory_free(w->memory, 0, action_context->context);
   return 0;
 }
 
-static int dyn_start(struct labcomm_writer *w, 
-		     struct labcomm_writer_action_context *action_context,
+static int dyn_start(struct labcomm2014_writer *w, 
+		     struct labcomm2014_writer_action_context *action_context,
 		     int index,
-		     const struct labcomm_signature *signature,
+		     const struct labcomm2014_signature *signature,
 		     void *value)
 {
   void *tmp;
 
   w->data_size = 1000;
   w->count = w->data_size;
-  tmp = labcomm_memory_realloc(w->memory, 1, w->data, w->data_size);
+  tmp = labcomm2014_memory_realloc(w->memory, 1, w->data, w->data_size);
   if (tmp != NULL) {
     w->data = tmp;
     w->error = 0;
@@ -75,20 +75,20 @@ static int dyn_start(struct labcomm_writer *w,
   return w->error;
 }
 
-static int dyn_end(struct labcomm_writer *w, 
-		   struct labcomm_writer_action_context *action_context)
+static int dyn_end(struct labcomm2014_writer *w, 
+		   struct labcomm2014_writer_action_context *action_context)
 {
   return 0;
 }
 
-static int dyn_flush(struct labcomm_writer *w, 
-		     struct labcomm_writer_action_context *action_context)
+static int dyn_flush(struct labcomm2014_writer *w, 
+		     struct labcomm2014_writer_action_context *action_context)
 {
   void *tmp;
 
   w->data_size += 1000;
   w->count = w->data_size;
-  tmp = labcomm_memory_realloc(w->memory, 1, w->data, w->data_size);
+  tmp = labcomm2014_memory_realloc(w->memory, 1, w->data, w->data_size);
   if (tmp != NULL) {
     w->data = tmp;
     w->error = 0;
@@ -100,10 +100,10 @@ static int dyn_flush(struct labcomm_writer *w,
   return w->error; 
 }
 
-static int dyn_ioctl(struct labcomm_writer *w, 
-		     struct labcomm_writer_action_context *action_context, 
+static int dyn_ioctl(struct labcomm2014_writer *w, 
+		     struct labcomm2014_writer_action_context *action_context, 
 		     int signature_index,
-		     const struct labcomm_signature *signature,
+		     const struct labcomm2014_signature *signature,
 		     uint32_t action, va_list arg)
 {
   int result = -ENOTSUP;
@@ -122,7 +122,7 @@ static int dyn_ioctl(struct labcomm_writer *w,
   return result;
 }
 
-static const struct labcomm_writer_action action = {
+static const struct labcomm2014_writer_action action = {
   .alloc = dyn_alloc,
   .free = dyn_free,
   .start = dyn_start,
@@ -130,18 +130,18 @@ static const struct labcomm_writer_action action = {
   .flush = dyn_flush,
   .ioctl = dyn_ioctl
 };
-const struct labcomm_writer_action *labcomm_dynamic_buffer_writer_action = 
+const struct labcomm2014_writer_action *labcomm2014_dynamic_buffer_writer_action = 
   &action;
 
-struct labcomm_writer *labcomm_dynamic_buffer_writer_new(
-  struct labcomm_memory *memory)
+struct labcomm2014_writer *labcomm2014_dynamic_buffer_writer_new(
+  struct labcomm2014_memory *memory)
 {
   struct result {
-    struct labcomm_writer writer;
-    struct labcomm_writer_action_context action_context;
+    struct labcomm2014_writer writer;
+    struct labcomm2014_writer_action_context action_context;
   } *result;
 
-  result = labcomm_memory_alloc(memory, 0, sizeof(*result));
+  result = labcomm2014_memory_alloc(memory, 0, sizeof(*result));
   if (result != NULL) {
     result->action_context.next = NULL;
     result->action_context.context = result;
diff --git a/lib/c/2014/labcomm_dynamic_buffer_writer.h b/lib/c/2014/labcomm2014_dynamic_buffer_writer.h
similarity index 65%
rename from lib/c/2014/labcomm_dynamic_buffer_writer.h
rename to lib/c/2014/labcomm2014_dynamic_buffer_writer.h
index 53a65d42c878dea278f78f7572774658c86d6fe0..ce19d735cbfcc9a527770851cc3fc9d4127ed56b 100644
--- a/lib/c/2014/labcomm_dynamic_buffer_writer.h
+++ b/lib/c/2014/labcomm2014_dynamic_buffer_writer.h
@@ -1,5 +1,5 @@
 /*
-  labcomm_dynamic_buffer_writer.h -- LabComm dynamic memory writer.
+  labcomm2014_dynamic_buffer_writer.h -- LabComm dynamic memory writer.
 
   Copyright 2006-2013 Anders Blomdell <anders.blomdell@control.lth.se>
 
@@ -19,14 +19,14 @@
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-#ifndef _LABCOMM_DYNAMIC_BUFFER_READER_WRITER_H_
-#define _LABCOMM_DYNAMIC_BUFFER_READER_WRITER_H_
+#ifndef __LABCOMM2014_DYNAMIC_BUFFER_READER_WRITER_H__
+#define __LABCOMM2014_DYNAMIC_BUFFER_READER_WRITER_H__
 
-#include "labcomm.h"
+#include "labcomm2014.h"
 
-extern const struct labcomm_writer_action *labcomm_dynamic_buffer_writer_action;
+extern const struct labcomm2014_writer_action *labcomm2014_dynamic_buffer_writer_action;
 
-struct labcomm_writer *labcomm_dynamic_buffer_writer_new(
-  struct labcomm_memory *memory);
+struct labcomm2014_writer *labcomm2014_dynamic_buffer_writer_new(
+  struct labcomm2014_memory *memory);
 
 #endif
diff --git a/lib/c/2014/labcomm2014_encoder.c b/lib/c/2014/labcomm2014_encoder.c
new file mode 100644
index 0000000000000000000000000000000000000000..cbd38c88cf18ecc9ba427d1be61e718d7ea48ac7
--- /dev/null
+++ b/lib/c/2014/labcomm2014_encoder.c
@@ -0,0 +1,398 @@
+/*
+  labcomm2014_encoder.c -- handling encoding of labcomm2014 samples.
+
+  Copyright 2006-2013 Anders Blomdell <anders.blomdell@control.lth.se>
+
+  This file is part of LabComm.
+
+  LabComm is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  LabComm is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+#define CURRENT_VERSION "LabComm2014"
+
+#include <errno.h>
+#include "labcomm2014.h"
+#include "labcomm2014_private.h"
+#include "labcomm2014_ioctl.h"
+#include "labcomm2014_dynamic_buffer_writer.h"
+
+//define the following to disable encoding of typedefs
+#undef LABCOMM_WITHOUT_TYPE_DEFS
+
+struct labcomm2014_encoder {
+  struct labcomm2014_writer *writer;
+  struct labcomm2014_error_handler *error;
+  struct labcomm2014_memory *memory;
+  struct labcomm2014_scheduler *scheduler;
+  LABCOMM_SIGNATURE_ARRAY_DEF(registered, int);
+  LABCOMM_SIGNATURE_ARRAY_DEF(sample_ref, int);
+  LABCOMM_SIGNATURE_ARRAY_DEF(typedefs, int);
+};
+
+static struct labcomm2014_encoder *internal_encoder_new(
+  struct labcomm2014_writer *writer,
+  struct labcomm2014_error_handler *error,
+  struct labcomm2014_memory *memory,
+  struct labcomm2014_scheduler *scheduler,
+  labcomm2014_bool outputVer)
+{
+  struct labcomm2014_encoder *result;
+
+  result = labcomm2014_memory_alloc(memory, 0, sizeof(*result));
+  if (result) {
+    int length;
+
+    result->writer = writer;
+    result->writer->encoder = result;
+    result->writer->data = NULL;
+    result->writer->data_size = 0;
+    result->writer->count = 0;
+    result->writer->pos = 0;
+    result->writer->error = 0;
+    result->error = error;
+    result->memory = memory;
+    result->scheduler = scheduler;
+    LABCOMM_SIGNATURE_ARRAY_INIT(result->registered, int);
+    LABCOMM_SIGNATURE_ARRAY_INIT(result->sample_ref, int);
+    LABCOMM_SIGNATURE_ARRAY_INIT(result->typedefs, int);
+    labcomm2014_writer_alloc(result->writer,
+			 result->writer->action_context);
+    if(outputVer) {
+        labcomm2014_writer_start(result->writer,
+                            result->writer->action_context,
+                            LABCOMM_VERSION, NULL, CURRENT_VERSION);
+        labcomm2014_write_packed32(result->writer, LABCOMM_VERSION);
+        length = labcomm2014_size_string(CURRENT_VERSION);
+        labcomm2014_write_packed32(result->writer, length);
+        labcomm2014_write_string(result->writer, CURRENT_VERSION);
+        labcomm2014_writer_end(result->writer, result->writer->action_context);
+    }
+  }
+  return result;
+}
+
+struct labcomm2014_encoder *labcomm2014_encoder_new(
+  struct labcomm2014_writer *writer,
+  struct labcomm2014_error_handler *error,
+  struct labcomm2014_memory *memory,
+  struct labcomm2014_scheduler *scheduler)
+{
+    return internal_encoder_new(writer,error,memory,scheduler,LABCOMM2014_TRUE);
+}
+void labcomm2014_encoder_free(struct labcomm2014_encoder* e)
+{
+  struct labcomm2014_memory *memory = e->memory;
+
+  labcomm2014_writer_free(e->writer, e->writer->action_context);
+  LABCOMM_SIGNATURE_ARRAY_FREE(e->memory, e->registered, int);
+  LABCOMM_SIGNATURE_ARRAY_FREE(e->memory, e->sample_ref, int);
+  LABCOMM_SIGNATURE_ARRAY_FREE(e->memory, e->typedefs, int);
+  labcomm2014_memory_free(memory, 0, e);
+}
+
+int labcomm2014_internal_encoder_register(
+  struct labcomm2014_encoder *e,
+  const struct labcomm2014_signature *signature,
+  labcomm2014_encoder_function encode)
+{
+  int result = -EINVAL;
+  int index, *done, err, i, length;
+
+  index = labcomm2014_get_local_index(signature);
+  labcomm2014_scheduler_writer_lock(e->scheduler);
+  if (index <= 0) { goto out; }
+  done = LABCOMM_SIGNATURE_ARRAY_REF(e->memory, e->registered, int, index);
+  if (*done) {
+      goto out; }
+  *done = 1;
+  err = labcomm2014_writer_start(e->writer, e->writer->action_context,
+			     index, signature, NULL);
+  if (err == -EALREADY) { result = 0; goto out; }
+  if (err != 0) { result = err; goto out; }
+  labcomm2014_write_packed32(e->writer, LABCOMM_SAMPLE_DEF);
+  length = (labcomm2014_size_packed32(index) +
+            labcomm2014_size_string(signature->name) +
+            labcomm2014_size_packed32(signature->size) +
+            signature->size);
+  labcomm2014_write_packed32(e->writer, length);
+  labcomm2014_write_packed32(e->writer, index);
+  labcomm2014_write_string(e->writer, signature->name);
+  labcomm2014_write_packed32(e->writer, signature->size);
+  for (i = 0 ; i < signature->size ; i++) {
+    if (e->writer->pos >= e->writer->count) {
+      labcomm2014_writer_flush(e->writer, e->writer->action_context);
+    }
+    e->writer->data[e->writer->pos] = signature->signature[i];
+    e->writer->pos++;
+  }
+  labcomm2014_writer_end(e->writer, e->writer->action_context);
+  result = e->writer->error;
+out:
+  labcomm2014_scheduler_writer_unlock(e->scheduler);
+  return result;
+}
+
+int labcomm2014_internal_encode(
+  struct labcomm2014_encoder *e,
+  const struct labcomm2014_signature *signature,
+  labcomm2014_encoder_function encode,
+  void *value)
+{
+  int result, index, length;
+
+  index = labcomm2014_get_local_index(signature);
+  length = (signature->encoded_size(value));
+  labcomm2014_scheduler_writer_lock(e->scheduler);
+  if (! LABCOMM_SIGNATURE_ARRAY_GET(e->registered, int, index, 0)) {
+    result = -EINVAL;
+    goto no_end;
+  }
+  result = labcomm2014_writer_start(e->writer, e->writer->action_context,
+				index, signature, value);
+  if (result == -EALREADY) { result = 0; goto no_end; }
+  if (result != 0) { goto out; }
+  result = labcomm2014_write_packed32(e->writer, index);
+  result = labcomm2014_write_packed32(e->writer, length);
+  if (result != 0) { goto out; }
+  result = encode(e->writer, value);
+out:
+  labcomm2014_writer_end(e->writer, e->writer->action_context);
+no_end:
+  labcomm2014_scheduler_writer_unlock(e->scheduler);
+  return result;
+}
+
+int labcomm2014_encoder_sample_ref_register(
+  struct labcomm2014_encoder *e,
+  const struct labcomm2014_signature *signature)
+{
+  int result = -EINVAL;
+  int index, *done, err, i, length;
+
+  index = labcomm2014_get_local_index(signature);
+  labcomm2014_scheduler_writer_lock(e->scheduler);
+  if (index <= 0) { goto out; }
+
+  done = LABCOMM_SIGNATURE_ARRAY_REF(e->memory, e->sample_ref, int, index);
+  if (*done) { goto out; }
+  *done = 1;
+  err = labcomm2014_writer_start(e->writer, e->writer->action_context,
+			     index, signature, NULL);
+  if (err == -EALREADY) { result = 0; goto out; }
+  if (err != 0) { result = err; goto out; }
+  labcomm2014_write_packed32(e->writer, LABCOMM_SAMPLE_REF);
+  length = (labcomm2014_size_packed32(index) +
+            labcomm2014_size_string(signature->name) +
+            labcomm2014_size_packed32(signature->size) +
+            signature->size);
+  labcomm2014_write_packed32(e->writer, length);
+  labcomm2014_write_packed32(e->writer, index);
+  labcomm2014_write_string(e->writer, signature->name);
+  labcomm2014_write_packed32(e->writer, signature->size);
+  for (i = 0 ; i < signature->size ; i++) {
+    if (e->writer->pos >= e->writer->count) {
+      labcomm2014_writer_flush(e->writer, e->writer->action_context);
+    }
+    e->writer->data[e->writer->pos] = signature->signature[i];
+    e->writer->pos++;
+  }
+  labcomm2014_writer_end(e->writer, e->writer->action_context);
+  result = e->writer->error;
+out:
+  labcomm2014_scheduler_writer_unlock(e->scheduler);
+  return result;
+}
+
+int labcomm2014_encoder_ioctl(struct labcomm2014_encoder *encoder,
+			  uint32_t action,
+			  ...)
+{
+  int result;
+  va_list va;
+
+  if (LABCOMM_IOC_SIG(action) != LABCOMM_IOC_NOSIG) {
+    result = -EINVAL;
+    goto out;
+  }
+
+  va_start(va, action);
+  result = labcomm2014_writer_ioctl(encoder->writer,
+			       encoder->writer->action_context,
+			       0, NULL, action, va);
+  va_end(va);
+
+out:
+  return result;
+}
+
+int labcomm2014_internal_encoder_ioctl(struct labcomm2014_encoder *encoder,
+				   const struct labcomm2014_signature *signature,
+				   uint32_t action, va_list va)
+{
+  int result = -ENOTSUP;
+  int index;
+
+  index = labcomm2014_get_local_index(signature);
+  result = labcomm2014_writer_ioctl(encoder->writer,
+				encoder->writer->action_context,
+				index, signature, action, va);
+  return result;
+}
+
+int labcomm2014_internal_encoder_signature_to_index(
+  struct labcomm2014_encoder *e, const struct labcomm2014_signature *signature)
+{
+  /* writer_lock should be held at this point */
+  int index = 0;
+  if (signature != NULL) {
+    index = labcomm2014_get_local_index(signature);
+    if (! LABCOMM_SIGNATURE_ARRAY_GET(e->sample_ref, int, index, 0)) {
+      index = 0;
+    }
+  }
+  return index;
+}
+
+
+/**********************************************************
+ * Start of code related to sending (hierarchical)
+ * typedefs. Define LABCOMM_WITHOUT_TYPEDEFS to disable
+ **********************************************************/
+#ifndef LABCOMM_WITHOUT_TYPE_DEFS
+
+static void write_sig_tree_byte(char b, const struct labcomm2014_signature *signature,
+                           void *context)
+{
+  struct labcomm2014_encoder *e = context;
+  if(signature) {
+    labcomm2014_write_packed32(e->writer, labcomm2014_get_local_index(signature));
+  }else {
+    if (e->writer->pos >= e->writer->count) {
+     labcomm2014_writer_flush(e->writer, e->writer->action_context);
+    }
+    e->writer->data[e->writer->pos] = b;
+    e->writer->pos++;
+  }
+}
+
+static void do_write_signature(struct labcomm2014_encoder * e, 
+                               const struct labcomm2014_signature *signature, 
+                               unsigned char flatten)
+{
+  map_signature(write_sig_tree_byte, e, signature, flatten);
+}
+
+static void sig_size(char b, const struct labcomm2014_signature *signature,
+                     void *context)
+{
+  int *result = context;
+  int diff;
+  if(signature) {
+    int idx = labcomm2014_get_local_index(signature);
+    diff = labcomm2014_size_packed32(idx);
+  }else {
+    diff = 1;
+  }
+    (*result)+=diff;
+}
+
+static int calc_sig_encoded_size(struct labcomm2014_encoder *e,
+                                 const struct labcomm2014_signature *sig)
+{
+  int result=0;
+  map_signature(sig_size, &result, sig, LABCOMM2014_FALSE);
+  return result;
+}
+
+static int internal_reg_type(
+  struct labcomm2014_encoder *e,
+  const struct labcomm2014_signature *signature,
+  labcomm2014_bool flatten)
+{
+  int result = -EINVAL;
+  int index, *done, err;
+
+  index = labcomm2014_get_local_index(signature);
+  labcomm2014_scheduler_writer_lock(e->scheduler);
+  if (index <= 0) { goto out; }
+  done = LABCOMM_SIGNATURE_ARRAY_REF(e->memory, e->typedefs, int, index);
+  if (*done) { goto out; }
+  *done = 1;
+  err = labcomm2014_writer_start(e->writer, e->writer->action_context,
+                 index, signature, NULL);
+  if (err == -EALREADY) { result = 0; goto out; }
+  if (err != 0) { result = err; goto out; }
+
+  int sig_size = calc_sig_encoded_size(e, signature);
+  int len =  labcomm2014_size_packed32(index) +
+             labcomm2014_size_string(signature->name) +
+             labcomm2014_size_packed32(sig_size) +
+              sig_size;
+
+  labcomm2014_write_packed32(e->writer, LABCOMM_TYPE_DEF);
+  labcomm2014_write_packed32(e->writer, len);
+  labcomm2014_write_packed32(e->writer, index);
+  labcomm2014_write_string(e->writer, signature->name);
+  labcomm2014_write_packed32(e->writer, sig_size);
+  do_write_signature(e, signature, LABCOMM2014_FALSE);
+
+  labcomm2014_writer_end(e->writer, e->writer->action_context);
+  result = e->writer->error;
+out:
+  labcomm2014_scheduler_writer_unlock(e->scheduler);
+  return result;
+}
+#endif
+
+int labcomm2014_internal_encoder_type_register(
+  struct labcomm2014_encoder *e,
+  const struct labcomm2014_signature *signature)
+{
+#ifndef LABCOMM_WITHOUT_TYPE_DEFS
+  return internal_reg_type(e, signature, LABCOMM2014_FALSE);
+#else
+  return 0;
+#endif
+}
+int labcomm2014_internal_encoder_type_bind(
+  struct labcomm2014_encoder *e,
+  const struct labcomm2014_signature *signature,
+  char has_deps)
+{
+#ifndef LABCOMM_WITHOUT_TYPE_DEFS
+  int result = -EINVAL;
+  int err;
+  int sindex = labcomm2014_get_local_index(signature);
+  int tindex = has_deps ? labcomm2014_get_local_type_index(signature) : LABCOMM_BIND_SELF;
+  labcomm2014_scheduler_writer_lock(e->scheduler);
+  if(sindex <= 0 || (has_deps && tindex <= 0)) {goto out;}
+  err = labcomm2014_writer_start(e->writer, e->writer->action_context,
+			     LABCOMM_TYPE_BINDING, signature, NULL);
+  if (err == -EALREADY) { result = 0; goto out; }
+  if (err != 0) { result = err; goto out; }
+  int length = (labcomm2014_size_packed32(sindex) +
+                labcomm2014_size_packed32(tindex));
+  labcomm2014_write_packed32(e->writer, LABCOMM_TYPE_BINDING);
+  labcomm2014_write_packed32(e->writer, length);
+  labcomm2014_write_packed32(e->writer, sindex);
+  labcomm2014_write_packed32(e->writer, tindex);
+  labcomm2014_writer_end(e->writer, e->writer->action_context);
+  result = e->writer->error;
+
+out:
+  labcomm2014_scheduler_writer_unlock(e->scheduler);
+  return result;
+#else
+  return 0;
+#endif
+}
diff --git a/lib/c/2014/labcomm_error.c b/lib/c/2014/labcomm2014_error.c
similarity index 86%
rename from lib/c/2014/labcomm_error.c
rename to lib/c/2014/labcomm2014_error.c
index 5bfea6ed319e2a8457fcbd57cb6e747e0e5af7e8..9ea193b73daa5f0af9f7f7b10057286192fa4692 100644
--- a/lib/c/2014/labcomm_error.c
+++ b/lib/c/2014/labcomm2014_error.c
@@ -1,5 +1,5 @@
 /*
-  labcomm_error.c -- labcomm error handling
+  labcomm2014_error.c -- labcomm2014 error handling
 
   Copyright 2013 Anders Blomdell <anders.blomdell@control.lth.se>
 
@@ -22,9 +22,9 @@
 #include <stdlib.h>
 #include <stdio.h>
 #include <stdarg.h>
-#include "labcomm_error.h"
+#include "labcomm2014_error.h"
 
-void labcomm_error_fatal_global(enum labcomm_error error,
+void labcomm2014_error_fatal_global(enum labcomm2014_error error,
 				char *format,
 				...)
 {
diff --git a/lib/c/2014/labcomm2014_error.h b/lib/c/2014/labcomm2014_error.h
new file mode 100644
index 0000000000000000000000000000000000000000..9162e63acb7795e0b054833ac98d60765dc95e94
--- /dev/null
+++ b/lib/c/2014/labcomm2014_error.h
@@ -0,0 +1,70 @@
+/*
+  labcomm2014_error.h -- labcomm2014 error declarations
+
+  Copyright 2013 Anders Blomdell <anders.blomdell@control.lth.se>
+
+  This file is part of LabComm.
+
+  LabComm is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  LabComm is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __LABCOMM2014_ERROR_H___
+#define __LABCOMM2014_ERROR_H___
+
+enum labcomm2014_error {
+#define LABCOMM2014_ERROR(name, description) name ,
+#include "labcomm2014_error.h"
+#undef LABCOMM2014_ERROR
+};
+
+struct labcomm2014_error_handler;
+
+void labcomm2014_error_warning(struct labcomm2014_error_handler *e,
+			   enum labcomm2014_error,
+			   char *format,
+			   ...);
+			 
+void labcomm2014_error_fatal_global(enum labcomm2014_error error,
+				char *format,
+				...);
+			 
+#endif
+
+#ifdef LABCOMM2014_ERROR
+
+LABCOMM2014_ERROR(LABCOMM2014_ERROR_SIGNATURE_ALREADY_SET,
+                  "Signature has already been set")
+LABCOMM2014_ERROR(LABCOMM2014_ERROR_SIGNATURE_NOT_SET,
+                  "Signature has not been set")
+
+LABCOMM2014_ERROR(LABCOMM2014_ERROR_ENC_NO_REG_SIGNATURE,
+                  "Encoder has no registration for this signature")
+LABCOMM2014_ERROR(LABCOMM2014_ERROR_ENC_BUF_FULL,
+                  "The labcomm2014 buffer is full")
+LABCOMM2014_ERROR(LABCOMM2014_ERROR_DEC_UNKNOWN_DATATYPE,
+                  "Decoder: Unknown datatype")
+LABCOMM2014_ERROR(LABCOMM2014_ERROR_DEC_INDEX_MISMATCH,
+                  "Decoder: index mismatch")
+LABCOMM2014_ERROR(LABCOMM2014_ERROR_DEC_TYPE_NOT_FOUND,
+                  "Decoder: type not found")
+LABCOMM2014_ERROR(LABCOMM2014_ERROR_UNIMPLEMENTED_FUNC,
+                  "This function is not yet implemented")
+LABCOMM2014_ERROR(LABCOMM2014_ERROR_MEMORY,
+                  "Could not allocate memory")
+LABCOMM2014_ERROR(LABCOMM2014_ERROR_USER_DEF,
+                  "User defined error")
+LABCOMM2014_ERROR(LABCOMM2014_ERROR_BAD_WRITER,
+                  "Decoder: writer_ioctl() failed")
+
+#endif
diff --git a/lib/c/2014/labcomm_fd_reader.c b/lib/c/2014/labcomm2014_fd_reader.c
similarity index 64%
rename from lib/c/2014/labcomm_fd_reader.c
rename to lib/c/2014/labcomm2014_fd_reader.c
index eaa59f9a0974fd63462e043d134371ecd2ff4ba5..ad2d22285e2b9b31b25e727fa40e9b33da6502c7 100644
--- a/lib/c/2014/labcomm_fd_reader.c
+++ b/lib/c/2014/labcomm2014_fd_reader.c
@@ -1,5 +1,5 @@
 /*
-  labcomm_fd_reader.c -- LabComm reader for Unix file descriptors.
+  labcomm2014_fd_reader.c -- LabComm reader for Unix file descriptors.
 
   Copyright 2006-2013 Anders Blomdell <anders.blomdell@control.lth.se>
 
@@ -23,26 +23,26 @@
 #include <unistd.h>
 #include <stdlib.h>
 #include <string.h>
-#include "labcomm_private.h"
-#include "labcomm_fd_reader.h"
+#include "labcomm2014_private.h"
+#include "labcomm2014_fd_reader.h"
 
 #define BUFFER_SIZE 2048
 
-struct labcomm_fd_reader {
-  struct labcomm_reader reader;
-  struct labcomm_reader_action_context action_context;
+struct labcomm2014_fd_reader {
+  struct labcomm2014_reader reader;
+  struct labcomm2014_reader_action_context action_context;
   int fd;
   int close_fd_on_free;
 };
 
-static int fd_alloc(struct labcomm_reader *r,
-		    struct labcomm_reader_action_context *action_context)
+static int fd_alloc(struct labcomm2014_reader *r,
+		    struct labcomm2014_reader_action_context *action_context)
 {
   int result = 0;
   
   r->count = 0;
   r->pos = 0;
-  r->data = labcomm_memory_alloc(r->memory, 0, BUFFER_SIZE);
+  r->data = labcomm2014_memory_alloc(r->memory, 0, BUFFER_SIZE);
   if (! r->data) {
     r->data_size = 0;
     result = -ENOMEM;
@@ -54,13 +54,13 @@ static int fd_alloc(struct labcomm_reader *r,
   return result;
 }
 
-static int fd_free(struct labcomm_reader *r, 
-		   struct labcomm_reader_action_context *action_context)
+static int fd_free(struct labcomm2014_reader *r, 
+		   struct labcomm2014_reader_action_context *action_context)
 {
-  struct labcomm_fd_reader *fd_reader = action_context->context;
-  struct labcomm_memory *memory = r->memory;
+  struct labcomm2014_fd_reader *fd_reader = action_context->context;
+  struct labcomm2014_memory *memory = r->memory;
 
-  labcomm_memory_free(memory, 0, r->data);
+  labcomm2014_memory_free(memory, 0, r->data);
   r->data = 0;
   r->data_size = 0;
   r->count = 0;
@@ -69,16 +69,16 @@ static int fd_free(struct labcomm_reader *r,
   if (fd_reader->close_fd_on_free) {
     close(fd_reader->fd);
   }
-  labcomm_memory_free(memory, 0, fd_reader);
+  labcomm2014_memory_free(memory, 0, fd_reader);
 
   return 0;
 }
 
-static int fd_fill(struct labcomm_reader *r, 
-		   struct labcomm_reader_action_context *action_context)
+static int fd_fill(struct labcomm2014_reader *r, 
+		   struct labcomm2014_reader_action_context *action_context)
 {
   int result = 0;
-  struct labcomm_fd_reader *fd_reader = action_context->context;
+  struct labcomm2014_fd_reader *fd_reader = action_context->context;
 
   if (r->pos < r->count) {
     result = r->count - r->pos;
@@ -99,7 +99,7 @@ static int fd_fill(struct labcomm_reader *r,
   return result;
 }
 
-static const struct labcomm_reader_action action = {
+static const struct labcomm2014_reader_action action = {
   .alloc = fd_alloc,
   .free = fd_free,
   .start = NULL,
@@ -108,12 +108,12 @@ static const struct labcomm_reader_action action = {
   .ioctl = NULL
 };
 
-struct labcomm_reader *labcomm_fd_reader_new(struct labcomm_memory *memory,
+struct labcomm2014_reader *labcomm2014_fd_reader_new(struct labcomm2014_memory *memory,
 					     int fd, int close_fd_on_free)
 {
-  struct labcomm_fd_reader *result;
+  struct labcomm2014_fd_reader *result;
 
-  result = labcomm_memory_alloc(memory, 0, sizeof(*result));
+  result = labcomm2014_memory_alloc(memory, 0, sizeof(*result));
   if (result == NULL) {
     return NULL;
   } else {
diff --git a/lib/c/2014/labcomm_fd_reader.h b/lib/c/2014/labcomm2014_fd_reader.h
similarity index 75%
rename from lib/c/2014/labcomm_fd_reader.h
rename to lib/c/2014/labcomm2014_fd_reader.h
index b04aa8ed5515ccb5caf3571fd05adf0fdfc294f0..0391c6ccfc0c207f74511a87db7ae98e4dd3002f 100644
--- a/lib/c/2014/labcomm_fd_reader.h
+++ b/lib/c/2014/labcomm2014_fd_reader.h
@@ -1,5 +1,5 @@
 /*
-  labcomm_fd_reader.c -- a reader for unix style file-descriptors
+  labcomm2014_fd_reader.c -- a reader for unix style file-descriptors
 
   Copyright 2006-2013 Anders Blomdell <anders.blomdell@control.lth.se>
 
@@ -19,12 +19,12 @@
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-#ifndef _LABCOMM_FD_READER_H_
-#define _LABCOMM_FD_READER_H_
+#ifndef __LABCOMM2014_FD_READER_H__
+#define __LABCOMM2014_FD_READER_H__
 
-#include "labcomm.h"
+#include "labcomm2014.h"
 
-struct labcomm_reader *labcomm_fd_reader_new(struct labcomm_memory *memory,
+struct labcomm2014_reader *labcomm2014_fd_reader_new(struct labcomm2014_memory *memory,
 					     int fd, int close_fd_on_free);
 
 #endif
diff --git a/lib/c/2014/labcomm_fd_writer.c b/lib/c/2014/labcomm2014_fd_writer.c
similarity index 60%
rename from lib/c/2014/labcomm_fd_writer.c
rename to lib/c/2014/labcomm2014_fd_writer.c
index 5833accd29183cfb3ba82624d127c2cfeea8eb0f..42c9dbcc14eb765dbae6547000994a2c7c3c8153 100644
--- a/lib/c/2014/labcomm_fd_writer.c
+++ b/lib/c/2014/labcomm2014_fd_writer.c
@@ -1,5 +1,5 @@
 /*
-  labcomm_fd_writer.c -- LabComm writer for Unix file descriptors.
+  labcomm2014_fd_writer.c -- LabComm writer for Unix file descriptors.
 
   Copyright 2006-2013 Anders Blomdell <anders.blomdell@control.lth.se>
 
@@ -24,25 +24,25 @@
 #include <string.h>
 #include <stdlib.h>
 #include <stdarg.h>
-#include "labcomm_private.h"
-#include "labcomm_fd_writer.h"
+#include "labcomm2014_private.h"
+#include "labcomm2014_fd_writer.h"
 
 #define BUFFER_SIZE 2048
 
-struct labcomm_fd_writer {
-  struct labcomm_writer writer;
-  struct labcomm_writer_action_context action_context;
+struct labcomm2014_fd_writer {
+  struct labcomm2014_writer writer;
+  struct labcomm2014_writer_action_context action_context;
   int fd;
   int close_fd_on_free;
 };
 
-static int fd_flush(struct labcomm_writer *w, 
-		    struct labcomm_writer_action_context *action_context);
+static int fd_flush(struct labcomm2014_writer *w, 
+		    struct labcomm2014_writer_action_context *action_context);
 
-static int fd_alloc(struct labcomm_writer *w, 
-		    struct labcomm_writer_action_context *action_context)
+static int fd_alloc(struct labcomm2014_writer *w, 
+		    struct labcomm2014_writer_action_context *action_context)
 {
-  w->data = labcomm_memory_alloc(w->memory, 0, BUFFER_SIZE);
+  w->data = labcomm2014_memory_alloc(w->memory, 0, BUFFER_SIZE);
   if (! w->data) {
     w->error = -ENOMEM;
     w->data_size = 0;
@@ -57,13 +57,13 @@ static int fd_alloc(struct labcomm_writer *w,
   return w->error;
 }
 
-static int fd_free(struct labcomm_writer *w, 
-		   struct labcomm_writer_action_context *action_context)
+static int fd_free(struct labcomm2014_writer *w, 
+		   struct labcomm2014_writer_action_context *action_context)
 {
-  struct labcomm_fd_writer *fd_writer = action_context->context;
-  struct labcomm_memory *memory = w->memory;
+  struct labcomm2014_fd_writer *fd_writer = action_context->context;
+  struct labcomm2014_memory *memory = w->memory;
 
-  labcomm_memory_free(memory, 0, w->data);
+  labcomm2014_memory_free(memory, 0, w->data);
   w->data = 0;
   w->data_size = 0;
   w->count = 0;
@@ -72,14 +72,14 @@ static int fd_free(struct labcomm_writer *w,
   if (fd_writer->close_fd_on_free) {
     close(fd_writer->fd);
   }
-  labcomm_memory_free(memory, 0, fd_writer);
+  labcomm2014_memory_free(memory, 0, fd_writer);
   return 0;
 }
 
-static int fd_start(struct labcomm_writer *w, 
-		    struct labcomm_writer_action_context *action_context,
+static int fd_start(struct labcomm2014_writer *w, 
+		    struct labcomm2014_writer_action_context *action_context,
 		    int index,
-		    const struct labcomm_signature *signature,
+		    const struct labcomm2014_signature *signature,
 		    void *value)
 {
   w->pos = 0;
@@ -87,10 +87,10 @@ static int fd_start(struct labcomm_writer *w,
   return w->error;
 }
 
-static int fd_flush(struct labcomm_writer *w, 
-		    struct labcomm_writer_action_context *action_context)
+static int fd_flush(struct labcomm2014_writer *w, 
+		    struct labcomm2014_writer_action_context *action_context)
 {
-  struct labcomm_fd_writer *fd_context = action_context->context;
+  struct labcomm2014_fd_writer *fd_context = action_context->context;
   int start, err;
   
   start = 0;
@@ -112,7 +112,7 @@ static int fd_flush(struct labcomm_writer *w,
   return w->error;
 }
 
-static const struct labcomm_writer_action action = {
+static const struct labcomm2014_writer_action action = {
   .alloc = fd_alloc,
   .free = fd_free,
   .start = fd_start,
@@ -121,12 +121,12 @@ static const struct labcomm_writer_action action = {
   .ioctl = NULL
 };
 
-struct labcomm_writer *labcomm_fd_writer_new(struct labcomm_memory *memory,
+struct labcomm2014_writer *labcomm2014_fd_writer_new(struct labcomm2014_memory *memory,
 					     int fd, int close_fd_on_free)
 {
-  struct labcomm_fd_writer *result;
+  struct labcomm2014_fd_writer *result;
 
-  result = labcomm_memory_alloc(memory, 0, sizeof(*result));
+  result = labcomm2014_memory_alloc(memory, 0, sizeof(*result));
   if (result == NULL) {
     return NULL;
   } else {
diff --git a/lib/c/2014/labcomm_fd_writer.h b/lib/c/2014/labcomm2014_fd_writer.h
similarity index 75%
rename from lib/c/2014/labcomm_fd_writer.h
rename to lib/c/2014/labcomm2014_fd_writer.h
index e89b5e7198c1d7822f276d23801baf9a889ce4f2..92145a55981b3bf0250b531bbb7f4e940062ab4e 100644
--- a/lib/c/2014/labcomm_fd_writer.h
+++ b/lib/c/2014/labcomm2014_fd_writer.h
@@ -1,5 +1,5 @@
 /*
-  labcomm_fd_writer.c -- a writer for unix style file-descriptors
+  labcomm2014_fd_writer.c -- a writer for unix style file-descriptors
 
   Copyright 2006-2013 Anders Blomdell <anders.blomdell@control.lth.se>
 
@@ -19,12 +19,12 @@
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-#ifndef _LABCOMM_FD_WRITER_H_
-#define _LABCOMM_FD_WRITER_H_
+#ifndef __LABCOMM2014_FD_WRITER_H__
+#define __LABCOMM2014_FD_WRITER_H__
 
-#include "labcomm.h"
+#include "labcomm2014.h"
 
-struct labcomm_writer *labcomm_fd_writer_new(struct labcomm_memory *memory,
+struct labcomm2014_writer *labcomm2014_fd_writer_new(struct labcomm2014_memory *memory,
 					     int fd, int close_on_free);
 
 #endif
diff --git a/lib/c/2014/labcomm_ioctl.h b/lib/c/2014/labcomm2014_ioctl.h
similarity index 84%
rename from lib/c/2014/labcomm_ioctl.h
rename to lib/c/2014/labcomm2014_ioctl.h
index 1ebf6531d4000ebfb2392a547eaf1f2a1f589b80..bb321edb396cbf268cbf222a121ef7fa42235f33 100644
--- a/lib/c/2014/labcomm_ioctl.h
+++ b/lib/c/2014/labcomm2014_ioctl.h
@@ -1,5 +1,5 @@
 /*
-  labcomm_ioctl.h -- labcomm ioctl declarations
+  labcomm2014_ioctl.h -- labcomm2014 ioctl declarations
 
   Copyright 2013 Anders Blomdell <anders.blomdell@control.lth.se>
 
@@ -19,10 +19,10 @@
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-#ifndef __LABCOMM_IOCTL_H__
-#define __LABCOMM_IOCTL_H__
+#ifndef __LABCOMM2014_IOCTL_H___
+#define __LABCOMM2014_IOCTL_H___
 
-#include "labcomm.h"
+#include "labcomm2014.h"
 
 /*
  * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
@@ -35,7 +35,7 @@
  *  | +----------------------------------------------- direction (2)
  *  +------------------------------------------------- signature (1)
  *  
- * type 0-31     are reserved for labcomm library use
+ * type 0-31     are reserved for labcomm2014 library use
  */
 
 
@@ -84,23 +84,14 @@
   LABCOMM_IOC(LABCOMM_IOC_NOSIG,LABCOMM_IOC_NONE,type,nr,0)
 #define LABCOMM_IOR(type,nr,size)					\
   LABCOMM_IOC(LABCOMM_IOC_NOSIG,LABCOMM_IOC_READ,type,nr,sizeof(size))
-/* FIXME: add flag to differentiate between size and nargs */
-#define LABCOMM_IORN(type,nr,nargs)					\
-  LABCOMM_IOC(LABCOMM_IOC_NOSIG,LABCOMM_IOC_READ,type,nr,nargs)
 #define LABCOMM_IOW(type,nr,size)					\
   LABCOMM_IOC(LABCOMM_IOC_NOSIG,LABCOMM_IOC_WRITE,type,nr,sizeof(size))
-#define LABCOMM_IOWN(type,nr,nargs)					\
-  LABCOMM_IOC(LABCOMM_IOC_NOSIG,LABCOMM_IOC_WRITE,type,nr,nargs)
-#define LABCOMM_IOS(type,nr)					\
+#define LABCOMM_IOS(type,nr)                                    \
   LABCOMM_IOC(LABCOMM_IOC_USESIG,LABCOMM_IOC_READ,type,nr,0)
 #define LABCOMM_IOSR(type,nr,size)					\
   LABCOMM_IOC(LABCOMM_IOC_USESIG,LABCOMM_IOC_READ,type,nr,sizeof(size))
-#define LABCOMM_IOSRN(type,nr,nargs)					\
-  LABCOMM_IOC(LABCOMM_IOC_USESIG,LABCOMM_IOC_READ,type,nr,nargs)
 #define LABCOMM_IOSW(type,nr,size)					\
   LABCOMM_IOC(LABCOMM_IOC_USESIG,LABCOMM_IOC_WRITE,type,nr,sizeof(size))
-#define LABCOMM_IOSWN(type,nr,nargs)					\
-  LABCOMM_IOC(LABCOMM_IOC_USESIG,LABCOMM_IOC_WRITE,type,nr,nargs)
 
 #define LABCOMM_IOCTL_WRITER_GET_BYTES_WRITTEN \
   LABCOMM_IOR(0,1,int)
diff --git a/lib/c/2014/labcomm_memory.c b/lib/c/2014/labcomm2014_memory.c
similarity index 74%
rename from lib/c/2014/labcomm_memory.c
rename to lib/c/2014/labcomm2014_memory.c
index 62bc9ac5a3f81ef496f836509cf4e7f8e8bb81cf..757640ad73124d1215d8409e78c0f27705aa92bd 100644
--- a/lib/c/2014/labcomm_memory.c
+++ b/lib/c/2014/labcomm2014_memory.c
@@ -1,5 +1,5 @@
 /*
-  labcomm_memory.c -- dynamic memory handlig dispatcher
+  labcomm2014_memory.c -- dynamic memory handlig dispatcher
 
   Copyright 2013 Anders Blomdell <anders.blomdell@control.lth.se>
 
@@ -19,21 +19,21 @@
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-#include "labcomm_private.h"
+#include "labcomm2014_private.h"
 
-void *labcomm_memory_alloc(struct labcomm_memory *m, int lifetime, 
+void *labcomm2014_memory_alloc(struct labcomm2014_memory *m, int lifetime, 
 			   size_t size) 
 {
   return m->alloc(m, lifetime, size);
 }
 
-void *labcomm_memory_realloc(struct labcomm_memory *m, int lifetime, 
+void *labcomm2014_memory_realloc(struct labcomm2014_memory *m, int lifetime, 
 			     void *ptr, size_t size) 
 {
   return m->realloc(m, lifetime, ptr, size);
 }
 
-void labcomm_memory_free(struct labcomm_memory *m, int lifetime, 
+void labcomm2014_memory_free(struct labcomm2014_memory *m, int lifetime, 
 			 void *ptr)
 {
   m->free(m, lifetime, ptr);
diff --git a/lib/c/2014/labcomm_private.h b/lib/c/2014/labcomm2014_private.h
similarity index 51%
rename from lib/c/2014/labcomm_private.h
rename to lib/c/2014/labcomm2014_private.h
index 95900fe29b81cc282494628737300ba0694d8247..03060722be6d6ae17d5addb0d18abb6d7d95d531 100644
--- a/lib/c/2014/labcomm_private.h
+++ b/lib/c/2014/labcomm2014_private.h
@@ -1,6 +1,6 @@
 /*
-  labcomm_private.h -- semi private declarations for handling encoding and 
-                       decoding of labcomm samples.
+  labcomm2014_private.h -- semi private declarations for handling encoding and 
+                       decoding of labcomm2014 samples.
 
   Copyright 2006-2013 Anders Blomdell <anders.blomdell@control.lth.se>
 
@@ -20,8 +20,8 @@
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-#ifndef _LABCOMM_PRIVATE_H_
-#define _LABCOMM_PRIVATE_H_
+#ifndef __LABCOMM2014_PRIVATE_H__
+#define __LABCOMM2014_PRIVATE_H__
 
 #ifdef LABCOMM_COMPAT
   #include LABCOMM_COMPAT
@@ -34,7 +34,7 @@
 
 //#include <stdlib.h>
 #include <string.h>
-#include "labcomm.h"
+#include "labcomm2014.h"
 
 /*
  * Allowed packet tags
@@ -42,8 +42,8 @@
 #define LABCOMM_VERSION      0x01
 #define LABCOMM_SAMPLE_DEF   0x02
 #define LABCOMM_SAMPLE_REF   0x03
-#define LABCOMM_TYPEDEF      0x04
-#define LABCOMM_TYPEBINDING  0x05
+#define LABCOMM_TYPE_DEF     0x04
+#define LABCOMM_TYPE_BINDING 0x05
 #define LABCOMM_PRAGMA       0x3f
 #define LABCOMM_USER         0x40 /* ..0xffffffff */
 
@@ -64,11 +64,17 @@
 #define LABCOMM_FLOAT        0x25
 #define LABCOMM_DOUBLE       0x26
 #define LABCOMM_STRING       0x27
+#define LABCOMM_REF          0x28
 
+/* 
+ * other special values
+ */
+
+#define LABCOMM_BIND_SELF    0
 
 /*
  * Macro to automagically call constructors in modules compiled 
- * with the labcomm compiler. If __attribute__((constructor)) is
+ * with the labcomm2014 compiler. If __attribute__((constructor)) is
  * not supported, these calls has to be done first in main program.
  */
 #ifndef LABCOMM_CONSTRUCTOR
@@ -79,36 +85,36 @@
  * Semi private dynamic memory declarations
  */
 
-struct labcomm_memory {
-  void *(*alloc)(struct labcomm_memory *m, int lifetime, size_t size);
-  void *(*realloc)(struct labcomm_memory *m, int lifetime, 
+struct labcomm2014_memory {
+  void *(*alloc)(struct labcomm2014_memory *m, int lifetime, size_t size);
+  void *(*realloc)(struct labcomm2014_memory *m, int lifetime, 
 		   void *ptr, size_t size);
-  void (*free)(struct labcomm_memory *m, int lifetime, void *ptr);
+  void (*free)(struct labcomm2014_memory *m, int lifetime, void *ptr);
   void *context;
 };
 
 /*
  * Semi private decoder declarations
  */
-typedef void (*labcomm_handler_function)(void *value, void *context);
+typedef void (*labcomm2014_handler_function)(void *value, void *context);
 
-typedef void (*labcomm_decoder_function)(
-  struct labcomm_reader *r,
-  labcomm_handler_function handler,
+typedef void (*labcomm2014_decoder_function)(
+  struct labcomm2014_reader *r,
+  labcomm2014_handler_function handler,
   void *context);
 
-struct labcomm_reader_action_context;
+struct labcomm2014_reader_action_context;
 
-struct labcomm_reader_action {
-  /* 'alloc' is called at the first invocation of 'labcomm_decoder_decode_one' 
+struct labcomm2014_reader_action {
+  /* 'alloc' is called at the first invocation of 'labcomm2014_decoder_decode_one' 
      on the decoder containing the reader.
 
      Returned value:
        >  0    Number of bytes allocated for buffering
        <= 0    Error
   */
-  int (*alloc)(struct labcomm_reader *r, 
-	       struct labcomm_reader_action_context *action_context);
+  int (*alloc)(struct labcomm2014_reader *r, 
+	       struct labcomm2014_reader_action_context *action_context);
   /* 'free' returns the resources claimed by 'alloc' and might have other
      reader specific side-effects as well.
 
@@ -116,8 +122,8 @@ struct labcomm_reader_action {
        == 0    Success
        != 0    Error
   */
-  int (*free)(struct labcomm_reader *r, 
-	      struct labcomm_reader_action_context *action_context);
+  int (*free)(struct labcomm2014_reader *r, 
+	      struct labcomm2014_reader_action_context *action_context);
   /* 'start' is called at the following instances:
      1. When a sample is registered 
           (local_index != 0, remote_index == 0, value == NULL)
@@ -126,33 +132,33 @@ struct labcomm_reader_action {
      3. When a sample is received
           (local_index != 0, remote_index != 0, value != NULL)
    */
-  int (*start)(struct labcomm_reader *r, 
-	       struct labcomm_reader_action_context *action_context,
+  int (*start)(struct labcomm2014_reader *r, 
+	       struct labcomm2014_reader_action_context *action_context,
 	       int local_index, int remote_index,
-	       const struct labcomm_signature *signature,
+	       const struct labcomm2014_signature *signature,
 	       void *value);
-  int (*end)(struct labcomm_reader *r, 
-	     struct labcomm_reader_action_context *action_context);
-  int (*fill)(struct labcomm_reader *r, 
-	      struct labcomm_reader_action_context *action_context);
-  int (*ioctl)(struct labcomm_reader *r, 
-	       struct labcomm_reader_action_context *action_context,
+  int (*end)(struct labcomm2014_reader *r, 
+	     struct labcomm2014_reader_action_context *action_context);
+  int (*fill)(struct labcomm2014_reader *r, 
+	      struct labcomm2014_reader_action_context *action_context);
+  int (*ioctl)(struct labcomm2014_reader *r, 
+	       struct labcomm2014_reader_action_context *action_context,
 	       int local_index, int remote_index,
-	       const struct labcomm_signature *signature, 
+	       const struct labcomm2014_signature *signature, 
 	       uint32_t ioctl_action, va_list args);
 };
 
-struct labcomm_reader_action_context {
-  struct labcomm_reader_action_context *next;
-  const struct labcomm_reader_action *action;
+struct labcomm2014_reader_action_context {
+  struct labcomm2014_reader_action_context *next;
+  const struct labcomm2014_reader_action *action;
   void *context;  
 };
 
-struct labcomm_reader {
-  struct labcomm_reader_action_context *action_context;
-  struct labcomm_memory *memory;
-  /* The following fields are initialized by labcomm_decoder_new */
-  struct labcomm_decoder *decoder;
+struct labcomm2014_reader {
+  struct labcomm2014_reader_action_context *action_context;
+  struct labcomm2014_memory *memory;
+  /* The following fields are initialized by labcomm2014_decoder_new */
+  struct labcomm2014_decoder *decoder;
   unsigned char *data;
   int data_size;
   int count;
@@ -160,51 +166,51 @@ struct labcomm_reader {
   int error;
 };
 
-int labcomm_reader_alloc(struct labcomm_reader *r, 
-			 struct labcomm_reader_action_context *action_context);
-int labcomm_reader_free(struct labcomm_reader *r, 
-			struct labcomm_reader_action_context *action_context);
-int labcomm_reader_start(struct labcomm_reader *r, 
-			 struct labcomm_reader_action_context *action_context,
+int labcomm2014_reader_alloc(struct labcomm2014_reader *r, 
+			 struct labcomm2014_reader_action_context *action_context);
+int labcomm2014_reader_free(struct labcomm2014_reader *r, 
+			struct labcomm2014_reader_action_context *action_context);
+int labcomm2014_reader_start(struct labcomm2014_reader *r, 
+			 struct labcomm2014_reader_action_context *action_context,
 			 int local_index, int remote_index,
-			 const struct labcomm_signature *signature,
+			 const struct labcomm2014_signature *signature,
 			 void *value);
-int labcomm_reader_end(struct labcomm_reader *r, 
-		       struct labcomm_reader_action_context *action_context);
-int labcomm_reader_fill(struct labcomm_reader *r, 
-			struct labcomm_reader_action_context *action_context);
-int labcomm_reader_ioctl(struct labcomm_reader *r, 
-			 struct labcomm_reader_action_context *action_context,
+int labcomm2014_reader_end(struct labcomm2014_reader *r, 
+		       struct labcomm2014_reader_action_context *action_context);
+int labcomm2014_reader_fill(struct labcomm2014_reader *r, 
+			struct labcomm2014_reader_action_context *action_context);
+int labcomm2014_reader_ioctl(struct labcomm2014_reader *r, 
+			 struct labcomm2014_reader_action_context *action_context,
 			 int local_index, int remote_index,
-			 const struct labcomm_signature *signature, 
+			 const struct labcomm2014_signature *signature, 
 			 uint32_t ioctl_action, va_list args);
 
 /*
  * Non typesafe registration function to be called from
- * generated labcomm_decoder_register_* functions.
+ * generated labcomm2014_decoder_register_* functions.
  */
-int labcomm_internal_decoder_register(
-  struct labcomm_decoder *d, 
-  const struct labcomm_signature *s, 
-  labcomm_decoder_function decoder,
-  labcomm_handler_function handler,
+int labcomm2014_internal_decoder_register(
+  struct labcomm2014_decoder *d, 
+  const struct labcomm2014_signature *s, 
+  labcomm2014_decoder_function decoder,
+  labcomm2014_handler_function handler,
   void *context);
 
-int labcomm_internal_decoder_ioctl(struct labcomm_decoder *decoder, 
-				   const struct labcomm_signature *signature,
+int labcomm2014_internal_decoder_ioctl(struct labcomm2014_decoder *decoder, 
+				   const struct labcomm2014_signature *signature,
 				   uint32_t ioctl_action, va_list args);
 
-const struct labcomm_signature *labcomm_internal_decoder_index_to_signature(
-  struct labcomm_decoder *decoder, int index);
+const struct labcomm2014_signature *labcomm2014_internal_decoder_index_to_signature(
+  struct labcomm2014_decoder *decoder, int index);
 
 #if __BYTE_ORDER == __LITTLE_ENDIAN
 
 #define LABCOMM_DECODE(name, type)					\
-  static inline type labcomm_read_##name(struct labcomm_reader *r) {	\
+  static inline type labcomm2014_read_##name(struct labcomm2014_reader *r) {	\
     type result; int i;							\
     for (i = sizeof(type) - 1 ; i >= 0 ; i--) {				\
       if (r->pos >= r->count) {						\
-	labcomm_reader_fill(r, r->action_context);			\
+	labcomm2014_reader_fill(r, r->action_context);			\
 	if (r->error < 0) {						\
 	  return 0;							\
 	}								\
@@ -218,11 +224,11 @@ const struct labcomm_signature *labcomm_internal_decoder_index_to_signature(
 #else
 
 #define LABCOMM_DECODE(name, type)					\
-  static inline type labcomm_read_##name(struct labcomm_reader *r) {	\
+  static inline type labcomm2014_read_##name(struct labcomm2014_reader *r) {	\
     type result; int i;							\
     for (i = 0 ; i < sizeof(type) ; i++) {				\
       if (r->pos >= r->count) {						\
-	labcomm_reader_fille(r, r->action_context);			\
+	labcomm2014_reader_fille(r, r->action_context);			\
 	if (r->error < 0) {						\
 	  return 0;							\
 	}								\
@@ -243,7 +249,7 @@ LABCOMM_DECODE(long, long long)
 LABCOMM_DECODE(float, float)
 LABCOMM_DECODE(double, double)
 
-static inline unsigned int labcomm_read_packed32(struct labcomm_reader *r)
+static inline unsigned int labcomm2014_read_packed32(struct labcomm2014_reader *r)
 {
   unsigned int result = 0;
   
@@ -251,7 +257,7 @@ static inline unsigned int labcomm_read_packed32(struct labcomm_reader *r)
     unsigned char tmp;
 
     if (r->pos >= r->count) {	
-      labcomm_reader_fill(r, r->action_context);
+      labcomm2014_reader_fill(r, r->action_context);
       if (r->error != 0) {
 	goto out;
       }
@@ -267,21 +273,21 @@ out:
   return result;
 }
  
-static inline char *labcomm_read_string(struct labcomm_reader *r)
+static inline char *labcomm2014_read_string(struct labcomm2014_reader *r)
 {
   char *result = NULL;
   int length, pos; 
   
-  length = labcomm_read_packed32(r);
-  result = labcomm_memory_alloc(r->memory, 1, length + 1);
+  length = labcomm2014_read_packed32(r);
+  result = labcomm2014_memory_alloc(r->memory, 1, length + 1);
   if (!result) {
-    labcomm2014_on_error_fprintf(LABCOMM_ERROR_MEMORY, 4, "%d byte at %s:%d",
+    labcomm20142014_on_error_fprintf(LABCOMM2014_ERROR_MEMORY, 4, "%d byte at %s:%d",
 		     length+1, __FUNCTION__, __LINE__);
     return NULL;
   }
   for (pos = 0 ; pos < length ; pos++) {
     if (r->pos >= r->count) {	
-      labcomm_reader_fill(r, r->action_context);
+      labcomm2014_reader_fill(r, r->action_context);
       if (r->error < 0) {
 	goto out;
       }
@@ -297,15 +303,15 @@ out:
 /*
  * Semi private encoder declarations
  */
-typedef int (*labcomm_encoder_function)(struct labcomm_writer *,
+typedef int (*labcomm2014_encoder_function)(struct labcomm2014_writer *,
 					void *value);
-struct labcomm_writer_action_context;
+struct labcomm2014_writer_action_context;
 
-struct labcomm_writer_action {
-  int (*alloc)(struct labcomm_writer *w, 
-	       struct labcomm_writer_action_context *action_context);
-  int (*free)(struct labcomm_writer *w, 
-	      struct labcomm_writer_action_context *action_context);
+struct labcomm2014_writer_action {
+  int (*alloc)(struct labcomm2014_writer *w, 
+	       struct labcomm2014_writer_action_context *action_context);
+  int (*free)(struct labcomm2014_writer *w, 
+	      struct labcomm2014_writer_action_context *action_context);
   /* 'start' is called right before a sample is to be sent. In the 
      case of a sample or typedef, 'value' == NULL.
 
@@ -315,31 +321,31 @@ struct labcomm_writer_action {
                                 'end' will not be called
        < 0           Error
    */
-  int (*start)(struct labcomm_writer *w, 
-	       struct labcomm_writer_action_context *action_context,
-	       int index, const struct labcomm_signature *signature,
+  int (*start)(struct labcomm2014_writer *w, 
+	       struct labcomm2014_writer_action_context *action_context,
+	       int index, const struct labcomm2014_signature *signature,
 	       void *value);
-  int (*end)(struct labcomm_writer *w, 
-	     struct labcomm_writer_action_context *action_context);
-  int (*flush)(struct labcomm_writer *w, 
-	       struct labcomm_writer_action_context *action_context); 
-  int (*ioctl)(struct labcomm_writer *w, 
-	       struct labcomm_writer_action_context *action_context, 
-	       int index, const struct labcomm_signature *signature, 
+  int (*end)(struct labcomm2014_writer *w, 
+	     struct labcomm2014_writer_action_context *action_context);
+  int (*flush)(struct labcomm2014_writer *w, 
+	       struct labcomm2014_writer_action_context *action_context); 
+  int (*ioctl)(struct labcomm2014_writer *w, 
+	       struct labcomm2014_writer_action_context *action_context, 
+	       int index, const struct labcomm2014_signature *signature, 
 	       uint32_t ioctl_action, va_list args);
 };
 
-struct labcomm_writer_action_context {
-  struct labcomm_writer_action_context *next;
-  const struct labcomm_writer_action *action;
+struct labcomm2014_writer_action_context {
+  struct labcomm2014_writer_action_context *next;
+  const struct labcomm2014_writer_action *action;
   void *context;  
 };
 
-struct labcomm_writer {
-  struct labcomm_writer_action_context *action_context;
-  struct labcomm_memory *memory;
-  /* The following fields are initialized by labcomm_encoder_new */
-  struct labcomm_encoder *encoder;
+struct labcomm2014_writer {
+  struct labcomm2014_writer_action_context *action_context;
+  struct labcomm2014_memory *memory;
+  /* The following fields are initialized by labcomm2014_encoder_new */
+  struct labcomm2014_encoder *encoder;
   unsigned char *data;
   int data_size;
   int count;
@@ -347,54 +353,63 @@ struct labcomm_writer {
   int error;
 };
 
-int labcomm_writer_alloc(struct labcomm_writer *w, 
-			 struct labcomm_writer_action_context *action_context);
-int labcomm_writer_free(struct labcomm_writer *w, 
-			struct labcomm_writer_action_context *action_context);
-int labcomm_writer_start(struct labcomm_writer *w, 
-			 struct labcomm_writer_action_context *action_context,
-			 int index, const struct labcomm_signature *signature,
+int labcomm2014_writer_alloc(struct labcomm2014_writer *w, 
+			 struct labcomm2014_writer_action_context *action_context);
+int labcomm2014_writer_free(struct labcomm2014_writer *w, 
+			struct labcomm2014_writer_action_context *action_context);
+int labcomm2014_writer_start(struct labcomm2014_writer *w, 
+			 struct labcomm2014_writer_action_context *action_context,
+			 int index, const struct labcomm2014_signature *signature,
 			 void *value);
-int labcomm_writer_end(struct labcomm_writer *w, 
-		       struct labcomm_writer_action_context *action_context);
-int labcomm_writer_flush(struct labcomm_writer *w, 
-			 struct labcomm_writer_action_context *action_context); 
-int labcomm_writer_ioctl(struct labcomm_writer *w, 
-			 struct labcomm_writer_action_context *action_context, 
-			 int index, const struct labcomm_signature *signature, 
+int labcomm2014_writer_end(struct labcomm2014_writer *w, 
+		       struct labcomm2014_writer_action_context *action_context);
+int labcomm2014_writer_flush(struct labcomm2014_writer *w, 
+			 struct labcomm2014_writer_action_context *action_context); 
+int labcomm2014_writer_ioctl(struct labcomm2014_writer *w, 
+			 struct labcomm2014_writer_action_context *action_context, 
+			 int index, const struct labcomm2014_signature *signature, 
 			 uint32_t ioctl_action, va_list args);
 
-int labcomm_internal_encoder_register(
-  struct labcomm_encoder *encoder, 
-  const struct labcomm_signature *signature, 
-  labcomm_encoder_function encode);
+int labcomm2014_internal_encoder_type_register(
+  struct labcomm2014_encoder *e,
+  const struct labcomm2014_signature *signature);
+
+int labcomm2014_internal_encoder_type_bind(
+  struct labcomm2014_encoder *e,
+  const struct labcomm2014_signature *signature,
+  char has_deps);
 
-int labcomm_internal_encode(
-  struct labcomm_encoder *encoder, 
-  const struct labcomm_signature *signature, 
-  labcomm_encoder_function encode,
+int labcomm2014_internal_encoder_register(
+  struct labcomm2014_encoder *encoder, 
+  const struct labcomm2014_signature *signature, 
+  labcomm2014_encoder_function encode);
+
+int labcomm2014_internal_encode(
+  struct labcomm2014_encoder *encoder, 
+  const struct labcomm2014_signature *signature, 
+  labcomm2014_encoder_function encode,
   void *value);
 
-int labcomm_internal_encoder_ioctl(struct labcomm_encoder *encoder, 
-				   const struct labcomm_signature *signature,
+int labcomm2014_internal_encoder_ioctl(struct labcomm2014_encoder *encoder, 
+				   const struct labcomm2014_signature *signature,
 				   uint32_t ioctl_action, va_list args);
 
-int labcomm_internal_encoder_signature_to_index(
-  struct labcomm_encoder *encoder, const struct labcomm_signature *signature);
+int labcomm2014_internal_encoder_signature_to_index(
+  struct labcomm2014_encoder *encoder, const struct labcomm2014_signature *signature);
 
-int labcomm_internal_sizeof(const struct labcomm_signature *signature,
+int labcomm2014_internal_sizeof(const struct labcomm2014_signature *signature,
                             void *v);
 
 
 #if __BYTE_ORDER == __LITTLE_ENDIAN
 
 #define LABCOMM_ENCODE(name, type)					\
-  static inline int labcomm_write_##name(struct labcomm_writer *w, type data) { \
+  static inline int labcomm2014_write_##name(struct labcomm2014_writer *w, type data) { \
     int i;								\
     for (i = sizeof(type) - 1 ; i >= 0 ; i--) {				\
       if (w->pos >= w->count) { /*buffer is full*/			\
         int err;							\
-	err = labcomm_writer_flush(w, w->action_context);		\
+	err = labcomm2014_writer_flush(w, w->action_context);		\
 	if (err != 0) { return err; }					\
       }									\
       w->data[w->pos] = ((unsigned char*)(&data))[i];			\
@@ -406,12 +421,12 @@ int labcomm_internal_sizeof(const struct labcomm_signature *signature,
 #else
 
 #define LABCOMM_ENCODE(name, type)					\
-  static inline int labcomm_write_##name(struct labcomm_writer *w, type data) { \
+  static inline int labcomm2014_write_##name(struct labcomm2014_writer *w, type data) { \
     int i;								\
     for (i = 0 ; i < sizeof(type) ; i++) {				\
       if (w->pos >= w->count) {						\
         int err;							\
-	err = labcomm_writer_flush(w, w->action_context);		\
+	err = labcomm2014_writer_flush(w, w->action_context);		\
 	if (err != 0) { return err; }					\
       }									\
       w->data[w->pos] = ((unsigned char*)(&data))[i];			\
@@ -430,7 +445,7 @@ LABCOMM_ENCODE(long, long long)
 LABCOMM_ENCODE(float, float)
 LABCOMM_ENCODE(double, double)
 
-static inline int labcomm_write_packed32(struct labcomm_writer *w, 
+static inline int labcomm2014_write_packed32(struct labcomm2014_writer *w, 
 					 unsigned int data)
 {
   unsigned char tmp[5];
@@ -442,7 +457,7 @@ static inline int labcomm_write_packed32(struct labcomm_writer *w,
   for (i = i - 1 ; i >= 0 ; i--) {
     if (w->pos >= w->count) {					
       int err;
-      err = labcomm_writer_flush(w, w->action_context);	
+      err = labcomm2014_writer_flush(w, w->action_context);	
       if (err != 0) { return err; }
     }
     w->data[w->pos++] = tmp[i] | (i?0x80:0x00);
@@ -450,17 +465,17 @@ static inline int labcomm_write_packed32(struct labcomm_writer *w,
   return 0;
 }
 
-static inline int labcomm_write_string(struct labcomm_writer *w, char *s)
+static inline int labcomm2014_write_string(struct labcomm2014_writer *w, char *s)
 {
   int length, i, err; 
 
   length = strlen(s);
-  err = labcomm_write_packed32(w, length);
+  err = labcomm2014_write_packed32(w, length);
   if (err != 0) { return err; }
   for (i = 0 ; i < length ; i++) {
     if (w->pos >= w->count) {	
       int err;
-      err = labcomm_writer_flush(w, w->action_context);	
+      err = labcomm2014_writer_flush(w, w->action_context);	
       if (err != 0) { return err; }
     }
     w->data[w->pos] = s[i];
@@ -470,7 +485,7 @@ static inline int labcomm_write_string(struct labcomm_writer *w, char *s)
 }
 
 /* Size of packed32 variable */
-static inline int labcomm_size_packed32(unsigned int data)
+static inline int labcomm2014_size_packed32(unsigned int data)
 {
   int result = 0;
   int i;
@@ -482,11 +497,11 @@ static inline int labcomm_size_packed32(unsigned int data)
 
 }
 
-static inline int labcomm_size_string(char *s)
+static inline int labcomm2014_size_string(char *s)
 {
   int length = strlen(s);
   
-  return labcomm_size_packed32(length) + length;
+  return labcomm2014_size_packed32(length) + length;
 }
 
 /*
@@ -508,10 +523,10 @@ static inline int labcomm_size_string(char *s)
   name.data = (kind *)name.data; /* typechecking no-op */
 
 #define LABCOMM_SIGNATURE_ARRAY_FREE(memory, name, kind)	\
-  if (name.data) { labcomm_memory_free(memory, 0, name.data); }	\
+  if (name.data) { labcomm2014_memory_free(memory, 0, name.data); }	\
   name.data = (kind *)NULL; /* typechecking */
 
-void *labcomm_signature_array_ref(struct labcomm_memory * memory,
+void *labcomm2014_signature_array_ref(struct labcomm2014_memory * memory,
 				  int *first, int *last, void **data,
 				  int size, int index);
 /*
@@ -523,7 +538,7 @@ void *labcomm_signature_array_ref(struct labcomm_memory * memory,
  */
 #define LABCOMM_SIGNATURE_ARRAY_REF(memory, name, kind, index)		\
   (name.data = (kind *)name.data, /* typechecking no-op */		\
-   (kind *)(labcomm_signature_array_ref(memory,				\
+   (kind *)(labcomm2014_signature_array_ref(memory,				\
 					&name.first, &name.last,	\
 					(void **)&name.data,		\
 					sizeof(kind), index)))
@@ -538,9 +553,11 @@ void *labcomm_signature_array_ref(struct labcomm_memory * memory,
        var = name.first ; var < name.last ; var++)
 
 /* Give signature a free local index, this may not be used concurrently */
-void labcomm_set_local_index(struct labcomm_signature *signature);
+void labcomm2014_set_local_index(struct labcomm2014_signature *signature);
 
 /* Get the local index for a signature */
-int labcomm_get_local_index(const struct labcomm_signature *s);
+int labcomm2014_get_local_index(const struct labcomm2014_signature *s);
+
+int labcomm2014_get_local_type_index(const struct labcomm2014_signature *s);
 
 #endif
diff --git a/lib/c/2014/labcomm_pthread_scheduler.c b/lib/c/2014/labcomm2014_pthread_scheduler.c
similarity index 75%
rename from lib/c/2014/labcomm_pthread_scheduler.c
rename to lib/c/2014/labcomm2014_pthread_scheduler.c
index a9b516a3b41af1ccfada40a9da50958299758a6e..e2f5a21be18660d34fbd36575d7012d0e594e66d 100644
--- a/lib/c/2014/labcomm_pthread_scheduler.c
+++ b/lib/c/2014/labcomm2014_pthread_scheduler.c
@@ -1,5 +1,5 @@
 /*
-  labcomm_pthread_scheduler.c -- labcomm pthread based task coordination
+  labcomm2014_pthread_scheduler.c -- labcomm2014 pthread based task coordination
 
   Copyright 2013 Anders Blomdell <anders.blomdell@control.lth.se>
 
@@ -23,18 +23,18 @@
 #include <stdlib.h>
 #include <errno.h>
 #include <pthread.h>
-#include "labcomm.h"
-#include "labcomm_scheduler.h"
-#include "labcomm_scheduler_private.h"
-#include "labcomm_pthread_scheduler.h"
+#include "labcomm2014.h"
+#include "labcomm2014_scheduler.h"
+#include "labcomm2014_scheduler_private.h"
+#include "labcomm2014_pthread_scheduler.h"
 
 #ifdef LABCOMM_COMPAT
   #include LABCOMM_COMPAT
 #endif 
 
 struct pthread_time {
-  struct labcomm_time time;
-  struct labcomm_memory *memory;
+  struct labcomm2014_time time;
+  struct labcomm2014_memory *memory;
   struct timespec abstime;
 };
 
@@ -47,8 +47,8 @@ struct pthread_deferred {
 };
 
 struct pthread_scheduler {
-  struct labcomm_scheduler scheduler;
-  struct labcomm_memory *memory;
+  struct labcomm2014_scheduler scheduler;
+  struct labcomm2014_memory *memory;
   int wakeup;
   pthread_mutex_t writer_mutex;
   pthread_mutex_t data_mutex;
@@ -58,7 +58,7 @@ struct pthread_scheduler {
   struct pthread_deferred deferred_with_delay;
 };
 
-static struct labcomm_time_action time_action;
+static struct labcomm2014_time_action time_action;
 
 static int queue_empty(struct pthread_deferred *queue)
 {
@@ -100,11 +100,11 @@ static int timespec_compare(struct timespec *t1, struct timespec *t2)
   }
 }
 
-static struct labcomm_time *time_new(struct labcomm_memory *memory)
+static struct labcomm2014_time *time_new(struct labcomm2014_memory *memory)
 {
   struct pthread_time *time;
 
-  time = labcomm_memory_alloc(memory, 0, sizeof(*time));
+  time = labcomm2014_memory_alloc(memory, 0, sizeof(*time));
   if (time == NULL) {
     return NULL;
   } else {
@@ -116,17 +116,17 @@ static struct labcomm_time *time_new(struct labcomm_memory *memory)
   }
 }
 
-static int time_free(struct labcomm_time *t)
+static int time_free(struct labcomm2014_time *t)
 {
   struct pthread_time *time = t->context;
-  struct labcomm_memory *memory = time->memory;
+  struct labcomm2014_memory *memory = time->memory;
   
-  labcomm_memory_free(memory, 0, time);
+  labcomm2014_memory_free(memory, 0, time);
   
   return 0;
 }
  
-static int time_add_usec(struct labcomm_time *t, uint32_t usec)
+static int time_add_usec(struct labcomm2014_time *t, uint32_t usec)
 {
   struct pthread_time *time = t->context;
 
@@ -135,7 +135,7 @@ static int time_add_usec(struct labcomm_time *t, uint32_t usec)
   return 0;
 }
 
-static struct labcomm_time_action time_action = {
+static struct labcomm2014_time_action time_action = {
   .free = time_free,
   .add_usec = time_add_usec
 };
@@ -146,10 +146,10 @@ static int run_action(struct pthread_scheduler *scheduler,
   /* Called with data_lock held */
   element->prev->next = element->next;
   element->next->prev = element->prev;
-  labcomm_scheduler_data_unlock(&scheduler->scheduler);
+  labcomm2014_scheduler_data_unlock(&scheduler->scheduler);
   element->action(element->context);
-  labcomm_memory_free(scheduler->memory, 1, element);
-  labcomm_scheduler_data_lock(&scheduler->scheduler);
+  labcomm2014_memory_free(scheduler->memory, 1, element);
+  labcomm2014_scheduler_data_lock(&scheduler->scheduler);
   return 0;
 }
 
@@ -175,44 +175,44 @@ out:
   return 0;
 }
 
-static int scheduler_free(struct labcomm_scheduler *s)
+static int scheduler_free(struct labcomm2014_scheduler *s)
 {
   struct pthread_scheduler *scheduler = s->context;
-  struct labcomm_memory *memory = scheduler->memory;
+  struct labcomm2014_memory *memory = scheduler->memory;
   
-  labcomm_memory_free(memory, 0, scheduler);
+  labcomm2014_memory_free(memory, 0, scheduler);
 
   return 0;
 }
  
-static int scheduler_writer_lock(struct labcomm_scheduler *s)
+static int scheduler_writer_lock(struct labcomm2014_scheduler *s)
 {
   struct pthread_scheduler *scheduler = s->context;
 
-  labcomm_scheduler_data_lock(&scheduler->scheduler);
+  labcomm2014_scheduler_data_lock(&scheduler->scheduler);
   run_deferred(scheduler);  /* Run deferred tasks before taking lock */
-  labcomm_scheduler_data_unlock(&scheduler->scheduler);
+  labcomm2014_scheduler_data_unlock(&scheduler->scheduler);
   if (pthread_mutex_lock(&scheduler->writer_mutex) != 0) {
     return -errno;
   }
   return 0;
 }
  
-static int scheduler_writer_unlock(struct labcomm_scheduler *s)
+static int scheduler_writer_unlock(struct labcomm2014_scheduler *s)
 {
   struct pthread_scheduler *scheduler = s->context;
 
   if (pthread_mutex_unlock(&scheduler->writer_mutex) != 0) {
     return -errno;
   }
-  labcomm_scheduler_data_lock(&scheduler->scheduler);
+  labcomm2014_scheduler_data_lock(&scheduler->scheduler);
   run_deferred(scheduler);  /* Run deferred tasks after releasing lock */
-  labcomm_scheduler_data_unlock(&scheduler->scheduler);
+  labcomm2014_scheduler_data_unlock(&scheduler->scheduler);
   
   return 0;
 }
 
-static int scheduler_data_lock(struct labcomm_scheduler *s)
+static int scheduler_data_lock(struct labcomm2014_scheduler *s)
 {
   struct pthread_scheduler *scheduler = s->context;
 
@@ -223,7 +223,7 @@ static int scheduler_data_lock(struct labcomm_scheduler *s)
   return 0;
 }
  
-static int scheduler_data_unlock(struct labcomm_scheduler *s)
+static int scheduler_data_unlock(struct labcomm2014_scheduler *s)
 {
   struct pthread_scheduler *scheduler = s->context;
 
@@ -235,20 +235,20 @@ static int scheduler_data_unlock(struct labcomm_scheduler *s)
   return 0;
 }
 
-static struct labcomm_time *scheduler_now(struct labcomm_scheduler *s)
+static struct labcomm2014_time *scheduler_now(struct labcomm2014_scheduler *s)
 {
   struct pthread_scheduler *scheduler = s->context;
 
   return time_new(scheduler->memory);
 }
  
-static int scheduler_sleep(struct labcomm_scheduler *s,
-			   struct labcomm_time *t)
+static int scheduler_sleep(struct labcomm2014_scheduler *s,
+			   struct labcomm2014_time *t)
 {
   struct pthread_scheduler *scheduler = s->context;
   struct pthread_time *time = t?t->context:NULL;
 
-  labcomm_scheduler_data_lock(&scheduler->scheduler);
+  labcomm2014_scheduler_data_lock(&scheduler->scheduler);
   while (1) {
     struct timespec *wakeup, now;
 
@@ -281,23 +281,23 @@ static int scheduler_sleep(struct labcomm_scheduler *s,
 			&scheduler->data_mutex);
     }
   }
-  labcomm_scheduler_data_unlock(&scheduler->scheduler);
+  labcomm2014_scheduler_data_unlock(&scheduler->scheduler);
   
   return 0;
 }
 
-static int scheduler_wakeup(struct labcomm_scheduler *s)
+static int scheduler_wakeup(struct labcomm2014_scheduler *s)
 {
   struct pthread_scheduler *scheduler = s->context;
 
-  labcomm_scheduler_data_lock(&scheduler->scheduler);
+  labcomm2014_scheduler_data_lock(&scheduler->scheduler);
   scheduler->wakeup = 1;
   pthread_cond_signal(&scheduler->data_cond);
-  labcomm_scheduler_data_unlock(&scheduler->scheduler);
+  labcomm2014_scheduler_data_unlock(&scheduler->scheduler);
   return 0;
 }
 
-static int scheduler_enqueue(struct labcomm_scheduler *s,
+static int scheduler_enqueue(struct labcomm2014_scheduler *s,
 			     uint32_t delay,
 			     void (*deferred)(void *context),
 			     void *context)
@@ -306,7 +306,7 @@ static int scheduler_enqueue(struct labcomm_scheduler *s,
   int result = 0;
   struct pthread_deferred *element, *insert_before;
 
-  element = labcomm_memory_alloc(scheduler->memory, 1, sizeof(*element));
+  element = labcomm2014_memory_alloc(scheduler->memory, 1, sizeof(*element));
   if (element == NULL) {
     result = -ENOMEM;
     goto out;
@@ -314,7 +314,7 @@ static int scheduler_enqueue(struct labcomm_scheduler *s,
   
   element->action = deferred;
   element->context = context;
-  labcomm_scheduler_data_lock(&scheduler->scheduler);
+  labcomm2014_scheduler_data_lock(&scheduler->scheduler);
   if (delay == 0) {
     insert_before = &scheduler->deferred;
   } else {
@@ -330,13 +330,13 @@ static int scheduler_enqueue(struct labcomm_scheduler *s,
   element->prev->next = element;
   element->next->prev = element;
   pthread_cond_signal(&scheduler->data_cond);
-  labcomm_scheduler_data_unlock(&scheduler->scheduler);
+  labcomm2014_scheduler_data_unlock(&scheduler->scheduler);
 
 out:
   return result;
 }
 
-static const struct labcomm_scheduler_action scheduler_action = {
+static const struct labcomm2014_scheduler_action scheduler_action = {
   .free = scheduler_free,
   .writer_lock = scheduler_writer_lock,
   .writer_unlock = scheduler_writer_unlock,
@@ -348,13 +348,13 @@ static const struct labcomm_scheduler_action scheduler_action = {
   .enqueue = scheduler_enqueue  
 };
 
-struct labcomm_scheduler *labcomm_pthread_scheduler_new(
-  struct labcomm_memory *memory)
+struct labcomm2014_scheduler *labcomm2014_pthread_scheduler_new(
+  struct labcomm2014_memory *memory)
 {
-  struct labcomm_scheduler *result = NULL;
+  struct labcomm2014_scheduler *result = NULL;
   struct pthread_scheduler *scheduler;
 
-  scheduler = labcomm_memory_alloc(memory, 0, sizeof(*scheduler));
+  scheduler = labcomm2014_memory_alloc(memory, 0, sizeof(*scheduler));
   if (scheduler == NULL) {
     goto out;
   } else {
@@ -386,7 +386,7 @@ destroy_data_mutex:
 destroy_writer_mutex:
   pthread_mutex_destroy(&scheduler->writer_mutex);
 free_scheduler:
-  labcomm_memory_free(memory, 0, scheduler);
+  labcomm2014_memory_free(memory, 0, scheduler);
 out:
   return result;
   
diff --git a/lib/c/2014/labcomm_pthread_scheduler.h b/lib/c/2014/labcomm2014_pthread_scheduler.h
similarity index 71%
rename from lib/c/2014/labcomm_pthread_scheduler.h
rename to lib/c/2014/labcomm2014_pthread_scheduler.h
index c8b20eca176925a9ba4468967ca6225f5d6ab806..e8e5a1b49581e33098cb2ed7d41876433befd73c 100644
--- a/lib/c/2014/labcomm_pthread_scheduler.h
+++ b/lib/c/2014/labcomm2014_pthread_scheduler.h
@@ -1,5 +1,5 @@
 /*
-  labcomm_pthread_scheduler.h -- labcomm pthread based task coordination
+  labcomm2014_pthread_scheduler.h -- labcomm2014 pthread based task coordination
 
   Copyright 2013 Anders Blomdell <anders.blomdell@control.lth.se>
 
@@ -19,13 +19,13 @@
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-#ifndef _LABCOMM_PTHREAD_SCHEDULER_H_
-#define _LABCOMM_PTHREAD_SCHEDULER_H_
+#ifndef __LABCOMM2014_PTHREAD_SCHEDULER_H__
+#define __LABCOMM2014_PTHREAD_SCHEDULER_H__
 
-#include "labcomm.h"
+#include "labcomm2014.h"
 
-struct labcomm_scheduler *labcomm_pthread_scheduler_new(
-  struct labcomm_memory *memory);
+struct labcomm2014_scheduler *labcomm2014_pthread_scheduler_new(
+  struct labcomm2014_memory *memory);
 
 #endif
 
diff --git a/lib/c/2014/labcomm_scheduler.c b/lib/c/2014/labcomm2014_scheduler.c
similarity index 66%
rename from lib/c/2014/labcomm_scheduler.c
rename to lib/c/2014/labcomm2014_scheduler.c
index 3ef62f3b54e076f0dbf726acd4421dddec71fb42..40288207149d93efc11c5084433b04d374b26a0c 100644
--- a/lib/c/2014/labcomm_scheduler.c
+++ b/lib/c/2014/labcomm2014_scheduler.c
@@ -1,5 +1,5 @@
 /*
-  labcomm_scheduler.c -- labcomm task coordination
+  labcomm2014_scheduler.c -- labcomm2014 task coordination
 
   Copyright 2013 Anders Blomdell <anders.blomdell@control.lth.se>
 
@@ -20,7 +20,7 @@
 */
 
 #include <errno.h>
-#include "labcomm_scheduler_private.h"
+#include "labcomm2014_scheduler_private.h"
 
 #define SCHEDULER_scheduler(scheduler, ...) scheduler
 #define SCHEDULER(func, ...)						\
@@ -30,32 +30,32 @@
   }									\
   return -ENOSYS;
 
-int labcomm_scheduler_free(struct labcomm_scheduler *s)
+int labcomm2014_scheduler_free(struct labcomm2014_scheduler *s)
 {
   SCHEDULER(free, s);
 }
 
-int labcomm_scheduler_writer_lock(struct labcomm_scheduler *s)
+int labcomm2014_scheduler_writer_lock(struct labcomm2014_scheduler *s)
 {
   SCHEDULER(writer_lock, s);
 }
 
-int labcomm_scheduler_writer_unlock(struct labcomm_scheduler *s)
+int labcomm2014_scheduler_writer_unlock(struct labcomm2014_scheduler *s)
 {
   SCHEDULER(writer_unlock, s);
 }
 
-int labcomm_scheduler_data_lock(struct labcomm_scheduler *s)
+int labcomm2014_scheduler_data_lock(struct labcomm2014_scheduler *s)
 {
   SCHEDULER(data_lock, s);
 }
 
-int labcomm_scheduler_data_unlock(struct labcomm_scheduler *s)
+int labcomm2014_scheduler_data_unlock(struct labcomm2014_scheduler *s)
 {
   SCHEDULER(data_unlock, s);
 }
 
-struct labcomm_time *labcomm_scheduler_now(struct labcomm_scheduler *s)
+struct labcomm2014_time *labcomm2014_scheduler_now(struct labcomm2014_scheduler *s)
 {
   if (s && s->action->now) {
     return s->action->now(s); 
@@ -63,18 +63,18 @@ struct labcomm_time *labcomm_scheduler_now(struct labcomm_scheduler *s)
   return NULL;
 }
 
-int labcomm_scheduler_sleep(struct labcomm_scheduler *s,
-			    struct labcomm_time *wakeup)
+int labcomm2014_scheduler_sleep(struct labcomm2014_scheduler *s,
+			    struct labcomm2014_time *wakeup)
 {
   SCHEDULER(sleep, s, wakeup);
 }
 
-int labcomm_scheduler_wakeup(struct labcomm_scheduler *s)
+int labcomm2014_scheduler_wakeup(struct labcomm2014_scheduler *s)
 {
   SCHEDULER(wakeup, s);
 }
 
-int labcomm_scheduler_enqueue(struct labcomm_scheduler *s,
+int labcomm2014_scheduler_enqueue(struct labcomm2014_scheduler *s,
 			      uint32_t delay,
 			      void (*func)(void *context),
 			      void *context)
diff --git a/lib/c/2014/labcomm_scheduler.h b/lib/c/2014/labcomm2014_scheduler.h
similarity index 50%
rename from lib/c/2014/labcomm_scheduler.h
rename to lib/c/2014/labcomm2014_scheduler.h
index 07f74c281ab7fff57ec8edf86e6f04219f2e3427..8d7e33217fcd7e7b043bfd527e10d429f29c42b4 100644
--- a/lib/c/2014/labcomm_scheduler.h
+++ b/lib/c/2014/labcomm2014_scheduler.h
@@ -1,5 +1,5 @@
 /*
-  labcomm_scheduler.h -- labcomm task coordination
+  labcomm2014_scheduler.h -- labcomm2014 task coordination
 
   Copyright 2013 Anders Blomdell <anders.blomdell@control.lth.se>
 
@@ -19,8 +19,8 @@
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-#ifndef _LABCOMM_SCHEDULER_H_
-#define _LABCOMM_SCHEDULER_H_
+#ifndef __LABCOMM2014_SCHEDULER_H__
+#define __LABCOMM2014_SCHEDULER_H__
 
 #ifdef LABCOMM_COMPAT
   #include LABCOMM_COMPAT
@@ -29,29 +29,29 @@
   #include <stdint.h>
 #endif
 
-struct labcomm_time;
+struct labcomm2014_time;
 
-int labcomm_time_free(struct labcomm_time *t);
-int labcomm_time_add_usec(struct labcomm_time *t, uint32_t usec);
+int labcomm2014_time_free(struct labcomm2014_time *t);
+int labcomm2014_time_add_usec(struct labcomm2014_time *t, uint32_t usec);
 
-struct labcomm_scheduler;
+struct labcomm2014_scheduler;
 
-int labcomm_scheduler_free(struct labcomm_scheduler *s);
+int labcomm2014_scheduler_free(struct labcomm2014_scheduler *s);
 
 /* Lock and event handling */
-int labcomm_scheduler_writer_lock(struct labcomm_scheduler *s);
-int labcomm_scheduler_writer_unlock(struct labcomm_scheduler *s);
-int labcomm_scheduler_data_lock(struct labcomm_scheduler *s);
-int labcomm_scheduler_data_unlock(struct labcomm_scheduler *s);
+int labcomm2014_scheduler_writer_lock(struct labcomm2014_scheduler *s);
+int labcomm2014_scheduler_writer_unlock(struct labcomm2014_scheduler *s);
+int labcomm2014_scheduler_data_lock(struct labcomm2014_scheduler *s);
+int labcomm2014_scheduler_data_unlock(struct labcomm2014_scheduler *s);
 
 /* Time handling */
-struct labcomm_time *labcomm_scheduler_now(struct labcomm_scheduler *s);
-int labcomm_scheduler_sleep(struct labcomm_scheduler *s,
-			    struct labcomm_time *wakeup);
-int labcomm_scheduler_wakeup(struct labcomm_scheduler *s);
+struct labcomm2014_time *labcomm2014_scheduler_now(struct labcomm2014_scheduler *s);
+int labcomm2014_scheduler_sleep(struct labcomm2014_scheduler *s,
+			    struct labcomm2014_time *wakeup);
+int labcomm2014_scheduler_wakeup(struct labcomm2014_scheduler *s);
 
 /* Deferred action handling */
-int labcomm_scheduler_enqueue(struct labcomm_scheduler *s,
+int labcomm2014_scheduler_enqueue(struct labcomm2014_scheduler *s,
 			      uint32_t delay,
 			      void (*deferred)(void *context),
 			      void *context);
diff --git a/lib/c/2014/labcomm2014_scheduler_private.h b/lib/c/2014/labcomm2014_scheduler_private.h
new file mode 100644
index 0000000000000000000000000000000000000000..31f4cdae3cef6d89d6d42971f7fc13b36982e02d
--- /dev/null
+++ b/lib/c/2014/labcomm2014_scheduler_private.h
@@ -0,0 +1,60 @@
+/*
+  labcomm2014_scheduler.h -- labcomm2014 task coordination, semi-private part
+
+  Copyright 2013 Anders Blomdell <anders.blomdell@control.lth.se>
+
+  This file is part of LabComm.
+
+  LabComm is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  LabComm is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __LABCOMM2014_SCHEDULER_PRIVATE_H__
+#define __LABCOMM2014_SCHEDULER_PRIVATE_H__
+
+#ifdef LABCOMM_COMPAT
+  #include LABCOMM_COMPAT
+#else
+  #include <unistd.h>
+#endif
+
+#include "labcomm2014_scheduler.h"
+
+struct labcomm2014_time {
+  const struct labcomm2014_time_action {
+    int (*free)(struct labcomm2014_time *t);
+    int (*add_usec)(struct labcomm2014_time *t, uint32_t usec);
+  } *action;
+  void *context;
+};
+
+struct labcomm2014_scheduler {
+  const struct labcomm2014_scheduler_action {
+    int (*free)(struct labcomm2014_scheduler *s);
+    int (*writer_lock)(struct labcomm2014_scheduler *s);
+    int (*writer_unlock)(struct labcomm2014_scheduler *s);
+    int (*data_lock)(struct labcomm2014_scheduler *s);
+    int (*data_unlock)(struct labcomm2014_scheduler *s);
+    struct labcomm2014_time *(*now)(struct labcomm2014_scheduler *s);
+    int (*sleep)(struct labcomm2014_scheduler *s,
+		 struct labcomm2014_time *wakeup);
+    int (*wakeup)(struct labcomm2014_scheduler *s);
+    int (*enqueue)(struct labcomm2014_scheduler *s,
+		   uint32_t delay,
+		   void (*deferred)(void *context),
+		   void *context);
+  } *action;
+  void *context;
+};
+
+#endif
diff --git a/lib/c/2014/labcomm_time.c b/lib/c/2014/labcomm2014_time.c
similarity index 82%
rename from lib/c/2014/labcomm_time.c
rename to lib/c/2014/labcomm2014_time.c
index a1a5235199aa31c1c315d19343f1e7d33963f2fd..eb5e1f5e43ab2cf4c6e03739078b57d022267874 100644
--- a/lib/c/2014/labcomm_time.c
+++ b/lib/c/2014/labcomm2014_time.c
@@ -1,5 +1,5 @@
 /*
-  labcomm_time.c -- labcomm time handling
+  labcomm2014_time.c -- labcomm2014 time handling
 
   Copyright 2013 Anders Blomdell <anders.blomdell@control.lth.se>
 
@@ -20,7 +20,7 @@
 */
 
 #include <errno.h>
-#include "labcomm_scheduler_private.h"
+#include "labcomm2014_scheduler_private.h"
 
 #define TIME_time(time, ...) time
 #define TIME(func, ...)						\
@@ -30,12 +30,12 @@
   }									\
   return -ENOSYS;
 
-int labcomm_time_free(struct labcomm_time *s)
+int labcomm2014_time_free(struct labcomm2014_time *s)
 {
   TIME(free, s);
 }
 
-int labcomm_time_add_usec(struct labcomm_time *s, uint32_t usec)
+int labcomm2014_time_add_usec(struct labcomm2014_time *s, uint32_t usec)
 {
   TIME(add_usec, s, usec);
 }
diff --git a/lib/c/2014/labcomm2014_type_signature.c b/lib/c/2014/labcomm2014_type_signature.c
new file mode 100644
index 0000000000000000000000000000000000000000..dce1836199fd47e30bf53f8f4766dd81cf3c7b43
--- /dev/null
+++ b/lib/c/2014/labcomm2014_type_signature.c
@@ -0,0 +1,128 @@
+#include "labcomm2014.h"
+#include <string.h>   // for memcmp
+#include <stdio.h>   // for debug printf
+
+/* Dump signature bytes on stdout 
+ */
+
+void labcomm2014_signature_print(struct labcomm2014_signature_data *signature)
+{
+  struct labcomm2014_signature_data *p = signature ;
+  while (p->length != -1) {
+    if (p->length) {
+      int i;
+      for ( i = 0 ; i < p->length ; i++) {
+        printf("%02x ", p->u.bytes[i]);
+      }
+    } else if(p->u.signature){
+      labcomm2014_signature_print(p->u.signature->treedata);
+    } else {
+      printf("neither data nor ref, bailing out.\n");
+      return;
+    }
+    p+=1;
+  }
+  printf("\n");
+}
+static labcomm2014_bool sig_dump_checked(struct labcomm2014_signature_data *signature, 
+                            char *buf, int *len, int buflen);
+
+/* buf (out)   : byte array to write signature into
+   len (in/out): input: buf size, out: signature length
+
+   return LABCOMM2014_TRUE if aborted due to overrun
+ */
+labcomm2014_bool labcomm2014_signature_dump(struct labcomm2014_signature_data *signature, 
+                           char *buf, int *len)
+{
+  int buflen = *len;
+  *len = 0;
+  return sig_dump_checked(signature, buf, len, buflen);
+}
+
+/* internal function with bounds checking for buf.
+ * buflen: capacity of buf
+ */
+static labcomm2014_bool sig_dump_checked(struct labcomm2014_signature_data *signature, 
+                            char *buf, int *len, int buflen)
+{
+  struct labcomm2014_signature_data *p = signature;
+  while ( (p->length != -1) && (*len < buflen)) {
+    if (p->length) {
+      int i;
+      for ( i = 0 ; (i < p->length) && (*len < buflen); i++) {
+        *buf++ = p->u.bytes[i];
+        ++*len;
+      }
+    } else if(p->u.signature){
+      int tmplen=*len;
+      //recursing. c.f. dump()
+      sig_dump_checked(p->u.signature->treedata, buf, len, buflen);
+      int inner_len = *len-tmplen;
+      buf += inner_len;
+    } else {
+      //printf("neither data nor ref, bailing out.\n");
+      return LABCOMM2014_TRUE;
+    }
+    p+=1;
+  }
+  return (*len >= buflen);
+}
+
+/* compare signature (flattened, if needed) to other
+   return LABCOMM2014_TRUE if equal
+*/
+labcomm2014_bool labcomm2014_signature_cmp( struct labcomm2014_signature_data *s1,
+                           struct labcomm2014_signature_data *s2)
+{
+  int buflen=512;
+  char buf1[buflen];
+  int len1=buflen;
+  char buf2[buflen];
+  int len2=buflen;
+  labcomm2014_bool res1 = labcomm2014_signature_dump(s1, buf1, &len1);
+  labcomm2014_bool res2 = labcomm2014_signature_dump(s2, buf2, &len2);
+  if(res1 || res2) {
+    printf("WARNING: OVERRUN\n");
+    return LABCOMM2014_FALSE;
+  } else {
+    return(len1 == len2 && memcmp(buf1, buf2, len1)==0);
+  }
+}
+/* maps a function f(char b, struct labcomm2014_signature *s, void *context) 
+ * on each byte (or type ref) in the signature. 
+ *
+ * If flatten, the signature is flattened to a byte array, and the 
+ * second argument to f is always zero.
+ *
+ * Otherwise, when a type ref is encountered, f is called with the first
+ * argument zero and the referenced type as the second argument.
+ *
+ * The context parameter is passed on, unaltered, to f
+ */ 
+void map_signature( void(*f)(char, const struct labcomm2014_signature *, void *), 
+                    void *context,
+                    const struct labcomm2014_signature *signature, labcomm2014_bool flatten)
+{
+  struct labcomm2014_signature_data* p = signature->treedata;
+  while (p->length != -1) {
+    //fprintf(stderr, "%p %x\n", p, p->length);
+    if (p->length) {
+      int i;
+      for ( i = 0 ; i < p->length ; i++) {
+        (*f)(p->u.bytes[i], 0, context);
+      }
+    } else if (p->u.signature) {
+      if(p->u.signature == 0) printf("p->u.signature == null\n");
+      if(flatten) {
+        map_signature(f, context, p->u.signature, flatten);
+      } else {
+        (*f)(0, p->u.signature, context);
+      }
+    } else {
+      fprintf(stderr, "neither data nor ref, bailing out.\n");
+      return;
+    }
+    p+=1;
+  }
+}
diff --git a/lib/c/2014/labcomm2014_type_signature.h b/lib/c/2014/labcomm2014_type_signature.h
new file mode 100644
index 0000000000000000000000000000000000000000..7c21b95b3435f14f81784a2d6f7fc0f5c926cb7d
--- /dev/null
+++ b/lib/c/2014/labcomm2014_type_signature.h
@@ -0,0 +1,139 @@
+#ifndef __LABCOMM2014_TYPE_SIGNATURE_H__
+#define __LABCOMM2014_TYPE_SIGNATURE_H__
+
+//XXX move to common.h
+#ifndef labcomm2014_bool
+#define labcomm2014_bool char
+#define LABCOMM2014_TRUE 1
+#define LABCOMM2014_FALSE 0
+#endif
+
+/*
+ * Signature entry
+ */
+#ifndef LABCOMM_NO_TYPEDECL
+#ifdef USE_UNIONS
+
+/* Useful for C99 and up (or GCC without -pedantic) */ 
+
+#define LABCOMM_SIGDEF_BYTES_OR_SIGNATURE          \
+  union {                                   \
+    char *bytes;                            \
+    struct labcomm2014_signature* signature;            \
+  } u;
+
+#define LABCOMM_SIGDEF_BYTES(l, b) { l, .u.bytes=b }
+#define LABCOMM_SIGDEF_SIGNATURE(s) { 0, .u.signature=&s } // addressof, as s is pointing at the sig struct, not directly the the sig_bytes[]
+#define LABCOMM_SIGDEF_END { -1, .u.bytes=0 }
+
+#else
+
+#define LABCOMM_SIGDEF_BYTES_OR_SIGNATURE          \
+  struct {                                  \
+    char *bytes;                            \
+    const struct labcomm2014_signature *signature;            \
+  } u;
+
+#define LABCOMM_SIGDEF_BYTES(l, b) { l, { b, 0 } }
+#define LABCOMM_SIGDEF_SIGNATURE(s) { 0, { 0, &s } }
+#define LABCOMM_SIGDEF_END { -1, { 0, 0 } }
+
+#endif
+
+struct labcomm2014_signature_data {
+  int length;
+  LABCOMM_SIGDEF_BYTES_OR_SIGNATURE
+};
+
+#endif
+struct labcomm2014_signature {
+  char *name;
+  int (*encoded_size)(void *); /* void* refers to sample_data */
+  int size;
+  unsigned char *signature; 
+  int index;
+#ifndef LABCOMM_NO_TYPEDECL
+  int tdsize;
+  struct labcomm2014_signature_data *treedata;
+#endif  
+#ifdef LABCOMM_EXPERIMENTAL_CACHED_ENCODED_SIZE
+  int cached_encoded_size; // -1 if not initialized or type is variable size
+#endif
+};
+
+/* a struct for "raw" type_defs, to be used as an intermediate representation
+ * between decoder and signature parser
+ */
+
+struct labcomm2014_raw_type_def {
+    char *name;
+    int index;
+    int length;
+    char *signature_data;
+};
+
+/* a struct for type bindings
+ */
+
+struct labcomm2014_type_binding {
+    int sample_index;
+    int type_index;
+};
+
+/*
+ * functions
+ */
+
+
+/* register a handler for type_defs and type bindings
+ */
+
+int labcomm2014_decoder_register_labcomm2014_type_def(
+  struct labcomm2014_decoder *d,
+  void (*handler)(
+    struct labcomm2014_raw_type_def *v,
+    void *context
+  ),
+  void *context
+);
+
+int labcomm2014_decoder_register_labcomm2014_type_binding(
+  struct labcomm2014_decoder *d,
+  void (*handler)(
+    struct labcomm2014_type_binding *v,
+    void *context
+  ),
+  void *context
+);
+
+/* Dump signature bytes on stdout 
+ */
+
+void labcomm2014_signature_print(struct labcomm2014_signature_data *signature);
+
+/* compare signatures (flattened, if needed) to other
+*  return LABCOMM2014_TRUE if equal
+*/
+labcomm2014_bool labcomm2014_signature_cmp( struct labcomm2014_signature_data *s2,
+                           struct labcomm2014_signature_data *s1);
+
+/* flatten and dump signature to a byte array.
+ * buf (out)   : byte array to write signature into
+ * len (in/out): input: buf size, out: signature length
+ *
+ * return LABCOMM2014_TRUE if aborted due to overrun
+ */
+labcomm2014_bool labcomm2014_signature_dump(struct labcomm2014_signature_data *signature, 
+                           char *buf, int *len);
+
+/* maps function f on each byte in the signature
+ * if flatten, the signature is flattened, and the second argument of
+ * f is always zero
+ * otherwise, when a type ref is encountered, f is called with the first
+ * argument zero and the type ref as the second argument.
+ */ 
+void map_signature( void(*f)(char, const struct labcomm2014_signature *, void *), 
+                    void *context,
+                    const struct labcomm2014_signature *signature, labcomm2014_bool flatten);
+
+#endif
diff --git a/lib/c/2014/labcomm_decoder.c b/lib/c/2014/labcomm_decoder.c
deleted file mode 100644
index 54575ee1eaf7fbb62fecc0dc0427b4696f08cb39..0000000000000000000000000000000000000000
--- a/lib/c/2014/labcomm_decoder.c
+++ /dev/null
@@ -1,506 +0,0 @@
-/*
-  labcomm_decoder.c -- runtime for handling decoding of labcomm samples.
-
-  Copyright 2006-2013 Anders Blomdell <anders.blomdell@control.lth.se>
-
-  This file is part of LabComm.
-
-  LabComm is free software: you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation, either version 3 of the License, or
-  (at your option) any later version.
-
-  LabComm is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-#define CURRENT_VERSION "LabComm2014"
-
-#include <errno.h>
-#include "labcomm.h"
-#include "labcomm_private.h"
-#include "labcomm_ioctl.h"
-#include "labcomm_dynamic_buffer_writer.h"
-
-struct sample_entry {
-  int remote_index;
-  const struct labcomm_signature *signature;
-  labcomm_decoder_function decode;
-  labcomm_handler_function handler;
-  void *context;
-};
-
-struct labcomm_decoder {
-  struct labcomm_reader *reader;
-  int reader_allocated;
-  int version_ok;
-  struct labcomm_error_handler *error;
-  struct labcomm_memory *memory;
-  struct labcomm_scheduler *scheduler;
-  labcomm_error_handler_callback on_error;
-  labcomm_handle_new_datatype_callback on_new_datatype;
-  LABCOMM_SIGNATURE_ARRAY_DEF(local, struct sample_entry);
-  LABCOMM_SIGNATURE_ARRAY_DEF(remote_to_local, int);
-  LABCOMM_SIGNATURE_ARRAY_DEF(local_ref, const struct labcomm_signature *);
-  LABCOMM_SIGNATURE_ARRAY_DEF(remote_to_local_ref, int);
-};
-
-struct labcomm_decoder *labcomm_decoder_new(
-  struct labcomm_reader *reader,
-  struct labcomm_error_handler *error,
-  struct labcomm_memory *memory,
-  struct labcomm_scheduler *scheduler)
-{
-  struct labcomm_decoder *result;
-
-  result = labcomm_memory_alloc(memory, 0, sizeof(*result));
-  if (result) {
-    result->reader = reader;
-    result->reader->decoder = result;
-    result->reader->data = 0;
-    result->reader->data_size = 0;
-    result->reader->count = 0;
-    result->reader->pos = 0;
-    result->reader->error = 0;
-    result->reader_allocated = 0;
-    result->version_ok = 0;
-    result->error = error;
-    result->memory = memory;
-    result->scheduler = scheduler;
-    result->on_error = labcomm2014_on_error_fprintf;
-    LABCOMM_SIGNATURE_ARRAY_INIT(result->local, struct sample_entry);
-    LABCOMM_SIGNATURE_ARRAY_INIT(result->remote_to_local, int);
-    LABCOMM_SIGNATURE_ARRAY_INIT(result->local_ref, 
-                                 const struct labcomm_signature*);
-    LABCOMM_SIGNATURE_ARRAY_INIT(result->remote_to_local_ref, int);
-  }
-  return result;
-}
-
-void labcomm_decoder_free(struct labcomm_decoder* d)
-{
-  struct labcomm_memory *memory = d->memory;
-
-  labcomm_reader_free(d->reader, d->reader->action_context);
-  LABCOMM_SIGNATURE_ARRAY_FREE(memory, d->local, struct sample_entry);
-  LABCOMM_SIGNATURE_ARRAY_FREE(memory, d->remote_to_local, int);
-  LABCOMM_SIGNATURE_ARRAY_FREE(memory, d->local_ref, 
-                               const struct labcomm_signature*);
-  LABCOMM_SIGNATURE_ARRAY_FREE(memory, d->remote_to_local_ref, int);
-  labcomm_memory_free(memory, 0, d);
-}
-
-static int handle_sample_def(struct labcomm_decoder *d, int remote_index,
-                             const struct labcomm_signature *signature)
-{
-  int result;
-  int i;
-  const struct labcomm_signature *local_signature = NULL;
-  int local_index = 0;
-
-  labcomm_scheduler_data_lock(d->scheduler);
-  LABCOMM_SIGNATURE_ARRAY_FOREACH(d->local, struct sample_entry, i) {
-    struct sample_entry *s;
-    int *remote_to_local;
-
-    result = -ENOENT;
-    s = LABCOMM_SIGNATURE_ARRAY_REF(d->memory, 
-                                    d->local, struct sample_entry, i);
-    if (s->signature &&
-        s->signature->size == signature->size &&
-        strcmp(s->signature->name, signature->name) == 0 &&
-        memcmp((void*)s->signature->signature, (void*)signature->signature,
-	       signature->size) == 0) {
-      s->remote_index = remote_index;
-      local_signature = s->signature;
-      local_index = i;
-      remote_to_local = LABCOMM_SIGNATURE_ARRAY_REF(d->memory,
-                                                    d->remote_to_local, int,
-                                                    remote_index);
-      *remote_to_local = i;
-      result = remote_index;
-      break;
-    }
-  }
-  labcomm_scheduler_data_unlock(d->scheduler);
-  if (local_signature) {
-    labcomm_reader_start(d->reader, d->reader->action_context,
-                         local_index, remote_index, local_signature,
-                         NULL);
-    labcomm_reader_end(d->reader, d->reader->action_context);
-  }
-  return result;
-}
-
-static int handle_sample_ref(struct labcomm_decoder *d, int remote_index,
-                             const struct labcomm_signature *signature)
-{
-  int result;
-  int i;
-
-  labcomm_scheduler_data_lock(d->scheduler);
-  LABCOMM_SIGNATURE_ARRAY_FOREACH(d->local_ref, const struct labcomm_signature *, i) {
-    const struct labcomm_signature *s;
-    int *remote_to_local_ref;
-
-    result = -ENOENT;
-    s = LABCOMM_SIGNATURE_ARRAY_GET(d->local_ref, const struct labcomm_signature *, i, 0);
-    if (s &&
-        s->signature &&
-        s->size == signature->size &&
-        strcmp(s->name, signature->name) == 0 &&
-        memcmp((void*)s->signature, (void*)signature->signature, signature->size) == 0) {
-      remote_to_local_ref = LABCOMM_SIGNATURE_ARRAY_REF(d->memory,
-                                                        d->remote_to_local_ref, int,
-                                                        remote_index);
-      *remote_to_local_ref = i;
-      result = remote_index;
-      break;
-    }
-  }
-  labcomm_scheduler_data_unlock(d->scheduler);
-  return result;
-}
-
-
-static int decode_sample_def_or_ref(struct labcomm_decoder *d, int kind)
-{
-  int result;
-  struct labcomm_signature signature;
-  int i, remote_index;
-
-  remote_index = labcomm_read_packed32(d->reader);
-  if (d->reader->error < 0) {
-    result = d->reader->error;
-    goto out;
-  }
-  signature.name = labcomm_read_string(d->reader);
-  if (d->reader->error < 0) {
-    result = d->reader->error;
-    goto out;
-  }
-  signature.size = labcomm_read_packed32(d->reader);
-  if (d->reader->error < 0) {
-    result = d->reader->error;
-    goto free_signature_name;
-  }
-  signature.signature = labcomm_memory_alloc(d->memory, 1,  signature.size);
-  if (d->reader->error < 0) {
-    result = d->reader->error;
-    goto free_signature_name;
-  }
-  for (i = 0 ; i < signature.size ; i++) {
-    signature.signature[i] = labcomm_read_byte(d->reader);
-    if (d->reader->error < 0) {
-      result = d->reader->error;
-      goto free_signature_signature;
-    }
-  }
-  if (kind == LABCOMM_SAMPLE_DEF) {
-    result = handle_sample_def(d, remote_index, &signature);
-  } else if (kind == LABCOMM_SAMPLE_REF) {
-    result = handle_sample_ref(d, remote_index, &signature);
-    if (result == -ENOENT) {
-      /* Dummy value to silently continue */
-      result = LABCOMM_SAMPLE_REF;
-    }
-  } else {
-    result = -EINVAL;
-  }
-free_signature_signature:
-  labcomm_memory_free(d->memory, 1,  signature.signature);
-free_signature_name:
-  labcomm_memory_free(d->memory, 0, signature.name);
-out:
-  return result;
-}
-
-struct call_handler_context {
-  struct labcomm_reader *reader;
-  int local_index;
-  int remote_index;
-  const struct labcomm_signature *signature;
-  labcomm_handler_function handler;
-  void *context;
-};
-
-static void call_handler(void *value, void *context)
-{
-  struct call_handler_context *wrap = context;
-
-  if (wrap->reader->error >= 0) {
-    labcomm_reader_start(wrap->reader, wrap->reader->action_context,
-			 wrap->local_index, wrap->remote_index, wrap->signature,
-			 value);
-    wrap->handler(value, wrap->context);
-    labcomm_reader_end(wrap->reader, wrap->reader->action_context);
-  }
-}
-
-static void reader_alloc(struct labcomm_decoder *d)
-{
-  if (!d->reader_allocated) {
-    d->reader_allocated = 1;
-    labcomm_reader_alloc(d->reader, d->reader->action_context);
-  }
-}
-
-static int decoder_skip(struct labcomm_decoder *d, int len, int tag)
-{
-  int i;
-  printf("got tag 0x%x, skipping %d bytes\n", tag, len);
-  for(i = 0; i <len; i++){
-    labcomm_read_byte(d->reader);
-    if (d->reader->error < 0) {
-      return d->reader->error;
-    }
-  }
-  return tag;
-}
-/* d        - decoder to read from
-   registry - decoder to lookup signatures (registry != d only if
-                nesting decoders, e.g., when decoding pragma)
-   len      - length of the labcomm packet )
-*/
-static int decode_pragma(struct labcomm_decoder *d,
-		         struct labcomm_decoder *registry,
-		         int len)
-{
-  char *pragma_type;
-  int result;
-  pragma_type = labcomm_read_string(d->reader);
-  if (d->reader->error < 0) {
-    result = d->reader->error;
-    goto out;
-  }
-  int bytes = labcomm_size_string(pragma_type);
-  int psize = len-bytes;
-  result = decoder_skip(d, psize, LABCOMM_PRAGMA);
-out:
-  return result;
-}
-
-static labcomm_decoder_function lookup_h(struct labcomm_decoder *d,
-		                         struct call_handler_context *wrap,
-		                         int remote_index,
-					 int **local_index)
-{
-  labcomm_decoder_function do_decode = NULL;
-  labcomm_scheduler_data_lock(d->scheduler);
-  *local_index = LABCOMM_SIGNATURE_ARRAY_REF(d->memory,
-      				      d->remote_to_local, int,
-      				      remote_index);
-  if (**local_index != 0) {
-    struct sample_entry *entry;
-
-    entry = LABCOMM_SIGNATURE_ARRAY_REF(d->memory,
-      				  d->local, struct sample_entry,
-      				  **local_index);
-    wrap->local_index = **local_index;
-    wrap->signature = entry->signature;
-    wrap->handler = entry->handler;
-    wrap->context = entry->context;
-    do_decode = entry->decode;
-  }
-  labcomm_scheduler_data_unlock(d->scheduler);
-  return do_decode;
-}
-/* d            - decoder to read from
-   registry     - decoder to lookup signatures (registry != d only if
-                    nesting decoders, e.g., when decoding pragma)
-   remote_index -  received type index )
-*/
-static int decode_and_handle(struct labcomm_decoder *d,
-		             struct labcomm_decoder *registry,
-		             int remote_index)
-{
-  int result;
-  int *local_index;
-  struct call_handler_context wrap = {
-    .reader = d->reader,
-    .remote_index = remote_index,
-    .signature = NULL,
-    .handler = NULL,
-    .context = NULL,
-  };
-  labcomm_decoder_function do_decode = lookup_h(registry, &wrap, remote_index, &local_index);
-  result = *local_index;
-  if (do_decode) {
-    do_decode(d->reader, call_handler, &wrap);
-    if (d->reader->error < 0) {
-      result = d->reader->error;
-    }
-  } else {
-    result = -ENOENT;
-  }
-  return result;
-}
-int labcomm_decoder_decode_one(struct labcomm_decoder *d)
-{
-  int result, remote_index, length;
-
-  reader_alloc(d);
-  remote_index = labcomm_read_packed32(d->reader);
-  if (d->reader->error < 0) {
-    result = d->reader->error;
-    goto out;
-  }
-  length = labcomm_read_packed32(d->reader);
-  if (d->reader->error < 0) {
-    result = d->reader->error;
-    goto out;
-  }
-  if (remote_index == LABCOMM_VERSION) {
-    char *version = labcomm_read_string(d->reader);
-    if (d->reader->error < 0) {
-      result = d->reader->error;
-      goto out;
-    }
-    if (strcmp(version, CURRENT_VERSION) == 0) {
-      result = LABCOMM_VERSION;
-      d->version_ok = 1;
-    } else {
-      result = -ECONNRESET;
-    }  
-    labcomm_memory_free(d->memory, 1,  version);
-  } else if (! d->version_ok) {
-    fprintf(stderr, "No VERSION %d %d\n", remote_index, length);
-    result = -ECONNRESET;
-  } else if (remote_index == LABCOMM_SAMPLE_DEF) {
-    result = decode_sample_def_or_ref(d, LABCOMM_SAMPLE_DEF); 
-  } else if (remote_index == LABCOMM_SAMPLE_REF) {
-    result = decode_sample_def_or_ref(d, LABCOMM_SAMPLE_REF); 
-  } else if (remote_index == LABCOMM_PRAGMA) {
-    result = decode_pragma(d, d, length);
-  } else if (remote_index < LABCOMM_USER) {
-    fprintf(stderr, "SKIP %d %d\n", remote_index, length);
-    result = remote_index;
-  } else {
-    result = decode_and_handle(d, d, remote_index);
-  }
-out:   
-  return result;
-}
-
-void labcomm_decoder_run(struct labcomm_decoder *d)
-{
-  while (labcomm_decoder_decode_one(d) > 0) {
-  }
-}
-
-int labcomm_decoder_ioctl(struct labcomm_decoder *d, 
-			  uint32_t action,
-			  ...)
-{
-  int result;  
-  va_list va;
-    
-  va_start(va, action);
-  result = labcomm_reader_ioctl(d->reader, 
-				d->reader->action_context,
-				0, 0, NULL, action, va);
-  va_end(va);
-  return result;
-}
-
-int labcomm_decoder_sample_ref_register(
-  struct labcomm_decoder *d,
-  const struct labcomm_signature *signature)
-{
-  int local_index, *remote_to_local_ref;
-  const struct labcomm_signature **s;
-
-  local_index = labcomm_get_local_index(signature);
-  if (local_index <= 0) { goto out; }
-  labcomm_scheduler_data_lock(d->scheduler);
-  s = LABCOMM_SIGNATURE_ARRAY_REF(d->memory, 
-                                  d->local_ref, 
-                                  const struct labcomm_signature*, local_index);
-  if (s == NULL) { local_index = -ENOMEM; goto unlock; };
-  if (*s) { goto unlock; }
-  *s = signature;	
-  remote_to_local_ref = LABCOMM_SIGNATURE_ARRAY_REF(d->memory, 
-                                                    d->remote_to_local_ref, 
-                                                    int, local_index);
-  *remote_to_local_ref = 0;
-unlock:
-  labcomm_scheduler_data_unlock(d->scheduler);
-out:
-  return local_index;
-}
-
-int labcomm_internal_decoder_ioctl(struct labcomm_decoder *d, 
-				   const struct labcomm_signature *signature,
-				   uint32_t action, va_list va)
-{
-  int result;
-  int local_index, remote_index;
-
-  local_index = labcomm_get_local_index(signature);
-  labcomm_scheduler_data_lock(d->scheduler);
-  remote_index = LABCOMM_SIGNATURE_ARRAY_REF(d->memory,
-					     d->local,
-					     struct sample_entry,
-					     local_index)->remote_index;
-  labcomm_scheduler_data_unlock(d->scheduler);
-  result = labcomm_reader_ioctl(d->reader, d->reader->action_context,
-				local_index, remote_index, 
-				signature, action, va);
-  return result;
-}
-
-int labcomm_internal_decoder_register(
-  struct labcomm_decoder *d,
-  const struct labcomm_signature *signature,
-  labcomm_decoder_function decode, 
-  labcomm_handler_function handler,
-  void *context)
-{
-  int local_index;
-  struct sample_entry *entry;
- 
-  reader_alloc(d);
-  local_index = labcomm_get_local_index(signature);
-  if (local_index <= 0) { goto out; }
-  labcomm_reader_start(d->reader, d->reader->action_context,
-		       local_index, 0, signature,
-		       NULL);
-  labcomm_reader_end(d->reader, d->reader->action_context);
-
-  labcomm_scheduler_data_lock(d->scheduler);
-  entry = LABCOMM_SIGNATURE_ARRAY_REF(d->memory,
-				      d->local, struct sample_entry,
-				      local_index);
-  if (entry == NULL) { local_index = -ENOMEM; goto unlock; }
-  entry->remote_index = 0;
-  entry->signature = signature;
-  entry->decode = decode;
-  entry->handler = handler;
-  entry->context = context;
-unlock:
-  labcomm_scheduler_data_unlock(d->scheduler);
-out:
-  return local_index;
-}
-
-const struct labcomm_signature *labcomm_internal_decoder_index_to_signature(
-  struct labcomm_decoder *d, int index)
-{
-  const struct labcomm_signature *result = 0;
-  int local_index;
-
-  labcomm_scheduler_data_lock(d->scheduler);
-  local_index = LABCOMM_SIGNATURE_ARRAY_GET(d->remote_to_local_ref, 
-                                            int, index, 0);
-  if (local_index) {
-    result = LABCOMM_SIGNATURE_ARRAY_GET(d->local_ref, 
-                                         const struct labcomm_signature*, 
-                                         local_index, 0);
-  }
-  labcomm_scheduler_data_unlock(d->scheduler);
-  return result;
-}
diff --git a/lib/c/2014/labcomm_encoder.c b/lib/c/2014/labcomm_encoder.c
deleted file mode 100644
index 4085bbd38c30a93af55714f54ead443ebaf563a3..0000000000000000000000000000000000000000
--- a/lib/c/2014/labcomm_encoder.c
+++ /dev/null
@@ -1,247 +0,0 @@
-/*
-  labcomm_encoder.c -- handling encoding of labcomm samples.
-
-  Copyright 2006-2013 Anders Blomdell <anders.blomdell@control.lth.se>
-
-  This file is part of LabComm.
-
-  LabComm is free software: you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation, either version 3 of the License, or
-  (at your option) any later version.
-
-  LabComm is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-#define CURRENT_VERSION "LabComm2014"
-
-#include <errno.h>
-#include "labcomm.h"
-#include "labcomm_private.h"
-#include "labcomm_ioctl.h"
-
-struct labcomm_encoder {
-  struct labcomm_writer *writer;
-  struct labcomm_error_handler *error;
-  struct labcomm_memory *memory;
-  struct labcomm_scheduler *scheduler;
-  LABCOMM_SIGNATURE_ARRAY_DEF(registered, int);
-  LABCOMM_SIGNATURE_ARRAY_DEF(sample_ref, int);
-};
-
-struct labcomm_encoder *labcomm_encoder_new(
-  struct labcomm_writer *writer,
-  struct labcomm_error_handler *error,
-  struct labcomm_memory *memory,
-  struct labcomm_scheduler *scheduler)
-{
-  struct labcomm_encoder *result;
-
-  result = labcomm_memory_alloc(memory, 0, sizeof(*result));
-  if (result) {
-    int length;
-
-    result->writer = writer;
-    result->writer->encoder = result;
-    result->writer->data = NULL;
-    result->writer->data_size = 0;
-    result->writer->count = 0;
-    result->writer->pos = 0;
-    result->writer->error = 0;
-    result->error = error;
-    result->memory = memory;
-    result->scheduler = scheduler;
-    LABCOMM_SIGNATURE_ARRAY_INIT(result->registered, int);
-    LABCOMM_SIGNATURE_ARRAY_INIT(result->sample_ref, int);
-    labcomm_writer_alloc(result->writer,
-			 result->writer->action_context);
-    labcomm_writer_start(result->writer, 
-                         result->writer->action_context, 
-                         LABCOMM_VERSION, NULL, CURRENT_VERSION);
-    labcomm_write_packed32(result->writer, LABCOMM_VERSION);
-#ifdef LENGTH_INCL_TAG    
-    length = (labcomm_size_packed32(LABCOMM_VERSION) +
-              labcomm_size_string(CURRENT_VERSION));
-#else
-    length = labcomm_size_string(CURRENT_VERSION);
-#endif
-    labcomm_write_packed32(result->writer, length);
-    labcomm_write_string(result->writer, CURRENT_VERSION);
-    labcomm_writer_end(result->writer, result->writer->action_context);
-  }
-  return result;
-}
-
-void labcomm_encoder_free(struct labcomm_encoder* e)
-{
-  struct labcomm_memory *memory = e->memory;
-
-  labcomm_writer_free(e->writer, e->writer->action_context);
-  LABCOMM_SIGNATURE_ARRAY_FREE(e->memory, e->registered, int);
-  LABCOMM_SIGNATURE_ARRAY_FREE(e->memory, e->sample_ref, int);
-  labcomm_memory_free(memory, 0, e);
-}
-
-int labcomm_internal_encoder_register(
-  struct labcomm_encoder *e,
-  const struct labcomm_signature *signature,
-  labcomm_encoder_function encode)
-{
-  int result = -EINVAL;
-  int index, *done, err, i, length;
-
-  index = labcomm_get_local_index(signature);
-  labcomm_scheduler_writer_lock(e->scheduler);
-  if (index <= 0) { goto out; }
-  done = LABCOMM_SIGNATURE_ARRAY_REF(e->memory, e->registered, int, index);
-  if (*done) { goto out; }
-  *done = 1;	
-  err = labcomm_writer_start(e->writer, e->writer->action_context, 
-			     index, signature, NULL);
-  if (err == -EALREADY) { result = 0; goto out; }
-  if (err != 0) { result = err; goto out; }
-  labcomm_write_packed32(e->writer, LABCOMM_SAMPLE_DEF);
-  length = (labcomm_size_packed32(index) +
-            labcomm_size_string(signature->name) +
-            labcomm_size_packed32(signature->size) +
-            signature->size);
-  labcomm_write_packed32(e->writer, length);
-  labcomm_write_packed32(e->writer, index);
-  labcomm_write_string(e->writer, signature->name);
-  labcomm_write_packed32(e->writer, signature->size);
-  for (i = 0 ; i < signature->size ; i++) {
-    if (e->writer->pos >= e->writer->count) {
-      labcomm_writer_flush(e->writer, e->writer->action_context);
-    }
-    e->writer->data[e->writer->pos] = signature->signature[i];
-    e->writer->pos++;
-  }
-  labcomm_writer_end(e->writer, e->writer->action_context);
-  result = e->writer->error;
-out:
-  labcomm_scheduler_writer_unlock(e->scheduler);
-  return result;
-}
-
-int labcomm_internal_encode(
-  struct labcomm_encoder *e,
-  const struct labcomm_signature *signature,
-  labcomm_encoder_function encode,
-  void *value)
-{
-  int result, index, length;
-
-  index = labcomm_get_local_index(signature);
-  length = (signature->encoded_size(value));
-  labcomm_scheduler_writer_lock(e->scheduler);
-  result = labcomm_writer_start(e->writer, e->writer->action_context, 
-				index, signature, value);
-  if (result == -EALREADY) { result = 0; goto no_end; }
-  if (result != 0) { goto out; }
-  result = labcomm_write_packed32(e->writer, index);
-  result = labcomm_write_packed32(e->writer, length);
-  if (result != 0) { goto out; }
-  result = encode(e->writer, value);
-out:
-  labcomm_writer_end(e->writer, e->writer->action_context);
-no_end:
-  labcomm_scheduler_writer_unlock(e->scheduler);
-  return result;
-}
-
-int labcomm_encoder_sample_ref_register(
-  struct labcomm_encoder *e,
-  const struct labcomm_signature *signature)
-{
-  int result = -EINVAL;
-  int index, *done, err, i, length;
-
-  index = labcomm_get_local_index(signature);
-  labcomm_scheduler_writer_lock(e->scheduler);
-  if (index <= 0) { goto out; }
-
-  done = LABCOMM_SIGNATURE_ARRAY_REF(e->memory, e->sample_ref, int, index);
-  if (*done) { goto out; }
-  *done = 1;	
-  err = labcomm_writer_start(e->writer, e->writer->action_context, 
-			     index, signature, NULL);
-  if (err == -EALREADY) { result = 0; goto out; }
-  if (err != 0) { result = err; goto out; }
-  labcomm_write_packed32(e->writer, LABCOMM_SAMPLE_REF);
-  length = (labcomm_size_packed32(index) +
-            labcomm_size_string(signature->name) +
-            labcomm_size_packed32(signature->size) +
-            signature->size);
-  labcomm_write_packed32(e->writer, length);
-  labcomm_write_packed32(e->writer, index);
-  labcomm_write_string(e->writer, signature->name);
-  labcomm_write_packed32(e->writer, signature->size);
-  for (i = 0 ; i < signature->size ; i++) {
-    if (e->writer->pos >= e->writer->count) {
-      labcomm_writer_flush(e->writer, e->writer->action_context);
-    }
-    e->writer->data[e->writer->pos] = signature->signature[i];
-    e->writer->pos++;
-  }
-  labcomm_writer_end(e->writer, e->writer->action_context);
-  result = e->writer->error;
-out:
-  labcomm_scheduler_writer_unlock(e->scheduler);
-  return result;
-}
-
-int labcomm_encoder_ioctl(struct labcomm_encoder *encoder, 
-			  uint32_t action,
-			  ...)
-{
-  int result;
-  va_list va;
-  
-  if (LABCOMM_IOC_SIG(action) != LABCOMM_IOC_NOSIG) {
-    result = -EINVAL;
-    goto out;
-  }
-  
-  va_start(va, action);
-  result = labcomm_writer_ioctl(encoder->writer, 
-			       encoder->writer->action_context,
-			       0, NULL, action, va);
-  va_end(va);
-
-out:
-  return result;
-}
-
-int labcomm_internal_encoder_ioctl(struct labcomm_encoder *encoder, 
-				   const struct labcomm_signature *signature,
-				   uint32_t action, va_list va)
-{
-  int result = -ENOTSUP;
-  int index;
-
-  index = labcomm_get_local_index(signature);
-  result = labcomm_writer_ioctl(encoder->writer, 
-				encoder->writer->action_context, 
-				index, signature, action, va);
-  return result;
-}
-
-int labcomm_internal_encoder_signature_to_index(
-  struct labcomm_encoder *e, const struct labcomm_signature *signature)
-{
-  /* writer_lock should be held at this point */
-  int index = 0;
-  if (signature != NULL) {
-    index = labcomm_get_local_index(signature);
-    if (! LABCOMM_SIGNATURE_ARRAY_GET(e->sample_ref, int, index, 0)) {
-      index = 0;
-    }
-  }
-  return index;
-}
-
diff --git a/lib/c/2014/labcomm_error.h b/lib/c/2014/labcomm_error.h
deleted file mode 100644
index 80e4805d96c071967d3be7b964c2d549e304f6ef..0000000000000000000000000000000000000000
--- a/lib/c/2014/labcomm_error.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
-  labcomm_error.h -- labcomm error declarations
-
-  Copyright 2013 Anders Blomdell <anders.blomdell@control.lth.se>
-
-  This file is part of LabComm.
-
-  LabComm is free software: you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation, either version 3 of the License, or
-  (at your option) any later version.
-
-  LabComm is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef __LABCOMM_ERROR_H__
-#define __LABCOMM_ERROR_H__
-
-enum labcomm_error {
-#define LABCOMM_ERROR(name, description) name ,
-#include "labcomm_error.h"
-#undef LABCOMM_ERROR
-};
-
-struct labcomm_error_handler;
-
-void labcomm_error_warning(struct labcomm_error_handler *e,
-			   enum labcomm_error,
-			   char *format,
-			   ...);
-			 
-void labcomm_error_fatal_global(enum labcomm_error error,
-				char *format,
-				...);
-			 
-#endif
-
-#ifdef LABCOMM_ERROR
-
-LABCOMM_ERROR(LABCOMM_ERROR_SIGNATURE_ALREADY_SET, 
-	      "Signature has already been set")
-LABCOMM_ERROR(LABCOMM_ERROR_SIGNATURE_NOT_SET, 
-	      "Signature has not been set")
-
-LABCOMM_ERROR(LABCOMM_ERROR_ENC_NO_REG_SIGNATURE, 
-	      "Encoder has no registration for this signature")
-LABCOMM_ERROR(LABCOMM_ERROR_ENC_BUF_FULL,
-	      "The labcomm buffer is full")
-LABCOMM_ERROR(LABCOMM_ERROR_DEC_UNKNOWN_DATATYPE,
-	      "Decoder: Unknown datatype")
-LABCOMM_ERROR(LABCOMM_ERROR_DEC_INDEX_MISMATCH, 
-	      "Decoder: index mismatch")
-LABCOMM_ERROR(LABCOMM_ERROR_DEC_TYPE_NOT_FOUND,
-	      "Decoder: type not found")
-LABCOMM_ERROR(LABCOMM_ERROR_UNIMPLEMENTED_FUNC,
-	      "This function is not yet implemented")
-LABCOMM_ERROR(LABCOMM_ERROR_MEMORY,
-	      "Could not allocate memory")
-LABCOMM_ERROR(LABCOMM_ERROR_USER_DEF,     
-	      "User defined error")
-LABCOMM_ERROR(LABCOMM_ERROR_BAD_WRITER,
-	      "Decoder: writer_ioctl() failed")
-
-#endif
diff --git a/lib/c/2014/labcomm_scheduler_private.h b/lib/c/2014/labcomm_scheduler_private.h
deleted file mode 100644
index 398552e0e434f17b4f332364ce09256dcb4d682c..0000000000000000000000000000000000000000
--- a/lib/c/2014/labcomm_scheduler_private.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
-  labcomm_scheduler.h -- labcomm task coordination, semi-private part
-
-  Copyright 2013 Anders Blomdell <anders.blomdell@control.lth.se>
-
-  This file is part of LabComm.
-
-  LabComm is free software: you can redistribute it and/or modify
-  it under the terms of the GNU General Public License as published by
-  the Free Software Foundation, either version 3 of the License, or
-  (at your option) any later version.
-
-  LabComm is distributed in the hope that it will be useful,
-  but WITHOUT ANY WARRANTY; without even the implied warranty of
-  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-  GNU General Public License for more details.
-
-  You should have received a copy of the GNU General Public License
-  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifndef _LABCOMM_SCHEDULER_PRIVATE_H_
-#define _LABCOMM_SCHEDULER_PRIVATE_H_
-
-#ifdef LABCOMM_COMPAT
-  #include LABCOMM_COMPAT
-#else
-  #include <unistd.h>
-#endif
-
-#include "labcomm_scheduler.h"
-
-struct labcomm_time {
-  const struct labcomm_time_action {
-    int (*free)(struct labcomm_time *t);
-    int (*add_usec)(struct labcomm_time *t, uint32_t usec);
-  } *action;
-  void *context;
-};
-
-struct labcomm_scheduler {
-  const struct labcomm_scheduler_action {
-    int (*free)(struct labcomm_scheduler *s);
-    int (*writer_lock)(struct labcomm_scheduler *s);
-    int (*writer_unlock)(struct labcomm_scheduler *s);
-    int (*data_lock)(struct labcomm_scheduler *s);
-    int (*data_unlock)(struct labcomm_scheduler *s);
-    struct labcomm_time *(*now)(struct labcomm_scheduler *s);
-    int (*sleep)(struct labcomm_scheduler *s,
-		 struct labcomm_time *wakeup);
-    int (*wakeup)(struct labcomm_scheduler *s);
-    int (*enqueue)(struct labcomm_scheduler *s,
-		   uint32_t delay,
-		   void (*deferred)(void *context),
-		   void *context);
-  } *action;
-  void *context;
-};
-
-#endif
diff --git a/lib/c/2014/test/.gitignore b/lib/c/2014/test/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..4f62b849d56cd043cb9725fe73e9f49522d3d931
--- /dev/null
+++ b/lib/c/2014/test/.gitignore
@@ -0,0 +1 @@
+gen
diff --git a/lib/c/2014/test/generated_encoding.lc b/lib/c/2014/test/generated_encoding.lc
index e561abee3d5bacbdd502fed94a013ed829bfe46f..e2de7133de344c45f3154811613028bd14f78a05 100644
--- a/lib/c/2014/test/generated_encoding.lc
+++ b/lib/c/2014/test/generated_encoding.lc
@@ -1,4 +1,6 @@
-sample void V;
+typedef void unused_t;
+typedef void v_t;
+sample v_t V;
 sample byte B;
 sample struct {
   int i;
diff --git a/lib/c/2014/test/test_labcomm.c b/lib/c/2014/test/test_labcomm.c
index e37950e612d3ffb38c08bdec4b31c0325cb851a7..de36a7f4a34905a20360c272bf8f27c0d703593e 100644
--- a/lib/c/2014/test/test_labcomm.c
+++ b/lib/c/2014/test/test_labcomm.c
@@ -1,5 +1,5 @@
 /*
-  test_labcomm.c -- Various labcomm tests
+  test_labcomm2014.c -- Various labcomm2014 tests
 
   Copyright 2013 Anders Blomdell <anders.blomdell@control.lth.se>
 
@@ -24,16 +24,54 @@
 #include <string.h>
 #include <stdlib.h>
 #include <errno.h>
-#include "labcomm_private.h"
-#include "labcomm_default_error_handler.h"
-#include "labcomm_default_memory.h"
-#include "labcomm_default_scheduler.h"
+#include "labcomm2014_private.h"
+#include "labcomm2014_default_error_handler.h"
+#include "labcomm2014_default_memory.h"
+#include "labcomm2014_default_scheduler.h"
 #include "test/gen/test_sample.h"
 
+static struct labcomm2014_writer writer;
+
+static struct expect {
+  char *description;
+  int result;
+  int (*trampoline)(struct labcomm2014_decoder *context);
+  struct labcomm2014_decoder *context;
+} *expect;
+
+static void check_expect()
+{
+  struct expect *p = expect;
+
+  {
+    int i;
+    for (i = 0 ; i < writer.pos ; i++) {
+      fprintf(stderr, "%02x ", writer.data[i]);
+    }
+    fprintf(stderr, "\n");
+  }
+  if (p && p->trampoline) {
+    int err;
+    
+    expect = p + 1;
+    fprintf(stderr, "Checking '%s' expected=%d ", p->description, p->result);
+    err = p->trampoline(p->context);
+    fprintf(stderr, "actual=%d\n", err);
+    if (p->result >= 0 && p->result != err) {
+      fprintf(stderr, "FAILED\n");
+      exit(1);
+    } else if (err == 0) {
+      fprintf(stderr, "FAILED (unexpected 0)\n");
+      exit(1);
+    }
+    writer.pos = 0;
+  }
+}
+
 static unsigned char buffer[512];
 
-static int writer_alloc(struct labcomm_writer *w, 
-			struct labcomm_writer_action_context *action_context)
+static int writer_alloc(struct labcomm2014_writer *w, 
+			struct labcomm2014_writer_action_context *action_context)
 {
   w->data = buffer;
   w->data_size = sizeof(buffer);
@@ -41,23 +79,36 @@ static int writer_alloc(struct labcomm_writer *w,
   
   return 0;
 }
-static int writer_start(struct labcomm_writer *w, 
-			 struct labcomm_writer_action_context *action_context,
-			 int index, const struct labcomm_signature *signature,
+
+static int writer_start(struct labcomm2014_writer *w, 
+			 struct labcomm2014_writer_action_context *action_context,
+			 int index, const struct labcomm2014_signature *signature,
 			 void *value)
 {
   return 0;
 }
-const struct labcomm_writer_action writer_action = {
+
+static int buf_writer_end(
+  struct labcomm2014_writer *w, 
+  struct labcomm2014_writer_action_context *action_context)
+{
+  check_expect();
+  return 0;
+}
+
+const struct labcomm2014_writer_action writer_action = {
   .alloc = writer_alloc,
   .start = writer_start,
+  .end = buf_writer_end,
 };
-static struct labcomm_writer_action_context writer_action_context = {
+
+static struct labcomm2014_writer_action_context writer_action_context = {
   .next = NULL,
   .action = &writer_action,
   .context = NULL
 }; 
-static struct labcomm_writer writer =  {
+
+static struct labcomm2014_writer writer =  {
   .action_context = &writer_action_context,
   .data = buffer,
   .data_size = sizeof(buffer),
@@ -66,32 +117,36 @@ static struct labcomm_writer writer =  {
   .error = 0,
 };
 
-static int reader_alloc(struct labcomm_reader *r, 
-			struct labcomm_reader_action_context *action_context)
+static int reader_alloc(struct labcomm2014_reader *r, 
+			struct labcomm2014_reader_action_context *action_context)
 {
   r->data = buffer;
   r->data_size = sizeof(buffer);
   r->count = 0;
-  r->memory = labcomm_default_memory;
+  r->memory = labcomm2014_default_memory;
   
   return 0;
 }
-static int reader_fill(struct labcomm_reader *r, 
-		       struct labcomm_reader_action_context *action_context)
+
+static int reader_fill(struct labcomm2014_reader *r, 
+		       struct labcomm2014_reader_action_context *action_context)
 {
   r->error = -ENOMEM;
   return r->error;
 }
-const struct labcomm_reader_action reader_action = {
+
+const struct labcomm2014_reader_action reader_action = {
   .alloc = reader_alloc,
   .fill = reader_fill,
 };
-static struct labcomm_reader_action_context reader_action_context = {
+
+static struct labcomm2014_reader_action_context reader_action_context = {
   .next = NULL,
   .action = &reader_action,
   .context = NULL
 }; 
-static struct labcomm_reader reader =  {
+
+static struct labcomm2014_reader reader =  {
   .action_context = &reader_action_context,
   .data = buffer,
   .data_size = sizeof(buffer),
@@ -106,6 +161,7 @@ static test_sample_test_var encoder_var = {
   .n_2 = 1,
   .a = encoder_data,
 };
+
 static int32_t decoder_data[256];
 static test_sample_test_var decoder_var = {
   .n_0 = 1,
@@ -118,34 +174,35 @@ void handle_test_var(test_sample_test_var *v, void *ctx)
   decoder_var.a[0] = v->a[0];  
 }
 
-int test_decode_one(struct labcomm_decoder *decoder)
+int test_decode_one(struct labcomm2014_decoder *decoder)
 {
   int result;
 
   for (reader.count = 0 ; reader.count < writer.pos ; reader.count++) {
     reader.error = 0;
     reader.pos = 0;
-    result = labcomm_decoder_decode_one(decoder); 
+    result = labcomm2014_decoder_decode_one(decoder); 
     if (result >= 0 ) {
-      fprintf(stderr, "Got result from buffer with bogus length (%d)\n",
-	      result);
+      fprintf(stderr,
+              "Got result from buffer with bogus length (%d, %d != %d)\n",
+	      result, reader.count, writer.pos);
       exit(1);
     }
   }
   reader.error = 0;
   reader.pos = 0;
   reader.count = writer.pos;
-  result = labcomm_decoder_decode_one(decoder);
+  result = labcomm2014_decoder_decode_one(decoder);
   if (result < 0) {
-    fprintf(stderr, "Got result from buffer with correct length (%d)\n",
+    fprintf(stderr, "Got no result from buffer with correct length (%d)\n",
 	    result);
     exit(1);
   }
   return result;
 }
 
-static void test_encode_decode(struct labcomm_encoder *encoder,
-			       struct labcomm_decoder *decoder,
+static void test_encode_decode(struct labcomm2014_encoder *encoder,
+			       struct labcomm2014_decoder *decoder,
 			       int expected, uint32_t n_0, uint32_t n_2)
 {
   int err;
@@ -154,14 +211,14 @@ static void test_encode_decode(struct labcomm_encoder *encoder,
   encoder_var.n_0 = n_0;
   encoder_var.n_2 = n_2;
   encoder_var.a[0] = 314;
-  labcomm_encode_test_sample_test_var(encoder, &encoder_var);
+  labcomm2014_encode_test_sample_test_var(encoder, &encoder_var);
   err = test_decode_one(decoder);
   fprintf(stderr, "decode of sample %u * 2 * %u -> size=%d err=%d\n", 
 	  n_0, n_2, writer.pos, err);
-  if (writer.pos != labcomm_sizeof_test_sample_test_var(&encoder_var)) {
+  if (writer.pos != labcomm2014_sizeof_test_sample_test_var(&encoder_var)) {
     fprintf(stderr, "Incorrect sizeof %u * 2 * %u (%d != %d)\n",
 	    n_0, n_2, 
-	    writer.pos, labcomm_sizeof_test_sample_test_var(&encoder_var));
+	    writer.pos, labcomm2014_sizeof_test_sample_test_var(&encoder_var));
     exit(1);
   }
   if (writer.pos != expected) {
@@ -174,26 +231,35 @@ static void test_encode_decode(struct labcomm_encoder *encoder,
 
 int main(void)
 {
-  int err, i;
-  struct labcomm_encoder *encoder = labcomm_encoder_new(
-    &writer, 
-    labcomm_default_error_handler,
-    labcomm_default_memory,
-    labcomm_default_scheduler);
-  struct labcomm_decoder *decoder = labcomm_decoder_new(
+  int i;
+  struct labcomm2014_decoder *decoder = labcomm2014_decoder_new(
     &reader,
-    labcomm_default_error_handler,
-    labcomm_default_memory,
-    labcomm_default_scheduler);
-  err = test_decode_one(decoder);
-  fprintf(stderr, "decode of version -> index %d\n", err);
-  writer.pos = 0;
-  labcomm_decoder_register_test_sample_test_var(decoder,
+    labcomm2014_default_error_handler,
+    labcomm2014_default_memory,
+    labcomm2014_default_scheduler);
+  struct expect expect_version[] = {
+    { "Version", 1, test_decode_one, decoder },
+    { 0, 0, 0 }
+  };
+  expect = expect_version;
+  struct labcomm2014_encoder *encoder = labcomm2014_encoder_new(
+    &writer, 
+    labcomm2014_default_error_handler,
+    labcomm2014_default_memory,
+    labcomm2014_default_scheduler);
+  labcomm2014_decoder_register_test_sample_test_var(decoder,
 						handle_test_var, 
 						NULL);
-  labcomm_encoder_register_test_sample_test_var(encoder);
-  err = test_decode_one(decoder);
-  fprintf(stderr, "decode of register -> index %d\n", err);
+  struct expect expect_registration[] = {
+    { "Sampledef", -1, test_decode_one, decoder },
+#ifdef SHOULD_THIS_BE_REMOVED
+    { "Typedef", -1, test_decode_one, decoder },
+#endif
+    { "Binding", -1, test_decode_one, decoder },
+    { 0, 0, 0 }
+  };
+  expect = expect_registration;
+  labcomm2014_encoder_register_test_sample_test_var(encoder);
   test_encode_decode(encoder, decoder, 12, 1, 1);
   if (decoder_var.a[0] != encoder_var.a[0]) {
     fprintf(stderr, "Failed to decode correct value %d != %d\n", 
diff --git a/lib/c/2014/test/test_labcomm_basic_type_encoding.c b/lib/c/2014/test/test_labcomm_basic_type_encoding.c
index b964c9890b4cef2ad1d89d43198f1bd4ebdc8a54..29079df684b8f919a2ee15e8ca1992672d3db0f6 100644
--- a/lib/c/2014/test/test_labcomm_basic_type_encoding.c
+++ b/lib/c/2014/test/test_labcomm_basic_type_encoding.c
@@ -1,5 +1,5 @@
 /*
-  test_labcomm_basic_type_encoding.c -- LabComm tests of basic encoding
+  test_labcomm2014_basic_type_encoding.c -- LabComm tests of basic encoding
 
   Copyright 2013 Anders Blomdell <anders.blomdell@control.lth.se>
 
@@ -23,13 +23,13 @@
 #include <inttypes.h>
 #include <string.h>
 #include <stdlib.h>
-#include "labcomm_private.h"
+#include "labcomm2014_private.h"
 
 static int line;
 
 static unsigned char buffer[128];
 
-static struct labcomm_writer writer =  {
+static struct labcomm2014_writer writer =  {
   .action_context = NULL,
   .data = buffer,
   .data_size = sizeof(buffer),
@@ -38,7 +38,7 @@ static struct labcomm_writer writer =  {
   .error = 0,
 };
 
-static struct labcomm_reader reader =  {
+static struct labcomm2014_reader reader =  {
   .action_context = NULL,
   .data = buffer,
   .data_size = sizeof(buffer),
@@ -53,11 +53,11 @@ typedef uint32_t packed32;
     type decoded;							\
     line = __LINE__;							\
     writer.pos = 0;							\
-    labcomm_write_##ltype(&writer, value);				\
+    labcomm2014_write_##ltype(&writer, value);				\
     writer_assert(#ltype, expect_count, (uint8_t*)expect_bytes);	\
     reader.count = writer.pos;						\
     reader.pos = 0;							\
-    decoded = labcomm_read_##ltype(&reader);				\
+    decoded = labcomm2014_read_##ltype(&reader);				\
     if (decoded != value) {						\
       fprintf(stderr, "Decode error" format " != " format " @%s:%d \n", \
 	      value, decoded, __FILE__, __LINE__);					\
diff --git a/lib/c/2014/test/test_labcomm_copy.c b/lib/c/2014/test/test_labcomm_copy.c
index 728195582a491be649adcb05c4aaa3c930456f69..d26ef966ab7a318fa108ba79c1e9017fadd4a567 100644
--- a/lib/c/2014/test/test_labcomm_copy.c
+++ b/lib/c/2014/test/test_labcomm_copy.c
@@ -7,13 +7,13 @@
 #include <assert.h>
 #include <err.h>
 
-#include "labcomm.h"
-#include "labcomm_private.h"
-#include "labcomm_default_error_handler.h"
-#include "labcomm_default_memory.h"
-#include "labcomm_default_scheduler.h"
-#include "labcomm_fd_writer.h"
-#include "labcomm_fd_reader.h"
+#include "labcomm2014.h"
+#include "labcomm2014_private.h"
+#include "labcomm2014_default_error_handler.h"
+#include "labcomm2014_default_memory.h"
+#include "labcomm2014_default_scheduler.h"
+#include "labcomm2014_fd_writer.h"
+#include "labcomm2014_fd_reader.h"
 #include "test/gen/generated_encoding.h"
 #include "test/gen/test_sample.h"
 #include "test/gen/more_types.h"
@@ -22,58 +22,58 @@
 
 static void handle_s1(generated_encoding_S1 *v, void *context)
 {
-  labcomm_copy_generated_encoding_S1(labcomm_default_memory, context, v);
+  labcomm2014_copy_generated_encoding_S1(labcomm2014_default_memory, context, v);
 }
 
 static void handle_b(generated_encoding_B *v, void *context)
 {
-  labcomm_copy_generated_encoding_B(labcomm_default_memory, context, v);
+  labcomm2014_copy_generated_encoding_B(labcomm2014_default_memory, context, v);
 }
 
 static void handle_i(generated_encoding_I *v, void *context)
 {
-  labcomm_copy_generated_encoding_I(labcomm_default_memory, context, v);
+  labcomm2014_copy_generated_encoding_I(labcomm2014_default_memory, context, v);
 }
 
 static void handle_p(generated_encoding_P *v, void *context)
 {
-  labcomm_copy_generated_encoding_P(labcomm_default_memory, context, v);
+  labcomm2014_copy_generated_encoding_P(labcomm2014_default_memory, context, v);
 }
 
 static void handle_r(generated_encoding_R *v, void *context)
 {
-  labcomm_copy_generated_encoding_R(labcomm_default_memory, context, v);
+  labcomm2014_copy_generated_encoding_R(labcomm2014_default_memory, context, v);
 }
 
 static void handle_test_var(test_sample_test_var *v, void *context)
 {
-  labcomm_copy_test_sample_test_var(labcomm_default_memory, context, v);
+  labcomm2014_copy_test_sample_test_var(labcomm2014_default_memory, context, v);
 }
 
 static void handle_a(more_types_A *v, void *context)
 {
-  labcomm_copy_more_types_A(labcomm_default_memory, context, v);
+  labcomm2014_copy_more_types_A(labcomm2014_default_memory, context, v);
 }
 
 static void handle_s(more_types_S *v, void *context)
 {
-  labcomm_copy_more_types_S(labcomm_default_memory, context, v);
+  labcomm2014_copy_more_types_S(labcomm2014_default_memory, context, v);
 }
 
 static void handle_ns(more_types_NS *v, void *context)
 {
-  labcomm_copy_more_types_NS(labcomm_default_memory, context, v);
+  labcomm2014_copy_more_types_NS(labcomm2014_default_memory, context, v);
 }
 
 static void handle_as(more_types_AS *v, void *context)
 {
-  labcomm_copy_more_types_AS(labcomm_default_memory, context, v);
+  labcomm2014_copy_more_types_AS(labcomm2014_default_memory, context, v);
 }
 
 int main(int argc, char **argv)
 {
-  struct labcomm_encoder *encoder;
-  struct labcomm_decoder *decoder;
+  struct labcomm2014_encoder *encoder;
+  struct labcomm2014_decoder *decoder;
   int fd;
   generated_encoding_S1 s1;
   generated_encoding_S1 cache_s1;
@@ -100,35 +100,35 @@ int main(int argc, char **argv)
   if (fd == -1)
     err(1, "open()");
   encoder =
-    labcomm_encoder_new(labcomm_fd_writer_new(labcomm_default_memory, fd, 0),
-			labcomm_default_error_handler,
-			labcomm_default_memory,
-			labcomm_default_scheduler);
+    labcomm2014_encoder_new(labcomm2014_fd_writer_new(labcomm2014_default_memory, fd, 0),
+			labcomm2014_default_error_handler,
+			labcomm2014_default_memory,
+			labcomm2014_default_scheduler);
 
-  labcomm_encoder_register_generated_encoding_S1(encoder);
+  labcomm2014_encoder_register_generated_encoding_S1(encoder);
   s1.i = 1;
-  labcomm_encode_generated_encoding_S1(encoder, &s1);
+  labcomm2014_encode_generated_encoding_S1(encoder, &s1);
 
-  labcomm_encoder_register_generated_encoding_B(encoder);
+  labcomm2014_encoder_register_generated_encoding_B(encoder);
   b = 2;
-  labcomm_encode_generated_encoding_B(encoder, &b);
+  labcomm2014_encode_generated_encoding_B(encoder, &b);
 
-  labcomm_encoder_register_generated_encoding_I(encoder);
+  labcomm2014_encoder_register_generated_encoding_I(encoder);
   I.n_0 = 3;
   I.a = calloc(I.n_0, sizeof(I.a[0]));
   I.a[0] = 4;
   I.a[1] = 5;
   I.a[2] = 6;
-  labcomm_encode_generated_encoding_I(encoder, &I);
+  labcomm2014_encode_generated_encoding_I(encoder, &I);
 
-  labcomm_encoder_register_generated_encoding_P(encoder);
+  labcomm2014_encoder_register_generated_encoding_P(encoder);
   p.n_0 = 7;
   p.a = calloc(p.n_0, sizeof(p.a[0]));
   for (int i = 0; i < p.n_0; i++)
     p.a[i].i = 8 + i;
-  labcomm_encode_generated_encoding_P(encoder, &p);
+  labcomm2014_encode_generated_encoding_P(encoder, &p);
 
-  labcomm_encoder_register_test_sample_test_var(encoder);
+  labcomm2014_encoder_register_test_sample_test_var(encoder);
   test_var.n_0 = 2;
   test_var.n_2 = 7;
   test_var.a = calloc(test_var.n_0 * 2 * test_var.n_2, sizeof(*test_var.a));
@@ -137,68 +137,69 @@ int main(int argc, char **argv)
       for (int k = 0; k < test_var.n_2; k++) {
         test_var.a[(((i) * 2 + j) * test_var.n_2) + k] = 100 * i + 10 * j + k;
       }
-  labcomm_encode_test_sample_test_var(encoder, &test_var);
+  labcomm2014_encode_test_sample_test_var(encoder, &test_var);
 
-  labcomm_encoder_register_more_types_A(encoder);
+  labcomm2014_encoder_register_more_types_A(encoder);
   for (int i = 0; i < sizeof(a.a) / sizeof(a.a[0]); i++)
     a.a[i] = i;
-  labcomm_encode_more_types_A(encoder, &a);
+  labcomm2014_encode_more_types_A(encoder, &a);
 
-  labcomm_encoder_register_more_types_S(encoder);
+  labcomm2014_encoder_register_more_types_S(encoder);
   s = "this is a string";
-  labcomm_encode_more_types_S(encoder, &s);
+  labcomm2014_encode_more_types_S(encoder, &s);
 
-  labcomm_encoder_register_more_types_NS(encoder);
+  labcomm2014_encoder_register_more_types_NS(encoder);
   ns.s1 = "this is a string";
   ns.s2 = "this is a another string";
-  labcomm_encode_more_types_NS(encoder, &ns);
+  labcomm2014_encode_more_types_NS(encoder, &ns);
 
-  labcomm_encoder_register_more_types_AS(encoder);
+  labcomm2014_encoder_register_more_types_AS(encoder);
   as.n_0 = 3;
   as.a = calloc(as.n_0, sizeof(as.a[0]));
   as.a[0] = "string 0";
   as.a[1] = "string 1";
   as.a[2] = "string 2";
-  labcomm_encode_more_types_AS(encoder, &as);
-
-  labcomm_encoder_register_generated_encoding_R(encoder);
-  labcomm_encoder_sample_ref_register(encoder, labcomm_signature_generated_encoding_V);
-  labcomm_encoder_sample_ref_register(encoder, 
-                                      labcomm_signature_generated_encoding_UnusedD);
-  labcomm_encoder_sample_ref_register(encoder, labcomm_signature_generated_encoding_R);
-  r.a[0] = labcomm_signature_generated_encoding_V;
-  r.a[1] = labcomm_signature_generated_encoding_UnusedE;
-  r.a[2] = labcomm_signature_generated_encoding_UnusedD;
-  r.a[3] = labcomm_signature_generated_encoding_R;
-  labcomm_encode_generated_encoding_R(encoder, &r);
-
-  labcomm_encoder_free(encoder);
+  labcomm2014_encode_more_types_AS(encoder, &as);
+
+  labcomm2014_encoder_register_generated_encoding_R(encoder);
+  labcomm2014_encoder_sample_ref_register(encoder, labcomm2014_signature_generated_encoding_V);
+  labcomm2014_encoder_sample_ref_register(encoder, 
+                                      labcomm2014_signature_generated_encoding_UnusedD);
+  labcomm2014_encoder_sample_ref_register(encoder, labcomm2014_signature_generated_encoding_R);
+  r.a[0] = labcomm2014_signature_generated_encoding_V;
+  r.a[1] = labcomm2014_signature_generated_encoding_UnusedE;
+  r.a[2] = labcomm2014_signature_generated_encoding_UnusedD;
+  r.a[3] = labcomm2014_signature_generated_encoding_R;
+  labcomm2014_encode_generated_encoding_R(encoder, &r);
+
+  labcomm2014_encoder_free(encoder);
   encoder = NULL;
   lseek(fd, 0, SEEK_SET);
   decoder =
-    labcomm_decoder_new(labcomm_fd_reader_new(labcomm_default_memory, fd, 0),
-			labcomm_default_error_handler,
-			labcomm_default_memory,
-			labcomm_default_scheduler);
-
-  labcomm_decoder_register_generated_encoding_S1(decoder, handle_s1, &cache_s1);
-  labcomm_decoder_register_generated_encoding_B(decoder, handle_b, &cache_b);
-  labcomm_decoder_register_generated_encoding_I(decoder, handle_i, &cache_I);
-  labcomm_decoder_register_generated_encoding_P(decoder, handle_p, &cache_p);
-  labcomm_decoder_register_test_sample_test_var(decoder, handle_test_var,
+    labcomm2014_decoder_new(labcomm2014_fd_reader_new(labcomm2014_default_memory, fd, 0),
+			labcomm2014_default_error_handler,
+			labcomm2014_default_memory,
+			labcomm2014_default_scheduler);
+
+  labcomm2014_decoder_register_generated_encoding_S1(decoder, handle_s1, &cache_s1);
+  labcomm2014_decoder_register_generated_encoding_B(decoder, handle_b, &cache_b);
+  labcomm2014_decoder_register_generated_encoding_I(decoder, handle_i, &cache_I);
+  labcomm2014_decoder_register_generated_encoding_P(decoder, handle_p, &cache_p);
+  labcomm2014_decoder_register_test_sample_test_var(decoder, handle_test_var,
 						&cache_test_var);
-  labcomm_decoder_register_more_types_A(decoder, handle_a, &cache_a);
-  labcomm_decoder_register_more_types_S(decoder, handle_s, &cache_s);
-  labcomm_decoder_register_more_types_NS(decoder, handle_ns, &cache_ns);
-  labcomm_decoder_register_more_types_AS(decoder, handle_as, &cache_as);
-  labcomm_decoder_register_generated_encoding_R(decoder, handle_r, &cache_r);
-  labcomm_decoder_sample_ref_register(decoder, labcomm_signature_generated_encoding_V);
-  labcomm_decoder_sample_ref_register(decoder, 
-                                      labcomm_signature_generated_encoding_UnusedE);
-  labcomm_decoder_sample_ref_register(decoder, labcomm_signature_generated_encoding_R);
-
-  while (labcomm_decoder_decode_one(decoder) > 0) ;
-
+  labcomm2014_decoder_register_more_types_A(decoder, handle_a, &cache_a);
+  labcomm2014_decoder_register_more_types_S(decoder, handle_s, &cache_s);
+  labcomm2014_decoder_register_more_types_NS(decoder, handle_ns, &cache_ns);
+  labcomm2014_decoder_register_more_types_AS(decoder, handle_as, &cache_as);
+  labcomm2014_decoder_register_generated_encoding_R(decoder, handle_r, &cache_r);
+  labcomm2014_decoder_sample_ref_register(decoder, labcomm2014_signature_generated_encoding_V);
+  labcomm2014_decoder_sample_ref_register(decoder, 
+                                      labcomm2014_signature_generated_encoding_UnusedE);
+  labcomm2014_decoder_sample_ref_register(decoder, labcomm2014_signature_generated_encoding_R);
+
+  while (labcomm2014_decoder_decode_one(decoder) > 0) ;
+
+  printf("cache_s1.i = %d, s1.i = %d\n", cache_s1.i, s1.i);
   assert(cache_s1.i == s1.i);
   puts("S1 copied ok");
 
@@ -257,26 +258,26 @@ int main(int argc, char **argv)
   assert(cache_r.a[3] == r.a[3]);
   puts("R copied ok");
 
-  labcomm_decoder_free(decoder);
+  labcomm2014_decoder_free(decoder);
   close(fd);
   unlink(DATA_FILE);
 
-  labcomm_copy_free_generated_encoding_S1(labcomm_default_memory, &cache_s1);
+  labcomm2014_copy_free_generated_encoding_S1(labcomm2014_default_memory, &cache_s1);
   puts("S1 deallocated ok");
-  labcomm_copy_free_generated_encoding_B(labcomm_default_memory, &cache_b);
+  labcomm2014_copy_free_generated_encoding_B(labcomm2014_default_memory, &cache_b);
   puts("B deallocated ok");
-  labcomm_copy_free_generated_encoding_I(labcomm_default_memory, &cache_I);
+  labcomm2014_copy_free_generated_encoding_I(labcomm2014_default_memory, &cache_I);
   puts("I deallocated ok");
-  labcomm_copy_free_generated_encoding_P(labcomm_default_memory, &cache_p);
+  labcomm2014_copy_free_generated_encoding_P(labcomm2014_default_memory, &cache_p);
   puts("P deallocated ok");
-  labcomm_copy_free_test_sample_test_var(labcomm_default_memory, &cache_test_var);
+  labcomm2014_copy_free_test_sample_test_var(labcomm2014_default_memory, &cache_test_var);
   puts("test_var deallocated ok");
-  labcomm_copy_free_more_types_A(labcomm_default_memory, &cache_a);
+  labcomm2014_copy_free_more_types_A(labcomm2014_default_memory, &cache_a);
   puts("A deallocated ok");
-  labcomm_copy_free_more_types_S(labcomm_default_memory, &cache_s);
+  labcomm2014_copy_free_more_types_S(labcomm2014_default_memory, &cache_s);
   puts("S deallocated ok");
-  labcomm_copy_free_more_types_NS(labcomm_default_memory, &cache_ns);
+  labcomm2014_copy_free_more_types_NS(labcomm2014_default_memory, &cache_ns);
   puts("NS deallocated ok");
-  labcomm_copy_free_more_types_AS(labcomm_default_memory, &cache_as);
+  labcomm2014_copy_free_more_types_AS(labcomm2014_default_memory, &cache_as);
   puts("AS deallocated ok");
 }
diff --git a/lib/c/2014/test/test_labcomm_generated_encoding.c b/lib/c/2014/test/test_labcomm_generated_encoding.c
index 58462aa0b4dd62a319ef60004ccf37db05a84a30..f728ac0d6600ae8f5862c0a7725c821a6d11f33f 100644
--- a/lib/c/2014/test/test_labcomm_generated_encoding.c
+++ b/lib/c/2014/test/test_labcomm_generated_encoding.c
@@ -1,5 +1,5 @@
 /*
-  test_labcomm_generated_encoding.c -- LabComm tests of generated encoding
+  test_labcomm2014_generated_encoding.c -- LabComm tests of generated encoding
 
   Copyright 2013 Anders Blomdell <anders.blomdell@control.lth.se>
 
@@ -23,21 +23,34 @@
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
-#include "labcomm_private.h"
-#include "labcomm_default_error_handler.h"
-#include "labcomm_default_memory.h"
-#include "labcomm_pthread_scheduler.h"
+#include "labcomm2014_private.h"
+#include "labcomm2014_default_error_handler.h"
+#include "labcomm2014_default_memory.h"
+#include "labcomm2014_pthread_scheduler.h"
 #include "test/gen/generated_encoding.h"
 
 #define IOCTL_WRITER_ASSERT_BYTES 4096
 #define IOCTL_WRITER_RESET 4097
 
+#define EXPECT(...)							\
+  {                                                                     \
+    int expected[] = __VA_ARGS__;					\
+    labcomm2014_encoder_ioctl(encoder, IOCTL_WRITER_ASSERT_BYTES,       \
+			  __LINE__,					\
+			  sizeof(expected)/sizeof(expected[0]),		\
+			  expected);					\
+  }
+
+#define VARIABLE(i) -(i + 1)
+#define IS_VARIABLE(i) (i < 0)
+
 static unsigned char buffer[128];
-struct labcomm_writer *writer;
+struct labcomm2014_writer *writer;
+static int seen_variable[1024];
 
 static int buf_writer_alloc(
-  struct labcomm_writer *w, 
-  struct labcomm_writer_action_context *action_context)
+  struct labcomm2014_writer *w, 
+  struct labcomm2014_writer_action_context *action_context)
 {
   writer = w; /* Hack */
   w->data_size = sizeof(buffer);
@@ -49,32 +62,32 @@ static int buf_writer_alloc(
 }
 
 static int buf_writer_free(
-  struct labcomm_writer *w, 
-  struct labcomm_writer_action_context *action_context)
+  struct labcomm2014_writer *w, 
+  struct labcomm2014_writer_action_context *action_context)
 {
   return 0;
 }
 
 static int buf_writer_start(
-  struct labcomm_writer *w,
-  struct labcomm_writer_action_context *action_context,
+  struct labcomm2014_writer *w,
+  struct labcomm2014_writer_action_context *action_context,
   int index,
-  const struct labcomm_signature *signature,
+  const struct labcomm2014_signature *signature,
   void *value)
 {
   return 0;
 }
 
 static int buf_writer_end(
-  struct labcomm_writer *w, 
-  struct labcomm_writer_action_context *action_context)
+  struct labcomm2014_writer *w, 
+  struct labcomm2014_writer_action_context *action_context)
 {
   return 0;
 }
 
 static int buf_writer_flush(
-  struct labcomm_writer *w, 
-  struct labcomm_writer_action_context *action_context)
+  struct labcomm2014_writer *w, 
+  struct labcomm2014_writer_action_context *action_context)
 {
   fprintf(stderr, "Should not come here %s:%d\n", __FILE__, __LINE__);
   exit(1);
@@ -83,9 +96,9 @@ static int buf_writer_flush(
 }
 
 static int buf_writer_ioctl(
-  struct labcomm_writer *w, 
-  struct labcomm_writer_action_context *action_context,
-  int signature_index, const struct labcomm_signature *signature,
+  struct labcomm2014_writer *w, 
+  struct labcomm2014_writer_action_context *action_context,
+  int signature_index, const struct labcomm2014_signature *signature,
   uint32_t action, va_list arg)
 {
   int result = -ENOTSUP;
@@ -96,13 +109,23 @@ static int buf_writer_ioctl(
       int *expected = va_arg(arg, int *);
       int i, mismatch;
 
+      mismatch = 0;
       if (w->pos != count) {
-	fprintf(stderr, "Invalid length encoded %d != %d (%s:%d)\n", 
+	fprintf(stderr, "Invalid length detected %d != %d (%s:%d)\n", 
 		w->pos, count, __FILE__, line);
 	mismatch = 1;
       } 
-      for (mismatch = 0, i = 0 ; i < count ; i++) {
-	if (expected[i] >= 0 && expected[i] != buffer[i]) {
+      for (i = 0 ; i < count ; i++) {
+        if (IS_VARIABLE(expected[i])) {
+          if (seen_variable[VARIABLE(expected[i])] == -1) {
+            seen_variable[VARIABLE(expected[i])] = buffer[i];
+          }
+          if (seen_variable[VARIABLE(expected[i])] != buffer[i]) {
+            fprintf(stderr, "Unexpected variable (%d:  != %d)\n",
+                    seen_variable[VARIABLE(expected[i])], buffer[i]);
+            mismatch = 1;
+          }
+        } else if (expected[i] != buffer[i]) {
 	  mismatch = 1;
 	}
       }
@@ -116,7 +139,7 @@ static int buf_writer_ioctl(
 	printf("\n");
 	for (i = 0 ; i < count ; i++) {
 	  if (expected[i] < 0) {
-	    printf(".. ");
+	    printf("v%d ", VARIABLE(expected[i]));
 	  } else {
 	    printf("%2.2x ", expected[i] );
 	  }
@@ -134,7 +157,7 @@ static int buf_writer_ioctl(
   return result;
 }
 
-const struct labcomm_writer_action writer_action = {
+const struct labcomm2014_writer_action writer_action = {
   .alloc = buf_writer_alloc,
   .free = buf_writer_free,
   .start = buf_writer_start,
@@ -143,12 +166,12 @@ const struct labcomm_writer_action writer_action = {
   .ioctl = buf_writer_ioctl
 };
 
-static struct labcomm_writer_action_context action_context = {
+static struct labcomm2014_writer_action_context action_context = {
   .next = NULL,
   .action = &writer_action,
   .context = NULL
 }; 
-static struct labcomm_writer buffer_writer = {
+static struct labcomm2014_writer buffer_writer = {
   .action_context = &action_context,
   .data = buffer,
   .data_size = sizeof(buffer),
@@ -157,7 +180,7 @@ static struct labcomm_writer buffer_writer = {
   .error = 0,
 };
 
-void dump_encoder(struct labcomm_encoder *encoder)
+void dump_encoder(struct labcomm2014_encoder *encoder)
 {
   int i;
   
@@ -167,83 +190,91 @@ void dump_encoder(struct labcomm_encoder *encoder)
   printf("\n");
 }
 
-#define EXPECT(...)							\
-  {									\
-    int expected[] = __VA_ARGS__;					\
-    labcomm_encoder_ioctl(encoder, IOCTL_WRITER_ASSERT_BYTES,		\
-			  __LINE__,					\
-			  sizeof(expected)/sizeof(expected[0]),		\
-			  expected);					\
-  }
-
 int main(void)
 {
   generated_encoding_B B = 1;
   generated_encoding_R R;
+  struct labcomm2014_encoder *encoder;
+  int i;
+
+  for (i = 0 ; i < sizeof(seen_variable)/sizeof(seen_variable[0]) ; i++) {
+    seen_variable[i] = -1;
+  }
 
-  struct labcomm_encoder *encoder = labcomm_encoder_new(
+  encoder = labcomm2014_encoder_new(
     &buffer_writer, 
-    labcomm_default_error_handler,
-    labcomm_default_memory,
-    labcomm_pthread_scheduler_new(labcomm_default_memory));
+    labcomm2014_default_error_handler,
+    labcomm2014_default_memory,
+    labcomm2014_pthread_scheduler_new(labcomm2014_default_memory));
   EXPECT({ 0x01, 0x0c, 0x0b, 
            'L', 'a', 'b', 'C', 'o', 'm', 'm', '2','0', '1', '4' });
 
-  labcomm_encoder_ioctl(encoder, IOCTL_WRITER_RESET);
+  labcomm2014_encoder_ioctl(encoder, IOCTL_WRITER_RESET);
   /* Register twice to make sure that only one registration gets encoded */
-  labcomm_encoder_register_generated_encoding_V(encoder);
-  labcomm_encoder_register_generated_encoding_V(encoder);
-  EXPECT({ 0x02, 0x06, -1, 0x01, 'V', 0x02, 0x11, 0x00 });
+  labcomm2014_encoder_register_generated_encoding_V(encoder);
+  labcomm2014_encoder_register_generated_encoding_V(encoder);
+  EXPECT({ 0x02, 0x06, VARIABLE(0), 0x01, 'V', 0x02, 0x11, 0x00,
+           0x04, 0x08, VARIABLE(1), 0x03, 'v', '_', 't', 0x02, 0x11, 0x00,
+           0x04, 0x05, VARIABLE(2), 0x01, 'V', 0x01, VARIABLE(1),
+           0x05, 0x02, VARIABLE(0), VARIABLE(2) });
 
-  labcomm_encoder_ioctl(encoder, IOCTL_WRITER_RESET);
+  labcomm2014_encoder_ioctl(encoder, IOCTL_WRITER_RESET);
   /* Register twice to make sure that only one registration gets encoded */
-  labcomm_encoder_register_generated_encoding_B(encoder);
-  labcomm_encoder_register_generated_encoding_B(encoder);
-  EXPECT({0x02, 0x05, -1, 0x01, 'B', 0x01, 0x21});
+  labcomm2014_encoder_register_generated_encoding_B(encoder);
+  labcomm2014_encoder_register_generated_encoding_B(encoder);
+  EXPECT({ 0x02, 0x05, VARIABLE(3), 0x01, 'B', 0x01, 0x21,
+           0x05, 0x02, VARIABLE(3), LABCOMM_BIND_SELF });
 
-  labcomm_encoder_ioctl(encoder, IOCTL_WRITER_RESET);
+  labcomm2014_encoder_ioctl(encoder, IOCTL_WRITER_RESET);
   /* Register twice to make sure that only one registration gets encoded */
-  labcomm_encoder_sample_ref_register(encoder, 
-                                      labcomm_signature_generated_encoding_V);
-  labcomm_encoder_sample_ref_register(encoder, 
-                                      labcomm_signature_generated_encoding_V);
-  EXPECT({0x03, 0x06, -1, 0x01, 'V', 0x02, 0x11, 0x00});
+  labcomm2014_encoder_register_generated_encoding_R(encoder);
+  labcomm2014_encoder_register_generated_encoding_R(encoder);
+  EXPECT({ 0x02, 0x08, VARIABLE(4), 0x01, 'R', 0x04, 0x10, 0x01, 0x04, 0x28,
+           0x05, 0x02, VARIABLE(4), LABCOMM_BIND_SELF });
 
-  labcomm_encoder_ioctl(encoder, IOCTL_WRITER_RESET);
+  labcomm2014_encoder_ioctl(encoder, IOCTL_WRITER_RESET);
   /* Register twice to make sure that only one registration gets encoded */
-  labcomm_encoder_sample_ref_register(encoder, 
-                                      labcomm_signature_generated_encoding_B);
-  labcomm_encoder_sample_ref_register(encoder, 
-                                      labcomm_signature_generated_encoding_B);
-  EXPECT({0x03, 0x05, -1, 0x01, 'B', 0x01, 0x21});
+  labcomm2014_encoder_sample_ref_register(encoder, 
+                                      labcomm2014_signature_generated_encoding_V);
+  labcomm2014_encoder_sample_ref_register(encoder, 
+                                      labcomm2014_signature_generated_encoding_V);
+  EXPECT({0x03, 0x06, VARIABLE(5), 0x01, 'V', 0x02, 0x11, 0x00});
 
-  labcomm_encoder_ioctl(encoder, IOCTL_WRITER_RESET);
+  labcomm2014_encoder_ioctl(encoder, IOCTL_WRITER_RESET);
   /* Register twice to make sure that only one registration gets encoded */
-  labcomm_encoder_sample_ref_register(encoder, 
-                                      labcomm_signature_generated_encoding_R);
-  labcomm_encoder_sample_ref_register(encoder, 
-                                      labcomm_signature_generated_encoding_R);
-  EXPECT({0x03, 0x08, -1, 0x01, 'R', 0x04, 0x10, 0x01, 0x04, 0x28});
-
-  labcomm_encoder_ioctl(encoder, IOCTL_WRITER_RESET);
-  // was: labcomm_encode_generated_encoding_V(encoder, &V);
-  labcomm_encode_generated_encoding_V(encoder);
-  EXPECT({-1, 0x00 });
-
-  labcomm_encoder_ioctl(encoder, IOCTL_WRITER_RESET);
-  labcomm_encode_generated_encoding_B(encoder, &B);
-  EXPECT({-1, 0x01, 1});
-
-  labcomm_encoder_ioctl(encoder, IOCTL_WRITER_RESET);
-  R.a[0] = labcomm_signature_generated_encoding_V;
-  R.a[1] = labcomm_signature_generated_encoding_B;
-  R.a[2] = labcomm_signature_generated_encoding_UnusedE;
-  R.a[3] = labcomm_signature_generated_encoding_R;
-  labcomm_encode_generated_encoding_R(encoder, &R);
-  EXPECT({-1, 0x10, 0x00, 0x00, 0x00, -1,
-                    0x00, 0x00, 0x00, -1,
-                    0x00, 0x00, 0x00, 0x00,
-                    0x00, 0x00, 0x00, -1});
+  labcomm2014_encoder_sample_ref_register(encoder, 
+                                      labcomm2014_signature_generated_encoding_B);
+  labcomm2014_encoder_sample_ref_register(encoder, 
+                                      labcomm2014_signature_generated_encoding_B);
+  EXPECT({0x03, 0x05, VARIABLE(6), 0x01, 'B', 0x01, 0x21});
+
+  labcomm2014_encoder_ioctl(encoder, IOCTL_WRITER_RESET);
+  /* Register twice to make sure that only one registration gets encoded */
+  labcomm2014_encoder_sample_ref_register(encoder, 
+                                      labcomm2014_signature_generated_encoding_R);
+  labcomm2014_encoder_sample_ref_register(encoder, 
+                                      labcomm2014_signature_generated_encoding_R);
+  EXPECT({0x03, 0x08, VARIABLE(7), 0x01, 'R', 0x04, 0x10, 0x01, 0x04, 0x28});
+
+  labcomm2014_encoder_ioctl(encoder, IOCTL_WRITER_RESET);
+  // was: labcomm2014_encode_generated_encoding_V(encoder, &V);
+  labcomm2014_encode_generated_encoding_V(encoder);
+  EXPECT({VARIABLE(10), 0x00 });
+
+  labcomm2014_encoder_ioctl(encoder, IOCTL_WRITER_RESET);
+  labcomm2014_encode_generated_encoding_B(encoder, &B);
+  EXPECT({VARIABLE(20), 0x01, 1});
+
+  labcomm2014_encoder_ioctl(encoder, IOCTL_WRITER_RESET);
+  R.a[0] = labcomm2014_signature_generated_encoding_V;
+  R.a[1] = labcomm2014_signature_generated_encoding_B;
+  R.a[2] = labcomm2014_signature_generated_encoding_UnusedE;
+  R.a[3] = labcomm2014_signature_generated_encoding_R;
+  labcomm2014_encode_generated_encoding_R(encoder, &R);
+  EXPECT({VARIABLE(4), 0x10, 0x00, 0x00, 0x00, VARIABLE(5),
+                             0x00, 0x00, 0x00, VARIABLE(6),
+                             0x00, 0x00, 0x00, 0x00,
+                             0x00, 0x00, 0x00, VARIABLE(7)});
   return 0;
 }
 
diff --git a/lib/c/2014/test/test_labcomm_pthread_scheduler.c b/lib/c/2014/test/test_labcomm_pthread_scheduler.c
index 718293d58af7cf51c6215d2e226343c3cd14d9b2..aa7c5f0e08a77ccdf46717418ed06a4d4d64f3bf 100644
--- a/lib/c/2014/test/test_labcomm_pthread_scheduler.c
+++ b/lib/c/2014/test/test_labcomm_pthread_scheduler.c
@@ -1,5 +1,5 @@
 /*
-  test_labcomm_pthread_scheduler.c -- test labcomm pthread based task 
+  test_labcomm2014_pthread_scheduler.c -- test labcomm2014 pthread based task 
                                       coordination
 
   Copyright 2013 Anders Blomdell <anders.blomdell@control.lth.se>
@@ -22,13 +22,13 @@
 
 #include <stdio.h>
 #include <stdlib.h>
-#include "labcomm_default_memory.h"
-#include "labcomm_scheduler.h"
-#include "labcomm_pthread_scheduler.h"
+#include "labcomm2014_default_memory.h"
+#include "labcomm2014_scheduler.h"
+#include "labcomm2014_pthread_scheduler.h"
 
 #define TICK 100000
 struct func_arg {
-  struct labcomm_scheduler *scheduler;
+  struct labcomm2014_scheduler *scheduler;
   int i;
 };
 
@@ -38,11 +38,11 @@ static void func(void *arg)
   
   printf("%p %d\n", arg, func_arg->i);
   if (func_arg->i == 999) {
-    labcomm_scheduler_wakeup(func_arg->scheduler);
+    labcomm2014_scheduler_wakeup(func_arg->scheduler);
   }
 }
 
-void enqueue(struct labcomm_scheduler *scheduler, 
+void enqueue(struct labcomm2014_scheduler *scheduler, 
 	     int first, int last)
 {
   int i;
@@ -52,16 +52,16 @@ void enqueue(struct labcomm_scheduler *scheduler,
     
     tmp->scheduler = scheduler;
     tmp->i = i;
-    labcomm_scheduler_enqueue(scheduler, i*TICK, func, tmp);
+    labcomm2014_scheduler_enqueue(scheduler, i*TICK, func, tmp);
   }
 }
 
 int main(int argc, char *argv[])
 {
-  struct labcomm_scheduler *scheduler;
-  struct labcomm_time *time;
+  struct labcomm2014_scheduler *scheduler;
+  struct labcomm2014_time *time;
 
-  scheduler = labcomm_pthread_scheduler_new(labcomm_default_memory);
+  scheduler = labcomm2014_pthread_scheduler_new(labcomm2014_default_memory);
   enqueue(scheduler, 0, 5);
   enqueue(scheduler, 0, 1);
   enqueue(scheduler, 1, 3);
@@ -71,12 +71,12 @@ int main(int argc, char *argv[])
     
     tmp->scheduler = scheduler;
     tmp->i = 999;
-    labcomm_scheduler_enqueue(scheduler, 6*TICK, func, tmp);
+    labcomm2014_scheduler_enqueue(scheduler, 6*TICK, func, tmp);
   }
-  time = labcomm_scheduler_now(scheduler);
-  labcomm_time_add_usec(time, 12*TICK);
-  labcomm_scheduler_sleep(scheduler, NULL);
-  labcomm_scheduler_sleep(scheduler, time);
+  time = labcomm2014_scheduler_now(scheduler);
+  labcomm2014_time_add_usec(time, 12*TICK);
+  labcomm2014_scheduler_sleep(scheduler, NULL);
+  labcomm2014_scheduler_sleep(scheduler, time);
 
   return 0;
 }
diff --git a/lib/c/2014/test/test_signature_numbers.c b/lib/c/2014/test/test_signature_numbers.c
index 675088a42e60b55dd1d6244aa6d4db65b48077c9..c540f81f51c8a558b097738a543023362daa284e 100644
--- a/lib/c/2014/test/test_signature_numbers.c
+++ b/lib/c/2014/test/test_signature_numbers.c
@@ -1,14 +1,14 @@
 #include <stdlib.h>
 #include <stdio.h>
-#include "labcomm_private.h"
+#include "labcomm2014_private.h"
 #include "test/gen/another_encoding.h"
 #include "test/gen/generated_encoding.h"
 
 static void info(char *name, char *full_name, 
-		 const struct labcomm_signature *signature) {
+		 const struct labcomm2014_signature *signature) {
   printf("%s %s %p -> %d\n", name,  full_name, signature, 
-	 labcomm_get_local_index(signature));
-  if (labcomm_get_local_index(signature) < 0x40) {
+	 labcomm2014_get_local_index(signature));
+  if (labcomm2014_get_local_index(signature) < 0x40) {
     exit(1);
   }
 };
@@ -16,7 +16,7 @@ static void info(char *name, char *full_name,
 int main(int argc, char *argv[])
 {
 #define FUNC(name, full_name) \
-  info( #name, #full_name, labcomm_signature_##full_name)
+  info( #name, #full_name, labcomm2014_signature_##full_name)
 
   LABCOMM_FORALL_SAMPLES_generated_encoding(FUNC, ;);
   LABCOMM_FORALL_SAMPLES_another_encoding(FUNC, ;);
diff --git a/lib/c/Makefile b/lib/c/Makefile
index c2b23ee9f9373497e4e1ae612a99ed1ee903110a..5d36fef53c20424e93bc83107bcf83be9d64f36c 100644
--- a/lib/c/Makefile
+++ b/lib/c/Makefile
@@ -6,8 +6,12 @@ all:
 	for v in $(VERSIONS) ; do $(MAKE) -C $${v} $@ || exit 1 ; done
 
 
+.PHONY: clean
+clean: 
+	for v in $(VERSIONS) ; do $(MAKE) -C $${v} $@ || exit 1 ; done
+
 .PHONY: distclean
-distclean: 
+distclean:
 	for v in $(VERSIONS) ; do $(MAKE) -C $${v} $@ || exit 1 ; done
 	rm -f *.o *.so *.so.1 *.a
 
diff --git a/lib/c/os_compat.mk b/lib/c/os_compat.mk
index 23b66f2faa2e425e1fb0be3eb0f8772cdd972d60..b916df333d7ef6023694e44cecbafccb13bd6685 100644
--- a/lib/c/os_compat.mk
+++ b/lib/c/os_compat.mk
@@ -10,15 +10,18 @@ ifeq ($(UNAME_S),Linux)
   LDLIBS=-llabcomm$(LIBVERSION) -lrt
   MAKESHARED=gcc -o $1 -shared -Wl,-soname,$2 $3 -lc -lrt
 else ifeq ($(UNAME_S),Darwin)
-  CC=$(CROSS_COMPILE)clang
-  LD=$(CROSS_COMPILE)ld
+  #CC=$(CROSS_COMPILE)clang
+  #LD=$(CROSS_COMPILE)ld
+  CC=$(CROSS_COMPILE)gcc
+  LD=$(CROSS_COMPILE)gcc
   CFLAGS=-g -Wall -Werror -O3  -I. -Itest \
 	 -DLABCOMM_COMPAT=\"labcomm_compat_osx.h\" \
-	 -DLABCOMM_OS_DARWIN=1\
-	 -Wno-tautological-compare -Wno-unused-function
-  LDFLAGS=-L..
+	 -DLABCOMM_OS_DARWIN=1
+#	 -Wno-tautological-compare -Wno-unused-function
+  CFLAGS+=-std=c99 
+  LDFLAGS=-L.. 
   LDLIBS=-llabcomm$(LIBVERSION)
-  MAKESHARED=clang -o $1 -shared -Wl,-install_name,$2 $3 -lc
+  MAKESHARED=clang -o $1 -shared -Wl,-install_name,$2 $3 -lc 
 else ifneq ($(findstring CYGWIN,$(UNAME_S)),)
   CC=$(CROSS_COMPILE)gcc
   LD=$(CROSS_COMPILE)ld
diff --git a/lib/c/version_compare.py b/lib/c/version_compare.py
index f3e90d8a7deb21b4218d1b6e92d5efed32b0f1e6..ad2c1b1c3fdf5186869bacc42801012b20dae789 100755
--- a/lib/c/version_compare.py
+++ b/lib/c/version_compare.py
@@ -9,7 +9,9 @@ class File:
 
     def __init__(self, path, match, replacement):
         def replace(s):
-            return re.sub('[ \t]+', ' ', s).replace(match, replacement)
+            r = re.sub('[ \t]+', ' ', s).replace(match, replacement)
+            r = r.strip() + '\n'
+            return r
         self.name = path.replace(match, replacement)
         self.path = path
         with open(path) as f:
diff --git a/lib/csharp/.gitignore b/lib/csharp/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..75dc324a513f08f46d387ada99191807a2060ec5
--- /dev/null
+++ b/lib/csharp/.gitignore
@@ -0,0 +1 @@
+labcomm2014.dll
diff --git a/lib/csharp/LabComm.csproj b/lib/csharp/LabComm.csproj
deleted file mode 100644
index c6406ea5d3069279beb23378a5cec15524b6be46..0000000000000000000000000000000000000000
--- a/lib/csharp/LabComm.csproj
+++ /dev/null
@@ -1,26 +0,0 @@
-<?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
diff --git a/lib/csharp/Makefile b/lib/csharp/Makefile
index 370c77e2fce1d12e48fa99ff3ce766feab2748b7..c689902e17402080d3f993ed7d9f00763c5967e1 100644
--- a/lib/csharp/Makefile
+++ b/lib/csharp/Makefile
@@ -10,10 +10,18 @@ MODULES=Constant\
 	SampleHandler \
 	SampleType 
 
-all: labcomm.dll
+.PHONY: all
+all: labcomm2014.dll
 
-labcomm.dll: $(MODULES:%=se/lth/control/labcomm/%.cs) Makefile
+labcomm2014.dll: $(MODULES:%=se/lth/control/labcomm2014/%.cs) Makefile
 	mcs -out:$@ -target:library $(filter %.cs, $^)
 
+.PHONY: test
+test:
+
+.PHONY: clean
 clean:
-	rm -f labcomm.dll
+
+.PHONY: distclean
+distclean:
+	rm -f labcomm2014.dll
diff --git a/lib/csharp/se/lth/control/labcomm/Constant.cs b/lib/csharp/se/lth/control/labcomm2014/Constant.cs
similarity index 92%
rename from lib/csharp/se/lth/control/labcomm/Constant.cs
rename to lib/csharp/se/lth/control/labcomm2014/Constant.cs
index 5b247f677c6f5c79c5ce288d3a681f629eec5248..19f18ad519e9bb5995ab65552cfc9cc7d08da3e5 100644
--- a/lib/csharp/se/lth/control/labcomm/Constant.cs
+++ b/lib/csharp/se/lth/control/labcomm2014/Constant.cs
@@ -1,4 +1,4 @@
-namespace se.lth.control.labcomm {
+namespace se.lth.control.labcomm2014 {
 
   public class Constant {
 
@@ -11,6 +11,7 @@ namespace se.lth.control.labcomm {
     public const int SAMPLE_DEF       = 0x02;
     public const int SAMPLE_REF       = 0x03;
     public const int TYPE_DEF         = 0x04;
+    public const int TYPE_BINDING     = 0x05;
     public const int PRAGMA           = 0x3f;
     public const int FIRST_USER_INDEX = 0x40; /* ..0xffffffff */
 
diff --git a/lib/csharp/se/lth/control/labcomm/Decoder.cs b/lib/csharp/se/lth/control/labcomm2014/Decoder.cs
similarity index 91%
rename from lib/csharp/se/lth/control/labcomm/Decoder.cs
rename to lib/csharp/se/lth/control/labcomm2014/Decoder.cs
index 4e8868fc7bc86949897b90911522c865bbc56887..ddc3b59f52fa9483332f5c358d00ee4a18d92dcf 100644
--- a/lib/csharp/se/lth/control/labcomm/Decoder.cs
+++ b/lib/csharp/se/lth/control/labcomm2014/Decoder.cs
@@ -1,6 +1,6 @@
 using System;
 
-namespace se.lth.control.labcomm {
+namespace se.lth.control.labcomm2014 {
 
   public interface Decoder {
 
diff --git a/lib/csharp/se/lth/control/labcomm/DecoderChannel.cs b/lib/csharp/se/lth/control/labcomm2014/DecoderChannel.cs
similarity index 95%
rename from lib/csharp/se/lth/control/labcomm/DecoderChannel.cs
rename to lib/csharp/se/lth/control/labcomm2014/DecoderChannel.cs
index aa8662172f6cd4ed00cafaba7b44dcd5a6aa1287..a56a6042af37e455eea0766e82901264714e93b3 100644
--- a/lib/csharp/se/lth/control/labcomm/DecoderChannel.cs
+++ b/lib/csharp/se/lth/control/labcomm2014/DecoderChannel.cs
@@ -1,4 +1,4 @@
-namespace se.lth.control.labcomm {
+namespace se.lth.control.labcomm2014 {
 
   using System;
   using System.IO;
@@ -45,6 +45,12 @@ namespace se.lth.control.labcomm {
           ReadBytes(signature, signature_length);
 	  ref_registry.add(index, name, signature);
         } break;
+        case Constant.TYPE_DEF: 
+        case Constant.TYPE_BINDING: {
+            for(int i=0; i<length;i++){
+                decodeByte();
+            }                
+        } break;
         default: {
           DecoderRegistry.Entry e = def_registry.get(tag);
           if (e == null) {
diff --git a/lib/csharp/se/lth/control/labcomm/DecoderRegistry.cs b/lib/csharp/se/lth/control/labcomm2014/DecoderRegistry.cs
similarity index 98%
rename from lib/csharp/se/lth/control/labcomm/DecoderRegistry.cs
rename to lib/csharp/se/lth/control/labcomm2014/DecoderRegistry.cs
index 132e37b1849c965a51093fc403f277b1bc615394..bebcff26c7355a184b471234ca85f72043d0f493 100644
--- a/lib/csharp/se/lth/control/labcomm/DecoderRegistry.cs
+++ b/lib/csharp/se/lth/control/labcomm2014/DecoderRegistry.cs
@@ -1,4 +1,4 @@
-namespace se.lth.control.labcomm {
+namespace se.lth.control.labcomm2014 {
 
   using System;
   using System.Collections.Generic;
diff --git a/lib/csharp/se/lth/control/labcomm/Encoder.cs b/lib/csharp/se/lth/control/labcomm2014/Encoder.cs
similarity index 93%
rename from lib/csharp/se/lth/control/labcomm/Encoder.cs
rename to lib/csharp/se/lth/control/labcomm2014/Encoder.cs
index 1deb1b7ee9d28e52c952eb78aaef1c7fe7cf3db7..4aac7b3ac949019684b969d462cf8d93b0b4c4e7 100644
--- a/lib/csharp/se/lth/control/labcomm/Encoder.cs
+++ b/lib/csharp/se/lth/control/labcomm2014/Encoder.cs
@@ -1,4 +1,4 @@
-namespace se.lth.control.labcomm {
+namespace se.lth.control.labcomm2014 {
 
   using System;
 
diff --git a/lib/csharp/se/lth/control/labcomm/EncoderChannel.cs b/lib/csharp/se/lth/control/labcomm2014/EncoderChannel.cs
similarity index 98%
rename from lib/csharp/se/lth/control/labcomm/EncoderChannel.cs
rename to lib/csharp/se/lth/control/labcomm2014/EncoderChannel.cs
index 2f3da1cc99cc0c1abe24fa991fc31d73eb4fef96..20536e4d79c192deba72cd20958554eb51a93939 100644
--- a/lib/csharp/se/lth/control/labcomm/EncoderChannel.cs
+++ b/lib/csharp/se/lth/control/labcomm2014/EncoderChannel.cs
@@ -1,4 +1,4 @@
-namespace se.lth.control.labcomm {
+namespace se.lth.control.labcomm2014 {
 
   using System;
   using System.IO;
diff --git a/lib/csharp/se/lth/control/labcomm/EncoderRegistry.cs b/lib/csharp/se/lth/control/labcomm2014/EncoderRegistry.cs
similarity index 96%
rename from lib/csharp/se/lth/control/labcomm/EncoderRegistry.cs
rename to lib/csharp/se/lth/control/labcomm2014/EncoderRegistry.cs
index 9c40028567ac2d3df3080e6d2fd88d7e796a6d4f..6c299296cf98aa5e63ff07feb6a712cb55e3a526 100644
--- a/lib/csharp/se/lth/control/labcomm/EncoderRegistry.cs
+++ b/lib/csharp/se/lth/control/labcomm2014/EncoderRegistry.cs
@@ -1,4 +1,4 @@
-namespace se.lth.control.labcomm {
+namespace se.lth.control.labcomm2014 {
 
   using System;
   using System.Collections.Generic;
diff --git a/lib/csharp/se/lth/control/labcomm/Sample.cs b/lib/csharp/se/lth/control/labcomm2014/Sample.cs
similarity index 66%
rename from lib/csharp/se/lth/control/labcomm/Sample.cs
rename to lib/csharp/se/lth/control/labcomm2014/Sample.cs
index c9ea7fde821102bea58948af6e7fb188abd8caf2..5162c9325b9cb61a48ff4553004fd378e166c081 100644
--- a/lib/csharp/se/lth/control/labcomm/Sample.cs
+++ b/lib/csharp/se/lth/control/labcomm2014/Sample.cs
@@ -1,4 +1,4 @@
-namespace se.lth.control.labcomm {
+namespace se.lth.control.labcomm2014 {
 
   public interface Sample {
 
diff --git a/lib/csharp/se/lth/control/labcomm/SampleDispatcher.cs b/lib/csharp/se/lth/control/labcomm2014/SampleDispatcher.cs
similarity index 85%
rename from lib/csharp/se/lth/control/labcomm/SampleDispatcher.cs
rename to lib/csharp/se/lth/control/labcomm2014/SampleDispatcher.cs
index 23d39ed510ac07653c753e201f452788a97a901f..b7104d1c28c98e4607858fd6e7958fd5a7022122 100644
--- a/lib/csharp/se/lth/control/labcomm/SampleDispatcher.cs
+++ b/lib/csharp/se/lth/control/labcomm2014/SampleDispatcher.cs
@@ -1,4 +1,4 @@
-namespace se.lth.control.labcomm {
+namespace se.lth.control.labcomm2014 {
 
   using System;
 
diff --git a/lib/csharp/se/lth/control/labcomm/SampleHandler.cs b/lib/csharp/se/lth/control/labcomm2014/SampleHandler.cs
similarity index 51%
rename from lib/csharp/se/lth/control/labcomm/SampleHandler.cs
rename to lib/csharp/se/lth/control/labcomm2014/SampleHandler.cs
index d30cd2623c954dcb22917225d46ed79a4d6dc3f3..fa6e9a35b8ebfb0f309823591b485ddc3af5bc51 100644
--- a/lib/csharp/se/lth/control/labcomm/SampleHandler.cs
+++ b/lib/csharp/se/lth/control/labcomm2014/SampleHandler.cs
@@ -1,4 +1,4 @@
-namespace se.lth.control.labcomm {
+namespace se.lth.control.labcomm2014 {
 
   public interface SampleHandler {
   }
diff --git a/lib/csharp/se/lth/control/labcomm/SampleType.cs b/lib/csharp/se/lth/control/labcomm2014/SampleType.cs
similarity index 100%
rename from lib/csharp/se/lth/control/labcomm/SampleType.cs
rename to lib/csharp/se/lth/control/labcomm2014/SampleType.cs
diff --git a/lib/java/.gitignore b/lib/java/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..6273ee5074291f7336d0678dd6ffbbaeefd443fb
--- /dev/null
+++ b/lib/java/.gitignore
@@ -0,0 +1,5 @@
+gen
+labcomm.jar
+labcomm2006.jar
+labcomm2014.jar
+
diff --git a/lib/java/Makefile b/lib/java/Makefile
index 060aeeba5ea2854ab8c8f2790325540854545366..ec46407f6c5815d90a4613cb166cdf7c8fa2a0dd 100644
--- a/lib/java/Makefile
+++ b/lib/java/Makefile
@@ -10,32 +10,49 @@ MODULES=Constant \
 	SampleDispatcher \
 	SampleHandler \
 	SampleType \
+	BuiltinType \
+	TypeDef \
+	TypeBinding \
+	ASTbuilder \
+	TypeDefParser \
 	Writer \
 	WriterWrapper
 
+.PHONY: all
 all: labcomm.jar labcomm2014.jar labcomm2006.jar
 
 labcomm.jar: gen/JAVAC
 	echo $@
-	cd gen ; jar cfm ../$@ ../osgi-manifest.txt se/lth/control/labcomm/*.class se/lth/control/labcomm2006/*.class
+	cd gen ; jar cf ../$@ \
+		se/lth/control/labcomm2014/*.class \
+		se/lth/control/labcomm2006/*.class
 
 labcomm2014.jar: gen/JAVAC
 	echo $@
-	cd gen ; jar cfm ../$@ ../osgi-manifest.txt se/lth/control/labcomm/*.class
+	cd gen ; jar cf ../$@ se/lth/control/labcomm2014/*.class
 
 labcomm2006.jar: gen/JAVAC
 	echo $@
-	cd gen ; jar cfm ../$@ ../osgi-manifest.txt se/lth/control/labcomm2006/*.class
+	cd gen ; jar cf ../$@ se/lth/control/labcomm2006/*.class
 
 gen:
 	mkdir gen
 
-gen/JAVAC: $(MODULES:%=se/lth/control/labcomm/%.java) $(MODULES:%=se/lth/control/labcomm2006/%.java) Makefile | gen
-	javac -d gen $(filter %.java, $^)
+gen/JAVAC: $(MODULES:%=se/lth/control/labcomm2006/%.java) \
+	   $(MODULES:%=se/lth/control/labcomm2014/%.java) \
+	   Makefile | gen
+	javac -cp ../../compiler/labcomm2014_compiler.jar -d gen \
+            $(filter %.java, $^)
 	touch $@
 
 
-.PHONY: clean
+.PHONY: test
+test:
 
+.PHONY: clean
 clean:
-	rm -rf labcomm.jar labcomm2006.jar labcomm2014.jar gen
+	rm -rf gen
+
+.PHONY: distclean
+distclean: clean
+	rm -rf labcomm.jar labcomm2006.jar labcomm2014.jar
diff --git a/lib/java/osgi-manifest.txt b/lib/java/osgi-manifest.txt
deleted file mode 100644
index 49ca3d6cd68f2212c9ab0d74a709ed38c6a2c233..0000000000000000000000000000000000000000
--- a/lib/java/osgi-manifest.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-Bundle-Description: Provides Labcomm to bundles
-Bundle-ManifestVersion: 2
-Bundle-Name: Labcomm OSGi
-Bundle-SymbolicName: se.lth.control.labcomm
-Bundle-Vendor: LTH
-Bundle-Version: 1.0.0
-Export-Package: se.lth.control.labcomm;version="1.0.0",se.lth.control.la
- bcomm2006;version="1.0.0"
diff --git a/lib/java/se/lth/control/labcomm/EncoderChannel.java b/lib/java/se/lth/control/labcomm/EncoderChannel.java
deleted file mode 100644
index 08f9c87074c6d675d3cb08fd397d481f708e1726..0000000000000000000000000000000000000000
--- a/lib/java/se/lth/control/labcomm/EncoderChannel.java
+++ /dev/null
@@ -1,160 +0,0 @@
-package se.lth.control.labcomm;
-
-import java.io.ByteArrayOutputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-
-public class EncoderChannel implements Encoder {
-
-  private Writer writer;
-  private ByteArrayOutputStream bytes = new ByteArrayOutputStream();
-  private DataOutputStream data = new DataOutputStream(bytes);
-  private EncoderRegistry def_registry = new EncoderRegistry();
-  private EncoderRegistry ref_registry = new EncoderRegistry();
-  private int current_tag; 
-
-  public EncoderChannel(Writer writer) throws IOException {
-    this.writer = writer;
-
-    begin(Constant.VERSION);
-    encodeString(Constant.CURRENT_VERSION);
-    end(null);
-  }
-
-  public EncoderChannel(OutputStream writer) throws IOException {
-    this(new WriterWrapper(writer));
-  }
-
-  public void register(SampleDispatcher dispatcher) throws IOException {
-    if(dispatcher.getTypeDeclTag() == Constant.SAMPLE_DEF) {
-        int index = def_registry.add(dispatcher);
-        //begin(Constant.SAMPLE_DEF);
-        begin(dispatcher.getTypeDeclTag());
-        encodePacked32(index);
-        encodeString(dispatcher.getName());
-        byte[] signature = dispatcher.getSignature();
-        encodePacked32(signature.length);
-        for (int i = 0 ; i < signature.length ; i++) {
-        encodeByte(signature[i]);
-        }
-        end(null);
-    }
-  }
-
-  public void registerSampleRef(SampleDispatcher dispatcher) throws IOException {
-    System.err.println(dispatcher);
-    int index = ref_registry.add(dispatcher);
-    begin(Constant.SAMPLE_REF);
-    encodePacked32(index);
-    encodeString(dispatcher.getName());
-    byte[] signature = dispatcher.getSignature();
-    encodePacked32(signature.length);
-    for (int i = 0 ; i < signature.length ; i++) {
-      encodeByte(signature[i]);
-    }
-    end(null);
-  }
-
-  private void begin(int tag) {
-    current_tag = tag;
-    bytes.reset();
-  }
-
-  public void begin(Class<? extends Sample> c) throws IOException {
-    begin(def_registry.getTag(c));
-  }
-
-  public void end(Class<? extends Sample> c) throws IOException {
-    data.flush();
-    WritePacked32(writer, current_tag);
-    WritePacked32(writer, bytes.size());
-    writer.write(bytes.toByteArray());
-    bytes.reset();
-  }
-
-  private void WritePacked32(Writer s, long value) throws IOException {
-    byte[] tmp1 = new byte[5];
-    byte[] tmp2 = new byte[1];
-    long v = value & 0xffffffff;
-    int i;
-    
-    for (i = 0 ; i == 0 || v != 0 ; i++, v = (v >> 7)) {
-      tmp1[i] = (byte)(v & 0x7f | (i!=0?0x80:0x00));
-    }
-    for (i = i - 1 ; i >= 0 ; i--) {
-      tmp2[0] = tmp1[i];
-      writer.write(tmp2);
-    }      
-  }
-
-  public void encodeBoolean(boolean value) throws IOException{
-    data.writeBoolean(value);
-  }
-
-  public void encodeByte(byte value) throws IOException {
-    data.writeByte(value);
-  }
-
-  public void encodeShort(short value) throws IOException {
-    data.writeShort(value);
-  }
-
-  public void encodeInt(int value) throws IOException {
-    data.writeInt(value);
-  }
-
-  public void encodeLong(long value) throws IOException {
-    data.writeLong(value);
-  }
-
-  public void encodeFloat(float value) throws IOException {
-    data.writeFloat(value);
-  }
-
-  public void encodeDouble(double value) throws IOException {
-    data.writeDouble(value);
-  }
-
-  public void encodeString(String value) throws IOException {
-    //data.writeShort(0); // HACK...
-    //data.writeUTF(value);
-
-    //kludge, to replace above hack with packed length
-    ByteArrayOutputStream tmpb = new ByteArrayOutputStream();
-    DataOutputStream tmps = new DataOutputStream(tmpb);
-
-    tmps.writeUTF(value);
-    tmps.flush();
-    byte[] tmp = tmpb.toByteArray();
-  
-    encodePacked32(tmp.length-2);
-    for (int i = 2 ; i < tmp.length ; i++) {
-      encodeByte(tmp[i]);
-    }
-  }
-
-  public void encodePacked32(long value) throws IOException {
-    byte[] tmp = new byte[5];
-    long v = value & 0xffffffff;
-    int i;
-
-    for (i = 0 ; i == 0 || v != 0 ; i++, v = (v >> 7)) {
-      tmp[i] = (byte)(v & 0x7f);
-    }
-    for (i = i - 1 ; i >= 0 ; i--) {
-      encodeByte((byte)(tmp[i] | (i!=0?0x80:0x00)));
-    }
-  }
-
-  public void encodeSampleRef(Class value) throws IOException {
-    int index = 0;
-    try {
-      index = ref_registry.getTag(value);
-    } catch (NullPointerException e) {
-    }
-    data.writeInt(index);
-  }
-
-}
-
diff --git a/lib/java/se/lth/control/labcomm/Sample.java b/lib/java/se/lth/control/labcomm/Sample.java
deleted file mode 100644
index f86f486b4bae2276780f73e24b33d03717c95840..0000000000000000000000000000000000000000
--- a/lib/java/se/lth/control/labcomm/Sample.java
+++ /dev/null
@@ -1,7 +0,0 @@
-package se.lth.control.labcomm;
-
-public interface Sample {
-
-  public SampleDispatcher getDispatcher();
-
-}
diff --git a/lib/java/se/lth/control/labcomm/SampleType.java b/lib/java/se/lth/control/labcomm/SampleType.java
deleted file mode 100644
index f51ce99de5bbf360b8cd319387fd4dcb16b9904a..0000000000000000000000000000000000000000
--- a/lib/java/se/lth/control/labcomm/SampleType.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package se.lth.control.labcomm;
-
-public interface SampleType {
-
-}
diff --git a/lib/java/se/lth/control/labcomm2006/ASTbuilder.java b/lib/java/se/lth/control/labcomm2006/ASTbuilder.java
new file mode 100644
index 0000000000000000000000000000000000000000..a65e88738f5ed796591f10a00f63733aa17d8116
--- /dev/null
+++ b/lib/java/se/lth/control/labcomm2006/ASTbuilder.java
@@ -0,0 +1,4 @@
+package se.lth.control.labcomm2006;
+
+public class ASTbuilder {
+}
diff --git a/lib/java/se/lth/control/labcomm2006/BuiltinType.java b/lib/java/se/lth/control/labcomm2006/BuiltinType.java
new file mode 100644
index 0000000000000000000000000000000000000000..ffcdc879cd4c727d112423d498603da897752f3e
--- /dev/null
+++ b/lib/java/se/lth/control/labcomm2006/BuiltinType.java
@@ -0,0 +1,5 @@
+package se.lth.control.labcomm2006;
+
+public interface BuiltinType extends SampleType{
+
+}
diff --git a/lib/java/se/lth/control/labcomm2006/TypeBinding.java b/lib/java/se/lth/control/labcomm2006/TypeBinding.java
new file mode 100644
index 0000000000000000000000000000000000000000..0a15ac99af8f32c711e621d667ee920cf14abd7b
--- /dev/null
+++ b/lib/java/se/lth/control/labcomm2006/TypeBinding.java
@@ -0,0 +1,3 @@
+public class TypeBinding {
+
+}
diff --git a/lib/java/se/lth/control/labcomm2006/TypeDef.java b/lib/java/se/lth/control/labcomm2006/TypeDef.java
new file mode 100644
index 0000000000000000000000000000000000000000..32997dd75bc4b149eef5d885da7b046819e47b2c
--- /dev/null
+++ b/lib/java/se/lth/control/labcomm2006/TypeDef.java
@@ -0,0 +1,3 @@
+public class TypeDef {
+
+}
diff --git a/lib/java/se/lth/control/labcomm2006/TypeDefParser.java b/lib/java/se/lth/control/labcomm2006/TypeDefParser.java
new file mode 100644
index 0000000000000000000000000000000000000000..2890eeec456346dbd786195991afcf1bfd21cdec
--- /dev/null
+++ b/lib/java/se/lth/control/labcomm2006/TypeDefParser.java
@@ -0,0 +1,2 @@
+public class TypeDefParser {
+}
diff --git a/lib/java/se/lth/control/labcomm2014/ASTbuilder.java b/lib/java/se/lth/control/labcomm2014/ASTbuilder.java
new file mode 100644
index 0000000000000000000000000000000000000000..442afb86c2faad21eb76958685f3c6607f1bc1fd
--- /dev/null
+++ b/lib/java/se/lth/control/labcomm2014/ASTbuilder.java
@@ -0,0 +1,177 @@
+package se.lth.control.labcomm2014;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.io.EOFException;
+
+import se.lth.control.labcomm2014.TypeDef;
+import se.lth.control.labcomm2014.TypeDefParser;
+
+import se.lth.control.labcomm2014.compiler.LabComm;
+import se.lth.control.labcomm2014.compiler.LabCommParser;
+
+import se.lth.control.labcomm2014.compiler.List;
+import se.lth.control.labcomm2014.compiler.Program;
+import se.lth.control.labcomm2014.compiler.Decl;
+import se.lth.control.labcomm2014.compiler.TypeDecl;
+import se.lth.control.labcomm2014.compiler.SampleDecl;
+import se.lth.control.labcomm2014.compiler.Type;
+import se.lth.control.labcomm2014.compiler.VoidType;
+import se.lth.control.labcomm2014.compiler.PrimType;
+import se.lth.control.labcomm2014.compiler.UserType;
+import se.lth.control.labcomm2014.compiler.StructType;
+import se.lth.control.labcomm2014.compiler.Field;
+import se.lth.control.labcomm2014.compiler.ArrayType;
+import se.lth.control.labcomm2014.compiler.VariableArrayType;
+import se.lth.control.labcomm2014.compiler.FixedArrayType;
+import se.lth.control.labcomm2014.compiler.Dim;
+import se.lth.control.labcomm2014.compiler.Exp;
+import se.lth.control.labcomm2014.compiler.IntegerLiteral;
+import se.lth.control.labcomm2014.compiler.VariableSize;
+
+
+/** A class for building a JastAdd AST from the parsed types
+ *  created by a TypeDefParser. This class depends on the LabComm compiler.
+ */
+public class ASTbuilder implements TypeDefParser.ParsedSymbolVisitor {
+
+        private LinkedList<Type> typeStack;
+        private LinkedList<Field> fieldStack;
+
+        public ASTbuilder() {
+            this.typeStack = new LinkedList<Type>();
+            this.fieldStack = new LinkedList<Field>();
+        }
+
+        private void assertStacksEmpty() throws RuntimeException {
+            if(!typeStack.isEmpty()) {
+               throw new RuntimeException("Error: type stack not empty"); 
+            }
+            if(!fieldStack.isEmpty()) {
+               throw new RuntimeException("Error: field stack not empty"); 
+            }
+        }
+
+        public void visit(TypeDefParser.TypeSymbol s){
+            throw new Error("not implemented? needed?");
+
+        }
+        public void visit(TypeDefParser.SampleSymbol s){
+            throw new Error("not implemented? needed?");
+
+        }
+        public void visit(TypeDefParser.NameSymbol s){
+            throw new Error("not implemented? needed?");
+        }
+
+        public void visit(TypeDefParser.PrimitiveType t){
+            typeStack.push(new PrimType(t.getName(), t.getTag()));
+        }
+
+// SampleRefs are currently represented as primitive types,
+// see comment in TypeDefParser
+//        public void visit(TypeDefParser.SampleRefType t){
+//            typeStack.push(new SampleRefType());
+//        }
+
+        public void visit(TypeDefParser.ParsedStructType t){
+            if(t.isVoid()) {
+                typeStack.push(new VoidType());
+            } else {
+                List<Field> tmpF = new List<Field>();
+                for( TypeDefParser.ParsedField f : t.getFields()) {
+                    f.accept(this);
+                    tmpF.add(fieldStack.pop());
+                }
+                typeStack.push(new StructType(tmpF));
+            }
+        }
+        public void visit(TypeDefParser.ParsedField t){
+            t.getType().accept(this);
+            fieldStack.push(new Field(typeStack.pop(),t.getName()));
+
+        }
+        public void visit(TypeDefParser.ArrayType t){
+            boolean isFixed = true;
+            List<Exp> dim = new List<Exp>();
+            for(int i : t.getIdx()) {
+                if(i == 0) {
+                    dim.add(new VariableSize());
+                    isFixed = false;
+                } else {
+                    dim.add(new IntegerLiteral(Integer.toString(i)));
+                }
+            }
+            t.getType().accept(this);
+            if(isFixed) {
+                typeStack.push(new FixedArrayType(typeStack.pop(), dim));
+            } else {
+                typeStack.push(new VariableArrayType(typeStack.pop(), dim));
+            }
+
+        }
+        public void visit(TypeDefParser.ParsedUserType t){
+            typeStack.push(new UserType(t.getName()));
+        }
+
+
+       public Decl makeDecl(TypeDefParser.ParsedTypeDef d) {
+           d.getType().accept(this);
+           Decl result = new TypeDecl(typeStack.pop(), d.getName());
+           return result;
+       }
+
+       private Program createAndCheckProgram(List<Decl> ds) {
+            Program p = new Program(ds);
+            LinkedList errors = new LinkedList();
+            p.errorCheck(errors);
+            if(errors.isEmpty()) {
+                return p;
+            } else {
+                // This should not happen
+                // get errors and throw exception
+                StringBuilder sb = new StringBuilder();
+                for (Iterator iter = errors.iterator(); iter.hasNext(); ) {
+                    String s = (String)iter.next();
+                    sb.append(s);
+                }
+                throw new RuntimeException("Internal error: parsed labcomm declaration has errors: "+sb.toString());
+            }
+       }
+       
+       public Program makeProgram(TypeDefParser.ParsedTypeDef d) {
+           assertStacksEmpty();
+           List<Decl> ds = new List<Decl>();
+
+           ds.add(makeDecl(d));
+           assertStacksEmpty();
+           return createAndCheckProgram(ds);
+       }
+
+       public Decl makeDecl(TypeDefParser.ParsedSampleDef d) {
+           d.getType().accept(this);
+           Decl result = new SampleDecl(typeStack.pop(), d.getName());
+           return result;
+       }
+       public Program makeProgram(TypeDefParser.ParsedSampleDef d) {
+           assertStacksEmpty();
+           List<Decl> ds = new List<Decl>();
+
+           Iterator<TypeDefParser.ParsedTypeDef> it = d.getDepIterator();
+           while(it.hasNext()){
+               ds.add(makeDecl(it.next()));
+           }
+
+           ds.add(makeDecl(d));
+
+           assertStacksEmpty();
+           return createAndCheckProgram(ds);
+       }
+    }
+
diff --git a/lib/java/se/lth/control/labcomm2014/BuiltinType.java b/lib/java/se/lth/control/labcomm2014/BuiltinType.java
new file mode 100644
index 0000000000000000000000000000000000000000..ab0cec18391d75e571b4f124987f397452c07bbf
--- /dev/null
+++ b/lib/java/se/lth/control/labcomm2014/BuiltinType.java
@@ -0,0 +1,5 @@
+package se.lth.control.labcomm2014;
+
+public interface BuiltinType extends SampleType{
+
+}
diff --git a/lib/java/se/lth/control/labcomm/Constant.java b/lib/java/se/lth/control/labcomm2014/Constant.java
similarity index 86%
rename from lib/java/se/lth/control/labcomm/Constant.java
rename to lib/java/se/lth/control/labcomm2014/Constant.java
index fc52a2805a7089f3537bb379234e3dd680feb0fd..f46018a23f4504614d95e669058da2da80ecc794 100644
--- a/lib/java/se/lth/control/labcomm/Constant.java
+++ b/lib/java/se/lth/control/labcomm2014/Constant.java
@@ -1,4 +1,4 @@
-package se.lth.control.labcomm;
+package se.lth.control.labcomm2014;
 
 public class Constant {
 
@@ -35,5 +35,12 @@ public class Constant {
   public static final int FLOAT            = 0x25;
   public static final int DOUBLE           = 0x26;
   public static final int STRING           = 0x27;
+  public static final int SAMPLE           = 0x28;
 
+
+  /*
+   * Other predefined symbols
+   */
+
+  public static final int TYPE_BIND_SELF   = 0x00;
 }
diff --git a/lib/java/se/lth/control/labcomm/Decoder.java b/lib/java/se/lth/control/labcomm2014/Decoder.java
similarity index 95%
rename from lib/java/se/lth/control/labcomm/Decoder.java
rename to lib/java/se/lth/control/labcomm2014/Decoder.java
index ae684467b0ab7ce23471fc4e5142b8d5264b6d75..52c6636f0959132f5bec214edba24a2d266d6744 100644
--- a/lib/java/se/lth/control/labcomm/Decoder.java
+++ b/lib/java/se/lth/control/labcomm2014/Decoder.java
@@ -1,4 +1,4 @@
-package se.lth.control.labcomm;
+package se.lth.control.labcomm2014;
 
 import java.io.IOException;
 
diff --git a/lib/java/se/lth/control/labcomm/DecoderChannel.java b/lib/java/se/lth/control/labcomm2014/DecoderChannel.java
similarity index 72%
rename from lib/java/se/lth/control/labcomm/DecoderChannel.java
rename to lib/java/se/lth/control/labcomm2014/DecoderChannel.java
index dc25d2366ad4752d56660a2628d6f1c1219c396f..0e3ac6e5210dd8e67499e1a48222b456c959c89e 100644
--- a/lib/java/se/lth/control/labcomm/DecoderChannel.java
+++ b/lib/java/se/lth/control/labcomm2014/DecoderChannel.java
@@ -1,4 +1,4 @@
-package se.lth.control.labcomm;
+package se.lth.control.labcomm2014;
 
 import java.io.ByteArrayOutputStream;
 import java.io.DataInputStream;
@@ -35,26 +35,57 @@ public class DecoderChannel implements Decoder {
   }	   
 
   private void processTypeDef(int len) throws IOException {
-       System.err.println("Got TypeDef: skipping "+len+" bytes"); 
-       for(int i=0; i<len; i++) {
-           decodeByte();		  
+       try {
+           processSample(Constant.TYPE_DEF);
+      } catch(Exception ex) {
+       int idx = decodePacked32();
+       String name = decodeString(); 
+       int siglen = decodePacked32();
+       for(int i=0; i<siglen; i++) {
+           byte b = decodeByte();		  
        }
+      }
   }
 
   private void processTypeBinding(int len) throws IOException {
-       System.err.println("Got TypeBinding: skipping "+len+" bytes"); 
-       for(int i=0; i<len; i++) {
-           decodeByte();		  
-       }
+      try {
+           processSample(Constant.TYPE_BINDING);
+      } catch(Exception ex) {
+          for(int i=0; i<len; i++) {
+              decodeByte();		  
+          }
+      } 
   }
 
   private void processPragma(int len) throws IOException {
-       System.err.println("Got Pragma: skipping "+len+" bytes"); 
        for(int i=0; i<len; i++) {
            decodeByte();		  
        }
   }
 
+  private void processSample(int tag) throws IOException {
+	  DecoderRegistry.Entry e = def_registry.get(tag);
+	  if (e == null) {
+	    throw new IOException("Unhandled tag " + tag);
+	  }
+	  SampleDispatcher d = e.getDispatcher();
+	  if (d == null) {
+	    throw new IOException("No dispatcher for '" + e.getName() + "'");
+	  }
+	  SampleHandler h = e.getHandler();
+	  if (h == null) {
+	    throw new IOException("No handler for '" + e.getName() +"'");
+	  }
+      try {
+        //XXX why does decodeAndHandle throw Exception and not IOException?
+        d.decodeAndHandle(this, h);
+      } catch (IOException ex) {
+          throw ex;
+      } catch (Exception ex) {
+          ex.printStackTrace();
+      }
+  }	  
+
   public void runOne() throws Exception {
     boolean done = false;
     while (!done) {
@@ -68,37 +99,26 @@ public class DecoderChannel implements Decoder {
 			          version + " != " + Constant.CURRENT_VERSION);
           }
         } break;
-	case Constant.SAMPLE_DEF: {
-          processSampleDef();
-	} break;
-	case Constant.SAMPLE_REF: {
-          processSampleRef();
-	} break;
-	case Constant.TYPE_DEF: {
-          processTypeDef(length);
-	} break;
-	case Constant.TYPE_BINDING: {
-          processTypeBinding(length);
-	} break;
-	case Constant.PRAGMA: {
-          processPragma(length);
-	} break;
-	default: {
-	  DecoderRegistry.Entry e = def_registry.get(tag);
-	  if (e == null) {
-	    throw new IOException("Unhandled tag " + tag);
-	  }
-	  SampleDispatcher d = e.getDispatcher();
-	  if (d == null) {
-	    throw new IOException("No dispatcher for '" + e.getName() + "'");
-	  }
-	  SampleHandler h = e.getHandler();
-	  if (h == null) {
-	    throw new IOException("No handler for '" + e.getName() +"'");
-	  }
-	  d.decodeAndHandle(this, h);
-	  done = true;
-	}
+        case Constant.SAMPLE_DEF: {
+            processSampleDef();
+        } break;
+        case Constant.SAMPLE_REF: {
+            processSampleRef();
+        } break;
+        case Constant.TYPE_DEF: {
+            processTypeDef(length);
+        } break;
+        case Constant.TYPE_BINDING: {
+            processTypeBinding(length);
+        } break;
+        case Constant.PRAGMA: {
+            processPragma(length);
+        } break;
+        default: {
+            processSample(tag);
+            done = true;
+
+        }
       }
     }
   }
@@ -196,5 +216,16 @@ public class DecoderChannel implements Decoder {
 
   }
     
+  /* Package visible methods for use from TypeDefParser */
+
+  String getSampleName(int idx) {
+    DecoderRegistry.Entry e = def_registry.get(idx); 
+    return e.getName();  
+  }
+
+  byte[] getSampleSignature(int idx) {
+    DecoderRegistry.Entry e = def_registry.get(idx); 
+    return e.getSignature();  
+  }
 }
 
diff --git a/lib/java/se/lth/control/labcomm/DecoderRegistry.java b/lib/java/se/lth/control/labcomm2014/DecoderRegistry.java
similarity index 79%
rename from lib/java/se/lth/control/labcomm/DecoderRegistry.java
rename to lib/java/se/lth/control/labcomm2014/DecoderRegistry.java
index fdf8f591d646dad3680e7fbea48e2dcb9ed2ba15..af264e6e36583735463493f7566fa7d95ebd359a 100644
--- a/lib/java/se/lth/control/labcomm/DecoderRegistry.java
+++ b/lib/java/se/lth/control/labcomm2014/DecoderRegistry.java
@@ -1,4 +1,4 @@
-package se.lth.control.labcomm;
+package se.lth.control.labcomm2014;
 
 import java.io.IOException;
 import java.util.HashMap;
@@ -51,6 +51,11 @@ public class DecoderRegistry {
       return index;
     }
 
+    // protected, for TypeDefParser...
+    byte[] getSignature() {
+        return signature;
+    }
+
     public void setIndex(int index) throws IOException {
       if (this.index != 0 && this.index != index) {
 	throw new IOException("Index mismatch " + 
@@ -96,6 +101,20 @@ public class DecoderRegistry {
 
   public synchronized void add(SampleDispatcher dispatcher,
 			       SampleHandler handler) throws IOException{
+ //XXX kludge: special handling of predefined types
+    if(dispatcher.getSampleClass() == TypeDef.class){
+      Entry e = new Entry(dispatcher, handler);
+      e.setIndex(Constant.TYPE_DEF);
+      byClass.put(dispatcher.getSampleClass(), e);
+      byIndex.put(Integer.valueOf(Constant.TYPE_DEF), e);
+      //System.out.println("LCDecoderRegistry.add("+e.getName()+", "+e.getIndex()+")");
+    } else if(dispatcher.getSampleClass() == TypeBinding.class){
+      Entry e = new Entry(dispatcher, handler);
+      e.setIndex(Constant.TYPE_BINDING);
+      byClass.put(dispatcher.getSampleClass(), e);
+      byIndex.put(Integer.valueOf(Constant.TYPE_BINDING), e);
+      //System.out.println("LCDecoderRegistry.add("+e.getName()+", "+e.getIndex()+")");
+    } else {
     Entry e = byClass.get(dispatcher.getSampleClass());
     if (e != null) {
       e.check(dispatcher.getName(), dispatcher.getSignature());
@@ -114,6 +133,7 @@ public class DecoderRegistry {
 	byClass.put(dispatcher.getSampleClass(), e);
       }
     }
+   }
   }
 
   public synchronized void add(int index, 
diff --git a/lib/java/se/lth/control/labcomm/Encoder.java b/lib/java/se/lth/control/labcomm2014/Encoder.java
similarity index 73%
rename from lib/java/se/lth/control/labcomm/Encoder.java
rename to lib/java/se/lth/control/labcomm2014/Encoder.java
index 203366e850ec1bcaae73c09c15b1cd1e3b842a12..78c2e48b0c5e030bf908d7af848c162ca1a32f38 100644
--- a/lib/java/se/lth/control/labcomm/Encoder.java
+++ b/lib/java/se/lth/control/labcomm2014/Encoder.java
@@ -1,4 +1,4 @@
-package se.lth.control.labcomm;
+package se.lth.control.labcomm2014;
 
 import java.io.IOException;
 
@@ -6,8 +6,11 @@ public interface Encoder {
 
   public void register(SampleDispatcher dispatcher) throws IOException;
   public void registerSampleRef(SampleDispatcher dispatcher) throws IOException;
-  public void begin(Class<? extends Sample> c) throws IOException;
-  public void end(Class<? extends Sample> c) throws IOException;
+  public void begin(Class<? extends SampleType> c) throws IOException;
+  public void end(Class<? extends SampleType> c) throws IOException;
+
+  public void begin(int t) throws IOException;
+  public int getTypeId(Class<? extends SampleType> c) throws IOException;
 
   public void encodeBoolean(boolean value) throws IOException;
   public void encodeByte(byte value) throws IOException;
diff --git a/lib/java/se/lth/control/labcomm2014/EncoderChannel.java b/lib/java/se/lth/control/labcomm2014/EncoderChannel.java
new file mode 100644
index 0000000000000000000000000000000000000000..b6c25bb4ea54176693820c0a78a09ba31f678678
--- /dev/null
+++ b/lib/java/se/lth/control/labcomm2014/EncoderChannel.java
@@ -0,0 +1,248 @@
+package se.lth.control.labcomm2014;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+public class EncoderChannel implements Encoder {
+
+  private Writer writer;
+  private ByteArrayOutputStream bytes = new ByteArrayOutputStream();
+  private DataOutputStream data = new DataOutputStream(bytes);
+  private EncoderRegistry sample_def_registry = new EncoderRegistry();
+  private EncoderRegistry sample_ref_registry = new EncoderRegistry();
+  private EncoderRegistry type_def_registry = new EncoderRegistry();
+  private int current_tag;
+
+  private EncoderChannel(Writer writer, boolean emitVersion) throws IOException {
+    this.writer = writer;
+
+    if(emitVersion){
+      begin(Constant.VERSION);
+      encodeString(Constant.CURRENT_VERSION);
+      end(null);
+    }
+  }
+  public EncoderChannel(Writer writer) throws IOException {
+      this(writer, true);
+  }
+
+  public EncoderChannel(OutputStream writer) throws IOException {
+    this(new WriterWrapper(writer), true);
+  }
+
+  private EncoderChannel(OutputStream writer, boolean emitVersion) throws IOException {
+    this(new WriterWrapper(writer), emitVersion);
+  }
+  private void bindType(int sampleId, int typeId) throws IOException {
+        begin(Constant.TYPE_BINDING);
+        encodePacked32(sampleId);
+        encodePacked32(typeId);
+        end(null);
+  }
+
+  private void registerSample(SampleDispatcher dispatcher) throws IOException {
+        int index = sample_def_registry.add(dispatcher);
+        begin(dispatcher.getTypeDeclTag());
+        encodePacked32(index);
+        encodeString(dispatcher.getName());
+        byte[] signature = dispatcher.getSignature();
+        encodePacked32(signature.length);
+        for (int i = 0 ; i < signature.length ; i++) {
+            encodeByte(signature[i]);
+        }
+        end(null);
+        int tindex;
+        if(dispatcher.hasDependencies()){
+            tindex = registerTypeDef(dispatcher);
+        } else {
+            tindex = Constant.TYPE_BIND_SELF;
+        }
+        bindType(index, tindex);
+
+  }
+
+  private static class WrappedEncoder extends EncoderChannel{
+      private Encoder wrapped;
+
+      public WrappedEncoder(Encoder e, OutputStream s, boolean emitVersion) throws IOException {
+          super(s,emitVersion);
+          this.wrapped = e;
+      }
+      public int getTypeId(Class<? extends SampleType> c) throws IOException{
+         return wrapped.getTypeId(c);
+      }
+  }
+
+
+  private int registerTypeDef(SampleDispatcher dispatcher) throws IOException {
+      // check if already registered
+        try {
+            return type_def_registry.getTag(dispatcher);
+        } catch (IOException e) {
+            //otherwise, add to the registry
+            int index = type_def_registry.add(dispatcher);
+            //wrap encoder to get encoded length of signature
+            ByteArrayOutputStream baos = new ByteArrayOutputStream();
+            EncoderChannel wrapped = new WrappedEncoder(this, baos, false);
+            dispatcher.encodeTypeDef(wrapped, index);
+            wrapped.flush();
+            byte b[] = baos.toByteArray();
+
+            begin(Constant.TYPE_DEF);
+            encodePacked32(index);
+            encodeString(dispatcher.getName());
+            encodePacked32(b.length);
+            for(int i = 0; i<b.length; i++) {
+                encodeByte(b[i]);
+            }
+            end(null);
+
+            return index;
+        }
+  }
+
+  public void register(SampleDispatcher dispatcher) throws IOException {
+    switch (dispatcher.getTypeDeclTag())  {
+        case Constant.SAMPLE_DEF: {
+            registerSample(dispatcher);
+            break;
+        }
+        case Constant.TYPE_DEF: {
+            registerTypeDef(dispatcher);
+            break;
+        }
+        default:
+            throw new Error("Unknown typeDeclTag: "+dispatcher.getTypeDeclTag());
+    }
+  }
+
+  public void registerSampleRef(SampleDispatcher dispatcher) throws IOException {
+    System.err.println(dispatcher);
+    int index = sample_ref_registry.add(dispatcher);
+    begin(Constant.SAMPLE_REF);
+    encodePacked32(index);
+    encodeString(dispatcher.getName());
+    byte[] signature = dispatcher.getSignature();
+    encodePacked32(signature.length);
+    for (int i = 0 ; i < signature.length ; i++) {
+      encodeByte(signature[i]);
+    }
+    end(null);
+  }
+
+  public void begin(int tag) {
+    current_tag = tag;
+    bytes.reset();
+  }
+
+  public void begin(Class<? extends SampleType> c) throws IOException {
+    begin(sample_def_registry.getTag(c));
+  }
+
+  /* aux. method used to allow nesting encoders to find encoded size */
+  private void flush() throws IOException{
+    data.flush();
+    writer.write(bytes.toByteArray());
+    bytes.reset();
+  }
+  public void end(Class<? extends SampleType> c) throws IOException {
+    data.flush();
+    WritePacked32(writer, current_tag);
+    WritePacked32(writer, bytes.size());
+    writer.write(bytes.toByteArray());
+    bytes.reset();
+  }
+
+  /**
+   * @return the id of a TYPE_DEF
+   */
+  public int getTypeId(Class<? extends SampleType> c) throws IOException {
+    return type_def_registry.getTag(c);
+  }
+
+  private void WritePacked32(Writer s, long value) throws IOException {
+    byte[] tmp1 = new byte[5];
+    byte[] tmp2 = new byte[1];
+    long v = value & 0xffffffff;
+    int i;
+
+    for (i = 0 ; i == 0 || v != 0 ; i++, v = (v >> 7)) {
+      tmp1[i] = (byte)(v & 0x7f | (i!=0?0x80:0x00));
+    }
+    for (i = i - 1 ; i >= 0 ; i--) {
+      tmp2[0] = tmp1[i];
+      writer.write(tmp2);
+    }
+  }
+
+  public void encodeBoolean(boolean value) throws IOException{
+    data.writeBoolean(value);
+  }
+
+  public void encodeByte(byte value) throws IOException {
+    data.writeByte(value);
+  }
+
+  public void encodeShort(short value) throws IOException {
+    data.writeShort(value);
+  }
+
+  public void encodeInt(int value) throws IOException {
+    data.writeInt(value);
+  }
+
+  public void encodeLong(long value) throws IOException {
+    data.writeLong(value);
+  }
+
+  public void encodeFloat(float value) throws IOException {
+    data.writeFloat(value);
+  }
+
+  public void encodeDouble(double value) throws IOException {
+    data.writeDouble(value);
+  }
+
+  public void encodeString(String value) throws IOException {
+    ByteArrayOutputStream tmpb = new ByteArrayOutputStream();
+    DataOutputStream tmps = new DataOutputStream(tmpb);
+
+    tmps.writeUTF(value);
+    tmps.flush();
+    byte[] tmp = tmpb.toByteArray();
+
+    //the two first bytes written by writeUTF is the length of
+    //the string, so we skip those
+    encodePacked32(tmp.length-2);
+    for (int i = 2 ; i < tmp.length ; i++) {
+      encodeByte(tmp[i]);
+    }
+  }
+
+  public void encodePacked32(long value) throws IOException {
+    byte[] tmp = new byte[5];
+    long v = value & 0xffffffff;
+    int i;
+
+    for (i = 0 ; i == 0 || v != 0 ; i++, v = (v >> 7)) {
+      tmp[i] = (byte)(v & 0x7f);
+    }
+    for (i = i - 1 ; i >= 0 ; i--) {
+      encodeByte((byte)(tmp[i] | (i!=0?0x80:0x00)));
+    }
+  }
+
+  public void encodeSampleRef(Class value) throws IOException {
+    int index = 0;
+    try {
+      index = sample_ref_registry.getTag(value);
+    } catch (NullPointerException e) {
+        //we want to return 0 for unregistered ref types
+    }
+    data.writeInt(index);
+  }
+
+}
+
diff --git a/lib/java/se/lth/control/labcomm/EncoderRegistry.java b/lib/java/se/lth/control/labcomm2014/EncoderRegistry.java
similarity index 77%
rename from lib/java/se/lth/control/labcomm/EncoderRegistry.java
rename to lib/java/se/lth/control/labcomm2014/EncoderRegistry.java
index cd0cf72f5f45ed9ccc3cb6ce1902c9c2e37333bf..804fface11506599942a0f49323779f427d35cbb 100644
--- a/lib/java/se/lth/control/labcomm/EncoderRegistry.java
+++ b/lib/java/se/lth/control/labcomm2014/EncoderRegistry.java
@@ -1,4 +1,4 @@
-package se.lth.control.labcomm;
+package se.lth.control.labcomm2014;
 
 import java.io.IOException;
 import java.util.HashMap;
@@ -42,7 +42,11 @@ public class EncoderRegistry {
     return e.getIndex();
   }
   
-  public int getTag(Class<? extends Sample> sample) throws IOException {
+  public int getTag(SampleDispatcher d) throws IOException {
+      return getTag(d.getSampleClass());
+  }
+
+  public int getTag(Class<? extends SampleType> sample) throws IOException {
     Entry e = byClass.get(sample);
     if (e == null) {
       throw new IOException("'" + 
@@ -52,4 +56,8 @@ public class EncoderRegistry {
     return e.index;
   }
 
+  public boolean contains(Class<? extends SampleType> sample) {
+    return byClass.containsKey(sample);
+  }
+
 }
diff --git a/lib/java/se/lth/control/labcomm/Reader.java b/lib/java/se/lth/control/labcomm2014/Reader.java
similarity index 70%
rename from lib/java/se/lth/control/labcomm/Reader.java
rename to lib/java/se/lth/control/labcomm2014/Reader.java
index 1dd0dacd16ecab62bfb7e1de7ed30d082741c9ec..986a3bced6131fe7aca544b9697223b176b30d58 100644
--- a/lib/java/se/lth/control/labcomm/Reader.java
+++ b/lib/java/se/lth/control/labcomm2014/Reader.java
@@ -1,4 +1,4 @@
-package se.lth.control.labcomm;
+package se.lth.control.labcomm2014;
 
 public interface Reader {
 
diff --git a/lib/java/se/lth/control/labcomm2014/Sample.java b/lib/java/se/lth/control/labcomm2014/Sample.java
new file mode 100644
index 0000000000000000000000000000000000000000..6dcf1cf8a235be7e89fdc1aebe91bf2fc22d06a2
--- /dev/null
+++ b/lib/java/se/lth/control/labcomm2014/Sample.java
@@ -0,0 +1,7 @@
+package se.lth.control.labcomm2014;
+
+public interface Sample extends SampleType {
+
+  public SampleDispatcher getDispatcher();
+
+}
diff --git a/lib/java/se/lth/control/labcomm/SampleDispatcher.java b/lib/java/se/lth/control/labcomm2014/SampleDispatcher.java
similarity index 54%
rename from lib/java/se/lth/control/labcomm/SampleDispatcher.java
rename to lib/java/se/lth/control/labcomm2014/SampleDispatcher.java
index 58e3d1debdb47e31125088cf9bb6502d0ebc74b5..0d6b8b44951c3eab494636d10fc3e1c78e91c509 100644
--- a/lib/java/se/lth/control/labcomm/SampleDispatcher.java
+++ b/lib/java/se/lth/control/labcomm2014/SampleDispatcher.java
@@ -1,8 +1,10 @@
-package se.lth.control.labcomm;
+package se.lth.control.labcomm2014;
 
-public interface SampleDispatcher {
+import java.io.IOException;
+
+public interface SampleDispatcher <T extends SampleType>{
     
-  public Class getSampleClass();
+  public Class<T> getSampleClass();
     
   public String getName();
 
@@ -11,6 +13,12 @@ public interface SampleDispatcher {
   public void decodeAndHandle(Decoder decoder,
 			      SampleHandler handler) throws Exception;
 
+  /** @return true if the type depends on one or more typedefs
+   */
+  public boolean hasDependencies();
+
+  public void encodeTypeDef(Encoder e, int index) throws IOException;
+
   /** return the tag SAMPLE_DEF or TYPE_DEF, for use
    *  by encoder.register.
    *  TODO: refactor types, moving this to a super-interface
diff --git a/lib/java/se/lth/control/labcomm/SampleHandler.java b/lib/java/se/lth/control/labcomm2014/SampleHandler.java
similarity index 50%
rename from lib/java/se/lth/control/labcomm/SampleHandler.java
rename to lib/java/se/lth/control/labcomm2014/SampleHandler.java
index d03da88d64f8a23e795149bda5b7ed1080dd88e4..a5f67f8ed833b9269691fefc88d6259835f67651 100644
--- a/lib/java/se/lth/control/labcomm/SampleHandler.java
+++ b/lib/java/se/lth/control/labcomm2014/SampleHandler.java
@@ -1,4 +1,4 @@
-package se.lth.control.labcomm;
+package se.lth.control.labcomm2014;
 
 public interface SampleHandler {
 }
diff --git a/lib/java/se/lth/control/labcomm2014/SampleType.java b/lib/java/se/lth/control/labcomm2014/SampleType.java
new file mode 100644
index 0000000000000000000000000000000000000000..71f97867e143c6de425c7f229b4bc458bb521704
--- /dev/null
+++ b/lib/java/se/lth/control/labcomm2014/SampleType.java
@@ -0,0 +1,5 @@
+package se.lth.control.labcomm2014;
+
+public interface SampleType {
+
+}
diff --git a/lib/java/se/lth/control/labcomm2014/TypeBinding.java b/lib/java/se/lth/control/labcomm2014/TypeBinding.java
new file mode 100644
index 0000000000000000000000000000000000000000..47b33d5139571b0b48c457fcbca62e16b0d157c7
--- /dev/null
+++ b/lib/java/se/lth/control/labcomm2014/TypeBinding.java
@@ -0,0 +1,125 @@
+package se.lth.control.labcomm2014;
+
+import java.io.IOException;
+import java.io.ByteArrayOutputStream;
+import java.io.ByteArrayInputStream;
+import se.lth.control.labcomm2014.Decoder;
+import se.lth.control.labcomm2014.DecoderChannel;
+import se.lth.control.labcomm2014.SampleDispatcher;
+import se.lth.control.labcomm2014.SampleHandler;
+
+public class TypeBinding implements BuiltinType {
+    private int sampleIndex;
+    private int typeIndex;
+
+  public TypeBinding(int sampleIndex, int typeIndex) {
+      this.sampleIndex = sampleIndex;
+      this.typeIndex = typeIndex;
+  }
+
+  public int getSampleIndex() {
+    return sampleIndex;
+  }
+
+  public int getTypeIndex() {
+    return typeIndex;
+  }
+
+  public boolean isSelfBinding() {
+      return typeIndex == Constant.TYPE_BIND_SELF;
+  }
+
+  public interface Handler extends SampleHandler {
+    public void handle_TypeBinding(TypeBinding value) throws Exception;
+  }
+
+  public static void register(Decoder d, Handler h) throws IOException {
+    d.register(Dispatcher.singleton(), h);
+  }
+
+  public static void register(Encoder e) throws IOException {
+    register(e,false);
+  }
+
+  public static void register(Encoder e, boolean sendMetaData) throws IOException {
+    throw new IOException("cannot send TypeDefs");
+  }
+
+ static class Dispatcher implements SampleDispatcher<TypeBinding> {
+
+    private static Dispatcher singleton;
+
+    public synchronized static Dispatcher singleton() {
+      if(singleton==null) singleton=new Dispatcher();
+      return singleton;
+    }
+
+    public Class<TypeBinding> getSampleClass() {
+      return TypeBinding.class;
+    }
+
+    public String getName() {
+      return "TypeBinding";
+    }
+
+    public byte getTypeDeclTag() {
+      throw new Error("Should not be called");
+    }
+
+    public boolean isSample() {
+      throw new Error("Should not be called");
+    }
+    public boolean hasStaticSignature() {
+      throw new Error("Should not be called");
+    }
+
+    public byte[] getSignature() {
+      return null; // not used for matching
+    }
+
+    public void encodeTypeDef(Encoder e, int index) throws IOException{
+      throw new Error("Should not be called");
+    }
+
+    public void decodeAndHandle(Decoder d,
+                                SampleHandler h) throws Exception {
+      ((Handler)h).handle_TypeBinding(TypeBinding.decode(d));
+    }
+
+    public boolean hasDependencies() {
+        return false;
+    }
+  }
+
+  public static void encode(Encoder e, TypeBinding value) throws IOException {
+    throw new Error("Should not be called");
+  }
+
+  /* HERE BE DRAGONS!
+   * This exposes (and relies on the stability of) indices that are
+   * internal to a decoder.
+   *
+   * The SAMPLE_DEF and TYPE_DEF must already have been received for the
+   * indices to be known, so this can be changed to instead return
+   * references to the SampleDispactcher corresponding to the sample type
+   * and the matching TypeDef.
+   *
+   * Sketch:
+   *
+   * SampleDispatcher sd = d.getDispatcherForId(sampleIndex);
+   * TypeDef td = d.getTypeDefForId(typeIndex);
+   *
+   * return new TypeBinding(sd, td);
+   *
+   * assuming that the Decoder keeps a registry for TypeDefs
+   */
+  public static TypeBinding decode(Decoder d) throws IOException {
+    TypeBinding result;
+    int sampleIndex = d.decodePacked32();
+    int typeIndex = d.decodePacked32();
+
+    result = new TypeBinding(sampleIndex, typeIndex);
+    return result;
+  }
+}
+
diff --git a/lib/java/se/lth/control/labcomm2014/TypeDef.java b/lib/java/se/lth/control/labcomm2014/TypeDef.java
new file mode 100644
index 0000000000000000000000000000000000000000..494365caf4e2e2e5fd11abae86ff759796bef225
--- /dev/null
+++ b/lib/java/se/lth/control/labcomm2014/TypeDef.java
@@ -0,0 +1,132 @@
+package se.lth.control.labcomm2014;
+
+import java.io.IOException;
+import java.io.ByteArrayOutputStream;
+import java.io.ByteArrayInputStream;
+import se.lth.control.labcomm2014.Decoder;
+import se.lth.control.labcomm2014.DecoderChannel;
+import se.lth.control.labcomm2014.SampleDispatcher;
+import se.lth.control.labcomm2014.SampleHandler;
+
+public class TypeDef implements BuiltinType {
+    private int index;
+    private String name;
+    private byte signature[];
+
+  public int getIndex() {
+    return index;
+  }
+
+  public String getName() {
+    return name;
+  }
+
+  public String toString() {
+     return getName();
+  }
+ 
+  public byte[] getSignature() {
+    return signature;
+  }
+
+  public void dump() {
+      System.out.print("=== TypeDef "+getName()+"( "+Integer.toHexString(getIndex())+") : ");
+      for (byte b : signature) {
+        System.out.print(String.format("0x%02X ", b));
+      }
+      System.out.println();
+  }
+  public interface Handler extends SampleHandler {
+    public void handle_TypeDef(TypeDef value) throws Exception;
+  }
+  
+  public static void register(Decoder d, Handler h) throws IOException {
+    d.register(Dispatcher.singleton(), h);
+  }
+  
+  public static void register(Encoder e) throws IOException {
+    register(e,false);
+  }
+  
+  public static void register(Encoder e, boolean sendMetaData) throws IOException {
+    throw new IOException("cannot send TypeDefs");
+  }
+  
+ static class Dispatcher implements SampleDispatcher<TypeDef> {
+    
+    private static Dispatcher singleton;
+    
+    public synchronized static Dispatcher singleton() {
+      if(singleton==null) singleton=new Dispatcher();
+      return singleton;
+    }
+    
+    public Class<TypeDef> getSampleClass() {
+      return TypeDef.class;
+    }
+    
+    public String getName() {
+      return "TypeDef";
+    }
+
+    public byte getTypeDeclTag() {
+      throw new Error("Should not be called");
+    }
+    
+    public boolean isSample() {
+      throw new Error("Should not be called");
+    }
+    public boolean hasStaticSignature() {
+      throw new Error("Should not be called");
+    }
+    
+    /** return the flat signature. Intended use is on decoder side */
+    public byte[] getSignature() {
+      return null; // not used for matching
+    }
+    
+    public void encodeTypeDef(Encoder e, int index) throws IOException{
+      throw new Error("Should not be called");
+    }
+    
+//    public boolean canDecodeAndHandle() {
+//      return true;
+//    }
+    
+    public void decodeAndHandle(Decoder d,
+                                SampleHandler h) throws Exception {
+      ((Handler)h).handle_TypeDef(TypeDef.decode(d));
+    }
+    
+    public boolean hasDependencies() {
+        return false;
+    }
+  }
+  
+  public static void encode(Encoder e, TypeDef value) throws IOException {
+    throw new Error("Should not be called");
+  }
+  
+  protected TypeDef() {
+  }
+
+  public TypeDef(int index, String name, byte sig[]) {
+      this.index = index;
+      this.name = name;
+      this.signature = sig;
+  }
+
+  public static TypeDef decode(Decoder d) throws IOException {
+    TypeDef result;
+    int index = d.decodePacked32();
+    String name = d.decodeString();
+    int siglen= d.decodePacked32();
+    byte sig[] = new byte[siglen];
+    for(int i=0; i<siglen;i++){
+        sig[i] = d.decodeByte();
+    }
+    result = new TypeDef(index, name, sig);
+    return result;
+  }
+}
+
diff --git a/lib/java/se/lth/control/labcomm2014/TypeDefParser.java b/lib/java/se/lth/control/labcomm2014/TypeDefParser.java
new file mode 100644
index 0000000000000000000000000000000000000000..4175bbca93292dd924dcccc0c4b1bb7ada7c6fd9
--- /dev/null
+++ b/lib/java/se/lth/control/labcomm2014/TypeDefParser.java
@@ -0,0 +1,663 @@
+package se.lth.control.labcomm2014;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.io.EOFException;
+
+import se.lth.control.labcomm2014.Decoder;
+import se.lth.control.labcomm2014.DecoderChannel;
+import se.lth.control.labcomm2014.TypeDef;
+import se.lth.control.labcomm2014.TypeBinding;
+
+public class TypeDefParser implements TypeDef.Handler, TypeBinding.Handler {
+
+    static class SelfBinding extends TypeDef {
+
+        private int sampleIndex;
+        private Decoder decoder;
+        private byte[] dummy = new byte[0];
+        public String toString() {return "self";} 
+        public String getName() {
+            if(decoder instanceof DecoderChannel) {
+                DecoderChannel dc = (DecoderChannel) decoder;
+                return dc.getSampleName(sampleIndex);
+            } else {
+                return "self";
+            }
+        } 
+        public int getIndex() {return 0;}
+        public byte[] getSignature() {
+            if(decoder instanceof DecoderChannel) {
+                DecoderChannel dc = (DecoderChannel) decoder;
+                return dc.getSampleSignature(sampleIndex);
+            } else {
+                return dummy;
+            }
+        }
+
+        public SelfBinding(int sampleIndex, Decoder decoder) {
+            super();
+            this.sampleIndex = sampleIndex;
+            this.decoder = decoder;
+        }
+    }
+
+    public interface TypeDefListener {
+        void onTypeDef(ParsedTypeDef d);
+    }
+
+    private HashMap<Integer,TypeDef> typeDefs;
+    private HashMap<Integer,Integer> typeBindings;
+    private HashSet<TypeDefListener> listeners;
+    private LinkedList<ParsedSampleDef> sampleDefs;
+    private Decoder decoder;
+
+    protected TypeDefParser(Decoder d) {
+        this.decoder = d;
+        typeDefs = new HashMap<Integer,TypeDef>();
+        typeBindings = new HashMap<Integer,Integer>();
+        listeners = new HashSet<TypeDefListener>();
+        sampleDefs = new LinkedList<ParsedSampleDef>();
+    }
+
+    public void addListener(TypeDefListener l) {
+        listeners.add(l);
+    }
+
+
+    public Iterator<ParsedSampleDef> sampleDefIterator() {
+        return sampleDefs.iterator();
+    }
+
+    public void handle_TypeDef(TypeDef d) throws java.io.IOException {
+        typeDefs.put(d.getIndex(), d);
+    }
+
+    public void handle_TypeBinding(TypeBinding d) throws java.io.IOException {
+        TypeDef td;
+        if(d.isSelfBinding()){
+             td = new SelfBinding(d.getSampleIndex(), decoder);
+        } else {
+            typeBindings.put(d.getSampleIndex(), d.getTypeIndex());
+            td = getTypeDefForIndex(d.getSampleIndex());
+        }
+        ParsedSampleDef result = parseSignature(td);
+
+        sampleDefs.add(result);
+
+        Iterator<TypeDefListener> it = listeners.iterator();
+        while(it.hasNext()){
+            notifyListener(it.next(), result);
+        }
+    }
+
+    private void notifyListener(TypeDefListener l, ParsedTypeDef d) {
+        l.onTypeDef(d);
+        if(d instanceof ParsedSampleDef) {
+            for(ParsedTypeDef dep : ((ParsedSampleDef)d).getDependencies()) {
+                //do we want to change ParseTypeDef to have dependencies,
+                //and do recursion here?
+                //if so, do notifyListener(l, dep);
+                l.onTypeDef(dep);
+            }
+        }
+    }
+
+    private TypeDef getTypeDefForIndex(int sampleIndex) {
+        return typeDefs.get(typeBindings.get(sampleIndex));
+    }
+
+
+    /** Factory method for use by application programs:
+     *  registers a TypeDefParser for handling TypeDef and TypeBinding
+     *  on the Decoder d.
+     *
+     *  @return a new TypeDefParser registered on d
+     */
+    public static TypeDefParser registerTypeDefParser(Decoder d) throws java.io.IOException  {
+
+        TypeDefParser res = new TypeDefParser(d);
+
+        TypeDef.register(d,res);
+        TypeBinding.register(d,res);
+
+        return res;
+    }
+
+    public LinkedList<ParsedSymbol> symbolify() {
+
+        LinkedList<ParsedSymbol> result = new LinkedList<ParsedSymbol>();
+
+        Iterator<ParsedSampleDef> sdi = sampleDefIterator();
+
+        while(sdi.hasNext()) {
+            ParsedSampleDef sd = sdi.next();
+            result.add(new SampleSymbol());
+            result.add(sd.getType());
+            result.add(new NameSymbol(sd.getName()));
+
+            Iterator<ParsedTypeDef> di = sd.getDepIterator();        
+            while(di.hasNext()) {
+                ParsedTypeDef d = di.next();
+                result.add(new TypeSymbol());
+                result.add(d.getType());
+                result.add(new NameSymbol(d.getName()));
+            }
+        }
+        return result;
+    }
+
+    public String symbolString() {
+        Iterator<ParsedSymbol> i = symbolify().iterator();
+
+        StringBuilder sb = new StringBuilder();
+
+        while(i.hasNext()) {
+            sb.append(i.next().toString());
+        }
+        return sb.toString();
+    }
+
+    /* An interface for using Visitor pattern to traverse 
+     * ParsedTypeDefs
+     */
+    public interface ParsedSymbolVisitor {
+        void visit(TypeSymbol s);
+        void visit(SampleSymbol s);
+        void visit(NameSymbol s);
+        void visit(PrimitiveType t);
+        //sampleRefs are sent as primitive types
+        //Put this back if that is changed to SampleRefType
+        //void visit(SampleRefType t);
+        void visit(ParsedStructType t);
+        void visit(ParsedField t);
+        void visit(ArrayType t);
+        void visit(ParsedUserType t);
+    }
+    public abstract class ParsedSymbol{
+        public abstract void accept(ParsedSymbolVisitor v);
+    }
+
+    public class TypeSymbol extends ParsedSymbol {
+        public String toString() {
+            return "typedef ";
+        }
+        public void accept(ParsedSymbolVisitor v){
+            v.visit(this);
+        }
+    }
+
+    public class SampleSymbol extends ParsedSymbol {
+        public String toString() {
+            return "sample ";
+        }
+        public void accept(ParsedSymbolVisitor v){
+            v.visit(this);
+        }
+    }
+
+    public class NameSymbol extends ParsedSymbol {
+        private String name;
+
+        public NameSymbol(String name) {
+            this.name = name;
+        }
+
+        public String toString() { 
+            return name;
+        }
+        public void accept(ParsedSymbolVisitor v){
+            v.visit(this);
+        }
+    }
+
+    public abstract class ParsedType extends ParsedSymbol{
+    }
+
+// SampleRefType currently not sent, se above
+//    public class SampleRefType extends ParsedType {
+//        public void accept(ParsedSymbolVisitor v) {
+//            v.visit(this);
+//        }
+//
+//        public String toString() { 
+//            return "sample";}
+//    }
+
+    public class PrimitiveType extends ParsedType {
+        private final String name;
+        private int tag;
+
+        String getName() {
+            return name;
+        }
+
+        int getTag() {
+            return tag;
+        }
+        PrimitiveType(int tag) {
+            this.tag = tag;
+            switch(tag) {
+                case Constant.BOOLEAN:
+                    this.name = "boolean";
+                    break;
+                case Constant.BYTE:
+                    this.name = "byte";
+                    break;
+                case Constant.SHORT:
+                    this.name = "short";
+                    break;
+                case Constant.INT:
+                    this.name = "int";
+                    break;
+                case Constant.LONG:
+                    this.name = "long";
+                    break;
+                case Constant.FLOAT:
+                    this.name = "float";
+                    break;
+                case Constant.DOUBLE:
+                    this.name = "double";
+                    break;
+                case Constant.STRING:
+                    this.name = "string";
+                    break;
+                case Constant.SAMPLE:
+                    this.name = "sample";
+                    break;
+                default:
+                    this.name = "??? unknown tag 0x"+Integer.toHexString(tag);    
+            }
+        }
+
+        public void accept(ParsedSymbolVisitor v) {
+            v.visit(this);
+        }
+
+        public String toString() { 
+            return name;}
+    }
+
+    public class ParsedStructType extends ParsedType {
+        private ParsedField fields[];
+
+        ParsedStructType(int nParsedFields) {
+            this.fields = new ParsedField[nParsedFields];
+        }
+
+        public ParsedField[] getFields() {
+            return fields;
+        }
+
+        void setParsedField(int idx, ParsedField f) {
+            fields[idx] = f;
+        }
+
+        public boolean isVoid() {
+            return fields.length == 0;
+        }
+
+        public String toString() {
+            if(isVoid()) { //void type is empty struct
+                return "void";
+            } else {
+                StringBuilder sb = new StringBuilder();
+                sb.append("struct {\n");
+                for(ParsedField f : fields) {
+                    sb.append(f.toString());
+                    sb.append(";\n");        
+                }
+                sb.append("}");
+                return sb.toString();
+            }
+        }
+
+        public void accept(ParsedSymbolVisitor v) {
+            v.visit(this);
+        }
+    }
+
+    public class ParsedField extends ParsedSymbol{
+        private ParsedType type;
+        private String name;
+
+        ParsedField(String name, ParsedType type) {
+            this.name = name;
+            this.type = type;
+        }
+
+        public ParsedType getType() {
+            return type;
+        }
+
+        public String getName() {
+            return name;
+        }
+
+        public String toString() {
+            return type.toString() + " " + name;
+        }
+
+        public void accept(ParsedSymbolVisitor v) {
+            v.visit(this);
+        }
+    }
+
+    public class ArrayType extends ParsedType {
+        private int idx[];
+        private ParsedType type;
+
+        ArrayType(int idx[], ParsedType elementType) {
+            this.idx = idx;
+            this.type = elementType;
+        }
+
+        public ParsedType getType() {
+            return type;
+        }
+
+        public int[] getIdx() {
+            return idx;
+        }
+
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            sb.append(type.toString());
+            for(int i : idx) {
+                sb.append("["+(i>0 ? i : "_")+"]");
+            }
+            return sb.toString();
+        }
+
+        public void accept(ParsedSymbolVisitor v) {
+            v.visit(this);
+        }
+    }
+
+    public class ParsedUserType extends ParsedType {
+        private String name;
+        public String getName() {
+            return name;
+        }
+
+        public String toString() {
+            return name;
+        }
+
+        ParsedUserType(String name) {
+            this.name = name;
+        }
+
+        public void accept(ParsedSymbolVisitor v) {
+            v.visit(this);
+        }
+    }
+
+    public class ParsedTypeDef{
+       private int idx;
+       private String name;
+       private ParsedType type;
+
+       ParsedTypeDef(int idx, String name){
+            this.idx = idx;
+            this.name = name;
+       }
+
+       ParsedTypeDef(int idx, String name, ParsedType type) {
+           this(idx, name);
+           this.type = type;
+       }
+
+       /** To be overridden in ParsedSampleDef
+        */
+       public boolean isSampleDef() {
+           return false;
+       }
+
+       void setType(ParsedType type) {
+           this.type = type;
+       }
+
+       ParsedType getType() {
+           return type;
+       }
+
+       int getIndex() {
+           return idx;
+       }
+
+       public String getName() {
+            return name;
+       }
+
+       public String toString() {
+          return type.toString();
+       }
+
+       public int hashCode() {
+           return name.hashCode();
+       }
+
+       public boolean equals(Object o) {
+            if(! (o instanceof ParsedTypeDef)){
+                return false;
+            } else {
+                ParsedTypeDef other = (ParsedTypeDef) o;
+                return other.idx == idx && other.name.equals(name);
+            }
+       }
+
+       public void accept(ParsedSymbolVisitor v) {
+            type.accept(v);
+       }
+    }
+   
+    public class ParsedSampleDef extends ParsedTypeDef{
+
+        private HashSet<ParsedTypeDef> deps;
+        ParsedSampleDef(ParsedTypeDef td) {
+            super(td.getIndex(), td.getName(), td.getType());
+            this.deps = new HashSet<ParsedTypeDef>();
+        }
+
+        void addDependency(ParsedTypeDef d) {
+            deps.add(d);
+        }
+
+        @Override
+        public boolean isSampleDef() {
+            return true;
+        }
+        private HashSet<ParsedTypeDef> getDependencies() {
+            return deps;
+        }
+
+        Iterator<ParsedTypeDef> getDepIterator() {
+            return deps.iterator();
+        }        
+    }
+
+    private class ParserState {
+        private ByteArrayInputStream bis;
+        private DataInputStream in;
+        private TypeDef current;
+        private ParsedTypeDef currentParsed;
+
+        private LinkedList<TypeDef> typeStack;
+
+        ParsedTypeDef newTypeDef() {
+            currentParsed =new ParsedTypeDef(getCurrentIndex(), getCurrentName());
+            return currentParsed;
+        }
+
+        private ParserState() {
+            typeStack = new LinkedList<TypeDef>();
+        }
+
+        ParserState(int typeIdx) {
+            this();
+            pushType(typeIdx);
+        }
+         
+        ParserState(TypeDef td) {
+            this();
+            pushType(td);
+        }
+         
+        ParserState(byte sig[]) {
+            this();
+            bis= new ByteArrayInputStream(sig);
+            in = new DataInputStream(bis);
+        }
+
+        void pushType(TypeDef td) {
+            if(!typeStack.contains(td)) {
+                typeStack.push(td);
+            }
+        }
+        void pushType(int typeIdx) {
+            if(typeIdx >= 0x40 && !typeStack.contains(typeIdx)) {
+                typeStack.push(typeDefs.get(typeIdx));
+            } 
+        }
+
+        void popType() {
+            TypeDef td2 = typeStack.pop();
+            current = td2;
+            bis =new ByteArrayInputStream(td2.getSignature());
+            in = new DataInputStream(bis);
+        }
+
+        boolean moreTypes() {
+            return !typeStack.isEmpty();
+        }
+
+        int getCurrentIndex() {
+            return current.getIndex();
+        }
+
+        String getCurrentName() {
+            return current.getName();
+        }
+
+        String decodeString() throws IOException {
+            int len = decodePacked32() & 0xffffffff;
+            byte[] chars = new byte[len];
+            for(int i=0; i<len; i++) {
+                chars[i] = in.readByte();
+            }
+            return new String(chars);
+        }
+
+        int decodePacked32() throws IOException {
+            long res=0;
+            byte i=0;
+            boolean cont=true;
+
+            do {
+            byte c = in.readByte();
+            res = (res << 7) | (c & 0x7f);
+            cont = (c & 0x80) != 0;
+            i++;
+            } while(cont);
+
+            return (int) (res & 0xffffffff);
+        }
+    }
+
+    public ParsedSampleDef parseSignature(TypeDef td) throws IOException{
+        ParserState s = new ParserState(td);
+
+        ParsedSampleDef result=null;
+        try {
+            s.popType();
+            result = parseSampleTypeDef(s);
+            while(s.moreTypes()) {
+                s.popType();
+                result.addDependency(parseTypeDef(s));
+            }
+        } catch(java.io.EOFException ex) {
+            System.out.println("EOF: self_binding");
+        }
+        return result;
+    }    
+
+    private ArrayType  parseArray(ParserState in) throws IOException {
+        int numIdx = in.decodePacked32();
+        int idx[] = new int[numIdx];
+        for(int i=0; i<numIdx; i++){
+            idx[i] = in.decodePacked32(); 
+        }
+        int type = in.decodePacked32();
+        ParsedType elementType = lookupType(type, in); 
+        ArrayType result = new ArrayType(idx, elementType);
+        for(int i=0; i<numIdx; i++){
+            idx[i] = in.decodePacked32(); 
+        }
+        return result;
+    }
+
+    private ParsedStructType parseStruct(ParserState in) throws IOException {
+        int numParsedFields = in.decodePacked32();
+        ParsedStructType result = new ParsedStructType(numParsedFields);
+        for(int i=0; i<numParsedFields; i++) {
+            result.setParsedField(i, parseParsedField(in));
+        }
+        return result;
+    }
+
+    private ParsedField parseParsedField(ParserState in) throws IOException {
+        String name = in.decodeString();
+        return new ParsedField(name, parseType(in));
+    }
+
+    private ParsedType lookupType(int tag, ParserState in) {
+        ParsedType result;
+        if(tag >= Constant.FIRST_USER_INDEX) {
+                TypeDef td = typeDefs.get(tag);
+                result = new ParsedUserType(td.getName());
+                in.pushType(tag);
+// sampleRefs are sent as primitive types, see above
+//        } else if(tag == Constant.SAMPLE) {
+//                result = new SampleRefType();       
+        } else {
+                result = new PrimitiveType(tag);
+        }
+        return result;
+    }
+
+    private ParsedSampleDef parseSampleTypeDef(ParserState in) throws IOException {
+        ParsedTypeDef td = parseTypeDef(in);
+        return new ParsedSampleDef(td);
+    }
+    private ParsedTypeDef parseTypeDef(ParserState in) throws IOException {
+        ParsedTypeDef result = in.newTypeDef();
+        result.setType(parseType(in));
+        return result;
+    }
+    private ParsedType parseType(ParserState in) throws IOException {
+        int tag = in.decodePacked32();
+        ParsedType result = null;
+        switch(tag) {
+            case 0:
+                System.out.println("SELF");
+                break;
+            case Constant.ARRAY:
+                result = parseArray(in);
+                break;
+            case Constant.STRUCT:
+                result = parseStruct(in);
+                break;
+            default:
+                result = lookupType(tag, in);
+                break;
+        }    
+        return result;
+    }
+}
diff --git a/lib/java/se/lth/control/labcomm/Writer.java b/lib/java/se/lth/control/labcomm2014/Writer.java
similarity index 75%
rename from lib/java/se/lth/control/labcomm/Writer.java
rename to lib/java/se/lth/control/labcomm2014/Writer.java
index 2e015b0f4d94c0c916c76043178a2dda90403d86..5546882233172f4414d8e6d2652efdb78e98e1cc 100644
--- a/lib/java/se/lth/control/labcomm/Writer.java
+++ b/lib/java/se/lth/control/labcomm2014/Writer.java
@@ -1,4 +1,4 @@
-package se.lth.control.labcomm;
+package se.lth.control.labcomm2014;
 
 import java.io.IOException;
 
diff --git a/lib/java/se/lth/control/labcomm/WriterWrapper.java b/lib/java/se/lth/control/labcomm2014/WriterWrapper.java
similarity index 88%
rename from lib/java/se/lth/control/labcomm/WriterWrapper.java
rename to lib/java/se/lth/control/labcomm2014/WriterWrapper.java
index 7c33137e31b309521a7526685dcdc3de6ef04b91..f8b358d3e525a2dda7fead43ed4857e6671d62b2 100644
--- a/lib/java/se/lth/control/labcomm/WriterWrapper.java
+++ b/lib/java/se/lth/control/labcomm2014/WriterWrapper.java
@@ -1,4 +1,4 @@
-package se.lth.control.labcomm;
+package se.lth.control.labcomm2014;
 
 import java.io.OutputStream;
 import java.io.IOException;
diff --git a/lib/python/Makefile b/lib/python/Makefile
index 7798ea9c77f5297ce46b92db52dce08cb5022453..6832e7887fe121e6bae3c2e8b84085a2fd47b858 100644
--- a/lib/python/Makefile
+++ b/lib/python/Makefile
@@ -1,5 +1,12 @@
+.PHONY: all
+all:
+
+.PHONY: test
+test:
+
+.PHONY: clean
 clean:
 	find . -name '*.pyc' -exec rm {} \;
 
-distclean:
-	find . -name '*.pyc' -exec rm {} \;
+.PHONY: distclean
+distclean: clean
diff --git a/lib/python/labcomm/__init__.py b/lib/python/labcomm/__init__.py
deleted file mode 100644
index 0c95e1d51f7ebefc008ce96c3fcfade381f65fe3..0000000000000000000000000000000000000000
--- a/lib/python/labcomm/__init__.py
+++ /dev/null
@@ -1,34 +0,0 @@
-import labcomm.LabComm
-    
-from labcomm.StreamReader import StreamReader
-from labcomm.StreamWriter import StreamWriter
-
-Decoder = labcomm.LabComm.Decoder
-Encoder = labcomm.LabComm.Encoder
-
-sample = labcomm.LabComm.sample_def
-sample_def = labcomm.LabComm.sample_def
-sample_ref = labcomm.LabComm.sample_ref
-
-array = labcomm.LabComm.array
-struct = labcomm.LabComm.struct
-primitive = labcomm.LabComm.primitive
-
-BOOLEAN = labcomm.LabComm.BOOLEAN
-BYTE = labcomm.LabComm.BYTE
-SHORT = labcomm.LabComm.SHORT
-INTEGER = labcomm.LabComm.INTEGER
-LONG = labcomm.LabComm.LONG
-FLOAT = labcomm.LabComm.FLOAT
-DOUBLE = labcomm.LabComm.DOUBLE
-STRING = labcomm.LabComm.STRING
-SAMPLE = labcomm.LabComm.SAMPLE
-
-decl_from_signature = labcomm.LabComm.decl_from_signature
-
-try:
-    import labcomm.TreeModel
-    TreeModel = labcomm.TreeModel.TreeModel
-except:
-    pass
-
diff --git a/lib/python/labcomm/LabComm.py b/lib/python/labcomm2014/LabComm.py
similarity index 88%
rename from lib/python/labcomm/LabComm.py
rename to lib/python/labcomm2014/LabComm.py
index c4b353c63d7c73994249ab4ab6221276f3a4d121..208b92f172dcba3d6503ae43878ad9c2e056747c 100644
--- a/lib/python/labcomm/LabComm.py
+++ b/lib/python/labcomm2014/LabComm.py
@@ -29,11 +29,29 @@
 #   | ...
 #   +----+--
 #
+# LabComm2014 SAMPLE_REF:
+#
+#   +----+----+----+----+
+#   | id = 0x03             (packed32)
+#   +----+----+----+----+
+#   | length                (packed32)
+#   +----+----+----+----+
+#   | type number           (packed32)
+#   +----+----+----+----+
+#   | type name (UTF8)
+#   | ...
+#   +----+----+----+----+
+#   | signature length      (packed32)
+#   +----+----+----+----+
+#   | type signature
+#   | ...
+#   +----+--
+#
 # LabComm2014 TYPE_DEF: (as SAMPLE_DEF, but signatures are hierarchical,
 #                         i.e., may contain references to other types
 #
 #   +----+----+----+----+
-#   | id = 0x03             (packed32)
+#   | id = 0x04             (packed32)
 #   +----+----+----+----+
 #   | length                (packed32)
 #   +----+----+----+----+
@@ -51,7 +69,7 @@
 # LabComm2014 TYPE_BINDING
 #
 #   +----+----+----+----+
-#   | id = 0x04             (packed32)
+#   | id = 0x05             (packed32)
 #   +----+----+----+----+
 #   | length                (packed32)
 #   +----+----+----+----+
@@ -157,6 +175,8 @@ DEFAULT_VERSION = "LabComm2014"
 i_VERSION     = 0x01
 i_SAMPLE_DEF  = 0x02
 i_SAMPLE_REF  = 0x03
+i_TYPE_DEF    = 0x04  
+i_TYPE_BINDING= 0x05 
 i_PRAGMA      = 0x3f
 i_USER        = 0x40 # ..0xffffffff
 
@@ -199,13 +219,28 @@ class length_encoder:
 def indent(i, s):
     return ("\n%s" % (" " * i)).join(s.split("\n"))
 
+#
+# Base type for all decl's
+#
+class type_decl(object):
+    pass
+
 #
 # Primitive types
 #
-class primitive(object):
+class primitive(type_decl):
     def decode_decl(self, decoder):
         return self
 
+    def __eq__(self, other):
+        return self.__class__ == other.__class__
+
+    def __ne__(self, other):
+        return not self.__eq__(other)
+    
+    def __hash__(self):
+        return hash(self.__class__)
+
 class BOOLEAN(primitive):
     def encode_decl(self, encoder):
         return encoder.encode_type(i_BOOLEAN)
@@ -348,16 +383,13 @@ class SAMPLE(primitive):
     def new_instance(self):
         return ""
 
-    def __eq__(self, other):
-        return self.__class__ == other.__class__
-
     def __repr__(self):
         return "labcomm.SAMPLE()"
 
 #
 # Aggregate types
 #
-class sample_def_or_ref(object):
+class sampledef_or_sampleref_or_typedef(type_decl):
     def __init__(self, name=None, decl=None):
         self.name = name
         self.decl = decl
@@ -370,8 +402,8 @@ class sample_def_or_ref(object):
             with length_encoder(e1) as e2:
                 self.decl.encode_decl(e2)
 
-    def encode(self, encoder, object):
-        self.decl.encode(encoder, object)
+    def encode(self, encoder, value):
+        self.decl.encode(encoder, value)
 
     def decode_decl(self, decoder):
         index = decoder.decode_type_number()
@@ -393,17 +425,20 @@ class sample_def_or_ref(object):
         return self.decl.new_instance()
 
     def __eq__(self, other):
-        return (type(self) == type(other) and 
+        return (self.__class__ == other.__class__ and 
                 self.name == other.name and
                 self.decl == other.decl)
         
     def __ne__(self, other):
-        return not self == other
+        return not self.__eq__(other)
 
+    def __hash__(self):
+        return hash(self.__class__) ^ hash(self.name) ^ hash(self.decl)
+    
     def __repr__(self):
         return "%s('%s', %s)" % (self.type_name, self.name, self.decl)
 
-class sample_def(sample_def_or_ref):
+class sample_def(sampledef_or_sampleref_or_typedef):
     type_index = i_SAMPLE_DEF
     type_name = 'sample'
 
@@ -412,8 +447,8 @@ class sample_def(sample_def_or_ref):
 
     def add_index(self, decoder, index, decl):
         decoder.add_decl(decl, index)
-
-class sample_ref(sample_def_or_ref):
+    
+class sample_ref(sampledef_or_sampleref_or_typedef):
     type_index = i_SAMPLE_REF
     type_name = 'sample_ref'
     
@@ -431,19 +466,32 @@ class sample_ref(sample_def_or_ref):
     def add_index(self, decoder, index, decl):
         decoder.add_ref(decl, index)
 
-class array(object):
+class typedef(sampledef_or_sampleref_or_typedef):
+    type_index = i_TYPE_DEF
+    type_name = 'typedef'
+
+    def encode_decl(self, encoder):
+        self.decl.encode_decl(encoder)
+
+    def encode(self, encoder, value):
+        self.decl.encode(encoder, value)
+
+class array(type_decl):
     def __init__(self, indices, decl):
-        self.indices = indices
+        self.indices = tuple(indices)
         self.decl = decl
         
     def __eq__(self, other):
-        return (type(self) == type(other) and 
+        return (self.__class__ == other.__class__ and 
                 self.indices == other.indices and
                 self.decl == other.decl)
         
     def __ne__(self, other):
-        return not self == other
+        return not self.__eq__(other)
 
+    def __hash__(self):
+        return hash(self.__class__) ^ hash(self.indices) ^ hash(self.decl)
+    
     def encode_decl(self, encoder):
         encoder.encode_type(i_ARRAY)
         encoder.encode_packed32(len(self.indices))
@@ -486,7 +534,6 @@ class array(object):
     def encode_indices(self, encoder, value):
         depth = len(self.indices)
         shape = self.shape(value)
-        #if len(shape) != len(self.indices):
         if len(shape) < len(self.indices):
             raise Exception("Actual dimension %s differs from declared %s" %
                             (shape, self.indices))
@@ -499,7 +546,6 @@ class array(object):
         return depth
 
     def encode_value(self, encoder, value, depth):
-        # if depth and isinstance(value, list):
         if depth:
             for e in value:
                 self.encode_value(encoder, e, depth - 1)
@@ -557,19 +603,19 @@ class array(object):
         return "labcomm.array(%s,\n    %s)" % (
             self.indices, indent(4, self.decl.__repr__()))
     
-class struct:
+class struct(type_decl):
     def __init__(self, field):
         self.field = tuple(field)
 
     def __eq__(self, other):
-        return (type(self) == type(other) and 
+        return (self.__class__ == other.__class__ and 
                 self.field == other.field)
         
     def __ne__(self, other):
-        return not self == other
+        return not self.__eq__(other)
 
     def __hash__(self):
-        return hash(self.field)
+        return hash(self.__class__) ^ hash(self.field)
 
     def encode_decl(self, encoder):
         encoder.encode_type(i_STRUCT)
@@ -577,7 +623,6 @@ class struct:
         for (name, decl) in self.field:
             encoder.encode_string(name)
             encoder.encode_type_number(decl)
-            #type.encode_decl(encoder)
 
     def encode(self, encoder, obj):
         if isinstance(obj, dict):
@@ -621,7 +666,7 @@ class struct:
 SAMPLE_DEF = sample_def()
 SAMPLE_REF = sample_ref()
 
-ARRAY = array(None, None)
+ARRAY = array([], None)
 STRUCT = struct([])
 
 class anonymous_object(dict):
@@ -671,6 +716,8 @@ class Codec(object):
         
     def add_decl(self, decl, index=0):
         if index == 0:
+            if decl in self.decl_to_index:
+                return False
             index = self.decl_index
             self.decl_index += 1
         self.index_to_decl[index] = decl
@@ -679,9 +726,12 @@ class Codec(object):
             self.name_to_decl[decl.name] = decl
         except:
             pass
+        return True
         
     def add_ref(self, ref, index=0):
         if index == 0:
+            if ref.sample in self.ref_to_index:
+                return False
             index = self.ref_index
             self.ref_index += 1
         self.index_to_ref[index] = ref.sample
@@ -690,7 +740,8 @@ class Codec(object):
             self.name_to_ref[ref.sample.name] = ref.sample
         except:
             pass
-
+        return True
+    
     def add_binding(self, name, decl):
         self.type_to_name[decl] = name
         self.name_to_type[name] = decl
@@ -724,27 +775,35 @@ class Encoder(Codec):
         self.writer.write(packer.pack(format, *args))
 
     def add_decl(self, decl, index=0):
-        super(Encoder, self).add_decl(decl, index)
+        if not isinstance(decl, type_decl):
+            decl = decl.signature
         if index == 0:
-            decl.encode_decl(self)
-            self.writer.mark()
+            self.writer.mark_begin(decl, None)
+            if super(Encoder, self).add_decl(decl, index):
+                decl.encode_decl(self)
+            self.writer.mark_end(decl, None)
  
     def add_ref(self, decl, index=0):
+        if not isinstance(decl, type_decl):
+            decl = decl.signature
         ref = sample_ref(name=decl.name, decl=decl.decl, sample=decl)
-        super(Encoder, self).add_ref(ref, index)
         if index == 0:
-            ref.encode_decl(self)
-            self.writer.mark()
+            self.writer.mark_begin(decl, None)
+            if super(Encoder, self).add_ref(ref, index):
+                ref.encode_decl(self)
+            self.writer.mark_end(decl, None)
  
     def encode(self, object, decl=None):
         if decl == None:
             name = self.type_to_name[object.__class__]
             decl = self.name_to_decl[name]
+        if not isinstance(decl, type_decl):
+            decl = decl.signature
+        self.writer.mark_begin(decl, object)
         self.encode_type_number(decl)
         with length_encoder(self) as e:
             decl.encode(e, object)
-#        decl.encode(self, object)
-        self.writer.mark()
+        self.writer.mark_end(decl, object)
 
     def encode_type_number(self, decl):
         try:
@@ -770,7 +829,6 @@ class Encoder(Codec):
 
     def encode_type(self, index):
         self.encode_packed32(index)
-#        self.pack("!i", index)
             
     def encode_boolean(self, v):
         if v:
@@ -800,7 +858,6 @@ class Encoder(Codec):
         s = v.encode("utf8")
 	self.encode_packed32(len(s));
 	self.pack("%ds" % len(s),s)
-#        self.pack("!i%ds" % len(s), len(s), s)
 
 class Decoder(Codec):
     def __init__(self, reader, version=DEFAULT_VERSION):
@@ -829,6 +886,13 @@ class Decoder(Codec):
         for _ in xrange(length):
             self.decode_byte()
 
+    # kludge, should really check if the index exists in self.version
+    def skip_or_raise(self, length, index):
+        if usePacketLength(self.version):
+            self.skip(length)
+        else:    
+            raise Exception("Invalid type index %d" % index)
+
     def decode(self):
         while True:
             index = self.decode_type_number()
@@ -847,6 +911,18 @@ class Decoder(Codec):
         elif index == i_SAMPLE_REF:
             decl = self.index_to_decl[index].decode_decl(self)
             value = None
+        elif index == i_TYPE_DEF:
+            self.skip_or_raise(length, index) 
+            decl = None
+            value = None
+        elif index == i_TYPE_BINDING:
+            self.skip_or_raise(length, index) 
+            decl = None
+            value = None
+        elif index == i_PRAGMA:
+            self.skip_or_raise(length, index) 
+            decl = None
+            value = None
         elif index < i_USER:
             raise Exception("Invalid type index %d" % index)
         else:
diff --git a/lib/python/labcomm/StreamReader.py b/lib/python/labcomm2014/StreamReader.py
similarity index 95%
rename from lib/python/labcomm/StreamReader.py
rename to lib/python/labcomm2014/StreamReader.py
index 87e9a5945fffde9409ad890e4c9194442cb65f75..a32b9934e21572da2a81ecf8018a51b94a77d3b5 100644
--- a/lib/python/labcomm/StreamReader.py
+++ b/lib/python/labcomm2014/StreamReader.py
@@ -1,5 +1,3 @@
-import labcomm
-
 class StreamReader:
 
     def __init__(self, stream):
diff --git a/lib/python/labcomm/StreamWriter.py b/lib/python/labcomm2014/StreamWriter.py
similarity index 72%
rename from lib/python/labcomm/StreamWriter.py
rename to lib/python/labcomm2014/StreamWriter.py
index a85c43d96b9d98de72f4a112720d5e23791df076..f72c44381556f6f8c43fe1bb7656b8b524a54dc8 100644
--- a/lib/python/labcomm/StreamWriter.py
+++ b/lib/python/labcomm2014/StreamWriter.py
@@ -1,5 +1,3 @@
-import labcomm
-
 class StreamWriter:
     
     def __init__(self, stream):
@@ -10,7 +8,10 @@ class StreamWriter:
         self.stream.write(data)
         pass
 
-    def mark(self):
+    def mark_begin(self, decl, value):
+        pass
+
+    def mark_end(self, decl, value):
         self.stream.flush()
         pass
 
diff --git a/lib/python/labcomm2014/__init__.py b/lib/python/labcomm2014/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..2e36c218d8fb8b8df01596bf9893ac5a3c0f68df
--- /dev/null
+++ b/lib/python/labcomm2014/__init__.py
@@ -0,0 +1,31 @@
+__all__ = [ 'LabComm' ]
+
+import LabComm
+
+from StreamReader import StreamReader
+from StreamWriter import StreamWriter
+
+Decoder = LabComm.Decoder
+Encoder = LabComm.Encoder
+
+sample = LabComm.sample_def
+sample_def = LabComm.sample_def
+sample_ref = LabComm.sample_ref
+typedef = LabComm.typedef
+
+array = LabComm.array
+struct = LabComm.struct
+primitive = LabComm.primitive
+
+BOOLEAN = LabComm.BOOLEAN
+BYTE = LabComm.BYTE
+SHORT = LabComm.SHORT
+INTEGER = LabComm.INTEGER
+LONG = LabComm.LONG
+FLOAT = LabComm.FLOAT
+DOUBLE = LabComm.DOUBLE
+STRING = LabComm.STRING
+SAMPLE = LabComm.SAMPLE
+
+decl_from_signature = LabComm.decl_from_signature
+
diff --git a/packaging/.gitignore b/packaging/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..9f87b19fef31586d928cf2dd4a18d5ea8c69a39f
--- /dev/null
+++ b/packaging/.gitignore
@@ -0,0 +1,2 @@
+labcomm-*.src.rpm
+rpmbuild
diff --git a/packaging/Makefile b/packaging/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..0c15aeb630ae9448d1d1df0e9a62847577fa6267
--- /dev/null
+++ b/packaging/Makefile
@@ -0,0 +1,18 @@
+.PHONY: all
+all:
+
+.PHONY: test
+test:
+
+.PHONY: clean
+clean:
+	rm -rf rpmbuild
+	rm -f *~
+
+.PHONY: distclean
+distclean: clean
+	rm -f labcomm-*.src.rpm
+
+.PHONY: srpm
+srpm:
+	./make_srpm
diff --git a/packaging/make_srpm b/packaging/make_srpm
new file mode 100755
index 0000000000000000000000000000000000000000..4925a831fe89f74a3bb3c0c45487540b1ba559d4
--- /dev/null
+++ b/packaging/make_srpm
@@ -0,0 +1,116 @@
+#!/bin/sh
+
+spec() {
+cat << 'EOF'
+Name:      labcomm__SUFFIX__
+Version:   __VERSION__
+Release:   1
+Summary:   LabComm communication protocol
+License:   GPLv3
+
+# https://gitlab.control.lth.se/anders_blomdell/labcomm/repository/archive.tar.gz?__COMMIT__
+Source0:  labcomm.__DESCRIBE__.tar.gz
+
+BuildRequires: gcc
+BuildRequires: ant
+BuildRequires: java
+BuildRequires: mono-core
+
+%description
+LabComm communication protocol
+
+%package devel
+Summary: LabComm communication protocol
+Requires: %{name} = %{version}-%{release}
+
+%description devel
+LabComm communication protocol
+
+%
+%prep
+%setup -q -c -a 0
+
+%build
+pwd
+make
+
+%install
+
+# 
+# C 
+#
+install -d ${RPM_BUILD_ROOT}/%{_libdir}
+install lib/c/liblabcomm2014.a ${RPM_BUILD_ROOT}/%{_libdir}/
+install lib/c/liblabcomm2014.so.1 ${RPM_BUILD_ROOT}/%{_libdir}/liblabcomm2014.so.__VERSION__
+ln -s liblabcomm2014.so.__VERSION__ ${RPM_BUILD_ROOT}/%{_libdir}/liblabcomm2014.so
+install -d ${RPM_BUILD_ROOT}/%{_includedir}/labcomm
+install lib/c/2014/*h ${RPM_BUILD_ROOT}/%{_includedir}/labcomm
+
+#
+# java 
+#
+install -d ${RPM_BUILD_ROOT}/usr/lib
+install -m u=r,g=r,o=r compiler/labcomm2014_compiler.jar ${RPM_BUILD_ROOT}/usr/lib
+install -m u=r,g=r,o=r lib/java/labcomm2014.jar ${RPM_BUILD_ROOT}/usr/lib
+
+install -d ${RPM_BUILD_ROOT}/%{_bindir}
+install -m u=rx,g=rx,o=rx \
+        compiler/labcomm2014 ${RPM_BUILD_ROOT}/%{_bindir}/labcomm2014
+ls -l ${RPM_BUILD_ROOT}/%{_bindir}
+
+#
+# C#
+#
+install -d ${RPM_BUILD_ROOT}/usr/lib
+install -m u=r,g=r,o=r lib/csharp/labcomm2014.dll ${RPM_BUILD_ROOT}/usr/lib
+
+#
+# Python
+#
+install -d ${RPM_BUILD_ROOT}/%{python_sitelib}/labcomm2014
+install lib/python/labcomm/* ${RPM_BUILD_ROOT}/%{python_sitelib}/labcomm2014
+
+%files
+%defattr (-, root, root)
+%exclude /usr/lib/debug
+%exclude /usr/lib/labcomm2014_compiler.jar
+/usr/lib/*
+%{_libdir}/*
+
+%files devel
+%defattr (-, root, root)
+/usr/lib/labcomm2014_compiler.jar
+%{_includedir}/labcomm/*
+%{_bindir}/*
+
+EOF
+}
+
+# Create a suitable directory for rpmbuild
+rm -rf rpmbuild
+mkdir -p rpmbuild/BUILD
+mkdir -p rpmbuild/SPECS
+mkdir -p rpmbuild/RPMS
+mkdir -p rpmbuild/SRPMS
+mkdir -p rpmbuild/SOURCES
+rm -rf rpmbuild/SOURCES/*
+
+# Create spec and .tar.gz
+DESCRIBE=$(git describe | sed -e 's/^v\(.*\)/\1/')
+SUFFIX=$(echo ${DESCRIBE} | sed -e 's/^\([^.]*\)[.].*$/\1/g')
+VERSION=$(echo ${DESCRIBE} | sed -e 's/^[^.]*[.]\(.*\)/\1/g;s/-/./g')
+COMMIT=$(git rev-parse HEAD)
+(
+    spec | \
+        sed -e "s/__SUFFIX__/${SUFFIX}/g" | \
+        sed -e "s/__VERSION__/${VERSION}/g" | \
+        sed -e "s/__DESCRIBE__/${DESCRIBE}/g" | \
+        sed -e "s/__COMMIT__/${COMMIT}/g" \
+) > rpmbuild/SPECS/labcomm.spec
+(
+    cd $(git rev-parse --show-toplevel)
+    git archive --format tar HEAD
+) > rpmbuild/SOURCES/labcomm.${DESCRIBE}.tar.gz
+rpmbuild --define "_topdir $(pwd)/rpmbuild" \
+         -bs rpmbuild/SPECS/labcomm.spec
+mv rpmbuild/SRPMS/* .
diff --git a/test/.gitignore b/test/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..4f62b849d56cd043cb9725fe73e9f49522d3d931
--- /dev/null
+++ b/test/.gitignore
@@ -0,0 +1 @@
+gen
diff --git a/test/Makefile b/test/Makefile
index 106810bafe9053807a2f59f8a46212d13853afad..57e86848bb81fc751e43fe167f58f168a81bb62b 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -1,5 +1,5 @@
 TESTS=basic simple nested ref
-LABCOMM_JAR=../compiler/labcomm_compiler.jar
+LABCOMM_JAR=../compiler/labcomm2014_compiler.jar
 LABCOMM=java -jar $(LABCOMM_JAR)
 
 include ../lib/c/os_compat.mk
@@ -78,13 +78,13 @@ gen/%/cs_relay.cs:  gen/%/typeinfo relay_gen_cs.py Makefile
 	./relay_gen_cs.py $< > $@
 
 .PRECIOUS: gen/%/labcomm.dll
-gen/%/labcomm.dll:
-	ln -s ../../../lib/csharp/labcomm.dll $@
+gen/%/labcomm2014.dll:
+	ln -s ../../../lib/csharp/labcomm2014.dll $@
 
 .PRECIOUS: gen/%/cs_relay.exe
 gen/%/cs_relay.exe: gen/%/cs_relay.cs gen/%/cs_code.cs \
-		    gen/%/labcomm.dll Makefile
-	mcs -out:$@ $(filter %.cs, $^) -lib:../lib/csharp/ -r:labcomm
+		    gen/%/labcomm2014.dll Makefile
+	mcs -out:$@ $(filter %.cs, $^) -lib:../lib/csharp/ -r:labcomm2014
 
 # Java relay test rules
 .PRECIOUS: gen/%/java_code
diff --git a/test/relay_gen_c.py b/test/relay_gen_c.py
index dd3f894efe0e00fbc29d428221a8987e500bc226..4d050640d0ec5b9091ff0c19d464ffd52361b5ba 100755
--- a/test/relay_gen_c.py
+++ b/test/relay_gen_c.py
@@ -27,32 +27,26 @@ if __name__ == '__main__':
       |#include <sys/types.h>
       |#include <sys/stat.h>
       |#include <fcntl.h>
-      |#include <labcomm.h>
-      |#include <labcomm_default_error_handler.h>
-      |#include <labcomm_default_memory.h>
-      |#include <labcomm_default_scheduler.h>
-      |#include <labcomm_fd_reader.h>
-      |#include <labcomm_fd_writer.h>
+      |#include <labcomm2014.h>
+      |#include <labcomm2014_default_error_handler.h>
+      |#include <labcomm2014_default_memory.h>
+      |#include <labcomm2014_default_scheduler.h>
+      |#include <labcomm2014_fd_reader.h>
+      |#include <labcomm2014_fd_writer.h>
       |#include "c_code.h"
     """))
     for func,arg,stype in sample:
         result.extend(split_match('^[^|]*\|(.*)$', """
           |void handle_%(func)s(%(arg)s *v, void *context)
           |{
-          |  struct labcomm_encoder *e = context;
-          |  labcomm_encode_%(func)s(e%(valargstr)s);
+          |  struct labcomm2014_encoder *e = context;
+          |  labcomm2014_encode_%(func)s(e%(valargstr)s);
           |}""" % { 'func': func, 'arg': arg, 'valargstr': '' if stype == "void" else', v' }))
-#        result.extend(split_match('^[^|]*\|(.*)$', """
-#          |void handle_%(func)s(%(arg)s *v, void *context)
-#          |{
-#          |  struct labcomm_encoder *e = context;
-#          |  labcomm_encode_%(func)s(e, v);
-#          |}""" % { 'func': func, 'arg': arg }))
         pass
     result.extend(split_match('^[^|]*\|(.*)$', """
       |int main(int argc, char *argv[]) {
-      |  struct labcomm_encoder *e;
-      |  struct labcomm_decoder *d;
+      |  struct labcomm2014_encoder *e;
+      |  struct labcomm2014_decoder *d;
       |  int in, out;
       |  
       |  if (argc < 3) { return 1; }
@@ -60,26 +54,26 @@ if __name__ == '__main__':
       |  if (in < 0) { return 1; }
       |  out = open(argv[2], O_WRONLY);
       |  if (out < 0) { return 1; }
-      |  e = labcomm_encoder_new(labcomm_fd_writer_new(
-      |                              labcomm_default_memory, out, 1), 
-      |                           labcomm_default_error_handler,
-      |                           labcomm_default_memory,
-      |                           labcomm_default_scheduler);
-      |  d = labcomm_decoder_new(labcomm_fd_reader_new(
-      |                              labcomm_default_memory, in, 1), 
-      |                           labcomm_default_error_handler,
-      |                           labcomm_default_memory,
-      |                           labcomm_default_scheduler);
+      |  e = labcomm2014_encoder_new(labcomm2014_fd_writer_new(
+      |                              labcomm2014_default_memory, out, 1), 
+      |                              labcomm2014_default_error_handler,
+      |                              labcomm2014_default_memory,
+      |                              labcomm2014_default_scheduler);
+      |  d = labcomm2014_decoder_new(labcomm2014_fd_reader_new(
+      |                              labcomm2014_default_memory, in, 1), 
+      |                              labcomm2014_default_error_handler,
+      |                              labcomm2014_default_memory,
+      |                              labcomm2014_default_scheduler);
     """))
     for func,arg,stype in sample:
         result.extend(split_match('^[^|]*\|(.*)$', """
-          |  labcomm_encoder_register_%(func)s(e);
-          |  labcomm_encoder_sample_ref_register(e, labcomm_signature_%(func)s);
-          |  labcomm_decoder_register_%(func)s(d, handle_%(func)s, e);
-          |  labcomm_decoder_sample_ref_register(d, labcomm_signature_%(func)s);
+          |  labcomm2014_encoder_register_%(func)s(e);
+          |  labcomm2014_encoder_sample_ref_register(e, labcomm2014_signature_%(func)s);
+          |  labcomm2014_decoder_register_%(func)s(d, handle_%(func)s, e);
+          |  labcomm2014_decoder_sample_ref_register(d, labcomm2014_signature_%(func)s);
        """ % { 'func': func, 'arg': arg }))
     result.extend(split_match('^[^|]*\|(.*)$', """
-      |  labcomm_decoder_run(d);
+      |  labcomm2014_decoder_run(d);
       |  return 0;
       |}
     """))
diff --git a/test/relay_gen_cs.py b/test/relay_gen_cs.py
index 8cd90431bd9cf4eee5bc747f613651f3c6999cbe..e5698aa06fbf0714fc8c6c1c9a561510fb7d076e 100755
--- a/test/relay_gen_cs.py
+++ b/test/relay_gen_cs.py
@@ -30,7 +30,7 @@ if __name__ == '__main__':
     result.extend(split_match('^[^|]*\|(.*)$', """
       |using System;
       |using System.IO;
-      |using se.lth.control.labcomm;
+      |using se.lth.control.labcomm2014;
       |
       |public class cs_relay :
     """))
diff --git a/test/relay_gen_java.py b/test/relay_gen_java.py
index a4a3b88d8e6fb60422b3db10ab79f32cec72ef25..c522367b4f98da99f0f2bca2639ba432ba8e0b49 100755
--- a/test/relay_gen_java.py
+++ b/test/relay_gen_java.py
@@ -31,9 +31,9 @@ if __name__ == '__main__':
       |import java.io.FileInputStream;
       |import java.io.FileOutputStream;
       |import java.io.IOException;
-      |import se.lth.control.labcomm.DecoderChannel;
-      |import se.lth.control.labcomm.EncoderChannel;
-      |import se.lth.control.labcomm.Sample;
+      |import se.lth.control.labcomm2014.DecoderChannel;
+      |import se.lth.control.labcomm2014.EncoderChannel;
+      |import se.lth.control.labcomm2014.Sample;
       |
       |public class java_relay implements
     """))
diff --git a/test/test_encoder_decoder.py b/test/test_encoder_decoder.py
index 7f0fb8baedb2afcc0f81e6f09cda443d1e509dd6..66e289ea1fd3d5a0ed8217ed715ed9b21f1d15df 100755
--- a/test/test_encoder_decoder.py
+++ b/test/test_encoder_decoder.py
@@ -3,7 +3,7 @@
 
 import argparse
 import imp
-import labcomm
+import labcomm2014
 import math
 import os
 import re
@@ -37,7 +37,7 @@ def get_signatures(path):
     with fp as fp:
         m = imp.load_module('signatures', fp, pathname, description)
         pass
-    return m.sample
+    return map(lambda s: s.signature, m.sample)
 
 class Test:
     
@@ -47,19 +47,25 @@ class Test:
         pass
 
     def generate(self, decl):
-        if decl.__class__ == labcomm.sample:
+        if decl.__class__ == labcomm2014.sample:
             result = []
             for values in self.generate(decl.decl):
                 result.append((decl, values))
             return result
     
-        elif decl.__class__ == labcomm.struct:
+        elif decl.__class__ == labcomm2014.typedef:
+            result = []
+            for values in self.generate(decl.decl):
+                result.append(values)
+            return result
+
+        elif decl.__class__ == labcomm2014.struct:
             result = []
             if len(decl.field) == 0:
                 result.append({})
             else:
                 values1 = self.generate(decl.field[0][1])
-                values2 = self.generate(labcomm.struct(decl.field[1:]))
+                values2 = self.generate(labcomm2014.struct(decl.field[1:]))
                 for v1 in values1:
                     for v2 in values2:
                         v = dict(v2)
@@ -67,7 +73,7 @@ class Test:
                         result.append(v)
             return result
         
-        elif decl.__class__ == labcomm.array:
+        elif decl.__class__ == labcomm2014.array:
             if len(decl.indices) == 1:
                 values = self.generate(decl.decl)
                 if decl.indices[0] == 0:
@@ -75,7 +81,7 @@ class Test:
                 else:
                     lengths = [ decl.indices[0] ]
             else:
-                values = self.generate(labcomm.array(decl.indices[1:],
+                values = self.generate(labcomm2014.array(decl.indices[1:],
                                                      decl.decl))
                 if decl.indices[0] == 0:
                     lengths = [1, 2]
@@ -90,53 +96,53 @@ class Test:
                     result.append(element)
             return result
     
-        elif decl.__class__ == labcomm.BOOLEAN:
+        elif decl.__class__ == labcomm2014.BOOLEAN:
             return [False, True]
     
-        elif decl.__class__ == labcomm.BYTE:
+        elif decl.__class__ == labcomm2014.BYTE:
             return [0, 127, 128, 255]
     
-        elif decl.__class__ == labcomm.SHORT:
+        elif decl.__class__ == labcomm2014.SHORT:
             return [-32768, 0, 32767]
     
-        elif decl.__class__ == labcomm.INTEGER:
+        elif decl.__class__ == labcomm2014.INTEGER:
             return [-2147483648, 0, 2147483647]
     
-        elif decl.__class__ == labcomm.LONG:
+        elif decl.__class__ == labcomm2014.LONG:
             return [-9223372036854775808, 0, 9223372036854775807]
     
-        elif decl.__class__ == labcomm.FLOAT:
+        elif decl.__class__ == labcomm2014.FLOAT:
             def tofloat(v):
                 return struct.unpack('f', struct.pack('f', v))[0]
             return [tofloat(-math.pi), 0.0, tofloat(math.pi)]
     
-        elif decl.__class__ == labcomm.DOUBLE:
+        elif decl.__class__ == labcomm2014.DOUBLE:
             return [-math.pi, 0.0, math.pi]
     
-        elif decl.__class__ == labcomm.STRING:
+        elif decl.__class__ == labcomm2014.STRING:
             return ['string', u'sträng' ]
     
-        elif decl.__class__ == labcomm.SAMPLE:
-            return [ s for n,s in self.signatures ]
+        elif decl.__class__ == labcomm2014.SAMPLE:
+            return self.signatures
     
         print>>sys.stderr, decl
         raise Exception("unhandled decl %s" % decl.__class__)
 
     def uses_refs(self, decls):
         for decl in decls:
-            if decl.__class__ == labcomm.sample:
+            if decl.__class__ == labcomm2014.sample:
                 if self.uses_refs([ decl.decl ]):
                     return True
     
-            elif decl.__class__ == labcomm.struct:
+            elif decl.__class__ == labcomm2014.struct:
                 if self.uses_refs([ d for n,d in decl.field ]):
                     return True
         
-            elif decl.__class__ == labcomm.array:
+            elif decl.__class__ == labcomm2014.array:
                 if self.uses_refs([ decl.decl ]):
                     return True
 
-            elif decl.__class__ == labcomm.SAMPLE:
+            elif decl.__class__ == labcomm2014.SAMPLE:
                 return True
 
         return False
@@ -153,18 +159,17 @@ class Test:
         self.next = threading.Condition()
         decoder = threading.Thread(target=self.decode, args=(p.stdout,))
         decoder.start()
-        encoder = labcomm.Encoder(labcomm.StreamWriter(p.stdin))
-        for name,signature in self.signatures:
+        encoder = labcomm2014.Encoder(labcomm2014.StreamWriter(p.stdin))
+        for signature in self.signatures:
             encoder.add_decl(signature)
             pass
-        if self.uses_refs([ s for n,s in self.signatures ]):
-            for name,signature in self.signatures:
+        if self.uses_refs(self.signatures):
+            for signature in self.signatures:
                 encoder.add_ref(signature)
-        for name,signature in self.signatures:
-            print>>sys.stderr, "Checking", name,
+        for signature in self.signatures:
+            print>>sys.stderr, "Checking", signature.name,
             for decl,value in self.generate(signature):
                 sys.stderr.write('.')
-                #print name,decl,value,value.__class__
                 self.next.acquire()
                 self.received_value = None
                 self.received_decl = None
@@ -176,7 +181,7 @@ class Test:
                     self.failed = True
                 elif value != self.received_value:
                     print>>sys.stderr, "Coding error"
-                    print>>sys.stderr,value == self.received_value
+                    print>>sys.stderr, value == self.received_value
                     print>>sys.stderr, "Got:     ", self.received_value 
                     print>>sys.stderr, "         ", self.received_decl 
                     print>>sys.stderr, "Expected:", value
@@ -197,7 +202,7 @@ class Test:
         pass
 
     def decode(self, f):
-        decoder = labcomm.Decoder(labcomm.StreamReader(f))
+        decoder = labcomm2014.Decoder(labcomm2014.StreamReader(f))
         try:
             while True:
                 value,decl = decoder.decode()
diff --git a/tools/lc2csv.py b/tools/lc2csv.py
index 134782e60288e989fa9caef239aed24ca25a6897..f887bdaf3510841e7dbb9e9c02fd01557f82d471 100755
--- a/tools/lc2csv.py
+++ b/tools/lc2csv.py
@@ -1,12 +1,14 @@
 #!/usr/bin/env python
 
+import argparse
+import labcomm2014
 import sys
-import labcomm
+import time
 
 
 class Reader(object):
-    def __init__(self, _file):
-        self._file = open(_file)
+    def __init__(self, file_):
+        self._file = file_
 
     def read(self, count):
         data = self._file.read(count)
@@ -18,43 +20,91 @@ class Reader(object):
         pass
 
 
+class FollowingReader(Reader):
+    def __init__(self, file_, interval, timeout):
+        super(FollowingReader, self).__init__(file_)
+        self._interval = interval
+        self._timeout = timeout
+
+    def read(self, count):
+        data = ''
+        t_start = time.time()
+        while len(data) < count:
+            tmp = self._file.read(count - len(data))
+            if tmp:
+                data += tmp
+            else:
+                time.sleep(self._interval)
+                if self._timeout and time.time() - t_start > self._timeout:
+                    raise EOFError()
+        return data
+
+
 def flatten(sample, _type):
-    if isinstance(_type, labcomm.sample):
+    if isinstance(_type, labcomm2014.sample):
         flatten(sample, _type.decl)
-    elif isinstance(_type, labcomm.array):
+    elif isinstance(_type, labcomm2014.array):
         for e in sample:
             flatten(e, _type.decl)
-    elif isinstance(_type, labcomm.struct):
+    elif isinstance(_type, labcomm2014.struct):
         for name, decl in _type.field:
             flatten(sample[name], decl)
-    elif isinstance(_type, labcomm.BOOLEAN):
+    elif isinstance(_type, labcomm2014.BOOLEAN):
         print "%d," % sample,
-    elif isinstance(_type, labcomm.STRING):
+    elif isinstance(_type, labcomm2014.STRING):
         print "\"%s\"," % sample,
-    elif isinstance(_type, labcomm.primitive):
+    elif isinstance(_type, labcomm2014.primitive):
         print "%s," % sample,
     else:
-        print sample, _type
+        raise Exception("Unhandled type. " + str(type(type_)) + " " + str(type_))
 
 
-def flatten_labels(sample, _type, prefix=""):
-    if isinstance(_type, labcomm.sample):
-        flatten_labels(sample, _type.decl, _type.name)
-    elif isinstance(_type, labcomm.array):
+def flatten_labels(_type, prefix=""):
+    if isinstance(_type, labcomm2014.sample):
+        flatten_labels(_type.decl, _type.name)
+    elif isinstance(_type, labcomm2014.array):
         if len(_type.indices) != 1:
             raise Exception("Fix multidimensional arrays")
-        if len(sample) == 0:
+        if len(_type.indices) == 0:
             raise Exception("We dont't handle dynamical sizes yet %s" % _type)
-        for i in range(0, len(sample)):
-            flatten_labels(sample[i], _type.decl, prefix + "[%d]" % i)
-    elif isinstance(_type, labcomm.struct):
+        for i in range(0, _type.indices[0]):
+            flatten_labels(_type.decl, prefix + "[%d]" % i)
+    elif isinstance(_type, labcomm2014.struct):
         for name, decl in _type.field:
-            flatten_labels(sample[name], decl,
+            flatten_labels(decl,
                            prefix + "." + name)
-    elif isinstance(_type, labcomm.primitive):
+    elif isinstance(_type, labcomm2014.primitive):
         print '"%s",' % prefix,
     else:
-        print sample, _type
+        raise Exception("Unhandled type. " + str(type(type_)) + " " + str(type_))
+
+
+def default(type_):
+    if isinstance(type_, labcomm2014.sample):
+        return default(type_.decl)
+    elif isinstance(type_, labcomm2014.array):
+        if len(type_.indices) != 1:
+            raise Exception("Fix multidimensional arrays")
+        if len(type_.indices) == 0:
+            raise Exception("We dont't handle dynamical sizes yet %s" % type_)
+        for i in range(0, type_.indices[0]):
+            return [default(type_.decl) for _ in range(type_.indices[0])]
+    elif isinstance(type_, labcomm2014.struct):
+        return {name: default(decl) for name, decl in type_.field}
+    elif isinstance(type_, labcomm2014.STRING):
+        return ''
+    elif isinstance(type_, labcomm2014.BOOLEAN):
+        return False
+    elif (isinstance(type_, labcomm2014.FLOAT) or
+          isinstance(type_, labcomm2014.DOUBLE)):
+        return float('NaN')
+    elif (isinstance(type_, labcomm2014.BYTE) or
+          isinstance(type_, labcomm2014.SHORT) or
+          isinstance(type_, labcomm2014.INTEGER) or
+          isinstance(type_, labcomm2014.LONG)):
+        return 0
+    else:
+        raise Exception("Unhandled type. " + str(type(type_)) + " " + str(type_))
 
 
 def dump(sample, _type):
@@ -63,49 +113,84 @@ def dump(sample, _type):
     print
 
 
-def dump_labels(current, _type):
-    for k in sorted(_type.keys()):
-        flatten_labels(current[k], _type[k])
+def dump_labels(type_):
+    for k in sorted(type_.keys()):
+        flatten_labels(type_[k])
     print
 
 
-def main():
-    if len(sys.argv) != 2:
-        sys.exit("Give input file as argument\n")
-    d = labcomm.Decoder(Reader(sys.argv[1]))
-    seen = {}
-    current = {}
-    _type = {}
-
-    # Do one pass through the file to find all registrations.
+def defaults(current, type_):
+    for k in sorted(type_.keys()):
+        if k not in current:
+            current[k] = default(type_[k])
+
+
+def main(main_args):
+    parser = argparse.ArgumentParser()
+    parser.add_argument('elc', type=str, help="The log file.")
+    parser.add_argument('-f', '--follow', action='store_true',
+                        help="find all registrations that already "
+                        "exist, then watch the file for changes. All "
+                        "future registrations are ignored (because "
+                        "the header has already been written).")
+    parser.add_argument('-s', '--interval', action="store", type=float,
+                        default=0.040,
+                        help="time to sleep between failed reads. Requires -f.")
+    parser.add_argument('-t', '--timeout', action="store", type=float,
+                        help="timeout to terminate when no changes are detected. "
+                        "Requires -f.")
+    parser.add_argument('-w', '--no-default-columns', action="store_true",
+                        help="Do not fill columns for which there is no "
+                        "data with default values. Wait instead until at least "
+                        "one sample has arrived for each registration.")
+    parser.add_argument('-a', '--trigger-all', action="store_true",
+                        help="Output one line for each sample instead of for "
+                        "each sample of the registration that has arrived with "
+                        "the highest frequency.")
+    args = parser.parse_args(main_args)
+    n_samples = {}         # The number of received samples for each sample reg.
+    current = {}           # The most recent sample for each sample reg.
+    type_ = {}             # The type (declaration) of each sample reg.
+    file_ = open(args.elc)
+    if args.follow:
+        reader = FollowingReader(file_, args.interval, args.timeout)
+    else:
+        reader = Reader(file_)
+    d = labcomm2014.Decoder(reader)
     while True:
         try:
             o, t = d.decode()
             if o is None:
-                seen[t.name] = 0
-                _type[t.name] = t
+                n_samples[t.name] = 0
+                type_[t.name] = t
             else:
+                n_samples[t.name] += 1
                 current[t.name] = o
+                break
         except EOFError:
             break
-    dump_labels(current, _type)
-
-    # Do another pass to extract the data.
-    current = {}
-    d = labcomm.Decoder(Reader(sys.argv[1]))
+    dump_labels(type_)
+    if not args.no_default_columns:
+        defaults(current, type_)
+    n_rows = 0
     while True:
         try:
             o, t = d.decode()
-            if o is not None:
-                current[t.name] = o
-                if len(current) == len(_type):
-                    # Assume that samples arrive at different rates.
-                    # Trigger on everything once we have a value for
-                    # each column.
-                    dump(current, _type)
+            if o is None:
+                continue
+            current[t.name] = o
+            n_samples[t.name] += 1
+            if len(current) < len(type_):
+                continue
+            if args.trigger_all:
+                dump(current, type_)
+            else:
+                if n_samples[t.name] > n_rows:
+                    n_rows = n_samples[t.name]
+                    dump(current, type_)
         except EOFError:
             break
 
 
 if __name__ == "__main__":
-    main()
+    main(sys.argv[1:])
diff --git a/tools/lc_to_matlab_coder.py b/tools/lc_to_matlab_coder.py
new file mode 100755
index 0000000000000000000000000000000000000000..dda966586b774727f98233f6ad3e88b8402e4fd5
--- /dev/null
+++ b/tools/lc_to_matlab_coder.py
@@ -0,0 +1,108 @@
+#!/usr/bin/python
+
+import sys
+import imp
+import subprocess
+import os
+import labcomm2014
+
+TRANSLATE={
+    labcomm2014.SHORT() : 'short',
+    labcomm2014.DOUBLE() : 'double'
+}
+
+def compile_lc(lc):
+    p = subprocess.Popen([ 'labcomm2014', '--python=/dev/stdout', lc],
+                         stdout=subprocess.PIPE)
+    src = p.stdout.read()
+    code = compile(src, 'lc_import', 'exec')
+    mod = sys.modules.setdefault('lc_import', imp.new_module('lc_import'))
+    exec code in mod.__dict__
+    import lc_import
+    return (lc_import.typedef, lc_import.sample)
+
+def gen_binding(decl, lc_prefix, prefix, suffix):
+    if isinstance(decl, labcomm2014.sample):
+        if isinstance(decl.decl, labcomm2014.typedef):
+            print "%(n1)s = coder.cstructname(%(n1)s, '%(lc)s_%(n2)s')" % dict(
+                n1=decl.name, n2=decl.decl.name, lc=lc_prefix)
+        else:
+            print "%(n1)s = coder.cstructname(%(n1)s, '%(lc)s_%(n2)s')" % dict(
+                n1=decl.name, n2=decl.name, lc=lc_prefix)
+        gen_binding(decl.decl, lc_prefix, '%s.' % decl.name, suffix)
+    elif isinstance(decl, labcomm2014.typedef):
+        print "%(p)s%(s)s = coder.cstructname(%(p)s%(s)s, '%(lc)s_%(n)s')" % dict(
+            n=decl.name, lc=lc_prefix, p=prefix, s=suffix)
+        gen_binding(decl.decl, lc_prefix, prefix, suffix)
+    elif isinstance(decl, labcomm2014.array):
+         raise Exception("Array unhandled")
+    elif isinstance(decl, labcomm2014.struct):
+        for n, d in decl.field:
+            gen_binding(d, lc_prefix, '%sFields.%s' % (prefix, n), suffix)
+    elif isinstance(decl, labcomm2014.primitive):
+        pass
+    else:
+        raise Exception("Unhandled type. %s", decl)
+    
+def gen_sample(lc_prefix, decl):
+    if isinstance(decl, labcomm2014.sample):
+        print "%s = " % decl.name,
+        gen_sample(lc_prefix, decl.decl)
+        print
+        gen_binding(decl, lc_prefix, '', '')
+    elif isinstance(decl, labcomm2014.typedef):
+        # Expand in place
+        gen_sample(lc_prefix, decl.decl)
+    elif isinstance(decl, labcomm2014.array):
+         raise Exception("Array unhandled")
+    elif isinstance(decl, labcomm2014.struct):
+        print "struct(..."
+        for n, d in decl.field:
+            print "'%s, " % n,
+            gen_sample(lc_prefix, d)
+        print ")..."
+    elif isinstance(decl, labcomm2014.primitive):
+        print "%s(0), ..." % TRANSLATE[decl]
+    else:
+        raise Exception("Unhandled type. %s", decl)  
+
+"""
+robtarget = struct(...
+	'orientation', ...
+	struct(...
+	    'q1', double(0), ...
+	    'q2', double(0), ...
+	    'q3', double(0), ...
+	    'q4', double(0) ...
+	), ...
+	'translation', ...
+	struct(...
+	    'x', double(0), ...
+	    'y', double(0), ...
+	    'z', double(0) ...
+	), ...
+	'configuration', ...
+	struct(...
+	    'cf1', int16(0), ...
+	    'cf4', int16(0), ...
+	    'cf6', int16(0), ...
+	    'cfx', int16(0) ...
+	) ...
+);
+robtarget_types = coder.typeof(robtarget);
+
+act = coder.cstructname(robtarget_types, 'egm_pb2lc_robtarget');
+act.Fields.translation = coder.cstructname(act.Fields.translation, 'egm_pb2lc_cartesian');
+act.Fields.orientation = coder.cstructname(act.Fields.orientation, 'egm_pb2lc_quaternion');
+act.Fields.configuration = coder.cstructname(act.Fields.configuration, 'egm_pb2lc_confdata');
+"""
+
+def gen_matlab(lc):
+    lc_prefix = os.path.basename(lc).split('.')[0]
+    typedef, sample = compile_lc(lc)
+    for s in sample:
+        gen_sample(lc_prefix, s.signature)
+
+if __name__ == '__main__':
+    for lc in sys.argv[1:]:
+        gen_matlab(lc)