diff --git a/Makefile b/Makefile
index 07c4765287f6c539daa52e7ab1a424c0f0ee7678..10bc7d42093bdb59a4744b31834600e68df31b08 100644
--- a/Makefile
+++ b/Makefile
@@ -1,6 +1,7 @@
 SUBDIRS=compiler lib test examples packaging
 export LABCOMM_JAR=$(shell pwd)/compiler/labcomm2014_compiler.jar
 export LABCOMM=java -jar $(LABCOMM_JAR) 
+export VALGRIND=valgrind --leak-check=full --error-exitcode=1
 
 UNAME_S=$(shell uname -s)
 
diff --git a/lib/c/2014/Makefile b/lib/c/2014/Makefile
index 81c0244deaa0578339cb541395c263c012b4a0e2..741f5e33c52de9ba86e09c7ba8b43b56ccd98a4b 100644
--- a/lib/c/2014/Makefile
+++ b/lib/c/2014/Makefile
@@ -108,7 +108,7 @@ endif
 # rules invoked by 'test'
 .PHONY: run-test-%
 run-test-%: $(TEST_DIR)/gen/% | $(TEST_DIR)/gen
-	$<
+	$(VALGRIND) $<
 
 .PRECIOUS: $(TEST_DIR)/gen/%
 
diff --git a/lib/c/2014/labcomm2014_decoder.c b/lib/c/2014/labcomm2014_decoder.c
index 80422737f75ea44f1e25776c8a2325cafc5f10c6..c9474aa76867db3e944394ab369ce0b091db6bb9 100644
--- a/lib/c/2014/labcomm2014_decoder.c
+++ b/lib/c/2014/labcomm2014_decoder.c
@@ -186,7 +186,7 @@ static int decode_sample_def_or_ref(struct labcomm2014_decoder *d, int kind)
   signature.name = TODO_read_intentions(d->reader);
   if (d->reader->error < 0) {
     result = d->reader->error;
-    goto out;
+    goto free_signature_name;
   }
   signature.size = labcomm2014_read_packed32(d->reader);
   if (d->reader->error < 0) {
@@ -224,7 +224,15 @@ static int decode_sample_def_or_ref(struct labcomm2014_decoder *d, int kind)
 free_signature_signature:
   labcomm2014_memory_free(d->memory, 1,  signature.signature);
 free_signature_name:
-  labcomm2014_memory_free(d->memory, 0, signature.name);
+  if (signature.name) {
+    if (result == -ENOENT) {
+      labcomm2014_error_warning(d->error,
+                                LABCOMM2014_ERROR_DEC_NO_REG_SIGNATURE,
+                                "Signature not found: %s\n",
+                                signature.name);
+    }
+    labcomm2014_memory_free(d->memory, 0, signature.name);
+  }
 out:
   return result;
 }
@@ -283,23 +291,26 @@ out:
 }
 
 static labcomm2014_decoder_function lookup_h(struct labcomm2014_decoder *d,
-		                         struct call_handler_context *wrap,
-		                         int remote_index,
-					 int **local_index)
+                                             struct call_handler_context *wrap,
+                                             int remote_index,
+                                             int *r_local_index)
 {
   struct decoder *id = d->context;
   labcomm2014_decoder_function do_decode = NULL;
+  int *local_index;
+
   labcomm2014_scheduler_data_lock(d->scheduler);
-  *local_index = LABCOMM_SIGNATURE_ARRAY_REF(d->memory,
-                                             id->remote_to_local, int,
-                                             remote_index);
-  if (**local_index != 0) {
+  local_index = LABCOMM_SIGNATURE_ARRAY_REF(d->memory,
+                                            id->remote_to_local, int,
+                                            remote_index);
+  *r_local_index = *local_index;
+  if (*local_index != 0) {
     struct sample_entry *entry;
 
     entry = LABCOMM_SIGNATURE_ARRAY_REF(d->memory,
                                         id->local, struct sample_entry,
-                                        **local_index);
-    wrap->local_index = **local_index;
+                                        *local_index);
+    wrap->local_index = *local_index;
     wrap->signature = entry->signature;
     wrap->handler = entry->handler;
     wrap->context = entry->context;
@@ -318,7 +329,7 @@ static int decode_and_handle(struct labcomm2014_decoder *d,
 		             int remote_index)
 {
   int result;
-  int *local_index;
+  int local_index;
   struct call_handler_context wrap = {
     .reader = d->reader,
     .remote_index = remote_index,
@@ -327,7 +338,7 @@ static int decode_and_handle(struct labcomm2014_decoder *d,
     .context = NULL,
   };
   labcomm2014_decoder_function do_decode = lookup_h(registry, &wrap, remote_index, &local_index);
-  result = *local_index;
+  result = local_index;
   if (do_decode) {
     do_decode(d->reader, call_handler, &wrap);
     if (d->reader->error < 0) {
@@ -363,15 +374,16 @@ static int do_decode_one(struct labcomm2014_decoder *d)
     char *version = labcomm2014_read_string(d->reader);
     if (d->reader->error < 0) {
       result = d->reader->error;
-      goto out;
-    }
-    if (strcmp(version, CURRENT_VERSION) == 0) {
+    } else if (strcmp(version, CURRENT_VERSION) == 0) {
       result = LABCOMM_VERSION;
       d->version_ok = 1;
     } else {
       result = -ECONNRESET;
     }  
     labcomm2014_memory_free(d->memory, 1,  version);
+    if (result < 0) {
+      goto out;
+    }
   } else if (! d->version_ok) {
     DEBUG_FPRINTF(stderr, "No VERSION %d %d\n", remote_index, length);
     result = -ECONNRESET;
diff --git a/lib/c/2014/labcomm2014_error.c b/lib/c/2014/labcomm2014_error.c
index 9a29a76ef02a6e4152354e7b2ae7d6165c37a322..a002026d6df70a558dd2125683a14e1182a8b8ec 100644
--- a/lib/c/2014/labcomm2014_error.c
+++ b/lib/c/2014/labcomm2014_error.c
@@ -24,15 +24,21 @@
 #include <stdarg.h>
 #include "labcomm2014_error.h"
 
+static char *description[] = {
+#define LABCOMM2014_ERROR(name, description) description ,
+#include "labcomm2014_error.h"
+#undef LABCOMM2014_ERROR
+};
+
 void labcomm2014_error_fatal_global(enum labcomm2014_error error,
                                     char *format,
                                     ...)
 {
   va_list args;
 
-  fprintf(stderr, "Fatal error %d\n", error);
+  fprintf(stderr, "Fatal error %d (%s)\n", error, description[error]);
   va_start(args, format);
-  vprintf(format, args);
+  vfprintf(stderr, format, args);
   va_end(args);
 
   exit(1);
@@ -45,9 +51,9 @@ void labcomm2014_error_warning(struct labcomm2014_error_handler *e,
 {
   va_list args;
 
-  fprintf(stderr, "Fatal warning %d\n", error);
+  fprintf(stderr, "Fatal warning %d (%s)\n", error, description[error]);
   va_start(args, format);
-  vprintf(format, args);
+  vfprintf(stderr, format, args);
   va_end(args);
 
   exit(1);
diff --git a/lib/c/2014/labcomm2014_error.h b/lib/c/2014/labcomm2014_error.h
index 9162e63acb7795e0b054833ac98d60765dc95e94..ae6ae08203dc38f25aa27730c35cadd9e00b0ea6 100644
--- a/lib/c/2014/labcomm2014_error.h
+++ b/lib/c/2014/labcomm2014_error.h
@@ -52,6 +52,9 @@ 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_NO_REG_SIGNATURE,
+                  "Decoder has no registration for this signature")
 LABCOMM2014_ERROR(LABCOMM2014_ERROR_DEC_UNKNOWN_DATATYPE,
                   "Decoder: Unknown datatype")
 LABCOMM2014_ERROR(LABCOMM2014_ERROR_DEC_INDEX_MISMATCH,
diff --git a/lib/c/2014/labcomm2014_renaming_decoder.c b/lib/c/2014/labcomm2014_renaming_decoder.c
index acd8d35b90a7696e35324ab61b139e6d2922be34..88cdb761242bd7fa6dcdad9a3f5f15ba7cff780a 100644
--- a/lib/c/2014/labcomm2014_renaming_decoder.c
+++ b/lib/c/2014/labcomm2014_renaming_decoder.c
@@ -147,6 +147,13 @@ static int do_ioctl(struct labcomm2014_decoder *d,
                          ioctl_action, args);
 }
 
+static int do_decode_one(struct labcomm2014_decoder *d)
+{
+  struct decoder *id = d->context;
+
+  return id->next->decode_one(id->next);
+}
+
 static const struct labcomm2014_sample_ref *do_index_to_sample_ref(
   struct labcomm2014_decoder *d, int index)
 {
@@ -161,8 +168,8 @@ static const struct labcomm2014_sample_ref *do_ref_get(
 {
   const struct labcomm2014_signature *renamed;
   struct decoder *id = d->context;
-  
- renamed = get_renamed(d, signature);
+
+  renamed = get_renamed(d, signature);
   if (renamed == NULL) {
     return id->next->ref_get(id->next, signature);
   } else {
@@ -201,12 +208,12 @@ struct labcomm2014_decoder *labcomm2014_renaming_decoder_new(
     return NULL;
   } else {
       result->decoder.context = result;
-      result->decoder.reader = NULL;
+      result->decoder.reader = d->reader;
       result->decoder.error = d->error;
       result->decoder.memory = d->memory;
       result->decoder.scheduler = d->scheduler;
       result->decoder.free = do_free;
-      result->decoder.decode_one = d->decode_one;
+      result->decoder.decode_one = do_decode_one;
       result->decoder.sample_register = do_sample_register;
       result->decoder.ref_register = do_ref_register;
       result->decoder.ioctl = do_ioctl;
diff --git a/lib/c/2014/labcomm2014_renaming_encoder.c b/lib/c/2014/labcomm2014_renaming_encoder.c
index feaa330147bb2777c188c85f3d5129daf4f7c2ac..b84eaaf11307d4b74f99a7a1acc3c260b141cff1 100644
--- a/lib/c/2014/labcomm2014_renaming_encoder.c
+++ b/lib/c/2014/labcomm2014_renaming_encoder.c
@@ -263,7 +263,7 @@ struct labcomm2014_encoder *labcomm2014_renaming_encoder_new(
     return NULL;
   } else {
       result->encoder.context = result;
-      result->encoder.writer = NULL;
+      result->encoder.writer = e->writer;
       result->encoder.error = e->error;
       result->encoder.memory = e->memory;
       result->encoder.scheduler = e->scheduler;
diff --git a/lib/c/2014/test/test_labcomm.c b/lib/c/2014/test/test_labcomm.c
index de36a7f4a34905a20360c272bf8f27c0d703593e..0b0fbf36fe0caa3c663654ba9a75bb5509b562f7 100644
--- a/lib/c/2014/test/test_labcomm.c
+++ b/lib/c/2014/test/test_labcomm.c
@@ -171,7 +171,9 @@ static test_sample_test_var decoder_var = {
 
 void handle_test_var(test_sample_test_var *v, void *ctx)
 {
-  decoder_var.a[0] = v->a[0];  
+  if (v->n_0 * v->n_2 > 0) {
+    decoder_var.a[0] = v->a[0];
+  }
 }
 
 int test_decode_one(struct labcomm2014_decoder *decoder)
@@ -229,7 +231,7 @@ static void test_encode_decode(struct labcomm2014_encoder *encoder,
   }
 }
 
-int main(void)
+static int do_test(int argc, char *argv[])
 {
   int i;
   struct labcomm2014_decoder *decoder = labcomm2014_decoder_new(
@@ -273,5 +275,13 @@ int main(void)
     test_encode_decode(encoder, decoder, 4+i, 0, (1<<(7*i)));
   }
   test_encode_decode(encoder, decoder, 8, 0, 4294967295);
+
+  labcomm2014_encoder_free(encoder);
+  labcomm2014_decoder_free(decoder);
   return 0;
 }
+
+int main(int argc, char *argv[])
+{
+  return do_test(argc, argv);
+}
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 29079df684b8f919a2ee15e8ca1992672d3db0f6..b7cf2b1bee28186b996350a92793524d484c34c8 100644
--- a/lib/c/2014/test/test_labcomm_basic_type_encoding.c
+++ b/lib/c/2014/test/test_labcomm_basic_type_encoding.c
@@ -91,7 +91,7 @@ static void writer_assert(char *type,
   }
 }
 
-int main(void)
+static int do_test(int argc, char *argv[])
 {
   TEST_WRITE_READ(packed32, packed32, "%d", 0x0, 1, "\x00");
   TEST_WRITE_READ(packed32, packed32, "%d", 0x7f, 1, "\x7f");
@@ -141,3 +141,7 @@ int main(void)
   return 0;
 }
 
+int main(int argc, char *argv[])
+{
+  return do_test(argc, argv);
+}
diff --git a/lib/c/2014/test/test_labcomm_copy.c b/lib/c/2014/test/test_labcomm_copy.c
index 173f152ab52db12b1d24aa417bd9c25f77526d10..fc4bbfe2ac43373305643f0f80ac8d3b1853df99 100644
--- a/lib/c/2014/test/test_labcomm_copy.c
+++ b/lib/c/2014/test/test_labcomm_copy.c
@@ -70,7 +70,7 @@ static void handle_as(more_types_AS *v, void *context)
   labcomm2014_copy_more_types_AS(labcomm2014_default_memory, context, v);
 }
 
-int main(int argc, char **argv)
+int do_test(int argc, char **argv)
 {
   struct labcomm2014_encoder *encoder;
   struct labcomm2014_decoder *decoder;
@@ -284,4 +284,15 @@ int main(int argc, char **argv)
   puts("NS deallocated ok");
   labcomm2014_copy_free_more_types_AS(labcomm2014_default_memory, &cache_as);
   puts("AS deallocated ok");
+
+  labcomm2014_copy_free_generated_encoding_R(labcomm2014_default_memory,
+                                             &cache_r);
+  puts("R deallocated ok");
+
+  return 0;
+}
+
+int main(int argc, char **argv)
+{
+  return do_test(argc, argv);
 }
diff --git a/lib/c/2014/test/test_labcomm_pthread_scheduler.c b/lib/c/2014/test/test_labcomm_pthread_scheduler.c
index aa7c5f0e08a77ccdf46717418ed06a4d4d64f3bf..c801308c5d8d408f1ece64f3061ef3f9a746b8a7 100644
--- a/lib/c/2014/test/test_labcomm_pthread_scheduler.c
+++ b/lib/c/2014/test/test_labcomm_pthread_scheduler.c
@@ -40,6 +40,7 @@ static void func(void *arg)
   if (func_arg->i == 999) {
     labcomm2014_scheduler_wakeup(func_arg->scheduler);
   }
+  free(func_arg);
 }
 
 void enqueue(struct labcomm2014_scheduler *scheduler, 
@@ -56,7 +57,7 @@ void enqueue(struct labcomm2014_scheduler *scheduler,
   }
 }
 
-int main(int argc, char *argv[])
+static int do_test(int argc, char *argv[])
 {
   struct labcomm2014_scheduler *scheduler;
   struct labcomm2014_time *time;
@@ -78,5 +79,12 @@ int main(int argc, char *argv[])
   labcomm2014_scheduler_sleep(scheduler, NULL);
   labcomm2014_scheduler_sleep(scheduler, time);
 
+  labcomm2014_time_free(time);
+  labcomm2014_scheduler_free(scheduler);
   return 0;
 }
+
+int main(int argc, char *argv[])
+{
+  return do_test(argc, argv);
+}
diff --git a/lib/c/2014/test/test_labcomm_renaming_decoder.c b/lib/c/2014/test/test_labcomm_renaming_decoder.c
index 9cafa7ca5881d0d8a1d73cb4fb8bc656da83e569..b0c4bd5aaefd8ee517f162bbb8e56150e9a8bf4d 100644
--- a/lib/c/2014/test/test_labcomm_renaming_decoder.c
+++ b/lib/c/2014/test/test_labcomm_renaming_decoder.c
@@ -169,7 +169,10 @@ int main(int argc, char **argv)
          labcomm2014_decoder_get_sample_ref(
            suffix_decoder, labcomm2014_signature_generated_encoding_R));
 
+  labcomm2014_decoder_free(suffix_decoder);
+  labcomm2014_decoder_free(prefix_decoder);
   labcomm2014_decoder_free(decoder);
+
   close(fd);
   unlink(DATA_FILE);
 }
diff --git a/lib/c/2014/test/test_labcomm_renaming_encoder.c b/lib/c/2014/test/test_labcomm_renaming_encoder.c
index f1e608fffbd92e0b6896fb24208eb22e7aa1371a..7996b2321158521b2151d263f7f735a741defa08 100644
--- a/lib/c/2014/test/test_labcomm_renaming_encoder.c
+++ b/lib/c/2014/test/test_labcomm_renaming_encoder.c
@@ -26,7 +26,7 @@
 #include "labcomm2014_private.h"
 #include "labcomm2014_default_error_handler.h"
 #include "labcomm2014_default_memory.h"
-#include "labcomm2014_pthread_scheduler.h"
+#include "labcomm2014_default_scheduler.h"
 #include "labcomm2014_renaming.h"
 #include "labcomm2014_renaming_encoder.h"
 #include "test/gen/generated_encoding.h"
@@ -193,7 +193,7 @@ void dump_encoder(struct labcomm2014_encoder *encoder)
   printf("\n");
 }
 
-int main(void)
+static int do_test(int argc, char *argv[])
 {
   struct labcomm2014_encoder *encoder, *prefix, *suffix;
   int i;
@@ -206,7 +206,7 @@ int main(void)
     &buffer_writer, 
     labcomm2014_default_error_handler,
     labcomm2014_default_memory,
-    labcomm2014_pthread_scheduler_new(labcomm2014_default_memory));
+    labcomm2014_default_scheduler);
   prefix = labcomm2014_renaming_encoder_new(encoder,
                                             labcomm2014_renaming_prefix,
                                             "p.");
@@ -277,6 +277,14 @@ int main(void)
   labcomm2014_encode_generated_encoding_V(suffix);
   EXPECT({VARIABLE(5), 0x00 });
 
+  labcomm2014_encoder_free(suffix);
+  labcomm2014_encoder_free(prefix);
+  labcomm2014_encoder_free(encoder);
+
   return 0;
 }
 
+int main(int argc, char *argv[])
+{
+  return do_test(argc, argv);
+}
diff --git a/test/Makefile b/test/Makefile
index dc3b8b735b9a24606719e8be46ee2f1960601421..0714905b12228697016e4fd26ce0f2b3d4be32f4 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -1,4 +1,6 @@
-TESTS=basic simple nested ref
+TESTS_RENAME=basic simple nested # sample_ref's does not transfer between
+                                 # encoder decoder for now
+TESTS=$(TESTS_RENAME) ref
 LABCOMM_JAR=../compiler/labcomm2014_compiler.jar
 LABCOMM=java -jar $(LABCOMM_JAR)
 MONO_PATH=$(shell pwd)/../lib/csharp
@@ -8,7 +10,7 @@ include ../lib/c/os_compat.mk
 
 all:
 
-test: $(TESTS:%=test_%) compiler_errors
+test: $(TESTS:%=test_%) $(TESTS_RENAME:%=test_renaming_%) compiler_errors
 #	PYTHONPATH=../lib/python \
 #		./test_encoder_decoder.py --labcomm="$(LABCOMM)" basic.lc
 
@@ -26,10 +28,28 @@ test_%: gen/%/signatures.py \
 		./test_encoder_decoder.py \
 		--signatures=gen/$*/signatures.py \
 		--test tee gen/$*/testdata \
-		--test gen/$*/c_relay /dev/stdin /dev/stdout \
+		--test $(shell echo $(VALGRIND) | sed -e 's/[-][-]/\\\\--/g') \
+		       gen/$*/c_relay /dev/stdin /dev/stdout \
 		--test mono gen/$*/cs_relay.exe /dev/stdin /dev/stdout \
-		--test java \\-cp gen/$*:../lib/java/labcomm2014.jar java_relay \
-			    /dev/stdin /dev/stdout
+		--test java \\-cp gen/$*:../lib/java/labcomm2014.jar \
+		       java_relay /dev/stdin /dev/stdout
+
+.PHONY: test_renaming_%
+test_renaming_%: gen/%/signatures.py \
+		gen/%/c_renaming_relay \
+		gen/%/cs_relay.exe \
+		gen/%/java_relay.class \
+		gen/%/java_code
+	PYTHONPATH=$(PYTHONPATH) MONO_PATH=$(MONO_PATH) \
+		./test_renaming_encoder_decoder.py \
+		--signatures=gen/$*/signatures.py \
+		--test tee gen/$*/testdata.renamed \
+		--test $(shell echo $(VALGRIND) | sed -e 's/[-][-]/\\\\--/g') \
+		       gen/$*/c_renaming_relay /dev/stdin /dev/stdout
+	echo \
+		--test mono gen/$*/cs_relay.exe /dev/stdin /dev/stdout \
+		--test java \\-cp gen/$*:../lib/java/labcomm2014.jar \
+		       java_relay /dev/stdin /dev/stdout
 
 # test cases for compiler error checking
 .PHONY: compiler_errors testErrorsOK testErrorsNOK
@@ -71,6 +91,15 @@ gen/%/c_relay: gen/%/c_relay.c gen/%/c_code.c Makefile
 	$(CC) $(CFLAGS) -o $@ $< -I../lib/c/2014 -I. -L../lib/c \
 		gen/$*/c_code.c -llabcomm2014
 
+.PRECIOUS: gen/%/c_renaming_relay.c
+gen/%/c_renaming_relay.c: gen/%/typeinfo relay_gen_c.py Makefile
+	./relay_gen_c.py --renaming $< > $@
+
+.PRECIOUS: gen/%/c_renaming_relay
+gen/%/c_renaming_relay: gen/%/c_renaming_relay.c gen/%/c_code.c Makefile
+	$(CC) $(CFLAGS) -o $@ $< -I../lib/c/2014 -I. -L../lib/c \
+		gen/$*/c_code.c -llabcomm2014
+
 # C# relay test rules
 .PRECIOUS: gen/%/cs_code.cs
 gen/%/cs_code.cs: %.lc Makefile | gen/%/.dir
diff --git a/test/relay_gen_c.py b/test/relay_gen_c.py
index 4d050640d0ec5b9091ff0c19d464ffd52361b5ba..e13f66ab01f77a57a740ba8957b992c99ae7c7c0 100755
--- a/test/relay_gen_c.py
+++ b/test/relay_gen_c.py
@@ -1,5 +1,6 @@
 #!/usr/bin/python
 
+import argparse
 import re
 import sys
 
@@ -13,7 +14,13 @@ def split_match(pattern, multiline):
    
 
 if __name__ == '__main__':
-    f = open(sys.argv[1])
+    parser = argparse.ArgumentParser(description='Generate C test relay.')
+    parser.add_argument('--renaming', action='store_true')
+    parser.add_argument('typeinfo', help='typeinfo file')
+
+    options = parser.parse_args(sys.argv[1:])
+
+    f = open(options.typeinfo)
     sample = []
     for l in map(lambda s: s.strip(), f):
         lang,kind,func,arg,stype = l[1:].split(l[0])
@@ -27,12 +34,21 @@ if __name__ == '__main__':
       |#include <sys/types.h>
       |#include <sys/stat.h>
       |#include <fcntl.h>
+      |#include <stdio.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>
+    """))
+    if options.renaming:
+        result.extend(split_match('^[^|]*\|(.*)$', """
+        |#include "labcomm2014_renaming.h"
+        |#include "labcomm2014_renaming_encoder.h"
+        |#include "labcomm2014_renaming_decoder.h"
+        """))
+    result.extend(split_match('^[^|]*\|(.*)$', """
       |#include "c_code.h"
     """))
     for func,arg,stype in sample:
@@ -45,26 +61,55 @@ if __name__ == '__main__':
         pass
     result.extend(split_match('^[^|]*\|(.*)$', """
       |int main(int argc, char *argv[]) {
-      |  struct labcomm2014_encoder *e;
-      |  struct labcomm2014_decoder *d;
-      |  int in, out;
+      |  struct labcomm2014_encoder *e, *e_e;
+      |  struct labcomm2014_decoder *d, *d_d;
+    """))
+    if options.renaming:
+        result.extend(split_match('^[^|]*\|(.*)$', """
+        |  struct labcomm2014_encoder *e_p, *e_s;
+        |  struct labcomm2014_decoder *d_p, *d_s;
+        """))
+    result.extend(split_match('^[^|]*\|(.*)$', """
+      |  int in, out, result;
       |  
       |  if (argc < 3) { return 1; }
       |  in = open(argv[1], O_RDONLY);
       |  if (in < 0) { return 1; }
       |  out = open(argv[2], O_WRONLY);
       |  if (out < 0) { return 1; }
-      |  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);
+      |  e_e = labcomm2014_encoder_new(labcomm2014_fd_writer_new(
+      |                                labcomm2014_default_memory, out, 1),
+      |                                labcomm2014_default_error_handler,
+      |                                labcomm2014_default_memory,
+      |                                labcomm2014_default_scheduler);
+      |  d_d = labcomm2014_decoder_new(labcomm2014_fd_reader_new(
+      |                                labcomm2014_default_memory, in, 1),
+      |                                labcomm2014_default_error_handler,
+      |                                labcomm2014_default_memory,
+      |                                labcomm2014_default_scheduler);
     """))
+    if not options.renaming:
+        result.extend(split_match('^[^|]*\|(.*)$', """
+        |  e = e_e;
+        |  d = d_d;
+        """))
+    else:
+        result.extend(split_match('^[^|]*\|(.*)$', """
+        |  e_p = labcomm2014_renaming_encoder_new(e_e,
+        |                                         labcomm2014_renaming_prefix,
+        |                                         "prefix:");
+        |  e_s = labcomm2014_renaming_encoder_new(e_p,
+        |                                         labcomm2014_renaming_suffix,
+        |                                         ":suffix");
+        |  e = e_s;
+        |  d_p = labcomm2014_renaming_decoder_new(d_d,
+        |                                         labcomm2014_renaming_prefix,
+        |                                         "prefix:");
+        |  d_s = labcomm2014_renaming_decoder_new(d_p,
+        |                                         labcomm2014_renaming_suffix,
+        |                                         ":suffix");
+        |  d = d_s;
+        """))
     for func,arg,stype in sample:
         result.extend(split_match('^[^|]*\|(.*)$', """
           |  labcomm2014_encoder_register_%(func)s(e);
@@ -73,7 +118,19 @@ if __name__ == '__main__':
           |  labcomm2014_decoder_sample_ref_register(d, labcomm2014_signature_%(func)s);
        """ % { 'func': func, 'arg': arg }))
     result.extend(split_match('^[^|]*\|(.*)$', """
-      |  labcomm2014_decoder_run(d);
+      |  while ((result = labcomm2014_decoder_decode_one(d)) > 0) {};
+    """))
+    if options.renaming:
+        result.extend(split_match('^[^|]*\|(.*)$', """
+        |  labcomm2014_decoder_free(d_s);
+        |  labcomm2014_decoder_free(d_p);
+        |  labcomm2014_encoder_free(e_s);
+        |  labcomm2014_encoder_free(e_p);
+        """))
+    result.extend(split_match('^[^|]*\|(.*)$', """
+      |  labcomm2014_decoder_free(d_d);
+      |  labcomm2014_encoder_free(e_e);
+      |  fprintf(stderr, "Failed with %d", result);
       |  return 0;
       |}
     """))
diff --git a/test/test_renaming_encoder_decoder.py b/test/test_renaming_encoder_decoder.py
new file mode 100755
index 0000000000000000000000000000000000000000..8f623f87dcf8833cedd9bcd1d750379b9ede86a3
--- /dev/null
+++ b/test/test_renaming_encoder_decoder.py
@@ -0,0 +1,253 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+import argparse
+import imp
+import labcomm2014
+import math
+import os
+import re
+import struct
+import subprocess
+import sys
+import threading
+
+
+def labcomm_compile(lc, name, args):
+    for lang in [ 'c', 'csharp', 'java', 'python']:
+        destdir = 'gen/%s/%s' % (name, lang)
+        if not os.path.exists(destdir):
+            os.makedirs(destdir)
+            pass
+        pass
+    cmd = args.labcomm.split() + [ 
+        "--c=gen/%s/c/%s.c" % (name, name),
+        "--h=gen/%s/c/%s.h" % (name, name),
+        "--cs=gen/%s/csharp/%s.cs" % (name, name),
+        "--python=gen/%s/python/%s.py" % (name, name),
+        "--java=gen/%s/java/" % name,
+        "--typeinfo=gen/%s/%s.typeinfo" % (name, name),
+        lc]
+    subprocess.check_call(cmd)
+    pass
+
+def get_signatures(path):
+    fp, pathname, description = imp.find_module(os.path.basename(path)[0:-3], 
+                                                [ os.path.dirname(path) ])
+    with fp as fp:
+        m = imp.load_module('signatures', fp, pathname, description)
+        pass
+    return map(lambda s: s.signature, m.sample)
+
+class Test:
+    
+    def __init__(self, program, signatures):
+        self.program = program
+        self.signatures = map(lambda s: s.rename('prefix:%s:suffix' % s.name),
+                              signatures)
+        pass
+
+    def generate(self, decl):
+        if decl.__class__ == labcomm2014.sample:
+            result = []
+            for values in self.generate(decl.decl):
+                result.append((decl, values))
+            return result
+    
+        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(labcomm2014.struct(decl.field[1:]))
+                for v1 in values1:
+                    for v2 in values2:
+                        v = dict(v2)
+                        v[decl.field[0][0]] = v1
+                        result.append(v)
+            return result
+        
+        elif decl.__class__ == labcomm2014.array:
+            if len(decl.indices) == 1:
+                values = self.generate(decl.decl)
+                if decl.indices[0] == 0:
+                    lengths = [0, 1, 2]
+                else:
+                    lengths = [ decl.indices[0] ]
+            else:
+                values = self.generate(labcomm2014.array(decl.indices[1:],
+                                                     decl.decl))
+                if decl.indices[0] == 0:
+                    lengths = [1, 2]
+                else:
+                    lengths = [ decl.indices[0] ]
+            result = []
+            for v in values:
+                for i in lengths:
+                    element = []
+                    for j in range(i):
+                        element.append(v)
+                    result.append(element)
+            return result
+    
+        elif decl.__class__ == labcomm2014.BOOLEAN:
+            return [False, True]
+    
+        elif decl.__class__ == labcomm2014.BYTE:
+            return [0, 127, 128, 255]
+    
+        elif decl.__class__ == labcomm2014.SHORT:
+            return [-32768, 0, 32767]
+    
+        elif decl.__class__ == labcomm2014.INTEGER:
+            return [-2147483648, 0, 2147483647]
+    
+        elif decl.__class__ == labcomm2014.LONG:
+            return [-9223372036854775808, 0, 9223372036854775807]
+    
+        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__ == labcomm2014.DOUBLE:
+            return [-math.pi, 0.0, math.pi]
+    
+        elif decl.__class__ == labcomm2014.STRING:
+            return ['string', u'sträng' ]
+    
+        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__ == labcomm2014.sample:
+                if self.uses_refs([ decl.decl ]):
+                    return True
+    
+            elif decl.__class__ == labcomm2014.struct:
+                if self.uses_refs([ d for n,d in decl.field ]):
+                    return True
+        
+            elif decl.__class__ == labcomm2014.array:
+                if self.uses_refs([ decl.decl ]):
+                    return True
+
+            elif decl.__class__ == labcomm2014.SAMPLE:
+                return True
+
+        return False
+        
+
+    def run(self):
+        print>>sys.stderr, 'Testing', self.program
+        p = subprocess.Popen(self.program, 
+                             stdin=subprocess.PIPE,
+                             stdout=subprocess.PIPE,
+                             stderr=sys.stderr)
+        self.expected = None
+        self.failed = False
+        self.next = threading.Condition()
+        decoder = threading.Thread(target=self.decode, args=(p.stdout,))
+        decoder.start()
+        encoder = labcomm2014.Encoder(labcomm2014.StreamWriter(p.stdin))
+        for signature in self.signatures:
+            encoder.add_decl(signature)
+            pass
+        if self.uses_refs(self.signatures):
+            for signature in self.signatures:
+                encoder.add_ref(signature)
+        for signature in self.signatures:
+            print>>sys.stderr, "Checking", signature.name,
+            for decl,value in self.generate(signature):
+                sys.stderr.write('.')
+                self.next.acquire()
+                self.received_value = None
+                self.received_decl = None
+                encoder.encode(value, decl)
+                self.next.wait(2)
+                self.next.release()
+                if p.poll() != None:
+                    print>>sys.stderr, "Failed with:", p.poll()
+                    self.failed = True
+                elif value != self.received_value:
+                    print>>sys.stderr, "Coding error"
+                    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
+                    print>>sys.stderr, "         ", decl
+                    self.failed = True
+                    
+                if self.failed: 
+                    if p.poll() == None:
+                        p.terminate()
+                    exit(1)
+                pass
+            print>>sys.stderr
+            pass
+        p.stdin.close()
+        if p.wait() != 0:
+            exit(1)
+            pass
+        pass
+
+    def decode(self, f):
+        decoder = labcomm2014.Decoder(labcomm2014.StreamReader(f))
+        try:
+            while True:
+                value,decl = decoder.decode()
+                if value != None:
+                    self.next.acquire()
+                    self.received_value = value
+                    self.received_decl = decl
+                    self.expected = None
+                    self.next.notify_all()
+                    self.next.release()
+                pass
+            pass
+        except EOFError:
+            pass
+        pass
+
+    pass
+    
+def run(test, signatures):
+    t = Test(test, signatures)
+    t.run()
+    pass
+
+if __name__ == "__main__":
+    parser = argparse.ArgumentParser(description='Run encoding test.')
+    class test_action(argparse.Action):
+        def __call__(self, parser, namespace, values, option_string=None):
+            old = list(getattr(namespace, self.dest))
+            def strip_slash(s):
+                if s.startswith('\\'):
+                    return s[1:]
+                return s
+            old.append(map(strip_slash, values))
+            setattr(namespace, self.dest, old)
+    parser.add_argument('--signatures')
+    parser.add_argument('--test', nargs='*', action=test_action, default=[])
+
+    args = parser.parse_args()
+    signatures = get_signatures(args.signatures)
+    for test in args.test:
+        run(test, signatures)
+    exit(0)
+    
+    for lc in args.lc:
+        run(lc, args)
+        pass
+    pass