diff --git a/compiler/C_CodeGen.jrag b/compiler/C_CodeGen.jrag
index d4450880d9034413dc9b16b6f43c9823915bd2ae..f79bbfce3698346a3c38fb50cb50f85b1292b1b2 100644
--- a/compiler/C_CodeGen.jrag
+++ b/compiler/C_CodeGen.jrag
@@ -803,8 +803,8 @@ aspect C_Signature {
       }
     }
     env.println("};");
-    env.println("labcomm_signature_t labcomm_signature_" + 
-		env.prefix + getName() + " = {");
+    env.println("LABCOMM_DECLARE_SIGNATURE(labcomm_signature_" + 
+		env.prefix + getName() + ") = {");
     env.indent();
     env.println("LABCOMM_SAMPLE, \"" + getName() + "\",");
     env.println("(int (*)(labcomm_signature_t *, void *))labcomm_sizeof_" + 
diff --git a/lib/c/Makefile b/lib/c/Makefile
index dd08db025ec66e0511a55cdc55cd544cc846512f..f201fa66a5421b35325bc66f1c86984d6a71b822 100644
--- a/lib/c/Makefile
+++ b/lib/c/Makefile
@@ -2,15 +2,15 @@
 
 # Use LLVM clang if it's found.
 CC = $(shell hash clang 2>/dev/null && echo clang || echo gcc)
-CFLAGS = -g -Wall -Werror -O3  -I. -Itest
+CFLAGS = -g -Wall -Werror -O3  -I. -Itest -DLABCOMM_ENCODER_LINEAR_SEARCH
 LDFLAGS = -L.
-LDLIBS_TEST = -lcunit -llabcomm
+LDLIBS_TEST = -Tlabcomm.linkscript  -lcunit -llabcomm
 
-OBJS= labcomm.o labcomm_dynamic_buffer_writer.o labcomm_fd_reader_writer.o labcomm_mem_reader.o labcomm_mem_writer.o
+OBJS= labcomm.o labcomm_dynamic_buffer_writer.o labcomm_fd_reader.o labcomm_fd_writer.o labcomm_mem_reader.o labcomm_mem_writer.o
 LABCOMMC_PATH=../../compiler
 LABCOMMC_JAR=$(LABCOMMC_PATH)/labComm.jar
 
-TESTS=test_labcomm_private test_labcomm test_labcomm_errors
+TESTS=test_labcomm_basic_type_encoding test_labcomm test_labcomm_errors
 TEST_DIR=test
 TESTDATA_DIR=$(TEST_DIR)/testdata
 TEST_GEN_DIR=$(TESTDATA_DIR)/gen
@@ -42,9 +42,9 @@ labcomm.o : labcomm.c labcomm.h  labcomm_private.h
 
 labcomm_fd_reader_writer.o : labcomm_fd_reader_writer.c  labcomm_fd_reader_writer.h  labcomm.h  labcomm_private.h
 
-$(TEST_DIR)/labcomm_mem_reader.o: labcomm_fd_reader_writer.c labcomm_fd_reader_writer.h
+#$(TEST_DIR)/labcomm_mem_reader.o: labcomm_fd_reader_writer.c labcomm_fd_reader_writer.h
 
-$(TEST_DIR)/labcomm_mem_writer.o: labcomm_mem_writer.c labcomm_mem_writer.h cppmacros.h
+#$(TEST_DIR)/labcomm_mem_writer.o: labcomm_mem_writer.c labcomm_mem_writer.h cppmacros.h
 
 ethaddr.o: ethaddr.c
 
diff --git a/lib/c/labcomm.c b/lib/c/labcomm.c
index 5256de8fc4b0012fc4c7e05f4d8fba6fb9843eb4..bdcd204edf7e189ecea889664ce80ef66e1c1d9a 100644
--- a/lib/c/labcomm.c
+++ b/lib/c/labcomm.c
@@ -7,11 +7,15 @@
 
 #include <errno.h>
 #include <string.h>
+#include <stdarg.h>
+
 #include "labcomm.h"
 #include "labcomm_private.h"
 #include "labcomm_ioctl.h"
 #include "labcomm_dynamic_buffer_writer.h"
 
+#define LABCOMM_VERSION "LabComm2013"
+
 typedef struct labcomm_sample_entry {
   struct labcomm_sample_entry *next;
   int index;
@@ -146,6 +150,8 @@ static labcomm_sample_entry_t *get_sample_by_index(
   return p;
 }
 
+#ifdef LABCOMM_ENCODER_LINEAR_SEARCH
+
 static int get_encoder_index(
   labcomm_encoder_t *e,
   labcomm_signature_t *s)
@@ -163,6 +169,25 @@ static int get_encoder_index(
   return result;
 }
 
+#else
+
+static int get_encoder_index(
+  labcomm_encoder_t *e,
+  labcomm_signature_t *s)
+{
+  int result = 0;
+  extern  labcomm_signature_t labcomm_first_signature;
+  extern  labcomm_signature_t labcomm_last_signature;
+
+  if (&labcomm_first_signature <= s && s <= &labcomm_last_signature) {
+    //fprintf(stderr, "%d\n", (int)(s - &labcomm_start));
+    result = s - &labcomm_first_signature + LABCOMM_USER;
+  }
+  return result;
+}
+
+#endif
+
 void labcomm_encoder_start(struct labcomm_encoder *e,
                            labcomm_signature_t *s) 
 {
@@ -301,12 +326,6 @@ void labcomm_internal_encode(
   }
 }
 
-void labcomm_internal_encoder_user_action(labcomm_encoder_t *e,
-					  int action)
-{
-  e->writer.write(&e->writer, action);
-}
-
 void labcomm_encoder_free(labcomm_encoder_t* e)
 {
   e->writer.write(&e->writer, labcomm_writer_free);
@@ -501,7 +520,7 @@ static int do_decode_one(labcomm_decoder_t *d)
 }
 
 labcomm_decoder_t *labcomm_decoder_new(
-  int (*reader)(labcomm_reader_t *, labcomm_reader_action_t),
+  int (*reader)(labcomm_reader_t *, labcomm_reader_action_t, ...),
   void *reader_context)
 {
   labcomm_decoder_t *result = malloc(sizeof(labcomm_decoder_t));
@@ -522,7 +541,7 @@ labcomm_decoder_t *labcomm_decoder_new(
     result->do_decode_one = do_decode_one;
     result->on_error = on_error_fprintf;
     result->on_new_datatype = on_new_datatype;
-    result->reader.read(&result->reader, labcomm_reader_alloc);
+    result->reader.read(&result->reader, labcomm_reader_alloc, LABCOMM_VERSION);
   }
   return result;
 }
diff --git a/lib/c/labcomm.h b/lib/c/labcomm.h
index baedb8d0d9b3c56be9bf24c3405876943823dae2..48d4cbe05b42c0981176acfc991b9252b65b6846 100644
--- a/lib/c/labcomm.h
+++ b/lib/c/labcomm.h
@@ -1,20 +1,8 @@
 #ifndef _LABCOMM_H_
 #define _LABCOMM_H_
 
-#ifdef ARM_CORTEXM3_CODESOURCERY
-  #include <machine/endian.h>
-#else
-  #include <endian.h>
-#endif
-
-// Some projects can not use stdio.h.
-#ifndef LABCOMM_NO_STDIO
-  #include <stdio.h>
-#endif
-
-#include <stdlib.h>
-#include <string.h>
 #include <stdarg.h>
+#include <unistd.h>
 
 /* Forward declaration */
 struct labcomm_encoder;
@@ -94,7 +82,8 @@ void labcomm_decoder_register_new_datatype_handler(struct labcomm_decoder *d,
  */
 
 typedef enum { 
-  labcomm_reader_alloc, 
+  labcomm_reader_alloc,     /* (..., char *labcomm_version)
+			       Allocate all neccessary data */
   labcomm_reader_free,
   labcomm_reader_start, 
   labcomm_reader_continue, 
@@ -108,13 +97,13 @@ typedef struct labcomm_reader {
   int data_size;
   int count;
   int pos;
-  int (*read)(struct labcomm_reader *, labcomm_reader_action_t);
+  int (*read)(struct labcomm_reader *, labcomm_reader_action_t, ...);
   int (*ioctl)(struct labcomm_reader *, int, va_list);
   labcomm_error_handler_callback on_error;
 }  labcomm_reader_t;
 
 struct labcomm_decoder *labcomm_decoder_new(
-  int (*reader)(labcomm_reader_t *, labcomm_reader_action_t),
+  int (*reader)(labcomm_reader_t *, labcomm_reader_action_t, ...),
   void *reader_context);
 int labcomm_decoder_decode_one(
   struct labcomm_decoder *decoder);
@@ -128,7 +117,8 @@ void labcomm_decoder_free(
  */
 
 typedef enum { 
-  labcomm_writer_alloc,              /* Allocate all neccessary data */
+  labcomm_writer_alloc,              /* (..., char *labcomm_version)
+					Allocate all neccessary data */
   labcomm_writer_free,               /* Free all allocated data */
   labcomm_writer_start,              /* Start writing an ordinary sample */
   labcomm_writer_continue,           /* Buffer full during ordinary sample */
diff --git a/lib/c/labcomm.linkscript b/lib/c/labcomm.linkscript
new file mode 100644
index 0000000000000000000000000000000000000000..27cf28f393d74530420884701d54ec3971cf4a7a
--- /dev/null
+++ b/lib/c/labcomm.linkscript
@@ -0,0 +1,8 @@
+SECTIONS { 
+  labcomm : {
+    labcomm_first_signature = ABSOLUTE(.) ;
+    *(labcomm)
+    labcomm_last_signature = ABSOLUTE(.) ;
+  }
+}
+INSERT AFTER .data;
diff --git a/lib/c/labcomm_dynamic_buffer_writer.c b/lib/c/labcomm_dynamic_buffer_writer.c
index 5e180ec820203d3d28cb82d54614d938170281de..4c2017119fa385b2167fe4bc497d03ac8c550968 100644
--- a/lib/c/labcomm_dynamic_buffer_writer.c
+++ b/lib/c/labcomm_dynamic_buffer_writer.c
@@ -1,4 +1,6 @@
 #include <errno.h>
+#include <stdlib.h>
+#include <stdarg.h>
 #include "labcomm_ioctl.h"
 #include "labcomm_dynamic_buffer_writer.h"
 
diff --git a/lib/c/labcomm_fd_reader_writer.c b/lib/c/labcomm_fd_reader.c
similarity index 52%
rename from lib/c/labcomm_fd_reader_writer.c
rename to lib/c/labcomm_fd_reader.c
index 3ddafc4e08ca3ac9ff63ddca429578850003ed28..62cb6b469265b3670976a3a801681c7a9fc5611a 100644
--- a/lib/c/labcomm_fd_reader_writer.c
+++ b/lib/c/labcomm_fd_reader.c
@@ -1,18 +1,29 @@
 #include <errno.h>
 #include <unistd.h>
-#include "labcomm_fd_reader_writer.h"
+#include <stdlib.h>
+#include <string.h>
+#include "labcomm_fd_reader.h"
 
 #define BUFFER_SIZE 2048
 
 int labcomm_fd_reader(
   labcomm_reader_t *r, 
-  labcomm_reader_action_t action)
+  labcomm_reader_action_t action,
+  ...)
 {
   int result = -EINVAL;
   int *fd = r->context;
   
   switch (action) {
     case labcomm_reader_alloc: {
+      va_list ap;
+      va_start(ap, action);
+      char *version = va_arg(ap, char *);
+      char *tmp = strdup(version);
+
+      read(*fd, tmp, strlen(version));
+      free(tmp);
+
       r->data = malloc(BUFFER_SIZE);
       if (r->data) {
         r->data_size = BUFFER_SIZE;
@@ -23,6 +34,7 @@ int labcomm_fd_reader(
       }
       r->count = 0;
       r->pos = 0;
+      va_end(ap);
     } break;
     case labcomm_reader_start: 
     case labcomm_reader_continue: {
@@ -60,48 +72,3 @@ int labcomm_fd_reader(
   return result;
 }
 
-int labcomm_fd_writer(
-  labcomm_writer_t *w, 
-  labcomm_writer_action_t action, ...)
-{
-  int result = 0;
-  int *fd = w->context;
-
-  switch (action) {
-    case labcomm_writer_alloc: {
-      w->data = malloc(BUFFER_SIZE);
-      if (! w->data) {
-        result = -ENOMEM;
-        w->data_size = 0;
-        w->count = 0;
-        w->pos = 0;
-      } else {
-        w->data_size = BUFFER_SIZE;
-        w->count = BUFFER_SIZE;
-        w->pos = 0;
-      }
-    } break;
-    case labcomm_writer_free: {
-      free(w->data);
-      w->data = 0;
-      w->data_size = 0;
-      w->count = 0;
-      w->pos = 0;
-    } break;
-    case labcomm_writer_start: 
-    case labcomm_writer_start_signature: {
-      w->pos = 0;
-    } break;
-    case labcomm_writer_continue: 
-    case labcomm_writer_continue_signature: {
-      result = write(*fd, w->data, w->pos);
-      w->pos = 0;
-    } break;
-    case labcomm_writer_end: 
-    case labcomm_writer_end_signature: {
-      result = write(*fd, w->data, w->pos);
-      w->pos = 0;
-    } break;
-  }
-  return result;
-}
diff --git a/lib/c/labcomm_fd_reader.h b/lib/c/labcomm_fd_reader.h
new file mode 100644
index 0000000000000000000000000000000000000000..c06cb3ada399b8a31cf5e9bd9ae914adf3a46f05
--- /dev/null
+++ b/lib/c/labcomm_fd_reader.h
@@ -0,0 +1,12 @@
+#ifndef _LABCOMM_FD_READER_H_
+#define _LABCOMM_FD_READER_H_
+
+#include "labcomm.h"
+
+extern int labcomm_fd_reader(
+  labcomm_reader_t *reader, 
+  labcomm_reader_action_t action,
+  ...);
+
+#endif
+
diff --git a/lib/c/labcomm_fd_reader_writer.h b/lib/c/labcomm_fd_reader_writer.h
deleted file mode 100644
index e5125d549d4623d1d98fabfe832cd4510e8ff574..0000000000000000000000000000000000000000
--- a/lib/c/labcomm_fd_reader_writer.h
+++ /dev/null
@@ -1,16 +0,0 @@
-#ifndef _LABCOMM_FD_READER_WRITER_H_
-#define _LABCOMM_FD_READER_WRITER_H_
-
-#include "labcomm.h"
-
-extern int labcomm_fd_reader(
-  labcomm_reader_t *reader, 
-  labcomm_reader_action_t action);
-
-extern int labcomm_fd_writer(
-  labcomm_writer_t *writer, 
-  labcomm_writer_action_t action,
-  ...);
-
-#endif
-
diff --git a/lib/c/labcomm_fd_writer.c b/lib/c/labcomm_fd_writer.c
new file mode 100644
index 0000000000000000000000000000000000000000..196e18f3d6a47d8264f9ebfb47118255e7aaca41
--- /dev/null
+++ b/lib/c/labcomm_fd_writer.c
@@ -0,0 +1,61 @@
+#include <errno.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include "labcomm_fd_writer.h"
+
+#define BUFFER_SIZE 2048
+
+int labcomm_fd_writer(
+  labcomm_writer_t *w, 
+  labcomm_writer_action_t action,
+  ...)
+{
+  int result = 0;
+  int *fd = w->context;
+
+  switch (action) {
+    case labcomm_writer_alloc: {
+      va_list ap;
+      va_start(ap, action);
+      char *version = va_arg(ap, char *);
+
+      write(*fd, version, strlen(version));
+      w->data = malloc(BUFFER_SIZE);
+      if (! w->data) {
+        result = -ENOMEM;
+        w->data_size = 0;
+        w->count = 0;
+        w->pos = 0;
+      } else {
+        w->data_size = BUFFER_SIZE;
+        w->count = BUFFER_SIZE;
+        w->pos = 0;
+      }
+      va_end(ap);
+    } break;
+    case labcomm_writer_free: {
+      free(w->data);
+      w->data = 0;
+      w->data_size = 0;
+      w->count = 0;
+      w->pos = 0;
+    } break;
+    case labcomm_writer_start: 
+    case labcomm_writer_start_signature: {
+      w->pos = 0;
+    } break;
+    case labcomm_writer_continue: 
+    case labcomm_writer_continue_signature: {
+      result = write(*fd, w->data, w->pos);
+      w->pos = 0;
+    } break;
+    case labcomm_writer_end: 
+    case labcomm_writer_end_signature: {
+      result = write(*fd, w->data, w->pos);
+      w->pos = 0;
+    } break;
+  }
+  return result;
+}
diff --git a/lib/c/labcomm_fd_writer.h b/lib/c/labcomm_fd_writer.h
new file mode 100644
index 0000000000000000000000000000000000000000..ea89eb29fe38b0147bbff077c627de72e8bef8bb
--- /dev/null
+++ b/lib/c/labcomm_fd_writer.h
@@ -0,0 +1,12 @@
+#ifndef _LABCOMM_FD_WRITER_H_
+#define _LABCOMM_FD_WRITER_H_
+
+#include "labcomm.h"
+
+extern int labcomm_fd_writer(
+  labcomm_writer_t *writer, 
+  labcomm_writer_action_t action,
+  ...);
+
+#endif
+
diff --git a/lib/c/labcomm_private.h b/lib/c/labcomm_private.h
index 2d6777871ed1d377768e837c3418c1100690d685..4271200ed144b5dc0e1841d797cb6685135d54f5 100644
--- a/lib/c/labcomm_private.h
+++ b/lib/c/labcomm_private.h
@@ -38,6 +38,12 @@
  */
 #define LABCOMM_USER     0x40
 
+/*
+ *
+ */
+#define LABCOMM_DECLARE_SIGNATURE(name) \
+  labcomm_signature_t name __attribute__((section("labcomm")))
+
 /*
  * Semi private decoder declarations
  */
@@ -194,34 +200,6 @@ static inline char *labcomm_decode_string(labcomm_decoder_t *d)
   return labcomm_read_string(&d->reader);
 }
 
-static inline int labcomm_buffer_read(struct labcomm_reader *r, 
-				      labcomm_reader_action_t action)
-{
-  // If this gets called, it is an error, 
-  // so note error and let producer proceed
-  r->context = r;
-  r->pos = 0;
-  return 0;
-}
-
-static inline int labcomm_buffer_reader_error(struct labcomm_reader *r) 
-{
-  return r->context != NULL;
-} 
-
-static inline void labcomm_buffer_reader_setup(
-  labcomm_reader_t *r,
-  void *data,
-  int length)
-{
-  r->context = NULL; // Used as error flag
-  r->data = data;  
-  r->data_size = length;
-  r->count = length;
-  r->pos = 0;
-  r->read = labcomm_buffer_read;
-}
-
 /*
  * Semi private encoder declarations
  */
diff --git a/lib/c/test/labcomm_mem_reader.c b/lib/c/test/labcomm_mem_reader.c
index 0c4e3f1d9c12879ef989c09364bca28133249674..e111433731e746b12df536b98c01eb9a9336fedd 100644
--- a/lib/c/test/labcomm_mem_reader.c
+++ b/lib/c/test/labcomm_mem_reader.c
@@ -1,6 +1,8 @@
 #include "labcomm_mem_reader.h"
 
 #include <errno.h>
+#include <stdlib.h>
+#include <string.h>
 
 /* This implementation assumes labcomm will call end exactly once after each start
  * It is not allowed to save data in mcontext->enc_data,
@@ -13,7 +15,9 @@
  */
 
 // TODO make labcomm use result!
-int labcomm_mem_reader(labcomm_reader_t *r, labcomm_reader_action_t action)
+int labcomm_mem_reader(labcomm_reader_t *r, 
+		       labcomm_reader_action_t action,
+		       ...)
 {
   int result = -EINVAL;
   labcomm_mem_reader_context_t *mcontext = (labcomm_mem_reader_context_t *) r->context;
diff --git a/lib/c/test/labcomm_mem_reader.h b/lib/c/test/labcomm_mem_reader.h
index 5cac018ff362c1c9ecfc7984c410b71d01e0016b..55b8ea9784a6eaabffb5801d3a8dd7d2f07254c4 100644
--- a/lib/c/test/labcomm_mem_reader.h
+++ b/lib/c/test/labcomm_mem_reader.h
@@ -12,6 +12,8 @@ struct labcomm_mem_reader_context_t {
   unsigned char *enc_data;
 };
 
-int labcomm_mem_reader( labcomm_reader_t *r, labcomm_reader_action_t action);
+int labcomm_mem_reader(labcomm_reader_t *r, 
+		       labcomm_reader_action_t action,
+		       ...);
 
 #endif
diff --git a/lib/c/test/labcomm_mem_writer.c b/lib/c/test/labcomm_mem_writer.c
index 294a471ef380b46aa95d87146c1f725b9b768bcb..4370361e97945f6aec61cbdb2c364bcb13a38fa7 100644
--- a/lib/c/test/labcomm_mem_writer.c
+++ b/lib/c/test/labcomm_mem_writer.c
@@ -2,6 +2,7 @@
 
 #include <stddef.h>  // For size_t.
 #include <stdarg.h>
+#include <stdlib.h>
 #include <errno.h>
 
 #include "labcomm.h"
diff --git a/lib/c/test/test_labcomm.c b/lib/c/test/test_labcomm.c
index fc4004c109e5583ae2acfbbe00caa33f07f93036..1c5020f7e8f5ee9b622351097fd44e496f330887 100644
--- a/lib/c/test/test_labcomm.c
+++ b/lib/c/test/test_labcomm.c
@@ -2,6 +2,7 @@
 #include "CUnit/Basic.h"
 #include "CUnit/Console.h"
 #include <stdbool.h>
+#include <stdlib.h>
 
 #include <labcomm.h>
 #include <labcomm_mem_writer.h>
diff --git a/lib/c/test/test_labcomm_private.c b/lib/c/test/test_labcomm_basic_type_encoding.c
similarity index 97%
rename from lib/c/test/test_labcomm_private.c
rename to lib/c/test/test_labcomm_basic_type_encoding.c
index 33e2a1aaf8e40e263e38f03b543584c9a041809f..c8dfff71d24341d19a4c500a659a1aaff6deec7b 100644
--- a/lib/c/test/test_labcomm_private.c
+++ b/lib/c/test/test_labcomm_basic_type_encoding.c
@@ -9,7 +9,7 @@ int test_write(struct labcomm_writer *w, labcomm_writer_action_t a, ...)
   exit(1);
 }
 
-int test_read(struct labcomm_reader *r, labcomm_reader_action_t a)
+int test_read(struct labcomm_reader *r, labcomm_reader_action_t a, ...)
 {
   fprintf(stderr, "test_read should not be called\n");
   exit(1);
@@ -40,7 +40,7 @@ static labcomm_decoder_t decoder = {
     .context = NULL,
     .data = buffer,
     .data_size = sizeof(buffer),
-    .count = sizeof(buffer),
+    .count = 0,
     .pos = 0,
     .read = test_read,
     .ioctl = NULL,
@@ -60,7 +60,8 @@ typedef unsigned char byte;
     encoder.writer.pos = 0;						\
     labcomm_encode_##type(&encoder, value);				\
     writer_assert(#type, __LINE__, expect_count, (uint8_t*)expect_bytes); \
-    decoder.reader.pos = 0;					\
+    decoder.reader.count = encoder.writer.pos;				\
+    decoder.reader.pos = 0;						\
     decoded = labcomm_decode_##type(&decoder);				\
     if (decoded != value) {						\
       fprintf(stderr, "Decode error" format " != " format " @%s:%d \n", value, decoded, \