diff --git a/compiler/C_CodeGen.jrag b/compiler/C_CodeGen.jrag
index f79bbfce3698346a3c38fb50cb50f85b1292b1b2..c352ce81e2aba3923ebbd538c8ad6988cf07ecb4 100644
--- a/compiler/C_CodeGen.jrag
+++ b/compiler/C_CodeGen.jrag
@@ -641,19 +641,9 @@ aspect C_Encoder {
     env.println(")");
     env.println("{");
     env.indent();
-    env.println("labcomm_encoder_start(e, &labcomm_signature_" + 
-		env.prefix + getName() + ");");
-    env.println("labcomm_encode_type_index(e, &labcomm_signature_" + 
-		env.prefix + getName() + ");");
-    env.println("{");
-    env.indent();
     getType().C_emitEncoder(env);
     env.unindent();
     env.println("}");
-    env.println("labcomm_encoder_end(e, &labcomm_signature_" + 
-		env.prefix + getName() + ");");
-    env.unindent();
-    env.println("}");
 
     // Typesafe encode wrapper
     env.println("void labcomm_encode_" + env.prefix + getName() + "(");
@@ -664,7 +654,9 @@ aspect C_Encoder {
     env.println("{");
     env.indent();
     env.println("labcomm_internal_encode(e, &labcomm_signature_" + 
-		env.prefix + getName() + ", v);");
+		env.prefix + getName() + 
+		", (labcomm_encode_typecast_t)encode_" + getName() +
+		", v);");
     env.unindent();
     env.println("}");
   }
diff --git a/lib/c/Makefile b/lib/c/Makefile
index f201fa66a5421b35325bc66f1c86984d6a71b822..4f578ee40f92fdc8a3694737b3cbac11ceb5edc8 100644
--- a/lib/c/Makefile
+++ b/lib/c/Makefile
@@ -10,7 +10,8 @@ OBJS= labcomm.o labcomm_dynamic_buffer_writer.o labcomm_fd_reader.o labcomm_fd_w
 LABCOMMC_PATH=../../compiler
 LABCOMMC_JAR=$(LABCOMMC_PATH)/labComm.jar
 
-TESTS=test_labcomm_basic_type_encoding test_labcomm test_labcomm_errors
+TESTS=test_labcomm_basic_type_encoding test_labcomm_generated_encoding test_labcomm 
+#FIXME: test_labcomm_errors
 TEST_DIR=test
 TESTDATA_DIR=$(TEST_DIR)/testdata
 TEST_GEN_DIR=$(TESTDATA_DIR)/gen
@@ -63,6 +64,15 @@ $(TEST_DIR)/%.o: $(TEST_DIR)/%.c
 $(TEST_DIR)/%: $(TEST_DIR)/%.o liblabcomm.a
 	$(CC) $(LDFLAGS) -o $@ $^ $(LDLIBS) $(LDLIBS_TEST)
 
+$(TEST_DIR)/gen:
+	mkdir -p $@
+
+$(TEST_DIR)/gen/%.c $(TEST_DIR)/gen/%.h: $(TEST_DIR)/%.lc | $(TEST_DIR)/gen
+	java -jar $(LABCOMMC_JAR) \
+		--c=$(TEST_DIR)/gen/$*.c \
+		--h=$(TEST_DIR)/gen/$*.h \
+		$<
+
 $(TEST_GEN_DIR)/%.c $(TEST_GEN_DIR)/%.h: $(TESTDATA_DIR)/%.lc \
 					 $(LABCOMMC_JAR) | $(TEST_GEN_DIR)
 	java -jar $(LABCOMMC_JAR) \
@@ -82,11 +92,14 @@ clean:
 	$(RM) test/*.gch
 	$(RM) test/test_labcomm_errors
 	$(RM) test/testdata/gen/*.[cho]
+	$(RM) test/gen/*.[cho]
 	$(RM) $(TEST_DIR)/test_labcomm
 
 distclean: clean
 	$(RM) liblabcomm.a
 
 # Extra dependencies
+$(TEST_DIR)/test_labcomm_basic_type_encoding.o: labcomm_private.h
+$(TEST_DIR)/test_labcomm_generated_encoding.o : $(TEST_DIR)/gen/generated_encoding.h
+$(TEST_DIR)/test_labcomm_generated_encoding : $(TEST_DIR)/gen/generated_encoding.o
 $(TEST_DIR)/test_labcomm:  $(TEST_GEN_DIR)/test_sample.o
-$(TEST_DIR)/test_labcomm_private.o: labcomm_private.h
diff --git a/lib/c/labcomm.c b/lib/c/labcomm.c
index bdcd204edf7e189ecea889664ce80ef66e1c1d9a..c571f168510254adbeef259e749b9bc0c97a021c 100644
--- a/lib/c/labcomm.c
+++ b/lib/c/labcomm.c
@@ -1,3 +1,23 @@
+/*
+  labcomm.c -- runtime for handling encoding and decoding of
+               labcomm samples.
+
+  Copyright 2006-2013 Anders Blomdell <anders.blomdell@control.lth.se>
+
+  This program 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.
+
+  This program 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/>.
+*/
+
 #ifdef LABCOMM_COMPAT
   #include LABCOMM_COMPAT
 #else
@@ -26,9 +46,18 @@ typedef struct labcomm_sample_entry {
   void *context;
 } labcomm_sample_entry_t;
 
+#ifndef LABCOMM_ENCODER_LINEAR_SEARCH
+extern  labcomm_signature_t labcomm_first_signature;
+extern  labcomm_signature_t labcomm_last_signature;
+#endif
+
 typedef struct labcomm_encoder_context {
+#ifdef LABCOMM_ENCODER_LINEAR_SEARCH
   labcomm_sample_entry_t *sample;
   int index;
+#else
+  labcomm_sample_entry_t *by_section;
+#endif
 } labcomm_encoder_context_t;
 
 typedef struct labcomm_decoder_context {
@@ -152,7 +181,7 @@ static labcomm_sample_entry_t *get_sample_by_index(
 
 #ifdef LABCOMM_ENCODER_LINEAR_SEARCH
 
-static int get_encoder_index(
+static int get_encoder_index_by_search(
   labcomm_encoder_t *e,
   labcomm_signature_t *s)
 {
@@ -171,14 +200,11 @@ static int get_encoder_index(
 
 #else
 
-static int get_encoder_index(
+static int get_encoder_index_by_section(
   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;
-
+  int result = -ENOENT;
   if (&labcomm_first_signature <= s && s <= &labcomm_last_signature) {
     //fprintf(stderr, "%d\n", (int)(s - &labcomm_start));
     result = s - &labcomm_first_signature + LABCOMM_USER;
@@ -187,6 +213,16 @@ static int get_encoder_index(
 }
 
 #endif
+static int get_encoder_index(
+  labcomm_encoder_t *e,
+  labcomm_signature_t *s)
+{
+#ifdef LABCOMM_ENCODER_LINEAR_SEARCH
+  return get_encoder_index_by_search(e, s);
+#else
+  return get_encoder_index_by_section(e, s);
+#endif
+}
 
 void labcomm_encoder_start(struct labcomm_encoder *e,
                            labcomm_signature_t *s) 
@@ -225,50 +261,142 @@ void labcomm_encode_signature(struct labcomm_encoder *e,
   e->writer.write(&e->writer, labcomm_writer_end_signature);
 }
 
+#ifdef LABCOMM_ENCODER_LINEAR_SEARCH
+static int encoder_add_signature_by_search(struct labcomm_encoder *e,
+					   labcomm_signature_t *signature,
+					   labcomm_encode_typecast_t encode)
+{
+  int result;
+  labcomm_encoder_context_t *context = e->context;
+  labcomm_sample_entry_t *sample;
+
+  sample = (labcomm_sample_entry_t*)malloc(sizeof(labcomm_sample_entry_t));
+  if (sample == NULL) {
+    result = -ENOMEM;
+  } else {
+    sample->next = context->sample;
+    sample->index = context->index;
+    sample->signature = signature;
+    sample->encode = encode;
+    context->index++;
+    context->sample = sample;
+    result = sample->index;
+  }
+  return result;
+}
+#endif
+
+#ifndef LABCOMM_ENCODER_LINEAR_SEARCH
+static int encoder_add_signature_by_section(struct labcomm_encoder *e,
+					    labcomm_signature_t *s,
+					    labcomm_encode_typecast_t encode)
+{
+  int result = -ENOENT;
+  
+  if (&labcomm_first_signature <= s && s <= &labcomm_last_signature) {
+    /* Signature is in right linker section */
+    labcomm_encoder_context_t *context = e->context;
+    int index = s - &labcomm_first_signature;
+
+    if (context->by_section == NULL) {
+      int n = &labcomm_last_signature - &labcomm_first_signature;
+      context->by_section = malloc(n * sizeof(context->by_section[0]));
+    }
+    if (context->by_section == NULL) {
+      result = -ENOMEM;
+      goto out;
+    }
+    context->by_section[index].next = NULL;
+    context->by_section[index].index = index + LABCOMM_USER;
+    context->by_section[index].signature = s;
+    context->by_section[index].encode = encode;
+    result = context->by_section[index].index;
+  }
+out:
+  return result;
+}
+#endif
+
+static int encoder_add_signature(struct labcomm_encoder *e,
+				  labcomm_signature_t *signature,
+				  labcomm_encode_typecast_t encode)
+{
+  int index = -ENOENT;
+
+#ifdef LABCOMM_ENCODER_LINEAR_SEARCH
+  index = encoder_add_signature_by_search(e, signature, encode);
+#else
+  index = encoder_add_signature_by_section(e, signature, encode);
+#endif
+  return index;
+}
+
 static void do_encoder_register(struct labcomm_encoder *e,
 				labcomm_signature_t *signature,
 				labcomm_encode_typecast_t encode)
 {
   if (signature->type == LABCOMM_SAMPLE) {
     if (get_encoder_index(e, signature) == 0) {
-      labcomm_encoder_context_t *context = e->context;
-      labcomm_sample_entry_t *sample =
-	(labcomm_sample_entry_t*)malloc(sizeof(labcomm_sample_entry_t));
-      sample->next = context->sample;
-      sample->index = context->index;
-      sample->signature = signature;
-      sample->encode = encode;
-      context->index++;
-      context->sample = sample;
-
-      struct labcomm_ioctl_register_signature ioctl_data;
-      int err;
-
-      ioctl_data.index = sample->index;
-      ioctl_data.signature = signature;	
-      err = labcomm_encoder_ioctl(e, LABCOMM_IOCTL_REGISTER_SIGNATURE,
-				  &ioctl_data);
-      if (err != 0) {
-	labcomm_encode_signature(e, signature);
+      int index = encoder_add_signature(e, signature, encode);
+      
+      if (index > 0) {
+	struct labcomm_ioctl_register_signature ioctl_data;
+	int err;
+	
+	ioctl_data.index = index;
+	ioctl_data.signature = signature;	
+	err = labcomm_encoder_ioctl(e, LABCOMM_IOCTL_REGISTER_SIGNATURE,
+				    &ioctl_data);
+	if (err != 0) {
+	  labcomm_encode_signature(e, signature);
+	}
       }
     }
   }
 }
 
+static labcomm_sample_entry_t *encoder_get_sample_by_signature_address(
+  labcomm_encoder_t *encoder,
+  labcomm_signature_t *s)
+{
+  labcomm_sample_entry_t *result = NULL;
+  labcomm_encoder_context_t *context = encoder->context;
+  
+#ifndef LABCOMM_ENCODER_LINEAR_SEARCH
+  if (&labcomm_first_signature <= s && s <= &labcomm_last_signature) {
+    result = &context->by_section[s - &labcomm_first_signature];
+  }
+#else
+  result = get_sample_by_signature_address(context->sample, s);
+#endif
+  return result;
+}
+						    
 static void do_encode(
   labcomm_encoder_t *encoder,
   labcomm_signature_t *signature,
+  labcomm_encode_typecast_t encode,
   void *value)
 {
-  labcomm_encoder_context_t *context = encoder->context;
   labcomm_sample_entry_t *sample;
-  sample = get_sample_by_signature_address(context->sample,
-					   signature);
+  sample = encoder_get_sample_by_signature_address(encoder, signature);
+  (void)sample;
+
+  labcomm_encoder_start(encoder, signature);
+  labcomm_encode_type_index(encoder, signature);
+  encode(encoder, value);
+  labcomm_encoder_end(encoder, signature);
+/*
+  labcomm_sample_entry_t *sample;
+
+  
+  sample = encoder_get_sample_by_signature_address(encoder, signature);
   if (sample && sample->encode) {
     sample->encode(encoder, value);
   } else {
     encoder->on_error(LABCOMM_ERROR_ENC_NO_REG_SIGNATURE, 2, "No registration for %s.\n", signature->name);
   }
+*/
 }
 
 labcomm_encoder_t *labcomm_encoder_new(
@@ -280,8 +408,12 @@ labcomm_encoder_t *labcomm_encoder_new(
     labcomm_encoder_context_t *context;
 
     context = malloc(sizeof(labcomm_encoder_context_t));
+#ifdef LABCOMM_ENCODER_LINEAR_SEARCH
     context->sample = NULL;
     context->index = LABCOMM_USER;
+#else
+    context->by_section = NULL;
+#endif
     result->context = context;
     result->writer.context = writer_context;
     result->writer.data = 0;
@@ -316,11 +448,11 @@ void labcomm_internal_encoder_register(
 void labcomm_internal_encode(
   labcomm_encoder_t *e,
   labcomm_signature_t *signature,
+  labcomm_encode_typecast_t encode,
   void *value)
 {
-  // Will segfault if e == NULL
   if (e->do_encode) {
-    e->do_encode(e, signature, value);
+    e->do_encode(e, signature, encode, value);
   } else {
     e->on_error(LABCOMM_ERROR_ENC_MISSING_DO_ENCODE, 0);
   }
@@ -329,16 +461,19 @@ void labcomm_internal_encode(
 void labcomm_encoder_free(labcomm_encoder_t* e)
 {
   e->writer.write(&e->writer, labcomm_writer_free);
-  labcomm_encoder_context_t *econtext = (labcomm_encoder_context_t *) e->context;
-
-  labcomm_sample_entry_t *sentry = econtext->sample;
-  labcomm_sample_entry_t *sentry_next;
-  while (sentry != NULL) {
-    sentry_next = sentry->next;
-    free(sentry);
-    sentry = sentry_next;
-  }
+  labcomm_encoder_context_t *context = (labcomm_encoder_context_t *) e->context;
 
+#ifdef LABCOMM_ENCODER_LINEAR_SEARCH
+  labcomm_sample_entry_t *entry = context->sample;
+  labcomm_sample_entry_t *entry_next;
+  while (entry != NULL) {
+    entry_next = entry->next;
+    free(entry);
+    entry = entry_next;
+  }
+#else
+  free(context->by_section);
+#endif
   free(e->context);
   free(e);
 }
diff --git a/lib/c/labcomm_private.h b/lib/c/labcomm_private.h
index 4271200ed144b5dc0e1841d797cb6685135d54f5..301f590d2835a6fc6657c7b3f85d40d9b3944977 100644
--- a/lib/c/labcomm_private.h
+++ b/lib/c/labcomm_private.h
@@ -215,6 +215,7 @@ typedef struct labcomm_encoder {
 		      labcomm_encode_typecast_t);
   void (*do_encode)(struct labcomm_encoder *encoder, 
 		    labcomm_signature_t *signature, 
+		    labcomm_encode_typecast_t encode,
 		    void *value);
   labcomm_error_handler_callback on_error;
 } labcomm_encoder_t;
@@ -227,19 +228,9 @@ void labcomm_internal_encoder_register(
 void labcomm_internal_encode(
   labcomm_encoder_t *encoder, 
   labcomm_signature_t *signature, 
+  labcomm_encode_typecast_t encode,
   void *value);
 
-void labcomm_encoder_start(
-  labcomm_encoder_t *encoder,
-  labcomm_signature_t *signature);
-
-//HERE BE DRAGONS: is the signature_t* needed here?
-void labcomm_encoder_end(
-  labcomm_encoder_t *encoder,
-  labcomm_signature_t *signature);
-
-
-
 #if __BYTE_ORDER == __LITTLE_ENDIAN
 
 #define LABCOMM_ENCODE(name, type)					\
@@ -384,6 +375,4 @@ static inline void labcomm_encode_string(labcomm_encoder_t *e,
   labcomm_write_string(&e->writer, s);
 }
 
-void labcomm_encode_type_index(labcomm_encoder_t *e, labcomm_signature_t *s);
-
 #endif
diff --git a/lib/c/test/generated_encoding.lc b/lib/c/test/generated_encoding.lc
new file mode 100644
index 0000000000000000000000000000000000000000..99cc300533e1da1c3ba48a40434e296bcfd708b7
--- /dev/null
+++ b/lib/c/test/generated_encoding.lc
@@ -0,0 +1,5 @@
+sample void V;
+sample byte B;
+sample struct {
+  int i;
+} S1;
diff --git a/lib/c/test/test_labcomm_generated_encoding.c b/lib/c/test/test_labcomm_generated_encoding.c
new file mode 100644
index 0000000000000000000000000000000000000000..17efb239106e1b09a8be68a3720ba5af4bbf985f
--- /dev/null
+++ b/lib/c/test/test_labcomm_generated_encoding.c
@@ -0,0 +1,163 @@
+#include <stdint.h>
+#include <string.h>
+#include <errno.h>
+#include "labcomm_private.h"
+#include "labcomm_private.h"
+#include "test/gen/generated_encoding.h"
+
+int test_write(struct labcomm_writer *w, labcomm_writer_action_t a, ...)
+{
+  fprintf(stderr, "test_write should not be called\n");
+  exit(1);
+}
+
+int test_read(struct labcomm_reader *r, labcomm_reader_action_t a, ...)
+{
+  fprintf(stderr, "test_read should not be called\n");
+  exit(1);
+}
+
+#define IOCTL_WRITER_ASSERT_BYTES 4096
+#define IOCTL_WRITER_RESET 4097
+
+static unsigned char buffer[128];
+
+static int buffer_writer_ioctl(
+  struct labcomm_writer *w, int action, va_list arg)
+{
+  int result = -ENOTSUP;
+  switch (action) {
+    case IOCTL_WRITER_ASSERT_BYTES: {
+      int line = va_arg(arg, int);
+      int count = va_arg(arg, int);
+      int *expected = va_arg(arg, int *);
+      int i, mismatch;
+
+      if (w->pos != count) {
+	fprintf(stderr, "Invalid length encoded %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]) {
+	  mismatch = 1;
+	}
+      }
+      if (mismatch) {
+	fprintf(stderr, "Encoder mismatch (%s:%d)\n",
+		__FILE__, line);
+
+	for (i = 0 ; i < w->pos ; i++) {
+	  printf("%2.2x ", w->data[i]);
+	}
+	printf("\n");
+	for (i = 0 ; i < count ; i++) {
+	  if (expected[i] < 0) {
+	    printf(".. ");
+	  } else {
+	    printf("%2.2x ", expected[i] );
+	  }
+	}
+	printf("\n");
+	exit(1);
+      }
+      result = 0;
+    } break;
+    case IOCTL_WRITER_RESET: {
+      w->pos = 0;
+      result = 0;
+    }
+  }
+  return result;
+}
+
+static int buffer_writer(
+  labcomm_writer_t *w, 
+  labcomm_writer_action_t action,
+  ...)
+{
+  switch (action) {
+    case labcomm_writer_alloc: {
+      w->data_size = sizeof(buffer);
+      w->count = w->data_size;
+      w->data = buffer;
+      w->pos = 0;
+      w->ioctl = buffer_writer_ioctl;
+    } break;
+    case labcomm_writer_start: 
+    case labcomm_writer_start_signature: {
+    } break;
+    case labcomm_writer_continue: 
+    case labcomm_writer_continue_signature: {
+      fprintf(stderr, "Should not come here %s:%d\n", __FILE__, __LINE__);
+      exit(1);
+    } break;
+    case labcomm_writer_end: 
+    case labcomm_writer_end_signature: {
+    } break;
+    case labcomm_writer_free: {
+      w->data = 0;
+      w->data_size = 0;
+      w->count = 0;
+      w->pos = 0;
+    } break;
+  }
+  return w->error;
+}
+
+void dump_encoder(labcomm_encoder_t *encoder)
+{
+  int i;
+  
+  for (i = 0 ; i < encoder->writer.pos ; i++) {
+    printf("%2.2x ", encoder->writer.data[i]);
+  }
+  printf("\n");
+}
+
+int main(void)
+{
+  generated_encoding_V V;
+  generated_encoding_B B = 1;
+
+  labcomm_encoder_t *encoder = labcomm_encoder_new(buffer_writer, buffer);
+
+  labcomm_encoder_ioctl(encoder, IOCTL_WRITER_RESET);
+  labcomm_encoder_register_generated_encoding_V(encoder);
+  {
+    int expected[] = { 0x02, -1, 0x01, 'V', 0x11, 0x00 };
+    labcomm_encoder_ioctl(encoder, IOCTL_WRITER_ASSERT_BYTES, 
+			  __LINE__, 
+			  6, expected);
+  }
+
+  labcomm_encoder_ioctl(encoder, IOCTL_WRITER_RESET);
+  labcomm_encoder_register_generated_encoding_B(encoder);
+  {
+    int expected[] = { 0x02, -1, 0x01, 'B', 0x21 };
+    labcomm_encoder_ioctl(encoder, IOCTL_WRITER_ASSERT_BYTES, 
+			  __LINE__, 
+			  5, expected);
+  }
+
+  labcomm_encoder_ioctl(encoder, IOCTL_WRITER_RESET);
+  labcomm_encode_generated_encoding_V(encoder, &V);
+  {
+    int expected[] = { -1 };
+    labcomm_encoder_ioctl(encoder, IOCTL_WRITER_ASSERT_BYTES, 
+			  __LINE__, 
+			  1, expected);
+  }
+
+  labcomm_encoder_ioctl(encoder, IOCTL_WRITER_RESET);
+  labcomm_encode_generated_encoding_B(encoder, &B);
+  {
+    int expected[] = { -1, 1 };
+    labcomm_encoder_ioctl(encoder, IOCTL_WRITER_ASSERT_BYTES, 
+			  __LINE__, 
+			  2, expected);
+  }
+
+  return 0;
+}
+