diff --git a/.bzrignore b/.bzrignore
new file mode 100644
index 0000000000000000000000000000000000000000..9aefbbac4a1b145311f9bd884612d08335e98465
--- /dev/null
+++ b/.bzrignore
@@ -0,0 +1,19 @@
+AST
+AST/*
+LabComm.class
+labComm.jar
+lib/java/se/lth/control/labcomm/LabComm.class
+lib/java/se/lth/control/labcomm/LabCommDecoderChannel.class
+lib/java/se/lth/control/labcomm/LabCommDecoder.class
+lib/java/se/lth/control/labcomm/LabCommDecoderRegistry.class
+lib/java/se/lth/control/labcomm/LabCommDecoderRegistry$Entry.class
+lib/java/se/lth/control/labcomm/LabCommDispatcher.class
+lib/java/se/lth/control/labcomm/LabCommEncoderChannel.class
+lib/java/se/lth/control/labcomm/LabCommEncoder.class
+lib/java/se/lth/control/labcomm/LabCommEncoderRegistry.class
+lib/java/se/lth/control/labcomm/LabCommEncoderRegistry$Entry.class
+lib/java/se/lth/control/labcomm/LabCommHandler.class
+lib/java/se/lth/control/labcomm/LabCommReader.class
+lib/java/se/lth/control/labcomm/LabCommSample.class
+lib/java/se/lth/control/labcomm/LabCommType.class
+lib/java/se/lth/control/labcomm/LabCommWriter.class
diff --git a/lib/c/labcomm.c b/lib/c/labcomm.c
new file mode 100644
index 0000000000000000000000000000000000000000..ee93aec315e0dfc0f097e07119abfa5a11edd651
--- /dev/null
+++ b/lib/c/labcomm.c
@@ -0,0 +1,437 @@
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+#ifndef __VXWORKS__
+#include <strings.h>
+#endif
+#include <stdlib.h>
+#ifdef __VXWORKS__
+#if (CPU == PPC603)
+#undef _LITTLE_ENDIAN
+#endif
+#if (CPU == PENTIUM4)
+#undef _BIG_ENDIAN
+#endif
+#endif
+#include "labcomm.h"
+#include "labcomm_private.h"
+
+typedef struct labcomm_sample_entry {
+  struct labcomm_sample_entry *next;
+  int index;
+  labcomm_signature_t *signature;
+  labcomm_decoder_typecast_t decoder;
+  labcomm_handler_typecast_t handler;
+  labcomm_encode_typecast_t encode;
+  void *context;
+} labcomm_sample_entry_t;
+
+typedef struct labcomm_encoder_context {
+  labcomm_sample_entry_t *sample;
+  int index;
+} labcomm_encoder_context_t;
+
+typedef struct labcomm_decoder_context {
+  labcomm_sample_entry_t *sample;
+} labcomm_decoder_context_t;
+
+static labcomm_sample_entry_t *get_sample_by_signature_address(
+  labcomm_sample_entry_t *head,
+  labcomm_signature_t *signature)
+{
+  labcomm_sample_entry_t *p;
+  for (p = head ; p && p->signature != signature ; p = p->next) {
+    
+  }
+  return p;
+}
+
+static labcomm_sample_entry_t *get_sample_by_signature_value(
+  labcomm_sample_entry_t *head,
+  labcomm_signature_t *signature)
+{
+  labcomm_sample_entry_t *p;
+  for (p = head ; p ; p = p->next) {
+    if (p->signature->type == signature->type &&
+	p->signature->size == signature->size &&
+	strcmp(p->signature->name, signature->name) == 0 &&
+	bcmp((void*)p->signature->signature, (void*)signature->signature, 
+	     signature->size) == 0) {
+      break;
+    }
+  }
+  return p;
+}
+
+static labcomm_sample_entry_t *get_sample_by_index(
+  labcomm_sample_entry_t *head,
+  int index)
+{
+  labcomm_sample_entry_t *p;
+  for (p = head ; p && p->index != index ; p = p->next) {
+  }
+  return p;
+}
+
+static int get_encoder_index(
+  labcomm_encoder_t *e,
+  labcomm_signature_t *s)
+{
+  int result = 0;
+  labcomm_encoder_context_t *context = e->context;
+  labcomm_sample_entry_t *sample = context->sample;
+  while (sample) {
+    if (sample->signature == s) { break; }
+    sample = sample->next;
+  }
+  if (sample) {
+    result = sample->index;
+  }
+  return result;
+}
+
+static void do_encoder_register(struct labcomm_encoder *e, 
+				labcomm_signature_t *signature,
+				labcomm_encode_typecast_t encode)
+{
+  if (signature->type == LABCOMM_SAMPLE) {
+    if (get_encoder_index(e, signature) == 0) {
+      int i;
+      labcomm_encoder_context_t *context = e->context;
+      labcomm_sample_entry_t *sample = 
+	(labcomm_sample_entry_t*)malloc(sizeof(labcomm_sample_entry_t));
+      sample->next = context->sample;
+      sample->index = context->index;
+      sample->signature = signature;
+      sample->encode = encode;
+      context->index++;
+      context->sample = sample;
+
+      e->writer.write(&e->writer, labcomm_writer_start);
+      labcomm_encode_int(e, signature->type);
+      labcomm_encode_type_index(e, signature);
+      labcomm_encode_string(e, signature->name);
+      for (i = 0 ; i < signature->size ; i++) {
+	if (e->writer.pos >= e->writer.count) {	
+	  e->writer.write(&e->writer, labcomm_writer_continue);
+	}
+	e->writer.data[e->writer.pos] = signature->signature[i];
+	e->writer.pos++;
+      }
+      e->writer.write(&e->writer, labcomm_writer_end);
+    }
+  }
+}
+
+static void do_encode(
+  labcomm_encoder_t *encoder, 
+  labcomm_signature_t *signature, 
+  void *value)
+{
+  labcomm_encoder_context_t *context = encoder->context;
+  labcomm_sample_entry_t *sample;
+  sample = get_sample_by_signature_address(context->sample, 
+					   signature);
+  if (sample && sample->encode) {
+    sample->encode(encoder, value);
+  } else {
+    printf("Encoder has no registration for %s\n", signature->name);
+  }
+}
+
+labcomm_encoder_t *labcomm_encoder_new(
+  int (*writer)(labcomm_writer_t *, labcomm_writer_action_t),
+  void *writer_context)
+{
+  labcomm_encoder_t *result = malloc(sizeof(labcomm_encoder_t));
+  if (result) {
+    labcomm_encoder_context_t *context;
+
+    context = malloc(sizeof(labcomm_encoder_context_t));
+    context->sample = 0;
+    context->index = LABCOMM_USER;
+    result->context = context;
+    result->writer.context = writer_context;
+    result->writer.data = 0;
+    result->writer.data_size = 0;
+    result->writer.count = 0;
+    result->writer.pos = 0;
+    result->writer.write = writer;
+    result->writer.write(&result->writer, labcomm_writer_alloc);
+    result->do_register = do_encoder_register;
+    result->do_encode = do_encode;
+  }
+  return result;
+}
+
+void labcomm_internal_encoder_register(
+  labcomm_encoder_t *e, 
+  labcomm_signature_t *signature,
+  labcomm_encode_typecast_t encode)
+{
+  if (e && e->do_register) {
+    e->do_register(e, signature, encode);
+  } else {
+    printf("Encoder is missing do_register\n");
+  }
+}
+
+void labcomm_internal_encode(
+  labcomm_encoder_t *e, 
+  labcomm_signature_t *signature, 
+  void *value)
+{
+  if (e && e->do_encode) {
+    e->do_encode(e, signature, value);
+  } else {
+    printf("Encoder is missing do_encode\n");
+  }  
+}
+  
+void labcomm_internal_encoder_user_action(labcomm_encoder_t *e,
+					  int action)
+{
+  e->writer.write(&e->writer, action);
+}
+
+void labcomm_encoder_free(labcomm_encoder_t* e) 
+{
+  
+  e->writer.write(&e->writer, labcomm_writer_free);
+  free(e);
+}
+
+void labcomm_encode_type_index(labcomm_encoder_t *e, labcomm_signature_t *s)
+{
+  int index = get_encoder_index(e, s);
+  labcomm_encode_int(e, index);
+}
+
+static int signature_writer(
+  labcomm_writer_t *w, 
+  labcomm_writer_action_t action)
+{
+  switch (action) {
+    case labcomm_writer_alloc: {
+      w->data_size = 1000;
+      w->count = w->data_size;
+      w->data = malloc(w->data_size);
+      w->pos = 0;
+    } break;
+    case labcomm_writer_start: {
+      w->data_size = 1000; 
+      w->count = w->data_size;
+      w->data = realloc(w->data, w->data_size);
+      w->pos = 0;
+    } break;
+    case labcomm_writer_continue: {
+      w->data_size += 1000; 
+      w->count = w->data_size;
+      w->data = realloc(w->data, w->data_size);
+    } break;
+    case labcomm_writer_end: {
+    } break;
+    case labcomm_writer_free: {
+      free(w->data);
+      w->data = 0;
+      w->data_size = 0;
+      w->count = 0;
+      w->pos = 0;
+    } break;
+    case labcomm_writer_available: {
+    } break;
+  }
+  return 0;
+
+}
+
+static void collect_flat_signature(
+  labcomm_decoder_t *decoder,
+  labcomm_encoder_t *signature_writer)
+{
+  int type = labcomm_decode_int(decoder);
+  if (type >= LABCOMM_USER) {
+    printf("Implement %s ...\n", __FUNCTION__);
+  } else {
+    labcomm_encode_int(signature_writer, type);
+    switch (type) {
+      case LABCOMM_ARRAY: {
+	int dimensions, i;
+	
+	dimensions = labcomm_decode_int(decoder);
+	labcomm_encode_int(signature_writer, dimensions);
+	for (i = 0 ; i < dimensions ; i++) {
+	  int n = labcomm_decode_int(decoder);
+	  labcomm_encode_int(signature_writer, n);
+	}
+	collect_flat_signature(decoder, signature_writer);
+      } break;
+      case LABCOMM_STRUCT: {
+	int fields, i;
+	fields = labcomm_decode_int(decoder);
+	labcomm_encode_int(signature_writer, fields);
+	for (i = 0 ; i < fields ; i++) {
+	  char *name = labcomm_decode_string(decoder);
+	  labcomm_encode_string(signature_writer, name);
+	  free(name);
+	  collect_flat_signature(decoder, signature_writer);
+	}
+      } break;
+      case LABCOMM_BOOLEAN:
+      case LABCOMM_BYTE:
+      case LABCOMM_SHORT:
+      case LABCOMM_INT:
+      case LABCOMM_LONG:
+      case LABCOMM_FLOAT:
+      case LABCOMM_DOUBLE:
+      case LABCOMM_STRING: {
+      } break;
+      default: {
+	printf("Implement %s ...\n", __FUNCTION__);
+      } break;
+    }
+  }
+}
+
+static void do_decoder_register(
+  labcomm_decoder_t *decoder, 
+  labcomm_signature_t *signature, 
+  labcomm_decoder_typecast_t type_decoder,
+  labcomm_handler_typecast_t handler,
+  void *handler_context)
+{
+  
+  labcomm_decoder_context_t *context = decoder->context;
+  labcomm_sample_entry_t *sample;
+  sample = get_sample_by_signature_address(context->sample, 
+					   signature);
+  if (!sample) {
+    sample = (labcomm_sample_entry_t*)malloc(sizeof(labcomm_sample_entry_t));
+    sample->next = context->sample;
+    context->sample = sample;
+    sample->index = 0;
+    sample->signature = signature;
+  } 
+  sample->decoder = type_decoder;
+  sample->handler = handler;
+  sample->context = handler_context;
+}
+
+static int do_decode_one(labcomm_decoder_t *d)
+{
+  int result;
+
+  do {
+    result = d->reader.read(&d->reader, labcomm_reader_start);
+    if (result > 0) { 
+      labcomm_decoder_context_t *context = d->context;
+
+      result = labcomm_decode_int(d);
+      if (result == LABCOMM_TYPEDEF || result == LABCOMM_SAMPLE) {
+	labcomm_encoder_t *e = labcomm_encoder_new(signature_writer, 0);
+	labcomm_signature_t signature;
+	labcomm_sample_entry_t *entry;
+	int index;
+	
+	e->writer.write(&e->writer, labcomm_writer_start);
+	signature.type = result;
+	index = labcomm_decode_int(d);
+	signature.name = labcomm_decode_string(d);
+	collect_flat_signature(d, e);
+	signature.size = e->writer.pos;
+	signature.signature = e->writer.data;
+	entry = get_sample_by_signature_value(context->sample, &signature);
+	if (! entry) {
+	  // Unknown datatype, bail out
+	  fprintf(stderr,	"%s: unknown datatype '%s' (id=0x%x)\n", 
+		  __FUNCTION__, signature.name, index);
+	} else if (entry->index && entry->index != index) {
+	  fprintf(stderr,	"%s: index mismatch '%s' (id=0x%x != 0x%x)\n", 
+		  __FUNCTION__, signature.name, entry->index, index);
+	} else {
+	  entry->index = index;
+	}
+	free(signature.name);
+	e->writer.write(&e->writer, labcomm_writer_end);
+	if (!entry) {
+	  // No handler for found type, bail out (after cleanup)
+	  result = -ENOENT;
+	}
+	labcomm_encoder_free(e);
+      } else {
+	labcomm_sample_entry_t *entry;
+	
+	entry = get_sample_by_index(context->sample, result);
+	if (!entry) {
+	  fprintf(stderr,	"%s: type not found (id=0x%x)\n", 
+		  __FUNCTION__, result);
+	  result = -ENOENT;
+	} else {
+	  entry->decoder(d, entry->handler, entry->context);
+	}
+      }
+    }
+    d->reader.read(&d->reader, labcomm_reader_end);
+  } while (result > 0 && result < LABCOMM_USER);  
+  return result;
+}
+
+labcomm_decoder_t *labcomm_decoder_new(
+  int (*reader)(labcomm_reader_t *, labcomm_reader_action_t),
+  void *reader_context)
+{
+  labcomm_decoder_t *result = malloc(sizeof(labcomm_decoder_t));
+  if (result) {
+    labcomm_decoder_context_t *context =
+      (labcomm_decoder_context_t*)malloc(sizeof(labcomm_decoder_context_t));
+    context->sample = 0;
+    result->context = context;
+    result->reader.context = reader_context;
+    result->reader.data = 0;
+    result->reader.data_size = 0;
+    result->reader.count = 0;
+    result->reader.pos = 0;
+    result->reader.read = reader;
+    result->reader.read(&result->reader, labcomm_reader_alloc);
+    result->do_register = do_decoder_register;
+    result->do_decode_one = do_decode_one;
+  }
+  return result;
+}
+
+void labcomm_internal_decoder_register(
+  labcomm_decoder_t *d, 
+  labcomm_signature_t *signature, 
+  labcomm_decoder_typecast_t type_decoder,
+  labcomm_handler_typecast_t handler,
+  void *handler_context)
+{
+  if (d && d->do_register) {
+    d->do_register(d, signature, type_decoder, handler, handler_context);
+  } else {
+    printf("Decoder is missing do_register\n");
+  }
+}
+
+int labcomm_decoder_decode_one(labcomm_decoder_t *d)
+{
+  int result = -1;
+  if (d && d->do_decode_one) {
+    result = d->do_decode_one(d);
+  } else {
+    printf("Decoder is missing do_decode_one\n");
+  }
+  return result;
+}
+
+void labcomm_decoder_run(labcomm_decoder_t *d)
+{
+  while (labcomm_decoder_decode_one(d) > 0) {
+  }
+}
+
+void labcomm_decoder_free(labcomm_decoder_t* d) 
+{
+  d->reader.read(&d->reader, labcomm_reader_free);
+  free(d);
+}
diff --git a/lib/c/labcomm.h b/lib/c/labcomm.h
new file mode 100644
index 0000000000000000000000000000000000000000..9fed6976f1d5760b60b36213578e70d4ab89d2ce
--- /dev/null
+++ b/lib/c/labcomm.h
@@ -0,0 +1,83 @@
+#ifndef _LABCOMM_H_
+#define _LABCOMM_H_
+
+#include <endian.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/*
+ * Signature entry
+ */
+typedef struct {
+  int type;
+  char *name;
+  int (*encoded_size)(void *);
+  int size;
+  unsigned char *signature; 
+} labcomm_signature_t;
+
+
+/*
+ * Decoder
+ */
+struct labcomm_decoder;
+
+typedef enum { 
+  labcomm_reader_alloc, 
+  labcomm_reader_free,
+  labcomm_reader_start, 
+  labcomm_reader_continue, 
+  labcomm_reader_end
+} labcomm_reader_action_t;
+
+typedef struct labcomm_reader {
+  void *context;
+  unsigned char *data;
+  int data_size;
+  int count;
+  int pos;
+  int (*read)(struct labcomm_reader *, labcomm_reader_action_t);
+}  labcomm_reader_t;
+
+struct labcomm_decoder *labcomm_decoder_new(
+  int (*reader)(labcomm_reader_t *, labcomm_reader_action_t),
+  void *reader_context);
+int labcomm_decoder_decode_one(
+  struct labcomm_decoder *decoder);
+void labcomm_decoder_run(
+  struct labcomm_decoder *decoder);
+void labcomm_decoder_free(
+  struct labcomm_decoder *decoder);
+
+/*
+ * Encoder
+ */
+struct labcomm_encoder;
+
+typedef enum { 
+  labcomm_writer_alloc, 
+  labcomm_writer_free,
+  labcomm_writer_start, 
+  labcomm_writer_continue, 
+  labcomm_writer_end, 
+  labcomm_writer_available,
+} labcomm_writer_action_t;
+
+typedef struct labcomm_writer {
+  void *context;
+  unsigned char *data;
+  int data_size;
+  int count;
+  int pos;
+  int (*write)(struct labcomm_writer *, labcomm_writer_action_t);
+} labcomm_writer_t;
+
+struct labcomm_encoder;
+struct labcomm_encoder *labcomm_encoder_new(
+  int (*writer)(labcomm_writer_t *, labcomm_writer_action_t),
+  void *writer_context);
+void labcomm_encoder_free(
+  struct labcomm_encoder *encoder);
+
+#endif
diff --git a/lib/c/labcomm_private.h b/lib/c/labcomm_private.h
new file mode 100644
index 0000000000000000000000000000000000000000..3bc5140640f9a2b473ce3cd887764fdc1807b03f
--- /dev/null
+++ b/lib/c/labcomm_private.h
@@ -0,0 +1,290 @@
+#ifndef _LABCOMM_PRIVATE_H_
+#define _LABCOMM_PRIVATE_H_
+
+#include <endian.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "labcomm.h"
+
+/*
+ * Predeclared aggregate type indices
+ */
+#define LABCOMM_TYPEDEF  0x01
+#define LABCOMM_SAMPLE   0x02
+#define LABCOMM_ARRAY    0x10
+#define LABCOMM_STRUCT   0x11
+
+/*
+ * Predeclared primitive type indices
+ */
+#define LABCOMM_BOOLEAN  0x20 
+#define LABCOMM_BYTE     0x21
+#define LABCOMM_SHORT    0x22
+#define LABCOMM_INT      0x23
+#define LABCOMM_LONG     0x24
+#define LABCOMM_FLOAT    0x25
+#define LABCOMM_DOUBLE   0x26
+#define LABCOMM_STRING   0x27
+
+/*
+ * Start index for user defined types
+ */
+#define LABCOMM_USER     0x80
+
+/*
+ * Semi private decoder declarations
+ */
+typedef void (*labcomm_handler_typecast_t)(void *, void *);
+
+typedef void (*labcomm_decoder_typecast_t)(
+  struct labcomm_decoder *,
+  labcomm_handler_typecast_t,
+  void *);
+
+typedef struct labcomm_decoder {
+  void *context;
+  labcomm_reader_t reader;
+  void (*do_register)(struct labcomm_decoder *, 
+		      labcomm_signature_t *, 
+		      labcomm_decoder_typecast_t,
+		      labcomm_handler_typecast_t,
+		      void *context);
+  int (*do_decode_one)(struct labcomm_decoder *decoder);
+} labcomm_decoder_t;
+
+/*
+ * Non typesafe registration function to be called from
+ * generated labcomm_decoder_register_* functions.
+ */
+void labcomm_internal_decoder_register(
+  labcomm_decoder_t *, 
+  labcomm_signature_t *, 
+  labcomm_decoder_typecast_t,
+  labcomm_handler_typecast_t,
+  void *context);
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+
+#define LABCOMM_DECODE(name, type)					\
+  static inline type labcomm_read_##name(labcomm_reader_t *r) {		\
+    type result; int i;							\
+    for (i = sizeof(type) - 1 ; i >= 0 ; i--) {				\
+      if (r->pos >= r->count) {						\
+	r->read(r, labcomm_reader_continue);				\
+      }									\
+      ((unsigned char*)(&result))[i] = r->data[r->pos];			\
+      r->pos++;								\
+    }									\
+    return result;							\
+  }									\
+  static inline type labcomm_decode_##name(labcomm_decoder_t *d) {	\
+    return labcomm_read_##name(&d->reader);				\
+  }
+
+#else
+
+#define LABCOMM_DECODE(name, type)					\
+  static inline type labcomm_read_##name(labcomm_reader_t *r) {		\
+    type result; int i;							\
+    for (i = 0 ; i < sizeof(type) ; i++) {				\
+      if (r->pos >= r->count) {						\
+	r->read(r, labcomm_reader_continue);				\
+      }									\
+      ((unsigned char*)(&result))[i] = r->data[r->pos];			\
+      r->pos++;								\
+    }									\
+    return result;							\
+  }									\
+  static inline type labcomm_decode_##name(labcomm_decoder_t *d) {	\
+    return labcomm_read_##name(&d->reader);				\
+  }
+
+#endif
+
+LABCOMM_DECODE(boolean, unsigned char)
+LABCOMM_DECODE(byte, unsigned char)
+LABCOMM_DECODE(short, short)
+LABCOMM_DECODE(int, int)
+LABCOMM_DECODE(long, long long)
+LABCOMM_DECODE(float, float)
+LABCOMM_DECODE(double, double)
+static inline char *labcomm_read_string(labcomm_reader_t *r)
+{
+  char *result;
+  int length, i; 
+  
+  length = labcomm_read_int(r);
+  result = malloc(length + 1);
+  for (i = 0 ; i < length ; i++) {
+    if (r->pos >= r->count) {	
+      r->read(r, labcomm_reader_continue);
+    }
+    result[i] = r->data[r->pos];
+    r->pos++;
+  }
+  result[length] = 0;
+  return result;
+}
+
+static inline char *labcomm_decode_string(labcomm_decoder_t *d)
+{
+  return labcomm_read_string(&d->reader);
+}
+
+static inline int labcomm_buffer_read(struct labcomm_reader *r, 
+				      labcomm_reader_action_t action)
+{
+  // If this gets called, it is an error, 
+  // so note error and let producer proceed
+  r->context = r;
+  r->pos = 0;
+  return 0;
+}
+
+static inline int labcomm_buffer_reader_error(struct labcomm_reader *r) 
+{
+  return r->context != NULL;
+} 
+
+static inline void labcomm_buffer_reader_setup(
+  labcomm_reader_t *r,
+  void *data,
+  int length)
+{
+  r->context = NULL; // Used as errer flag
+  r->data = data;  
+  r->data_size = length;
+  r->count = length;
+  r->pos = 0;
+  r->read = labcomm_buffer_read;
+}
+
+/*
+ * Semi private encoder declarations
+ */
+typedef void (*labcomm_encode_typecast_t)(
+  struct labcomm_encoder *,
+  void *value);
+
+typedef struct labcomm_encoder {
+  void *context;
+  labcomm_writer_t writer;
+  void (*do_register)(struct labcomm_encoder *encoder, 
+		      labcomm_signature_t *signature,
+		      labcomm_encode_typecast_t);
+  void (*do_encode)(struct labcomm_encoder *encoder, 
+		    labcomm_signature_t *signature, 
+		    void *value);
+} labcomm_encoder_t;
+
+void labcomm_internal_encoder_register(
+  labcomm_encoder_t *encoder, 
+  labcomm_signature_t *signature, 
+  labcomm_encode_typecast_t encode);
+
+void labcomm_internal_encode(
+  labcomm_encoder_t *encoder, 
+  labcomm_signature_t *signature, 
+  void *value);
+
+#define LABCOMM_USER_ACTION(i) (i + 100)
+void labcomm_internal_encoder_user_action(struct labcomm_encoder *encoder, 
+					  int action);
+
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+
+#define LABCOMM_ENCODE(name, type)					\
+  static inline void labcomm_write_##name(labcomm_writer_t *w, type data) { \
+    int i;								\
+    for (i = sizeof(type) - 1 ; i >= 0 ; i--) {				\
+      if (w->pos >= w->count) {						\
+	w->write(w, labcomm_writer_continue);				\
+      }									\
+      w->data[w->pos] = ((unsigned char*)(&data))[i];			\
+      w->pos++;								\
+    }									\
+  }									\
+  static inline void labcomm_encode_##name(labcomm_encoder_t *e, type data) { \
+    labcomm_write_##name(&e->writer, data);				\
+  }
+
+#else
+
+#define LABCOMM_ENCODE(name, type)					\
+  static inline void labcomm_write_##name(labcomm_writer_t *w, type data) { \
+    int i;								\
+    for (i = 0 ; i < sizeof(type) ; i++) {				\
+      if (w->pos >= w->count) {						\
+	w->write(w, labcomm_writer_continue);			\
+      }									\
+      w->data[w->pos] = ((unsigned char*)(&data))[i];			\
+      w->pos++;								\
+    }									\
+  }									\
+  static inline void labcomm_encode_##name(labcomm_encoder_t *e, type data) { \
+    labcomm_write_##name(&e->writer, data);				\
+  }
+
+#endif
+
+LABCOMM_ENCODE(boolean, unsigned char)
+LABCOMM_ENCODE(byte, unsigned char)
+LABCOMM_ENCODE(short, short)
+LABCOMM_ENCODE(int, int)
+LABCOMM_ENCODE(long, long long)
+LABCOMM_ENCODE(float, float)
+LABCOMM_ENCODE(double, double)
+static inline void labcomm_write_string(labcomm_writer_t *w, char *s)
+{
+  int length, i; 
+
+  length = strlen((char*)s);
+  labcomm_write_int(w, length);
+  for (i = 0 ; i < length ; i++) {
+    if (w->pos >= w->count) {	
+      w->write(w, labcomm_writer_continue);
+    }
+    w->data[w->pos] = s[i];
+    w->pos++;
+  }
+}
+
+static inline void labcomm_encode_string(labcomm_encoder_t *e, 
+					 char *s)
+{
+  labcomm_write_string(&e->writer, s);
+}
+
+void labcomm_encode_type_index(labcomm_encoder_t *e, labcomm_signature_t *s);
+
+static inline int labcomm_buffer_write(struct labcomm_writer *w, 
+                                       labcomm_writer_action_t action)
+{
+  // If this gets called, it is an error, 
+  // so note error and let producer proceed
+  w->context = w;
+  w->pos = 0;
+  return 0;
+}
+
+
+static inline int labcomm_buffer_writer_error(struct labcomm_writer *w) 
+{
+  return w->context != NULL;
+} 
+
+
+static inline void labcomm_buffer_writer_setup(struct labcomm_writer *w,
+                                               void *data,
+                                               int length)
+{
+  w->context = NULL; // Used as error flag
+  w->data = data;
+  w->data_size = length;
+  w->count = length;
+  w->pos = 0;
+  w->write = labcomm_buffer_write;
+}
+
+#endif