diff --git a/compiler/C_CodeGen.jrag b/compiler/C_CodeGen.jrag
index d14895095392a1e7bdff9270a7cf72ec8aa1efa7..7ccb94425845f4ecc9044ea2241a9a0287c495ac 100644
--- a/compiler/C_CodeGen.jrag
+++ b/compiler/C_CodeGen.jrag
@@ -40,9 +40,12 @@ aspect C_CodeGenEnv {
     private int indent;
     public final int depth;
     private C_printer printer;
+    public final int nestedLevel;
+    private boolean rootIsPointer;
+    private int rootLevel;
 
     private C_env(String qualid, String lcName, String rawPrefix, 
-		  int indent, int depth, C_printer printer) {
+		  int indent, int depth, C_printer printer, int nestedLevel) {
       this.qualid = qualid;
       this.lcName = lcName;
       this.rawPrefix = rawPrefix;
@@ -54,6 +57,7 @@ aspect C_CodeGenEnv {
       this.indent = indent;
       this.depth = depth;
       this.printer = printer;
+      this.nestedLevel = nestedLevel;
     }
 
     public C_env(String qualid, String lcName, String rawPrefix, 
@@ -69,16 +73,22 @@ aspect C_CodeGenEnv {
       this.depth = 0;
       this.indent = 0;
       this.printer = new C_printer(out);
+      this.nestedLevel = 0;
+    }
+
+    public C_env(String qualid, String lcName, String rawPrefix,
+		 int indent, int depth, C_printer printer) {
+      this(qualid, lcName, rawPrefix, indent, depth, printer, 0);
     }
 
     public C_env nestArray(String suffix) {
       return new C_env(qualid + suffix, lcName, rawPrefix, 
-		       indent, depth + 1, printer);
+		       indent, depth + 1, printer, nestedLevel + 1);
     }
 
     public C_env nestStruct(String suffix) {
       return new C_env(qualid + suffix, lcName, rawPrefix, 
-		       indent, depth, printer);
+		       indent, depth, printer, nestedLevel + 1);
     }
 
     public void indent() {
@@ -101,6 +111,19 @@ aspect C_CodeGenEnv {
       printer.println(this, s);
     }
 
+    public C_env setPointer() {
+      rootIsPointer = true;
+      rootLevel = nestedLevel;
+      return this;
+    }
+
+    public String memberAccessor() {
+      return (rootIsPointer && (nestedLevel == rootLevel)) ? "->" : ".";
+    }
+
+    public String accessor() {
+      return (rootIsPointer && (nestedLevel == rootLevel)) ? "*" : "";
+    }
   }
 
   public C_env ArrayType.C_Nest(C_env env) {
@@ -110,7 +133,7 @@ aspect C_CodeGenEnv {
   }
 
   public C_env FixedArrayType.C_Nest(C_env env) {
-    String index = ".a";
+    String index = env.memberAccessor() + "a";
     for (int i = 0 ; i < getNumExp() ; i++) {
       index += "[i_" + env.depth + "_" + i + "]";
     }
@@ -118,7 +141,7 @@ aspect C_CodeGenEnv {
   }
 
   public C_env VariableArrayType.C_Nest(C_env env) {
-    return env.nestArray(".a[i_" + env.depth + "]");
+    return env.nestArray(env.memberAccessor() + "a[i_" + env.depth + "]");
   }
 
 
@@ -195,6 +218,8 @@ aspect C_CodeGen {
       getDecl(i).C_emitDecoderDeclaration(env);
       getDecl(i).C_emitEncoderDeclaration(env);
       getDecl(i).C_emitSizeofDeclaration(env);
+      getDecl(i).C_emitCopyDeclaration(env);
+      getDecl(i).C_emitCopyDeallocationDeclaration(env);
       env.println("");
     }
     C_emitConstructorDeclaration(env);
@@ -211,6 +236,8 @@ aspect C_CodeGen {
       getDecl(i).C_emitEncoderRegisterHandler(env);
       getDecl(i).C_emitEncoderIoctl(env);
       getDecl(i).C_emitSizeof(env);
+      getDecl(i).C_emitCopy(env);
+      getDecl(i).C_emitCopyDeallocation(env);
     }
     C_emitConstructor(env);
   }
@@ -405,7 +432,7 @@ aspect C_Limit {
   }
 
   public String VariableSize.C_getLimit(C_env env, int i) {
-    return env.qualid + ".n_" + i;
+    return env.qualid + env.memberAccessor() + "n_" + i;
   }
   
 }
@@ -653,6 +680,259 @@ aspect C_Decoder {
 
 }
 
+aspect C_copy {
+
+  private void SampleDecl.C_emitCopyFunctionParam(C_env env_src, String src,
+						  String dst)
+  {
+    env_src.println("void labcomm_copy_" + env_src.prefix + getName() + "(");
+    env_src.indent();
+    env_src.println("struct labcomm_memory *mem,");
+    env_src.println(env_src.prefix + getName() + " *" + dst + ",");
+    env_src.println(env_src.prefix + getName() + " *" + src);
+    env_src.unindent();
+    env_src.print(")");
+  }
+
+  public void Decl.C_emitCopyDeclaration(C_env env) {
+  }
+
+  public void SampleDecl.C_emitCopyDeclaration(C_env env) {
+    C_emitCopyFunctionParam(env, "src", "dst");
+    env.println(";");
+  }
+
+  public void Decl.C_emitCopy(C_env env) {
+    throw new Error(this.getClass().getName() + 
+		    ".C_emitCopy(C_env env)" + 
+		    " not declared");
+  }
+
+  public void TypeDecl.C_emitCopy(C_env env) {
+  }
+
+  public void SampleDecl.C_emitCopy(C_env env) {
+    final String dst = "dst";
+    final String src = "src";
+    C_env env_src = env.nestStruct(src).setPointer();
+    C_env env_dst = env.nestStruct(dst).setPointer();
+
+    C_emitCopyFunctionParam(env_src, src, dst);
+    env_src.println("");
+    env_src.println("{");
+    env_src.indent();
+    getType().C_emitCopy(env_src, env_dst);
+    env_src.unindent();
+    env_src.println("}");
+  }
+
+  public void Type.C_emitCopy(C_env env_src, C_env env_dst) {
+    throw new Error(this.getClass().getName() + 
+		    ".C_emitCopy(C_env env)" + 
+		    " not declared");
+  }
+
+  public void VoidType.C_emitCopy(C_env env_src, C_env env_dst) {
+  }
+
+  public void PrimType.C_emitCopy(C_env env_src, C_env env_dst) {
+    if (C_isDynamic()) {
+      env_src.println(String.format(
+	  "%s%s = labcomm_memory_alloc(mem, 1, strlen(%s%s)+1);",
+	  env_dst.accessor(), env_dst.qualid,
+	  env_src.accessor(), env_src.qualid));
+      env_src.println(String.format(
+	  "memcpy(%s%s, %s%s, strlen(%s%s)+1);",
+	  env_dst.accessor(), env_dst.qualid,
+	  env_src.accessor(), env_src.qualid,
+	  env_src.accessor(), env_src.qualid));
+    } else {
+      env_src.println(env_dst.accessor() + env_dst.qualid + " = " +
+		      env_src.accessor() + env_src.qualid + ";");
+    }
+  }
+
+  public void UserType.C_emitCopy(C_env env_src, C_env env_dst) {
+    lookupType(getName()).getType().C_emitCopy(env_src, env_dst);
+  }
+
+  public void StructType.C_emitCopy(C_env env_src, C_env env_dst) {
+    for (int i = 0 ; i < getNumField() ; i++) {
+      getField(i).C_emitCopy(env_src, env_dst);
+    }
+  }
+
+  public void ArrayType.C_emitCopy(C_env env_src, C_env env_dst) {
+    C_emitCopyDecodeLimit(env_src, env_dst);
+    C_emitCopyArrayAllocate(env_src, env_dst);
+    env_src.println("{");
+    env_src.indent();
+    C_emitLoopVariables(env_src);
+    for (int i = 0 ; i < getNumExp() ; i++) {
+      String iterator = "i_" + env_src.depth + "_" + i;
+      env_src.println("for (" + iterator + " = 0" +
+		  " ; " +
+		  iterator + " < " + getExp(i).C_getLimit(env_src, i) +
+		  " ; " +
+		  iterator + "++) {");
+      env_src.indent();
+    }
+    C_emitCalcIndex(env_src);
+    getType().C_emitCopy(C_Nest(env_src), C_Nest(env_dst));
+    for (int i = getNumExp() - 1 ; i >= 0 ; i--) {
+      env_src.unindent();
+      env_src.println("}");
+    }
+    env_src.unindent();
+    env_src.println("}");
+  }
+
+  public void Field.C_emitCopy(C_env env_src, C_env env_dst) {
+    String fnam = env_src.memberAccessor() + getName();
+    getType().C_emitCopy(env_src.nestStruct(fnam), env_dst.nestStruct(fnam));
+  }
+
+  public void Exp.C_emitCopyDecodeLimit(C_env env_src, C_env env_dst, int i) {
+    // Ordinary array has no length-member.
+  }
+
+  public void VariableSize.C_emitCopyDecodeLimit(C_env env_src, C_env env_dst, int i) {
+    String src = env_src.qualid + env_src.memberAccessor() + "n_" + i;
+    String dst = env_dst.qualid + env_dst.memberAccessor() + "n_" + i;
+    env_src.println(dst + " = " + src + ";");
+  }
+
+  public void ArrayType.C_emitCopyDecodeLimit(C_env env_src, C_env env_dst) {
+    for (int i = 0 ; i < getNumExp() ; i++) {
+      getExp(i).C_emitCopyDecodeLimit(env_src, env_dst, i);
+    }
+  }
+
+  public void ArrayType.C_emitCopyArrayAllocate(C_env env_src, C_env env_dst) {
+  }
+
+  public void VariableArrayType.C_emitCopyArrayAllocate(C_env env_src,
+							C_env env_dst)
+  {
+    env_src.print(env_dst.qualid + env_dst.memberAccessor() +
+	      "a = labcomm_memory_alloc(mem, 1, sizeof(" +
+		  env_src.qualid + env_src.memberAccessor() + "a[0])");
+    for (int i = 0 ; i < getNumExp() ; i++) {
+      env_src.print(" * " + getExp(i).C_getLimit(env_src, i));
+    }
+    env_dst.println(");");
+  }
+
+  // Code for deallocation of dynamically allocated data in a copy.
+
+  private void SampleDecl.C_emitCopyDeallocationFunctionParam(C_env env,
+							      String par)
+  {
+    env.println("void labcomm_copy_free_" + env.prefix + getName() + "(");
+    env.indent();
+    env.println("struct labcomm_memory *mem,");
+    env.println(env.prefix + getName() + " *" + par);
+    env.unindent();
+    env.print(")");
+  }
+
+  public void Decl.C_emitCopyDeallocationDeclaration(C_env env) {
+  }
+
+  public void SampleDecl.C_emitCopyDeallocationDeclaration(C_env env) {
+    C_emitCopyDeallocationFunctionParam(env, "c");
+    env.println(";");
+  }
+
+  public void Decl.C_emitCopyDeallocation(C_env env) {
+    throw new Error(this.getClass().getName() +
+		    ".C_emitCopy(C_env env)" +
+		    " not declared");
+  }
+
+  public void TypeDecl.C_emitCopyDeallocation(C_env env) {
+  }
+
+  public void SampleDecl.C_emitCopyDeallocation(C_env env) {
+    String par = "par";
+    env = env.nestStruct(par).setPointer();
+
+    C_emitCopyDeallocationFunctionParam(env, par);
+    env.println("");
+    env.println("{");
+    env.indent();
+    getType().C_emitCopyDeallocation(env);
+    env.unindent();
+    env.println("}");
+  }
+
+  public void Type.C_emitCopyDeallocation(C_env env) {
+    throw new Error(this.getClass().getName() +
+  		    ".C_emitCopyDeallocation(C_env env)" +
+  		    " not declared");
+  }
+
+  public void VoidType.C_emitCopyDeallocation(C_env env) {
+  }
+
+  public void PrimType.C_emitCopyDeallocation(C_env env) {
+    if (C_isDynamic()) {
+      env.println("labcomm_memory_free(mem, 1, " +
+                  env.accessor() + env.qualid + ");");
+    }
+  }
+
+  public void UserType.C_emitCopyDeallocation(C_env env) {
+    if (C_isDynamic()) {
+      lookupType(getName()).getType().C_emitCopyDeallocation(env);
+    }
+  }
+
+  public void StructType.C_emitCopyDeallocation(C_env env) {
+    if (C_isDynamic()) {
+      for (int i = 0 ; i < getNumField() ; i++) {
+  	getField(i).C_emitCopyDeallocation(env);
+      }
+    }
+  }
+
+  public void ArrayType.C_emitCopyDeallocation(C_env env) {
+    if (getType().C_isDynamic()) {
+      env.println("{");
+      env.indent();
+      C_emitLoopVariables(env);
+      for (int i = 0 ; i < getNumExp() ; i++) {
+  	String iterator = "i_" + env.depth + "_" + i;
+  	env.println("for (" + iterator + " = 0" +
+  		    " ; " +
+  		    iterator + " < " + getExp(i).C_getLimit(env, i) +
+  		    " ; " +
+  		    iterator + "++) {");
+  	env.indent();
+      }
+      C_emitCalcIndex(env);
+      getType().C_emitCopyDeallocation(C_Nest(env));
+      for (int i = 0 ; i < getNumExp() ; i++) {
+  	env.unindent();
+  	env.println("}");
+      }
+      env.unindent();
+      env.println("}");
+    }
+  }
+
+  public void VariableArrayType.C_emitCopyDeallocation(C_env env) {
+    super.C_emitCopyDeallocation(env);
+    env.println("labcomm_memory_free(mem, 1, " +
+                env.qualid + env.memberAccessor() + "a);");
+  }
+
+  public void Field.C_emitCopyDeallocation(C_env env) {
+    getType().C_emitCopyDeallocation(env.nestStruct(env.memberAccessor()
+						    + getName()));
+  }
+}
+
 aspect C_DecoderIoctl {
 
   public void Decl.C_emitDecoderIoctl(C_env env) {
diff --git a/examples/Makefile b/examples/Makefile
index cdbef3d2ac044cc003c28a599cd3e1df93fe318a..072b2d80a1c7367490cc3c37daaf42ab0d492861 100644
--- a/examples/Makefile
+++ b/examples/Makefile
@@ -1,4 +1,5 @@
 .PHONY: all
+
 all:
 	echo To be done...
 	$(MAKE) -C twoway all
diff --git a/examples/simple/compile.sh b/examples/simple/compile.sh
index 50538af7800a79754f32d0a7baf16b11393b9801..d77358eeb180fb6b58c394260029ff97e4e9584d 100644
--- a/examples/simple/compile.sh
+++ b/examples/simple/compile.sh
@@ -5,10 +5,12 @@ java -jar ../../compiler/labComm.jar --java=gen --c=gen/simple.c --h=gen/simple.
 
 javac -cp ../../lib/java:. gen/*.java Encoder.java Decoder.java
 
-gcc -Wall -Werror -I. -I../../lib/c -L../../lib/c \
+gcc -Wall -Werror -Wno-unused-function \
+    -I. -I../../lib/c -L../../lib/c \
     -o example_encoder example_encoder.c gen/simple.c \
     -llabcomm -Tlabcomm.linkscript
-gcc -Wall -Werror -I . -I ../../lib/c -L../../lib/c \
+gcc -Wall -Werror -Wno-unused-function \
+    -I . -I ../../lib/c -L../../lib/c \
     -o example_decoder example_decoder.c gen/simple.c \
     -llabcomm -Tlabcomm.linkscript
 
diff --git a/examples/twoway/Makefile b/examples/twoway/Makefile
index b14550b48aff392429a8aaec85f2fb00e8077d12..60b5708efd2d48df21b41e87b19e9d2eb1534161 100644
--- a/examples/twoway/Makefile
+++ b/examples/twoway/Makefile
@@ -2,7 +2,7 @@ TARGETS=client server
 LABCOMM_JAR=../../compiler/labComm.jar
 LABCOMM=java -jar $(LABCOMM_JAR) 
 
-CFLAGS=-O3 -g -Wall -Werror -I../../lib/c -I.
+CFLAGS=-O3 -g -Wall -Werror -I../../lib/c -I. -Wno-unused-function
 
 all: $(TARGETS:%=gen/%)
 
diff --git a/lib/c/Makefile b/lib/c/Makefile
index 46c7ad5cc59f109f45481ebf534f4f9f062cb2c7..8edd0f6a977b6ecc91507ed8c9a844c8dc9c7f04 100644
--- a/lib/c/Makefile
+++ b/lib/c/Makefile
@@ -18,6 +18,13 @@ else ifeq ($(UNAME_S),Darwin)
   LDFLAGS=-L.
   LDLIBS=-llabcomm
   MAKESHARED=clang -o $1 -shared -Wl,-install_name,$2 $3 -lc
+else ifneq ($(findstring CYGWIN,$(UNAME_S)),)
+  CFLAGS=-std=c99 -g -Wall -Werror -O3  -I. -Itest
+  CC=$(CROSS_COMPILE)gcc
+  LD=$(CROSS_COMPILE)ld
+  LDFLAGS=-L.
+  LDLIBS=-llabcomm -lrt
+  ALL_DEPS:=$(filter-out %.so.1, $(ALL_DEPS)) # No -fPIC supported in windows?
 else
   $(error Unknown system $(UNAME_S))
 endif
@@ -49,6 +56,7 @@ TESTS=test_labcomm_basic_type_encoding test_labcomm_generated_encoding \
       test_signature_numbers \
       test_labcomm \
       test_labcomm_pthread_scheduler \
+      test_labcomm_copy
 #
 #FIXME: test_labcomm test_labcomm_errors
 TEST_DIR=test
@@ -133,6 +141,7 @@ clean:
 	$(RM) test/testdata/gen/*.[cho]
 	$(RM) test/gen/*.[cho]
 	$(RM) $(TEST_DIR)/test_labcomm
+	$(RM) $(TEST_DIR)/test_labcomm_copy
 
 distclean: clean
 	$(RM) liblabcomm.so.1
@@ -150,6 +159,7 @@ $(TEST_DIR)/test_signature_numbers.c: $(TEST_DIR)/gen/another_encoding.h
 $(TEST_DIR)/test_signature_numbers.c: $(TEST_DIR)/gen/generated_encoding.h
 $(TEST_DIR)/test_signature_numbers: $(TEST_DIR)/gen/another_encoding.o
 $(TEST_DIR)/test_signature_numbers: $(TEST_DIR)/gen/generated_encoding.o
+$(TEST_DIR)/test_labcomm_copy:  $(TEST_DIR)/gen/generated_encoding.o $(TEST_DIR)/gen/test_sample.o $(TEST_DIR)/gen/more_types.o
 labcomm_fd_reader.o: labcomm_private.h
 labcomm_fd_writer.o: labcomm_private.h
 labcomm_dynamic_buffer_writer.o: labcomm_private.h
diff --git a/lib/c/test/more_types.lc b/lib/c/test/more_types.lc
new file mode 100644
index 0000000000000000000000000000000000000000..91fb9358134fccf3149507e96d27680465c50411
--- /dev/null
+++ b/lib/c/test/more_types.lc
@@ -0,0 +1,7 @@
+sample string S;
+sample int A[8];
+sample struct {
+  string s1;
+  string s2;
+} NS;
+sample string AS[_];
diff --git a/lib/c/test/test_labcomm_copy.c b/lib/c/test/test_labcomm_copy.c
new file mode 100644
index 0000000000000000000000000000000000000000..b7b5e0829b01a6ad98306fbf56263bbdca61d6e5
--- /dev/null
+++ b/lib/c/test/test_labcomm_copy.c
@@ -0,0 +1,242 @@
+#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 "labcomm.h"
+#include "labcomm_private.h"
+#include "labcomm_default_error_handler.h"
+#include "labcomm_default_memory.h"
+#include "labcomm_default_scheduler.h"
+#include "labcomm_fd_writer.h"
+#include "labcomm_fd_reader.h"
+#include "test/gen/generated_encoding.h"
+#include "test/gen/test_sample.h"
+#include "test/gen/more_types.h"
+
+#define DATA_FILE "copy_test.dat"
+
+static void handle_s1(generated_encoding_S1 *v, void *context)
+{
+  labcomm_copy_generated_encoding_S1(labcomm_default_memory, context, v);
+}
+
+static void handle_b(generated_encoding_B *v, void *context)
+{
+  labcomm_copy_generated_encoding_B(labcomm_default_memory, context, v);
+}
+
+static void handle_i(generated_encoding_I *v, void *context)
+{
+  labcomm_copy_generated_encoding_I(labcomm_default_memory, context, v);
+}
+
+static void handle_p(generated_encoding_P *v, void *context)
+{
+  labcomm_copy_generated_encoding_P(labcomm_default_memory, context, v);
+}
+
+static void handle_test_var(test_sample_test_var *v, void *context)
+{
+  labcomm_copy_test_sample_test_var(labcomm_default_memory, context, v);
+}
+
+static void handle_a(more_types_A *v, void *context)
+{
+  labcomm_copy_more_types_A(labcomm_default_memory, context, v);
+}
+
+static void handle_s(more_types_S *v, void *context)
+{
+  labcomm_copy_more_types_S(labcomm_default_memory, context, v);
+}
+
+static void handle_ns(more_types_NS *v, void *context)
+{
+  labcomm_copy_more_types_NS(labcomm_default_memory, context, v);
+}
+
+static void handle_as(more_types_AS *v, void *context)
+{
+  labcomm_copy_more_types_AS(labcomm_default_memory, context, v);
+}
+
+int main(int argc, char **argv)
+{
+  struct labcomm_encoder *encoder;
+  struct labcomm_decoder *decoder;
+  int fd;
+  generated_encoding_S1 s1;
+  generated_encoding_S1 cache_s1;
+  generated_encoding_B b;
+  generated_encoding_B cache_b;
+  generated_encoding_I I;
+  generated_encoding_I cache_I;
+  generated_encoding_P p;
+  generated_encoding_P cache_p;
+  test_sample_test_var test_var;
+  test_sample_test_var cache_test_var;
+  more_types_A a;
+  more_types_A cache_a;
+  more_types_S s;
+  more_types_S cache_s = NULL;
+  more_types_NS ns;
+  more_types_NS cache_ns;
+  more_types_AS as;
+  more_types_AS cache_as;
+
+  fd = open(DATA_FILE, O_RDWR | O_CREAT | O_TRUNC, 0644);
+  if (fd == -1)
+    err(1, "open()");
+  encoder =
+    labcomm_encoder_new(labcomm_fd_writer_new(labcomm_default_memory, fd, 0),
+			labcomm_default_error_handler,
+			labcomm_default_memory,
+			labcomm_default_scheduler);
+
+  labcomm_encoder_register_generated_encoding_S1(encoder);
+  s1.i = 1;
+  labcomm_encode_generated_encoding_S1(encoder, &s1);
+
+  labcomm_encoder_register_generated_encoding_B(encoder);
+  b = 2;
+  labcomm_encode_generated_encoding_B(encoder, &b);
+
+  labcomm_encoder_register_generated_encoding_I(encoder);
+  I.n_0 = 3;
+  I.a = calloc(I.n_0, sizeof(I.a[0]));
+  I.a[0] = 4;
+  I.a[1] = 5;
+  I.a[2] = 6;
+  labcomm_encode_generated_encoding_I(encoder, &I);
+
+  labcomm_encoder_register_generated_encoding_P(encoder);
+  p.n_0 = 7;
+  p.a = calloc(p.n_0, sizeof(p.a[0]));
+  for (int i = 0; i < p.n_0; i++)
+    p.a[i].i = 8 + i;
+  labcomm_encode_generated_encoding_P(encoder, &p);
+
+  labcomm_encoder_register_test_sample_test_var(encoder);
+  test_var.n_0 = 2;
+  test_var.n_1 = 7;
+  test_var.a = calloc(test_var.n_0 * test_var.n_1, sizeof(*test_var.a));
+  for (int i = 0; i < test_var.n_0; i++)
+    for (int j = 0; j < test_var.n_1; j++)
+      test_var.a[i] = 10 * i + j;
+  labcomm_encode_test_sample_test_var(encoder, &test_var);
+
+  labcomm_encoder_register_more_types_A(encoder);
+  for (int i = 0; i < sizeof(a.a) / sizeof(a.a[0]); i++)
+    a.a[i] = i;
+  labcomm_encode_more_types_A(encoder, &a);
+
+  labcomm_encoder_register_more_types_S(encoder);
+  s = "this is a string";
+  labcomm_encode_more_types_S(encoder, &s);
+
+  labcomm_encoder_register_more_types_NS(encoder);
+  ns.s1 = "this is a string";
+  ns.s2 = "this is a another string";
+  labcomm_encode_more_types_NS(encoder, &ns);
+
+  labcomm_encoder_register_more_types_AS(encoder);
+  as.n_0 = 3;
+  as.a = calloc(as.n_0, sizeof(as.a[0]));
+  as.a[0] = "string 0";
+  as.a[1] = "string 1";
+  as.a[2] = "string 2";
+  labcomm_encode_more_types_AS(encoder, &as);
+
+  labcomm_encoder_free(encoder);
+  encoder = NULL;
+  lseek(fd, 0, SEEK_SET);
+  decoder =
+    labcomm_decoder_new(labcomm_fd_reader_new(labcomm_default_memory, fd, 0),
+			labcomm_default_error_handler,
+			labcomm_default_memory,
+			labcomm_default_scheduler);
+
+  labcomm_decoder_register_generated_encoding_S1(decoder, handle_s1, &cache_s1);
+  labcomm_decoder_register_generated_encoding_B(decoder, handle_b, &cache_b);
+  labcomm_decoder_register_generated_encoding_I(decoder, handle_i, &cache_I);
+  labcomm_decoder_register_generated_encoding_P(decoder, handle_p, &cache_p);
+  labcomm_decoder_register_test_sample_test_var(decoder, handle_test_var,
+						&cache_test_var);
+  labcomm_decoder_register_more_types_A(decoder, handle_a, &cache_a);
+  labcomm_decoder_register_more_types_S(decoder, handle_s, &cache_s);
+  labcomm_decoder_register_more_types_NS(decoder, handle_ns, &cache_ns);
+  labcomm_decoder_register_more_types_AS(decoder, handle_as, &cache_as);
+
+  while (labcomm_decoder_decode_one(decoder) > 0) ;
+
+  assert(cache_s1.i == s1.i);
+  puts("S1 copied ok");
+
+  assert(cache_b == b);
+  puts("B copied ok");
+
+  assert(cache_I.n_0 == I.n_0);
+  assert(cache_I.a[0] == I.a[0]);
+  assert(cache_I.a[1] == I.a[1]);
+  assert(cache_I.a[2] == I.a[2]);
+  free(I.a);
+  puts("I copied ok");
+
+  assert(cache_p.n_0 == p.n_0);
+  for (int i = 0; i < p.n_0; i++)
+    assert(cache_p.a[i].i == p.a[i].i);
+  free(p.a);
+  puts("P copied ok");
+
+  assert(cache_test_var.n_0 == test_var.n_0);
+  assert(cache_test_var.n_1 == test_var.n_1);
+  for (int i = 0; i < test_var.n_0; i++)
+    for (int j = 0; j < test_var.n_1; j++)
+      assert(cache_test_var.a[p.n_0 * i + j] == test_var.a[p.n_0 * i + j]);
+  free(test_var.a);
+  puts("test_var copied ok");
+
+  for (int i = 0; i < sizeof(a.a) / sizeof(a.a[0]); i++)
+    assert(cache_a.a[i] == a.a[i]);
+  puts("A copied ok");
+
+  assert(!strcmp(cache_s, s));
+  puts("S copied ok");
+
+  assert(!strcmp(cache_ns.s1, ns.s1));
+  assert(!strcmp(cache_ns.s2, ns.s2));
+  puts("NS copied ok");
+
+  for (int i = 0; i < as.n_0; i++)
+    assert(!strcmp(cache_as.a[i], as.a[i]));
+  free(as.a);
+  puts("AS copied ok");
+
+  labcomm_decoder_free(decoder);
+  close(fd);
+  unlink(DATA_FILE);
+
+  labcomm_copy_free_generated_encoding_S1(labcomm_default_memory, &cache_s1);
+  puts("S1 deallocated ok");
+  labcomm_copy_free_generated_encoding_B(labcomm_default_memory, &cache_b);
+  puts("B deallocated ok");
+  labcomm_copy_free_generated_encoding_I(labcomm_default_memory, &cache_I);
+  puts("I deallocated ok");
+  labcomm_copy_free_generated_encoding_P(labcomm_default_memory, &cache_p);
+  puts("P deallocated ok");
+  labcomm_copy_free_test_sample_test_var(labcomm_default_memory, &cache_test_var);
+  puts("test_var deallocated ok");
+  labcomm_copy_free_more_types_A(labcomm_default_memory, &cache_a);
+  puts("A deallocated ok");
+  labcomm_copy_free_more_types_S(labcomm_default_memory, &cache_s);
+  puts("S deallocated ok");
+  labcomm_copy_free_more_types_NS(labcomm_default_memory, &cache_ns);
+  puts("NS deallocated ok");
+  labcomm_copy_free_more_types_AS(labcomm_default_memory, &cache_as);
+  puts("AS deallocated ok");
+}
diff --git a/test/Makefile b/test/Makefile
index 7401102eba4792c16788f41379678faca4fae516..ddf69b93d74c8c7c5267b7dc2051b9bd266ecbc3 100644
--- a/test/Makefile
+++ b/test/Makefile
@@ -2,7 +2,7 @@ TESTS=basic simple nested
 LABCOMM_JAR=../compiler/labComm.jar
 LABCOMM=java -jar $(LABCOMM_JAR) 
 
-CFLAGS=-O3 -g -Wall -Werror
+CFLAGS=-O3 -g -Wall -Werror -Wno-unused-function
 
 all: