diff --git a/examples/user_types/Encoder.java b/examples/user_types/ExampleEncoder.java
similarity index 75%
rename from examples/user_types/Encoder.java
rename to examples/user_types/ExampleEncoder.java
index cfce51368416313f9f30e92febbd81e60e7540b7..d3cca03d0d8b1ec2f99fcff37672d1c3f9d50911 100644
--- a/examples/user_types/Encoder.java
+++ b/examples/user_types/ExampleEncoder.java
@@ -2,34 +2,35 @@ import java.io.File;
 import java.io.FileOutputStream;
 import java.io.OutputStream;
 
+import se.lth.control.labcomm.Encoder;
 import se.lth.control.labcomm.EncoderChannel;
 
 /**
  * Simple encoder
  */
-public class Encoder
+public class ExampleEncoder
 {
 
   EncoderChannel encoder;
 
-  public Encoder(OutputStream out)
+  public ExampleEncoder(OutputStream out)
     throws Exception
   {
     encoder = new EncoderChannel(out);
     twoLines.register(encoder);
     theint.register(encoder);
-    //LabCommEncoder.MetaDataTransaction t = encoder.beginMetaData(twoLines.class);
-    ////LabCommEncoder.MetaDataTransaction t = encoder.beginMetaData();
-    //Comment.register(t, false);
-    //Comment c = new Comment();
+    Encoder.PragmaPacketBuilder t = encoder.newPragma("se.lth.cs.sven.pragma");
+    Comment.register(t);
+    Comment c = new Comment();
     //c.id = encoder.getTypeId(twoLines.class);
-    //c.comment = "Test comment";
-    //Comment.encode(t,c);
-    //t.commit();
-    //t = encoder.beginMetaData(null);
-    //afoo.register(t, false);
-    //afoo.encode(t, new foo());
-    //t.commit();
+    c.id = 42;
+    c.comment = "Test comment";
+    Comment.encode(t,c);
+    t.send();
+    t = encoder.newPragma(null);
+    afoo.register(t);
+    afoo.encode(t, new foo());
+    t.send();
   }
 
   public void doEncode() throws java.io.IOException {
@@ -94,7 +95,7 @@ public class Encoder
 
   public static void main(String[] arg) throws Exception {
     FileOutputStream fos = new FileOutputStream(arg[0]);
-    Encoder example = new Encoder(fos);
+    ExampleEncoder example = new ExampleEncoder(fos);
     example.doEncode();
     fos.close();
   }
diff --git a/examples/user_types/Makefile b/examples/user_types/Makefile
index 4953342d569b1ede7ebf4fcfa0b86137b9e6f86b..628829274e41460f8bc13f4258a5dc4b48b9be92 100644
--- a/examples/user_types/Makefile
+++ b/examples/user_types/Makefile
@@ -2,7 +2,7 @@ LCDIR=../..
 LCCJAR=${LCDIR}/compiler/labcomm_compiler.jar  # the LabComm compiler
 LCLJAR=${LCDIR}/lib/java/labcomm.jar  # the LabComm library
 
-EXECUTABLES=example_encoder example_decoder Encoder.class Decoder.class Encoder.exe Decoder.exe
+EXECUTABLES=example_encoder example_decoder ExampleEncoder.class Decoder.class Encoder.exe Decoder.exe
 include ${LCDIR}/lib/c/os_compat.mk
 
 GENDIR=gen
@@ -44,7 +44,7 @@ build :
 	mkdir -p ${GENDIR}
 	java -jar ${LCDIR}/compiler/labcomm_compiler.jar --java=${GENDIR} --c=${GENDIR}/test.c --h=${GENDIR}/test.h  --python=${GENDIR}/test.py --cs=${GENDIR}/test.cs test.lc 
 
-	javac -cp ${LCDIR}/lib/java/labcomm.jar:. ${GENDIR}/*.java Encoder.java Decoder.java
+	javac -cp ${LCDIR}/lib/java/labcomm.jar:. ${GENDIR}/*.java ExampleEncoder.java Decoder.java
 
 	${CC} ${CFLAGS} ${LDFLAGS} -Wall -Werror -Wno-unused-function \
 	    -I. -I${LCDIR}/lib/c -L${LCDIR}/lib/c \
@@ -65,7 +65,7 @@ run:
 	@echo "********************************************"
 	@echo
 
-	@java -cp .:${LCDIR}/lib/java/labcomm.jar:${GENDIR} Encoder encoded_data_j
+	@java -cp .:${LCDIR}/lib/java/labcomm.jar:${GENDIR} ExampleEncoder encoded_data_j
 
 	@echo "************ running Java  decoder: *****************"
 	@java -cp .:${LCDIR}/lib/java/labcomm.jar:${GENDIR} Decoder encoded_data_j
@@ -108,7 +108,7 @@ runwcs: Encoder.exe Decoder.exe
 	@echo "********************************************"
 	@echo
 
-	@java -cp .:${LCDIR}/lib/java/labcomm.jar:${GENDIR} Encoder encoded_data_j
+	@java -cp .:${LCDIR}/lib/java/labcomm.jar:${GENDIR} ExampleEncoder encoded_data_j
 
 	@echo "************ running Java  decoder: *****************"
 	@java -cp .:${LCDIR}/lib/java/labcomm.jar:${GENDIR} Decoder encoded_data_j
diff --git a/lib/java/se/lth/control/labcomm/DecoderChannel.java b/lib/java/se/lth/control/labcomm/DecoderChannel.java
index 2397a1609d98326b733cd07fa3f4389f889011f1..b4b561e742f072f2920e31265cd1cd7e8366aa48 100644
--- a/lib/java/se/lth/control/labcomm/DecoderChannel.java
+++ b/lib/java/se/lth/control/labcomm/DecoderChannel.java
@@ -37,7 +37,7 @@ public class DecoderChannel implements Decoder {
        //     decodeByte();		  
        //   }
     String type = decodeString();
-    int plen = len - (type.length()+1); // XXX HERE BE DRAGONS: +1?
+    int plen = len - Encoder.Util.sizeof_string(type); 
     System.out.println("[ begin pragma ("+type+") ]");
     //System.out.println("metadata : "+len + " bytes, ref: " + Integer.toHexString(typeRefId)+".");
     byte buf[] = new byte[plen];
diff --git a/lib/java/se/lth/control/labcomm/Encoder.java b/lib/java/se/lth/control/labcomm/Encoder.java
index d6ef3e5ff2a08502dcde3c548a36e58aa9a5faf5..b646b6b088159e9f4fdc20ea0e00cc91dc1c3f63 100644
--- a/lib/java/se/lth/control/labcomm/Encoder.java
+++ b/lib/java/se/lth/control/labcomm/Encoder.java
@@ -1,10 +1,15 @@
 package se.lth.control.labcomm;
 
 import java.io.IOException;
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
 
 public interface Encoder {
 
   public void register(SampleDispatcher dispatcher) throws IOException;
+  //HERE BE DRAGONS: for internal use, but needs to be public
+  //in Java interfaces...
+  public void begin(int tag) throws IOException;
   public void begin(Class<? extends Sample> c) throws IOException;
   public void end(Class<? extends Sample> c) throws IOException;
   public void encodeBoolean(boolean value) throws IOException;
@@ -17,4 +22,93 @@ public interface Encoder {
   public void encodeString(String value) throws IOException;
   public void encodePacked32(long value) throws IOException;
 
+  public PragmaPacketBuilder newPragma(String type) throws IOException;
+
+  static class Util {
+  /* Aux method to get encoded size of packed32 variable */
+  //static int sizeofPacked32(int... vars)
+    static int sizeof_packed32(int data){
+      int result = 0;
+    //for(int data : vars) {
+        //XXX fixme... define number range for packed32
+        if(data < 0) throw new Error("TODO: emulate unsigned int...");
+        int i;
+  
+        for (i = 0 ; i == 0 || data != 0 ; i++, data = (data >> 7)) {
+          result++;
+        }
+   // }
+      return result;
+  
+    }
+    static int sizeof_string(String s){
+      int len = s.length();
+      return len+sizeof_packed32(len);
+    }
+  }
+
+  public static class PragmaPacketBuilder implements Encoder {
+    private final ByteArrayOutputStream bytes ;
+    private final DataOutputStream data ;
+    private final Encoder encoder, tempEncoder ;
+    private final EncoderRegistry reg;
+    private final String type;
+    private boolean sent = false;
+    //private final int typeRef;
+    //private Class<? extends LabCommSample> typeRef;
+
+    PragmaPacketBuilder(Encoder e, EncoderRegistry reg, String type) throws IOException {
+      bytes = new ByteArrayOutputStream();
+      data  = new DataOutputStream(bytes);
+      encoder = e;
+      this.reg = reg;
+      this.type = (type==null)?"undefined":type;
+      System.out.println("PragmaPacketBuilder: "+this.type);
+      tempEncoder = new EncoderChannel(data,e,false);
+    } 
+
+    public void send() throws IOException {
+      if(sent) throw new IOException("Already sent.");
+      tempEncoder.end(null); 
+      data.close();
+      byte[] b = bytes.toByteArray();
+      //System.out.println("LabCommEncoder.MetaDataTransaction committing "+b.length+" bytes");
+      //encoder.encodePacked32(Constant.PRAGMA);
+      //encoder.encodePacked32(b.length);
+      encoder.begin(Constant.PRAGMA);
+      encoder.encodeString(this.type);
+     
+      for (int i = 0 ; i < b.length ; i++) {
+        encoder.encodeByte(b[i]);
+      }
+      encoder.end(null); 
+    } 
+    // forward everything to tempEncoder
+    public void register(SampleDispatcher dispatcher) throws IOException {tempEncoder.register(dispatcher);}
+
+    //XXX hack for registration
+    public void begin(Class<? extends Sample> c) throws IOException{
+      System.err.println("begin...");
+      try {
+        tempEncoder.begin(c);
+      } catch (IOException e) {
+        System.err.println("trying lookup in enclosing encoder...");
+        tempEncoder.encodePacked32(reg.getTag(c));
+      }
+    }
+    public void begin(int c) throws IOException{
+        tempEncoder.begin(c);
+    }	
+    public void end(Class<? extends Sample> c) throws IOException{tempEncoder.end(c);}
+    public void encodeBoolean(boolean value) throws IOException{tempEncoder.encodeBoolean(value);}
+    public void encodeByte(byte value) throws IOException{tempEncoder.encodeByte(value);}
+    public void encodeShort(short value) throws IOException{tempEncoder.encodeShort(value);}
+    public void encodeInt(int value) throws IOException{tempEncoder.encodeInt(value);}
+    public void encodeLong(long value) throws IOException{tempEncoder.encodeLong(value);}
+    public void encodeFloat(float value) throws IOException{tempEncoder.encodeFloat(value);}
+    public void encodeDouble(double value) throws IOException{tempEncoder.encodeDouble(value);}
+    public void encodeString(String value) throws IOException{tempEncoder.encodeString(value);}
+    public void encodePacked32(long value) throws IOException{tempEncoder.encodePacked32(value);}
+  public PragmaPacketBuilder newPragma(String type) throws IOException {throw new IOException("PragmaPacketBuilders do not nest");}
+  } 
 }
diff --git a/lib/java/se/lth/control/labcomm/EncoderChannel.java b/lib/java/se/lth/control/labcomm/EncoderChannel.java
index 08ef0fc415a064e63b4158e4d52bc82f0e8d86e2..962a04f5f23cac83bf4a9e5fc7af0ccd9a38c376 100644
--- a/lib/java/se/lth/control/labcomm/EncoderChannel.java
+++ b/lib/java/se/lth/control/labcomm/EncoderChannel.java
@@ -14,20 +14,44 @@ public class EncoderChannel implements Encoder {
   private int current_tag; 
 
   public EncoderChannel(Writer writer) throws IOException {
-    this.writer = writer;
-    bytes = new ByteArrayOutputStream();
-    data = new DataOutputStream(bytes);
-    registry = new EncoderRegistry();
+    this(writer, true);
+  } 
 
-    begin(Constant.VERSION);
-    encodeString(Constant.CURRENT_VERSION);
-    end(null);
+  public EncoderChannel(OutputStream writer) throws IOException {
+    this(writer, true);
   }
 
-  public EncoderChannel(OutputStream writer) throws IOException {
-    this(new WriterWrapper(writer));
+  EncoderChannel(Writer writer, boolean emitVersion) throws IOException {
+    this(writer, new EncoderRegistry(), emitVersion);
+  } 
+
+  private EncoderChannel(Writer writer,
+                         EncoderRegistry registry,
+			 boolean emitVersion) throws IOException {
+    this.writer = writer;
+    this.bytes = new ByteArrayOutputStream();
+    this.data = new DataOutputStream(bytes);
+    this.registry = registry;
+
+    if(emitVersion) {
+      begin(Constant.VERSION);
+      encodeString(Constant.CURRENT_VERSION);
+      end(null);
+    }
   }
 
+  EncoderChannel(OutputStream writer, boolean emitVersion) throws IOException {
+    this(new WriterWrapper(writer), emitVersion);
+  }
+
+  /* for sharing registry with PragmaPacketBuilder */
+  EncoderChannel(OutputStream writer, 
+                        Encoder e,
+			boolean emitVersion) throws IOException {
+    this(new WriterWrapper(writer), (e instanceof EncoderChannel) ? ((EncoderChannel)e).registry : new EncoderRegistry(), emitVersion);
+  } 
+
+
   public void register(SampleDispatcher dispatcher) throws IOException {
     int index = registry.add(dispatcher);
     begin(Constant.SAMPLE_DEF);
@@ -41,7 +65,7 @@ public class EncoderChannel implements Encoder {
     end(null);
   }
 
-  private void begin(int tag) {
+  public void begin(int tag) {
     current_tag = tag;
     bytes.reset();
   }
@@ -131,5 +155,9 @@ public class EncoderChannel implements Encoder {
       encodeByte((byte)(tmp[i] | (i!=0?0x80:0x00)));
     }
   }
+
+  public PragmaPacketBuilder newPragma(String type)  throws IOException{
+    return new PragmaPacketBuilder(this, registry, type);
+  }
 }