diff --git a/compiler/build.xml b/compiler/build.xml
index 932ba0441be5534fa1e5518f953f4ea1c976d636..ff8cf2aa16f4d392dba1f47d5e38e9faac95dbab 100644
--- a/compiler/build.xml
+++ b/compiler/build.xml
@@ -4,7 +4,7 @@
        clean           - removes all generated files and class files
  Targets for working from Eclipse:
        gen             - generates java files
-       genClean        - removes all generated files and their class files
+       cleanGen        - removes all generated files and their class files
 -->
 <project name="LabComm" default="build" basedir=".">
 
@@ -77,7 +77,9 @@ classpath="tools/jastadd2.jar"/>
      <!-- delete all .class files recursively -->
     <delete>
       <fileset dir="." includes="**/*.class"/>
+      <fileset dir="." includes="labComm.jar"/>
     </delete>
+
 </target>
 
 
diff --git a/examples/simple/compile.sh b/examples/simple/compile.sh
index 468f77ef760a0591e9a6643a570f6af3263f40fe..cd7729c2da8ed0e3ca6f8387b65326c1de5eed0d 100644
--- a/examples/simple/compile.sh
+++ b/examples/simple/compile.sh
@@ -1,4 +1,4 @@
-(cd ../../lib/c; make)
+(cd ../../lib/c; make -e LABCOMM_NO_EXPERIMENTAL=true)
 (cd ../../compiler ; ant jar)
 
 java -jar ../../compiler/labComm.jar --java=gen --c=gen/simple.c --h=gen/simple.h  --python=gen/simple.py simple.lc 
diff --git a/examples/wiki_example/data.java b/examples/wiki_example/data.java
index ce225eae8310622166e4babeda1943c26e52cb61..7acf55a5a1c915dc72ed235b9d3a88cd45ad8b5d 100644
--- a/examples/wiki_example/data.java
+++ b/examples/wiki_example/data.java
@@ -56,7 +56,7 @@ public class data implements LabCommSample {
   }
   
   private static byte[] signature = new byte[] {
-    0, 0, 0, 37, 
+    37, 
   };
 
 }
diff --git a/examples/wiki_example/example.c b/examples/wiki_example/example.c
index 4b6f639c492e0c24a54997beb688aadd20f56600..827f4e3effa68fe0f674106b1676f1ccd12a9a4f 100644
--- a/examples/wiki_example/example.c
+++ b/examples/wiki_example/example.c
@@ -4,30 +4,30 @@
 
 static unsigned char signature_bytes_log_message[] = {
 // struct { 2 fields
-0, 0, 0, 17, 
-  0, 0, 0, 2, 
+17, 
+  2, 
   // int 'sequence'
-  0, 0, 0, 8, 
+  8, 
   115, 101, 113, 117, 101, 110, 99, 101, 
-  0, 0, 0, 35, 
+  35, 
   // array [_] 'line'
-  0, 0, 0, 4, 
+  4, 
   108, 105, 110, 101, 
   // array [_]
-  0, 0, 0, 16, 
-    0, 0, 0, 1, 
-    0, 0, 0, 0, 
+  16, 
+    1, 
+    0, 
     // struct { 2 fields
-    0, 0, 0, 17, 
-      0, 0, 0, 2, 
+    17, 
+      2, 
       // boolean 'last'
-      0, 0, 0, 4, 
+      4, 
       108, 97, 115, 116, 
-      0, 0, 0, 32, 
+      32, 
       // string 'data'
-      0, 0, 0, 4, 
+      4, 
       100, 97, 116, 97, 
-      0, 0, 0, 39, 
+      39, 
     // }
   // }
 // }
@@ -39,7 +39,7 @@ labcomm_signature_t labcomm_signature_example_log_message = {
   signature_bytes_log_message
  };
 static unsigned char signature_bytes_data[] = {
-0, 0, 0, 37, 
+37, 
 };
 labcomm_signature_t labcomm_signature_example_data = {
   LABCOMM_SAMPLE, "data",
@@ -58,7 +58,7 @@ static void decode_log_message(
 {
   example_log_message v;
   v.sequence = labcomm_decode_int(d);
-  v.line.n_0 = labcomm_decode_int(d);
+  v.line.n_0 = labcomm_decode_packed32(d);
   v.line.a = malloc(sizeof(v.line.a[0]) * v.line.n_0);
   {
     int i_0_0;
@@ -106,7 +106,7 @@ static void encode_log_message(
   labcomm_encode_type_index(e, &labcomm_signature_example_log_message);
   {
     labcomm_encode_int(e, (*v).sequence);
-    labcomm_encode_int(e, (*v).line.n_0);
+    labcomm_encode_packed32(e, (*v).line.n_0);
     {
       int i_0_0;
       for (i_0_0 = 0 ; i_0_0 < (*v).line.n_0 ; i_0_0++) {
diff --git a/examples/wiki_example/example.encoded b/examples/wiki_example/example.encoded
index fe3d4eb2a5acba9e220ffd62cef467eb02850fdb..6cd2cd814a2721384a24d02bd60685d11b0df634 100644
Binary files a/examples/wiki_example/example.encoded and b/examples/wiki_example/example.encoded differ
diff --git a/lib/c/Makefile b/lib/c/Makefile
index 4d7117ed6f12b6fc6113a486daa67fe5ccdf81e0..a17c72d4a7f6807c43c630da5095d5e8392d96dd 100644
--- a/lib/c/Makefile
+++ b/lib/c/Makefile
@@ -1,22 +1,85 @@
-CC = gcc
-CFLAGS = -g -I .
+## Macros
 
-liblabcomm.a : labcomm.o labcomm_fd_reader_writer.o experimental/labcomm_udp_reader_writer.o \
-               experimental/udp_hack.o experimental/ethaddr.o \
-               experimental/labcomm_thr_reader_writer.o \
-               experimental/ThrottleDrv/ethernet_drv.o experimental/ThrottleDrv/throttle_drv.o
+# Use LLVM clang if it's found.
+CC = $(shell hash clang 2>/dev/null && echo clang || echo gcc)
+CFLAGS = -g -Wall -I .
+LDFLAGS = -L .
+LDLIBS_TEST = -lcunit -llabcomm
+
+OBJS= labcomm.o labcomm_fd_reader_writer.o labcomm_mem_reader.o labcomm_mem_writer.o
+LABCOMMC_PATH=../../compiler
+LABCOMMC_JAR=$(LABCOMMC_PATH)/labComm.jar
+
+TEST_DIR=test
+TESTDATA_DIR=$(TEST_DIR)/testdata
+TEST_GEN_DIR=$(TESTDATA_DIR)/gen
+
+CREATED_DIRS=$(TEST_DIR) $(TESTDATA_DIR) $(TEST_GEN_DIR)
+
+# Disable experimental objects by invoking make like `make -e LABCOMM_NO_EXPERIMENTAL=true`
+ifneq ($(LABCOMM_NO_EXPERIMENTAL),true)
+	OBJS += experimental/udp_hack.o experimental/ethaddr.o \
+		experimental/labcomm_thr_reader_writer.o \
+		experimental/ThrottleDrv/ethernet_drv.o \
+		experimental/ThrottleDrv/throttle_drv.o \
+		experimental/labcomm_udp_reader_writer.o
+endif
+
+## Targets
+
+.PHONY: all run-test clean distclean
+
+all: liblabcomm.a test/test_labcomm_errors
+
+liblabcomm.a: $(OBJS)
 	ar -r liblabcomm.a $^
 
+
 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
 
+labcomm_mem_reader.o: labcomm_fd_reader_writer.c labcomm_fd_reader_writer.h
+
+labcomm_mem_writer.o: labcomm_mem_writer.c labcomm_mem_writer.h cppmacros.h
+
 ethaddr.o: ethaddr.c
 
-%o: %c %h
+$(CREATED_DIRS):
+	mkdir -p $@
+
+run-test: $(TEST_DIR)/test_labcomm_errors |$(TEST_DIR)
+	test/test_labcomm_errors
+
+$(TEST_DIR)/test_labcomm_errors: $(TEST_DIR)/test_labcomm_errors.o liblabcomm.a |$(TEST_DIR)
+	$(CC) $(CFLAGS) $(LDFLAGS) -llabcomm -o $@ $^
+
+$(TEST_DIR)/test_labcomm_errors.o: $(TEST_DIR)/test_labcomm_errors.c $(TEST_DIR)/test_labcomm_errors.h |$(TEST_DIR)
+	cd test; $(CC) $(CFLAGS) -I .. -c $(patsubst $(TEST_DIR)/%, %, $^)
+
+$(TEST_DIR)/test_labcomm.o: $(TEST_DIR)/test_labcomm.c $(TEST_GEN_DIR)/test_sample.h |$(TEST_DIR)
+	$(CC) -c $(CFLAGS) -o $@ $<
+
+$(TEST_DIR)/test_labcomm: $(TEST_DIR)/test_labcomm.o $(TEST_GEN_DIR)/test_sample.o liblabcomm.a
+	$(CC) $(CFLAGS) $(LDFLAGS) $(filter-out %.a,$^) $(LDLIBS) $(LDLIBS_TEST) -o $@
+
+$(TEST_GEN_DIR)/%.c $(TEST_GEN_DIR)/%.h: $(TESTDATA_DIR)/%.lc $(LABCOMMC_JAR) |$(TEST_GEN_DIR)
+	java -jar $(LABCOMMC_JAR) --c=$(patsubst %.h,%.c,$@) --h=$(patsubst %.c,%.h,$@) $<
+
+$(LABCOMMC_JAR):
+	@echo "======Building LabComm compiler======"
+	cd $(LABCOMMC_PATH); ant jar
+	@echo "======End building LabComm compiler======"
+
+%.o: %.c %.h
 
 clean:
-	rm *.o experimental/*.o experimental/ThrottleDrv/*.o
+	$(RM) *.o
+	$(RM) experimental/*.o experimental/ThrottleDrv/*.o
+	$(RM) test/*.o
+	$(RM) test/*.gch
+	$(RM) test/test_labcomm_errors
+	$(RM) $(TEST_DIR)/test_labcomm
 
 distclean: clean
-	rm liblabcomm.a
+	$(RM) liblabcomm.a
diff --git a/lib/c/cppmacros.h b/lib/c/cppmacros.h
new file mode 100644
index 0000000000000000000000000000000000000000..a3e446b0a76d4e3218d9146dc929473ebd68f9c0
--- /dev/null
+++ b/lib/c/cppmacros.h
@@ -0,0 +1,8 @@
+// C Preprocessor macros.
+#ifndef CPP_MACROS_H
+#define CPP_MACROS_H
+
+#define X_EMPTY(mac) var ## 1
+#define EMPTY(mac) X_EMPTY(mac)	// Returns 1 if macro mac is empty.
+
+#endif
diff --git a/lib/c/experimental/ThrottleDrv/display.h b/lib/c/experimental/ThrottleDrv/display.h
index f8bed7568b1bd6284f8d09779732c04242529579..49c9cd4c84c02df8710685d301237fbb6492d137 100644
--- a/lib/c/experimental/ThrottleDrv/display.h
+++ b/lib/c/experimental/ThrottleDrv/display.h
@@ -1,7 +1,12 @@
 #define PC_MODE
 #ifdef PC_MODE
-#include <stdio.h>
 #define DISPLAY_ERR(s) 	perror(s);
+
+// Some projects can not use stdio.h.
+#ifndef LABCOMM_NO_STDIO
+  #include <stdio.h>
+#endif
+
 #else
 #define DISPLAY_ERR(s)  ;
 #endif
diff --git a/lib/c/experimental/ThrottleDrv/ethernet_drv.c b/lib/c/experimental/ThrottleDrv/ethernet_drv.c
index fe0004cad4ff5bcb6819fd500db5bc0b27f05393..9b4126eeee3befc7403c036dbab08dbc413fdb44 100644
--- a/lib/c/experimental/ThrottleDrv/ethernet_drv.c
+++ b/lib/c/experimental/ThrottleDrv/ethernet_drv.c
@@ -1,7 +1,6 @@
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
-#include <stdio.h>
 #include <errno.h>
 #include <sys/socket.h>
 #include <sys/ioctl.h>
@@ -14,6 +13,10 @@
 #include "ethernet_drv.h"
 #include "display.h"
 
+// Some projects can not use stdio.h.
+#ifndef LABCOMM_NO_STDIO
+  #include <stdio.h>
+#endif
 
 /** LOCAL FUNCTIONS **/
 
diff --git a/lib/c/experimental/ethaddr.c b/lib/c/experimental/ethaddr.c
index b2207e5f52537abed048192850f5d447185e13c2..5aed408adc13df509d9e6956bb2a2a846ed3301c 100644
--- a/lib/c/experimental/ethaddr.c
+++ b/lib/c/experimental/ethaddr.c
@@ -1,6 +1,10 @@
-#include <stdio.h>
 #include "ethaddr.h"
 
+// Some projects can not use stdio.h.
+#ifndef LABCOMM_NO_STDIO
+  #include <stdio.h>
+#endif
+
 #if ETH_ALEN != 6 
 	#warning "Assumption that ETH_ALEN == 6 appears false. Here be dragons."
 #endif
diff --git a/lib/c/experimental/udp_hack.c b/lib/c/experimental/udp_hack.c
index f4670bb3495f6d53d3544b5c70a6ed3850683e64..1d26eb7d838b8c4781a6b623e560cb5e71beeca1 100644
--- a/lib/c/experimental/udp_hack.c
+++ b/lib/c/experimental/udp_hack.c
@@ -1,11 +1,15 @@
 #include <arpa/inet.h>
 #include <netinet/in.h>
-#include <stdio.h>
 #include <stdlib.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <unistd.h>
 
+// Some projects can not use stdio.h.
+#ifndef LABCOMM_NO_STDIO
+  #include <stdio.h>
+#endif
+
 #define BUFLEN 512
 #define NPACK 10
 #define PORT 9930
diff --git a/lib/c/labcomm.c b/lib/c/labcomm.c
index b67be7ad7da55a96100385603a3066da53c4ab92..ac8cf561b5df02c2b9003b763d03ac5a36d805f8 100644
--- a/lib/c/labcomm.c
+++ b/lib/c/labcomm.c
@@ -1,18 +1,32 @@
 #include <errno.h>
 #include <string.h>
-#include <stdio.h>
+
 #ifndef __VXWORKS__
-#include <strings.h>
+  #ifdef ARM_CORTEXM3_CODESOURCERY
+    #include <string.h>
+  #else
+    #include <strings.h>
+  #endif
 #endif
-#include <stdlib.h>
-#ifdef __VXWORKS__
-#if (CPU == PPC603)
-#undef _LITTLE_ENDIAN
+
+#ifndef ARM_CORTEXM3_CODESOURCERY
+  #include <stdlib.h>
 #endif
-#if (CPU == PENTIUM4)
-#undef _BIG_ENDIAN
+
+// Some projects can not use stdio.h.
+#ifndef LABCOMM_NO_STDIO
+  #include <stdio.h>
 #endif
+
+#ifdef __VXWORKS__
+  #if (CPU == PPC603)
+    #undef _LITTLE_ENDIAN
+  #endif
+  #if (CPU == PENTIUM4)
+    #undef _BIG_ENDIAN
+  #endif
 #endif
+
 #include "labcomm.h"
 #include "labcomm_private.h"
 
@@ -35,6 +49,83 @@ typedef struct labcomm_decoder_context {
   labcomm_sample_entry_t *sample;
 } labcomm_decoder_context_t;
 
+void labcomm_register_error_handler_encoder(struct labcomm_encoder *encoder, labcomm_error_handler_callback callback)
+{
+ encoder->on_error = callback; 
+ encoder->writer.on_error = callback; 
+}
+
+void labcomm_register_error_handler_decoder(struct labcomm_decoder *decoder, labcomm_error_handler_callback callback)
+{
+ decoder->on_error = callback; 
+ decoder->reader.on_error = callback; 
+}
+
+/* Error strings. _must_ be the same order as in enum labcomm_error */
+const char *labcomm_error_strings[] = { 
+  "Enum begin guard. DO NO use this as an error.",
+  "Encoder has no registration for this signature.",
+  "Encoder is missing do_register",
+  "Encoder is missing do_encode",
+  "The labcomm buffer is full and it.",
+  "Decoder is missing do_register",
+  "Decoder is missing do_decode_one",
+  "Decoder: Unknown datatype",
+  "Decoder: index mismatch",
+  "Decoder: type not found",
+  "This function is not yet implemented.",
+  "User defined error.",
+  "Could not allocate memory.",
+  "Enum end guard. DO NO use this as an error."
+};
+
+const char *labcomm_error_get_str(enum labcomm_error error_id)
+{
+  const char *error_str = NULL;
+  // Check if this is a known error ID.
+  if (error_id >= LABCOMM_ERROR_ENUM_BEGIN_GUARD && error_id <= LABCOMM_ERROR_ENUM_END_GUARD) {
+    error_str = labcomm_error_strings[error_id];
+  }
+  return error_str;
+}
+
+void labcomm_decoder_register_new_datatype_handler(struct labcomm_decoder *d, labcomm_handle_new_datatype_callback on_new_datatype)
+{
+	d->on_new_datatype = on_new_datatype;
+}
+
+int on_new_datatype(labcomm_decoder_t *d, labcomm_signature_t *sig)
+{
+	  d->on_error(LABCOMM_ERROR_DEC_UNKNOWN_DATATYPE, 4, "%s(): unknown datatype '%s'\n", __FUNCTION__, sig->name);
+	  return 0;
+}
+
+void on_error_fprintf(enum labcomm_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.
+  if (err_msg == NULL) {
+    err_msg = "Error with an unknown error ID occured.";
+  }
+  fprintf(stderr, "%s\n", err_msg);
+
+ if (nbr_va_args > 0) {
+   va_list arg_pointer;
+   va_start(arg_pointer, nbr_va_args);
+
+   fprintf(stderr, "%s\n", "Extra info {");
+   char *print_format = va_arg(arg_pointer, char *);
+   vfprintf(stderr, print_format, arg_pointer);
+   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.
+#endif
+}
+
+
 static labcomm_sample_entry_t *get_sample_by_signature_address(
   labcomm_sample_entry_t *head,
   labcomm_signature_t *signature)
@@ -135,7 +226,7 @@ static void do_encode(
   if (sample && sample->encode) {
     sample->encode(encoder, value);
   } else {
-    printf("Encoder has no registration for %s\n", signature->name);
+    encoder->on_error(LABCOMM_ERROR_ENC_NO_REG_SIGNATURE, 2, "No registration for %s.\n", signature->name);
   }
 }
 
@@ -148,7 +239,7 @@ labcomm_encoder_t *labcomm_encoder_new(
     labcomm_encoder_context_t *context;
 
     context = malloc(sizeof(labcomm_encoder_context_t));
-    context->sample = 0;
+    context->sample = NULL;
     context->index = LABCOMM_USER;
     result->context = context;
     result->writer.context = writer_context;
@@ -158,8 +249,10 @@ labcomm_encoder_t *labcomm_encoder_new(
     result->writer.pos = 0;
     result->writer.write = writer;
     result->writer.write(&result->writer, labcomm_writer_alloc);
+    result->writer.on_error = on_error_fprintf;
     result->do_register = do_encoder_register;
     result->do_encode = do_encode;
+    result->on_error = on_error_fprintf;
   }
   return result;
 }
@@ -169,10 +262,11 @@ void labcomm_internal_encoder_register(
   labcomm_signature_t *signature,
   labcomm_encode_typecast_t encode)
 {
-  if (e && e->do_register) {
+  // Will segfault if e == NULL.
+  if (e->do_register) {
     e->do_register(e, signature, encode);
   } else {
-    printf("Encoder is missing do_register\n");
+    e->on_error(LABCOMM_ERROR_ENC_MISSING_DO_REG, 0);
   }
 }
 
@@ -181,10 +275,11 @@ void labcomm_internal_encode(
   labcomm_signature_t *signature,
   void *value)
 {
-  if (e && e->do_encode) {
+  // Will segfault if e == NULL
+  if (e->do_encode) {
     e->do_encode(e, signature, value);
   } else {
-    printf("Encoder is missing do_encode\n");
+    e->on_error(LABCOMM_ERROR_ENC_MISSING_DO_ENCODE, 0);
   }
 }
 
@@ -196,8 +291,18 @@ void labcomm_internal_encoder_user_action(labcomm_encoder_t *e,
 
 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;
+  }
+
+  free(e->context);
   free(e);
 }
 
@@ -253,7 +358,8 @@ static void collect_flat_signature(
   int type = labcomm_decode_packed32(decoder); 
 //  printf("%s: type=%x\n", __FUNCTION__, type);
   if (type >= LABCOMM_USER) {
-    printf("Implement %s ... (1) for type 0x%x\n", __FUNCTION__, type);
+    decoder->on_error(LABCOMM_ERROR_UNIMPLEMENTED_FUNC, 3,
+			"Implement %s ... (1) for type 0x%x\n", __FUNCTION__, type);
   } else {
     //labcomm_encode_int(signature_writer, type); 
     labcomm_encode_packed32(signature_writer, type); 
@@ -292,7 +398,8 @@ static void collect_flat_signature(
       case LABCOMM_STRING: {
       } break;
       default: {
-	printf("Implement %s (2) for type 0x%x...\n", __FUNCTION__, type);
+        decoder->on_error(LABCOMM_ERROR_UNIMPLEMENTED_FUNC, 3,
+				"Implement %s (2) for type 0x%x...\n", __FUNCTION__, type);
       } break;
     }
   }
@@ -351,12 +458,12 @@ static int do_decode_one(labcomm_decoder_t *d)
 	entry = get_sample_by_signature_value(context->sample, &signature);
 	if (! entry) {
 	  // Unknown datatype, bail out
-	  fprintf(stderr,	"%s: unknown datatype '%s' (id=0x%x)\n",
-		  __FUNCTION__, signature.name, index);
+          /*d->on_error(LABCOMM_ERROR_DEC_UNKNOWN_DATATYPE, 4, "%s(): unknown datatype '%s' (id=0x%x)\n", __FUNCTION__, signature.name, index);*/
+		d->on_new_datatype(d, &signature);
 	} else if (entry->index && entry->index != index) {
-	  fprintf(stderr,	"%s: index mismatch '%s' (id=0x%x != 0x%x)\n",
-		  __FUNCTION__, signature.name, entry->index, index);
+          d->on_error(LABCOMM_ERROR_DEC_INDEX_MISMATCH, 5, "%s(): index mismatch '%s' (id=0x%x != 0x%x)\n", __FUNCTION__, signature.name, entry->index, index);
 	} else {
+		// TODO unnessesary, since entry->index == index in above if statement
 	  entry->index = index;
 	}
 	free(signature.name);
@@ -371,8 +478,9 @@ static int do_decode_one(labcomm_decoder_t *d)
 
 	entry = get_sample_by_index(context->sample, result);
 	if (!entry) {
-	  fprintf(stderr,	"%s: type not found (id=0x%x)\n",
-		  __FUNCTION__, result);
+	  // printf("Error: %s: type not found (id=0x%x)\n",
+		  //__FUNCTION__, result);
+          d->on_error(LABCOMM_ERROR_DEC_TYPE_NOT_FOUND, 3, "%s(): type not found (id=0x%x)\n", __FUNCTION__, result);
 	  result = -ENOENT;
 	} else {
 	  entry->decoder(d, entry->handler, entry->context);
@@ -401,8 +509,11 @@ labcomm_decoder_t *labcomm_decoder_new(
     result->reader.pos = 0;
     result->reader.read = reader;
     result->reader.read(&result->reader, labcomm_reader_alloc);
+    result->reader.on_error = on_error_fprintf;
     result->do_register = do_decoder_register;
     result->do_decode_one = do_decode_one;
+    result->on_error = on_error_fprintf;
+	result->on_new_datatype = on_new_datatype;
   }
   return result;
 }
@@ -414,23 +525,25 @@ void labcomm_internal_decoder_register(
   labcomm_handler_typecast_t handler,
   void *handler_context)
 {
-  if (d && d->do_register) {
+  // Will segfault if d == NULL
+  if (d->do_register) {
     d->do_register(d, signature, type_decoder, handler, handler_context);
   } else {
-    printf("Decoder is missing do_register\n");
+    d->on_error(LABCOMM_ERROR_DEC_MISSING_DO_REG, 0);
   }
 }
 
 int labcomm_decoder_decode_one(labcomm_decoder_t *d)
 {
   int result = -1;
-  if (d && d->do_decode_one)
+  // Will segfault if decoder == NULL.
+  if (d->do_decode_one)
   {
     result = d->do_decode_one(d);
   }
   else
   {
-    printf("Decoder is missing do_decode_one\n");
+    d->on_error(LABCOMM_ERROR_DEC_MISSING_DO_DECODE_ONE, 0);
   }
   return result;
 }
@@ -444,5 +557,16 @@ void labcomm_decoder_run(labcomm_decoder_t *d)
 void labcomm_decoder_free(labcomm_decoder_t* d)
 {
   d->reader.read(&d->reader, labcomm_reader_free);
+  labcomm_decoder_context_t *context = (labcomm_decoder_context_t *) d->context;
+  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;
+  }
+
+  free(d->context);
   free(d);
 }
diff --git a/lib/c/labcomm.h b/lib/c/labcomm.h
index 9fed6976f1d5760b60b36213578e70d4ab89d2ce..5763b8d30975598e071b42a6429d35e6683081f5 100644
--- a/lib/c/labcomm.h
+++ b/lib/c/labcomm.h
@@ -1,10 +1,24 @@
 #ifndef _LABCOMM_H_
 #define _LABCOMM_H_
 
-#include <endian.h>
-#include <stdio.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>
+
+/* Forward declaration */
+struct labcomm_encoder;
+struct labcomm_decoder;
 
 /*
  * Signature entry
@@ -17,11 +31,62 @@ typedef struct {
   unsigned char *signature; 
 } labcomm_signature_t;
 
+/*
+ * Error handling.
+ */
+
+/* Error IDs */
+enum labcomm_error {
+  LABCOMM_ERROR_ENUM_BEGIN_GUARD,	// _must_ be the first enum element. labcomm_error_get_str() depends on this.
+  LABCOMM_ERROR_ENC_NO_REG_SIGNATURE, 	
+  LABCOMM_ERROR_ENC_MISSING_DO_REG,
+  LABCOMM_ERROR_ENC_MISSING_DO_ENCODE,
+  LABCOMM_ERROR_ENC_BUF_FULL,
+  LABCOMM_ERROR_DEC_MISSING_DO_REG,
+  LABCOMM_ERROR_DEC_MISSING_DO_DECODE_ONE,
+  LABCOMM_ERROR_DEC_UNKNOWN_DATATYPE,
+  LABCOMM_ERROR_DEC_INDEX_MISMATCH,
+  LABCOMM_ERROR_DEC_TYPE_NOT_FOUND,
+  LABCOMM_ERROR_UNIMPLEMENTED_FUNC,
+  LABCOMM_ERROR_MEMORY,
+  LABCOMM_ERROR_USER_DEF,			
+  LABCOMM_ERROR_ENUM_END_GUARD		// _must_ be the last enum element. labcomm_error_get_str() depends on this.
+};
+
+/* Error strings. _must_ be the same order as in enum labcomm_error */
+extern const char *labcomm_error_strings[];
+
+/* 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 noneit 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 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,
+		labcomm_signature_t *sig);
+
+void labcomm_decoder_register_new_datatype_handler(struct labcomm_decoder *d,
+		labcomm_handle_new_datatype_callback on_new_datatype);
+
 
 /*
  * Decoder
  */
-struct labcomm_decoder;
 
 typedef enum { 
   labcomm_reader_alloc, 
@@ -38,6 +103,7 @@ typedef struct labcomm_reader {
   int count;
   int pos;
   int (*read)(struct labcomm_reader *, labcomm_reader_action_t);
+  labcomm_error_handler_callback on_error;
 }  labcomm_reader_t;
 
 struct labcomm_decoder *labcomm_decoder_new(
@@ -53,7 +119,6 @@ void labcomm_decoder_free(
 /*
  * Encoder
  */
-struct labcomm_encoder;
 
 typedef enum { 
   labcomm_writer_alloc, 
@@ -71,9 +136,9 @@ typedef struct labcomm_writer {
   int count;
   int pos;
   int (*write)(struct labcomm_writer *, labcomm_writer_action_t);
+  labcomm_error_handler_callback on_error;
 } labcomm_writer_t;
 
-struct labcomm_encoder;
 struct labcomm_encoder *labcomm_encoder_new(
   int (*writer)(labcomm_writer_t *, labcomm_writer_action_t),
   void *writer_context);
diff --git a/lib/c/labcomm_mem_reader.c b/lib/c/labcomm_mem_reader.c
new file mode 100644
index 0000000000000000000000000000000000000000..088123d0eb1c57b0ecd322559087ac80df6e5b49
--- /dev/null
+++ b/lib/c/labcomm_mem_reader.c
@@ -0,0 +1,73 @@
+#include "labcomm_mem_reader.h"
+
+#include <errno.h>
+
+/* This implementation assumes labcomm will call end exactly once after each start
+ * It is not allowed to save data in mcontext->enc_data,
+ * this pointer will be set to NULL after decoding.
+ */
+/* NOTE!!!!
+ * start will be run first, once a signature or a data section is decoded
+ * end will be run and then start again. If end of encoded data is reached this
+ * must be handled in start.
+ */
+
+// TODO make labcomm use result!
+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;
+
+  switch (action) {
+    case labcomm_reader_alloc: {
+      r->data = NULL;
+      r->data_size = 0;
+      r->pos = 0;
+      r->count = 0;
+      } break;
+    case labcomm_reader_start: {
+      if (r->data == NULL && mcontext->enc_data != NULL) {
+        r->data = (unsigned char *) malloc(mcontext->size);
+        if(r->data != NULL) {
+          memcpy(r->data, mcontext->enc_data, mcontext->size);
+          r->data_size = mcontext->size;
+          r->count = mcontext->size;
+          r->pos = 0;
+          result = r->data_size;
+        } else {
+          r->data_size = 0;
+          result = -ENOMEM;
+        }
+      } else if (r->data == NULL && mcontext->enc_data == NULL) {
+        result = -1;
+      } else {
+        result = r->count - r->pos;
+      }
+    } break;
+    case labcomm_reader_continue: {
+      if (r->pos < r->count) {
+        result = r->count - r->pos;
+      } else {
+        // TODO set some describing error here
+        result = -1;
+      }
+    } break;
+    case labcomm_reader_end: {
+      if (r->pos >= r->count) {
+        free(r->data);
+        r->data = NULL;
+        r->data_size = 0;
+        mcontext->enc_data = NULL;
+        mcontext->size = 0;
+      }
+      result = r->count - r->pos;
+    } break;
+    case labcomm_reader_free: {
+      r->count = 0;
+      r->pos = 0;
+      result = 0;
+    } break;
+  }
+  return result;
+}
+
diff --git a/lib/c/labcomm_mem_reader.h b/lib/c/labcomm_mem_reader.h
new file mode 100644
index 0000000000000000000000000000000000000000..5cac018ff362c1c9ecfc7984c410b71d01e0016b
--- /dev/null
+++ b/lib/c/labcomm_mem_reader.h
@@ -0,0 +1,17 @@
+#ifndef LABCOMM_MEM_READER_H
+#define LABCOMM_MEM_READER_H
+
+#include "labcomm.h"
+
+/* enc_data: The data to be decoded
+ * size: the size of the data to be decoded
+ */
+typedef struct labcomm_mem_reader_context_t labcomm_mem_reader_context_t;
+struct labcomm_mem_reader_context_t {
+  size_t size;
+  unsigned char *enc_data;
+};
+
+int labcomm_mem_reader( labcomm_reader_t *r, labcomm_reader_action_t action);
+
+#endif
diff --git a/lib/c/labcomm_mem_writer.c b/lib/c/labcomm_mem_writer.c
new file mode 100644
index 0000000000000000000000000000000000000000..7275649e2bf901ff24f47bff395e58b5a9226271
--- /dev/null
+++ b/lib/c/labcomm_mem_writer.c
@@ -0,0 +1,143 @@
+#include "labcomm_mem_writer.h"
+
+#include "stddef.h"  // For size_t.
+#include <errno.h>
+
+#include "labcomm.h"
+#include "cppmacros.h"
+
+#define BUFFER_SIZE 150 // Suitable size is at least the size of a fully encoded message. Found by inspecting size of file genreated from the labcomm_fs_reader_writer.c on the same message type.
+
+// Put encdoded data directly in mcontext->mbuf or malloc new temporary memory.
+// 1 == Allocate new memory.
+// 2 == Use mcontext->buf directly. But _beware_; you can not then later change 
+// mcontext->buf to something else since the writer gets a reference to this 
+// buffer!
+#if defined(MEM_WRITER_ENCODED_BUFFER) && (EMPTY(MEM_WRITER_ENCODED_BUFFER) != 1)
+  #define ENCODED_BUFFER MEM_WRITER_ENCODED_BUFFER
+#else
+  #define ENCODED_BUFFER 1
+#endif
+
+static int get_writer_available(labcomm_writer_t *w, labcomm_mem_writer_context_t *mcontext);
+static void copy_data(labcomm_writer_t *w, labcomm_mem_writer_context_t *mcontext, unsigned char *mbuf);
+
+/*
+ * Write encoded messages to memory. w->context is assumed to be a pointer to a
+ * labcomm_mem_writer_context_t structure.
+ */
+int labcomm_mem_writer(labcomm_writer_t *w, labcomm_writer_action_t action)
+{
+  int result = 0;
+  // Unwrap pointers for easy access.
+  labcomm_mem_writer_context_t *mcontext = (labcomm_mem_writer_context_t *) w->context;
+  unsigned char *mbuf = mcontext->buf;
+
+  switch (action) {
+  case labcomm_writer_alloc: {
+#if (ENCODED_BUFFER == 1)
+    w->data = malloc(BUFFER_SIZE); // Buffer that LabComm will use for putting the encoded data.
+    if (w->data == NULL) {
+      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;
+    }
+#elif (ENCODED_BUFFER == 2)
+    w->data = mbuf;
+    int bytes_left = (mcontext->length - mcontext->write_pos);
+    w->data_size = bytes_left;
+    w->count = bytes_left;
+    w->pos = mcontext->write_pos;
+#endif
+     } break;
+  case labcomm_writer_free:{
+#if (ENCODED_BUFFER == 1)
+    free(w->data);
+#endif
+    w->data = 0;
+    w->data_size = 0;
+    w->count = 0;
+    w->pos = 0;
+   } break;
+  case labcomm_writer_start:{
+#if (ENCODED_BUFFER == 1)
+    w->pos = 0;
+#elif (ENCODED_BUFFER == 2)
+    w->pos = mcontext->write_pos;
+#endif
+    } break;
+  case labcomm_writer_continue:{ // Encode-buffer(w->data) is full; empty/handle it. (w->pos == w->count) most likely.
+#if (ENCODED_BUFFER == 1)
+    copy_data(w, mcontext, mbuf);
+    result = w->pos; // Assume result here should be number of bytes written.
+    w->pos = 0;
+#elif (ENCODED_BUFFER == 2)
+    mcontext->write_pos = w->pos;
+#endif
+     result = 0;
+       } break;
+  case labcomm_writer_end:{ // Nothing more to encode, handle encode-buffer(w->data).
+#if (ENCODED_BUFFER == 1)
+    copy_data(w, mcontext, mbuf);
+    result = w->pos;
+    w->pos = 0;
+#elif (ENCODED_BUFFER == 2)
+    mcontext->write_pos = w->pos;
+#endif
+    result = 0;
+    } break;
+  case labcomm_writer_available:{
+    result = w->count - w->pos;
+        } break;
+  }
+  return result;
+}
+
+labcomm_mem_writer_context_t *labcomm_mem_writer_context_t_new(size_t init_pos, size_t length, unsigned char *buf)
+{
+  labcomm_mem_writer_context_t *mcontext = (labcomm_mem_writer_context_t *) malloc(sizeof(labcomm_mem_writer_context_t));
+  if (mcontext == NULL) {
+    //fprintf(stderr, "error: Can not allocate labcomm_mem_writer_context_t.\n");
+  } else {
+    mcontext->write_pos = init_pos;
+    mcontext->length = length;
+    mcontext->buf = buf;
+  }
+  return mcontext;
+}
+
+void labcomm_mem_writer_context_t_free(labcomm_mem_writer_context_t **mcontext)
+{
+  free(*mcontext);
+  *mcontext = NULL;
+}
+
+// Get the number of available bytes in the mcontext->buf buffer.
+static int get_writer_available(labcomm_writer_t *w, labcomm_mem_writer_context_t *mcontext)
+{
+  return (mcontext->length - mcontext->write_pos);
+}
+
+// Copy data from encoded buffer to mbuf.
+static void copy_data(labcomm_writer_t *w, labcomm_mem_writer_context_t *mcontext, unsigned char *mbuf)
+{
+        int writer_available = get_writer_available(w, mcontext);
+  if (( writer_available - w->pos) < 0) {
+    w->on_error(LABCOMM_ERROR_ENC_BUF_FULL, 3, "labcomm_writer_t->pos=%i, but available in mcontext is %i", w->pos, writer_available); 
+  } else {
+    int i;
+    for (i = 0; i < w->pos; ++i, mcontext->write_pos++) {
+      mbuf[mcontext->write_pos] = w->data[i];
+    }
+  }
+}
+
+void test_copy_data(labcomm_writer_t *w, labcomm_mem_writer_context_t *mcontext, unsigned char *mbuf)
+{
+  copy_data(w, mcontext, mbuf); 
+}
diff --git a/lib/c/labcomm_mem_writer.h b/lib/c/labcomm_mem_writer.h
new file mode 100644
index 0000000000000000000000000000000000000000..4585903c93beea5ae17bd2a845c216b801a59539
--- /dev/null
+++ b/lib/c/labcomm_mem_writer.h
@@ -0,0 +1,25 @@
+#ifndef LABCOMM_MEM_WRITER_H
+#define LABCOMM_MEM_WRITER_H
+
+#include "labcomm.h"
+
+/* Wrapper structure for the memory buffer including a writer position. */
+typedef struct labcomm_mem_writer_context_t labcomm_mem_writer_context_t;
+struct labcomm_mem_writer_context_t {
+  size_t write_pos;  // Position where next write should be.
+  size_t length;  // Length of the buffer.
+  unsigned char *buf;  // Allocated destination buffer.
+};
+
+int labcomm_mem_writer(labcomm_writer_t *w, labcomm_writer_action_t action);
+
+/* Wrapper the internal static function copy_data. This is needed so that the exceptions can be unit tested. */
+void test_copy_data(labcomm_writer_t *w, labcomm_mem_writer_context_t *mcontext, unsigned char *mbuf);
+
+/* Allocate new labcomm_mem_writer_context_t. */
+labcomm_mem_writer_context_t *labcomm_mem_writer_context_t_new(size_t init_pos, size_t length, unsigned char *buf);
+
+/* Deallocate mcontext. */
+void labcomm_mem_writer_context_t_free(labcomm_mem_writer_context_t **mcontext);
+
+#endif
diff --git a/lib/c/labcomm_private.h b/lib/c/labcomm_private.h
index 20d3fe875c1ea636eeef87e27dcc8d0ad3a4c335..57239ff07134227aa24b5b09f6430e118cf4f0f7 100644
--- a/lib/c/labcomm_private.h
+++ b/lib/c/labcomm_private.h
@@ -1,8 +1,17 @@
 #ifndef _LABCOMM_PRIVATE_H_
 #define _LABCOMM_PRIVATE_H_
 
-#include <endian.h>
-#include <stdio.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 "labcomm.h"
@@ -51,6 +60,8 @@ typedef struct labcomm_decoder {
 		      labcomm_handler_typecast_t,
 		      void *context);
   int (*do_decode_one)(struct labcomm_decoder *decoder);
+  labcomm_error_handler_callback on_error;
+  labcomm_handle_new_datatype_callback on_new_datatype;
 } labcomm_decoder_t;
 
 /*
@@ -209,6 +220,7 @@ typedef struct labcomm_encoder {
   void (*do_encode)(struct labcomm_encoder *encoder, 
 		    labcomm_signature_t *signature, 
 		    void *value);
+  labcomm_error_handler_callback on_error;
 } labcomm_encoder_t;
 
 void labcomm_internal_encoder_register(
@@ -231,7 +243,7 @@ void labcomm_internal_encoder_user_action(struct labcomm_encoder *encoder,
   static inline void labcomm_write_##name(labcomm_writer_t *w, type data) { \
     int i;								\
     for (i = sizeof(type) - 1 ; i >= 0 ; i--) {				\
-      if (w->pos >= w->count) {						\
+      if (w->pos >= w->count) { /*buffer is full*/			\
 	w->write(w, labcomm_writer_continue);				\
       }									\
       w->data[w->pos] = ((unsigned char*)(&data))[i];			\
diff --git a/lib/c/test/test_labcomm.c b/lib/c/test/test_labcomm.c
new file mode 100644
index 0000000000000000000000000000000000000000..fc4004c109e5583ae2acfbbe00caa33f07f93036
--- /dev/null
+++ b/lib/c/test/test_labcomm.c
@@ -0,0 +1,187 @@
+
+#include "CUnit/Basic.h"
+#include "CUnit/Console.h"
+#include <stdbool.h>
+
+#include <labcomm.h>
+#include <labcomm_mem_writer.h>
+#include <labcomm_mem_reader.h>
+#include "test/testdata/gen/test_sample.h"
+
+#define TEST_BUFFER_SIZE (50)
+
+void test_error_handler(enum labcomm_error error_id, size_t nbr_va_args, ...);
+
+int init_suit_labcomm()
+{
+	return 0;
+}
+
+int clean_suit_labcomm()
+{
+	return 0;
+}
+
+void setup_connected_encoder_decoder(struct labcomm_encoder **enc,
+		labcomm_mem_writer_context_t *enc_ctx,
+		struct labcomm_decoder **dec,
+		labcomm_mem_reader_context_t *dec_ctx)
+{
+	enc_ctx->write_pos = 0;
+	enc_ctx->buf = malloc(TEST_BUFFER_SIZE);
+	enc_ctx->length = TEST_BUFFER_SIZE;
+
+	*enc = labcomm_encoder_new(labcomm_mem_writer, enc_ctx);
+
+	dec_ctx->size = 0;
+	dec_ctx->enc_data = enc_ctx->buf;
+	*dec = labcomm_decoder_new(labcomm_mem_reader, dec_ctx);
+
+	labcomm_register_error_handler_decoder(*dec, test_error_handler);
+	labcomm_register_error_handler_encoder(*enc, test_error_handler);
+}
+
+static bool in_error = false;
+static enum labcomm_error in_error_id = LABCOMM_ERROR_ENUM_BEGIN_GUARD;
+void test_error_handler(enum labcomm_error error_id, size_t nbr_va_args, ...)
+{
+	in_error = true;
+	in_error_id = error_id;
+}
+
+static bool got_sample = false;
+void test_decoder_handle_test_sample_test_var(test_sample_test_var *v, void *ctx)
+{
+	got_sample = true;
+}
+
+void test_decoder_decode_sig()
+{
+	labcomm_mem_writer_context_t enc_ctx;
+	struct labcomm_encoder *encoder;
+	labcomm_mem_reader_context_t dec_ctx;
+	struct labcomm_decoder *decoder;
+	setup_connected_encoder_decoder(&encoder, &enc_ctx, &decoder, &dec_ctx);
+
+	labcomm_encoder_register_test_sample_test_var(encoder);
+	dec_ctx.size = enc_ctx.write_pos;
+
+	labcomm_decoder_register_test_sample_test_var(decoder,
+			test_decoder_handle_test_sample_test_var, NULL);
+	labcomm_decoder_decode_one(decoder);
+
+	CU_ASSERT_FALSE(in_error);
+	enc_ctx.write_pos = 0;
+	test_sample_test_var var = 1;
+	labcomm_encode_test_sample_test_var(encoder, &var);
+	dec_ctx.size = enc_ctx.write_pos;
+	labcomm_decoder_decode_one(decoder);
+
+	CU_ASSERT_FALSE(in_error);
+	CU_ASSERT_FALSE(got_sample);
+
+	labcomm_decoder_free(decoder);
+	labcomm_encoder_free(encoder);
+	free(enc_ctx.buf);
+
+	in_error = false;
+	in_error_id = LABCOMM_ERROR_ENUM_BEGIN_GUARD;
+	got_sample = false;
+}
+
+static bool got_new_datatype = false;
+static labcomm_signature_t new_sig;
+int test_new_datatype(struct labcomm_decoder *decoder,
+		labcomm_signature_t *sig)
+{
+	got_new_datatype = true;
+	memcpy(&new_sig, sig, sizeof(labcomm_signature_t));
+	return 0;
+}
+
+void test_decode_unreg_signature_handle()
+{
+	labcomm_mem_writer_context_t enc_ctx;
+	struct labcomm_encoder *encoder;
+	labcomm_mem_reader_context_t dec_ctx;
+	struct labcomm_decoder *decoder;
+	setup_connected_encoder_decoder(&encoder, &enc_ctx, &decoder, &dec_ctx);
+
+	labcomm_encoder_register_test_sample_test_var(encoder);
+	dec_ctx.size = enc_ctx.write_pos;
+	labcomm_decoder_register_new_datatype_handler(decoder, test_new_datatype);
+	labcomm_decoder_decode_one(decoder);
+
+	CU_ASSERT_TRUE(got_new_datatype);
+	CU_ASSERT_EQUAL(
+			memcmp(new_sig.signature, dec_ctx.enc_data, dec_ctx.size), 0);
+
+	got_new_datatype = false;
+	labcomm_decoder_free(decoder);
+	labcomm_encoder_free(encoder);
+	free(enc_ctx.buf);
+}
+
+void test_decode_unreg_signature_error()
+{
+	labcomm_mem_writer_context_t enc_ctx;
+	struct labcomm_encoder *encoder;
+	labcomm_mem_reader_context_t dec_ctx;
+	struct labcomm_decoder *decoder;
+	setup_connected_encoder_decoder(&encoder, &enc_ctx, &decoder, &dec_ctx);
+
+	labcomm_encoder_register_test_sample_test_var(encoder);
+	dec_ctx.size = enc_ctx.write_pos;
+
+	labcomm_decoder_decode_one(decoder);
+
+	CU_ASSERT_TRUE(in_error);
+	CU_ASSERT_EQUAL(in_error_id, LABCOMM_ERROR_DEC_UNKNOWN_DATATYPE);
+	got_new_datatype = false;
+	labcomm_decoder_free(decoder);
+	labcomm_encoder_free(encoder);
+	free(enc_ctx.buf);
+}
+int main()
+{
+	CU_pSuite suite_decoder = NULL;
+
+	// Initialize CUnit test registry.
+	if (CUE_SUCCESS != CU_initialize_registry()) {
+		return CU_get_error();
+	}
+
+	// Add our test suites.
+	suite_decoder = CU_add_suite("transport_enc_dec",
+			init_suit_labcomm, clean_suit_labcomm);
+	if (suite_decoder == NULL) {
+		CU_cleanup_registry();
+		return CU_get_error();
+	}
+
+	if (
+			(CU_add_test(suite_decoder, "test_decoder_decode_sig",
+					test_decoder_decode_sig) == NULL)
+			||
+			(CU_add_test(suite_decoder, "test_decode_unreg_signature_handle",
+					test_decode_unreg_signature_handle) == NULL)
+			||
+			(CU_add_test(suite_decoder, "test_decode_unreg_signature_error",
+					test_decode_unreg_signature_error) == NULL)
+		) {
+		CU_cleanup_registry();
+		return CU_get_error();
+	}
+
+	// Set verbosity.
+	CU_basic_set_mode(CU_BRM_VERBOSE);
+	/*CU_console_run_tests();*/
+
+	// Run all test suites.
+	CU_basic_run_tests();
+
+	// Clean up.
+	CU_cleanup_registry();
+
+	return CU_get_error();
+}
diff --git a/lib/c/test/test_labcomm_errors b/lib/c/test/test_labcomm_errors
new file mode 100755
index 0000000000000000000000000000000000000000..d55cfeb49cd8a2c1941d63bed9b2d276d5d2d4aa
Binary files /dev/null and b/lib/c/test/test_labcomm_errors differ
diff --git a/lib/c/test/test_labcomm_errors.c b/lib/c/test/test_labcomm_errors.c
new file mode 100644
index 0000000000000000000000000000000000000000..7742175f4d30da7c593f0b8a41f0f1e13b153dac
--- /dev/null
+++ b/lib/c/test/test_labcomm_errors.c
@@ -0,0 +1,168 @@
+#include "test_labcomm_errors.h"
+
+#include <stdlib.h>
+
+#include <labcomm.h>
+#include <labcomm_private.h>
+#include <labcomm_mem_writer.h>
+#include <labcomm_mem_reader.h>
+
+static enum labcomm_error callback_error_id;
+
+int assert_callback(enum labcomm_error expected, const char *name, const char *err_msg)
+{
+  int success;
+  printf("----> %s()\n", name);
+  if (callback_error_id == expected) {
+    printf("Succeeded.\n");
+    success = 1;
+  } else {
+    printf("Failed! %s\n", err_msg);
+    success = 0;
+  }
+  return success;
+}
+
+/* Our callback that just logs which error_id that the library reported. */
+void test_callback(enum labcomm_error error_id, size_t nbr_va_args, ...)
+{
+   va_list arg_pointer;
+   va_start(arg_pointer, nbr_va_args);
+   va_end(arg_pointer);
+   callback_error_id = error_id;
+}
+ 
+void reset_callback_erro_id()
+{
+  callback_error_id = -128;
+}
+
+int encoded_size_mock(void *voidp)
+{
+  return 0;
+}
+
+int test_enc_not_reg_encoder_sign()
+{
+  reset_callback_erro_id();
+  unsigned char *buf = (unsigned char *) "a";
+  labcomm_mem_writer_context_t *mcontext = labcomm_mem_writer_context_t_new(0, 1, buf);
+  labcomm_encoder_t *encoder = labcomm_encoder_new(labcomm_mem_writer, mcontext);
+  labcomm_register_error_handler_encoder(encoder, test_callback);
+  
+  labcomm_signature_t signature = {.type = 0, .name = "test_signature", .encoded_size = encoded_size_mock, .size = 0, .signature = (unsigned char *) "0"};
+  encoder->do_encode(encoder, &signature, NULL);
+
+  return assert_callback(LABCOMM_ERROR_ENC_NO_REG_SIGNATURE, __FUNCTION__, "");
+}
+
+int test_enc_missing_do_reg()
+{
+  reset_callback_erro_id();
+  unsigned char *buf = (unsigned char *) "a";
+  labcomm_mem_writer_context_t *mcontext = labcomm_mem_writer_context_t_new(0, 1, buf);
+  labcomm_encoder_t *encoder = labcomm_encoder_new(labcomm_mem_writer, mcontext);
+  labcomm_register_error_handler_encoder(encoder, test_callback);
+
+  encoder->do_register = NULL;
+  labcomm_internal_encoder_register(encoder, NULL, NULL);
+
+  return assert_callback(LABCOMM_ERROR_ENC_MISSING_DO_REG, __FUNCTION__, "");
+}
+
+int test_enc_missing_do_encode()
+{
+  reset_callback_erro_id();
+  unsigned char *buf = (unsigned char *) "a";
+  labcomm_mem_writer_context_t *mcontext = labcomm_mem_writer_context_t_new(0, 1, buf);
+  labcomm_encoder_t *encoder = labcomm_encoder_new(labcomm_mem_writer, mcontext);
+  labcomm_register_error_handler_encoder(encoder, test_callback);
+
+  encoder->do_encode = NULL;
+  labcomm_internal_encode(encoder, NULL, NULL);
+
+  return assert_callback(LABCOMM_ERROR_ENC_MISSING_DO_ENCODE, __FUNCTION__, "");
+}
+
+int test_enc_buf_full()
+{
+  reset_callback_erro_id();
+  unsigned char *buf = (unsigned char *) "a";
+  labcomm_mem_writer_context_t *mcontext = labcomm_mem_writer_context_t_new(0, 1, buf);
+  labcomm_encoder_t *encoder = labcomm_encoder_new(labcomm_mem_writer, mcontext);
+  labcomm_register_error_handler_encoder(encoder, test_callback);
+
+  unsigned char *mbuf = mcontext->buf;
+  labcomm_writer_t writer = encoder->writer;
+  writer.data = malloc(1);
+  writer.pos = 1;
+  mcontext->write_pos = 1;
+  test_copy_data(&writer, mcontext, mbuf);
+
+  return assert_callback(LABCOMM_ERROR_ENC_BUF_FULL, __FUNCTION__, "");
+}
+
+void labcomm_decoder_typecast_t_mock(struct labcomm_decoder *decoder, labcomm_handler_typecast_t handler, void *voidp)
+{
+        ;
+}
+
+void labcomm_handler_typecast_t_mock(void *arg1, void *arg2)
+{
+        ;
+}
+
+int test_dec_missing_do_reg()
+{
+  reset_callback_erro_id();
+  unsigned char *buf = (unsigned char *) "a";
+  labcomm_mem_reader_context_t *mcontext = (labcomm_mem_reader_context_t *) malloc(sizeof(labcomm_mem_reader_context_t));
+  labcomm_decoder_t *decoder = labcomm_decoder_new(labcomm_mem_reader, mcontext);
+  labcomm_register_error_handler_decoder(decoder, test_callback);
+  
+  decoder->do_register = NULL;
+  labcomm_internal_decoder_register(decoder, NULL, labcomm_decoder_typecast_t_mock, labcomm_handler_typecast_t_mock, buf);
+
+  return assert_callback(LABCOMM_ERROR_DEC_MISSING_DO_REG, __FUNCTION__, "");
+}
+
+int test_dec_missing_do_decode_one()
+{
+  reset_callback_erro_id();
+  labcomm_mem_reader_context_t *mcontext = (labcomm_mem_reader_context_t *) malloc(sizeof(labcomm_mem_reader_context_t));
+  labcomm_decoder_t *decoder = labcomm_decoder_new(labcomm_mem_reader, mcontext);
+  labcomm_register_error_handler_decoder(decoder, test_callback);
+  
+  decoder->do_decode_one = NULL;
+  labcomm_decoder_decode_one(decoder);
+
+  return assert_callback(LABCOMM_ERROR_DEC_MISSING_DO_DECODE_ONE, __FUNCTION__, "");
+}
+
+int main()
+{
+  printf("####> Begin tests.\n");
+  size_t nbr_succeed = 0;
+  size_t nbr_tests = 6; // Increment this when new tests are written.
+  nbr_succeed += test_enc_not_reg_encoder_sign();
+  nbr_succeed += test_enc_missing_do_reg();
+  nbr_succeed += test_enc_missing_do_encode();
+  nbr_succeed += test_enc_buf_full();
+  nbr_succeed += test_dec_missing_do_reg();
+  nbr_succeed += test_dec_missing_do_decode_one();
+
+  // Too tedius to test really...
+  //nbr_succeed += test_dec_unknown_datatype();
+  //nbr_succeed += test_dec_index_mismatch();
+  //nbr_succeed += test_dec_type_not_found();
+
+  //nbr_succeed += test_unimplemented_func(); // This test will be obsolete in the future ;-)
+  //nbr_succeed += test_user_def();           // There are no user defined errors in the library of course.
+
+  printf("####> End tests.\nSummary: %i/%i tests succeed.\n", nbr_succeed, nbr_tests);
+  if (nbr_succeed == nbr_tests) {
+	  return EXIT_SUCCESS;
+  } else {
+  	  return EXIT_FAILURE;
+  }
+}
diff --git a/lib/c/test/test_labcomm_errors.h b/lib/c/test/test_labcomm_errors.h
new file mode 100644
index 0000000000000000000000000000000000000000..8cc39182950f981e3955537da46780f9263256a9
--- /dev/null
+++ b/lib/c/test/test_labcomm_errors.h
@@ -0,0 +1,6 @@
+#ifndef TEST_LABCOMM_ERRORS_H
+#define TEST_LABCOMM_ERRORS_H
+
+void test_not_reg_encoder_sign();
+
+#endif
diff --git a/lib/c/test/testdata/test_sample.lc b/lib/c/test/testdata/test_sample.lc
new file mode 100644
index 0000000000000000000000000000000000000000..bf686a731f5c075a55d6a97dd632b6c1499bc000
--- /dev/null
+++ b/lib/c/test/testdata/test_sample.lc
@@ -0,0 +1 @@
+sample int test_var;