diff --git a/compiler/2014/CS_CodeGen.jrag b/compiler/2014/CS_CodeGen.jrag
index e4658604da3aff4440f578291bcf627941f3fa93..efbd16be6c2f41e27a699ea16f2e838ee8174519 100644
--- a/compiler/2014/CS_CodeGen.jrag
+++ b/compiler/2014/CS_CodeGen.jrag
@@ -9,7 +9,6 @@ aspect CS_CodeGenEnv {
   public class CS_env extends PrintEnv {
 
     private CS_printer printer;
-    private HashMap unique = new HashMap();
 
     final private static class CS_printer extends PrintEnv.FilePrinter {
      public CS_printer(File f) {
@@ -57,15 +56,6 @@ aspect CS_CodeGenEnv {
       println("}");
     }
 
-    public String getUnique(Object o) {
-      String result = (String)unique.get(o);
-      if (result == null) {
-   	result = "_" + (unique.size() + 1) + "_";
-      }
-      unique.put(o, result);
-      return result;
-    }
-
   }
 
 }
@@ -275,6 +265,7 @@ aspect CS_Class {
     CS_emitSignature(env);
 
     env.println("}");
+    env.unindent();
   }
 
   public void Decl.CS_emitSignature(CS_env env) {
@@ -320,12 +311,12 @@ aspect CS_Class {
     env.unindent();
     env.println("}");
     env.println();
-    env.println("private class Dispatcher : SampleDispatcher{");
+    env.println("private class Dispatcher : SampleDispatcher {");
     env.indent();
     env.println();
-    env.println("public Type getSampleClass() {");
+    env.println("public SampleDispatcher getSampleIdentity() {");
     env.indent();
-    env.println("return typeof(" + getName() + ");");
+    env.println("return dispatcher;");
     env.unindent();
     env.println("}");
     env.println();
@@ -357,21 +348,6 @@ aspect CS_Class {
     env.unindent();
     env.println("}");
     env.println();
-//    env.println("public void encodeSignature(Encoder e) throws IOException{");
-//    env.indent();
-//    env.println("emitSignature(e);");
-//    env.unindent();
-//    env.println("}");
-//    env.println();
-//  env.println("public void encodeSignatureMetadata(Encoder e, int index){");
-//  env.indent();
-//  env.println("e.encodePacked32(Constant.TYPE_DEF);");
-//  env.println("e.encodePacked32(index);");
-//  env.println("e.encodeString(getName());");
-//  env.println("emitSignature(e);");
-//  env.unindent();
-//  env.println("}");
-//  env.println();
     env.println("public bool canDecodeAndHandle() {");
     env.indent();
     env.println("return "+isSample+";");
@@ -397,7 +373,6 @@ aspect CS_Class {
     env.unindent();
     env.println("}");
     env.println("");
-
  } //TODO, fix above method
 
   public void TypeDecl.CS_emitEncoder(CS_env env) {
@@ -424,9 +399,9 @@ aspect CS_Class {
     }
     env.println(") {");
     env.indent();
-    env.println("e.begin(typeof(" + getName() + "));");
+    env.println("e.begin(dispatcher);");
     getDataType().CS_emitEncoder(env, "value");
-    env.println("e.end(typeof(" + getName() + "));");
+    env.println("e.end(dispatcher);");
     env.unindent();
     env.println("}");
     env.println();
@@ -634,7 +609,7 @@ aspect CS_Class {
   public void PrimType.CS_emitTypePrefix(CS_env env) {
     switch (getToken()) {
       case LABCOMM_STRING: { env.print("String"); } break;
-      case LABCOMM_SAMPLE: { env.print("Type"); } break;
+      case LABCOMM_SAMPLE: { env.print("SampleDispatcher"); } break;
       default: { env.print(getName()); } break;
     }
   }
@@ -764,7 +739,7 @@ aspect CS_Class {
     switch (getToken()) {
       case LABCOMM_STRING: { env.print("String"); } break;
       case LABCOMM_BOOLEAN: { env.print("bool"); } break;
-      case LABCOMM_SAMPLE: { env.print("Type"); } break;
+      case LABCOMM_SAMPLE: { env.print("SampleDispatcher"); } break;
       default: { env.print(getName()); } break;
     }
   }
diff --git a/lib/c/2014/Makefile b/lib/c/2014/Makefile
index 741f5e33c52de9ba86e09c7ba8b43b56ccd98a4b..b18a9e469ed7c24e8c845138c5adb2db856ae180 100644
--- a/lib/c/2014/Makefile
+++ b/lib/c/2014/Makefile
@@ -24,6 +24,7 @@ OBJS=labcomm$(VERSION).o \
      labcomm$(VERSION)_fd_writer.o \
      labcomm$(VERSION)_pthread_scheduler.o \
      labcomm$(VERSION)_renaming.o \
+     labcomm$(VERSION)_renaming_registry.o \
      labcomm$(VERSION)_renaming_encoder.o \
      labcomm$(VERSION)_renaming_decoder.o
 
@@ -50,6 +51,7 @@ TESTS=test_labcomm_basic_type_encoding \
       test_labcomm \
       test_labcomm_pthread_scheduler \
       test_labcomm_copy \
+      test_labcomm_renaming_registry \
       test_labcomm_renaming_encoder \
       test_labcomm_renaming_decoder
 #FIXME: test_labcomm_errors
@@ -175,6 +177,9 @@ $(TEST_DIR)/gen/test_labcomm_copy: \
 	$(TEST_DIR)/gen/test_sample.o \
 	$(TEST_DIR)/gen/more_types.o
 
+$(TEST_DIR)/gen/test_labcomm_renaming_registry: \
+	$(TEST_DIR)/gen/generated_encoding.o
+
 $(TEST_DIR)/gen/test_labcomm_renaming_encoder: \
 	$(TEST_DIR)/gen/generated_encoding.o
 
diff --git a/lib/c/2014/labcomm2014_renaming.h b/lib/c/2014/labcomm2014_renaming.h
index 903010e283700a4d76a3665b25c1eedd4d3d775c..6ec3d6fc5fbdc2ec7896d197d8ab92c6dfc6970c 100644
--- a/lib/c/2014/labcomm2014_renaming.h
+++ b/lib/c/2014/labcomm2014_renaming.h
@@ -31,4 +31,12 @@ char *labcomm2014_renaming_prefix(struct labcomm2014_memory *m,
 char *labcomm2014_renaming_suffix(struct labcomm2014_memory *m,
                                   char *name, void *context);
 
+struct labcomm2014_renaming_registry *labcomm2014_renaming_registry_new(
+  struct labcomm2014_error_handler *error,
+  struct labcomm2014_memory *memory,
+  struct labcomm2014_scheduler *scheduler);
+
+void labcomm2014_renaming_registry_free(
+  struct labcomm2014_renaming_registry *r);
+
 #endif
diff --git a/lib/c/2014/labcomm2014_renaming_decoder.c b/lib/c/2014/labcomm2014_renaming_decoder.c
index 88cdb761242bd7fa6dcdad9a3f5f15ba7cff780a..0a9f193aa814568a98063b35a01f097994480f49 100644
--- a/lib/c/2014/labcomm2014_renaming_decoder.c
+++ b/lib/c/2014/labcomm2014_renaming_decoder.c
@@ -23,92 +23,63 @@
 #include "labcomm2014_renaming_decoder.h"
 #include "labcomm2014.h"
 #include "labcomm2014_private.h"
+#include "labcomm2014_renaming_private.h"
 
 struct decoder {
   struct labcomm2014_decoder decoder;
   struct labcomm2014_decoder *next;
-  char *(*rename)(struct labcomm2014_memory *m, char *name, void *context);
+  struct labcomm2014_renaming_registry *registry;
+  char *(*rename_func)(struct labcomm2014_memory *m, char *name, void *context);
   void *context;
-  LABCOMM_SIGNATURE_ARRAY_DEF(renamed, struct labcomm2014_signature *);
+  LABCOMM_SIGNATURE_ARRAY_DEF(renamed,
+                              struct labcomm2014_renaming_rename *);
 };
 
-static struct labcomm2014_signature *get_renamed(
+static struct labcomm2014_renaming_rename *get_renamed(
   struct labcomm2014_decoder *d,
   const struct labcomm2014_signature *signature)
 {
-  struct labcomm2014_signature *result;
+  struct labcomm2014_renaming_rename *result;
   struct decoder *id = d->context;
   int index;
 
   index = labcomm2014_get_local_index(signature);
   labcomm2014_scheduler_data_lock(d->scheduler);
   result = LABCOMM_SIGNATURE_ARRAY_GET(id->renamed,
-                                      struct labcomm2014_signature *,
+                                      struct labcomm2014_renaming_rename *,
                                       index, NULL);
   labcomm2014_scheduler_data_unlock(d->scheduler);
   return result;
 }
   
-static struct labcomm2014_signature *set_renamed(
+static struct labcomm2014_renaming_rename *set_renamed(
   struct labcomm2014_decoder *d,
   const struct labcomm2014_signature *signature)
 {
-  struct labcomm2014_signature *result;
+  struct labcomm2014_renaming_rename *result = NULL;
 
   result = get_renamed(d, signature);
   if (result == NULL) {
-    /* create a renamed sample */
     struct decoder *id = d->context;
+    struct labcomm2014_renaming_rename **renamed;
+    struct labcomm2014_renaming_rename *entry = NULL;
     int index;
-    struct labcomm2014_signature **renamed;
-  
+
     index = labcomm2014_get_local_index(signature);
-    if (index <= 0) { goto out; /*result already NULL */}
+    entry = labcomm2014_renaming_rename_new(id->registry, signature,
+                                            id->rename_func, id->context);
+    if (entry == NULL) { goto out; }
     labcomm2014_scheduler_data_lock(d->scheduler);
     renamed = LABCOMM_SIGNATURE_ARRAY_REF(d->memory, id->renamed,
-                                          struct labcomm2014_signature *,
+                                          struct labcomm2014_renaming_rename *,
                                           index);
-    if (renamed == NULL) {
-      labcomm2014_error_warning(d->error,
-                                LABCOMM2014_ERROR_MEMORY,
-                                "Could not allocate rename slot: %s\n",
-                                signature->name);
-      goto unlock;
-    }
-    if (*renamed != NULL) {
-      /* Somebody beat as to allocation, this should never happen */
-      goto unlock;
-    }
-    result = labcomm2014_memory_alloc(d->memory, 0, sizeof(*result));
-    if (result == NULL) {
-      labcomm2014_error_warning(d->error,
-                                LABCOMM2014_ERROR_MEMORY,
-                                "Could not allocate rename signature: %s\n",
-                                signature->name);
-      goto unlock;
-    }
-    result->name = id->rename(d->memory, signature->name, id->context);
-    if (result->name == NULL) {
-      labcomm2014_error_warning(d->error,
-                                LABCOMM2014_ERROR_MEMORY,
-                                "Could not allocate rename name: %s\n",
-                                signature->name);
-      goto unlock_free_result;
-    }
-    result->encoded_size = signature->encoded_size;
-    result->size = signature->size;
-    result->signature = signature->signature; 
-    result->index = 0;
-#ifndef LABCOMM_NO_TYPEDECL
-    result->tdsize = signature->tdsize;
-    result->treedata = signature->treedata;
-#endif  
-    labcomm2014_set_local_index(result);
-    *renamed = result;
+    if (renamed == NULL) { goto free_unlock; }
+    if (*renamed != NULL) { result = *renamed; goto free_unlock; }
+    *renamed = entry;
+    result = entry;
     goto unlock;
-  unlock_free_result:
-    labcomm2014_memory_free(d->memory, 0, result);
-    result = NULL;
+  free_unlock:
+    labcomm2014_renaming_rename_free(id->registry, entry);
   unlock:
     labcomm2014_scheduler_data_unlock(d->scheduler);
   out:
@@ -118,33 +89,42 @@ static struct labcomm2014_signature *set_renamed(
 }
 
 static int do_sample_register(struct labcomm2014_decoder *d, 
-                         const struct labcomm2014_signature *s, 
+                         const struct labcomm2014_signature *signature, 
                          labcomm2014_decoder_function decoder,
                          labcomm2014_handler_function handler,
                          void *context)
 {
+  const struct labcomm2014_renaming_rename *renamed;
   struct decoder *id = d->context;
   
-  return id->next->sample_register(id->next, set_renamed(d, s), decoder,
-				   handler, context);
+  renamed = set_renamed(d, signature);  
+  return id->next->sample_register(
+    id->next, labcomm2014_renaming_rename_signature(renamed),
+    decoder, handler, context);
 }
 
 static int do_ref_register(struct labcomm2014_decoder *d, 
                       const struct labcomm2014_signature *signature)
 {
+  const struct labcomm2014_renaming_rename *renamed;
   struct decoder *id = d->context;
-  
-  return id->next->ref_register(id->next, set_renamed(d, signature));
+
+  renamed = set_renamed(d, signature);  
+  return id->next->ref_register(
+    id->next, labcomm2014_renaming_rename_signature(renamed));
 }
 
 static int do_ioctl(struct labcomm2014_decoder *d, 
                     const struct labcomm2014_signature *signature,
                     uint32_t ioctl_action, va_list args)
 {
+  const struct labcomm2014_renaming_rename *renamed;
   struct decoder *id = d->context;
   
-  return id->next->ioctl(id->next, get_renamed(d, signature),
-                         ioctl_action, args);
+  renamed = get_renamed(d, signature);
+  return id->next->ioctl(
+    id->next, labcomm2014_renaming_rename_signature(renamed),
+    ioctl_action, args);
 }
 
 static int do_decode_one(struct labcomm2014_decoder *d)
@@ -166,14 +146,15 @@ static const struct labcomm2014_sample_ref *do_ref_get(
   struct labcomm2014_decoder *d,
   const struct labcomm2014_signature *signature)
 {
-  const struct labcomm2014_signature *renamed;
+  const struct labcomm2014_renaming_rename *renamed;
   struct decoder *id = d->context;
 
   renamed = get_renamed(d, signature);
   if (renamed == NULL) {
     return id->next->ref_get(id->next, signature);
   } else {
-    return id->next->ref_get(id->next, renamed);
+    return id->next->ref_get(id->next,
+                             labcomm2014_renaming_rename_signature(renamed));
   }
 }
 
@@ -182,23 +163,25 @@ static void do_free(struct labcomm2014_decoder *d)
   struct decoder *id = d->context;
   int i;
 
-  LABCOMM_SIGNATURE_ARRAY_FOREACH(id->renamed, struct labcomm2014_signature *,
+  LABCOMM_SIGNATURE_ARRAY_FOREACH(id->renamed,
+                                  struct labcomm2014_renaming_rename *,
                                   i) {
-    struct labcomm2014_signature *s;
-    s = LABCOMM_SIGNATURE_ARRAY_GET(id->renamed,
-                                    struct labcomm2014_signature *, i, NULL);
-    if (s) {
-      labcomm2014_memory_free(d->memory, 0, s->name);
-      labcomm2014_memory_free(d->memory, 0, s);
+    struct labcomm2014_renaming_rename *r;
+    r = LABCOMM_SIGNATURE_ARRAY_GET(id->renamed,
+                                    struct labcomm2014_renaming_rename *,
+                                    i, NULL);
+    if (r) {
+      labcomm2014_renaming_rename_free(id->registry, r);
     }
   }
   LABCOMM_SIGNATURE_ARRAY_FREE(d->memory, id->renamed,
-                               struct labcomm2014_signature *);
+                               struct labcomm2014_renaming_rename *);
   labcomm2014_memory_free(d->memory, 0, id);
 }
 
 struct labcomm2014_decoder *labcomm2014_renaming_decoder_new(
   struct labcomm2014_decoder *d,
+  struct labcomm2014_renaming_registry *registry,
   char *(*rename)(struct labcomm2014_memory *m, char *name, void *context),
   void *context)
 {
@@ -220,10 +203,11 @@ struct labcomm2014_decoder *labcomm2014_renaming_decoder_new(
       result->decoder.index_to_sample_ref = do_index_to_sample_ref;
       result->decoder.ref_get = do_ref_get;
       result->next = d;
-      result->rename = rename;
+      result->registry = registry;
+      result->rename_func = rename;
       result->context = context;
       LABCOMM_SIGNATURE_ARRAY_INIT(result->renamed,
-                                   struct labcomm2014_signature *);
+                                   struct labcomm2014_renaming_rename *);
       return &(result->decoder);
   }
 }
diff --git a/lib/c/2014/labcomm2014_renaming_decoder.h b/lib/c/2014/labcomm2014_renaming_decoder.h
index d13e6ea350f8668e986934f6d01f7ede40c349b0..e12474f08d78c4cf86b540670061727760958d6f 100644
--- a/lib/c/2014/labcomm2014_renaming_decoder.h
+++ b/lib/c/2014/labcomm2014_renaming_decoder.h
@@ -23,9 +23,11 @@
 #define __LABCOMM2014_RENAMING_DECODER_H__
 
 #include "labcomm2014.h"
+#include "labcomm2014_renaming.h"
 
 struct labcomm2014_decoder *labcomm2014_renaming_decoder_new(
   struct labcomm2014_decoder *d,
+  struct labcomm2014_renaming_registry *r,
   char *(*rename)(struct labcomm2014_memory *m, char *name, void *context),
   void *context);
 
diff --git a/lib/c/2014/labcomm2014_renaming_encoder.c b/lib/c/2014/labcomm2014_renaming_encoder.c
index b84eaaf11307d4b74f99a7a1acc3c260b141cff1..1d610327959a2df5d28230698ea046e74df25fdc 100644
--- a/lib/c/2014/labcomm2014_renaming_encoder.c
+++ b/lib/c/2014/labcomm2014_renaming_encoder.c
@@ -23,104 +23,63 @@
 #include "labcomm2014_renaming_encoder.h"
 #include "labcomm2014.h"
 #include "labcomm2014_private.h"
-
-struct renamed {
-  struct labcomm2014_signature signature;
-  struct labcomm2014_signature_data s_treedata[2]; 
-};
+#include "labcomm2014_renaming_private.h"
 
 struct encoder {
   struct labcomm2014_encoder encoder;
   struct labcomm2014_encoder *next;
-  char *(*rename)(struct labcomm2014_memory *m, char *name, void *context);
+  struct labcomm2014_renaming_registry *registry;
+  char *(*rename_func)(struct labcomm2014_memory *m, char *name, void *context);
   void *context;
-  LABCOMM_SIGNATURE_ARRAY_DEF(renamed, struct renamed *);
+  LABCOMM_SIGNATURE_ARRAY_DEF(renamed,
+                              struct labcomm2014_renaming_rename *);
 };
 
-static struct renamed *get_renamed(
+static struct labcomm2014_renaming_rename *get_renamed(
   struct labcomm2014_encoder *e,
   const struct labcomm2014_signature *signature)
 {
-  struct renamed *result;
+  struct labcomm2014_renaming_rename *result;
   struct encoder *ie = e->context;
   int index;
 
   index = labcomm2014_get_local_index(signature);
   labcomm2014_scheduler_writer_lock(e->scheduler);
   result = LABCOMM_SIGNATURE_ARRAY_GET(ie->renamed,
-                                      struct renamed *,
+                                      struct labcomm2014_renaming_rename *,
                                       index, NULL);
   labcomm2014_scheduler_writer_unlock(e->scheduler);
   return result;
 }
   
-static struct renamed *set_renamed(
+static struct labcomm2014_renaming_rename *set_renamed(
   struct labcomm2014_encoder *e,
   const struct labcomm2014_signature *signature)
 {
-  struct renamed *result;
+  struct labcomm2014_renaming_rename *result = NULL;
 
   result = get_renamed(e, signature);
   if (result == NULL) {
-    /* create a renamed sample */
     struct encoder *ie = e->context;
+    struct labcomm2014_renaming_rename **renamed;
+    struct labcomm2014_renaming_rename *entry = NULL;
     int index;
-    struct renamed **renamed;
-  
+
     index = labcomm2014_get_local_index(signature);
-    if (index <= 0) { goto out; /*result already NULL */}
+    entry = labcomm2014_renaming_rename_new(ie->registry, signature,
+                                            ie->rename_func, ie->context);
+    if (entry == NULL) { goto out; }
     labcomm2014_scheduler_writer_lock(e->scheduler);
     renamed = LABCOMM_SIGNATURE_ARRAY_REF(e->memory, ie->renamed,
-                                          struct renamed *,
+                                          struct labcomm2014_renaming_rename *,
                                           index);
-    if (renamed == NULL) {
-      labcomm2014_error_warning(e->error,
-                                LABCOMM2014_ERROR_MEMORY,
-                                "Could not allocate rename slot: %s\n",
-                                signature->name);
-      goto unlock;
-    }
-    if (*renamed != NULL) {
-      /* Somebody beat as to allocation, this should never happen */
-      goto unlock;
-    }
-    result = labcomm2014_memory_alloc(e->memory, 0, sizeof(*result));
-    if (result == NULL) {
-      labcomm2014_error_warning(e->error,
-                                LABCOMM2014_ERROR_MEMORY,
-                                "Could not allocate rename signature: %s\n",
-                                signature->name);
-      goto unlock;
-    }
-    result->signature.name = ie->rename(
-      e->memory, signature->name, ie->context);
-    if (result->signature.name == NULL) {
-      labcomm2014_error_warning(e->error,
-                                LABCOMM2014_ERROR_MEMORY,
-                                "Could not allocate rename name: %s\n",
-                                signature->name);
-      goto unlock_free_result;
-    }
-    result->signature.encoded_size = signature->encoded_size;
-    result->signature.size = signature->size;
-    result->signature.signature = signature->signature; 
-    result->signature.index = 0;
-#ifndef LABCOMM_NO_TYPEDECL
-    struct labcomm2014_signature_data s_treedata[2] = { 
-      LABCOMM_SIGDEF_SIGNATURE(*signature),
-      LABCOMM_SIGDEF_END
-    };
-    result->s_treedata[0] = s_treedata[0];
-    result->s_treedata[1] = s_treedata[1];
-    result->signature.tdsize = sizeof(result->s_treedata);
-    result->signature.treedata = result->s_treedata;
-#endif  
-    labcomm2014_set_local_index(&result->signature);
-    *renamed = result;
+    if (renamed == NULL) { goto free_unlock; }
+    if (*renamed != NULL) { result = *renamed; goto free_unlock; }
+    *renamed = entry;
+    result = entry;
     goto unlock;
-  unlock_free_result:
-    labcomm2014_memory_free(e->memory, 0, result);
-    result = NULL;
+  free_unlock:
+    labcomm2014_renaming_rename_free(ie->registry, entry);
   unlock:
     labcomm2014_scheduler_writer_unlock(e->scheduler);
   out:
@@ -132,14 +91,15 @@ static struct renamed *set_renamed(
 static int do_type_register(struct labcomm2014_encoder *e,
                             const struct labcomm2014_signature *signature)
 {
-  const struct renamed *renamed;
+  const struct labcomm2014_renaming_rename *renamed;
   struct encoder *ie = e->context;
 
   renamed = get_renamed(e, signature);
   if (renamed) {
     /* Register base type and renamed type */
     ie->next->type_register(ie->next, signature);
-    return ie->next->type_register(ie->next, &renamed->signature);
+    return ie->next->type_register(
+      ie->next, labcomm2014_renaming_rename_signature(renamed));
   } else {
     return ie->next->type_register(ie->next, signature);
   }
@@ -149,12 +109,13 @@ static int do_type_bind(struct labcomm2014_encoder *e,
                         const struct labcomm2014_signature *signature,
                         char has_deps)
 {
-  const struct renamed *renamed;
+  const struct labcomm2014_renaming_rename *renamed;
   struct encoder *ie = e->context;
 
   renamed = get_renamed(e, signature);
   if (renamed) {
-    return ie->next->type_bind(ie->next, &renamed->signature, 1);
+    return ie->next->type_bind(
+      ie->next, labcomm2014_renaming_rename_signature(renamed), 1);
   } else {
     return ie->next->type_bind(ie->next, signature, has_deps);
   }
@@ -164,21 +125,23 @@ static int do_sample_register(struct labcomm2014_encoder *e,
                          const struct labcomm2014_signature *signature, 
                          labcomm2014_encoder_function encode)
 {
-  const struct renamed *renamed;
+  const struct labcomm2014_renaming_rename *renamed;
   struct encoder *ie = e->context;
 
   renamed = set_renamed(e, signature);  
-  return ie->next->sample_register(ie->next, &renamed->signature, encode);
+  return ie->next->sample_register(
+    ie->next, labcomm2014_renaming_rename_signature(renamed), encode);
 }
 
 static int do_ref_register(struct labcomm2014_encoder *e, 
                       const struct labcomm2014_signature *signature)
 {
-  const struct renamed *renamed;
+  const struct labcomm2014_renaming_rename *renamed;
   struct encoder *ie = e->context;
 
   renamed = set_renamed(e, signature);  
-  return ie->next->ref_register(ie->next, &renamed->signature);
+  return ie->next->ref_register(ie->next,
+                                labcomm2014_renaming_rename_signature(renamed));
 }
 
 static int do_encode(struct labcomm2014_encoder *e, 
@@ -186,14 +149,16 @@ static int do_encode(struct labcomm2014_encoder *e,
                      labcomm2014_encoder_function encode,
                      void *value)
 {
-  const struct renamed *renamed;
+  const struct labcomm2014_renaming_rename *renamed;
   struct encoder *ie = e->context;
 
   renamed = get_renamed(e, signature);
   if (renamed == NULL) {
     return -EINVAL;
   } else {
-    return ie->next->encode(ie->next, &renamed->signature, encode, value);
+    return ie->next->encode(ie->next,
+                            labcomm2014_renaming_rename_signature(renamed),
+                            encode, value);
   }
 }
 
@@ -201,12 +166,12 @@ static int do_ioctl(struct labcomm2014_encoder *e,
                     const struct labcomm2014_signature *signature,
                     uint32_t ioctl_action, va_list args)
 {
-  const struct renamed *renamed;
+  const struct labcomm2014_renaming_rename *renamed;
   struct encoder *ie = e->context;
 
   renamed = get_renamed(e, signature);
   if (renamed != NULL) {
-    signature = &renamed->signature;
+    signature = labcomm2014_renaming_rename_signature(renamed);
   }
   return ie->next->ioctl(ie->next, signature, ioctl_action, args);
 }
@@ -224,14 +189,15 @@ static const struct labcomm2014_sample_ref *do_ref_get(
   struct labcomm2014_encoder *e,
   const struct labcomm2014_signature *signature)
 {
-  const struct renamed *renamed;
+  const struct labcomm2014_renaming_rename *renamed;
   struct encoder *ie = e->context;
 
   renamed = get_renamed(e, signature);
   if (renamed == NULL) {
     return ie->next->ref_get(ie->next, signature);
   } else {
-    return ie->next->ref_get(ie->next, &renamed->signature);
+    return ie->next->ref_get(
+      ie->next, labcomm2014_renaming_rename_signature(renamed));
   }
 }
 
@@ -240,20 +206,23 @@ static void do_free(struct labcomm2014_encoder *e)
   struct encoder *ie = e->context;
   int i;
 
-  LABCOMM_SIGNATURE_ARRAY_FOREACH(ie->renamed, struct renamed *, i) {
-    struct renamed *r;
-    r = LABCOMM_SIGNATURE_ARRAY_GET(ie->renamed, struct renamed *, i, NULL);
+  LABCOMM_SIGNATURE_ARRAY_FOREACH(ie->renamed,
+                                  struct labcomm2014_renaming_rename *, i) {
+    struct labcomm2014_renaming_rename *r;
+    r = LABCOMM_SIGNATURE_ARRAY_GET(ie->renamed,
+                                    struct labcomm2014_renaming_rename *, i,
+                                    NULL);
     if (r) {
-      labcomm2014_memory_free(e->memory, 0, r->signature.name);
-      labcomm2014_memory_free(e->memory, 0, r);
+      labcomm2014_renaming_rename_free(ie->registry, r);
     }
   }
-  LABCOMM_SIGNATURE_ARRAY_FREE(e->memory, ie->renamed, struct renamed *);
+  LABCOMM_SIGNATURE_ARRAY_FREE(e->memory, ie->renamed, struct labcomm2014_renaming_rename *);
   labcomm2014_memory_free(e->memory, 0, ie);
 }
 
 struct labcomm2014_encoder *labcomm2014_renaming_encoder_new(
   struct labcomm2014_encoder *e,
+  struct labcomm2014_renaming_registry *registry,
   char *(*rename)(struct labcomm2014_memory *m, char *name, void *context),
   void *context)
 {
@@ -277,10 +246,11 @@ struct labcomm2014_encoder *labcomm2014_renaming_encoder_new(
       result->encoder.sample_ref_to_index = do_sample_ref_to_index;
       result->encoder.ref_get = do_ref_get;
       result->next = e;
-      result->rename = rename;
+      result->registry = registry;
+      result->rename_func = rename;
       result->context = context;
       LABCOMM_SIGNATURE_ARRAY_INIT(result->renamed,
-                                   struct renamed *);
+                                   struct labcomm2014_renaming_rename *);
       return &(result->encoder);
   }
 }
diff --git a/lib/c/2014/labcomm2014_renaming_encoder.h b/lib/c/2014/labcomm2014_renaming_encoder.h
index acbcbae0176b4b633849f7df0e4991d0d5b4a4cd..bd7e38cedd82f680667f7b56b5df45aaa7fc3e0a 100644
--- a/lib/c/2014/labcomm2014_renaming_encoder.h
+++ b/lib/c/2014/labcomm2014_renaming_encoder.h
@@ -23,9 +23,11 @@
 #define __LABCOMM2014_RENAMING_ENCODER_H__
 
 #include "labcomm2014.h"
+#include "labcomm2014_renaming.h"
 
 struct labcomm2014_encoder *labcomm2014_renaming_encoder_new(
   struct labcomm2014_encoder *e,
+  struct labcomm2014_renaming_registry *r,
   char *(*rename)(struct labcomm2014_memory *m, char *name, void *context),
   void *context);
 
diff --git a/lib/c/2014/labcomm2014_renaming_private.h b/lib/c/2014/labcomm2014_renaming_private.h
new file mode 100644
index 0000000000000000000000000000000000000000..a6926772d13b307b254d3c98be59ad2b131157d6
--- /dev/null
+++ b/lib/c/2014/labcomm2014_renaming_private.h
@@ -0,0 +1,42 @@
+/*
+  labcomm2014_renaming_private.h -- functions intended for renaming
+                                    encoders and decoders
+
+  Copyright 2015 Anders Blomdell <anders.blomdell@control.lth.se>
+
+  This file is part of LabComm.
+
+  LabComm is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  LabComm is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __LABCOMM2014_RENAMING__PRIVATE_H__
+#define __LABCOMM2014_RENAMING_PRIVATE_H__
+
+#include "labcomm2014.h"
+#include "labcomm2014_renaming.h"
+
+struct labcomm2014_renaming_rename *labcomm2014_renaming_rename_new(
+  struct labcomm2014_renaming_registry *r,
+  const struct labcomm2014_signature *signature,
+  char *(*rename)(struct labcomm2014_memory *m, char *name, void *context),
+  void *context);
+
+void labcomm2014_renaming_rename_free(
+  struct labcomm2014_renaming_registry *r,
+  struct labcomm2014_renaming_rename *rename);
+
+const struct labcomm2014_signature *labcomm2014_renaming_rename_signature(
+  const struct labcomm2014_renaming_rename *rename);
+
+#endif
diff --git a/lib/c/2014/labcomm2014_renaming_registry.c b/lib/c/2014/labcomm2014_renaming_registry.c
new file mode 100644
index 0000000000000000000000000000000000000000..03949e0a4500532b4628dbd6947497b3fc1281f4
--- /dev/null
+++ b/lib/c/2014/labcomm2014_renaming_registry.c
@@ -0,0 +1,232 @@
+/*
+  labcomm2014_renaming_registry.c -- renaming registry
+
+  Copyright 2015 Anders Blomdell <anders.blomdell@control.lth.se>
+
+  This file is part of LabComm.
+
+  LabComm is free software: you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation, either version 3 of the License, or
+  (at your option) any later version.
+
+  LabComm is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "labcomm2014.h"
+#include "labcomm2014_private.h"
+#include "labcomm2014_renaming_private.h"
+
+struct alias {
+  int usecount;
+  struct alias *next;
+  char *name;
+};
+
+struct registry {
+  struct registry *base; /* NULL if this is the base type */
+  const struct labcomm2014_signature *signature;
+  struct labcomm2014_renaming_rename *rename;
+};
+
+struct labcomm2014_renaming_rename {
+  struct labcomm2014_renaming_rename *next;
+  int use_count;
+  struct registry *base;
+  struct labcomm2014_signature signature;
+  struct labcomm2014_signature_data s_treedata[2];
+};
+
+struct labcomm2014_renaming_registry {
+  struct labcomm2014_error_handler *error;
+  struct labcomm2014_memory *memory;
+  struct labcomm2014_scheduler *scheduler;
+  LABCOMM_SIGNATURE_ARRAY_DEF(registry, struct registry *);
+};
+
+struct labcomm2014_renaming_registry *labcomm2014_renaming_registry_new(
+  struct labcomm2014_error_handler *error,
+  struct labcomm2014_memory *memory,
+  struct labcomm2014_scheduler *scheduler)
+{
+  struct labcomm2014_renaming_registry *result;
+  result = labcomm2014_memory_alloc(memory, 0, sizeof(*result));
+  if (! result) {
+    return NULL;
+  } else {
+    result->error = error;
+    result->memory = memory;
+    result->scheduler = scheduler;
+    LABCOMM_SIGNATURE_ARRAY_INIT(result->registry, struct registry *);
+    return result;
+  }
+}
+
+void labcomm2014_renaming_registry_free(
+  struct labcomm2014_renaming_registry *r)
+{
+  LABCOMM_SIGNATURE_ARRAY_FREE(r->memory, r->registry, struct registry *);
+  labcomm2014_memory_free(r->memory, 0, r);
+}
+
+static struct registry *registry_new(
+  struct labcomm2014_renaming_registry *r,
+  const struct labcomm2014_signature *signature,
+  struct registry *base)
+{
+  /* Called with registry locked */
+  struct registry *result = NULL;
+  struct registry **registry;
+  int index;
+
+  index = labcomm2014_get_local_index(signature);
+  if (index <= 0) {
+    labcomm2014_error_warning(r->error,
+                              LABCOMM2014_ERROR_MEMORY,
+                              "Signature has no index: %s\n",
+                              signature->name);
+    goto out;
+  }
+  registry = LABCOMM_SIGNATURE_ARRAY_REF(r->memory, r->registry,
+                                          struct registry *, index);
+  if (registry == NULL) { goto out; }
+  if (*registry != NULL) {
+    result = *registry;
+  } else {
+    /* Add previosly unknown sample to registry */
+    registry = LABCOMM_SIGNATURE_ARRAY_REF(r->memory, r->registry,
+                                          struct registry *, index);
+    if (registry == NULL) { goto out; }
+    result = labcomm2014_memory_alloc(r->memory, 0, sizeof(*result));
+    if (result == NULL) { goto out; }
+    result->base = base;
+    result->signature = signature;
+    result->rename = NULL;
+    *registry = result;
+  }
+out:
+  return result;
+}
+
+struct labcomm2014_renaming_rename *labcomm2014_renaming_rename_new(
+  struct labcomm2014_renaming_registry *r,
+  const struct labcomm2014_signature *signature,
+  char *(*rename)(struct labcomm2014_memory *m, char *name, void *context),
+  void *context)
+{
+  struct labcomm2014_renaming_rename *result = NULL;
+
+  labcomm2014_scheduler_data_lock(r->scheduler);
+  {
+    char *new_name = NULL;
+    static struct registry *base, *renamed;
+    struct labcomm2014_renaming_rename **l;
+
+    base = registry_new(r, signature, NULL);
+    if (base == NULL) { goto out; }
+    if (base->base) {
+      base = base->base;
+    }
+
+    /* Find if renamed entry already exists */
+    new_name = rename(r->memory, signature->name, context);
+    if (new_name == NULL) { goto out; }
+    for (l = &base->rename ; *l ; l = &(*l)->next) {
+      if (strcmp((*l)->signature.name, new_name) == 0) { break; }
+    }
+    if ((*l) == NULL) {
+      /* Create a new rename entry */
+      struct labcomm2014_renaming_rename *entry = NULL;
+
+      entry = labcomm2014_memory_alloc(r->memory, 0, sizeof(*entry));
+      if (entry == NULL) { goto out; }
+      entry->signature.name = new_name;
+      new_name = NULL;
+      entry->signature.encoded_size = base->signature->encoded_size;
+      entry->signature.size = base->signature->size;
+      entry->signature.signature = base->signature->signature;
+      entry->signature.index = 0;
+#ifndef LABCOMM_NO_TYPEDECL
+      struct labcomm2014_signature_data s_treedata[2] = {
+        LABCOMM_SIGDEF_SIGNATURE(*base->signature),
+        LABCOMM_SIGDEF_END
+      };
+      entry->s_treedata[0] = s_treedata[0];
+      entry->s_treedata[1] = s_treedata[1];
+      entry->signature.tdsize = sizeof(entry->s_treedata);
+      entry->signature.treedata = entry->s_treedata;
+#endif
+      labcomm2014_set_local_index(&entry->signature);
+      renamed = registry_new(r, &entry->signature, base);
+      if (renamed == NULL) {
+        /* Failed to create registry entry */
+        labcomm2014_memory_free(r->memory, 0, entry);
+        goto out;
+      } else {
+        entry->next = NULL;
+        entry->use_count = 0;
+        entry->base = base;
+        (*l) = entry;
+      }
+    }
+    result = *l;
+    if (result) {
+      result->use_count++;
+    }
+  out:
+    if (new_name != NULL) {
+      labcomm2014_memory_free(r->memory, 0, new_name);
+    }
+  }
+  labcomm2014_scheduler_data_unlock(r->scheduler);
+  return result;
+}
+
+void labcomm2014_renaming_rename_free(
+  struct labcomm2014_renaming_registry *r,
+  struct labcomm2014_renaming_rename *rename)
+{
+  labcomm2014_scheduler_data_lock(r->scheduler);
+  rename->use_count--;
+  if (rename->use_count == 0) {
+    int index;
+    struct labcomm2014_renaming_rename **l;
+    struct registry **registry;
+
+    for (l = &rename->base->rename ; *l ; l = &(*l)->next) {
+      if (*l == rename) { break; }
+    }
+    *l = rename->next;
+    if (rename->base->rename == NULL) {
+      /* Last use of base signature */
+      index = labcomm2014_get_local_index(rename->base->signature);
+      registry = LABCOMM_SIGNATURE_ARRAY_REF(r->memory, r->registry,
+                                             struct registry *, index);
+      labcomm2014_memory_free(r->memory, 0, *registry);
+      *registry = NULL;
+    }
+    index = labcomm2014_get_local_index(&rename->signature);
+    registry = LABCOMM_SIGNATURE_ARRAY_REF(r->memory, r->registry,
+                                           struct registry *, index);
+    labcomm2014_memory_free(r->memory, 0, *registry);
+    *registry = NULL;
+       
+    /* TODO: We should return the index to the pool*/
+    labcomm2014_memory_free(r->memory, 0, rename->signature.name);
+    labcomm2014_memory_free(r->memory, 0, rename);
+  }
+  labcomm2014_scheduler_data_unlock(r->scheduler);
+
+}
+
+const struct labcomm2014_signature *labcomm2014_renaming_rename_signature(
+  const struct labcomm2014_renaming_rename *rename)
+{
+  return &rename->signature;
+}
diff --git a/lib/c/2014/test/test_labcomm_renaming_decoder.c b/lib/c/2014/test/test_labcomm_renaming_decoder.c
index b0c4bd5aaefd8ee517f162bbb8e56150e9a8bf4d..36631d7148e2ea4e36c32f7ba7edd6d475a815ce 100644
--- a/lib/c/2014/test/test_labcomm_renaming_decoder.c
+++ b/lib/c/2014/test/test_labcomm_renaming_decoder.c
@@ -28,6 +28,7 @@ static void handle_r(generated_encoding_R *v, void *context)
 
 int main(int argc, char **argv)
 {
+  struct labcomm2014_renaming_registry *registry;
   struct labcomm2014_encoder *encoder, *prefix_encoder, *suffix_encoder;
   struct labcomm2014_decoder *decoder, *prefix_decoder, *suffix_decoder;
   int fd;
@@ -38,15 +39,19 @@ int main(int argc, char **argv)
   if (fd == -1) {
     err(1, "open()");
   }
+  registry = labcomm2014_renaming_registry_new(
+    labcomm2014_default_error_handler,
+    labcomm2014_default_memory,
+    labcomm2014_default_scheduler);
   encoder = labcomm2014_encoder_new(
     labcomm2014_fd_writer_new(labcomm2014_default_memory, fd, 0),
     labcomm2014_default_error_handler,
     labcomm2014_default_memory,
     labcomm2014_default_scheduler);
   prefix_encoder = labcomm2014_renaming_encoder_new(
-    encoder, labcomm2014_renaming_prefix, "p.");
+    encoder, registry, labcomm2014_renaming_prefix, "p.");
   suffix_encoder = labcomm2014_renaming_encoder_new(
-    prefix_encoder, labcomm2014_renaming_suffix, ".s");
+    prefix_encoder, registry, labcomm2014_renaming_suffix, ".s");
 
   labcomm2014_encoder_register_generated_encoding_R(encoder);
   labcomm2014_encoder_register_generated_encoding_R(prefix_encoder);
@@ -90,9 +95,9 @@ int main(int argc, char **argv)
       labcomm2014_default_memory,
       labcomm2014_default_scheduler);
   prefix_decoder = labcomm2014_renaming_decoder_new(
-    decoder, labcomm2014_renaming_prefix, "p.");
+    decoder, registry, labcomm2014_renaming_prefix, "p.");
   suffix_decoder = labcomm2014_renaming_decoder_new(
-    prefix_decoder, labcomm2014_renaming_suffix, ".s");
+    prefix_decoder, registry, labcomm2014_renaming_suffix, ".s");
 
   labcomm2014_decoder_register_generated_encoding_R(
     decoder, handle_r, &cache_r);
@@ -172,6 +177,7 @@ int main(int argc, char **argv)
   labcomm2014_decoder_free(suffix_decoder);
   labcomm2014_decoder_free(prefix_decoder);
   labcomm2014_decoder_free(decoder);
+  labcomm2014_renaming_registry_free(registry);
 
   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 7996b2321158521b2151d263f7f735a741defa08..b598e1ea03b64f51605463b306192ac35510b835 100644
--- a/lib/c/2014/test/test_labcomm_renaming_encoder.c
+++ b/lib/c/2014/test/test_labcomm_renaming_encoder.c
@@ -132,10 +132,18 @@ static int buf_writer_ioctl(
 	  mismatch = 1;
 	}
       }
-      if (1 || mismatch) {
+      if (mismatch) {
 	fprintf(stderr, "Encoder mismatch (%s:%d)\n",
 		__FILE__, line);
 
+	for (i = 0 ; i < w->pos ; i++) {
+          if (32 <= w->data[i] &&  w->data[i] < 127) {
+            printf("%2c ", w->data[i]);
+          } else {
+            printf("%2.2x ", w->data[i]);
+          }
+	}
+	printf("\n");
 	for (i = 0 ; i < w->pos ; i++) {
 	  printf("%2.2x ", w->data[i]);
 	}
@@ -195,6 +203,7 @@ void dump_encoder(struct labcomm2014_encoder *encoder)
 
 static int do_test(int argc, char *argv[])
 {
+  struct labcomm2014_renaming_registry *registry;
   struct labcomm2014_encoder *encoder, *prefix, *suffix;
   int i;
 
@@ -202,15 +211,21 @@ static int do_test(int argc, char *argv[])
     seen_variable[i] = -1;
   }
 
+  registry = labcomm2014_renaming_registry_new(
+    labcomm2014_default_error_handler,
+    labcomm2014_default_memory,
+    labcomm2014_default_scheduler);
   encoder = labcomm2014_encoder_new(
     &buffer_writer, 
     labcomm2014_default_error_handler,
     labcomm2014_default_memory,
     labcomm2014_default_scheduler);
   prefix = labcomm2014_renaming_encoder_new(encoder,
+                                            registry,
                                             labcomm2014_renaming_prefix,
                                             "p.");
   suffix = labcomm2014_renaming_encoder_new(prefix,
+                                            registry,
                                             labcomm2014_renaming_suffix,
                                             ".s");
   EXPECT({ 0x01, 0x0c, 0x0b, 
@@ -235,9 +250,16 @@ static int do_test(int argc, char *argv[])
   labcomm2014_encoder_ioctl(suffix, IOCTL_WRITER_RESET);
   labcomm2014_encoder_register_generated_encoding_V(suffix);
   labcomm2014_encoder_register_generated_encoding_V(suffix);
+// XXX HERE BE DRAGONS!  What does "BOGUS" man in the below renaming test?
+// previous version (from merge conflict): VARIABLE(6) vs VARIABLE(2)
+// <<<<<<< ours
+//   EXPECT({ 0x02, 0x0c, VARIABLE(5), 0x01, 0x00, 0x05, 'p', '.', 'V', '.', 's', 0x02, 0x11, 0x00,
+//            0x04, 0x09, VARIABLE(6), 0x01, 0x00, 0x03, 'V', '.', 's', 0x01, VARIABLE(2),
+//            0x04, 0x0b, VARIABLE(7), 0x01, 0x00, 0x05, 'p', '.', 'V', '.', 's', 0x01, VARIABLE(6),
+// =======
   EXPECT({ 0x02, 0x0c, VARIABLE(5), 0x01, 0x00, 0x05, 'p', '.', 'V', '.', 's', 0x02, 0x11, 0x00,
-           0x04, 0x09, VARIABLE(6), 0x01, 0x00, 0x03, 'V', '.', 's', 0x01, VARIABLE(2),
-           0x04, 0x0b, VARIABLE(7), 0x01, 0x00, 0x05, 'p', '.', 'V', '.', 's', 0x01, VARIABLE(6),
+           0x04, 0x09, VARIABLE(6), 0x01, 0x00, 0x03, 'V', '.', 's', 0x01, VARIABLE(2), /* BOGUS */
+           0x04, 0x0b, VARIABLE(7), 0x01, 0x00, 0x05, 'p', '.', 'V', '.', 's', 0x01, VARIABLE(2),
            0x05, 0x02, VARIABLE(5), VARIABLE(7) });
 
 
@@ -280,6 +302,7 @@ static int do_test(int argc, char *argv[])
   labcomm2014_encoder_free(suffix);
   labcomm2014_encoder_free(prefix);
   labcomm2014_encoder_free(encoder);
+  labcomm2014_renaming_registry_free(registry);
 
   return 0;
 }
diff --git a/lib/c/2014/test/test_labcomm_renaming_registry.c b/lib/c/2014/test/test_labcomm_renaming_registry.c
new file mode 100644
index 0000000000000000000000000000000000000000..903450c59083e325b757fd894947b0f459aa1d52
--- /dev/null
+++ b/lib/c/2014/test/test_labcomm_renaming_registry.c
@@ -0,0 +1,56 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <assert.h>
+#include <err.h>
+
+#include "labcomm2014.h"
+#include "labcomm2014_private.h"
+#include "labcomm2014_default_error_handler.h"
+#include "labcomm2014_default_memory.h"
+#include "labcomm2014_default_scheduler.h"
+#include "labcomm2014_renaming.h"
+#include "labcomm2014_renaming_private.h"
+#include "test/gen/generated_encoding.h"
+
+static int do_test(int argc, char **argv)
+{
+  struct labcomm2014_renaming_registry *registry;
+  struct labcomm2014_renaming_rename *r1, *r2, *r3, *r4;
+
+  registry = labcomm2014_renaming_registry_new(
+    labcomm2014_default_error_handler,
+    labcomm2014_default_memory,
+    labcomm2014_default_scheduler);
+  r1 = labcomm2014_renaming_rename_new(
+    registry,
+    labcomm2014_signature_generated_encoding_R,
+    labcomm2014_renaming_prefix, "p:");
+  r2 = labcomm2014_renaming_rename_new(
+    registry,
+    labcomm2014_renaming_rename_signature(r1),
+    labcomm2014_renaming_suffix, ":s");
+  r3 = labcomm2014_renaming_rename_new(
+    registry,
+    labcomm2014_signature_generated_encoding_R,
+    labcomm2014_renaming_suffix, ":s");
+  r4 = labcomm2014_renaming_rename_new(
+    registry,
+    labcomm2014_renaming_rename_signature(r3),
+    labcomm2014_renaming_prefix, "p:");
+  assert(r2 == r4);
+  labcomm2014_renaming_rename_free(registry, r1);
+  labcomm2014_renaming_rename_free(registry, r2);
+  labcomm2014_renaming_rename_free(registry, r3);
+  labcomm2014_renaming_rename_free(registry, r4);
+  labcomm2014_renaming_registry_free(registry);
+  return 0;
+}
+
+int main(int argc, char **argv)
+{
+  return do_test(argc, argv);
+}
diff --git a/lib/csharp/Makefile b/lib/csharp/Makefile
index c689902e17402080d3f993ed7d9f00763c5967e1..0c67e052db39ee02344de066c159adf7648a9dba 100644
--- a/lib/csharp/Makefile
+++ b/lib/csharp/Makefile
@@ -1,4 +1,5 @@
-MODULES=Constant\
+MODULES=AbstractDecoder \
+        Constant\
 	Decoder \
 	DecoderChannel \
 	DecoderRegistry \
@@ -8,7 +9,7 @@ MODULES=Constant\
 	Sample \
 	SampleDispatcher \
 	SampleHandler \
-	SampleType 
+	SampleType
 
 .PHONY: all
 all: labcomm2014.dll
diff --git a/lib/csharp/se/lth/control/labcomm2014/AbstractDecoder.cs b/lib/csharp/se/lth/control/labcomm2014/AbstractDecoder.cs
new file mode 100644
index 0000000000000000000000000000000000000000..4ea8760333148a13838cb111949854a46e4b4820
--- /dev/null
+++ b/lib/csharp/se/lth/control/labcomm2014/AbstractDecoder.cs
@@ -0,0 +1,18 @@
+using System;
+
+namespace se.lth.control.labcomm2014 {
+
+  public interface AbstractDecoder {
+
+    void runOne();
+
+    void run();
+
+    void register(SampleDispatcher dispatcher, 
+		  SampleHandler handler);
+
+    void registerSampleRef(SampleDispatcher dispatcher);
+
+  }
+
+} 
diff --git a/lib/csharp/se/lth/control/labcomm2014/Decoder.cs b/lib/csharp/se/lth/control/labcomm2014/Decoder.cs
index ddc3b59f52fa9483332f5c358d00ee4a18d92dcf..0d79bcab539a512205fe0c40e7fe16296f8feb5e 100644
--- a/lib/csharp/se/lth/control/labcomm2014/Decoder.cs
+++ b/lib/csharp/se/lth/control/labcomm2014/Decoder.cs
@@ -2,11 +2,7 @@ using System;
 
 namespace se.lth.control.labcomm2014 {
 
-  public interface Decoder {
-
-    void register(SampleDispatcher dispatcher, 
-		  SampleHandler handler);
-    void registerSampleRef(SampleDispatcher dispatcher);
+  public interface Decoder : AbstractDecoder {
 
     bool decodeBoolean();
     byte decodeByte();
@@ -17,7 +13,7 @@ namespace se.lth.control.labcomm2014 {
     double decodeDouble();
     String decodeString();
     int decodePacked32();
-    Type decodeSampleRef();
+    SampleDispatcher decodeSampleRef();
 
   }
 
diff --git a/lib/csharp/se/lth/control/labcomm2014/DecoderChannel.cs b/lib/csharp/se/lth/control/labcomm2014/DecoderChannel.cs
index 6d11ba99c5e2161f4b6ecf5b78579072e8e924ca..9638477ce8e450ac90491220abb80ed3b676959e 100644
--- a/lib/csharp/se/lth/control/labcomm2014/DecoderChannel.cs
+++ b/lib/csharp/se/lth/control/labcomm2014/DecoderChannel.cs
@@ -190,11 +190,11 @@ namespace se.lth.control.labcomm2014 {
     return name;
   }
 
-    public Type decodeSampleRef() {
+    public SampleDispatcher decodeSampleRef() {
       int index = (int)ReadInt(4);
       try {
         DecoderRegistry.Entry e = ref_registry.get(index);
-        return e.getSampleDispatcher().getSampleClass();
+        return e.getSampleDispatcher().getSampleIdentity();
       } catch (NullReferenceException) {
         return null;
       }
diff --git a/lib/csharp/se/lth/control/labcomm2014/DecoderRegistry.cs b/lib/csharp/se/lth/control/labcomm2014/DecoderRegistry.cs
index bebcff26c7355a184b471234ca85f72043d0f493..6c7a4a49fc5d4d66336015cacceeb259bb637784 100644
--- a/lib/csharp/se/lth/control/labcomm2014/DecoderRegistry.cs
+++ b/lib/csharp/se/lth/control/labcomm2014/DecoderRegistry.cs
@@ -90,11 +90,11 @@ namespace se.lth.control.labcomm2014 {
       }
     }
 
-    private Dictionary<Type, Entry> byClass;
+    private Dictionary<SampleDispatcher, Entry> byIdentity;
     private Dictionary<int, Entry> byIndex;
 
     public DecoderRegistry() {
-      byClass = new Dictionary<Type, Entry>();
+      byIdentity = new Dictionary<SampleDispatcher, Entry>();
       byIndex = new Dictionary<int, Entry>();
     }
 
@@ -102,7 +102,7 @@ namespace se.lth.control.labcomm2014 {
 		    SampleHandler handler) {
       lock(this) {
 	Entry e;
-	byClass.TryGetValue(dispatcher.getSampleClass(), out e);
+	byIdentity.TryGetValue(dispatcher.getSampleIdentity(), out e);
 	if (e != null) {
 	  e.check(dispatcher.getName(), dispatcher.getSignature());
 	  e.setHandler(handler);
@@ -117,7 +117,7 @@ namespace se.lth.control.labcomm2014 {
 	  }
 	  if (e == null) {
 	    e = new Entry(dispatcher, handler);
-	    byClass.Add(dispatcher.getSampleClass(), e);
+	    byIdentity.Add(dispatcher.getSampleIdentity(), e);
 	  }
 	}
       }
@@ -132,7 +132,7 @@ namespace se.lth.control.labcomm2014 {
 	if (e != null) {
 	  e.check(name, signature);
 	} else {
-	  foreach (Entry e2 in byClass.Values) {
+	  foreach (Entry e2 in byIdentity.Values) {
 	    if (e2.match(name, signature)) {
 	      e2.setIndex(index);
 	      e = e2;
diff --git a/lib/csharp/se/lth/control/labcomm2014/Encoder.cs b/lib/csharp/se/lth/control/labcomm2014/Encoder.cs
index 4aac7b3ac949019684b969d462cf8d93b0b4c4e7..08d77514037bc3bfdd1c1526f60c91b653bd1790 100644
--- a/lib/csharp/se/lth/control/labcomm2014/Encoder.cs
+++ b/lib/csharp/se/lth/control/labcomm2014/Encoder.cs
@@ -6,8 +6,8 @@ namespace se.lth.control.labcomm2014 {
     
     void register(SampleDispatcher dispatcher);
     void registerSampleRef(SampleDispatcher dispatcher);
-    void begin(Type c);
-    void end(Type c);
+    void begin(SampleDispatcher dispatcher);
+    void end(SampleDispatcher dispatcher);
 
     void encodeBoolean(bool value);
     void encodeByte(byte value);
@@ -18,7 +18,7 @@ namespace se.lth.control.labcomm2014 {
     void encodeDouble(double value);
     void encodeString(String value);
     void encodePacked32(Int64 value);
-    void encodeSampleRef(Type value);
+    void encodeSampleRef(SampleDispatcher value);
     
   }
 
diff --git a/lib/csharp/se/lth/control/labcomm2014/EncoderChannel.cs b/lib/csharp/se/lth/control/labcomm2014/EncoderChannel.cs
index b8f98e1203d014a32f20f1fd0274e3f0f9f504d9..b58936aa962af3a6c48d62f8207bad7b0ccb8fef 100644
--- a/lib/csharp/se/lth/control/labcomm2014/EncoderChannel.cs
+++ b/lib/csharp/se/lth/control/labcomm2014/EncoderChannel.cs
@@ -53,11 +53,11 @@ namespace se.lth.control.labcomm2014 {
       bytes.SetLength(0);
     }
 
-    public void begin(Type c) {
-      begin(def_registry.getTag(c));
+    public void begin(SampleDispatcher identity) {
+      begin(def_registry.getTag(identity));
     }
 
-    public void end(Type c) {
+    public void end(SampleDispatcher identity) {
       WritePacked32(writer, current_tag);
       WritePacked32(writer, bytes.Length);
       bytes.WriteTo(writer);
@@ -138,7 +138,7 @@ namespace se.lth.control.labcomm2014 {
       encodeString(name);
     }
 
-    public void encodeSampleRef(Type value) {
+    public void encodeSampleRef(SampleDispatcher value) {
       int index = 0;
       try {
         index = ref_registry.getTag(value);
diff --git a/lib/csharp/se/lth/control/labcomm2014/EncoderRegistry.cs b/lib/csharp/se/lth/control/labcomm2014/EncoderRegistry.cs
index 5d35ecb17235e656c258e8953862e719cd84653a..72ec5f2bb606525014e7e85725b99525b0b6954d 100644
--- a/lib/csharp/se/lth/control/labcomm2014/EncoderRegistry.cs
+++ b/lib/csharp/se/lth/control/labcomm2014/EncoderRegistry.cs
@@ -26,29 +26,29 @@ namespace se.lth.control.labcomm2014 {
     }
 
     private int userIndex = Constant.FIRST_USER_INDEX;
-    private Dictionary<Type, Entry> byClass;
+    private Dictionary<SampleDispatcher, Entry> byIdentity;
 
     public EncoderRegistry() {
-      byClass = new Dictionary<Type, Entry>();
+      byIdentity = new Dictionary<SampleDispatcher, Entry>();
     }
 
     public int add(SampleDispatcher dispatcher) {
       lock(this) {
 	Entry e;
-	byClass.TryGetValue(dispatcher.getSampleClass(), out e);
+	byIdentity.TryGetValue(dispatcher.getSampleIdentity(), out e);
 	if (e == null) {
 	  e = new Entry(dispatcher, userIndex);
-	  byClass.Add(dispatcher.getSampleClass(), e);
+	  byIdentity.Add(dispatcher.getSampleIdentity(), e);
 	  userIndex++;
 	}
 	return e.getIndex();
       }
     }
   
-    public int getTag(Type sample) {
+    public int getTag(SampleDispatcher sample) {
       lock(this) {
 	Entry e;
-	byClass.TryGetValue(sample, out e);
+	byIdentity.TryGetValue(sample, out e);
 	if (e == null) {
 	  throw new Exception("'" + 
 			      sample.ToString() + 
diff --git a/lib/csharp/se/lth/control/labcomm2014/SampleDispatcher.cs b/lib/csharp/se/lth/control/labcomm2014/SampleDispatcher.cs
index b7104d1c28c98e4607858fd6e7958fd5a7022122..de405d1505371766aced4e00462c297942e1a0b1 100644
--- a/lib/csharp/se/lth/control/labcomm2014/SampleDispatcher.cs
+++ b/lib/csharp/se/lth/control/labcomm2014/SampleDispatcher.cs
@@ -4,12 +4,12 @@ namespace se.lth.control.labcomm2014 {
 
   public interface SampleDispatcher {
     
-    Type getSampleClass();
+    SampleDispatcher getSampleIdentity();
     
     String getName();
     
     byte[] getSignature();
-    
+
     void decodeAndHandle(Decoder decoder,
 			 SampleHandler handler);
 
diff --git a/test/Makefile b/test/Makefile
index 0714905b12228697016e4fd26ce0f2b3d4be32f4..456cc4e317402ef207456f21c7273457f09aa2dd 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -1,6 +1,4 @@
-TESTS_RENAME=basic simple nested # sample_ref's does not transfer between
-                                 # encoder decoder for now
-TESTS=$(TESTS_RENAME) ref
+TESTS=basic simple nested ref
 LABCOMM_JAR=../compiler/labcomm2014_compiler.jar
 LABCOMM=java -jar $(LABCOMM_JAR)
 MONO_PATH=$(shell pwd)/../lib/csharp
@@ -10,7 +8,7 @@ include ../lib/c/os_compat.mk
 
 all:
 
-test: $(TESTS:%=test_%) $(TESTS_RENAME:%=test_renaming_%) compiler_errors
+test: $(TESTS:%=test_%) $(TESTS:%=test_renaming_%) compiler_errors
 #	PYTHONPATH=../lib/python \
 #		./test_encoder_decoder.py --labcomm="$(LABCOMM)" basic.lc
 
diff --git a/test/relay_gen_c.py b/test/relay_gen_c.py
index e13f66ab01f77a57a740ba8957b992c99ae7c7c0..3e4944ad762fdca378767c8fd8ec7d24eebb3ca2 100755
--- a/test/relay_gen_c.py
+++ b/test/relay_gen_c.py
@@ -35,6 +35,7 @@ if __name__ == '__main__':
       |#include <sys/stat.h>
       |#include <fcntl.h>
       |#include <stdio.h>
+      |#include <errno.h>
       |#include <labcomm2014.h>
       |#include <labcomm2014_default_error_handler.h>
       |#include <labcomm2014_default_memory.h>
@@ -66,6 +67,7 @@ if __name__ == '__main__':
     """))
     if options.renaming:
         result.extend(split_match('^[^|]*\|(.*)$', """
+        |  struct labcomm2014_renaming_registry *registry;
         |  struct labcomm2014_encoder *e_p, *e_s;
         |  struct labcomm2014_decoder *d_p, *d_s;
         """))
@@ -95,17 +97,25 @@ if __name__ == '__main__':
         """))
     else:
         result.extend(split_match('^[^|]*\|(.*)$', """
+        |  registry = labcomm2014_renaming_registry_new(
+        |    labcomm2014_default_error_handler,
+        |    labcomm2014_default_memory,
+        |    labcomm2014_default_scheduler);
         |  e_p = labcomm2014_renaming_encoder_new(e_e,
+        |                                         registry,
         |                                         labcomm2014_renaming_prefix,
         |                                         "prefix:");
         |  e_s = labcomm2014_renaming_encoder_new(e_p,
+        |                                         registry,
         |                                         labcomm2014_renaming_suffix,
         |                                         ":suffix");
         |  e = e_s;
         |  d_p = labcomm2014_renaming_decoder_new(d_d,
+        |                                         registry,
         |                                         labcomm2014_renaming_prefix,
         |                                         "prefix:");
         |  d_s = labcomm2014_renaming_decoder_new(d_p,
+        |                                         registry,
         |                                         labcomm2014_renaming_suffix,
         |                                         ":suffix");
         |  d = d_s;
@@ -126,12 +136,15 @@ if __name__ == '__main__':
         |  labcomm2014_decoder_free(d_p);
         |  labcomm2014_encoder_free(e_s);
         |  labcomm2014_encoder_free(e_p);
+        |  labcomm2014_renaming_registry_free(registry);
         """))
     result.extend(split_match('^[^|]*\|(.*)$', """
       |  labcomm2014_decoder_free(d_d);
       |  labcomm2014_encoder_free(e_e);
+      |  if (result == 0) return 0;
+      |  if (result == -EPIPE) return 0;
       |  fprintf(stderr, "Failed with %d", result);
-      |  return 0;
+      |  return 1;
       |}
     """))
     print "\n".join(result)